diff options
Diffstat (limited to 'tui/widget/list/scrolllist.ha')
| -rw-r--r-- | tui/widget/list/scrolllist.ha | 49 |
1 files changed, 32 insertions, 17 deletions
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) { |
