this repo has no description
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 01605eebf65be21caa85ee9d840047f864553308 105 lines 3.9 kB view raw
1const std = @import("std"); 2const vaxis = @import("vaxis"); 3const Cell = vaxis.Cell; 4 5const log = std.log.scoped(.main); 6pub fn main() !void { 7 var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 8 defer { 9 const deinit_status = gpa.deinit(); 10 //fail test; can't try in defer as defer is executed after we return 11 if (deinit_status == .leak) { 12 log.err("memory leak", .{}); 13 } 14 } 15 const alloc = gpa.allocator(); 16 17 var tty = try vaxis.Tty.init(); 18 defer tty.deinit(); 19 20 var vx = try vaxis.init(alloc, .{}); 21 defer vx.deinit(alloc, tty.anyWriter()); 22 23 var loop: vaxis.Loop(Event) = .{ .tty = &tty, .vaxis = &vx }; 24 try loop.init(); 25 26 try loop.start(); 27 defer loop.stop(); 28 29 // Optionally enter the alternate screen 30 try vx.enterAltScreen(tty.anyWriter()); 31 try vx.queryTerminal(tty.anyWriter(), 1 * std.time.ns_per_s); 32 33 // We'll adjust the color index every keypress 34 var color_idx: u8 = 0; 35 const msg = "Hello, world!"; 36 37 // The main event loop. Vaxis provides a thread safe, blocking, buffered 38 // queue which can serve as the primary event queue for an application 39 while (true) { 40 // nextEvent blocks until an event is in the queue 41 const event = loop.nextEvent(); 42 log.debug("event: {}", .{event}); 43 // exhaustive switching ftw. Vaxis will send events if your Event 44 // enum has the fields for those events (ie "key_press", "winsize") 45 switch (event) { 46 .key_press => |key| { 47 color_idx = switch (color_idx) { 48 255 => 0, 49 else => color_idx + 1, 50 }; 51 if (key.codepoint == 'c' and key.mods.ctrl) { 52 break; 53 } 54 }, 55 .winsize => |ws| { 56 try vx.resize(alloc, tty.anyWriter(), ws); 57 }, 58 else => {}, 59 } 60 61 // vx.window() returns the root window. This window is the size of the 62 // terminal and can spawn child windows as logical areas. Child windows 63 // cannot draw outside of their bounds 64 const win = vx.window(); 65 // Clear the entire space because we are drawing in immediate mode. 66 // vaxis double buffers the screen. This new frame will be compared to 67 // the old and only updated cells will be drawn 68 win.clear(); 69 70 const msg_len: u16 = @intCast(msg.len); 71 // Create some child window. .expand means the height and width will 72 // fill the remaining space of the parent. Child windows do not store a 73 // reference to their parent: this is true immediate mode. Do not store 74 // windows, always create new windows each render cycle 75 const child = win.child( 76 .{ .x_off = win.width / 2 - msg_len / 2, .y_off = win.height / 2 }, 77 ); 78 // Loop through the message and print the cells to the screen 79 for (msg, 0..) |_, i| { 80 const cell: Cell = .{ 81 // each cell takes a _grapheme_ as opposed to a single 82 // codepoint. This allows Vaxis to handle emoji properly, 83 // particularly with terminals that the Unicode Core extension 84 // (IE Mode 2027) 85 .char = .{ .grapheme = msg[i .. i + 1] }, 86 .style = .{ 87 .fg = .{ .index = color_idx }, 88 }, 89 }; 90 child.writeCell(@intCast(i), 0, cell); 91 } 92 // Render the screen 93 try vx.render(tty.anyWriter()); 94 } 95} 96 97// Our Event. This can contain internal events as well as Vaxis events. 98// Internal events can be posted into the same queue as vaxis events to allow 99// for a single event loop with exhaustive switching. Booya 100const Event = union(enum) { 101 key_press: vaxis.Key, 102 winsize: vaxis.Winsize, 103 focus_in, 104 foo: u8, 105};