const std = @import("std"); const terminal = @import("../terminal.zig"); const isTaggedUnion = @import("../event.zig").isTaggedUnion; const Error = @import("../event.zig").Error; const Key = @import("../key.zig"); pub fn Layout(comptime Event: 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 Events = std.ArrayList(Event); return struct { widget: Widget = undefined, events: Events = undefined, c: std.ArrayList(u8) = undefined, pub fn init(allocator: std.mem.Allocator, widget: Widget) @This() { return .{ .widget = widget, .events = Events.init(allocator), .c = std.ArrayList(u8).init(allocator), }; } pub fn deinit(this: *@This()) void { this.widget.deinit(); this.events.deinit(); this.c.deinit(); this.* = undefined; } pub fn handle(this: *@This(), event: Event) !*Events { this.events.clearRetainingCapacity(); switch (event) { .resize => |size| { const widget_event: Event = .{ .resize = .{ .cols = size.cols, .rows = size.rows -| 2, // remove top and bottom rows }, }; if (this.widget.handle(widget_event)) |e| { try this.events.append(e); } }, else => { if (this.widget.handle(event)) |e| { try this.events.append(e); } }, } return &this.events; } pub fn content(this: *@This()) !*std.ArrayList(u8) { const widget_content = try this.widget.content(); this.c.clearRetainingCapacity(); try this.c.appendSlice("\n"); try this.c.appendSlice(widget_content); try this.c.appendSlice("\n"); return &this.c; } }; }