aboutsummaryrefslogtreecommitdiff
path: root/libui/list/list.ha
diff options
context:
space:
mode:
Diffstat (limited to 'libui/list/list.ha')
-rw-r--r--libui/list/list.ha31
1 files changed, 30 insertions, 1 deletions
diff --git a/libui/list/list.ha b/libui/list/list.ha
index 6cbafd7..16e2ecc 100644
--- a/libui/list/list.ha
+++ b/libui/list/list.ha
@@ -29,6 +29,7 @@ export type ttysize = struct {
export type listener = *fn(l: *listwidget, r: rune) bool;
+// Create a new list with the given items.
export fn newlist(ui: libui::ttyui, items: str...) listwidget = {
let sz = libui::getwinsize(ui)!;
let rows: (u16 | size) = if (sz.rows - 2 < len(items)) {
@@ -53,10 +54,13 @@ export fn newlist(ui: libui::ttyui, items: str...) listwidget = {
return w;
};
+// Add a listener to the given list.
export fn addlistener(list: *listwidget, l: listener) void = {
append(list.listeners, l);
};
+// Print the list's items while truncating the items to not be wider than the
+// list.sz.cols.
export fn print(list: *listwidget) (void | io::error | tty::error) = {
//let sz = libui::getwinsize(list.ui)?;
//let rows: (u16 | size) = if (sz.rows - 2 < len(list.items)) {
@@ -90,6 +94,8 @@ export fn print(list: *listwidget) (void | io::error | tty::error) = {
libui::print(list.ui, s);
};
+// Notify (call) the listwidget's listeners with the listwidget and r as a
+// parameter.
export fn notify(l: *listwidget, r: rune) bool = {
for (let i = 0z; i < len(l.listeners); i += 1) {
if (l.listeners[i](l, r)) {
@@ -99,6 +105,7 @@ export fn notify(l: *listwidget, r: rune) bool = {
return false;
};
+// Move the list's cursor down one item. Returns the new cursor.
export fn down(l: *listwidget) size = {
if (l.cursor < len(l.items) - 1) {
l.cursor += 1;
@@ -107,6 +114,7 @@ export fn down(l: *listwidget) size = {
return l.cursor;
};
+// Move the list's cursor up one item. Returns the new cursor.
export fn up(l: *listwidget) size = {
if (l.cursor > 0) {
l.cursor -= 1;
@@ -115,6 +123,8 @@ export fn up(l: *listwidget) size = {
return l.cursor;
};
+// Reset the list's frame based on the cursor. Returns whether the frame was
+// updated.
fn reframe(l: *listwidget) bool = {
let reframed: bool = false;
if (l.cursor < l.frame.start) {
@@ -130,6 +140,7 @@ fn reframe(l: *listwidget) bool = {
return reframed;
};
+// Move the list's cursor to the top (first item). Returns the new cursor.
export fn top(l: *listwidget) size = {
l.cursor = 0;
l.frame.start = 0;
@@ -137,6 +148,7 @@ export fn top(l: *listwidget) size = {
return l.cursor;
};
+// Move the list's cursor to the bottom (last item). Returns the new cursor.
export fn bottom(l: *listwidget) size = {
l.cursor = len(l.items) - 1;
l.frame.end = len(l.items): u16;
@@ -144,11 +156,28 @@ export fn bottom(l: *listwidget) size = {
return l.cursor;
};
+// Forward search through the list's items for an item containing s. Returns the
+// new cursor.
export fn search(l: *listwidget, s: str) size = {
- for (let i = 0z; i < len(l.items); i += 1) {
+ for (let i = l.cursor + 1; i < len(l.items); i += 1) {
if (strings::contains(l.items[i], s)) {
l.cursor = i;
reframe(l);
+ return l.cursor;
+ };
+ };
+ return l.cursor;
+};
+
+// Backwards search through the list's items for an item containing s. Returns
+// the new cursor.
+export fn rsearch(l: *listwidget, s: str) size = {
+ // size wraps to max value for size when < 0
+ for (let i = l.cursor: int - 1; i >= 0; i -= 1) {
+ if (strings::contains(l.items[i], s)) {
+ l.cursor = i: size;
+ reframe(l);
+ return l.cursor;
};
};
return l.cursor;