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.
123 lines
4.3 KiB
Zig
123 lines
4.3 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 Cell = zterm.Cell;
|
|
const Layout = App.Layout;
|
|
const Widget = App.Widget;
|
|
|
|
const log = std.log.scoped(.tabs);
|
|
|
|
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 tabs = Layout.Tab.init(allocator, .{}, .{
|
|
.{
|
|
Layout.createFrom(margin: {
|
|
var margin = Layout.Margin.init(allocator, .{ .margin = 10 }, .{
|
|
.widget = Widget.createFrom(blk: {
|
|
const file = try std.fs.cwd().openFile("./examples/tabs.zig", .{});
|
|
defer file.close();
|
|
var widget = Widget.RawText.init(allocator, file);
|
|
break :blk &widget;
|
|
}),
|
|
});
|
|
break :margin &margin;
|
|
}),
|
|
"Tab 2",
|
|
Cell.Style.Color{ .index = 6 },
|
|
},
|
|
.{
|
|
Layout.createFrom(framing: {
|
|
var framing = Layout.Framing.init(
|
|
allocator,
|
|
.{
|
|
.frame = .round,
|
|
.title = .{
|
|
.str = "Content in Margin",
|
|
.style = .{
|
|
.ul_style = .single,
|
|
.ul = .{ .index = 4 },
|
|
.bold = true,
|
|
},
|
|
},
|
|
},
|
|
.{
|
|
.layout = Layout.createFrom(margin: {
|
|
var margin = Layout.Margin.init(allocator, .{ .margin = 10 }, .{
|
|
.widget = Widget.createFrom(blk: {
|
|
var widget = Widget.List.init(allocator, .ordered, .{
|
|
&[_]Cell{.{ .content = "First entry" }},
|
|
&[_]Cell{.{ .content = "Second entry" }},
|
|
&[_]Cell{.{ .content = "Third entry" }},
|
|
});
|
|
break :blk &widget;
|
|
}),
|
|
});
|
|
break :margin &margin;
|
|
}),
|
|
},
|
|
);
|
|
break :framing &framing;
|
|
}),
|
|
"Tab 1",
|
|
Cell.Style.Color{ .index = 4 },
|
|
},
|
|
});
|
|
break :layout &tabs;
|
|
});
|
|
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);
|
|
}
|
|
}
|