mod(memory): do not create items on the stack instead using the provided allocator
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 4m26s

This commit is contained in:
2025-01-06 21:56:04 +01:00
parent 04e1ca087f
commit c2c3f41ff3
21 changed files with 404 additions and 464 deletions

View File

@@ -30,56 +30,37 @@ 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; break :blk Widget.RawText.init(allocator, file);
}), }),
25, 50,
}, },
.{ .{
Widget.createFrom(blk: { Widget.createFrom(Widget.Spacer.init(allocator)),
const file = try std.fs.cwd().openFile("./src/app.zig", .{}); 25,
defer file.close(); },
var widget = Widget.RawText.init(allocator, file); })),
break :blk &widget; 70,
}), },
50, .{
}, Widget.createFrom(Widget.Spacer.init(allocator)),
.{ 15,
Widget.createFrom(blk: { },
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(null); try app.start(null);

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();
const min_size: zterm.Size = .{ const min_size: zterm.Size = .{

View File

@@ -30,54 +30,44 @@ 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(
.layout = Layout.createFrom(framing: { allocator,
var framing = Layout.Framing.init( .{
.style = .{
.fg = .{
.index = 6,
},
},
.frame = .round,
.title = .{
.str = "Content in Margin",
.style = .{
.ul_style = .single,
.ul = .{ .index = 6 },
.bold = true,
},
},
},
.{
.layout = Layout.createFrom(Layout.Margin.init(
allocator, allocator,
.{ .{
.style = .{ .margin = 10,
.fg = .{
.index = 6,
},
},
.frame = .round,
.title = .{
.str = "Content in Margin",
.style = .{
.ul_style = .single,
.ul = .{ .index = 6 },
.bold = true,
},
},
}, },
.{ .{
.layout = Layout.createFrom(margin: { .widget = Widget.createFrom(blk: {
var margin = Layout.Margin.init( const file = try std.fs.cwd().openFile("./examples/padding.zig", .{});
allocator, defer file.close();
.{ break :blk Widget.RawText.init(allocator, file);
.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(null); try app.start(null);

View File

@@ -30,97 +30,71 @@ 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 = Layout.createFrom(hstack: { Layout.Margin.init(
var hstack = Layout.HStack.init(allocator, .{
Widget.createFrom(blk: {
var spacer = Widget.Spacer.init();
break :blk &spacer;
}),
Layout.createFrom(framing: {
var framing = Layout.Framing.init(
allocator, allocator,
.{ .{
.style = .{ .margin = 10,
.fg = .{
.index = 6,
},
},
.frame = .round,
.title = .{
.str = "VStack",
.style = .{
.ul_style = .single,
.ul = .{ .index = 6 },
.bold = true,
},
},
}, },
.{ .{
.layout = Layout.createFrom( .layout = Layout.createFrom(Layout.VStack.init(allocator, .{
padding: { Widget.createFrom(blk: {
var padding = Layout.Margin.init( const file = try std.fs.cwd().openFile("./examples/stack.zig", .{});
allocator, defer file.close();
.{ break :blk Widget.RawText.init(allocator, file);
.margin = 10, }),
}, Widget.createFrom(Widget.Spacer.init(allocator)),
.{ Widget.createFrom(blk: {
.layout = Layout.createFrom(vstack: { const file = try std.fs.cwd().openFile("./examples/stack.zig", .{});
var vstack = Layout.VStack.init(allocator, .{ defer file.close();
Widget.createFrom(blk: { break :blk Widget.RawText.init(allocator, file);
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(); Widget.createFrom(Widget.Spacer.init(allocator)),
break :blk &spacer; })),
}), }));
});
break :hstack &hstack;
}),
});
break :layout &framing;
});
defer layout.deinit(); defer layout.deinit();
try app.start(null); try app.start(null);

View File

@@ -31,62 +31,46 @@ 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.Tab.init(allocator, .{}, .{
var tabs = Layout.Tab.init(allocator, .{}, .{ .{
.{ Layout.createFrom(Layout.Margin.init(allocator, .{ .margin = 10 }, .{
Layout.createFrom(margin: { .widget = Widget.createFrom(blk: {
var margin = Layout.Margin.init(allocator, .{ .margin = 10 }, .{ const file = try std.fs.cwd().openFile("./examples/tabs.zig", .{});
.widget = Widget.createFrom(blk: { defer file.close();
const file = try std.fs.cwd().openFile("./examples/tabs.zig", .{}); break :blk Widget.RawText.init(allocator, file);
defer file.close();
var widget = Widget.RawText.init(allocator, file);
break :blk &widget;
}),
});
break :margin &margin;
}), }),
"Tab 2", })),
Cell.Style.Color{ .index = 6 }, "Tab 2",
}, Cell.Style.Color{ .index = 6 },
.{ },
Layout.createFrom(framing: { .{
var framing = Layout.Framing.init( Layout.createFrom(Layout.Framing.init(
allocator, allocator,
.{ .{
.frame = .round, .frame = .round,
.title = .{ .title = .{
.str = "Content in Margin", .str = "Content in Margin",
.style = .{ .style = .{
.ul_style = .single, .ul_style = .single,
.ul = .{ .index = 4 }, .ul = .{ .index = 4 },
.bold = true, .bold = true,
},
},
}, },
.{ },
.layout = Layout.createFrom(margin: { },
var margin = Layout.Margin.init(allocator, .{ .margin = 10 }, .{ .{
.widget = Widget.createFrom(blk: { .layout = Layout.createFrom(Layout.Margin.init(allocator, .{ .margin = 10 }, .{
var widget = Widget.List.init(allocator, .ordered, .{ .widget = Widget.createFrom(Widget.List.init(allocator, .ordered, .{
&[_]Cell{.{ .content = "First entry" }}, &[_]Cell{.{ .content = "First entry" }},
&[_]Cell{.{ .content = "Second entry" }}, &[_]Cell{.{ .content = "Second entry" }},
&[_]Cell{.{ .content = "Third entry" }}, &[_]Cell{.{ .content = "Third entry" }},
}); })),
break :blk &widget; })),
}), },
}); )),
break :margin &margin; "Tab 1",
}), Cell.Style.Color{ .index = 4 },
}, },
); }));
break :framing &framing;
}),
"Tab 1",
Cell.Style.Color{ .index = 4 },
},
});
break :layout &tabs;
});
defer layout.deinit(); defer layout.deinit();
try app.start(null); try app.start(null);

View File

@@ -25,73 +25,49 @@ pub fn main() !void {
var renderer: App.Renderer = .{}; var renderer: App.Renderer = .{};
// FIXME: the layout creates an 'incorrect alignment'? // FIXME: the layout creates an 'incorrect alignment'?
var layout = Layout.createFrom(layout: { var layout = Layout.createFrom(Layout.VContainer.init(allocator, .{
var layout = Layout.VContainer.init(allocator, .{ .{
.{ Layout.createFrom(Layout.Framing.init(allocator, .{
Layout.createFrom(framing: { .title = .{
var framing = Layout.Framing.init(allocator, .{ .str = "Welcome to my terminal website",
.title = .{ .style = .{
.str = "Welcome to my terminal website", .ul = .{ .index = 6 },
.style = .{ .ul_style = .single,
.ul = .{ .index = 6 }, },
.ul_style = .single, },
}, }, .{
}, .layout = Layout.createFrom(Layout.HContainer.init(allocator, .{
}, .{ .{
.layout = Layout.createFrom(hcontainer: { Widget.createFrom(Widget.Text.init(allocator, .left, &[1]Cell{
var hcontainer = Layout.HContainer.init(allocator, .{ .{ .content = "Yves Biener", .style = .{ .bold = true } },
.{ })),
Widget.createFrom(text: { 25,
var text = Widget.Text.init(.left, &[1]Cell{ },
.{ .content = "Yves Biener", .style = .{ .bold = true } }, .{
}); Widget.createFrom(Widget.Text.init(allocator, .left, &[1]Cell{
break :text &text; .{ .content = "File name", .style = .{ .bold = true } },
}), })),
25, 50,
}, },
.{ .{
Widget.createFrom(text: { Widget.createFrom(Widget.Text.init(allocator, .left, &[1]Cell{
var text = Widget.Text.init(.left, &[1]Cell{ .{ .content = "Contacts", .style = .{ .bold = true } },
.{ .content = "File name", .style = .{ .bold = true } }, })),
}); 25,
break :text &text; },
}), })),
50, })),
}, 10,
.{ },
Widget.createFrom(text: { .{
var text = Widget.Text.init(.left, &[1]Cell{ Layout.createFrom(Layout.Margin.init(allocator, .{ .left = 15, .right = 15 }, .{
.{ .content = "Contacts", .style = .{ .bold = true } }, .widget = Widget.createFrom(Widget.Text.init(allocator, .default, &[1]Cell{
}); .{ .content = "Does this change anything", .style = .{ .ul = .default, .ul_style = .single } },
break :text &text; })),
}), })),
25, 90,
}, },
}); }));
break :hcontainer &hcontainer;
}),
});
break :framing &framing;
}),
10,
},
.{
Layout.createFrom(margin: {
var margin = Layout.Margin.init(allocator, .{ .left = 15, .right = 15 }, .{
.widget = Widget.createFrom(text: {
var text = Widget.Text.init(.default, &[1]Cell{
.{ .content = "Does this change anything", .style = .{ .ul = .default, .ul_style = .single } },
});
break :text &text;
}),
});
break :margin &margin;
}),
90,
},
});
break :layout &layout;
});
defer layout.deinit(); defer layout.deinit();
try app.start(null); try app.start(null);

View File

@@ -52,7 +52,6 @@ pub fn Layout(comptime Event: type, comptime Renderer: type) type {
pub fn deinit(this: *LayoutType) void { pub fn deinit(this: *LayoutType) void {
this.vtable.deinit(this); this.vtable.deinit(this);
this.* = undefined;
} }
pub fn createFrom(object: anytype) LayoutType { pub fn createFrom(object: anytype) LayoutType {

View File

@@ -27,11 +27,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 {
size: terminal.Size = undefined, allocator: std.mem.Allocator,
require_render: bool = true, size: terminal.Size,
element: Element = undefined, require_render: bool,
events: Events = undefined, element: Element,
config: Config = undefined, events: Events,
config: Config,
const Config = struct { const Config = struct {
style: Style = .{ .fg = .default }, style: Style = .{ .fg = .default },
@@ -49,12 +50,14 @@ 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 .{ var this = allocator.create(@This()) catch @panic("Framing.zig: Failed to create.");
.config = config, this.allocator = allocator;
.element = element, this.require_render = true;
.events = Events.init(allocator), this.config = config;
}; this.element = element;
this.events = Events.init(allocator);
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -67,6 +70,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
widget.deinit(); widget.deinit();
}, },
} }
this.allocator.destroy(this);
} }
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`?
size: terminal.Size = undefined, allocator: std.mem.Allocator,
containers: Containers = undefined, size: terminal.Size,
events: Events = undefined, containers: Containers,
events: Events,
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 .{ var this = allocator.create(@This()) catch @panic("HContainer.zig: Failed to create.");
.containers = containers, this.allocator = allocator;
.events = Events.init(allocator), this.containers = containers;
}; this.events = Events.init(allocator);
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -106,6 +108,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
} }
this.containers.deinit(); this.containers.deinit();
this.allocator.destroy(this);
} }
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`?
size: terminal.Size = undefined, allocator: std.mem.Allocator,
elements: Elements = undefined, size: terminal.Size,
events: Events = undefined, elements: Elements,
events: Events,
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 .{ var this = allocator.create(@This()) catch @panic("HStack.zig: Failed to create.");
.elements = elements, this.allocator = allocator;
.events = Events.init(allocator), this.elements = elements;
}; this.events = Events.init(allocator);
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -74,6 +76,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
} }
this.elements.deinit(); this.elements.deinit();
this.allocator.destroy(this);
} }
pub fn handle(this: *@This(), event: Event) !*Events { pub fn handle(this: *@This(), event: Event) !*Events {

View File

@@ -26,11 +26,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 {
size: terminal.Size = undefined, allocator: std.mem.Allocator,
require_render: bool = false, size: terminal.Size,
element: Element = undefined, require_render: bool,
events: Events = undefined, element: Element,
config: Config = undefined, events: Events,
config: Config,
const Config = struct { const Config = struct {
margin: ?u8 = null, margin: ?u8 = null,
@@ -40,18 +41,20 @@ 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 .{ var this = allocator.create(@This()) catch @panic("Margin.zig: Failed to create.");
.config = config, this.allocator = allocator;
.element = element, this.require_render = true;
.events = Events.init(allocator), this.config = config;
}; this.element = element;
this.events = Events.init(allocator);
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -64,6 +67,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
widget.deinit(); widget.deinit();
}, },
} }
this.allocator.destroy(this);
} }
pub fn handle(this: *@This(), event: Event) !*Events { pub fn handle(this: *@This(), event: Event) !*Events {

View File

@@ -26,11 +26,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 {
size: terminal.Size = undefined, allocator: std.mem.Allocator,
require_render: bool = false, size: terminal.Size,
element: Element = undefined, require_render: bool,
events: Events = undefined, element: Element,
config: Config = undefined, events: Events,
config: Config,
const Config = struct { const Config = struct {
padding: ?u16 = null, padding: ?u16 = null,
@@ -40,12 +41,14 @@ 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 .{ var this = allocator.create(@This()) catch @panic("Padding.zig: Failed to create.");
.config = config, this.allocator = allocator;
.element = element, this.require_render = true;
.events = Events.init(allocator), this.config = config;
}; this.element = element;
this.events = Events.init(allocator);
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -58,6 +61,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
widget.deinit(); widget.deinit();
}, },
} }
this.allocator.destroy(this);
} }
pub fn handle(this: *@This(), event: Event) !*Events { pub fn handle(this: *@This(), event: Event) !*Events {

View File

@@ -37,12 +37,13 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
}; };
const Tabs = std.ArrayList(Tab); const Tabs = std.ArrayList(Tab);
return struct { return struct {
size: terminal.Size = undefined, allocator: std.mem.Allocator,
require_render: bool = true, size: terminal.Size,
tabs: Tabs = undefined, require_render: bool,
active_tab: usize = 0, tabs: Tabs,
events: Events = undefined, active_tab: usize,
config: Config = undefined, events: Events,
config: Config,
const Config = struct { const Config = struct {
frame: Frame = .round, frame: Frame = .round,
@@ -53,7 +54,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
}; };
}; };
pub fn init(allocator: std.mem.Allocator, config: Config, children: anytype) @This() { pub fn init(allocator: std.mem.Allocator, config: Config, 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") {
@@ -104,11 +105,14 @@ 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 .{ var this = allocator.create(@This()) catch @panic("Tab.zig: Failed to create.");
.config = config, this.allocator = allocator;
.tabs = tabs, this.active_tab = 0;
.events = Events.init(allocator), this.require_render = true;
}; this.config = config;
this.tabs = tabs;
this.events = Events.init(allocator);
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -124,6 +128,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
} }
this.tabs.deinit(); this.tabs.deinit();
this.allocator.destroy(this);
} }
fn resize_active_tab(this: *@This()) !void { fn resize_active_tab(this: *@This()) !void {

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`?
size: terminal.Size = undefined, allocator: std.mem.Allocator,
containers: Containers = undefined, size: terminal.Size,
events: Events = undefined, containers: Containers,
events: Events,
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 .{ var this = allocator.create(@This()) catch @panic("VContainer.zig: Failed to create.");
.containers = containers, this.allocator = allocator;
.events = Events.init(allocator), this.containers = containers;
}; this.events = Events.init(allocator);
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -106,6 +108,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
} }
this.containers.deinit(); this.containers.deinit();
this.allocator.destroy(this);
} }
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`?
size: terminal.Size = undefined, allocator: std.mem.Allocator,
elements: Elements = undefined, size: terminal.Size,
events: Events = undefined, elements: Elements,
events: Events,
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 .{ var this = allocator.create(@This()) catch @panic("VStack.zig: Failed to create.");
.elements = elements, this.allocator = allocator;
.events = Events.init(allocator), this.elements = elements;
}; this.events = Events.init(allocator);
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
@@ -74,6 +76,7 @@ pub fn Layout(comptime Event: type, comptime Element: type, comptime Renderer: t
} }
} }
this.elements.deinit(); this.elements.deinit();
this.allocator.destroy(this);
} }
pub fn handle(this: *@This(), event: Event) !*Events { pub fn handle(this: *@This(), event: Event) !*Events {

View File

@@ -58,7 +58,6 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
pub fn deinit(this: *WidgetType) void { pub fn deinit(this: *WidgetType) void {
this.vtable.deinit(this); this.vtable.deinit(this);
this.* = undefined;
} }
pub fn createFrom(object: anytype) WidgetType { pub fn createFrom(object: anytype) WidgetType {

View File

@@ -13,30 +13,38 @@ 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 {
active: bool = false, active: bool,
allocator: std.mem.Allocator = undefined, allocator: std.mem.Allocator,
label: ?[]const u8 = null, label: ?[]const u8,
placeholder: ?[]const u8 = null, placeholder: ?[]const u8,
size: Size = undefined, size: Size,
require_render: bool = false, require_render: bool,
value: std.ArrayList(u8) = undefined, value: std.ArrayList(u8),
value_len: usize = 0, // value content length /// value content length
cursor_idx: usize = 0, // current cursor position value_len: usize,
/// current cursor position
cursor_idx: usize,
pub fn init(allocator: std.mem.Allocator, label: ?[]const u8, placeholder: ?[]const u8) @This() { pub fn init(allocator: std.mem.Allocator, label: ?[]const u8, placeholder: ?[]const u8) *@This() {
var value = std.ArrayList(u8).init(allocator); var value = std.ArrayList(u8).init(allocator);
value.resize(32) catch @panic("Input.zig: out of memory"); value.resize(32) catch @panic("Input.zig: out of memory");
return .{ var this = allocator.create(@This()) catch @panic("Input.zig: Failed to create.");
.allocator = allocator, this.allocator = allocator;
.value = value, this.active = false;
.label = label, this.require_render = true;
.placeholder = placeholder, this.label = null;
}; this.placeholder = null;
this.value_len = 0;
this.cursor_idx = 0;
this.value = value;
this.label = label;
this.placeholder = placeholder;
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
this.value.deinit(); this.value.deinit();
this.* = undefined; this.allocator.destroy(this);
} }
pub fn getValue(this: *const @This()) []const u8 { pub fn getValue(this: *const @This()) []const u8 {

View File

@@ -14,18 +14,19 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
} }
const ListItems = std.ArrayList([]const Cell); const ListItems = std.ArrayList([]const Cell);
return struct { return struct {
idx: usize = 0, allocator: std.mem.Allocator,
config: ListType = undefined, idx: usize,
contents: ListItems = undefined, config: ListType,
size: terminal.Size = undefined, contents: ListItems,
require_render: bool = false, size: terminal.Size,
require_render: bool,
const ListType = enum { const ListType = enum {
unordered, unordered,
ordered, ordered,
}; };
pub fn init(allocator: std.mem.Allocator, config: ListType, children: anytype) @This() { pub fn init(allocator: std.mem.Allocator, config: ListType, 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") {
@@ -42,15 +43,18 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
} }
contents.append(child) catch {}; contents.append(child) catch {};
} }
return .{ var this = allocator.create(@This()) catch @panic("List.zig: Failed to create.");
.config = config, this.allocator = allocator;
.contents = contents, this.require_render = true;
}; this.idx = 0;
this.config = config;
this.contents = contents;
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
this.contents.deinit(); this.contents.deinit();
this.* = undefined; this.allocator.destroy(this);
} }
pub fn handle(this: *@This(), event: Event) ?Event { pub fn handle(this: *@This(), event: Event) ?Event {

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 {
contents: Contents = undefined, allocator: std.mem.Allocator,
line_index: std.ArrayList(usize) = undefined, contents: Contents,
line: usize = 0, line_index: std.ArrayList(usize),
size: terminal.Size = undefined, line: usize,
require_render: bool = false, size: terminal.Size,
require_render: bool,
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,16 +31,19 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
line_index.append(i + 1) catch {}; line_index.append(i + 1) catch {};
} }
} }
return .{ var this = allocator.create(@This()) catch @panic("RawText.zig: Failed to create.");
.contents = contents, this.allocator = allocator;
.line_index = line_index, this.line = 0;
}; this.require_render = true;
this.contents = contents;
this.line_index = line_index;
return this;
} }
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.* = undefined; this.allocator.destroy(this);
} }
pub fn handle(this: *@This(), event: Event) ?Event { pub fn handle(this: *@This(), event: Event) ?Event {

View File

@@ -11,15 +11,19 @@ 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 {
size: terminal.Size = undefined, allocator: std.mem.Allocator,
size_changed: bool = false, size: terminal.Size,
size_changed: bool,
pub fn init() @This() { pub fn init(allocator: std.mem.Allocator) *@This() {
return .{}; var this = allocator.create(@This()) catch @panic("Space.zig: Failed to create.");
this.allocator = allocator;
this.size_changed = true;
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
this.* = undefined; this.allocator.destroy(this);
} }
pub fn handle(this: *@This(), event: Event) ?Event { pub fn handle(this: *@This(), event: Event) ?Event {

View File

@@ -12,10 +12,11 @@ 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 {
alignment: Alignment = undefined, allocator: std.mem.Allocator,
contents: []const Cell = undefined, alignment: Alignment,
size: terminal.Size = undefined, contents: []const Cell,
require_render: bool = false, size: terminal.Size,
require_render: bool,
const Alignment = enum { const Alignment = enum {
default, default,
@@ -26,15 +27,17 @@ 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 .{ var this = allocator.create(@This()) catch @panic("Text.zig: Failed to create");
.alignment = alignment, this.allocator = allocator;
.contents = contents, this.require_render = true;
}; this.alignment = alignment;
this.contents = contents;
return this;
} }
pub fn deinit(this: *@This()) void { pub fn deinit(this: *@This()) void {
this.* = undefined; this.allocator.destroy(this);
} }
pub fn handle(this: *@This(), event: Event) ?Event { pub fn handle(this: *@This(), event: Event) ?Event {