···11+const std = @import("std");
22+const vaxis = @import("vaxis");
33+44+const log = std.log.scoped(.main);
55+66+// Our EventType. This can contain internal events as well as Vaxis events.
77+// Internal events can be posted into the same queue as vaxis events to allow
88+// for a single event loop with exhaustive switching. Booya
99+const Event = union(enum) {
1010+ key_press: vaxis.Key,
1111+ winsize: vaxis.Winsize,
1212+ focus_in,
1313+ focus_out,
1414+ foo: u8,
1515+};
1616+1717+pub fn main() !void {
1818+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
1919+ defer {
2020+ const deinit_status = gpa.deinit();
2121+ //fail test; can't try in defer as defer is executed after we return
2222+ if (deinit_status == .leak) {
2323+ log.err("memory leak", .{});
2424+ }
2525+ }
2626+ const alloc = gpa.allocator();
2727+2828+ // Initialize Vaxis with our event type
2929+ var vx = try vaxis.init(Event, .{});
3030+ // deinit takes an optional allocator. If your program is exiting, you can
3131+ // choose to pass a null allocator to save some exit time.
3232+ defer vx.deinit(alloc);
3333+3434+ // Start the read loop. This puts the terminal in raw mode and begins
3535+ // reading user input
3636+ try vx.startReadThread();
3737+ defer vx.stopReadThread();
3838+3939+ // Optionally enter the alternate screen
4040+ try vx.enterAltScreen();
4141+4242+ // Sends queries to terminal to detect certain features. This should
4343+ // _always_ be called, but is left to the application to decide when
4444+ try vx.queryTerminal();
4545+4646+ var img = try vaxis.Image.init(alloc, .{ .path = "vaxis.png" }, 1, .kitty);
4747+ defer img.deinit();
4848+4949+ // The main event loop. Vaxis provides a thread safe, blocking, buffered
5050+ // queue which can serve as the primary event queue for an application
5151+ outer: while (true) {
5252+ // nextEvent blocks until an event is in the queue
5353+ const event = vx.nextEvent();
5454+ log.debug("event: {}\r\n", .{event});
5555+ // exhaustive switching ftw. Vaxis will send events if your EventType
5656+ // enum has the fields for those events (ie "key_press", "winsize")
5757+ switch (event) {
5858+ .key_press => |key| {
5959+ if (key.matches('c', .{ .ctrl = true })) {
6060+ break :outer;
6161+ } else if (key.matches('l', .{ .ctrl = true })) {
6262+ vx.queueRefresh();
6363+ } else if (key.matches('n', .{ .ctrl = true })) {
6464+ try vx.notify("vaxis", "hello from vaxis");
6565+ } else {}
6666+ },
6767+6868+ .winsize => |ws| try vx.resize(alloc, ws),
6969+ else => {},
7070+ }
7171+7272+ // vx.window() returns the root window. This window is the size of the
7373+ // terminal and can spawn child windows as logical areas. Child windows
7474+ // cannot draw outside of their bounds
7575+ const win = vx.window();
7676+7777+ // Clear the entire space because we are drawing in immediate mode.
7878+ // vaxis double buffers the screen. This new frame will be compared to
7979+ // the old and only updated cells will be drawn
8080+ win.clear();
8181+8282+ try img.draw(win);
8383+8484+ // Render the screen
8585+ try vx.render();
8686+ }
8787+}
···298298 } else true;
299299 if (!transmit) continue;
300300 // TODO: transmit the new image to the screen
301301+ try img.img.transmit(tty.buffered_writer.writer());
301302 }
302303303304 var i: usize = 0;