summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Hurst <ark@mansus.space>2025-03-20 13:54:08 +0100
committerJulian Hurst <ark@mansus.space>2025-03-20 13:54:08 +0100
commit5e93fe240e489ff13a90a7ff29fee415c8113cc9 (patch)
tree98c16dc327c242b47d813deab6e2c1bd4b412f46
parent39b580c33ce568bb3b055df6bc4b16fa5969e77b (diff)
parent3a137cfcfbc8686f2441de9604b15dc5d9ab4cd7 (diff)
downloadhare-tui-5e93fe240e489ff13a90a7ff29fee415c8113cc9.tar.gz
Merge branch 'master' into nomem
-rw-r--r--cmd/il.ha6
-rw-r--r--tui/widget/list/list.ha11
-rw-r--r--tui/widget/list/scrolllist.ha49
3 files changed, 41 insertions, 25 deletions
diff --git a/cmd/il.ha b/cmd/il.ha
index 156ab1e..3afbb37 100644
--- a/cmd/il.ha
+++ b/cmd/il.ha
@@ -95,9 +95,9 @@ fn nextsearch(li: *list::scrolllist, term: (str | void)) void = {
case void =>
return;
};
- for (let i = li.cursor + 1; i < len(li.items); i += 1) {
+ for (let i = li.cursor + 1; i < len(li.items): int; i += 1) {
if (strings::contains(li.items[i], term)) {
- list::setcursor(li, i: u16);
+ list::setcursor(li, i);
return;
};
};
@@ -112,7 +112,7 @@ fn prevsearch(li: *list::scrolllist, term: (str | void)) void = {
};
for (let i: int = li.cursor: int - 1; i >= 0; i -= 1) {
if (strings::contains(li.items[i], term)) {
- list::setcursor(li, i: u16);
+ list::setcursor(li, i);
return;
};
};
diff --git a/tui/widget/list/list.ha b/tui/widget/list/list.ha
index 56588ec..cbf83fa 100644
--- a/tui/widget/list/list.ha
+++ b/tui/widget/list/list.ha
@@ -6,8 +6,8 @@ use memio;
use strings;
export type frame = struct {
- start: u16,
- end: u16,
+ start: int,
+ end: int,
};
export type list = struct {
@@ -29,9 +29,10 @@ style: (*widget::style | void), items: str...) (list | tty::error) = {
case void =>
yield tsz.rows - 1;
};
+ let end = end: int;
- if (end > len(items)) {
- end = len(items): u16;
+ if (end > len(items): int) {
+ end = len(items): int;
};
return list {
@@ -49,7 +50,7 @@ style: (*widget::style | void), items: str...) (list | tty::error) = {
items = items,
frame = frame {
start = 0,
- end = end,
+ end = end: int,
},
};
};
diff --git a/tui/widget/list/scrolllist.ha b/tui/widget/list/scrolllist.ha
index d08c7d7..fed58a5 100644
--- a/tui/widget/list/scrolllist.ha
+++ b/tui/widget/list/scrolllist.ha
@@ -4,12 +4,13 @@ use io;
use unix::tty;
use memio;
use strings;
+use fmt;
export type scrolllist = struct {
widget: widget::widget,
items: []str,
frame: frame,
- cursor: u16,
+ cursor: int,
};
// Return an instance of list. out is the tty file, pos the starting position,
@@ -26,9 +27,10 @@ style: (*widget::style | void), items: str...) (scrolllist | tty::error) = {
case void =>
yield tsz.rows - 1;
};
+ let end = end: int;
- if (end > len(items)) {
- end = len(items): u16;
+ if (end > len(items): int) {
+ end = len(items): int;
};
return scrolllist {
@@ -48,12 +50,16 @@ style: (*widget::style | void), items: str...) (scrolllist | tty::error) = {
start = 0,
end = end,
},
- cursor = 0u16,
+ cursor = 0,
};
};
fn printscrolllist(widget: *widget::widget) void = {
const list = widget: *scrolllist;
+ assert(list.frame.start >= 0);
+ assert(list.frame.end <= len(list.items): int);
+ fmt::errorln(list.frame.start)!;
+ fmt::errorln(list.frame.end)!;
list.widget.buf = widget::linesbuf {
lines = list.items[list.frame.start..list.frame.end],
styles = &stylesscrolllist,
@@ -73,7 +79,7 @@ export fn down(li: *scrolllist) void = {
if (li.cursor == li.frame.end - 1) {
framedown(li);
};
- if (li.cursor < len(li.items) - 1) {
+ if (li.cursor < len(li.items): int - 1) {
li.cursor += 1;
};
};
@@ -95,7 +101,7 @@ export fn frameup(li: *scrolllist) void = {
};
export fn framedown(li: *scrolllist) void = {
- if (li.frame.end < len(li.items)) {
+ if (li.frame.end < len(li.items): int) {
li.frame.start += 1;
li.frame.end += 1;
};
@@ -110,12 +116,12 @@ export fn top(li: *scrolllist) void = {
export fn bottom(li: *scrolllist) void = {
const sz = li.frame.end - li.frame.start;
- li.cursor = len(li.items): u16 - 1;
- li.frame.end = len(li.items): u16;
- li.frame.start = len(li.items): u16 - sz;
+ li.cursor = len(li.items): int - 1;
+ li.frame.end = len(li.items): int;
+ li.frame.start = len(li.items): int - sz;
};
-export fn setcursor(li: *scrolllist, newpos: u16) void = {
+export fn setcursor(li: *scrolllist, newpos: int) void = {
li.cursor = newpos;
reframe(li);
};
@@ -123,19 +129,28 @@ export fn setcursor(li: *scrolllist, newpos: u16) void = {
fn reframe(li: *scrolllist) void = {
if (li.cursor > li.frame.end) {
const diff = li.frame.end - li.frame.start;
- li.frame.start = li.cursor;
- li.frame.end = li.frame.start + diff;
- };
- if (li.cursor < li.frame.start) {
+ li.frame.start = if (li.cursor <= len(li.items): int - diff) li.cursor else len(li.items): int - diff;
+ li.frame.end = if (li.frame.start + diff > len(li.items): int) {
+ yield len(li.items): int;
+ } else {
+ yield li.frame.start + diff;
+ };
+ } else if (li.cursor < li.frame.start) {
const diff = li.frame.end - li.frame.start;
- li.frame.end = li.cursor;
- li.frame.start = li.frame.end - diff;
+ li.frame.end = if (li.cursor > diff) li.cursor else diff;
+ li.frame.start = if (li.frame.end - diff < 0) {
+ yield 0;
+ } else {
+ yield li.frame.end - diff;
+ };
};
+ assert(li.frame.start >= 0);
+ assert(li.frame.end <= len(li.items): int);
};
fn stylesscrolllist(widget: *widget::widget, txt: str, idx: size) str = {
const list = widget: *scrolllist;
- const idx = idx + list.frame.start;
+ const idx = idx: int + list.frame.start;
let st = memio::dynamic();
defer io::close(&st)!;
if (idx == list.cursor) {