rem(container): sizing options

This enables the `Layout` struct to be packed (as well as the
`Properties` struct) which should further reduce the memory footprint.
This commit is contained in:
2025-02-14 22:19:20 +01:00
parent 73a7f740c9
commit abaea968a6
2 changed files with 7 additions and 56 deletions

View File

@@ -41,10 +41,6 @@ pub fn main() !void {
.gap = 1,
.direction = .horizontal,
.padding = .vertical(1),
.sizing = .{
// .width = .{ .fixed = 700 },
// .height = .{ .fixed = 180 },
},
},
});
try box.append(try App.Container.init(allocator, .{

View File

@@ -199,9 +199,8 @@ pub const Scroll = packed struct {
// - render corresponding scroll-bars?
};
// TODO: can `Layout` become `packed`? -> for that the sizing cannot be a tagged enum!
/// Layout configuration struct
pub const Layout = struct {
pub const Layout = packed struct {
/// control the direction in which child elements are laid out
direction: enum(u1) { horizontal, vertical } = .horizontal,
/// Padding outside of the child elements
@@ -234,13 +233,6 @@ pub const Layout = struct {
x: enum(u2) { center, left, right } = .center,
y: enum(u2) { center, left, right } = .center,
} = .{},
// TODO: is there a way to make width / height type copied by the compiler at comptime instead? such that this only has to be defined once?
// NOTE: `sizing` cannot be *packed* because of the tagged unions? is this necessary -> I would need to measure the size differences
/// Sizing to be used for the width and height of this element to use
sizing: struct {
width: union(enum(u2)) { fit, grow, fixed: u16, percent: u16 } = .fit,
height: union(enum(u2)) { fit, grow, fixed: u16, percent: u16 } = .fit,
} = .{},
};
pub fn Container(comptime Event: type) type {
@@ -261,7 +253,7 @@ pub fn Container(comptime Event: type) type {
/// Properties for each `Container` to configure their layout,
/// border, styling, etc. For details see the corresponding individual
/// documentation of the members of this struct accordingly.
pub const Properties = struct {
pub const Properties = packed struct {
border: Border = .{},
rectangle: Rectangle = .{},
scroll: Scroll = .{},
@@ -299,48 +291,11 @@ pub fn Container(comptime Event: type) type {
s.rows,
});
this.viewport = s;
// sizing
// FIX: fixed sizing for smaller and bigger values does not work yet
var size = s;
size.anchor = .{}; // reset relative anchor of size!
const sizing = this.properties.layout.sizing;
switch (sizing.width) {
.fit => {
// use as much space as necessary (but nothing more than necessary)
},
.grow => {
// grow use as much space as available by the parent (i.e. the entire width)
// NOTE: this is pretty much the current implementation
},
.fixed => |fix| {
// NOTE: fixed may now even define a larger column / row span for a container (but not everything might be rendered)
size.cols = fix;
},
.percent => |percent| {
// use a percentage unit calculated from the available space
size.cols = @divTrunc(size.cols * percent, 100);
},
}
switch (sizing.height) {
.fit => {
// use as much space as necessary (but nothing more than necessary)
// TODO: I need to work out the representation between the
// - `Size` and `Size.Position` with the actual screen size
// - the virtual screen may be larger than the actual screen (can I do this?)
},
.grow => {
// grow use as much space as available by the parent (i.e. the entire width)
// NOTE: this is pretty much the current implementation
},
.fixed => |fix| {
// NOTE: fixed may now even define a larger column / row span for a container (but not everything might be rendered)
size.rows = fix;
},
.percent => |percent| {
// use a percentage unit calculated from the available space
size.rows = @divTrunc(size.rows * percent, 100);
},
}
const size: Size = .{
.cols = s.cols,
.rows = s.rows,
};
this.size = size;
if (this.elements.items.len == 0) break :resize;