diff options
Diffstat (limited to 'tui/widget/widget.ha')
| -rw-r--r-- | tui/widget/widget.ha | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/tui/widget/widget.ha b/tui/widget/widget.ha index a56203a..426d844 100644 --- a/tui/widget/widget.ha +++ b/tui/widget/widget.ha @@ -11,17 +11,30 @@ export type coords = (u16, u16); export type printfn = fn(w: *widget) void; export type resizefn = fn(w: *widget, ttysize: tty::ttysize) void; +export type finishfn = fn(w: *widget) void; export type widgetsize = (tty::ttysize | void); +export type none = void; +export type all = void; +export type row = uint; +export type col = uint; + +//export type damageitem = (row | col | coords); +export type damageitem = row; + +export type damage = (none | all | []damageitem); + export type widget = struct { state: *tui::tui, print: *printfn, resize: *resizefn, + finish: *finishfn, buf: str, pos: coords, sz: widgetsize, style: (*style | void), + damage: damage, }; export type color = enum uint { @@ -66,6 +79,9 @@ def NOUNDERLINE: str = "\x1B[0m"; def OVERLINE: rune = '\u0305'; def NOOVERLINE: str = "\x1B[0m"; +def CLEAR: str = "\x1B[2J"; +def CLEARROW: str = "\x1B[2K"; + // Must free return value fn underline(s: str) str = { return strings::concat(UNDERLINE, s, NOUNDERLINE); @@ -76,10 +92,19 @@ fn overline(s: str) str = { const st = memio::dynamic(); defer io::close(&st)!; let iter = strings::iter(s); + let iscolorcode = false; for (let r: rune => strings::next(&iter)) { - const char = strings::fromrunes([r, OVERLINE]); + if (r == '\x1B') { + iscolorcode = true; + }; + const char = if (!iscolorcode) { + yield strings::fromrunes([r, OVERLINE]); + } else { + yield strings::fromrunes([r]); + }; defer free(char); memio::concat(&st, char)!; + if (iscolorcode && r == 'm') iscolorcode = false; }; return strings::dup(memio::string(&st)!); }; @@ -97,21 +122,46 @@ fn minrows(out: io::file, x: u16, y: widgetsize) (u16 | tty::error) = { // Must free return string fn color_to_str(color: color) str = fmt::asprintf("\x1B[{}m", strconv::utos(color)); +fn clearrow(row: uint) str = fmt::asprintf("\x1B[{}d{}", row, CLEARROW); + export fn print(w: *widget) void = { + const clear = match (w.damage) { + case all => + yield strings::dup(CLEAR); + case none => + yield strings::dup(""); + case let dam: []damageitem => + let st = memio::dynamic(); + defer io::close(&st)!; + for (let item: damageitem .. dam) { + memio::concat(&st, clearrow(item))!; + //match (item) { + //case let r: row => + // yield clearrow(r); + ////case let c: col => + ////case let co: coords => + //}; + }; + yield strings::dup(memio::string(&st)!); + }; + defer free(clear); + let s = truncate_to_size(w); defer free(s); let sstyle = applystyles(w.style, s); defer free(sstyle); - const clear = if (w.state.clear) "\x1B[2J" else ""; + //const clear = if (w.state.clear) "\x1B[2J" else ""; let seekpos = fmt::asprintf("{}\x1B[{};{}H", clear, w.pos.0, w.pos.1); defer free(seekpos); const sout = strings::concat(seekpos, sstyle); defer free(sout); fmt::fprint(w.state.out, sout)!; + + w.state.clear = false; }; // Applies styling (style) to the given string @@ -187,3 +237,25 @@ export fn prints(out: io::file, s: str, pos: coords) void = { fmt::fprintf(out, "\x1B[{};{}H", pos.0, pos.1)!; fmt::fprint(out, s)!; }; + +export fn finish(w: *widget) void = { + match (w.damage) { + case let dam: []damageitem => + free(dam); + case all => + return; + case all => + return; + }; +}; + +export fn cleardamage(w: *widget) void = { + let dam = if (w.damage is all) { + return; + } else { + yield w.damage as []damageitem; + }; + for (let i = 0z; i < len(dam); i += 1) { + delete(dam[i]); + }; +}; |
