2 Commits

Author SHA1 Message Date
c2a03e95c1 fix(container/layout): padding calculation for anchor corrections 2025-02-14 21:59:10 +01:00
8998afd9d6 mod(): 2025-02-14 21:49:30 +01:00
2 changed files with 76 additions and 51 deletions

View File

@@ -31,20 +31,32 @@ pub fn main() !void {
.separator = .{ .enabled = false }, .separator = .{ .enabled = false },
}, },
.layout = .{ .layout = .{
.gap = 1,
.padding = .all(5), .padding = .all(5),
.direction = .horizontal, .direction = .vertical,
}, },
}); });
try container.append(try App.Container.init(allocator, .{ var box = try App.Container.init(allocator, .{
.rectangle = .{ .fill = .blue }, .rectangle = .{ .fill = .blue },
.layout = .{ .layout = .{
.gap = 1,
.direction = .horizontal,
.padding = .vertical(1),
.sizing = .{ .sizing = .{
.width = .{ .fixed = 70 }, // .width = .{ .fixed = 700 },
.height = .{ .fixed = 18 }, // .height = .{ .fixed = 180 },
}, },
}, },
});
try box.append(try App.Container.init(allocator, .{
.rectangle = .{ .fill = .light_green },
})); }));
try box.append(try App.Container.init(allocator, .{
.rectangle = .{ .fill = .light_green },
}));
try box.append(try App.Container.init(allocator, .{
.rectangle = .{ .fill = .light_green },
}));
try container.append(box);
try container.append(try App.Container.init(allocator, .{ try container.append(try App.Container.init(allocator, .{
.border = .{ .color = .light_blue, .corners = .squared }, .border = .{ .color = .light_blue, .corners = .squared },
})); }));

View File

@@ -311,6 +311,7 @@ pub fn Container(comptime Event: type) type {
}); });
this.viewport = s; this.viewport = s;
// sizing // sizing
// FIX: fixed sizing for smaller and bigger values does not work yet
var size = s; var size = s;
size.anchor = .{}; // reset relative anchor of size! size.anchor = .{}; // reset relative anchor of size!
const sizing = this.properties.layout.sizing; const sizing = this.properties.layout.sizing;
@@ -410,16 +411,21 @@ pub fn Container(comptime Event: type) type {
} }
element_size = .{ element_size = .{
.anchor = .{ .anchor = .{
.col = size.anchor.col + offset, .col = this.viewport.anchor.col + offset,
.row = size.anchor.row, .row = this.viewport.anchor.row,
}, },
.cols = cols, .cols = cols,
.rows = size.rows, .rows = size.rows,
}; };
// border
if (sides.top) element_size.rows -= 1; if (sides.top) element_size.rows -= 1;
if (sides.bottom) element_size.rows -= 1; if (sides.bottom) element_size.rows -= 1;
offset += cols; // padding
element_size.anchor.row += padding.top;
element_size.rows -= padding.top + padding.bottom;
// gap
offset += gap; offset += gap;
offset += cols;
}, },
.vertical => { .vertical => {
var rows = element_rows; var rows = element_rows;
@@ -429,16 +435,21 @@ pub fn Container(comptime Event: type) type {
} }
element_size = .{ element_size = .{
.anchor = .{ .anchor = .{
.col = size.anchor.col, .col = this.viewport.anchor.col,
.row = size.anchor.row + offset, .row = this.viewport.anchor.row + offset,
}, },
.cols = size.cols, .cols = size.cols,
.rows = rows, .rows = rows,
}; };
// border
if (sides.left) element_size.cols -= 1; if (sides.left) element_size.cols -= 1;
if (sides.right) element_size.cols -= 1; if (sides.right) element_size.cols -= 1;
offset += rows; // padding
element_size.anchor.col += padding.left;
element_size.cols -= padding.left + padding.right;
// gap
offset += gap; offset += gap;
offset += rows;
}, },
} }
@@ -451,10 +462,6 @@ pub fn Container(comptime Event: type) type {
} }
// padding resizing // padding resizing
element_size.anchor.row += padding.top;
element_size.anchor.col += padding.left;
element_size.rows -= padding.top + padding.bottom;
element_size.cols -= padding.left + padding.right;
try element.handle(.{ .resize = element_size }); try element.handle(.{ .resize = element_size });
} }
@@ -464,52 +471,58 @@ pub fn Container(comptime Event: type) type {
} }
pub fn contents(this: *const @This()) ![]const Cell { pub fn contents(this: *const @This()) ![]const Cell {
const content = try this.allocator.alloc(Cell, @as(usize, this.properties.scroll.size.cols) * @as(usize, this.properties.scroll.size.rows)); const content_cells = try this.allocator.alloc(Cell, @as(usize, this.properties.scroll.size.cols) * @as(usize, this.properties.scroll.size.rows));
defer this.allocator.free(content); defer this.allocator.free(content_cells);
@memset(content, .{}); @memset(content_cells, .{});
const cells = try this.allocator.alloc(Cell, @as(usize, this.viewport.cols) * @as(usize, this.viewport.rows)); const viewport_cells = try this.allocator.alloc(Cell, @as(usize, this.viewport.cols) * @as(usize, this.viewport.rows));
@memset(cells, .{}); @memset(viewport_cells, .{});
this.properties.border.contents(content, this.properties.scroll.size, this.properties.layout, @truncate(this.elements.items.len)); this.properties.border.contents(content_cells, this.properties.scroll.size, this.properties.layout, @truncate(this.elements.items.len));
this.properties.rectangle.contents(content, this.properties.scroll.size); this.properties.rectangle.contents(content_cells, this.properties.scroll.size);
const cols = blk: { log.debug("Content::contents .scroll.size: {{ .anchor = {{ .col = {d}, .row = {d} }}, .cols = {d}, .rows = {d} }}", .{
var cols: u16 = this.properties.scroll.size.cols;
if (this.properties.scroll.size.cols > this.viewport.cols) {
cols = this.viewport.cols;
}
break :blk cols;
};
const rows = blk: {
var rows: u16 = this.properties.scroll.size.rows;
if (this.properties.scroll.size.rows > this.viewport.rows) {
rows = this.viewport.rows;
}
break :blk rows;
};
const anchor = (this.properties.scroll.size.anchor.row * this.properties.scroll.size.cols) + this.properties.scroll.size.anchor.col;
log.debug("viewport = .{{ .anchor = {{ .col = {d}, .row = {d} }}, .cols = {d}, .rows = {d} }}", .{
this.viewport.anchor.col,
this.viewport.anchor.row,
this.viewport.cols,
this.viewport.rows,
});
log.debug("size = .{{ .anchor = {{ .col = {d}, .row = {d} }}, .cols = {d}, .rows = {d} }}", .{
this.properties.scroll.size.anchor.col, this.properties.scroll.size.anchor.col,
this.properties.scroll.size.anchor.row, this.properties.scroll.size.anchor.row,
this.properties.scroll.size.cols, this.properties.scroll.size.cols,
this.properties.scroll.size.rows, this.properties.scroll.size.rows,
}); });
for (0..rows) |row| {
for (0..cols) |col| { const cols = blk: {
var cols: u16 = this.properties.scroll.size.cols - this.properties.scroll.size.anchor.col;
if (cols > this.viewport.cols) {
cols = this.viewport.cols;
}
break :blk cols;
};
const rows = blk: {
var rows: u16 = this.properties.scroll.size.rows - this.properties.scroll.size.anchor.col;
if (rows > this.viewport.rows) {
rows = this.viewport.rows;
}
break :blk rows;
};
var content_row: usize = this.properties.scroll.size.anchor.row;
var content_col: usize = this.properties.scroll.size.anchor.col;
var viewport_row: usize = 0;
var viewport_col: usize = 0;
for (0..rows) |_| {
for (0..cols) |_| {
// TODO: try to do this with @memcpy instead to improve performance // TODO: try to do this with @memcpy instead to improve performance
const cell = content[anchor + (row * this.properties.scroll.size.cols) + col]; const cell = content_cells[(content_row * this.properties.scroll.size.cols) + content_col];
cells[row * this.viewport.cols + col].cp = cell.cp; viewport_cells[(viewport_row * this.viewport.cols) + viewport_col] = cell;
cells[row * this.viewport.cols + col].style = cell.style;
content_col += 1;
viewport_col += 1;
} }
content_row += 1;
viewport_row += 1;
content_col = 0;
viewport_col = 0;
} }
return cells; return viewport_cells;
} }
}; };
} }