fix calculator demo

turns out it was an incorrect handling of  scissor test
This commit is contained in:
Alessandro Mauri 2025-08-16 10:10:06 +02:00
parent be00c87c6a
commit 00299bec0b
5 changed files with 85 additions and 42 deletions

12
TODO
View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
// }
}
<*

View File

@ -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("/")!!;
}!!;
}!!;
}