ref(event): remove .resize and replace with recursize method calls
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 40s

This also means that currently the dynamic resizing through the app's
detached thread is not working, as it cannot send size updates. The
examples have been overhauled to still implement intermediate mode
applications accordingly.
This commit is contained in:
2025-03-04 14:52:19 +01:00
parent 43cdc46853
commit ec22e68e8c
17 changed files with 334 additions and 224 deletions

View File

@@ -601,173 +601,174 @@ pub fn Container(comptime Event: type) type {
try this.elements.append(element);
}
pub fn position(this: *@This(), pos: Point) !void {
log.debug("pos: .{{ .x = {d}, .y = {d} }}", .{ pos.x, pos.y });
this.origin = pos;
pub fn reposition(this: *@This(), origin: Point) void {
log.debug("origin: .{{ .x = {d}, .y = {d} }}", .{ origin.x, origin.y });
this.origin = origin;
this.element.reposition(origin);
}
pub fn resize(this: *@This(), size: Point) void {
log.debug("Event .size: {{ .x = {d}, .y = {d} }}", .{ size.x, size.y });
this.size = size;
if (this.properties.fixed_size.x > 0 and size.x < this.properties.fixed_size.x) return;
if (this.properties.fixed_size.y > 0 and size.y < this.properties.fixed_size.y) return;
this.element.resize(size);
if (this.elements.items.len == 0) return;
const layout = this.properties.layout;
var fixed_size_elements: u16 = 0;
var fixed_size: Point = .{};
for (this.elements.items) |element| {
switch (layout.direction) {
.horizontal => if (element.properties.fixed_size.x > 0) {
fixed_size_elements += 1;
},
.vertical => if (element.properties.fixed_size.y > 0) {
fixed_size_elements += 1;
},
}
fixed_size = fixed_size.add(element.properties.fixed_size);
}
// check if the available screen is large enough
switch (layout.direction) {
.horizontal => if (fixed_size.x > size.x) return,
.vertical => if (fixed_size.y > size.y) return,
}
const sides = this.properties.border.sides;
const padding = layout.padding;
var gap = layout.gap;
if (layout.separator.enabled) gap += 1;
const len: u16 = @truncate(this.elements.items.len);
const element_x = blk: {
var x = size.x - fixed_size.x - gap * (len - 1);
if (sides.left) x -= 1;
if (sides.right) x -= 1;
x -= padding.left + padding.right;
if (fixed_size_elements == len) break :blk 0;
if (fixed_size_elements == 0) {
break :blk @divTrunc(x, len);
} else {
break :blk @divTrunc(x, len - fixed_size_elements);
}
};
const element_y = blk: {
var y = size.y - fixed_size.y - gap * (len - 1);
if (sides.top) y -= 1;
if (sides.bottom) y -= 1;
y -= padding.top + padding.bottom;
if (fixed_size_elements == len) break :blk 0;
if (fixed_size_elements == 0) {
break :blk @divTrunc(y, len);
} else {
break :blk @divTrunc(y, len - fixed_size_elements);
}
};
var offset: u16 = switch (layout.direction) {
.horizontal => padding.left,
.vertical => padding.top,
};
var overflow = switch (layout.direction) {
.horizontal => blk: {
var x = size.x - fixed_size.x - gap * (len - 1);
if (sides.left) x -= 1;
if (sides.right) x -= 1;
x -= padding.left + padding.right;
if (fixed_size_elements == len) break :blk 0;
if (fixed_size_elements == 0) {
break :blk x - element_x * len;
} else {
break :blk x - element_x * (len - fixed_size_elements);
}
},
.vertical => blk: {
var y = size.y - fixed_size.y - gap * (len - 1);
if (sides.top) y -= 1;
if (sides.bottom) y -= 1;
y -= padding.top + padding.bottom;
if (fixed_size_elements == len) break :blk 0;
if (fixed_size_elements == 0) {
break :blk y - element_y * len;
} else {
break :blk y - element_y * (len - fixed_size_elements);
}
},
};
for (this.elements.items) |*element| {
var element_size: Point = undefined;
var element_origin: Point = undefined;
switch (layout.direction) {
.horizontal => {
// TODO this should not always be the max size property!
var x = blk: {
if (element.properties.fixed_size.x > 0) break :blk element.properties.fixed_size.x;
break :blk element_x;
};
if (overflow > 0) {
overflow -|= 1;
x += 1;
}
element_origin = .{
.x = this.origin.x + offset,
.y = this.origin.y,
};
element_size = .{
.x = x,
.y = size.y,
};
// border
if (sides.top) element_size.y -= 1;
if (sides.bottom) element_size.y -= 1;
// padding
element_origin.y += padding.top;
element_size.y -= padding.top + padding.bottom;
// gap
offset += gap;
offset += x;
},
.vertical => {
var y = blk: {
if (element.properties.fixed_size.y > 0) break :blk element.properties.fixed_size.y;
break :blk element_y;
};
if (overflow > 0) {
overflow -|= 1;
y += 1;
}
element_origin = .{
.x = this.origin.x,
.y = this.origin.y + offset,
};
element_size = .{
.x = size.x,
.y = y,
};
// border
if (sides.left) element_size.x -= 1;
if (sides.right) element_size.x -= 1;
// padding
element_origin.x += padding.left;
element_size.x -= padding.left + padding.right;
// gap
offset += gap;
offset += y;
},
}
// border resizing
if (sides.top) element_origin.y += 1;
if (sides.left) element_origin.x += 1;
element.reposition(element_origin);
element.resize(element_size);
}
}
pub fn handle(this: *@This(), event: Event) !void {
switch (event) {
.size => |size| resize: {
log.debug("Event .size: {{ .x = {d}, .y = {d} }}", .{ size.x, size.y });
this.size = size;
if (this.properties.fixed_size.x > 0 and size.x < this.properties.fixed_size.x) return Error.TooSmall;
if (this.properties.fixed_size.y > 0 and size.y < this.properties.fixed_size.y) return Error.TooSmall;
try this.element.handle(event);
if (this.elements.items.len == 0) break :resize;
const layout = this.properties.layout;
var fixed_size_elements: u16 = 0;
var fixed_size: Point = .{};
for (this.elements.items) |element| {
switch (layout.direction) {
.horizontal => if (element.properties.fixed_size.x > 0) {
fixed_size_elements += 1;
},
.vertical => if (element.properties.fixed_size.y > 0) {
fixed_size_elements += 1;
},
}
fixed_size = fixed_size.add(element.properties.fixed_size);
}
// check if the available screen is large enough
switch (layout.direction) {
.horizontal => if (fixed_size.x > size.x) return Error.TooSmall,
.vertical => if (fixed_size.y > size.y) return Error.TooSmall,
}
const sides = this.properties.border.sides;
const padding = layout.padding;
var gap = layout.gap;
if (layout.separator.enabled) gap += 1;
const len: u16 = @truncate(this.elements.items.len);
const element_x = blk: {
var x = size.x - fixed_size.x - gap * (len - 1);
if (sides.left) x -= 1;
if (sides.right) x -= 1;
x -= padding.left + padding.right;
if (fixed_size_elements == len) break :blk 0;
if (fixed_size_elements == 0) {
break :blk @divTrunc(x, len);
} else {
break :blk @divTrunc(x, len - fixed_size_elements);
}
};
const element_y = blk: {
var y = size.y - fixed_size.y - gap * (len - 1);
if (sides.top) y -= 1;
if (sides.bottom) y -= 1;
y -= padding.top + padding.bottom;
if (fixed_size_elements == len) break :blk 0;
if (fixed_size_elements == 0) {
break :blk @divTrunc(y, len);
} else {
break :blk @divTrunc(y, len - fixed_size_elements);
}
};
var offset: u16 = switch (layout.direction) {
.horizontal => padding.left,
.vertical => padding.top,
};
var overflow = switch (layout.direction) {
.horizontal => blk: {
var x = size.x - fixed_size.x - gap * (len - 1);
if (sides.left) x -= 1;
if (sides.right) x -= 1;
x -= padding.left + padding.right;
if (fixed_size_elements == len) break :blk 0;
if (fixed_size_elements == 0) {
break :blk x - element_x * len;
} else {
break :blk x - element_x * (len - fixed_size_elements);
}
},
.vertical => blk: {
var y = size.y - fixed_size.y - gap * (len - 1);
if (sides.top) y -= 1;
if (sides.bottom) y -= 1;
y -= padding.top + padding.bottom;
if (fixed_size_elements == len) break :blk 0;
if (fixed_size_elements == 0) {
break :blk y - element_y * len;
} else {
break :blk y - element_y * (len - fixed_size_elements);
}
},
};
for (this.elements.items) |*element| {
var element_size: Point = undefined;
var element_origin: Point = undefined;
switch (layout.direction) {
.horizontal => {
// TODO this should not always be the max size property!
var x = blk: {
if (element.properties.fixed_size.x > 0) break :blk element.properties.fixed_size.x;
break :blk element_x;
};
if (overflow > 0) {
overflow -|= 1;
x += 1;
}
element_origin = .{
.x = this.origin.x + offset,
.y = this.origin.y,
};
element_size = .{
.x = x,
.y = size.y,
};
// border
if (sides.top) element_size.y -= 1;
if (sides.bottom) element_size.y -= 1;
// padding
element_origin.y += padding.top;
element_size.y -= padding.top + padding.bottom;
// gap
offset += gap;
offset += x;
},
.vertical => {
var y = blk: {
if (element.properties.fixed_size.y > 0) break :blk element.properties.fixed_size.y;
break :blk element_y;
};
if (overflow > 0) {
overflow -|= 1;
y += 1;
}
element_origin = .{
.x = this.origin.x,
.y = this.origin.y + offset,
};
element_size = .{
.x = size.x,
.y = y,
};
// border
if (sides.left) element_size.x -= 1;
if (sides.right) element_size.x -= 1;
// padding
element_origin.x += padding.left;
element_size.x -= padding.left + padding.right;
// gap
offset += gap;
offset += y;
},
}
// border resizing
if (sides.top) element_origin.y += 1;
if (sides.left) element_origin.x += 1;
// TODO tell the element its origin
try element.position(element_origin);
try element.handle(.{ .size = element_size });
}
},
.mouse => |mouse| if (mouse.in(this.origin, this.size)) {
try this.element.handle(event);
for (this.elements.items) |*element| try element.handle(event);