Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 3m54s
feat(app): add minimal size argument for App.start Read more corresponding inputs from stdin and convert them correctly (i.e. in band window resizing), further keys (arrow keys, F-keys, etc.). Respect the provided minimal size for the application which posts an error message in case the size is smaller than the requested minimal size.
116 lines
3.6 KiB
Zig
116 lines
3.6 KiB
Zig
const std = @import("std");
|
|
const zterm = @import("zterm");
|
|
|
|
const App = zterm.App(
|
|
union(enum) {},
|
|
zterm.Renderer.Direct,
|
|
true,
|
|
);
|
|
const Key = zterm.Key;
|
|
const Layout = App.Layout;
|
|
const Widget = App.Widget;
|
|
|
|
const log = std.log.scoped(.container);
|
|
|
|
pub fn main() !void {
|
|
errdefer |err| log.err("Application Error: {any}", .{err});
|
|
|
|
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .{};
|
|
defer {
|
|
const deinit_status = gpa.deinit();
|
|
// fail test; can't try in defer as defer is executed after we return
|
|
if (deinit_status == .leak) {
|
|
log.err("memory leak", .{});
|
|
}
|
|
}
|
|
const allocator = gpa.allocator();
|
|
|
|
var app: App = .{};
|
|
var renderer: App.Renderer = .{};
|
|
// TODO: when not running fullscreen, the application needs to screen down accordingly to display the contents
|
|
// -> size hint how much should it use?
|
|
|
|
var layout = Layout.createFrom(layout: {
|
|
var stack = Layout.HContainer.init(allocator, .{
|
|
.{
|
|
Widget.createFrom(blk: {
|
|
var spacer = Widget.Spacer.init();
|
|
break :blk &spacer;
|
|
}),
|
|
15,
|
|
},
|
|
.{
|
|
Layout.createFrom(container: {
|
|
var container = Layout.VContainer.init(allocator, .{
|
|
.{
|
|
Widget.createFrom(blk: {
|
|
var spacer = Widget.Spacer.init();
|
|
break :blk &spacer;
|
|
}),
|
|
25,
|
|
},
|
|
.{
|
|
Widget.createFrom(blk: {
|
|
const file = try std.fs.cwd().openFile("./src/app.zig", .{});
|
|
defer file.close();
|
|
var widget = Widget.RawText.init(allocator, file);
|
|
break :blk &widget;
|
|
}),
|
|
50,
|
|
},
|
|
.{
|
|
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();
|
|
|
|
try app.start(null);
|
|
defer app.stop() catch unreachable;
|
|
|
|
// App.Event loop
|
|
while (true) {
|
|
const event = app.nextEvent();
|
|
log.debug("received event: {s}", .{@tagName(event)});
|
|
|
|
switch (event) {
|
|
.quit => break,
|
|
.resize => |size| {
|
|
renderer.resize(size);
|
|
},
|
|
.key => |key| {
|
|
// ctrl+c to quit
|
|
if (Key.matches(key, .{ .cp = 'c', .mod = .{ .ctrl = true } })) {
|
|
app.quit();
|
|
}
|
|
},
|
|
.err => |err| {
|
|
log.err("Received {any} with message: {s}", .{ err.err, err.msg });
|
|
},
|
|
else => {},
|
|
}
|
|
const events = try layout.handle(event);
|
|
for (events.items) |e| {
|
|
app.postEvent(e);
|
|
}
|
|
try layout.render(&renderer);
|
|
}
|
|
}
|