From 00299bec0bffbc8fe5a654c134443544ff168637 Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Sat, 16 Aug 2025 10:10:06 +0200 Subject: [PATCH] fix calculator demo turns out it was an incorrect handling of scissor test --- TODO | 12 ++++++- lib/ugui.c3l/src/ugui_button.c3 | 13 +++---- lib/ugui.c3l/src/ugui_cmd.c3 | 36 ++++++++++++++++--- lib/ugui.c3l/src/ugui_core.c3 | 5 +++ src/main.c3 | 61 +++++++++++++++++---------------- 5 files changed, 85 insertions(+), 42 deletions(-) diff --git a/TODO b/TODO index 07b3bfb..f1e191d 100644 --- a/TODO +++ b/TODO @@ -56,12 +56,22 @@ to maintain focus until mouse release (fix scroll bars) [ ] Consider a multi-pass recursive approach to layout (like https://github.com/nicbarker/clay) instead of the curren multi-frame approach. [ ] Implement column/row sizing (min, max) +[ ] Implement a way to size the element as the current row/column size + * +-------------+ + * | | + * +-------------+ + * +--+ + * | | + * +--+ + * <-------------> + * column size + See the calculator example for why it is useful [ ] Find a way to concile pixel measurements to the mm ones used in css, for example in min/max sizing of elements [ ] Center elements to div (center children_bounds to the center of the div bounds and shift the origin accordingly) [x] Use containing_rect() in position_element() to skip some computing and semplify the function [x] Rename position_element() to layout_element() -[ ] Make functions to mark rows/columns as full, to fix the calculator demo +[x] Make functions to mark rows/columns as full, to fix the calculator demo ## Input diff --git a/lib/ugui.c3l/src/ugui_button.c3 b/lib/ugui.c3l/src/ugui_button.c3 index 064a350..f2132be 100644 --- a/lib/ugui.c3l/src/ugui_button.c3 +++ b/lib/ugui.c3l/src/ugui_button.c3 @@ -64,7 +64,7 @@ fn ElemEvents? Ctx.button_id(&ctx, Id id, String label, String icon) .h = (short)max(icon_size.h, content_bounds.h) }; icon_bounds = icon_size.center_to(icon_bounds); - + bool is_active = ctx.elem_focus(elem) || elem.events.mouse_hover; Style s = *style; if (is_active) { @@ -73,11 +73,12 @@ fn ElemEvents? Ctx.button_id(&ctx, Id id, String label, String icon) } ctx.push_rect(elem.bounds, parent.div.z_index, &s)!; - ctx.push_sprite(icon_bounds, sprite.uv(), ctx.sprite_atlas.id, parent.div.z_index, type: sprite.type)!; -// Style ss = {.bg = 0x000000ffu.@to_rgba()}; -// ctx.push_rect(content_bounds, parent.div.z_index, &ss)!; - ctx.push_string(text_bounds, label, parent.div.z_index, style.fg)!; - + if (icon != "") { + ctx.push_sprite(icon_bounds, sprite.uv(), ctx.sprite_atlas.id, parent.div.z_index, type: sprite.type)!; + } + if (label != "") { + ctx.push_string(text_bounds, label, parent.div.z_index, style.fg)!; + } return elem.events; } diff --git a/lib/ugui.c3l/src/ugui_cmd.c3 b/lib/ugui.c3l/src/ugui_cmd.c3 index 4d6e09c..463605e 100644 --- a/lib/ugui.c3l/src/ugui_cmd.c3 +++ b/lib/ugui.c3l/src/ugui_cmd.c3 @@ -58,7 +58,26 @@ fn int Cmd.compare_to(Cmd a, Cmd b) // implement the Printable interface fn usz? Cmd.to_format(Cmd* cmd, Formatter *f) @dynamic { - return f.printf("Cmd{ type: %s, z_index: %d }", cmd.type, cmd.z_index); + usz ret; + + ret += f.printf("Cmd{ type: %s, z_index: %d, ", cmd.type, cmd.z_index)!; + switch (cmd.type) { + case CMD_RECT: + ret += f.print("CmdRect")!; + ret += io::struct_to_format(cmd.rect, f, false)!; + case CMD_SCISSOR: + ret += f.print("CmdScissor")!; + ret += io::struct_to_format(cmd.scissor, f, false)!; + case CMD_SPRITE: + ret += f.print("CmdSprite")!; + ret += io::struct_to_format(cmd.sprite, f, false)!; + case CMD_UPDATE_ATLAS: + ret += f.print("CmdUpdateAtlas")!; + ret += io::struct_to_format(cmd.update_atlas, f, false)!; + } + + ret += f.print("}")!; + return ret; } macro bool cull_rect(Rect rect, Rect clip = {0,0,short.max,short.max}) @@ -77,7 +96,13 @@ macro Ctx.push_cmd(&ctx, Cmd *cmd, int z_index) case CMD_SPRITE: rect = cmd.sprite.rect; default: return ctx.cmd_queue.enqueue(cmd); } - if (cull_rect(rect, ctx.div_scissor)) return; + if (cull_rect(rect, ctx.div_scissor)) { + io::print("NOPE: "); + io::print(cmd.rect.rect); + io::printn(cmd.z_index); +// unreachable(); + return; + } return ctx.cmd_queue.enqueue(cmd); } @@ -90,6 +115,8 @@ fn void? Ctx.push_scissor(&ctx, Rect rect, int z_index) ctx.push_cmd(&sc, z_index)!; } +fn void? Ctx.reset_scissor(&ctx, int z_index) => ctx.push_cmd(&&(Cmd){.type=CMD_SCISSOR,.scissor.rect=ctx.div_scissor}, z_index)!; + fn void? Ctx.push_rect(&ctx, Rect rect, int z_index, Style* style) { Rect border = style.border; @@ -119,7 +146,6 @@ fn void? Ctx.push_rect(&ctx, Rect rect, int z_index, Style* style) .rect.color = bg, .rect.radius = radius, }; - if (cull_rect(cmd.rect.rect, ctx.div_scissor)) return; ctx.push_cmd(&cmd, z_index)!; } @@ -157,8 +183,8 @@ fn TextInfo? Ctx.push_string(&ctx, Rect bounds, char[] text, int z_index, Color ctx.push_sprite(ti.glyph_bounds, ti.glyph_uv, texture_id, z_index, hue)!; } } - - ctx.push_scissor({}, z_index)!; + + ctx.reset_scissor(z_index)!; return ti; } diff --git a/lib/ugui.c3l/src/ugui_core.c3 b/lib/ugui.c3l/src/ugui_core.c3 index 144d236..b85e996 100644 --- a/lib/ugui.c3l/src/ugui_core.c3 +++ b/lib/ugui.c3l/src/ugui_core.c3 @@ -291,6 +291,11 @@ $endif // sort the command buffer by the z-index ctx.cmd_queue.sort()!; + +// foreach (i, c: ctx.cmd_queue) { +// io::printf("[%d]: ", i); +// io::printn(c); +// } } <* diff --git a/src/main.c3 b/src/main.c3 index cfd51c3..307e34d 100644 --- a/src/main.c3 +++ b/src/main.c3 @@ -212,14 +212,12 @@ $endswitch ui.layout_set_floating()!!; // FIXME: I cannot anchor shit to the bottom of the screen - ui.div_begin({0, ui.height-150, -300, 150})!!; - { + ui.@div({0, ui.height-150, -300, 150}) { ui.layout_set_column()!!; ui.text_unbounded(string::tformat("frame %d, fps = %.2f", frame, fps))!!; ui.text_unbounded(string::tformat("ui avg: %s\ndraw avg: %s\nTOT: %s", uts.avg, dts.avg, uts.avg+dts.avg))!!; ui.text_unbounded(string::tformat("%s %s", mod.lctrl, (String)ui.input.keyboard.text[:ui.input.keyboard.text_len]))!!; - }; - ui.div_end()!!; + }!!; ui.frame_end()!!; /* End UI Handling */ @@ -324,34 +322,37 @@ fn void debug_app(ugui::Ctx* ui) fn void calculator(ugui::Ctx* ui) { ui.@div(ugui::DIV_FILL) { - ui.@div({0,0,-300,50}) { + ui.layout_set_column()!!; + + ui.@div({0,0,250,50}) { ui.text_unbounded("80085")!!; }!!; - ui.layout_next_row()!!; - - ui.button("7")!!; - ui.button("8")!!; - ui.button("9")!!; - ui.layout_next_row()!!; - ui.button("4")!!; - ui.button("5")!!; - ui.button("6")!!; - ui.layout_next_row()!!; - ui.button("3")!!; - ui.button("2")!!; - ui.button("1")!!; - ui.layout_next_row()!!; - ui.button(".")!!; - ui.button("0")!!; - ui.button("")!!; - - ui.layout_next_column()!!; - ui.layout_set_column()!!; - ui.button("+")!!; - ui.button("-")!!; - ui.button("*")!!; - ui.button("/")!!; - + ui.@div({0,0,250,-100}) { + ui.layout_set_row()!!; + + ui.button("7")!!; + ui.button("8")!!; + ui.button("9")!!; + ui.layout_next_row()!!; + ui.button("4")!!; + ui.button("5")!!; + ui.button("6")!!; + ui.layout_next_row()!!; + ui.button("3")!!; + ui.button("2")!!; + ui.button("1")!!; + ui.layout_next_row()!!; + ui.button(".")!!; + ui.button("0")!!; + //ui.button("")!!; + + ui.layout_next_column()!!; + ui.layout_set_column()!!; + ui.button("+")!!; + ui.button("-")!!; + ui.button("*")!!; + ui.button("/")!!; + }!!; }!!; }