mod: replace Layout.content with Layout.render
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 30s

The App.Renderer is used for the new `Layout.render` method. Each layout
renders itself now with corresponding renderers which might only update
parts of the screen, etc.
This commit is contained in:
2024-11-10 14:34:28 +01:00
parent b32556720e
commit b314ff7813
12 changed files with 112 additions and 92 deletions

View File

@@ -11,23 +11,21 @@ const Key = terminal.Key;
const log = std.log.scoped(.layout_hstack);
pub fn Layout(comptime Event: type) type {
pub fn Layout(comptime Event: type, comptime Renderer: type) type {
if (!isTaggedUnion(Event)) {
@compileError("Provided user event `Event` for `Layout(comptime Event: type)` is not of type `union(enum)`.");
}
const Widget = @import("../widget.zig").Widget(Event);
const Lay = @import("../layout.zig").Layout(Event);
const Lay = @import("../layout.zig").Layout(Event, Renderer);
const Element = union(enum) {
layout: Lay,
widget: Widget,
};
const Elements = std.ArrayList(Element);
const Events = std.ArrayList(Event);
const Contents = std.ArrayList(u8);
return struct {
// TODO: current focused `Element`?
size: terminal.Size = undefined,
contents: Contents = undefined,
elements: Elements = undefined,
events: Events = undefined,
@@ -53,7 +51,6 @@ pub fn Layout(comptime Event: type) type {
@compileError("child: " ++ field.name ++ " is not of type " ++ @typeName(Lay) ++ " or " ++ @typeName(Widget) ++ " but " ++ @typeName(ChildType));
}
return .{
.contents = Contents.init(allocator),
.elements = elements,
.events = Events.init(allocator),
};
@@ -61,7 +58,6 @@ pub fn Layout(comptime Event: type) type {
pub fn deinit(this: *@This()) void {
this.events.deinit();
this.contents.deinit();
for (this.elements.items) |*element| {
switch (element.*) {
.layout => |*layout| {
@@ -116,21 +112,21 @@ pub fn Layout(comptime Event: type) type {
return &this.events;
}
pub fn content(this: *@This()) !*Contents {
this.contents.clearRetainingCapacity();
// TODO: concat contents accordingly to create a vertical stack
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| {
const layout_content = try layout.content();
try this.contents.appendSlice(layout_content.items);
try layout.render(renderer);
},
.widget => |*widget| {
try this.contents.appendSlice(try widget.content());
// 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);
},
}
}
return &this.contents;
}
};
}