summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/list.ha2
-rw-r--r--cmd/text.ha14
-rw-r--r--tui/layout/layout.ha5
-rw-r--r--tui/layout/vlayout.ha2
-rw-r--r--tui/widget/list/list.ha6
-rw-r--r--tui/widget/text/text.ha6
-rw-r--r--tui/widget/widget.ha76
7 files changed, 100 insertions, 11 deletions
diff --git a/cmd/list.ha b/cmd/list.ha
index 1db46b4..348083e 100644
--- a/cmd/list.ha
+++ b/cmd/list.ha
@@ -15,6 +15,8 @@ export fn main() void = {
colorfg = widget::color::REDFG,
colorbg = widget::color::REDBG,
},"hello", "world", "bye", "world")!;
+
let l = layout::newvlayout(&li);
+ defer l.layout.finish(&l);
l.layout.print(&l);
};
diff --git a/cmd/text.ha b/cmd/text.ha
index f7ce1fc..7c569a8 100644
--- a/cmd/text.ha
+++ b/cmd/text.ha
@@ -17,7 +17,7 @@ export fn main() void = {
let l = layout::newvlayout(&txt);
l.layout.print(&l);
- tui::clear(&state);
+ //tui::clear(&state);
time::sleep(1 * time::SECOND);
let st = txt.widget.style as *widget::style;
@@ -25,37 +25,37 @@ export fn main() void = {
text::settext(&txt, "bye world");
l.layout.print(&l);
- tui::clear(&state);
+ //tui::clear(&state);
time::sleep(1 * time::SECOND);
st.colorfg = widget::color::BROWNFG;
l.layout.print(&l);
- tui::clear(&state);
+ //tui::clear(&state);
time::sleep(1 * time::SECOND);
st.colorfg = widget::color::BLUEFG;
l.layout.print(&l);
- tui::clear(&state);
+ //tui::clear(&state);
time::sleep(1 * time::SECOND);
st.colorfg = widget::color::MAGENTAFG;
l.layout.print(&l);
- tui::clear(&state);
+ //tui::clear(&state);
time::sleep(1 * time::SECOND);
st.colorfg = widget::color::CYANFG;
l.layout.print(&l);
- tui::clear(&state);
+ //tui::clear(&state);
time::sleep(1 * time::SECOND);
st.colorfg = widget::color::WHITEFG;
l.layout.print(&l);
- tui::clear(&state);
+ //tui::clear(&state);
time::sleep(1 * time::SECOND);
st.colorfg = widget::color::DEFAULTFG;
diff --git a/tui/layout/layout.ha b/tui/layout/layout.ha
index d425891..7a64221 100644
--- a/tui/layout/layout.ha
+++ b/tui/layout/layout.ha
@@ -10,5 +10,8 @@ export type layout = struct {
};
fn finish(l: *layout) void = {
- free(l.widgets);
+ for (let w .. l.widgets) {
+ w.finish(w);
+ };
+ //free(l.widgets);
};
diff --git a/tui/layout/vlayout.ha b/tui/layout/vlayout.ha
index 0381a9f..8a6a0a6 100644
--- a/tui/layout/vlayout.ha
+++ b/tui/layout/vlayout.ha
@@ -20,7 +20,7 @@ fn printvlayout(l: *layout) void = {
};
};
-fn finishvlayout(l: *layout) void = {
+export fn finishvlayout(l: *layout) void = {
let vl = l: *vlayout;
finish(&vl.layout);
};
diff --git a/tui/widget/list/list.ha b/tui/widget/list/list.ha
index ca7571b..d741a4d 100644
--- a/tui/widget/list/list.ha
+++ b/tui/widget/list/list.ha
@@ -39,9 +39,11 @@ style: (*widget::style | void), items: str...) (list | tty::error) = {
state = state,
print = &printlist,
resize = &resizelist,
+ finish = &finishlist,
pos = pos,
sz = sz,
style = style,
+ damage = widget::all,
...
},
items = items,
@@ -76,3 +78,7 @@ export fn printlist(widget: *widget::widget) void = {
export fn resizelist(widget: *widget::widget, ttysize: tty::ttysize) void = {
return;
};
+
+fn finishlist(widget: *widget::widget) void = {
+ widget::finish(widget);
+};
diff --git a/tui/widget/text/text.ha b/tui/widget/text/text.ha
index d849661..0a30eb0 100644
--- a/tui/widget/text/text.ha
+++ b/tui/widget/text/text.ha
@@ -15,9 +15,11 @@ export fn newtext(state: *tui::tui, txt: str, pos: widget::coords, style: (*widg
state = state,
print = &printtext,
resize = &resizetext,
+ finish = &finishtext,
pos = pos,
sz = void,
style = style,
+ damage = widget::all,
...
},
txt = txt,
@@ -38,3 +40,7 @@ fn resizetext(widget: *widget::widget, ttysize: tty::ttysize) void = {
export fn settext(text: *text, txt: str) void = {
text.txt = txt;
};
+
+fn finishtext(widget: *widget::widget) void = {
+ widget::finish(widget);
+};
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]);
+ };
+};