add(widget): Text widget to display static Cell contents
This commit is contained in:
70
build.zig
70
build.zig
@@ -32,41 +32,46 @@ pub fn build(b: *std.Build) void {
|
|||||||
lib.addImport("interface", interface.module("interface"));
|
lib.addImport("interface", interface.module("interface"));
|
||||||
lib.addImport("code_point", zg.module("code_point"));
|
lib.addImport("code_point", zg.module("code_point"));
|
||||||
|
|
||||||
const exe = b.addExecutable(.{
|
// example executables
|
||||||
.name = "zterm",
|
const stack_example = b.addExecutable(.{
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.name = "stack",
|
||||||
|
.root_source_file = b.path("examples/stack.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
exe.root_module.addImport("zterm", lib);
|
stack_example.root_module.addImport("zterm", lib);
|
||||||
|
|
||||||
|
const container_example = b.addExecutable(.{
|
||||||
|
.name = "container",
|
||||||
|
.root_source_file = b.path("examples/container.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
container_example.root_module.addImport("zterm", lib);
|
||||||
|
|
||||||
|
const padding_example = b.addExecutable(.{
|
||||||
|
.name = "padding",
|
||||||
|
.root_source_file = b.path("examples/padding.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
padding_example.root_module.addImport("zterm", lib);
|
||||||
|
|
||||||
|
const exec_example = b.addExecutable(.{
|
||||||
|
.name = "exec",
|
||||||
|
.root_source_file = b.path("examples/exec.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
exec_example.root_module.addImport("zterm", lib);
|
||||||
|
|
||||||
// This declares intent for the executable to be installed into the
|
// This declares intent for the executable to be installed into the
|
||||||
// standard location when the user invokes the "install" step (the default
|
// standard location when the user invokes the "install" step (the default
|
||||||
// step when running `zig build`).
|
// step when running `zig build`).
|
||||||
b.installArtifact(exe);
|
b.installArtifact(stack_example);
|
||||||
|
b.installArtifact(container_example);
|
||||||
// This *creates* a Run step in the build graph, to be executed when another
|
b.installArtifact(padding_example);
|
||||||
// step is evaluated that depends on it. The next line below will establish
|
b.installArtifact(exec_example);
|
||||||
// such a dependency.
|
|
||||||
const run_cmd = b.addRunArtifact(exe);
|
|
||||||
|
|
||||||
// By making the run step depend on the install step, it will be run from the
|
|
||||||
// installation directory rather than directly from within the cache directory.
|
|
||||||
// This is not necessary, however, if the application depends on other installed
|
|
||||||
// files, this ensures they will be present and in the expected location.
|
|
||||||
run_cmd.step.dependOn(b.getInstallStep());
|
|
||||||
|
|
||||||
// This allows the user to pass arguments to the application in the build
|
|
||||||
// command itself, like this: `zig build run -- arg1 arg2 etc`
|
|
||||||
if (b.args) |args| {
|
|
||||||
run_cmd.addArgs(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This creates a build step. It will be visible in the `zig build --help` menu,
|
|
||||||
// and can be selected like this: `zig build run`
|
|
||||||
// This will evaluate the `run` step rather than the default, which is "install".
|
|
||||||
const run_step = b.step("run", "Run the app");
|
|
||||||
run_step.dependOn(&run_cmd.step);
|
|
||||||
|
|
||||||
// Creates a step for unit testing. This only builds the test executable
|
// Creates a step for unit testing. This only builds the test executable
|
||||||
// but does not run it.
|
// but does not run it.
|
||||||
@@ -79,18 +84,9 @@ pub fn build(b: *std.Build) void {
|
|||||||
|
|
||||||
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
||||||
|
|
||||||
const exe_unit_tests = b.addTest(.{
|
|
||||||
.root_source_file = b.path("src/main.zig"),
|
|
||||||
.target = target,
|
|
||||||
.optimize = optimize,
|
|
||||||
});
|
|
||||||
|
|
||||||
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
|
|
||||||
|
|
||||||
// Similar to creating the run step earlier, this exposes a `test` step to
|
// Similar to creating the run step earlier, this exposes a `test` step to
|
||||||
// the `zig build --help` menu, providing a way for the user to request
|
// the `zig build --help` menu, providing a way for the user to request
|
||||||
// running the unit tests.
|
// running the unit tests.
|
||||||
const test_step = b.step("test", "Run unit tests");
|
const test_step = b.step("test", "Run unit tests");
|
||||||
test_step.dependOn(&run_lib_unit_tests.step);
|
test_step.dependOn(&run_lib_unit_tests.step);
|
||||||
test_step.dependOn(&run_exe_unit_tests.step);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const std = @import("std");
|
|||||||
pub const Style = @import("Style.zig");
|
pub const Style = @import("Style.zig");
|
||||||
|
|
||||||
style: Style = .{},
|
style: Style = .{},
|
||||||
content: []u8 = undefined,
|
content: []const u8 = undefined,
|
||||||
|
|
||||||
pub const Result = struct {
|
pub const Result = struct {
|
||||||
idx: usize,
|
idx: usize,
|
||||||
|
|||||||
@@ -91,11 +91,13 @@ pub fn Widget(comptime Event: type, comptime Renderer: type) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// import and export of `Widget` implementations
|
// 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 RawText = @import("widget/RawText.zig").Widget(Event, Renderer);
|
||||||
pub const Spacer = @import("widget/Spacer.zig").Widget(Event, Renderer);
|
pub const Spacer = @import("widget/Spacer.zig").Widget(Event, Renderer);
|
||||||
};
|
};
|
||||||
// test widget implementation satisfies the interface
|
// test widget implementation satisfies the interface
|
||||||
comptime Type.Interface.satisfiedBy(Type);
|
comptime Type.Interface.satisfiedBy(Type);
|
||||||
|
comptime Type.Interface.satisfiedBy(Type.Text);
|
||||||
comptime Type.Interface.satisfiedBy(Type.RawText);
|
comptime Type.Interface.satisfiedBy(Type.RawText);
|
||||||
comptime Type.Interface.satisfiedBy(Type.Spacer);
|
comptime Type.Interface.satisfiedBy(Type.Spacer);
|
||||||
return Type;
|
return Type;
|
||||||
|
|||||||
50
src/widget/Text.zig
Normal file
50
src/widget/Text.zig
Normal 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user