Compare commits
2 Commits
9dc1a4b95a
...
eb89f7f98b
| Author | SHA1 | Date | |
|---|---|---|---|
| eb89f7f98b | |||
| cc847b7035 |
@@ -128,7 +128,7 @@ the primary use-case for myself to create this library in the first place.
|
|||||||
- [x] vertical
|
- [x] vertical
|
||||||
- [x] horizontal
|
- [x] horizontal
|
||||||
- [x] grid
|
- [x] grid
|
||||||
- [ ] mixed (some sort of form)
|
- [x] mixed (some sort of form)
|
||||||
- [ ] Elements
|
- [ ] Elements
|
||||||
- [ ] Button
|
- [ ] Button
|
||||||
- [ ] Text Input field
|
- [ ] Text Input field
|
||||||
|
|||||||
10
build.zig
10
build.zig
@@ -12,6 +12,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
vertical,
|
vertical,
|
||||||
horizontal,
|
horizontal,
|
||||||
grid,
|
grid,
|
||||||
|
mixed,
|
||||||
// styles:
|
// styles:
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -78,6 +79,14 @@ pub fn build(b: *std.Build) void {
|
|||||||
});
|
});
|
||||||
grid.root_module.addImport("zterm", lib);
|
grid.root_module.addImport("zterm", lib);
|
||||||
|
|
||||||
|
const mixed = b.addExecutable(.{
|
||||||
|
.name = "mixed",
|
||||||
|
.root_source_file = b.path("examples/layouts/mixed.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
mixed.root_module.addImport("zterm", lib);
|
||||||
|
|
||||||
// mapping of user selected example to compile step
|
// mapping of user selected example to compile step
|
||||||
const exe = switch (example) {
|
const exe = switch (example) {
|
||||||
// elements:
|
// elements:
|
||||||
@@ -87,6 +96,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
.vertical => vertical,
|
.vertical => vertical,
|
||||||
.horizontal => horizontal,
|
.horizontal => horizontal,
|
||||||
.grid => grid,
|
.grid => grid,
|
||||||
|
.mixed => mixed,
|
||||||
// styles:
|
// styles:
|
||||||
};
|
};
|
||||||
b.installArtifact(exe);
|
b.installArtifact(exe);
|
||||||
|
|||||||
113
examples/layouts/mixed.zig
Normal file
113
examples/layouts/mixed.zig
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const zterm = @import("zterm");
|
||||||
|
|
||||||
|
const App = zterm.App(union(enum) {});
|
||||||
|
|
||||||
|
const log = std.log.scoped(.default);
|
||||||
|
|
||||||
|
const QuitText = struct {
|
||||||
|
const text = "Press ctrl+c to quit.";
|
||||||
|
|
||||||
|
pub fn element(this: *@This()) App.Element {
|
||||||
|
return .{
|
||||||
|
.ptr = this,
|
||||||
|
// no handle function required
|
||||||
|
.vtable = &.{ .content = content },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn content(ctx: *anyopaque, cells: []zterm.Cell, size: zterm.Size) !void {
|
||||||
|
_ = ctx;
|
||||||
|
std.debug.assert(cells.len == @as(usize, size.cols) * @as(usize, size.rows));
|
||||||
|
|
||||||
|
const row: u16 = 2;
|
||||||
|
const col: u16 = size.cols / 2 -| (@as(u16, @truncate(text.len)) / 2);
|
||||||
|
const anchor = (row * size.cols) + col;
|
||||||
|
|
||||||
|
for (text, 0..) |cp, idx| {
|
||||||
|
cells[anchor + idx].style.fg = .white;
|
||||||
|
cells[anchor + idx].style.bg = .black;
|
||||||
|
cells[anchor + idx].cp = cp;
|
||||||
|
|
||||||
|
// NOTE: do not write over the contents of this `Container`'s `Size`
|
||||||
|
if (anchor + idx == cells.len - 1) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
errdefer |err| log.err("Application Error: {any}", .{err});
|
||||||
|
|
||||||
|
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
|
||||||
|
defer if (gpa.deinit() == .leak) {
|
||||||
|
log.err("memory leak", .{});
|
||||||
|
};
|
||||||
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
|
var app: App = .init;
|
||||||
|
var renderer = zterm.Renderer.Buffered.init(allocator);
|
||||||
|
defer renderer.deinit();
|
||||||
|
|
||||||
|
var quit_text: QuitText = .{};
|
||||||
|
const element = quit_text.element();
|
||||||
|
|
||||||
|
var container = try App.Container.init(allocator, .{
|
||||||
|
.layout = .{
|
||||||
|
.gap = 2,
|
||||||
|
.padding = .{ .top = 5, .bottom = 3, .left = 3, .right = 3 },
|
||||||
|
.direction = .horizontal,
|
||||||
|
},
|
||||||
|
}, element);
|
||||||
|
for (0..3) |i| {
|
||||||
|
var column = try App.Container.init(allocator, .{
|
||||||
|
.border = .{ .separator = .{ .enabled = true } },
|
||||||
|
.layout = .{
|
||||||
|
.direction = if (i > 0) .vertical else .horizontal,
|
||||||
|
},
|
||||||
|
}, .{});
|
||||||
|
if (i != 1) {
|
||||||
|
try column.append(try App.Container.init(allocator, .{
|
||||||
|
.rectangle = .{ .fill = .green },
|
||||||
|
}, .{}));
|
||||||
|
try column.append(try App.Container.init(allocator, .{
|
||||||
|
.rectangle = .{ .fill = .yellow },
|
||||||
|
}, .{}));
|
||||||
|
} else {
|
||||||
|
try column.append(try App.Container.init(allocator, .{}, .{}));
|
||||||
|
}
|
||||||
|
try column.append(try App.Container.init(allocator, .{
|
||||||
|
.rectangle = .{ .fill = .blue },
|
||||||
|
}, .{}));
|
||||||
|
try container.append(column);
|
||||||
|
}
|
||||||
|
defer container.deinit(); // also de-initializes the children
|
||||||
|
|
||||||
|
try app.start();
|
||||||
|
defer app.stop() catch |err| log.err("Failed to stop application: {any}", .{err});
|
||||||
|
|
||||||
|
// event loop
|
||||||
|
while (true) {
|
||||||
|
const event = app.nextEvent();
|
||||||
|
log.debug("received event: {s}", .{@tagName(event)});
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
.init => continue,
|
||||||
|
.quit => break,
|
||||||
|
.resize => |size| try renderer.resize(size),
|
||||||
|
.key => |key| if (key.eql(.{ .cp = 'c', .mod = .{ .ctrl = true } })) app.quit(),
|
||||||
|
// NOTE: errors could be displayed in another container in case one was received, etc. to provide the user with feedback
|
||||||
|
.err => |err| log.err("Received {s} with message: {s}", .{ @errorName(err.err), err.msg }),
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: returned errors should be propagated back to the application
|
||||||
|
container.handle(event) catch |err| app.postEvent(.{
|
||||||
|
.err = .{
|
||||||
|
.err = err,
|
||||||
|
.msg = "Container Event handling failed",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
try renderer.render(@TypeOf(container), &container);
|
||||||
|
try renderer.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,6 +66,7 @@ pub fn value(this: Style, writer: anytype, cp: u21) !void {
|
|||||||
try std.fmt.format(writer, "m", .{});
|
try std.fmt.format(writer, "m", .{});
|
||||||
// content
|
// content
|
||||||
try std.fmt.format(writer, "{s}", .{buffer});
|
try std.fmt.format(writer, "{s}", .{buffer});
|
||||||
|
try std.fmt.format(writer, "\x1b[0m", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement helper functions for terminal capabilities:
|
// TODO: implement helper functions for terminal capabilities:
|
||||||
|
|||||||
Reference in New Issue
Block a user