aboutsummaryrefslogtreecommitdiff
path: root/kscurses/ui/scalable_group.jai
diff options
context:
space:
mode:
Diffstat (limited to 'kscurses/ui/scalable_group.jai')
-rw-r--r--kscurses/ui/scalable_group.jai88
1 files changed, 88 insertions, 0 deletions
diff --git a/kscurses/ui/scalable_group.jai b/kscurses/ui/scalable_group.jai
new file mode 100644
index 0000000..6c12bcc
--- /dev/null
+++ b/kscurses/ui/scalable_group.jai
@@ -0,0 +1,88 @@
+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