From ab8522fbe1f893a7998c8d470a7bb8b0fd40c02c Mon Sep 17 00:00:00 2001 From: Able Date: Wed, 6 Nov 2024 11:43:40 -0600 Subject: [PATCH] widget UI --- sysdata/libraries/horizon_api/src/lib.hb | 1 + sysdata/libraries/horizon_api/src/ui.hb | 50 ++++++++++++++++++++ sysdata/libraries/horizon_api/src/widgets.hb | 41 ++++++++++++++-- sysdata/programs/horizon/src/main.hb | 38 ++++----------- 4 files changed, 97 insertions(+), 33 deletions(-) create mode 100644 sysdata/libraries/horizon_api/src/ui.hb diff --git a/sysdata/libraries/horizon_api/src/lib.hb b/sysdata/libraries/horizon_api/src/lib.hb index 1db3411ef..72f58d10b 100644 --- a/sysdata/libraries/horizon_api/src/lib.hb +++ b/sysdata/libraries/horizon_api/src/lib.hb @@ -6,6 +6,7 @@ render := @use("../../../libraries/render/src/lib.hb") input := @use("../../intouch/src/lib.hb") widgets := @use("widgets.hb") +ui := @use("ui.hb") WindowID := struct { host_id: int, diff --git a/sysdata/libraries/horizon_api/src/ui.hb b/sysdata/libraries/horizon_api/src/ui.hb new file mode 100644 index 000000000..93fae2d8e --- /dev/null +++ b/sysdata/libraries/horizon_api/src/ui.hb @@ -0,0 +1,50 @@ +stn := @use("../../../libraries/stn/src/lib.hb"); +.{string, log} := stn; +.{Vec2} := stn.math + +render := @use("../../../libraries/render/src/lib.hb"); +.{Surface} := render; +.{Font} := render.text + +UI := struct { + raw: ^u8, + raw_length: uint, + is_dirty: bool, + surface: Surface, +} + +render_ui := fn(surface: Surface, ui: UI): void { + if ui.is_dirty { + render.clear(ui.surface, render.black) + ui.is_dirty = false + } + pos := Vec2(uint).(0, 0) + render.put_surface(surface, ui.surface, pos, false) +} + +sexpr_parser := fn(sexpr: ^u8): UI { + cursor := sexpr + paren_balance := 0 + loop { + if *cursor == 0 { + if paren_balance != 0 { + log.error("Unbalanced Parens\0") + } + break + } else if *cursor == 40 { + log.info("Open paren\0") + paren_balance += 1 + } else if *cursor == 41 { + log.info("Closed paren\0") + paren_balance -= 1 + } + + cursor += 1 + } + + length := string.length(sexpr) + + ui_surface := render.new_surface(100, 100) + + return UI.(sexpr, length, true, ui_surface) +} \ No newline at end of file diff --git a/sysdata/libraries/horizon_api/src/widgets.hb b/sysdata/libraries/horizon_api/src/widgets.hb index 04574f28a..9bf56f753 100644 --- a/sysdata/libraries/horizon_api/src/widgets.hb +++ b/sysdata/libraries/horizon_api/src/widgets.hb @@ -1,6 +1,13 @@ // Widget types // End types +stn := @use("../../../libraries/stn/src/lib.hb"); +.{string, log} := stn; +.{Vec2} := stn.math + +render := @use("../../../libraries/render/src/lib.hb"); +.{Surface} := render; +.{Font} := render.text LayoutChildHorizontalFirst := 0 LayoutChildVerticalFirst := 1 @@ -12,9 +19,33 @@ Size := struct { max_height: int, } -Widget := struct { - size: Size, - clickable: bool, - layout: u8, - a: bool, +Label := struct { + is_dirty: bool, + surface: Surface, + text: ^u8, + text_length: uint, +} + +set_label_text := fn(label: Label, text: ^u8): void { + text_length := string.length(text) + + label.is_dirty = true + label.text = text + label.text_length = text_length +} + +render_label_to_surface := fn(surface: Surface, label: Label, font: Font, pos: Vec2(uint)): void { + if label.is_dirty { + render.clear(label.surface, render.black) + render.put_text(label.surface, font, .(0, 0), render.white, label.text) + } + render.put_surface(surface, label.surface, pos, false) + render.sync(surface) +} + +new_label := fn(text: ^u8): Label { + text_surface := render.new_surface(100, 20) + text_length := string.length(text) + label := Label.(true, text_surface, text, text_length) + return label } \ No newline at end of file diff --git a/sysdata/programs/horizon/src/main.hb b/sysdata/programs/horizon/src/main.hb index 5535bcd3b..c33882e60 100644 --- a/sysdata/programs/horizon/src/main.hb +++ b/sysdata/programs/horizon/src/main.hb @@ -2,37 +2,15 @@ stn := @use("../../../libraries/stn/src/lib.hb"); .{string, memory, buffer, random, log} := stn; .{Vec2} := stn.math -horizon_api := @use("../../../libraries/horizon_api/src/lib.hb") +horizon_api := @use("../../../libraries/horizon_api/src/lib.hb"); +.{new_label, render_label_to_surface, set_label_text} := horizon_api.widgets; +.{sexpr_parser, render_ui} := horizon_api.ui render := @use("../../../libraries/render/src/lib.hb"); .{Surface} := render; .{Font} := render.text intouch := @use("../../../libraries/intouch/src/lib.hb") -Label := struct {is_dirty: bool, surface: Surface, text: ^u8, text_length: uint} -set_label_text := fn(label: Label, text: ^u8, text_length: uint): void { - label.is_dirty = true - label.text = text - label.text_length = text_length -} - -render_label_to_surface := fn(surface: Surface, label: Label, font: Font): void { - if label.is_dirty { - render.clear(label.surface, render.blue) - render.put_text(label.surface, font, .(0, 0), render.red, "hi\0") - } - pos := Vec2(uint).(100, 100) - render.put_surface(surface, label.surface, pos, false) - render.sync(surface) -} - -new_label := fn(text: ^u8): Label { - text_surface := render.new_surface(100, 16) - text_length := string.length(text) - label := Label.(true, text_surface, text, text_length) - return label -} - Window := struct { // TODO: Replace this with widgets implicit_framebuffer: render.Surface, @@ -64,6 +42,8 @@ main := fn(): int { mouse_x := 0 mouse_y := 0 text_label := new_label("Hi\0") + widgets := "()\0" + ui := sexpr_parser(widgets) loop { // Clear the screen @@ -87,6 +67,7 @@ main := fn(): int { if mouse_event != null { mouse_x += mouse_event.x_change mouse_y += mouse_event.y_change + set_label_text(text_label, "Mouse Moved\0") } // render mouse render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), render.white) @@ -96,9 +77,10 @@ main := fn(): int { // TODO: Get windows out of a collection and iter through render.put_rect(screen, .(0, 0), .(screen.width - 1, screen.height - 1), render.white) - - render_label_to_surface(screen, text_label, font) - + { + pos := Vec2(uint).(1, screen.height - 21) + render_label_to_surface(screen, text_label, font, pos) + } // Sync the screen render.sync(screen) }