add(widget): Text widget to display static Cell contents

This commit is contained in:
2024-11-15 21:01:50 +01:00
parent 273da37020
commit 58982a53f2
4 changed files with 86 additions and 38 deletions

View File

@@ -2,7 +2,7 @@ const std = @import("std");
pub const Style = @import("Style.zig");
style: Style = .{},
content: []u8 = undefined,
content: []const u8 = undefined,
pub const Result = struct {
idx: usize,

View File

@@ -91,11 +91,13 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
}
// import and export of `Widget` implementations
pub const Text = @import("widget/Text.zig").Widget(Event, Renderer);
pub const RawText = @import("widget/RawText.zig").Widget(Event, Renderer);
pub const Spacer = @import("widget/Spacer.zig").Widget(Event, Renderer);
};
// test widget implementation satisfies the interface
comptime Type.Interface.satisfiedBy(Type);
comptime Type.Interface.satisfiedBy(Type.Text);
comptime Type.Interface.satisfiedBy(Type.RawText);
comptime Type.Interface.satisfiedBy(Type.Spacer);
return Type;

50
src/widget/Text.zig Normal file
View File

@@ -0,0 +1,50 @@
const std = @import("std");
const terminal = @import("../terminal.zig");
const isTaggedUnion = @import("../event.zig").isTaggedUnion;
const Error = @import("../event.zig").Error;
const Cell = terminal.Cell;
const log = std.log.scoped(.widget_text);
pub fn Widget(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)`.");
}
return struct {
contents: []const Cell = undefined,
size: terminal.Size = undefined,
require_render: bool = false,
pub fn init(contents: []const Cell) @This() {
return .{
.contents = contents,
};
}
pub fn deinit(this: *@This()) void {
this.* = undefined;
}
pub fn handle(this: *@This(), event: Event) ?Event {
switch (event) {
// store the received size
.resize => |size| {
this.size = size;
this.require_render = true;
},
else => {},
}
return null;
}
pub fn render(this: *@This(), renderer: *Renderer) !void {
if (!this.require_render) {
return;
}
try renderer.clear(this.size);
try renderer.render(this.size, this.contents);
this.require_render = false;
}
};
}