a modern tui library written in zig
1const std = @import("std");
2const vaxis = @import("vaxis");
3const vxfw = vaxis.vxfw;
4
5const Model = struct {
6 split: vxfw.SplitView,
7 lhs: vxfw.Text,
8 rhs: vxfw.Text,
9 children: [1]vxfw.SubSurface = undefined,
10
11 pub fn widget(self: *Model) vxfw.Widget {
12 return .{
13 .userdata = self,
14 .eventHandler = Model.typeErasedEventHandler,
15 .drawFn = Model.typeErasedDrawFn,
16 };
17 }
18
19 fn typeErasedEventHandler(ptr: *anyopaque, ctx: *vxfw.EventContext, event: vxfw.Event) anyerror!void {
20 const self: *Model = @ptrCast(@alignCast(ptr));
21 switch (event) {
22 .init => {
23 self.split.lhs = self.lhs.widget();
24 self.split.rhs = self.rhs.widget();
25 },
26 .key_press => |key| {
27 if (key.matches('c', .{ .ctrl = true })) {
28 ctx.quit = true;
29 return;
30 }
31 },
32 else => {},
33 }
34 }
35
36 fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) std.mem.Allocator.Error!vxfw.Surface {
37 const self: *Model = @ptrCast(@alignCast(ptr));
38 const surf = try self.split.widget().draw(ctx);
39 self.children[0] = .{
40 .surface = surf,
41 .origin = .{ .row = 0, .col = 0 },
42 };
43 return .{
44 .size = ctx.max.size(),
45 .widget = self.widget(),
46 .buffer = &.{},
47 .children = &self.children,
48 };
49 }
50};
51
52pub fn main() !void {
53 var gpa = std.heap.GeneralPurposeAllocator(.{}){};
54 defer _ = gpa.deinit();
55
56 const allocator = gpa.allocator();
57
58 var app = try vxfw.App.init(allocator);
59 defer app.deinit();
60
61 const model = try allocator.create(Model);
62 defer allocator.destroy(model);
63 model.* = .{
64 .lhs = .{ .text = "Left hand side" },
65 .rhs = .{ .text = "right hand side" },
66 .split = .{ .lhs = undefined, .rhs = undefined, .width = 10 },
67 };
68
69 model.split.lhs = model.lhs.widget();
70 model.split.rhs = model.rhs.widget();
71
72 try app.run(model.widget(), .{});
73}