diff options
Diffstat (limited to 'tui/widget/list/scrolllist.ha')
| -rw-r--r-- | tui/widget/list/scrolllist.ha | 192 |
1 files changed, 0 insertions, 192 deletions
diff --git a/tui/widget/list/scrolllist.ha b/tui/widget/list/scrolllist.ha deleted file mode 100644 index ab1e7bc..0000000 --- a/tui/widget/list/scrolllist.ha +++ /dev/null @@ -1,192 +0,0 @@ -use tui; -use tui::widget; -use io; -use unix::tty; -use memio; -use strings; -use fmt; - -export type scrolllist = struct { - widget: widget::widget, - items: []str, - frame: frame, - cursor: int, - marked: []int, -}; - -// Return an instance of list. out is the tty file, pos the starting position, -// sz is the size of the widget (if void is used, the maximum possible -// size is used), items is the slice of items of the list. -export fn newscrolllist(state: *tui::tui, pos: widget::coords, sz: widget::widgetsize, -style: (*widget::style | void), items: str...) (scrolllist | tty::error) = { - const tsz = tty::winsize(state.out)?; - - let end = match (sz) { - case let sz: tty::ttysize => - const rows = if (tsz.rows < sz.rows) tsz.rows - 1 else sz.rows; - yield rows; - case void => - yield tsz.rows - 1; - }; - let end = end: int; - - if (end > len(items): int) { - end = len(items): int; - }; - - return scrolllist { - widget = widget::widget { - state = state, - print = &printscrolllist, - resize = &resizescrolllist, - finish = &finishscrolllist, - pos = pos, - sz = sz, - style = style, - damage = widget::damageall, - ... - }, - items = items, - frame = frame { - start = 0, - end = end, - }, - cursor = 0, - marked = [], - }; -}; - -fn printscrolllist(widget: *widget::widget) void = { - const list = widget: *scrolllist; - assert(list.frame.start >= 0); - assert(list.frame.end <= len(list.items): int); - list.widget.buf = widget::linesbuf { - lines = list.items[list.frame.start..list.frame.end], - styles = &stylesscrolllist, - }; - widget::print(list); -}; - -fn resizescrolllist(widget: *widget::widget, ttysize: tty::ttysize) void = { - return; -}; - -fn finishscrolllist(widget: *widget::widget) void = { - const list = widget: *scrolllist; - widget::finish(widget); - free(list.marked); -}; - -export fn down(li: *scrolllist) void = { - if (li.cursor == li.frame.end - 1) { - framedown(li); - }; - if (li.cursor < len(li.items): int - 1) { - li.cursor += 1; - }; -}; - -export fn up(li: *scrolllist) void = { - if (li.cursor == li.frame.start) { - frameup(li); - }; - if (li.cursor > 0) { - li.cursor -= 1; - }; -}; - -export fn frameup(li: *scrolllist) void = { - if (li.frame.start > 0) { - li.frame.start -= 1; - li.frame.end -= 1; - }; -}; - -export fn framedown(li: *scrolllist) void = { - if (li.frame.end < len(li.items): int) { - li.frame.start += 1; - li.frame.end += 1; - }; -}; - -export fn top(li: *scrolllist) void = { - const sz = li.frame.end - li.frame.start; - li.cursor = 0; - li.frame.end = sz; - li.frame.start = 0; -}; - -export fn bottom(li: *scrolllist) void = { - const sz = li.frame.end - li.frame.start; - 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: int) void = { - if (newpos < 0) { - li.cursor = 0; - } else if (newpos > len(li.items): int) { - li.cursor = len(li.items): int - 1; - } else { - li.cursor = newpos; - }; - reframe(li); -}; - -fn reframe(li: *scrolllist) void = { - if (li.cursor >= li.frame.end) { - const diff = li.frame.end - li.frame.start; - li.frame.end = li.cursor + 1; - li.frame.start = li.frame.end - diff; - } else if (li.cursor < li.frame.start) { - const diff = li.frame.end - li.frame.start; - li.frame.start = li.cursor; - li.frame.end = li.frame.start + 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: int + list.frame.start; - let st = memio::dynamic(); - defer io::close(&st)!; - if (idx == list.cursor) { - memio::concat(&st, "\x1B[7m")!; - }; - if (ismarked(*list, idx) is size) { - memio::concat(&st, "\x1B[44m")!; - }; - memio::concat(&st, txt)!; - if (idx == list.cursor) { - memio::concat(&st, "\x1B[27m")!; - }; - if (ismarked(*list, idx) is size) { - memio::concat(&st, "\x1B[49m")!; - }; - return strings::dup(memio::string(&st)!); -}; - -fn ismarked(li: scrolllist, j: int) (size | void) = { - for (let i = 0z; i < len(li.marked); i += 1) { - const idx = li.marked[i]; - if (idx == j) { - return i; - }; - }; - return; -}; - -export fn mark(li: *scrolllist) bool = { - defer down(li); - match (ismarked(*li, li.cursor)) { - case let s: size => - delete(li.marked[s]); - return false; - case void => - append(li.marked, li.cursor); - return true; - }; -}; |
