╭ changed ─────────╮ │src/ui/AuthTab.zig│ ╰──────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────╮ │1 const std = @import("std"); │ │2 -const evt = @import("../event.zig");│ │2 const ui = @import("../ui.zig"); │ │3 const xit = @import("xit"); │ │4 const xitui = xit.xitui; │ ╰───────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │17 pub const View = struct { │ │18 text_box: wgt.TextBox(ui.Widget), │ │19 session: *ui.Session, │ │21 - // backs the tab's text, which borrows it. sized for the longest name, so │ │22 - // build never allocates. │ │23 - text_buf: [logout_prefix.len + evt.User.name_max_len]u8, │ │24 - │ │25 - const logout_prefix = "logout "; │ │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 });│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────╮ │28 return .{ │ │29 .text_box = text_box, │ │30 .session = session, │ │35 - .text_buf = undefined, │ │31 + .bottom_label_buf = undefined,│ │32 }; │ │33 } │ │34 │ ╰──────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │36 self.text_box.deinit(allocator); │ │37 } │ │38 │ │43 - // the action the tab performs, naming whoever is logged in │ │44 - fn text(self: *View) []const u8 { │ │45 - if (self.session.data.user_id == null) return "login"; │ │46 - const name = self.session.data.user_name orelse return "logout"; │ │47 - // validateName caps the name, so the buffer always fits it │ │48 - return std.fmt.bufPrint(&self.text_buf, logout_prefix ++ "{s}", .{name}) catch unreachable; │ │39 + fn text(self: *const View) []const u8 { │ │40 + return if (self.session.data.user_id == null) "login" else "logout"; │ │41 } │ │42 │ │51 - // what the tab's text needs, plus its border │ │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 { │ │53 - return self.text().len + 2; │ │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 {│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────╮ │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 │ ╰────────────────────────────────────────────────────────────────────────────────────────╯