this repo has no description
1const std = @import("std");
2const builtin = @import("builtin");
3
4const vaxis = @import("vaxis");
5const vxfw = vaxis.vxfw;
6
7const Allocator = std.mem.Allocator;
8
9var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
10
11const Column = struct {
12 children: []vxfw.Widget,
13
14 pub fn widget(self: *Model) vxfw.Widget {
15 return .{
16 .userdata = self,
17 .eventHandler = @This().typeErasedEventHandler,
18 .drawFn = @This().typeErasedDrawFn,
19 };
20 }
21
22 fn typeErasedEventHandler(ptr: *anyopaque, ctx: *vxfw.EventContext, event: vxfw.Event) anyerror!void {
23 _ = ptr;
24 _ = ctx;
25 _ = event;
26 }
27
28 fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface {
29 const self: *@This() = @ptrCast(@alignCast(ptr));
30
31 const max_size = ctx.max.size();
32
33 const children = try ctx.arena.alloc(vxfw.SubSurface, self.children.len);
34
35 for (self.children, 0..) |child, n| {
36 children[n] = child.draw(ctx);
37 }
38
39 return .{
40 .size = max_size,
41 .widget = self.widget(),
42 .buffer = &.{},
43 .children = children,
44 };
45 }
46};
47
48const Revset = struct {
49 revset_str: []const u8,
50};
51
52const Model = struct {
53 count: u32 = 0,
54 header: Revset,
55 button: vxfw.Button,
56
57 pub fn widget(self: *Model) vxfw.Widget {
58 return .{
59 .userdata = self,
60 .eventHandler = Model.typeErasedEventHandler,
61 .drawFn = Model.typeErasedDrawFn,
62 };
63 }
64
65 fn typeErasedEventHandler(ptr: *anyopaque, ctx: *vxfw.EventContext, event: vxfw.Event) anyerror!void {
66 const self: *Model = @ptrCast(@alignCast(ptr));
67 switch (event) {
68 .init => return ctx.requestFocus(self.button.widget()),
69 .key_press => |key| {
70 if (key.matches('q', .{})) {
71 ctx.quit = true;
72 return;
73 }
74 if (key.matches('c', .{ .ctrl = true })) {
75 ctx.quit = true;
76 return;
77 }
78 },
79 .focus_in => return ctx.requestFocus(self.button.widget()),
80 else => {},
81 }
82 }
83
84 fn typeErasedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface {
85 const self: *Model = @ptrCast(@alignCast(ptr));
86
87 const max_size = ctx.max.size();
88
89 const count_text = try std.fmt.allocPrint(ctx.arena, "{d}", .{self.count});
90 const text: vxfw.Text = .{ .text = count_text };
91
92 const header: vxfw.Text = .{ .text = self.header.revset_str };
93
94 const header_child: vxfw.SubSurface = .{
95 .origin = .{ .row = 0, .col = 0 },
96 .surface = try header.draw(ctx),
97 };
98
99 const text_child: vxfw.SubSurface = .{
100 .origin = .{ .row = 2, .col = 0 },
101 .surface = try text.draw(ctx),
102 };
103
104 const button_child: vxfw.SubSurface = .{
105 .origin = .{ .row = 4, .col = 2 },
106 .surface = try self.button.draw(ctx.withConstraints(ctx.min, .{ .width = 16, .height = 3 })),
107 };
108
109 const children = try ctx.arena.alloc(vxfw.SubSurface, 3);
110
111 children[0] = header_child;
112 children[1] = text_child;
113 children[2] = button_child;
114
115 return .{
116 .size = max_size,
117 .widget = self.widget(),
118
119 .buffer = &.{},
120 .children = children,
121 };
122 }
123
124 fn onClick(maybe_ptr: ?*anyopaque, ctx: *vxfw.EventContext) anyerror!void {
125 const ptr = maybe_ptr orelse return;
126 const self: *Model = @ptrCast(@alignCast(ptr));
127 self.count += 1;
128 return ctx.consumeAndRedraw();
129 }
130};
131
132pub fn main() !void {
133 var gpa, const is_debug = gpa: {
134 break :gpa switch (builtin.mode) {
135 .Debug, .ReleaseSafe => .{ debug_allocator, true },
136 .ReleaseFast, .ReleaseSmall => .{ std.heap.smp_allocator, false },
137 };
138 };
139 defer if (is_debug) {
140 _ = debug_allocator.deinit();
141 };
142
143 const allocator: Allocator = gpa.allocator();
144
145 var app = try vxfw.App.init(allocator);
146 defer app.deinit();
147
148 const model = try allocator.create(Model);
149 defer allocator.destroy(model);
150
151 model.* = .{
152 .count = 0,
153 .header = .{ .revset_str = "hello" },
154 .button = .{
155 .label = "Click me!",
156 .onClick = Model.onClick,
157 .userdata = model,
158 },
159 };
160
161 try app.run(model.widget(), .{});
162}