╭ AuthTab.zig ──────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
1 const std = @import("std"); 2 const ui = @import("../ui.zig"); 3 const xit = @import("xit"); 4 const xitui = xit.xitui; 5 const wgt = xitui.widget; 6 const layout = xitui.layout; 7 const Key = xitui.input.Key; 8 const Grid = xitui.grid.Grid; 9 const Focus = xitui.focus.Focus; 10 11 const Self = @This(); 12 13 pub fn init() Self { 14 return .{}; 15 } 16 17 pub const View = struct { 18 text_box: wgt.TextBox(ui.Widget), 19 session: *ui.Session, 20 // backs the bottom label, which borrows it 21 bottom_label_buf: [ui.clipped_bottom_label_max_len]u8, 22 23 pub fn init(allocator: std.mem.Allocator, session: *ui.Session) !View { 24 var text_box = try wgt.TextBox(ui.Widget).init(allocator, "login", .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none }); 25 errdefer text_box.deinit(allocator); 26 text_box.getFocus().focusable = true; 27 text_box.getFocus().kind = .{ .custom = "ai:/auth" }; 28 return .{ 29 .text_box = text_box, 30 .session = session, 31 .bottom_label_buf = undefined, 32 }; 33 } 34 35 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { 36 self.text_box.deinit(allocator); 37 } 38 39 fn text(self: *const View) []const u8 { 40 return if (self.session.data.user_id == null) "login" else "logout"; 41 } 42 43 fn bottomLabel(self: *View) []const u8 { 44 if (self.session.data.user_id == null) return ""; 45 const name = self.session.data.user_name orelse return ""; 46 return ui.clippedBottomLabel(&self.bottom_label_buf, name) catch unreachable; 47 } 48 49 pub fn minWidth(self: *View) usize { 50 return @max(self.text().len, self.bottomLabel().len) + 2; 51 } 52 53 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void { 54 // update the displayed text based on session state. the inner Text 55 // widget's content is just a slice, so we can repoint it without 56 // re-allocating. 57 if (self.text_box.box.children.values().len > 0) { 58 const text_widget = &self.text_box.box.children.values()[0].widget.text; 59 text_widget.content = self.text(); 60 } 61 self.text_box.options.bottom_label = self.bottomLabel(); 62 try self.text_box.build(allocator, constraint, root_focus); 63 } 64 65 pub fn input(self: *View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { 66 try self.text_box.input(allocator, key, root_focus); 67 } 68 69 pub fn clearGrid(self: *View) void { 70 self.text_box.clearGrid(); 71 } 72 73 pub fn getGrid(self: View) ?Grid { 74 return self.text_box.getGrid(); 75 } 76 77 pub fn getFocus(self: *View) *Focus { 78 return self.text_box.getFocus(); 79 } 80 }; 81