aboutsummaryrefslogtreecommitdiff
path: root/kscurses/ui
diff options
context:
space:
mode:
Diffstat (limited to 'kscurses/ui')
-rw-r--r--kscurses/ui/button.jai25
-rw-r--r--kscurses/ui/element.jai156
-rw-r--r--kscurses/ui/group.jai44
-rw-r--r--kscurses/ui/line_input.jai122
-rw-r--r--kscurses/ui/links.jai94
-rw-r--r--kscurses/ui/master.jai105
-rw-r--r--kscurses/ui/parent.jai33
-rw-r--r--kscurses/ui/popup_manager.jai65
-rw-r--r--kscurses/ui/progress_bar.jai37
-rw-r--r--kscurses/ui/scalable_group.jai88
-rw-r--r--kscurses/ui/scene_manager.jai48
-rw-r--r--kscurses/ui/select_list.jai79
-rw-r--r--kscurses/ui/style.jai118
-rw-r--r--kscurses/ui/table.jai87
-rw-r--r--kscurses/ui/text_buf.jai15
-rw-r--r--kscurses/ui/tilemap.jai20
16 files changed, 0 insertions, 1136 deletions
diff --git a/kscurses/ui/button.jai b/kscurses/ui/button.jai
deleted file mode 100644
index 3866e03..0000000
--- a/kscurses/ui/button.jai
+++ /dev/null
@@ -1,25 +0,0 @@
-UI_Button :: struct {
- #as using base : UI_Elem = .{type = .BUTTON};
- text := "";
- on_click : struct {
- proc := (data : *void){};
- data : *void;
- };
-}
-
-handle_key_button :: (ui_elem : *UI_Elem, key : Key) -> handled:bool {
- using cast(*UI_Button) ui_elem;
- assert(cursor_state == .ON);
- assert(!links.inner);
- if key == .ENTER {
- on_click.proc(on_click.data);
- return true;
- }
- return false;
-}
-c_draw_button :: (canvas : *Canvas, ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
- using cast(*UI_Button) ui_elem;
- mode := ifx cursor_state == .ON && box_type == .NONE then style.text.cursor else style.text.default;
- c_draw_line_ascii(canvas, text, zone, .{(zone.width - xx text.count) / 2, xx ((zone.height - 1) / 2)}, mode);
- return true;
-}
diff --git a/kscurses/ui/element.jai b/kscurses/ui/element.jai
deleted file mode 100644
index 3db8fcb..0000000
--- a/kscurses/ui/element.jai
+++ /dev/null
@@ -1,156 +0,0 @@
-UI_Elem :: struct {
- type : enum u8 {
- NONE :: 0;
- BUTTON :: 1;
- TEXT_BUF :: 2;
- GROUP :: 3;
- SELECT_LIST :: 4;
- SCENE_MANAGER :: 5;
- POPUP_MANAGER :: 6;
- LINE_INPUT :: 7;
- SCALABLE_GROUP :: 8;
- TABLE :: 9;
- PROGRESS_BAR :: 10;
- } = .NONE;
-
- using visual_data : struct {
- cursor_state : enum u8 { OUTSIDE :: 0; ON :: 1; IN :: 2; } = .OUTSIDE;
- box_type : enum u8 { NONE :: 0; BORDER :: 1; NO_BORDER :: 2; } = .BORDER;
- description_pos : enum u8 { TOP_LEFT :: 0; TOP_CENTER :: 1; TOP_RIGHT :: 2; BOTTOM_LEFT :: 4; BOTTOM_CENTER :: 5; BOTTOM_RIGHT :: 6; } = .TOP_LEFT;
- description := "";
- }
-
- using links : struct {
- left, right, bottom, top, inner, outer : *UI_Elem;
- parent : *UI_Parent;
- }
-
- extra_handler : struct {
- proc : (key : Key, data : *void) -> bool = null;
- data : *void;
- }
-}
-
-
-vtable_c_draw : []#type (*Canvas, *UI_Elem, Ibox2, *UI_Style) -> (bool) = .[
- c_draw_default,
- c_draw_button,
- c_draw_textbuf,
- c_draw_group,
- c_draw_select_list,
- c_draw_scene_manager,
- c_draw_popup_manager,
- c_draw_line_input,
- c_draw_scalable_group,
- c_draw_table,
- c_draw_progress_bar
-];
-c_draw :: (canvas : *Canvas, using ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
- ok := box_type == .NONE || c_box(canvas, zone, ifx cursor_state == .ON && __ui_master.blink_stage != 1 then style.box.cursor else style.box.default, box_type == .BORDER);
- if !ok return false;
- ok = c_draw_description(canvas, ui_elem, zone, style);
- if !ok return false;
-
- content_zone := ifx box_type == .BORDER then cut_border(zone, 1) else zone;
-
- c_draw_proc := vtable_c_draw[xx ui_elem.type];
- assert(xx c_draw_proc);
- return c_draw_proc(canvas, ui_elem, content_zone, style);
-}
-c_draw_default :: (canvas : *Canvas, using ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool { return true; };
-
-intersection_line :: (box : Ibox2, _line : string, _start : ivec2) -> line:string, start:ivec2 {
- line, start := _line, _start;
- if start.x < box.left {
- line.count += start.x - box.left;
- start.x = box.left;
- }
- if start.x + line.count > box.left + box.width {
- line.count = box.left + box.width - start.x;
- }
- return line, start;
-}
-
-c_draw_line_ascii_raw :: (canvas : *Canvas, line : string, start : ivec2, mode : Graphics_Mode) {
- for x : 0..line.count-1 c_putchar(canvas, .{code = xx line[x], mode = mode}, start + ivec2.{xx x, 0});
-}
-
-c_draw_line_ascii :: (canvas : *Canvas, _line : string, _start : ivec2, mode : Graphics_Mode) {
- line, start := intersection_line(canvas.zone, _line, _start);
- c_draw_line_ascii_raw(canvas, line, start, mode);
-}
-c_draw_line_ascii :: (canvas : *Canvas, _line : string, bounds : Ibox2, offset : ivec2, mode : Graphics_Mode) {
- assert(inside(bounds, canvas.zone));
- line, start := intersection_line(bounds, _line, bounds.corner + offset);
- c_draw_line_ascii_raw(canvas, line, start, mode);
-}
-c_draw_description :: (canvas : *Canvas, using ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
- if !description return true;
- if description.count > zone.width - 2 return false;
-
- top_or_bottom := !(description_pos & 4);
- y := ifx top_or_bottom then zone.top else zone.top + zone.height - 1;
-
- mode := style.text.default;
- if description_pos & 3 == {
- case 0; c_draw_line_ascii(canvas, description, .{zone.left + 1, y}, mode);
- case 1; c_draw_line_ascii(canvas, description, .{xx (zone.left + (zone.width - description.count) / 2), y}, mode);
- case 2; c_draw_line_ascii(canvas, description, .{xx (zone.left + zone.width - description.count - 1), y}, mode);
- case; assert(false);
- }
- return true;
-}
-
-vtable_handle_key : []#type (*UI_Elem, Key) -> (bool) = .[
- handle_key_none,
- handle_key_button,
- handle_key_none,
- handle_key_group,
- handle_key_select_list,
- handle_key_scene_manager,
- handle_key_popup_manager,
- handle_key_line_input,
- handle_key_scalable_group,
- handle_key_table,
- handle_key_none
-];
-handle_key :: (using ui_elem : *UI_Elem, key : Key) -> handled:bool {
- handle_proc := vtable_handle_key[ui_elem.type];
- assert(xx handle_proc);
-
- handled := handle_proc(ui_elem, key);
- // assert(cursor_state == .ON || cursor_state == .IN);
- if !handled && cursor_state == .ON {
- handled = handle_key_move(ui_elem, key);
- }
-
- if !handled && extra_handler.proc {
- handled = extra_handler.proc(key, extra_handler.data);
- }
- return handled;
-}
-handle_key_none :: (using ui_elem : *UI_Elem, key : Key) -> handled:bool { return false; }
-handle_key_move :: (using ui_elem : *UI_Elem, key : Key) -> handled:bool {
- __ui_master.blink_stage = 0;
- restart_clock_cycle();
-
- active_elem := ui_elem;
- assert(active_elem.cursor_state == .ON);
- try_move :: (new_elem : *UI_Elem) #expand {
- if new_elem {
- unset_active_recursive(`active_elem);
- set_active_recursive(new_elem);
- `active_elem = new_elem;
- }
- }
- if key == {
- case .LEFT; try_move(links.left);
- case .RIGHT; try_move(links.right);
- case .UP; try_move(links.top);
- case .DOWN; try_move(links.bottom);
- case .ESCAPE; try_move(links.outer);
- case .ENTER; try_move(links.inner);;
- }
- assert(active_elem.cursor_state == .ON);
- return ui_elem != active_elem;
-} \ No newline at end of file
diff --git a/kscurses/ui/group.jai b/kscurses/ui/group.jai
deleted file mode 100644
index 366c513..0000000
--- a/kscurses/ui/group.jai
+++ /dev/null
@@ -1,44 +0,0 @@
-UI_Group :: struct {
- #as using base_parent : UI_Parent = .{type = .GROUP};
-
- Element :: struct {
- ptr : *UI_Elem;
- zone : Ibox2;
- }
-
- elements : []Element;
-}
-set_sub_elements :: (group : *UI_Group, elements : ..UI_Group.Element) {
- group.elements = elements;
- for e : elements {
- e.ptr.parent = group;
- }
-}
-c_draw_group :: (canvas : *Canvas, ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
- using cast(*UI_Group) ui_elem;
- for e : elements {
- e_zone := e.zone;
- if !inside(e_zone, zone.size) return false;
- e_zone.corner += zone.corner;
- if !c_draw(canvas, e.ptr, e_zone, style) return false;
- }
- return true;
-}
-handle_key_group :: (ui_elem : *UI_Elem, key : Key) -> handled:bool {
- using cast(*UI_Group) ui_elem;
- assert(cursor_state == .ON || cursor_state == .OUTSIDE);
-
- handled := false;
- if cursor_state == .OUTSIDE {
- assert(xx active_element);
- {
- ok := false;
- for e : elements if e.ptr == active_element ok = true;
- assert(ok);
- }
- handled = handle_key(active_element, key);
- } else {
- assert(xx !active_element);
- }
- return handled;
-} \ No newline at end of file
diff --git a/kscurses/ui/line_input.jai b/kscurses/ui/line_input.jai
deleted file mode 100644
index 17823db..0000000
--- a/kscurses/ui/line_input.jai
+++ /dev/null
@@ -1,122 +0,0 @@
-Char_Type :: u8;
-UI_Line_Input :: struct {
- #as using base : UI_Elem = .{type = .LINE_INPUT};
- buffer : []Char_Type;
-
- // resizeable := false;
- ptr_left, ptr_right : int;
- offset : int;
-}
-
-handle_key_line_input :: (ui_elem : *UI_Elem, key : Key) -> bool {
- using ui_line_input := cast(*UI_Line_Input) ui_elem;
-
- handle_inner :: (using ui_line_input : *UI_Line_Input, key : Key) -> bool {
- if is_printable(key) {
- return add_char(ui_line_input, xx key);
- } else if key == {
- case .LEFT; #through;
- case .RIGHT;
- return move_ptr(ui_line_input, key);
- case .BACKSPACE;
- return remove_char_left(ui_line_input);
- case .ESCAPE;
- cursor_state = .ON;
- return true;
- }
- return false;
- }
-
- if cursor_state == .IN {
- return handle_inner(ui_line_input, key);
- } else if cursor_state == .ON && key == .ENTER {
- cursor_state = .IN;
- return true;
- }
-
- return false;
-}
-c_draw_line_input :: (canvas : *Canvas, ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
- using cast(*UI_Line_Input) ui_elem;
-
- fix_offset :: () #expand {
- if ptr_left - offset < 0 {
- offset = ptr_left;
- } else if ptr_left - offset >= zone.width {
- offset = ptr_left - zone.width + 1;
- }
- }
- fix_offset();
-
- left_part, right_part : string;
- left_part.data, left_part.count = buffer.data, ptr_left;
-
- right_part.data, right_part.count = buffer.data + ptr_right + 1, (buffer.count - ptr_right - 1);
-
- c_draw_line_ascii(canvas, left_part, zone, .{xx -offset, 0}, style.text.default);
- c_draw_line_ascii(canvas, right_part, zone, .{xx (ptr_left - offset), 0}, style.text.default);
-
- terminal_state.cursor = ifx cursor_state == .IN then zone.corner + ivec2.{xx(ptr_left - offset), 0} else .{-1, -1};
-
- return true;
-}
-
-init :: (using ui_line_input : *UI_Line_Input, max_length := 100) {
- buffer = NewArray(max_length, Char_Type);
- ptr_left, ptr_right = 0, max_length - 1;
-}
-add_char :: (using ui_line_input : *UI_Line_Input, c : Char_Type) -> bool {
- if ptr_left > ptr_right return false;
- buffer[ptr_left] = c;
- ptr_left += 1;
- return true;
-}
-remove_char_left :: (using ui_line_input : *UI_Line_Input) -> bool {
- if ptr_left == 0 return false;
- ptr_left -= 1;
- return true;
-}
-move_ptr :: (using ui_line_input : *UI_Line_Input, key : Key) -> bool {
- if key == {
- case .LEFT;
- if ptr_left > 0 {
- ptr_left -= 1;
- buffer[ptr_right] = buffer[ptr_left];
- ptr_right -= 1;
- return true;
- }
- case .RIGHT;
- if ptr_right < buffer.count-1 {
- ptr_right += 1;
- buffer[ptr_left] = buffer[ptr_right];
- ptr_left += 1;
- return true;
- }
- case;
- assert(false);
- }
- return false;
-}
-deinit :: (using ui_line_input : *UI_Line_Input) {
- array_free(buffer);
-}
-
-is_printable :: (key : Key) -> bool {
- code := cast(u64) key;
- return (code >= #char" " && code <= #char"~");
-}
-
-get_string :: (using ui_line_input : *UI_Line_Input, allocator := context.allocator) -> string {
- result : string;
- size := ptr_left + (buffer.count - ptr_right - 1);
- result.count = size;
- result.data = alloc(size, allocator);
-
- memcpy(result.data, buffer.data, ptr_left);
- memcpy(result.data + ptr_left, buffer.data + ptr_right + 1, buffer.count - ptr_right - 1);
- return result;
-}
-reset :: (using ui_line_input : *UI_Line_Input) {
- ptr_left = 0;
- ptr_right = buffer.count - 1;
-} \ No newline at end of file
diff --git a/kscurses/ui/links.jai b/kscurses/ui/links.jai
deleted file mode 100644
index dc8c667..0000000
--- a/kscurses/ui/links.jai
+++ /dev/null
@@ -1,94 +0,0 @@
-link_lr :: (el : *UI_Elem, er : *UI_Elem) {
- el.right = er;
- er.left = el;
-}
-link_tb :: (et : *UI_Elem, eb : *UI_Elem) {
- et.bottom = eb;
- eb.top = et;
-}
-link_oi :: (eo : *UI_Elem, ei : *UI_Elem) {
- eo.inner = ei;
- ei.outer = eo;
-}
-
-link_grid :: (size : ivec2, elements : ..*UI_Elem) {
- assert(size.x * size.y == elements.count);
- for y : 0..size.y-1 {
- for x : 0..size.x-2 {
- i := x + size.x * y;
- link_lr(elements[i], elements[i + 1]);
- }
- }
- for y : 0..size.y-2 {
- for x : 0..size.x-1 {
- i := x + size.x * y;
- link_tb(elements[i], elements[i + size.x]);
- }
- }
-}
-link_grid :: (size : ivec2, elements : []UI_Elem) {
- assert(size.x * size.y == elements.count);
- for y : 0..size.y-1 {
- for x : 0..size.x-2 {
- i := x + size.x * y;
- link_lr(*elements[i], *elements[i + 1]);
- }
- }
- for y : 0..size.y-2 {
- for x : 0..size.x-1 {
- i := x + size.x * y;
- link_tb(*elements[i], *elements[i + size.x]);
- }
- }
-}
-link_row :: (elements : ..*UI_Elem) {
- for i : 0..elements.count-2 {
- link_lr(elements[i], elements[i + 1]);
- }
-}
-link_column :: (elements : ..*UI_Elem) {
- for i : 0..elements.count-2 {
- link_tb(elements[i], elements[i + 1]);
- }
-}
-link_to_outer :: (eo : *UI_Elem, ei : ..*UI_Elem) {
- if ei.count > 0 {
- for ei {
- it.outer = eo;
- }
- eo.inner = ei[0];
- }
-
-}
-link_to_bottom :: (eb : *UI_Elem, et : ..*UI_Elem) {
- if et.count > 0 {
- for et {
- it.bottom = eb;
- }
- eb.top = et[0];
- }
-}
-link_to_top :: (et : *UI_Elem, eb : ..*UI_Elem) {
- if eb.count > 0 {
- for eb {
- it.top = et;
- }
- et.bottom = eb[0];
- }
-}
-link_to_right :: (er : *UI_Elem, el : ..*UI_Elem) {
- if el.count > 0 {
- for el {
- it.right = er;
- }
- er.left = el[0];
- }
-}
-link_to_left :: (el : *UI_Elem, er : ..*UI_Elem) {
- if er.count > 0 {
- for er {
- it.left = el;
- }
- el.right = er[0];
- }
-} \ No newline at end of file
diff --git a/kscurses/ui/master.jai b/kscurses/ui/master.jai
deleted file mode 100644
index 9cb0702..0000000
--- a/kscurses/ui/master.jai
+++ /dev/null
@@ -1,105 +0,0 @@
-UI_Master :: struct {
- style : UI_Style;
- canvas : Canvas;
- root : *UI_Elem;
- should_exit := false;
-
- blink_stage := 0;
-
- before_draw : struct {
- proc := (data : *void) { };
- data : *void;
- };
- extra_handle : struct {
- proc := (e : Event, data : *void) { };
- data : *void;
- };
-}
-__ui_master : UI_Master;
-
-
-set_main_scene :: (scene : UI_Scene) {
- __ui_master.root = scene.root;
- set_active_recursive(scene.entry);
-}
-run_singlethread_ui :: () {
- use_default_winch_handler();
- using __ui_master;
- while 1 {
- before_draw.proc(before_draw.data);
- if should_exit break;
- draw(*__ui_master);
- reset_temporary_storage();
- handle_key(*__ui_master, ks_getch(block = false));
- if should_exit break;
- }
- deinit(*__ui_master);
-}
-run_multithread_ui :: () {
- use_events(tick_duration_ms = 530);
- __event_handler = .{
- proc = (e : Event, __data : *void) {
- using __ui_master;
- if e.type == {
- case .KEY;
- handle_key(*__ui_master, e.key);
- case .TICK;
- #if ENABLE_UI_BLINKING __ui_master.blink_stage = xx !__ui_master.blink_stage;
- }
- extra_handle.proc(e, extra_handle.data);
- },
- data = null
- }; defer __event_handler = .{};
-
- using __ui_master;
-
- while 1 {
- before_draw.proc(before_draw.data);
- if should_exit break;
- processed := wait_and_process_events();
- if should_exit break;
- if processed {
- draw(*__ui_master);
- reset_temporary_storage();
- }
- }
- deinit(*__ui_master);
-}
-
-#scope_file
-draw :: (using ui_master : *UI_Master) {
- new_zone := Ibox2.{size = terminal_state.size};
- builder : String_Builder;
-
- if new_zone != canvas.zone {
- resize_clear(*canvas, new_zone);
- }
- ok := c_draw(*canvas, root, canvas.zone, *style);
- if ok {
- ks_draw_canvas(*canvas);
- } else {
- b_mode_set(*builder, style.text.default);
- b_clear_screen(*builder);
- b_print(*builder, .{0, 0}, style.text.debug, "screen to small: %x%", terminal_state.size.x, terminal_state.size.y);
- }
- b_cursor_set_visibility(*builder, terminal_state.cursor != ivec2.{-1, -1});
- if terminal_state.cursor != ivec2.{-1, -1} then b_move_cursor(*builder, terminal_state.cursor);
-
- ks_write(builder_to_string(*builder, allocator = temp));
-}
-handle_key :: (using ui_master : *UI_Master, key : Key) {
- handled := handle_key(root, key);
- if handled return;
-
- if key == {
- case .ESCAPE; {
- should_exit = true;
- unset_active_recursive(__last_set);
- }
- case; if key != .READ_ERROR ui_bell();
- }
-}
-deinit :: (using ui_master : *UI_Master) {
- deinit(*canvas);
- __ui_master = .{};
-} \ No newline at end of file
diff --git a/kscurses/ui/parent.jai b/kscurses/ui/parent.jai
deleted file mode 100644
index af459de..0000000
--- a/kscurses/ui/parent.jai
+++ /dev/null
@@ -1,33 +0,0 @@
-UI_Parent :: struct {
- #as using base : UI_Elem;
- active_element : *UI_Elem;
-}
-
-__last_set : *UI_Elem;
-
-set_active_recursive :: (ui_elem : *UI_Elem) {
- assert(!__last_set); __last_set = ui_elem;
- assert(ui_elem.cursor_state == .OUTSIDE); ui_elem.cursor_state = .ON;
-
- current := ui_elem;
- while 1 {
- parent := current.parent;
- if !parent break;
- assert(!parent.active_element);
- parent.active_element = current;
- current = xx parent;
- }
-}
-unset_active_recursive :: (ui_elem : *UI_Elem) {
- assert(__last_set == ui_elem); __last_set = null;
- assert(ui_elem.cursor_state == .ON); ui_elem.cursor_state = .OUTSIDE;
-
- current := ui_elem;
- while 1 {
- parent := current.parent;
- if !parent break;
- assert(parent.active_element == current);
- parent.active_element = null;
- current = xx parent;
- }
-} \ No newline at end of file
diff --git a/kscurses/ui/popup_manager.jai b/kscurses/ui/popup_manager.jai
deleted file mode 100644
index 704ad49..0000000
--- a/kscurses/ui/popup_manager.jai
+++ /dev/null
@@ -1,65 +0,0 @@
-MAX_POPUP_LEVES :: 10;
-
-UI_Popup_Manager :: struct {
- #as using base_parent : UI_Parent = .{type = .POPUP_MANAGER, box_type = .NONE};
-
- layers : [MAX_POPUP_LEVES]UI_Popup;
-
- layers_count := 0;
-}
-
-set_background :: (using ui_popup_manager : *UI_Popup_Manager, scene : UI_Scene) {
- assert(layers_count == 0);
- layers[0] = .{root = scene.root, entry = scene.entry};
- scene.root.parent = xx ui_popup_manager;
- layers_count = 1;
-}
-
-handle_key_popup_manager :: (ui_elem : *UI_Elem, key : Key) -> handled:bool {
- using ui_popup_manager := cast(*UI_Popup_Manager) ui_elem;
- assert(layers_count > 0, "0 layers in popup manager");
- if !handle_key(active_element, key) {
- if key == .ESCAPE && layers_count > 1 {
- pop(ui_popup_manager);
- return true;
- } else {
- return false;
- }
- } else {
- return true;
- }
-}
-
-c_draw_popup_manager :: (canvas : *Canvas, ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
- using ui_popup_manager := cast(*UI_Popup_Manager) ui_elem;
- assert(layers_count > 0, "0 layers in popup manager");
- for i : 0..layers_count-1 {
- popup_zone := zone;
- ok : bool;
- if layers[i].size != .{-1, -1} then {
- popup_zone, ok = fit_in_center(zone, layers[i].size);
- if !ok return false;
- }
- if !c_draw(canvas, layers[i].root, popup_zone, style) return false;
- }
- return true;
-}
-
-pop :: (using ui_popup_manager : *UI_Popup_Manager) {
- assert(layers_count > 1, "can't pop background");
- layers_count -= 1;
- unset_active_recursive(__last_set);
- layers[layers_count].root.parent = null;
- set_active_recursive(layers[layers_count - 1].entry);
-
-}
-push :: (using ui_popup_manager : *UI_Popup_Manager, scene : UI_Popup) {
- assert(layers_count < MAX_POPUP_LEVES, "too much popup layers");
- unset_active_recursive(__last_set);
-
- layers[layers_count] = scene;
- scene.root.parent = xx ui_popup_manager;
- set_active_recursive(layers[layers_count].entry);
-
- layers_count += 1;
-} \ No newline at end of file
diff --git a/kscurses/ui/progress_bar.jai b/kscurses/ui/progress_bar.jai
deleted file mode 100644
index 23d7dc9..0000000
--- a/kscurses/ui/progress_bar.jai
+++ /dev/null
@@ -1,37 +0,0 @@
-UI_Progress_Bar :: struct {
- #as using base : UI_Elem = .{type = .PROGRESS_BAR};
-
- value : float;
- value_ptr : *float;
-
- draw_proc := (percent : float, pix_coord : float) -> Vector3 { return ifx pix_coord < percent then Vector3.{0, 1, 0} else .{0, 0, 0}; }
- show_percent := true;
-}
-
-set_value :: (progress_bar : *UI_Progress_Bar, value : float) {
- progress_bar.value = value;
- progress_bar.value_ptr = null;
-}
-set_value_ptr :: (progress_bar : *UI_Progress_Bar, value_ptr : *float) {
- progress_bar.value_ptr = value_ptr;
-}
-
-c_draw_progress_bar :: (canvas : *Canvas, ui_elem : *UI_Elem, _zone : Ibox2, style : *UI_Style) -> bool {
- using progress_bar := cast(*UI_Progress_Bar) ui_elem;
- value_current := ifx value_ptr then <<value_ptr else value;
- zone := _zone;
- if zone.width < 6 return false;
- if show_percent {
- percent_str := tprint("%1%%", formatFloat(value_current * 100, width = 4, trailing_width = 1, zero_removal = .NO));
- c_draw_line_ascii(canvas, percent_str, zone, .{zone.width - 5, zone.height / 2}, style.text.default);
- zone.width -= 5;
- }
- for x : 0..zone.width-1 {
- pix_coord := (x + .5) / zone.width;
- char := find_best_char(draw_proc(value_current, pix_coord), true);
- for y : 0..zone.height-1 {
- c_putchar(canvas, char, zone.corner + ivec2.{x, y});
- }
- }
- return true;
-}
diff --git a/kscurses/ui/scalable_group.jai b/kscurses/ui/scalable_group.jai
deleted file mode 100644
index 6c12bcc..0000000
--- a/kscurses/ui/scalable_group.jai
+++ /dev/null
@@ -1,88 +0,0 @@
-UI_Scalable_Group :: struct {
- #as using base_parent : UI_Parent = .{type = .SCALABLE_GROUP};
-
- Scale_Params :: struct {
- // using metrics : struct {
- x1, y1, x2, y2 : s32;
- #place x1; v1 : ivec2;
- #place x2; v2 : ivec2;
- // };
- scale_mode : enum u8 {
- ANCHOR_TL :: 0; // v1 - size, v2 - offset from corner (both positive)
- ANCHOR_TR :: 1;
- ANCHOR_BL :: 2;
- ANCHOR_BR :: 3;
-
- STRETCH_T :: 4; // x1/2 - left/right offset, y1 - top offset, y2 - height
- STRETCH_B :: 5; // x1/2 - left/right offset, y1 - bottom offset, y2 - height
- STRETCH_L :: 6; // y1/2 - top/bottom offset, x1 - left offset, x2 - width
- STRETCH_R :: 7; // y1/2 - top/bottom offset, x1 - right offset, x2 - width
-
- STRETCH_C :: 8; // v1 - top-left offset, v2 - bottom-right offset
- CENTERIZE :: 9; // v1 - size, v2 - offset from center(signed)
-
- FIT_EXACT :: 10; //TODO
- FIT_ROUGH :: 11;
- } = .ANCHOR_TL;
- }
-
- Element :: struct {
- ptr : *UI_Elem;
- scale_params : Scale_Params;
- }
-
- elements : []Element;
-}
-
-get_zone :: (using zone : Ibox2, using scale_params : UI_Scalable_Group.Scale_Params) -> Ibox2 {
- if scale_mode == {
- case .ANCHOR_TL; return .{corner = corner + v2, size = v1};
- case .ANCHOR_TR; return .{corner = .{left + width - x2 - x1, top + y2}, size = v1};
- case .ANCHOR_BL; return .{corner = .{left + x2, top + height - y2 - y1}, size = v1};
- case .ANCHOR_BR; return .{corner = .{left + width - x2 - x1, top + height - y2 - y1}, size = v1};
-
- case .STRETCH_T; return .{corner = .{left + x1, top + y1}, size = .{width - x1 - x2, y2}};
- case .STRETCH_B; return .{corner = .{left + x1, top + height - y1 - y2}, size = .{width - x1 - x2, y2}};
- case .STRETCH_L; return .{corner = .{left + x1, top + y1}, size = .{x2, height - y1 - y2}};
- case .STRETCH_R; return .{corner = .{left + width - x1 - x2, top + y1}, size = .{x2, height - y1 - y2}};
-
- case .STRETCH_C; return .{corner = corner + v1, size = size - v1 - v2};
- case .CENTERIZE; return .{corner = corner + (size - v1) / 2 + v2 , size = v1};
- }
- assert(false);
- return .{};
-}
-
-set_sub_elements :: (group : *UI_Scalable_Group, elements : ..UI_Scalable_Group.Element) {
- group.elements = elements;
- for e : elements {
- e.ptr.parent = group;
- }
-}
-c_draw_scalable_group :: (canvas : *Canvas, ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
- using cast(*UI_Scalable_Group) ui_elem;
- for e : elements {
- e_zone := get_zone(zone, e.scale_params);
- if !inside(e_zone, zone) return false;
- if !c_draw(canvas, e.ptr, e_zone, style) return false;
- }
- return true;
-}
-handle_key_scalable_group :: (ui_elem : *UI_Elem, key : Key) -> handled:bool {
- using cast(*UI_Scalable_Group) ui_elem;
- assert(cursor_state == .ON || cursor_state == .OUTSIDE);
-
- handled := false;
- if cursor_state == .OUTSIDE {
- assert(xx active_element);
- {
- ok := false;
- for e : elements if e.ptr == active_element ok = true;
- assert(ok);
- }
- handled = handle_key(active_element, key);
- } else {
- assert(xx !active_element);
- }
- return handled;
-} \ No newline at end of file
diff --git a/kscurses/ui/scene_manager.jai b/kscurses/ui/scene_manager.jai
deleted file mode 100644
index 1caff8b..0000000
--- a/kscurses/ui/scene_manager.jai
+++ /dev/null
@@ -1,48 +0,0 @@
-UI_Scene :: struct {
- root : *UI_Elem;
- entry : *UI_Elem;
-}
-UI_Popup :: struct {
- root : *UI_Elem;
- entry : *UI_Elem;
- size : ivec2 = .{-1, -1};
-}
-
-UI_Scene_Manager :: struct {
- #as using base_parent : UI_Parent = .{type = .SCENE_MANAGER, box_type = .NONE};
- scenes : []UI_Scene;
-}
-
-set_sub_elements :: (ui_scene_manager : *UI_Scene_Manager, scenes : ..UI_Scene) {
- ui_scene_manager.scenes = scenes;
- for ui_scene_manager.scenes it.root.parent = ui_scene_manager;
-}
-
-handle_key_scene_manager :: (ui_elem : *UI_Elem, key : Key) -> handled:bool {
- using cast(*UI_Scene_Manager) ui_elem;
- assert(cursor_state == .ON || cursor_state == .OUTSIDE);
-
- handled := false;
- if cursor_state == .OUTSIDE {
- assert(xx active_element);
- {
- ok := false;
- for s : scenes if s.root == active_element ok = true;
- assert(ok);
- }
- handled = handle_key(active_element, key);
- } else {
- assert(xx !active_element);
- }
- return handled;
-}
-
-c_draw_scene_manager :: (canvas : *Canvas, ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
- using cast(*UI_Scene_Manager) ui_elem;
- return c_draw(canvas, active_element, zone, style);
-}
-
-switch_scene :: (using ui_scene_manager : *UI_Scene_Manager, id : int) {
- unset_active_recursive(__last_set);
- set_active_recursive(scenes[id].entry);
-}
diff --git a/kscurses/ui/select_list.jai b/kscurses/ui/select_list.jai
deleted file mode 100644
index 8c338c6..0000000
--- a/kscurses/ui/select_list.jai
+++ /dev/null
@@ -1,79 +0,0 @@
-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
diff --git a/kscurses/ui/style.jai b/kscurses/ui/style.jai
deleted file mode 100644
index 4715860..0000000
--- a/kscurses/ui/style.jai
+++ /dev/null
@@ -1,118 +0,0 @@
-mode_black_and_white :: #run make_graphics_mode(foreground = .BRIGHT_WHITE, background = .BLACK);
-
-Box_Style :: struct {
- c, tb, lr, tl, tr, bl, br, tbl, tbr, tlr, blr, tblr : u32;
- mode_border, mode_space, mode_no_border := mode_black_and_white;
-}
-
-box_style_active :: Box_Style.{
- c = #run utf8(" "),
- tb = #run utf8("║"),
- lr = #run utf8("═"),
- tl = #run utf8("╝"),
- tr = #run utf8("╚"),
- bl = #run utf8("╗"),
- br = #run utf8("╔"),
- tbl = #run utf8("╣"),
- tbr = #run utf8("╠"),
- tlr = #run utf8("╩"),
- blr = #run utf8("╦"),
- tblr = #run utf8("╬"),
- mode_no_border = #run make_graphics_mode(foreground = .BRIGHT_WHITE, background = .BRIGHT_BLACK)
-};
-box_style_passive :: Box_Style.{
- c = #run utf8(" "),
- tb = #run utf8("│"),
- lr = #run utf8("─"),
- tl = #run utf8("┘"),
- tr = #run utf8("└"),
- bl = #run utf8("┐"),
- br = #run utf8("┌"),
- tbl = #run utf8("┤"),
- tbr = #run utf8("├"),
- tlr = #run utf8("┴"),
- blr = #run utf8("┬"),
- tblr = #run utf8("┼")
-};
-
-UI_Style :: struct {
- box : struct {
- default := box_style_passive;
- cursor := box_style_active;
- }
-
- mode_main := mode_black_and_white;
-
- text : struct {
- default := mode_black_and_white;
- cursor := #run make_graphics_mode(background = .BRIGHT_BLACK);
- selection := #run make_graphics_mode(background = .YELLOW);
- cursor_and_selection := #run make_graphics_mode(background = .BRIGHT_YELLOW);
-
- debug := #run make_graphics_mode(foreground = .BLACK, background = .BRIGHT_GREEN);
- }
-}
-
-c_box :: (canvas : *Canvas, zone : Ibox2, using box_style : Box_Style, border := true) -> bool {
- if !inside(ifx border then ivec2.{2, 2} else ivec2.{0, 0}, zone.size) return false;
- assert(inside(zone, canvas.zone));
- charset : [9]u32;
- if border {
- charset[0], charset[1], charset[2], charset[3], charset[4], charset[5], charset[6], charset[7], charset[8] = br, lr, bl, tb, c, tb, tr, lr, tl;
- } else {
- charset[0], charset[1], charset[2], charset[3], charset[4], charset[5], charset[6], charset[7], charset[8] = c, c, c, c, c, c, c, c, c;
- }
-
- for y : 0..zone.height-1 {
- yi := ifx y == 0 then 0 else ifx y == zone.height - 1 then 2 else 1;
- for x : 0..zone.width-1 {
- xi := ifx x == 0 then 0 else ifx x == zone.width - 1 then 2 else 1;
- i := yi * 3 + xi;
- c_putchar(canvas, .{code = charset[i], mode = mode_border}, zone.corner + ivec2.{xx x, xx y});
- }
- }
- return true;
-}
-
-b_box :: (builder : *String_Builder, zone : Ibox2, using charset := box_style_passive, mode := Graphics_Mode.{}, clear_center := true, border := true) {
- //assert(inside(zone, terminal_state.size));
-
- charset : [9]u32;
- if border {
- charset = .[br, lr, bl, tb, c, tb, tr, lr, tl];
- } else {
- charset = .[c, c, c, c, c, c, c, c, c];
- }
-
- b_move_cursor(builder, zone.corner);
- b_mode_set(builder, mode);
-
- for y : 0..zone.height-1 {
- yi := ifx y == 0 then 0 else ifx y == zone.height - 1 then 2 else 1;
- b_move_cursor(builder, .{zone.corner.x, zone.corner.y + y});
-
- if !clear_center && yi == 1 {
- b_putchar(builder, charset[3]);
- b_move_cursor(builder, .{zone.corner.x + zone.width - 1, zone.corner.y + y});
- b_putchar(builder, charset[5]);
- } else {
- for x : 0..zone.width-1 {
- xi := ifx x == 0 then 0 else ifx x == zone.width - 1 then 2 else 1;
- i := yi * 3 + xi;
- b_putchar(builder, charset[i]);
- }
- }
-
- }
-}
-t_box :: (zone : Ibox2, charset := box_style_passive, clear_center := false) -> string {
- builder := String_Builder.{allocator=temp};
- b_box(*builder, zone, charset, make_graphics_mode(), clear_center);
- return builder_to_string(*builder, temp);
-}
-ks_box :: (zone : Ibox2, charset := box_style_passive, clear_center := false) {
- ks_write(t_box(zone, charset, clear_center));
-}
-
-
-
diff --git a/kscurses/ui/table.jai b/kscurses/ui/table.jai
deleted file mode 100644
index dadc1c3..0000000
--- a/kscurses/ui/table.jai
+++ /dev/null
@@ -1,87 +0,0 @@
-UI_Table :: struct {
- #as using base : UI_Elem = .{type = .TABLE};
-
- // auto_scale := false;
- // metrics : []int;
- columns := 0;
- rows := 0;
-
- // description : []string;
- content : [..]string;
-
- cursor, offset := 0;
- show_cursor := false;
-}
-
-handle_key_table :: (ui_elem : *UI_Elem, key : Key) -> handled:bool {
- return false;
-}
-
-c_draw_table_content :: (canvas : *Canvas, using ui_table : *UI_Table, zone : Ibox2, style : *UI_Style, rows_visible : int) -> bool {
- for y : 0..zone.height-1 {
- is_selected := y == cursor && show_cursor;
- mode := ifx is_selected then style.text.selection else style.text.default;
- separator_char := Char.{code = style.box.default.tb, mode = mode};
-
- if zone.width < columns {
- for x : 0..zone.width {
- c_putchar(canvas, separator_char, zone.corner + ivec2.{xx x, xx y});
- }
- } else {
- i := y + offset;
- for x : 0..columns-1 {
- l := (zone.width + 1) * x / columns;
- r := (zone.width + 1) * (x + 1) / columns - 1;
- if y < rows_visible {
- field_content := content[i * columns + x];
- field_content.count = min(field_content.count, r - l);
- c_draw_line_ascii(canvas, field_content, zone, .{xx l, xx y}, mode);
- }
- if x != columns-1 c_putchar(canvas, separator_char, zone.corner + ivec2.{xx r, xx y});
- }
- }
- }
- return true;
-}
-
-c_draw_table :: (canvas : *Canvas, ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
- using ui_table := cast(*UI_Table) ui_elem;
- assert(rows * columns == content.count);
-
- rows_visible := min(cast(int) zone.height, rows - offset);
-
- fix_offset :: () #expand {
- if cursor - offset < 0 {
- offset = cursor;
- } else if cursor - offset >= zone.height {
- offset = cursor - zone.height + 1;
- }
- }
- fix_offset();
-
- ok := c_draw_table_content(canvas, ui_table, zone, style, rows_visible);
- return ok;
-}
-init :: (table : *UI_Table, description : []string) {
- table.columns = description.count;
- table.description = description;
-}
-init :: (table : *UI_Table, columns : int) {
- table.columns = columns;
-}
-
-add_line :: (using table : *UI_Table, line : ..string) {
- assert(line.count == columns);
- array_add(*content, ..line);
- rows += 1;
-}
-deinit :: (using table : *UI_Table) {
- array_free(content);
-}
-
-// TODO
-// variadic columns count, different content types
-// empty separator
-// automatic scale, as option
-// description
-// align content left/right/center \ No newline at end of file
diff --git a/kscurses/ui/text_buf.jai b/kscurses/ui/text_buf.jai
deleted file mode 100644
index 689bb98..0000000
--- a/kscurses/ui/text_buf.jai
+++ /dev/null
@@ -1,15 +0,0 @@
-UI_Text_Buf :: struct {
- #as using base : UI_Elem = .{type = .TEXT_BUF};
- lines : []string;
- lines_dynamic : *[]string;
-}
-c_draw_textbuf :: (canvas : *Canvas, ui_elem : *UI_Elem, zone : Ibox2, style : *UI_Style) -> bool {
- using cast(*UI_Text_Buf) ui_elem;
-
- lines_to_draw := ifx lines_dynamic then <<lines_dynamic else lines;
- for l, y : lines_to_draw {
- if y >= zone.height break;
- c_draw_line_ascii(canvas, l, zone, .{0, xx y}, style.text.default);
- }
- return true;
-}
diff --git a/kscurses/ui/tilemap.jai b/kscurses/ui/tilemap.jai
deleted file mode 100644
index 73f96e5..0000000
--- a/kscurses/ui/tilemap.jai
+++ /dev/null
@@ -1,20 +0,0 @@
-UI_Tilemap :: struct {
- #as using base : UI_Elem = .{type = .TILEMAP};
-
- map_size : ivec2;
- map : []u64;
- tileset : *Tileset;
-
- background : Char; // if not set, then box's filler instead
-}
-Tileset :: struct {
- tile_size : ivec2;
- tiles_count : int;
- data : []Char;
- // code = 0 -> skip entire character
- // fcol/bcol = .DEFAULT -> skip foreground/background
-}
-c_draw_tile :: (canvas : *Canvas, tileset : *Tileset, offset : ivec2, id : u64, cutoff : Ibox2) {
-
-}
-