feat(render): implement direct rendering
All checks were successful
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 38s

This commit is contained in:
2024-11-10 19:08:38 +01:00
parent 35a7f9cc02
commit 67a535db6d
5 changed files with 93 additions and 32 deletions

View File

@@ -78,8 +78,34 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
.resize => |size| {
this.size = size;
// adjust size according to the containing elements
log.debug("Event .resize: {{ .anchor = {{ .col = {d}, .row = {d} }}, .cols = {d}, .rows = {d} }}", .{
size.anchor.col,
size.anchor.row,
size.cols,
size.rows,
});
const len: u16 = @truncate(this.elements.items.len);
const element_cols = @divTrunc(size.cols, len);
var overflow = size.cols % len;
var offset: u16 = 0;
// adjust size according to the containing elements
for (this.elements.items) |*element| {
const sub_event = event;
var cols = element_cols;
if (overflow > 0) {
overflow -|= 1;
cols += 1;
}
const sub_event: Event = .{
.resize = .{
.anchor = .{
.col = size.anchor.col + offset,
.row = size.anchor.row,
},
.cols = cols,
.rows = size.rows,
},
};
offset += cols;
switch (element.*) {
.layout => |*layout| {
const events = try layout.handle(sub_event);
@@ -113,17 +139,13 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
}
pub fn render(this: *@This(), renderer: Renderer) !void {
// TODO: concat contents accordingly to create a horizontal stack
for (this.elements.items) |*element| {
switch (element.*) {
.layout => |*layout| {
try layout.render(renderer);
},
.widget => |*widget| {
// TODO: clear per widget if necessary (i.e. can I query that?)
// TODO: render using `renderer`
const content = try widget.content();
_ = try terminal.write(content);
try widget.render(renderer);
},
}
}

View File

@@ -25,10 +25,7 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
const Events = std.ArrayList(Event);
return struct {
// TODO: current focused `Element`?
// FIX: this should not be 'hardcoded' but dynamically be calculated and updated (i.e. through the event system)
anchor: terminal.Position = .{ .col = 1, .row = 1 },
size: terminal.Size = undefined,
element_rows: u16 = undefined,
elements: Elements = undefined,
events: Events = undefined,
@@ -87,12 +84,12 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
size.rows,
});
const len: u16 = @truncate(this.elements.items.len);
this.element_rows = @divTrunc(size.rows, len);
var overflow = this.size.rows % len;
const element_rows = @divTrunc(size.rows, len);
var overflow = size.rows % len;
var offset: u16 = 0;
// adjust size according to the containing elements
for (this.elements.items) |*element| {
var rows = this.element_rows;
var rows = element_rows;
if (overflow > 0) {
overflow -|= 1;
rows += 1;
@@ -141,7 +138,6 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
}
pub fn render(this: *@This(), renderer: Renderer) !void {
// FIX: renderer should clear only what is going to change! (i.e. the 'active' widget / layout)
for (this.elements.items) |*element| {
switch (element.*) {
.layout => |*layout| {