mod(element): introduce deinit interface for deinitializing Elements automatically with the Container
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 1m34s
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 1m34s
This commit is contained in:
@@ -66,7 +66,6 @@ pub fn main() !void {
|
|||||||
try box.append(try App.Container.init(allocator, .{
|
try box.append(try App.Container.init(allocator, .{
|
||||||
.rectangle = .{ .fill = .lightgreen },
|
.rectangle = .{ .fill = .lightgreen },
|
||||||
}, .{}));
|
}, .{}));
|
||||||
defer box.deinit();
|
|
||||||
|
|
||||||
var scrollable: App.Scrollable = .init(box, .disabled);
|
var scrollable: App.Scrollable = .init(box, .disabled);
|
||||||
|
|
||||||
|
|||||||
@@ -73,8 +73,6 @@ pub fn main() !void {
|
|||||||
defer renderer.deinit();
|
defer renderer.deinit();
|
||||||
|
|
||||||
var input_field: App.Input(.accept) = .init(allocator, &app.queue, .init(.black, .blue));
|
var input_field: App.Input(.accept) = .init(allocator, &app.queue, .init(.black, .blue));
|
||||||
defer input_field.deinit();
|
|
||||||
|
|
||||||
var mouse_draw: MouseDraw = .{};
|
var mouse_draw: MouseDraw = .{};
|
||||||
var second_mouse_draw: MouseDraw = .{};
|
var second_mouse_draw: MouseDraw = .{};
|
||||||
var quit_text: QuitText = .{};
|
var quit_text: QuitText = .{};
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ pub fn main() !void {
|
|||||||
.dim = .{ .y = 2 },
|
.dim = .{ .y = 2 },
|
||||||
},
|
},
|
||||||
}, .{}));
|
}, .{}));
|
||||||
defer top_box.deinit();
|
|
||||||
|
|
||||||
var bottom_box = try App.Container.init(allocator, .{
|
var bottom_box = try App.Container.init(allocator, .{
|
||||||
.border = .{
|
.border = .{
|
||||||
@@ -134,7 +133,6 @@ pub fn main() !void {
|
|||||||
try bottom_box.append(try App.Container.init(allocator, .{
|
try bottom_box.append(try App.Container.init(allocator, .{
|
||||||
.rectangle = .{ .fill = .grey },
|
.rectangle = .{ .fill = .grey },
|
||||||
}, .{}));
|
}, .{}));
|
||||||
defer bottom_box.deinit();
|
|
||||||
|
|
||||||
var container = try App.Container.init(allocator, .{
|
var container = try App.Container.init(allocator, .{
|
||||||
.layout = .{
|
.layout = .{
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ pub fn main() !void {
|
|||||||
var box = try App.Container.init(allocator, .{
|
var box = try App.Container.init(allocator, .{
|
||||||
.layout = .{ .direction = .horizontal },
|
.layout = .{ .direction = .horizontal },
|
||||||
}, .{});
|
}, .{});
|
||||||
defer box.deinit();
|
|
||||||
|
|
||||||
inline for (std.meta.fields(zterm.Color)) |field| {
|
inline for (std.meta.fields(zterm.Color)) |field| {
|
||||||
if (field.value == 0) continue; // zterm.Color.default == 0 -> skip
|
if (field.value == 0) continue; // zterm.Color.default == 0 -> skip
|
||||||
|
|||||||
@@ -207,12 +207,9 @@ pub fn main() !void {
|
|||||||
},
|
},
|
||||||
}, table_head.element()));
|
}, table_head.element()));
|
||||||
|
|
||||||
var box = try App.Container.init(allocator, .{
|
var scrollable: App.Scrollable = .init(try .init(allocator, .{
|
||||||
.layout = .{ .direction = .vertical },
|
.layout = .{ .direction = .vertical },
|
||||||
}, text_styles.element());
|
}, text_styles.element()), .enabled(.white, true));
|
||||||
defer box.deinit();
|
|
||||||
|
|
||||||
var scrollable: App.Scrollable = .init(box, .disabled);
|
|
||||||
try container.append(try App.Container.init(allocator, .{}, scrollable.element()));
|
try container.append(try App.Container.init(allocator, .{}, scrollable.element()));
|
||||||
|
|
||||||
try app.start();
|
try app.start();
|
||||||
|
|||||||
@@ -648,6 +648,7 @@ pub fn Container(Model: type, Event: type) type {
|
|||||||
pub fn deinit(this: *@This()) void {
|
pub fn deinit(this: *@This()) void {
|
||||||
for (this.elements.items) |*element| element.deinit();
|
for (this.elements.items) |*element| element.deinit();
|
||||||
this.elements.deinit(this.allocator);
|
this.elements.deinit(this.allocator);
|
||||||
|
this.element.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append(this: *@This(), element: @This()) !void {
|
pub fn append(this: *@This(), element: @This()) !void {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pub fn Element(Model: type, Event: type) type {
|
|||||||
vtable: *const VTable = &.{},
|
vtable: *const VTable = &.{},
|
||||||
|
|
||||||
pub const VTable = struct {
|
pub const VTable = struct {
|
||||||
|
deinit: ?*const fn (ctx: *anyopaque) void = null,
|
||||||
minSize: ?*const fn (ctx: *anyopaque, model: *const Model, size: Point) Point = null,
|
minSize: ?*const fn (ctx: *anyopaque, model: *const Model, size: Point) Point = null,
|
||||||
resize: ?*const fn (ctx: *anyopaque, model: *const Model, size: Point) void = null,
|
resize: ?*const fn (ctx: *anyopaque, model: *const Model, size: Point) void = null,
|
||||||
reposition: ?*const fn (ctx: *anyopaque, model: *const Model, origin: Point) void = null,
|
reposition: ?*const fn (ctx: *anyopaque, model: *const Model, origin: Point) void = null,
|
||||||
@@ -22,6 +23,20 @@ pub fn Element(Model: type, Event: type) type {
|
|||||||
content: ?*const fn (ctx: *anyopaque, model: *const Model, cells: []Cell, size: Point) anyerror!void = null,
|
content: ?*const fn (ctx: *anyopaque, model: *const Model, cells: []Cell, size: Point) anyerror!void = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Deinitialize the `Element`. Each `Element` that requires an
|
||||||
|
/// `Allocator` shall keep one in their instance as no `Allocator`
|
||||||
|
/// will be passed through to the `deinit` call. The `deinit` function
|
||||||
|
/// is called from the root `Container` for every `Element` in the
|
||||||
|
/// `Container` tree to deinitialize the entire tree.
|
||||||
|
///
|
||||||
|
/// This function is only necessary to provide if the `Element`
|
||||||
|
/// implementation does allocate memory that should be cleaned up at
|
||||||
|
/// the end.
|
||||||
|
pub inline fn deinit(this: @This()) void {
|
||||||
|
if (this.vtable.deinit) |deinit_fn|
|
||||||
|
deinit_fn(this.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/// Request the minimal size required for this `Element` the provided
|
/// Request the minimal size required for this `Element` the provided
|
||||||
/// available *size* can be used as a fallback. This function ensures
|
/// available *size* can be used as a fallback. This function ensures
|
||||||
/// that the minimal size returned has at least the dimensions of the
|
/// that the minimal size returned has at least the dimensions of the
|
||||||
@@ -149,10 +164,16 @@ pub fn Alignment(Model: type, Event: type) type {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deinit(ctx: *anyopaque) void {
|
||||||
|
const this: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
|
this.container.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn element(this: *@This()) Element(Model, Event) {
|
pub fn element(this: *@This()) Element(Model, Event) {
|
||||||
return .{
|
return .{
|
||||||
.ptr = this,
|
.ptr = this,
|
||||||
.vtable = &.{
|
.vtable = &.{
|
||||||
|
.deinit = deinit,
|
||||||
.resize = resize,
|
.resize = resize,
|
||||||
.reposition = reposition,
|
.reposition = reposition,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
@@ -258,10 +279,16 @@ pub fn Scrollable(Model: type, Event: type) type {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deinit(ctx: *anyopaque) void {
|
||||||
|
const this: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
|
this.container.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn element(this: *@This()) Element(Model, Event) {
|
pub fn element(this: *@This()) Element(Model, Event) {
|
||||||
return .{
|
return .{
|
||||||
.ptr = this,
|
.ptr = this,
|
||||||
.vtable = &.{
|
.vtable = &.{
|
||||||
|
.deinit = deinit,
|
||||||
.resize = resize,
|
.resize = resize,
|
||||||
.reposition = reposition,
|
.reposition = reposition,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
@@ -506,7 +533,7 @@ pub fn Input(Model: type, Event: type, Queue: type) fn (meta.FieldEnum(Event)) t
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
return struct {
|
return struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: Allocator,
|
||||||
/// Offset from the end describing the current position of the cursor.
|
/// Offset from the end describing the current position of the cursor.
|
||||||
cursor_offset: usize = 0,
|
cursor_offset: usize = 0,
|
||||||
/// Configuration for the InputField.
|
/// Configuration for the InputField.
|
||||||
@@ -529,7 +556,7 @@ pub fn Input(Model: type, Event: type, Queue: type) fn (meta.FieldEnum(Event)) t
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(allocator: std.mem.Allocator, queue: *Queue, configuration: Configuration) @This() {
|
pub fn init(allocator: Allocator, queue: *Queue, configuration: Configuration) @This() {
|
||||||
return .{
|
return .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.configuration = configuration,
|
.configuration = configuration,
|
||||||
@@ -538,7 +565,8 @@ pub fn Input(Model: type, Event: type, Queue: type) fn (meta.FieldEnum(Event)) t
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(this: *@This()) void {
|
fn deinit(ctx: *anyopaque) void {
|
||||||
|
const this: *@This() = @ptrCast(@alignCast(ctx));
|
||||||
this.input.deinit(this.allocator);
|
this.input.deinit(this.allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,6 +574,7 @@ pub fn Input(Model: type, Event: type, Queue: type) fn (meta.FieldEnum(Event)) t
|
|||||||
return .{
|
return .{
|
||||||
.ptr = this,
|
.ptr = this,
|
||||||
.vtable = &.{
|
.vtable = &.{
|
||||||
|
.deinit = deinit,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
.content = content,
|
.content = content,
|
||||||
},
|
},
|
||||||
@@ -1087,6 +1116,7 @@ pub fn Progress(Model: type, Event: type, Queue: type) fn (meta.FieldEnum(Event)
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
const meta = std.meta;
|
const meta = std.meta;
|
||||||
const build_options = @import("build_options");
|
const build_options = @import("build_options");
|
||||||
const input = @import("input.zig");
|
const input = @import("input.zig");
|
||||||
@@ -1134,7 +1164,6 @@ test "scrollable vertical" {
|
|||||||
try box.append(try .init(allocator, .{
|
try box.append(try .init(allocator, .{
|
||||||
.rectangle = .{ .fill = .grey },
|
.rectangle = .{ .fill = .grey },
|
||||||
}, .{}));
|
}, .{}));
|
||||||
defer box.deinit();
|
|
||||||
|
|
||||||
var scrollable: Scrollable(Model, event.SystemEvent) = .init(box, .disabled);
|
var scrollable: Scrollable(Model, event.SystemEvent) = .init(box, .disabled);
|
||||||
|
|
||||||
@@ -1251,7 +1280,6 @@ test "scrollable vertical with scrollbar" {
|
|||||||
try box.append(try .init(allocator, .{
|
try box.append(try .init(allocator, .{
|
||||||
.rectangle = .{ .fill = .grey },
|
.rectangle = .{ .fill = .grey },
|
||||||
}, .{}));
|
}, .{}));
|
||||||
defer box.deinit();
|
|
||||||
|
|
||||||
var scrollable: Scrollable(Model, event.SystemEvent) = .init(box, .enabled(.white, true));
|
var scrollable: Scrollable(Model, event.SystemEvent) = .init(box, .enabled(.white, true));
|
||||||
|
|
||||||
@@ -1331,7 +1359,6 @@ test "scrollable horizontal" {
|
|||||||
try box.append(try .init(allocator, .{
|
try box.append(try .init(allocator, .{
|
||||||
.rectangle = .{ .fill = .grey },
|
.rectangle = .{ .fill = .grey },
|
||||||
}, .{}));
|
}, .{}));
|
||||||
defer box.deinit();
|
|
||||||
|
|
||||||
var scrollable: Scrollable(Model, event.SystemEvent) = .init(box, .disabled);
|
var scrollable: Scrollable(Model, event.SystemEvent) = .init(box, .disabled);
|
||||||
|
|
||||||
@@ -1411,7 +1438,6 @@ test "scrollable horizontal with scrollbar" {
|
|||||||
try box.append(try .init(allocator, .{
|
try box.append(try .init(allocator, .{
|
||||||
.rectangle = .{ .fill = .grey },
|
.rectangle = .{ .fill = .grey },
|
||||||
}, .{}));
|
}, .{}));
|
||||||
defer box.deinit();
|
|
||||||
|
|
||||||
var scrollable: Scrollable(Model, event.SystemEvent) = .init(box, .enabled(.white, true));
|
var scrollable: Scrollable(Model, event.SystemEvent) = .init(box, .enabled(.white, true));
|
||||||
|
|
||||||
@@ -1465,16 +1491,13 @@ test "alignment center" {
|
|||||||
var container: Container(Model, event.SystemEvent) = try .init(allocator, .{}, .{});
|
var container: Container(Model, event.SystemEvent) = try .init(allocator, .{}, .{});
|
||||||
defer container.deinit();
|
defer container.deinit();
|
||||||
|
|
||||||
var aligned_container: Container(Model, event.SystemEvent) = try .init(allocator, .{
|
var alignment: Alignment(Model, event.SystemEvent) = .init(try .init(allocator, .{
|
||||||
.rectangle = .{ .fill = .green },
|
.rectangle = .{ .fill = .green },
|
||||||
.size = .{
|
.size = .{
|
||||||
.dim = .{ .x = 12, .y = 5 },
|
.dim = .{ .x = 12, .y = 5 },
|
||||||
.grow = .fixed,
|
.grow = .fixed,
|
||||||
},
|
},
|
||||||
}, .{});
|
}, .{}), .center);
|
||||||
defer aligned_container.deinit();
|
|
||||||
|
|
||||||
var alignment: Alignment(Model, event.SystemEvent) = .init(aligned_container, .center);
|
|
||||||
try container.append(try .init(allocator, .{}, alignment.element()));
|
try container.append(try .init(allocator, .{}, alignment.element()));
|
||||||
|
|
||||||
try testing.expectContainerScreen(.{
|
try testing.expectContainerScreen(.{
|
||||||
@@ -1492,16 +1515,13 @@ test "alignment left" {
|
|||||||
var container: Container(Model, event.SystemEvent) = try .init(allocator, .{}, .{});
|
var container: Container(Model, event.SystemEvent) = try .init(allocator, .{}, .{});
|
||||||
defer container.deinit();
|
defer container.deinit();
|
||||||
|
|
||||||
var aligned_container: Container(Model, event.SystemEvent) = try .init(allocator, .{
|
var alignment: Alignment(Model, event.SystemEvent) = .init(try .init(allocator, .{
|
||||||
.rectangle = .{ .fill = .green },
|
.rectangle = .{ .fill = .green },
|
||||||
.size = .{
|
.size = .{
|
||||||
.dim = .{ .x = 12, .y = 5 },
|
.dim = .{ .x = 12, .y = 5 },
|
||||||
.grow = .fixed,
|
.grow = .fixed,
|
||||||
},
|
},
|
||||||
}, .{});
|
}, .{}), .{
|
||||||
defer aligned_container.deinit();
|
|
||||||
|
|
||||||
var alignment: Alignment(Model, event.SystemEvent) = .init(aligned_container, .{
|
|
||||||
.h = .start,
|
.h = .start,
|
||||||
.v = .center,
|
.v = .center,
|
||||||
});
|
});
|
||||||
@@ -1522,16 +1542,13 @@ test "alignment right" {
|
|||||||
var container: Container(Model, event.SystemEvent) = try .init(allocator, .{}, .{});
|
var container: Container(Model, event.SystemEvent) = try .init(allocator, .{}, .{});
|
||||||
defer container.deinit();
|
defer container.deinit();
|
||||||
|
|
||||||
var aligned_container: Container(Model, event.SystemEvent) = try .init(allocator, .{
|
var alignment: Alignment(Model, event.SystemEvent) = .init(try .init(allocator, .{
|
||||||
.rectangle = .{ .fill = .green },
|
.rectangle = .{ .fill = .green },
|
||||||
.size = .{
|
.size = .{
|
||||||
.dim = .{ .x = 12, .y = 5 },
|
.dim = .{ .x = 12, .y = 5 },
|
||||||
.grow = .fixed,
|
.grow = .fixed,
|
||||||
},
|
},
|
||||||
}, .{});
|
}, .{}), .{
|
||||||
defer aligned_container.deinit();
|
|
||||||
|
|
||||||
var alignment: Alignment(Model, event.SystemEvent) = .init(aligned_container, .{
|
|
||||||
.h = .end,
|
.h = .end,
|
||||||
.v = .center,
|
.v = .center,
|
||||||
});
|
});
|
||||||
@@ -1552,16 +1569,13 @@ test "alignment top" {
|
|||||||
var container: Container(Model, event.SystemEvent) = try .init(allocator, .{}, .{});
|
var container: Container(Model, event.SystemEvent) = try .init(allocator, .{}, .{});
|
||||||
defer container.deinit();
|
defer container.deinit();
|
||||||
|
|
||||||
var aligned_container: Container(Model, event.SystemEvent) = try .init(allocator, .{
|
var alignment: Alignment(Model, event.SystemEvent) = .init(try .init(allocator, .{
|
||||||
.rectangle = .{ .fill = .green },
|
.rectangle = .{ .fill = .green },
|
||||||
.size = .{
|
.size = .{
|
||||||
.dim = .{ .x = 12, .y = 5 },
|
.dim = .{ .x = 12, .y = 5 },
|
||||||
.grow = .fixed,
|
.grow = .fixed,
|
||||||
},
|
},
|
||||||
}, .{});
|
}, .{}), .{
|
||||||
defer aligned_container.deinit();
|
|
||||||
|
|
||||||
var alignment: Alignment(Model, event.SystemEvent) = .init(aligned_container, .{
|
|
||||||
.h = .center,
|
.h = .center,
|
||||||
.v = .start,
|
.v = .start,
|
||||||
});
|
});
|
||||||
@@ -1582,16 +1596,13 @@ test "alignment bottom" {
|
|||||||
var container: Container(Model, event.SystemEvent) = try .init(allocator, .{}, .{});
|
var container: Container(Model, event.SystemEvent) = try .init(allocator, .{}, .{});
|
||||||
defer container.deinit();
|
defer container.deinit();
|
||||||
|
|
||||||
var aligned_container: Container(Model, event.SystemEvent) = try .init(allocator, .{
|
var alignment: Alignment(Model, event.SystemEvent) = .init(try .init(allocator, .{
|
||||||
.rectangle = .{ .fill = .green },
|
.rectangle = .{ .fill = .green },
|
||||||
.size = .{
|
.size = .{
|
||||||
.dim = .{ .x = 12, .y = 5 },
|
.dim = .{ .x = 12, .y = 5 },
|
||||||
.grow = .fixed,
|
.grow = .fixed,
|
||||||
},
|
},
|
||||||
}, .{});
|
}, .{}), .{
|
||||||
defer aligned_container.deinit();
|
|
||||||
|
|
||||||
var alignment: Alignment(Model, event.SystemEvent) = .init(aligned_container, .{
|
|
||||||
.h = .center,
|
.h = .center,
|
||||||
.v = .end,
|
.v = .end,
|
||||||
});
|
});
|
||||||
@@ -1625,8 +1636,6 @@ test "input element" {
|
|||||||
var queue: Queue = .{};
|
var queue: Queue = .{};
|
||||||
|
|
||||||
var input_element: Input(Model, Event, Queue)(.accept) = .init(allocator, &queue, .init(.black, .default));
|
var input_element: Input(Model, Event, Queue)(.accept) = .init(allocator, &queue, .init(.black, .default));
|
||||||
defer input_element.deinit();
|
|
||||||
|
|
||||||
const input_container: Container(Model, Event) = try .init(allocator, .{
|
const input_container: Container(Model, Event) = try .init(allocator, .{
|
||||||
.rectangle = .{ .fill = .green },
|
.rectangle = .{ .fill = .green },
|
||||||
.size = .{
|
.size = .{
|
||||||
|
|||||||
Reference in New Issue
Block a user