mod(tui): create own terminal interface framework

This commit is contained in:
2024-11-04 22:27:45 +01:00
parent 0330b3a2f5
commit 14aab9ef50
9 changed files with 559 additions and 96 deletions

View File

@@ -1,18 +1,15 @@
const std = @import("std");
const terminal = @import("terminal.zig");
const zlog = @import("zlog");
const terminal = @import("terminal.zig");
const UserEvent = union(enum) {};
const Widget = @import("widget.zig").Widget(UserEvent);
const Layout = @import("layout.zig").Layout(UserEvent);
const App = @import("app.zig").App(union(enum) {});
pub const std_options = zlog.std_options;
const log = std.log.scoped(.main);
pub fn main() !void {
errdefer |err| log.err("Application Error: {any}", .{err});
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer {
const deinit_status = gpa.deinit();
@@ -23,18 +20,46 @@ pub fn main() !void {
}
const allocator = gpa.allocator();
const size = terminal.getTerminalSize();
var app = App.init();
log.debug("Size := [x: {d}, y: {d}]", .{ size.cols, size.rows });
var rawText = Widget.RawText.init(allocator);
const widget = Widget.createFrom(&rawText);
var layout = Layout.Pane.init(allocator, widget);
var rawText = App.Widget.RawText.init(allocator);
const widget = App.Widget.createFrom(&rawText);
var layout = App.Layout.Pane.init(allocator, widget);
defer layout.deinit();
// single 'draw' loop
_ = layout.handle(.none);
log.debug("Layout result: {s}", .{layout.content().items});
try app.start();
defer app.stop() catch unreachable;
// NOTE: necessary for fullscreen tui applications
try terminal.enterAltScreen();
defer terminal.existAltScreen() catch unreachable;
// App.Event loop
while (true) {
const event = app.nextEvent();
switch (event) {
.none => continue,
.quit => break,
.resize => |size| {
// NOTE: draw actions should not happen here (still here for testing)
// NOTE: clearing the screen and positioning the cursor is only necessary for full screen applications
// - in-line applications should use relative movements instead and should only clear lines (which they draw)
// - in-line applications should not enter the alt screen
try terminal.clearScreen();
try terminal.setCursorPositionHome();
log.debug("Size := [x: {d}, y: {d}]", .{ size.cols, size.rows });
},
else => {},
}
const events = try layout.handle(event);
for (events.items) |e| {
app.postEvent(e);
}
log.debug("Layout result: {s}", .{(try layout.content()).items});
}
// TODO: I could use the ascii codes in vaxis
// - see https://gist.github.com/ConnerWill/d4b6c776b509add763e17f9f113fd25b
// how would I draw?
// use array for screen contents? <-> support partial re-draws
// support widget type drawing similar to the already existing widgets
@@ -43,3 +68,7 @@ pub fn main() !void {
// - contents of corresponding locations
// resize event
}
test {
_ = @import("queue.zig");
}