aboutsummaryrefslogtreecommitdiff
path: root/libtui/widget/widget.ha
diff options
context:
space:
mode:
Diffstat (limited to 'libtui/widget/widget.ha')
-rw-r--r--libtui/widget/widget.ha89
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;
+};