diff options
Diffstat (limited to 'libtui/widget/widget.ha')
| -rw-r--r-- | libtui/widget/widget.ha | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/libtui/widget/widget.ha b/libtui/widget/widget.ha new file mode 100644 index 0000000..6875692 --- /dev/null +++ b/libtui/widget/widget.ha @@ -0,0 +1,89 @@ +// License: MPL-2.0 +// (c) 2022 Julian Hurst <ark@mansus.space> + +use libtui; +use io; +use unix::tty; + +export type error = !(io::error | tty::error); + +// A function that displays the widget. +export type print = fn(w: *widget) (void | error); + +// A function that frees the resources associated to the widget. +export type finish = fn(w: *widget) void; + +// An input listener on a widget. The returning value is intended to be used as +// a signal that will be returned by [[notify]] in order to trigger certain more +// global ui events (terminate the program, change widget focus, etc.). To +// register a listener with a widget, use [[addlistener]]. +export type listener = *fn(w: *widget, r: libtui::key) bool; + +// A widget is an abstraction around a user-defined UI component. Custom widgets +// can be created through sub-typing: +// +// export type my_widget = struct { +// widget: widget::widget, +// lines: []str, +// }; +// +// fn print(w: *widget::widget) (void | widget::error) = { +// const w = w: *my_widget; +// for (let i = 0z; i < len(w.lines); i += 1) { +// fmt::println(w.lines[i])!; +// }; +// }; +// +// fn finish(w: *widget::widget) void = { +// const w = w: *my_widget; +// free(w.lines); +// widget::finishcommon(w); +// }; +// +// let list = my_widget { +// widget = widget::widget { +// print = &print, +// finish = &finish, +// ... +// }; +// lines = strings::split("one,two,three", ","), +// }; +// let l = layout::newlayout(list); +// layout::print(l)!; +export type widget = struct { + print: nullable *print, + finish: nullable *finish, + listeners: []listener, + ui: libtui::ttyui, +}; + +// Add a listener to the given widget. +export fn addlistener(w: *widget, listener: listener) void = { + append(w.listeners, listener); +}; + +// Delete a listener from the given widget. +export fn dellistener(w: *widget, idx: size) void = { + delete(w.listeners[idx]); +}; + +// Clear the listeners of the given widget. +export fn clearlisteners(w: *widget) void = { + w.listeners = []; +}; + +// Free the widget's listeners. +export fn finishcommon(w: *widget) void = { + free(w.listeners); +}; + +// Notify (call) the widget's listeners with the widget and r as a parameter. +// Returns true if a listener returned true, false otherwise. +export fn notify(w: *widget, r: (rune | libtui::specialkey)) bool = { + for (let i = 0z; i < len(w.listeners); i += 1) { + if (w.listeners[i](w, r)) { + return true; + }; + }; + return false; +}; |
