an experimental irc client

app: draw client list

+54 -2
+34 -2
src/app.zig
··· 85 86 lhs: vxfw.SplitView, 87 rhs: vxfw.SplitView, 88 89 /// initialize vaxis, lua state 90 pub fn init(self: *App, gpa: std.mem.Allocator) !void { ··· 101 .write_thread = undefined, 102 .lhs = .{ 103 .width = self.state.buffers.width, 104 - .lhs = self.bufferWidget(), 105 .rhs = self.rhs.widget(), 106 }, 107 .rhs = .{ ··· 115 .deinited = false, 116 .completer = null, 117 .should_quit = false, 118 }; 119 120 self.lua = try Lua.init(&self.alloc); ··· 259 }; 260 } 261 262 fn typeErasedBufferDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface { 263 - _ = ptr; 264 const text: vxfw.Text = .{ .text = "buffers" }; 265 return text.draw(ctx); 266 }
··· 85 86 lhs: vxfw.SplitView, 87 rhs: vxfw.SplitView, 88 + buffer_list: vxfw.ListView, 89 90 /// initialize vaxis, lua state 91 pub fn init(self: *App, gpa: std.mem.Allocator) !void { ··· 102 .write_thread = undefined, 103 .lhs = .{ 104 .width = self.state.buffers.width, 105 + .lhs = self.buffer_list.widget(), 106 .rhs = self.rhs.widget(), 107 }, 108 .rhs = .{ ··· 116 .deinited = false, 117 .completer = null, 118 .should_quit = false, 119 + .buffer_list = .{ 120 + .children = .{ 121 + .builder = .{ 122 + .userdata = self, 123 + .buildFn = App.bufferBuilderFn, 124 + }, 125 + }, 126 + .draw_cursor = false, 127 + }, 128 }; 129 130 self.lua = try Lua.init(&self.alloc); ··· 269 }; 270 } 271 272 + fn bufferBuilderFn(ptr: *const anyopaque, idx: usize, cursor: usize) ?vxfw.Widget { 273 + const self: *const App = @ptrCast(@alignCast(ptr)); 274 + var i: usize = 0; 275 + for (self.clients.items) |client| { 276 + if (i == idx and i == cursor) { 277 + return .{ 278 + .userdata = client, 279 + .drawFn = irc.Client.typeErasedNameSelectedDrawFn, 280 + }; 281 + } 282 + if (i == idx) { 283 + return .{ 284 + .userdata = client, 285 + .drawFn = irc.Client.typeErasedNameDrawFn, 286 + }; 287 + } 288 + i += 1; 289 + } 290 + return null; 291 + } 292 + 293 fn typeErasedBufferDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface { 294 + const self: *App = @ptrCast(@alignCast(ptr)); 295 + _ = self; 296 const text: vxfw.Text = .{ .text = "buffers" }; 297 return text.draw(ctx); 298 }
+20
src/irc.zig
··· 8 9 const testing = std.testing; 10 const mem = std.mem; 11 12 const Allocator = std.mem.Allocator; 13 const Base64Encoder = std.base64.standard.Encoder; ··· 563 } 564 batches.deinit(); 565 self.fifo.deinit(); 566 } 567 568 pub fn drainFifo(self: *Client) void {
··· 8 9 const testing = std.testing; 10 const mem = std.mem; 11 + const vxfw = vaxis.vxfw; 12 13 const Allocator = std.mem.Allocator; 14 const Base64Encoder = std.base64.standard.Encoder; ··· 564 } 565 batches.deinit(); 566 self.fifo.deinit(); 567 + } 568 + 569 + pub fn typeErasedNameDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface { 570 + const self: *Client = @ptrCast(@alignCast(ptr)); 571 + const text: vxfw.Text = .{ 572 + .text = self.config.name orelse self.config.server, 573 + .softwrap = false, 574 + }; 575 + return text.draw(ctx); 576 + } 577 + 578 + pub fn typeErasedNameSelectedDrawFn(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface { 579 + const self: *Client = @ptrCast(@alignCast(ptr)); 580 + const text: vxfw.Text = .{ 581 + .text = self.config.name orelse self.config.server, 582 + .softwrap = false, 583 + .style = .{ .reverse = true }, 584 + }; 585 + return text.draw(ctx); 586 } 587 588 pub fn drainFifo(self: *Client) void {