aboutsummaryrefslogtreecommitdiff
path: root/kscurses/ui/select_list.jai
diff options
context:
space:
mode:
authordam <dam@gudinoff>2023-08-17 20:28:47 +0100
committerdam <dam@gudinoff>2023-08-17 20:28:47 +0100
commit709879ee56d31fe543a0ad882713bd4e3d17d2d2 (patch)
tree12a35282bdd0f1f8a2159ade147944c89254db24 /kscurses/ui/select_list.jai
parentfa1b8ea54646f1a0f3eadef33e3a660b875cc1ff (diff)
downloadtask-time-tracker-709879ee56d31fe543a0ad882713bd4e3d17d2d2.tar.zst
task-time-tracker-709879ee56d31fe543a0ad882713bd4e3d17d2d2.zip
Added kscurses and testing program.
Diffstat (limited to 'kscurses/ui/select_list.jai')
-rw-r--r--kscurses/ui/select_list.jai79
1 files changed, 79 insertions, 0 deletions
diff --git a/kscurses/ui/select_list.jai b/kscurses/ui/select_list.jai
new file mode 100644
index 0000000..8c338c6
--- /dev/null
+++ b/kscurses/ui/select_list.jai
@@ -0,0 +1,79 @@
+UI_Select_List :: struct {
+ #as using base : UI_Elem = .{type = .SELECT_LIST};
+ only_one := true;
+ options : []string;
+ selected : []bool;
+
+ selected_id := -1;
+ cursor, offset := 0, 0;
+
+ prefix_default := "[ ]";
+ prefix_selected := "[+]";
+}
+handle_key_select_list :: (ui_elem : *UI_Elem, key : Key) -> handled:bool {
+ using cast(*UI_Select_List) ui_elem;
+ assert(cursor_state != .OUTSIDE);
+ if cursor_state == .ON {
+ if key == .ENTER {
+ cursor_state = .IN;
+ return true;
+ }
+ } else {
+ if key == {
+ case .DOWN;
+ if cursor < options.count - 1 then cursor += 1;
+ case .UP;
+ if cursor > 0 then cursor -= 1;
+ case .ESCAPE;
+ cursor_state = .ON;
+ case .ENTER;
+ if only_one {
+ if cursor == selected_id {
+ selected_id = -1;
+ } else {
+ selected_id = cursor;
+ }
+ } else {
+ selected[cursor] ^= true;
+ }
+ case;
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+init :: (select_list : *UI_Select_List, only_one := true) {
+ select_list.only_one = only_one;
+ if !only_one select_list.selected = NewArray(select_list.options.count, bool);
+}
+deinit :: (using select_list : *UI_Select_List) {
+ array_free(selected);
+}
+c_draw_select_list :: (canvas : *Canvas, ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
+ using cast(*UI_Select_List) ui_elem;
+ rows := min(cast(int) zone.height, options.count - offset);
+
+ fix_offset :: () #expand {
+ if cursor - offset < 0 {
+ offset = cursor;
+ } else if cursor - offset >= zone.height {
+ offset = cursor - zone.height + 1;
+ }
+ }
+ fix_offset();
+
+ for y : 0..rows-1 {
+ i := y + offset;
+ is_selected := ifx only_one then i == selected_id else selected[i];
+ prefix := ifx is_selected then prefix_selected else prefix_default;
+ mode := ifx i == cursor && cursor_state == .IN
+ ifx is_selected style.text.cursor_and_selection else style.text.cursor
+ else
+ ifx is_selected style.text.selection else style.text.default;
+
+ c_draw_line_ascii(canvas, prefix, zone, .{0, xx y}, mode);
+ c_draw_line_ascii(canvas, options[i], zone, .{xx prefix.count, xx y}, mode);
+ }
+ return true;
+} \ No newline at end of file