corrected layout offset

This commit is contained in:
Alessandro Mauri 2025-09-14 20:32:31 +02:00
parent d33d72a074
commit 622b648d26
10 changed files with 51 additions and 72 deletions

View File

@ -308,7 +308,8 @@ $if DEBUG == 1:
$endif $endif
// sort the command buffer by the z-index // sort the command buffer by the z-index
ctx.cmd_queue.sort()!; // FIXME: sorting the buffer fucks with scissor commands that have to be kept in place
//ctx.cmd_queue.sort()!;
// foreach (i, c: ctx.cmd_queue) { // foreach (i, c: ctx.cmd_queue) {
// io::printf("[%d]: ", i); // io::printf("[%d]: ", i);

View File

@ -106,17 +106,6 @@ macro Point Elem.content_space(&e)
}; };
} }
// Update the parent element's grow children counter
fn void update_parent_grow(Elem* child, Elem* parent)
{
switch (parent.layout.dir) {
case ROW:
if (child.layout.w.@is_grow()) parent.layout.grow_children++;
case COLUMN:
if (child.layout.h.@is_grow()) parent.layout.grow_children++;
}
}
// Update the parent element's children size // Update the parent element's children size
fn void update_parent_size(Elem* child, Elem* parent) fn void update_parent_size(Elem* child, Elem* parent)
{ {
@ -129,9 +118,11 @@ fn void update_parent_size(Elem* child, Elem* parent)
case ROW: // on rows grow the ch width by the child width and only grow ch height if it exceeds case ROW: // on rows grow the ch width by the child width and only grow ch height if it exceeds
pl.children.w += @exact(child_size.x); pl.children.w += @exact(child_size.x);
pl.children.h = pl.children.h.comb_max(@exact(child_size.y)); pl.children.h = pl.children.h.comb_max(@exact(child_size.y));
if (child.layout.w.@is_grow()) parent.layout.grow_children++;
case COLUMN: // do the opposite on column case COLUMN: // do the opposite on column
pl.children.w = pl.children.w.comb_max(@exact(child_size.x)); pl.children.w = pl.children.w.comb_max(@exact(child_size.x));
pl.children.h += @exact(child_size.y); pl.children.h += @exact(child_size.y);
if (child.layout.h.@is_grow()) parent.layout.grow_children++;
} }
} }
@ -187,8 +178,6 @@ fn void resolve_grow_elements(Elem* e, Elem* p)
if (e.layout.w.@is_grow()) { if (e.layout.w.@is_grow()) {
if (p.layout.dir == ROW) { // grow along the axis, divide the parent size if (p.layout.dir == ROW) { // grow along the axis, divide the parent size
short slot = (short)((p.content_space().x - p.layout.occupied) / p.layout.grow_children); short slot = (short)((p.content_space().x - p.layout.occupied) / p.layout.grow_children);
// the space slot accounts for the total size, while the element bounds does not account
// for the margin
e.bounds.w = slot; e.bounds.w = slot;
p.layout.grow_children--; p.layout.grow_children--;
p.layout.occupied += slot; p.layout.occupied += slot;
@ -216,8 +205,8 @@ fn void resolve_placement(Elem* c, Elem* p)
Layout* cl = &c.layout; Layout* cl = &c.layout;
Point off = { Point off = {
.x = p.bounds.x + pl.origin.x, .x = p.bounds.x + pl.origin.x + pl.content_offset.x,
.y = p.bounds.y + pl.origin.y, .y = p.bounds.y + pl.origin.y + pl.content_offset.y,
}; };
switch (pl.anchor) { switch (pl.anchor) {
@ -226,7 +215,7 @@ fn void resolve_placement(Elem* c, Elem* p)
c.bounds.y = off.y; c.bounds.y = off.y;
case LEFT: case LEFT:
c.bounds.x = off.x; c.bounds.x = off.x;
c.bounds.y = off.y + p.bounds.h/2; c.bounds.y = off.y + p.content_space().y/2;
if (pl.dir == COLUMN) { if (pl.dir == COLUMN) {
c.bounds.y -= pl.occupied/2; c.bounds.y -= pl.occupied/2;
} else if (pl.dir == ROW) { } else if (pl.dir == ROW) {
@ -234,15 +223,15 @@ fn void resolve_placement(Elem* c, Elem* p)
} }
case BOTTOM_LEFT: case BOTTOM_LEFT:
c.bounds.x = off.x; c.bounds.x = off.x;
c.bounds.y = off.y + p.bounds.h ; c.bounds.y = off.y + p.content_space().y ;
if (pl.dir == COLUMN) { if (pl.dir == COLUMN) {
c.bounds.y -= pl.occupied; c.bounds.y -= pl.occupied;
} else if (pl.dir == ROW) { } else if (pl.dir == ROW) {
c.bounds.y -= c.bounds.h; c.bounds.y -= c.bounds.h;
} }
case BOTTOM: case BOTTOM:
c.bounds.x = off.x + p.bounds.w/2; c.bounds.x = off.x + p.content_space().x/2;
c.bounds.y = off.y + p.bounds.h; c.bounds.y = off.y + p.content_space().y;
if (pl.dir == COLUMN) { if (pl.dir == COLUMN) {
c.bounds.y -= pl.occupied; c.bounds.y -= pl.occupied;
c.bounds.x -= c.bounds.w/2; c.bounds.x -= c.bounds.w/2;
@ -251,8 +240,8 @@ fn void resolve_placement(Elem* c, Elem* p)
c.bounds.x -= pl.occupied/2; c.bounds.x -= pl.occupied/2;
} }
case BOTTOM_RIGHT: case BOTTOM_RIGHT:
c.bounds.x = off.x + p.bounds.w; c.bounds.x = off.x + p.content_space().x;
c.bounds.y = off.y + p.bounds.h; c.bounds.y = off.y + p.content_space().y;
if (pl.dir == COLUMN) { if (pl.dir == COLUMN) {
c.bounds.y -= pl.occupied; c.bounds.y -= pl.occupied;
c.bounds.x -= c.bounds.w; c.bounds.x -= c.bounds.w;
@ -261,8 +250,8 @@ fn void resolve_placement(Elem* c, Elem* p)
c.bounds.x -= pl.occupied; c.bounds.x -= pl.occupied;
} }
case RIGHT: case RIGHT:
c.bounds.x = off.x + p.bounds.w; c.bounds.x = off.x + p.content_space().x;
c.bounds.y = off.y + p.bounds.h/2; c.bounds.y = off.y + p.content_space().y/2;
if (pl.dir == COLUMN) { if (pl.dir == COLUMN) {
c.bounds.y -= pl.occupied/2; c.bounds.y -= pl.occupied/2;
c.bounds.x -= c.bounds.w; c.bounds.x -= c.bounds.w;
@ -271,7 +260,7 @@ fn void resolve_placement(Elem* c, Elem* p)
c.bounds.x -= pl.occupied; c.bounds.x -= pl.occupied;
} }
case TOP_RIGHT: case TOP_RIGHT:
c.bounds.x = off.x + p.bounds.w; c.bounds.x = off.x + p.content_space().x;
c.bounds.y = off.y; c.bounds.y = off.y;
if (pl.dir == COLUMN) { if (pl.dir == COLUMN) {
c.bounds.x -= c.bounds.w; c.bounds.x -= c.bounds.w;
@ -279,7 +268,7 @@ fn void resolve_placement(Elem* c, Elem* p)
c.bounds.x -= pl.occupied; c.bounds.x -= pl.occupied;
} }
case TOP: case TOP:
c.bounds.x = off.x + p.bounds.w/2; c.bounds.x = off.x + p.content_space().x/2;
c.bounds.y = off.y; c.bounds.y = off.y;
if (pl.dir == COLUMN) { if (pl.dir == COLUMN) {
c.bounds.x -= c.bounds.w/2; c.bounds.x -= c.bounds.w/2;
@ -287,8 +276,8 @@ fn void resolve_placement(Elem* c, Elem* p)
c.bounds.x -= pl.occupied/2; c.bounds.x -= pl.occupied/2;
} }
case CENTER: case CENTER:
c.bounds.x = off.x + p.bounds.w/2; c.bounds.x = off.x + p.content_space().x/2;
c.bounds.y = off.y + p.bounds.h/2; c.bounds.y = off.y + p.content_space().y/2;
if (pl.dir == COLUMN) { if (pl.dir == COLUMN) {
c.bounds.x -= c.bounds.w/2; c.bounds.x -= c.bounds.w/2;
c.bounds.y -= pl.occupied/2; c.bounds.y -= pl.occupied/2;
@ -314,9 +303,7 @@ fn void Ctx.layout_element_tree(&ctx)
isz current = ctx.tree.level_order_it(0, &cursor)!!; isz current = ctx.tree.level_order_it(0, &cursor)!!;
for (; current >= 0; current = ctx.tree.level_order_it(0, &cursor)!!) { for (; current >= 0; current = ctx.tree.level_order_it(0, &cursor)!!) {
Elem* p = ctx.find_elem(ctx.tree.get(current))!!; Elem* p = ctx.find_elem(ctx.tree.get(current))!!;
// offset the origin by the margin //if (ctx.tree.is_root(current)!!) p = &&{};
p.layout.origin.x = p.layout.content_offset.x;
p.layout.origin.y = p.layout.content_offset.y;
// RESOLVE KNOWN DIMENSIONS // RESOLVE KNOWN DIMENSIONS
isz ch_cur = 0; isz ch_cur = 0;
@ -349,7 +336,7 @@ fn void Ctx.layout_element_tree(&ctx)
Elem* c = ctx.find_elem(ctx.tree.get(ch))!!; Elem* c = ctx.find_elem(ctx.tree.get(ch))!!;
if (ctx.tree.is_root(ch)!!) { if (ctx.tree.is_root(ch)!!) {
resolve_placement(p, &&{}); resolve_placement(p, &&{});
update_children_bounds(c, p); update_children_bounds(p, &&{});
} else { } else {
resolve_placement(c, p); resolve_placement(c, p);
update_children_bounds(c, p); update_children_bounds(c, p);

View File

@ -24,7 +24,7 @@ const Style DEFAULT_STYLE = {
.margin = {2, 2, 2, 2}, .margin = {2, 2, 2, 2},
.border = {2, 2, 2, 2}, .border = {2, 2, 2, 2},
.padding = {1, 1, 1, 1}, .padding = {1, 1, 1, 1},
.radius = 12, .radius = 0,
.size = 16, .size = 16,
.bg = 0x282828ffu.@to_rgba(), .bg = 0x282828ffu.@to_rgba(),

View File

@ -44,7 +44,6 @@ fn ElemEvents? Ctx.button_id(&ctx, Id id, String label, String icon)
elem.layout.text = ctx.measure_string(label)!; elem.layout.text = ctx.measure_string(label)!;
elem.layout.content_offset = style.margin + style.border + style.padding; elem.layout.content_offset = style.margin + style.border + style.padding;
update_parent_grow(elem, parent);
update_parent_size(elem, parent); update_parent_size(elem, parent);
elem.events = ctx.get_elem_events(elem); elem.events = ctx.get_elem_events(elem);
@ -113,7 +112,6 @@ fn void? Ctx.checkbox_id(&ctx, Id id, String description, bool* active, String t
elem.layout.text = ctx.measure_string(description)!; elem.layout.text = ctx.measure_string(description)!;
elem.layout.content_offset = style.margin + style.border + style.padding; elem.layout.content_offset = style.margin + style.border + style.padding;
update_parent_grow(elem, parent);
update_parent_size(elem, parent); update_parent_size(elem, parent);
elem.events = ctx.get_elem_events(elem); elem.events = ctx.get_elem_events(elem);
@ -188,7 +186,6 @@ fn void? Ctx.toggle_id(&ctx, Id id, String description, bool* active)
elem.layout.text = ctx.measure_string(description)!; elem.layout.text = ctx.measure_string(description)!;
elem.layout.content_offset = style.margin + style.border + style.padding; elem.layout.content_offset = style.margin + style.border + style.padding;
update_parent_grow(elem, parent);
update_parent_size(elem, parent); update_parent_size(elem, parent);
elem.events = ctx.get_elem_events(elem); elem.events = ctx.get_elem_events(elem);

View File

@ -68,10 +68,6 @@ fn void? Ctx.div_begin_id(&ctx,
elem.div.scroll_size = slider_style.size ? slider_style.size : (style.size ? style.size : DEFAULT_STYLE.size); elem.div.scroll_size = slider_style.size ? slider_style.size : (style.size ? style.size : DEFAULT_STYLE.size);
elem.div.z_index = parent.div.z_index + 1; elem.div.z_index = parent.div.z_index + 1;
// update the ctx scissor
ctx.div_scissor = elem.bounds;
ctx.push_scissor(elem.bounds, elem.div.z_index)!;
// update layout with correct info // update layout with correct info
elem.layout = { elem.layout = {
.w = width, .w = width,
@ -81,11 +77,12 @@ fn void? Ctx.div_begin_id(&ctx,
.content_offset = style.margin + style.border + style.padding, .content_offset = style.margin + style.border + style.padding,
}; };
// update parent grow children
update_parent_grow(elem, parent);
ctx.push_rect(elem.bounds.pad(style.margin), elem.div.z_index, style)!; ctx.push_rect(elem.bounds.pad(style.margin), elem.div.z_index, style)!;
// update the ctx scissor, it HAS to be after drawing the background
ctx.div_scissor = elem.bounds.pad(elem.layout.content_offset);
ctx.push_scissor(elem.bounds.pad(elem.layout.content_offset), elem.div.z_index)!;
elem.events = ctx.get_elem_events(elem); elem.events = ctx.get_elem_events(elem);
// TODO: check active // TODO: check active
@ -132,7 +129,7 @@ fn Id? Ctx.div_end(&ctx)
// the active_div returns to the parent of the current one // the active_div returns to the parent of the current one
ctx.active_div = ctx.tree.parentof(ctx.active_div)!; ctx.active_div = ctx.tree.parentof(ctx.active_div)!;
Elem* parent = ctx.get_parent()!; Elem* parent = ctx.get_parent()!;
ctx.div_scissor = parent.bounds; ctx.div_scissor = parent.bounds.pad(parent.layout.content_offset);
ctx.reset_scissor(elem.div.z_index)!; ctx.reset_scissor(elem.div.z_index)!;
update_parent_size(elem, parent); update_parent_size(elem, parent);

View File

@ -29,7 +29,6 @@ fn ElemEvents? Ctx.slider_hor_id(&ctx, Id id, Size w, Size h, float* value, floa
elem.layout.w = w; elem.layout.w = w;
elem.layout.h = h; elem.layout.h = h;
elem.layout.content_offset = style.margin + style.border + style.padding; elem.layout.content_offset = style.margin + style.border + style.padding;
update_parent_grow(elem, parent);
update_parent_size(elem, parent); update_parent_size(elem, parent);
Rect bg_bounds = elem.bounds.pad(style.margin); Rect bg_bounds = elem.bounds.pad(style.margin);
@ -93,7 +92,6 @@ fn ElemEvents? Ctx.slider_ver_id(&ctx, Id id, Size w, Size h, float* value, floa
elem.layout.w = w; elem.layout.w = w;
elem.layout.h = h; elem.layout.h = h;
elem.layout.content_offset = style.margin + style.border + style.padding; elem.layout.content_offset = style.margin + style.border + style.padding;
update_parent_grow(elem, parent);
update_parent_size(elem, parent); update_parent_size(elem, parent);
// 2. Layout // 2. Layout

View File

@ -19,7 +19,6 @@ fn void? Ctx.sprite_id(&ctx, Id id, String name)
elem.layout.w = elem.layout.children.w = @exact(sprite.w); elem.layout.w = elem.layout.children.w = @exact(sprite.w);
elem.layout.h = elem.layout.children.h = @exact(sprite.h); elem.layout.h = elem.layout.children.h = @exact(sprite.h);
update_parent_grow(elem, parent);
update_parent_size(elem, parent); update_parent_size(elem, parent);
Id tex_id = ctx.sprite_atlas.id; Id tex_id = ctx.sprite_atlas.id;

View File

@ -29,7 +29,6 @@ fn void? Ctx.text_id(&ctx, Id id, String text)
elem.layout.text = elem.text.size; elem.layout.text = elem.text.size;
elem.layout.content_offset = style.margin + style.border + style.padding; elem.layout.content_offset = style.margin + style.border + style.padding;
update_parent_grow(elem, parent);
update_parent_size(elem, parent); update_parent_size(elem, parent);
ctx.layout_string(text, elem.bounds.pad(elem.layout.content_offset), TOP_LEFT, parent.div.z_index, style.fg)!; ctx.layout_string(text, elem.bounds.pad(elem.layout.content_offset), TOP_LEFT, parent.div.z_index, style.fg)!;
@ -59,7 +58,6 @@ fn ElemEvents? Ctx.text_box_id(&ctx, Id id, Size w, Size h, TextEdit* te)
elem.layout.text = elem.text.size; elem.layout.text = elem.text.size;
elem.layout.content_offset = style.margin + style.border + style.padding; elem.layout.content_offset = style.margin + style.border + style.padding;
update_parent_grow(elem, parent);
update_parent_size(elem, parent); update_parent_size(elem, parent);
// check input and update the text // check input and update the text
@ -70,6 +68,7 @@ fn ElemEvents? Ctx.text_box_id(&ctx, Id id, Size w, Size h, TextEdit* te)
} }
// draw the box // draw the box
Rect bg_bounds = elem.bounds.pad(style.margin); Rect bg_bounds = elem.bounds.pad(style.margin);
Rect text_bounds = elem.bounds.pad(elem.layout.content_offset); Rect text_bounds = elem.bounds.pad(elem.layout.content_offset);
ctx.push_rect(bg_bounds, parent.div.z_index, style)!; ctx.push_rect(bg_bounds, parent.div.z_index, style)!;

View File

@ -7,6 +7,7 @@ default {
border: 1; border: 1;
padding: 0; padding: 0;
margin: 0; margin: 0;
radius: 0;
} }
button { button {