mod: each layout and widget now allocates their own instance in memory using the provided allocator (and destroy's themselfes in the end)
All checks were successful
Zig Project Action / Lint, Spell-check and test zig project (push) Successful in 36s

This commit is contained in:
2024-11-16 19:56:36 +01:00
parent f4adf53067
commit ec71e34958
14 changed files with 232 additions and 270 deletions

View File

@@ -30,56 +30,38 @@ pub fn main() !void {
// TODO: when not running fullscreen, the application needs to screen down accordingly to display the contents // TODO: when not running fullscreen, the application needs to screen down accordingly to display the contents
// -> size hint how much should it use? // -> size hint how much should it use?
var layout = Layout.createFrom(layout: { var layout = Layout.createFrom(Layout.HContainer.init(allocator, .{
var stack = Layout.HContainer.init(allocator, .{ .{
.{ Widget.createFrom(Widget.Spacer.init(allocator)),
Widget.createFrom(blk: { 15,
var spacer = Widget.Spacer.init(); },
break :blk &spacer; .{
}), Layout.createFrom(Layout.VContainer.init(allocator, .{
15, .{
}, Widget.createFrom(Widget.Spacer.init(allocator)),
.{ 25,
Layout.createFrom(container: { },
var container = Layout.VContainer.init(allocator, .{ .{
.{ Widget.createFrom(blk: {
Widget.createFrom(blk: { const file = try std.fs.cwd().openFile("./src/app.zig", .{});
var spacer = Widget.Spacer.init(); defer file.close();
break :blk &spacer; const widget = Widget.RawText.init(allocator, file);
}), break :blk widget;
25, }),
}, 50,
.{ },
Widget.createFrom(blk: { .{
const file = try std.fs.cwd().openFile("./src/app.zig", .{}); Widget.createFrom(Widget.Spacer.init(allocator)),
defer file.close(); 25,
var widget = Widget.RawText.init(allocator, file); },
break :blk &widget; })),
}), 70,
50, },
}, .{
.{ Widget.createFrom(Widget.Spacer.init(allocator)),
Widget.createFrom(blk: { 15,
var spacer = Widget.Spacer.init(); },
break :blk &spacer; }));
}),
25,
},
});
break :container &container;
}),
70,
},
.{
Widget.createFrom(blk: {
var spacer = Widget.Spacer.init();
break :blk &spacer;
}),
15,
},
});
break :layout &stack;
});
defer layout.deinit(); defer layout.deinit();
try app.start(); try app.start();

View File

@@ -31,41 +31,26 @@ pub fn main() !void {
// TODO: when not running fullscreen, the application needs to screen down accordingly to display the contents // TODO: when not running fullscreen, the application needs to screen down accordingly to display the contents
// -> size hint how much should it use? // -> size hint how much should it use?
var layout = Layout.createFrom(layout: { var layout = Layout.createFrom(Layout.VContainer.init(allocator, .{
var container = Layout.VContainer.init(allocator, .{ .{
.{ Widget.createFrom(Widget.Spacer.init(allocator)),
Widget.createFrom(blk: { 45,
var spacer = Widget.Spacer.init(); },
break :blk &spacer; .{
}), Layout.createFrom(Layout.Framing.init(allocator, .{}, .{
45, .widget = Widget.createFrom(Widget.Text.init(allocator, .center, &[_]Cell{
}, .{ .content = "Press " },
.{ .{ .content = "Ctrl+n", .style = .{ .fg = .{ .index = 6 } } },
Layout.createFrom(framing: { .{ .content = " to launch $EDITOR" },
var framing = Layout.Framing.init(allocator, .{}, .{ })),
.widget = Widget.createFrom(blk: { })),
var widget = Widget.Text.init(.center, &[_]Cell{ 10,
.{ .content = "Press " }, },
.{ .content = "Ctrl+n", .style = .{ .fg = .{ .index = 6 } } }, .{
.{ .content = " to launch $EDITOR" }, Widget.createFrom(Widget.Spacer.init(allocator)),
}); 45,
break :blk &widget; },
}), }));
});
break :framing &framing;
}),
10,
},
.{
Widget.createFrom(blk: {
var spacer = Widget.Spacer.init();
break :blk &spacer;
}),
45,
},
});
break :layout &container;
});
defer layout.deinit(); defer layout.deinit();
try app.start(); try app.start();

View File

@@ -30,54 +30,41 @@ pub fn main() !void {
// TODO: when not running fullscreen, the application needs to screen down accordingly to display the contents // TODO: when not running fullscreen, the application needs to screen down accordingly to display the contents
// -> size hint how much should it use? // -> size hint how much should it use?
var layout = Layout.createFrom(layout: { var layout = Layout.createFrom(Layout.Padding.init(allocator, .{
var padding = Layout.Padding.init(allocator, .{ .padding = 15,
.padding = 15, }, .{
.layout = Layout.createFrom(Layout.Framing.init(allocator, .{
.style = .{
.fg = .{
.index = 6,
},
},
.frame = .round,
.title = .{
.str = "Content in Margin",
.style = .{
.ul_style = .single,
.ul = .{ .index = 6 },
.bold = true,
},
},
}, .{ }, .{
.layout = Layout.createFrom(framing: { .layout = Layout.createFrom(Layout.Margin.init(
var framing = Layout.Framing.init( allocator,
allocator, .{
.{ .margin = 10,
.style = .{ },
.fg = .{ .{
.index = 6, .widget = Widget.createFrom(blk: {
}, const file = try std.fs.cwd().openFile("./examples/padding.zig", .{});
}, defer file.close();
.frame = .round, const widget = Widget.RawText.init(allocator, file);
.title = .{ break :blk widget;
.str = "Content in Margin", }),
.style = .{ },
.ul_style = .single, )),
.ul = .{ .index = 6 }, })),
.bold = true, }));
},
},
},
.{
.layout = Layout.createFrom(margin: {
var margin = Layout.Margin.init(
allocator,
.{
.margin = 10,
},
.{
.widget = Widget.createFrom(blk: {
const file = try std.fs.cwd().openFile("./examples/padding.zig", .{});
defer file.close();
var widget = Widget.RawText.init(allocator, file);
break :blk &widget;
}),
},
);
break :margin &margin;
}),
},
);
break :framing &framing;
}),
});
break :layout &padding;
});
defer layout.deinit(); defer layout.deinit();
try app.start(); try app.start();

View File

@@ -30,97 +30,67 @@ pub fn main() !void {
// TODO: when not running fullscreen, the application needs to screen down accordingly to display the contents // TODO: when not running fullscreen, the application needs to screen down accordingly to display the contents
// -> size hint how much should it use? // -> size hint how much should it use?
var layout = Layout.createFrom(layout: { var layout = Layout.createFrom(Layout.Framing.init(allocator, .{
var framing = Layout.Framing.init(allocator, .{ .style = .{
.fg = .{
.index = 6,
},
},
.frame = .round,
.title = .{
.str = "HStack",
.style = .{ .style = .{
.fg = .{ .ul_style = .single,
.index = 6, .ul = .{ .index = 6 },
}, .bold = true,
}, },
.frame = .round, },
.title = .{ }, .{
.str = "HStack", .layout = Layout.createFrom(Layout.HStack.init(allocator, .{
.style = .{ Widget.createFrom(Widget.Spacer.init(allocator)),
.ul_style = .single, Layout.createFrom(Layout.Framing.init(
.ul = .{ .index = 6 }, allocator,
.bold = true, .{
.style = .{
.fg = .{
.index = 6,
},
},
.frame = .round,
.title = .{
.str = "VStack",
.style = .{
.ul_style = .single,
.ul = .{ .index = 6 },
.bold = true,
},
},
}, },
}, .{
}, .{ .layout = Layout.createFrom(Layout.Margin.init(allocator, .{
.layout = Layout.createFrom(hstack: { .margin = 10,
var hstack = Layout.HStack.init(allocator, .{ }, .{
Widget.createFrom(blk: { .layout = Layout.createFrom(Layout.VStack.init(allocator, .{
var spacer = Widget.Spacer.init(); Widget.createFrom(blk: {
break :blk &spacer; const file = try std.fs.cwd().openFile("./examples/stack.zig", .{});
}), defer file.close();
Layout.createFrom(framing: { const widget = Widget.RawText.init(allocator, file);
var framing = Layout.Framing.init( break :blk widget;
allocator, }),
.{ Widget.createFrom(Widget.Spacer.init(allocator)),
.style = .{ Widget.createFrom(blk: {
.fg = .{ const file = try std.fs.cwd().openFile("./examples/stack.zig", .{});
.index = 6, defer file.close();
}, const widget = Widget.RawText.init(allocator, file);
}, break :blk widget;
.frame = .round, }),
.title = .{ })),
.str = "VStack", })),
.style = .{ },
.ul_style = .single, )),
.ul = .{ .index = 6 }, Widget.createFrom(Widget.Spacer.init(allocator)),
.bold = true, })),
}, }));
},
},
.{
.layout = Layout.createFrom(
padding: {
var padding = Layout.Margin.init(
allocator,
.{
.margin = 10,
},
.{
.layout = Layout.createFrom(vstack: {
var vstack = Layout.VStack.init(allocator, .{
Widget.createFrom(blk: {
const file = try std.fs.cwd().openFile("./examples/stack.zig", .{});
defer file.close();
var widget = Widget.RawText.init(allocator, file);
break :blk &widget;
}),
Widget.createFrom(blk: {
var spacer = Widget.Spacer.init();
break :blk &spacer;
}),
Widget.createFrom(blk: {
const file = try std.fs.cwd().openFile("./examples/stack.zig", .{});
defer file.close();
var widget = Widget.RawText.init(allocator, file);
break :blk &widget;
}),
});
break :vstack &vstack;
}),
},
);
break :padding &padding;
},
),
},
);
break :framing &framing;
}),
Widget.createFrom(blk: {
var spacer = Widget.Spacer.init();
break :blk &spacer;
}),
});
break :hstack &hstack;
}),
});
break :layout &framing;
});
defer layout.deinit(); defer layout.deinit();
try app.start(); try app.start();

View File

@@ -27,6 +27,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
const Events = std.ArrayList(Event); const Events = std.ArrayList(Event);
return struct { return struct {
allocator: std.mem.Allocator = undefined,
size: terminal.Size = undefined, size: terminal.Size = undefined,
require_render: bool = true, require_render: bool = true,
element: Element = undefined, element: Element = undefined,
@@ -49,12 +50,13 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
}; };
}; };
pub fn init(allocator: std.mem.Allocator, config: Config, element: Element) @This() { pub fn init(allocator: std.mem.Allocator, config: Config, element: Element) *@This() {
return .{ const layout = allocator.create(@This()) catch @panic("OOM");
.config = config, layout.allocator = allocator;
.element = element, layout.config = config;
.events = Events.init(allocator), layout.element = element;
}; layout.events = Events.init(allocator);
return layout;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -67,6 +69,8 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
widget.deinit(); widget.deinit();
}, },
} }
this.allocator.destroy(this);
this.* = undefined;
} }
pub fn handle(this: *@This(), event: Event) !*Events { pub fn handle(this: *@This(), event: Event) !*Events {

View File

@@ -36,11 +36,12 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
const Events = std.ArrayList(Event); const Events = std.ArrayList(Event);
return struct { return struct {
// TODO: current focused `Element`? // TODO: current focused `Element`?
allocator: std.mem.Allocator = undefined,
size: terminal.Size = undefined, size: terminal.Size = undefined,
containers: Containers = undefined, containers: Containers = undefined,
events: Events = undefined, events: Events = undefined,
pub fn init(allocator: std.mem.Allocator, children: anytype) @This() { pub fn init(allocator: std.mem.Allocator, children: anytype) *@This() {
const ArgsType = @TypeOf(children); const ArgsType = @TypeOf(children);
const args_type_info = @typeInfo(ArgsType); const args_type_info = @typeInfo(ArgsType);
if (args_type_info != .Struct) { if (args_type_info != .Struct) {
@@ -87,10 +88,11 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
@compileError("nested child: " ++ field.name ++ " is not of type " ++ @typeName(WidgetType) ++ " or " ++ @typeName(LayoutType) ++ " but " ++ @typeName(ChildType)); @compileError("nested child: " ++ field.name ++ " is not of type " ++ @typeName(WidgetType) ++ " or " ++ @typeName(LayoutType) ++ " but " ++ @typeName(ChildType));
} }
return .{ const layout = allocator.create(@This()) catch @panic("OOM");
.containers = containers, layout.allocator = allocator;
.events = Events.init(allocator), layout.containers = containers;
}; layout.events = Events.init(allocator);
return layout;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -106,6 +108,8 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
} }
this.containers.deinit(); this.containers.deinit();
this.allocator.destroy(this);
this.* = undefined;
} }
pub fn handle(this: *@This(), event: Event) !*Events { pub fn handle(this: *@This(), event: Event) !*Events {

View File

@@ -30,11 +30,12 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
const Events = std.ArrayList(Event); const Events = std.ArrayList(Event);
return struct { return struct {
// TODO: current focused `Element`? // TODO: current focused `Element`?
allocator: std.mem.Allocator = undefined,
size: terminal.Size = undefined, size: terminal.Size = undefined,
elements: Elements = undefined, elements: Elements = undefined,
events: Events = undefined, events: Events = undefined,
pub fn init(allocator: std.mem.Allocator, children: anytype) @This() { pub fn init(allocator: std.mem.Allocator, children: anytype) *@This() {
const ArgsType = @TypeOf(children); const ArgsType = @TypeOf(children);
const args_type_info = @typeInfo(ArgsType); const args_type_info = @typeInfo(ArgsType);
if (args_type_info != .Struct) { if (args_type_info != .Struct) {
@@ -55,10 +56,11 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
@compileError("child: " ++ field.name ++ " is not of type " ++ @typeName(WidgetType) ++ " or " ++ @typeName(LayoutType) ++ " but " ++ @typeName(ChildType)); @compileError("child: " ++ field.name ++ " is not of type " ++ @typeName(WidgetType) ++ " or " ++ @typeName(LayoutType) ++ " but " ++ @typeName(ChildType));
} }
return .{ const layout = allocator.create(@This()) catch @panic("OOM");
.elements = elements, layout.allocator = allocator;
.events = Events.init(allocator), layout.elements = elements;
}; layout.events = Events.init(allocator);
return layout;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -74,6 +76,8 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
} }
this.elements.deinit(); this.elements.deinit();
this.allocator.destroy(this);
this.* = undefined;
} }
pub fn handle(this: *@This(), event: Event) !*Events { pub fn handle(this: *@This(), event: Event) !*Events {

View File

@@ -26,6 +26,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
const Events = std.ArrayList(Event); const Events = std.ArrayList(Event);
return struct { return struct {
allocator: std.mem.Allocator = undefined,
size: terminal.Size = undefined, size: terminal.Size = undefined,
require_render: bool = false, require_render: bool = false,
element: Element = undefined, element: Element = undefined,
@@ -40,18 +41,19 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
bottom: u8 = 0, bottom: u8 = 0,
}; };
pub fn init(allocator: std.mem.Allocator, config: Config, element: Element) @This() { pub fn init(allocator: std.mem.Allocator, config: Config, element: Element) *@This() {
if (config.margin) |margin| { if (config.margin) |margin| {
std.debug.assert(margin <= 50); std.debug.assert(margin <= 50);
} else { } else {
std.debug.assert(config.left + config.right < 100); std.debug.assert(config.left + config.right < 100);
std.debug.assert(config.top + config.bottom < 100); std.debug.assert(config.top + config.bottom < 100);
} }
return .{ const layout = allocator.create(@This()) catch @panic("OOM");
.config = config, layout.allocator = allocator;
.element = element, layout.config = config;
.events = Events.init(allocator), layout.element = element;
}; layout.events = Events.init(allocator);
return layout;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -64,6 +66,8 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
widget.deinit(); widget.deinit();
}, },
} }
this.allocator.destroy(this);
this.* = undefined;
} }
pub fn handle(this: *@This(), event: Event) !*Events { pub fn handle(this: *@This(), event: Event) !*Events {

View File

@@ -26,6 +26,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
const Events = std.ArrayList(Event); const Events = std.ArrayList(Event);
return struct { return struct {
allocator: std.mem.Allocator = undefined,
size: terminal.Size = undefined, size: terminal.Size = undefined,
require_render: bool = false, require_render: bool = false,
element: Element = undefined, element: Element = undefined,
@@ -40,12 +41,13 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
bottom: u16 = 0, bottom: u16 = 0,
}; };
pub fn init(allocator: std.mem.Allocator, config: Config, element: Element) @This() { pub fn init(allocator: std.mem.Allocator, config: Config, element: Element) *@This() {
return .{ const layout = allocator.create(@This()) catch @panic("OOM");
.config = config, layout.allocator = allocator;
.element = element, layout.config = config;
.events = Events.init(allocator), layout.element = element;
}; layout.events = Events.init(allocator);
return layout;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -58,6 +60,8 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
widget.deinit(); widget.deinit();
}, },
} }
this.allocator.destroy(this);
this.* = undefined;
} }
pub fn handle(this: *@This(), event: Event) !*Events { pub fn handle(this: *@This(), event: Event) !*Events {

View File

@@ -36,11 +36,12 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
const Events = std.ArrayList(Event); const Events = std.ArrayList(Event);
return struct { return struct {
// TODO: current focused `Element`? // TODO: current focused `Element`?
allocator: std.mem.Allocator = undefined,
size: terminal.Size = undefined, size: terminal.Size = undefined,
containers: Containers = undefined, containers: Containers = undefined,
events: Events = undefined, events: Events = undefined,
pub fn init(allocator: std.mem.Allocator, children: anytype) @This() { pub fn init(allocator: std.mem.Allocator, children: anytype) *@This() {
const ArgsType = @TypeOf(children); const ArgsType = @TypeOf(children);
const args_type_info = @typeInfo(ArgsType); const args_type_info = @typeInfo(ArgsType);
if (args_type_info != .Struct) { if (args_type_info != .Struct) {
@@ -87,10 +88,11 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
@compileError("nested child: " ++ field.name ++ " is not of type " ++ @typeName(WidgetType) ++ " or " ++ @typeName(LayoutType) ++ " but " ++ @typeName(ChildType)); @compileError("nested child: " ++ field.name ++ " is not of type " ++ @typeName(WidgetType) ++ " or " ++ @typeName(LayoutType) ++ " but " ++ @typeName(ChildType));
} }
return .{ const layout = allocator.create(@This()) catch @panic("OOM");
.containers = containers, layout.allocator = allocator;
.events = Events.init(allocator), layout.containers = containers;
}; layout.events = Events.init(allocator);
return layout;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -106,6 +108,8 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
} }
this.containers.deinit(); this.containers.deinit();
this.allocator.destroy(this);
this.* = undefined;
} }
pub fn handle(this: *@This(), event: Event) !*Events { pub fn handle(this: *@This(), event: Event) !*Events {

View File

@@ -30,11 +30,12 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
const Events = std.ArrayList(Event); const Events = std.ArrayList(Event);
return struct { return struct {
// TODO: current focused `Element`? // TODO: current focused `Element`?
allocator: std.mem.Allocator = undefined,
size: terminal.Size = undefined, size: terminal.Size = undefined,
elements: Elements = undefined, elements: Elements = undefined,
events: Events = undefined, events: Events = undefined,
pub fn init(allocator: std.mem.Allocator, children: anytype) @This() { pub fn init(allocator: std.mem.Allocator, children: anytype) *@This() {
const ArgsType = @TypeOf(children); const ArgsType = @TypeOf(children);
const args_type_info = @typeInfo(ArgsType); const args_type_info = @typeInfo(ArgsType);
if (args_type_info != .Struct) { if (args_type_info != .Struct) {
@@ -55,10 +56,11 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
@compileError("child: " ++ field.name ++ " is not of type " ++ @typeName(WidgetType) ++ " or " ++ @typeName(LayoutType) ++ " but " ++ @typeName(ChildType)); @compileError("child: " ++ field.name ++ " is not of type " ++ @typeName(WidgetType) ++ " or " ++ @typeName(LayoutType) ++ " but " ++ @typeName(ChildType));
} }
return .{ const layout = allocator.create(@This()) catch @panic("OOM");
.elements = elements, layout.allocator = allocator;
.events = Events.init(allocator), layout.elements = elements;
}; layout.events = Events.init(allocator);
return layout;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -74,6 +76,8 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
} }
this.elements.deinit(); this.elements.deinit();
this.allocator.destroy(this);
this.* = undefined;
} }
pub fn handle(this: *@This(), event: Event) !*Events { pub fn handle(this: *@This(), event: Event) !*Events {

View File

@@ -14,13 +14,14 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
} }
const Contents = std.ArrayList(u8); const Contents = std.ArrayList(u8);
return struct { return struct {
allocator: std.mem.Allocator = undefined,
contents: Contents = undefined, contents: Contents = undefined,
line_index: std.ArrayList(usize) = undefined, line_index: std.ArrayList(usize) = undefined,
line: usize = 0, line: usize = 0,
size: terminal.Size = undefined, size: terminal.Size = undefined,
require_render: bool = false, require_render: bool = false,
pub fn init(allocator: std.mem.Allocator, file: std.fs.File) @This() { pub fn init(allocator: std.mem.Allocator, file: std.fs.File) *@This() {
var contents = Contents.init(allocator); var contents = Contents.init(allocator);
var line_index = std.ArrayList(usize).init(allocator); var line_index = std.ArrayList(usize).init(allocator);
file.reader().readAllArrayList(&contents, std.math.maxInt(usize)) catch {}; file.reader().readAllArrayList(&contents, std.math.maxInt(usize)) catch {};
@@ -30,15 +31,17 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
line_index.append(i + 1) catch {}; line_index.append(i + 1) catch {};
} }
} }
return .{ const widget = allocator.create(@This()) catch @panic("OOM");
.contents = contents, widget.allocator = allocator;
.line_index = line_index, widget.contents = contents;
}; widget.line_index = line_index;
return widget;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
this.contents.deinit(); this.contents.deinit();
this.line_index.deinit(); this.line_index.deinit();
this.allocator.destroy(this);
this.* = undefined; this.* = undefined;
} }

View File

@@ -11,14 +11,18 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
@compileError("Provided user event `Event` for `Layout(comptime Event: type)` is not of type `union(enum)`."); @compileError("Provided user event `Event` for `Layout(comptime Event: type)` is not of type `union(enum)`.");
} }
return struct { return struct {
allocator: std.mem.Allocator = undefined,
size: terminal.Size = undefined, size: terminal.Size = undefined,
size_changed: bool = false, size_changed: bool = false,
pub fn init() @This() { pub fn init(allocator: std.mem.Allocator) *@This() {
return .{}; const widget = allocator.create(@This()) catch @panic("OOM");
widget.allocator = allocator;
return widget;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
this.allocator.destroy(this);
this.* = undefined; this.* = undefined;
} }

View File

@@ -12,6 +12,7 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
@compileError("Provided user event `Event` for `Layout(comptime Event: type)` is not of type `union(enum)`."); @compileError("Provided user event `Event` for `Layout(comptime Event: type)` is not of type `union(enum)`.");
} }
return struct { return struct {
allocator: std.mem.Allocator = undefined,
alignment: Alignment = undefined, alignment: Alignment = undefined,
contents: []const Cell = undefined, contents: []const Cell = undefined,
size: terminal.Size = undefined, size: terminal.Size = undefined,
@@ -26,14 +27,16 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
right, right,
}; };
pub fn init(alignment: Alignment, contents: []const Cell) @This() { pub fn init(allocator: std.mem.Allocator, alignment: Alignment, contents: []const Cell) *@This() {
return .{ const widget = allocator.create(@This()) catch @panic("OOM");
.alignment = alignment, widget.allocator = allocator;
.contents = contents, widget.alignment = alignment;
}; widget.contents = contents;
return widget;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
this.allocator.destroy(this);
this.* = undefined; this.* = undefined;
} }