╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ─────────────╮ │src/ui/Home/Header.zig│ ╰──────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────╮ │75 else if (std.mem.eql(u8, "a:/auth", focus_name)) { │ │76 var auth_tab = try AuthTab.View.init(allocator, &data.auth_tab, session);│ │77 errdefer auth_tab.deinit(allocator); │ │78 - tab_ids[tab_index] = auth_tab.getFocus().id; │ │79 - tab_index += 1; │ │78 + try tab_ids.put(allocator, auth_tab.getFocus().id, {}); │ │79 try box.children.put(allocator, auth_tab.getFocus().id, .{ │ │80 .widget = .{ .auth_tab = auth_tab }, │ │81 .rect = null, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────╮ │88 errdefer text_box.deinit(allocator); │ │89 text_box.getFocus().focusable = true; │ │90 text_box.getFocus().kind = .{ .custom = focus_name }; │ │92 - tab_ids[tab_index] = text_box.getFocus().id; │ │93 - tab_index += 1; │ │91 + try tab_ids.put(allocator, text_box.getFocus().id, {}); │ │92 try box.children.put(allocator, text_box.getFocus().id, .{│ │93 .widget = .{ .text_box = text_box }, │ │94 .rect = null, │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 97 } │ │ 98 } │ │ 99 │ │100 + // quit tab │ │101 + if (session.is_terminal) { │ │102 + var text_box = try wgt.TextBox(ui.Widget).init(allocator, ui.Quit.tab_label, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none });│ │103 + errdefer text_box.deinit(allocator); │ │104 + text_box.getFocus().focusable = true; │ │105 + text_box.getFocus().kind = .{ .custom = ui.Quit.tab_kind }; │ │106 + try tab_ids.put(allocator, text_box.getFocus().id, {}); │ │107 + try box.children.put(allocator, text_box.getFocus().id, .{ │ │108 + .widget = .{ .text_box = text_box }, │ │109 + .rect = null, │ │110 + // the label is a single column; +2 for the border │ │111 + .min_size = .{ .width = 1 + 2, .height = null }, │ │112 + }); │ │113 + } │ │114 + │ │115 var self = View{ .box = box, .data = data, .tab_ids = tab_ids }; │ │116 // initial selected tab │ │104 - self.getFocus().child_id = tab_ids[ │ │117 + self.getFocus().child_id = self.tab_ids.keys()[ │ │118 switch (session.data.current_page) { │ │119 .home_users => 0, │ │120 .home_repos => 1, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │128 │ │129 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { │ │130 self.box.deinit(allocator); │ │131 + self.tab_ids.deinit(allocator); │ │132 } │ │133 │ │134 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void {│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────╮ │152 var new_tab = current_tab; │ │153 switch (key) { │ │154 .arrow_left => new_tab -|= 1, │ │141 - .arrow_right => if (new_tab + 1 < self.tab_ids.len) { │ │155 + .arrow_right => if (new_tab + 1 < self.tab_ids.count()) {│ │156 new_tab += 1; │ │157 }, │ │158 else => {}, │ ╰──────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────╮ │159 } │ │160 if (new_tab != current_tab) { │ │147 - try root_focus.setFocus(self.tab_ids[new_tab]); │ │161 + try root_focus.setFocus(self.tab_ids.keys()[new_tab]);│ │162 } │ │163 } │ │164 │ ╰───────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────╮ │180 │ │181 fn currentTabIndex(self: View) ?usize { │ │182 const child_id = self.box.focus.child_id orelse return null;│ │169 - for (self.tab_ids, 0..) |id, i| { │ │170 - if (id == child_id) return i; │ │171 - } │ │172 - return null; │ │183 + return self.tab_ids.getIndex(child_id); │ │184 } │ │185 }; │ │186 │ ╰─────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────╮ │src/ui/User.zig│ ╰───────────────╯ ╭────────────────────────────────────────────────────╮ │13 pub const Header = @import("./User/Header.zig");│ │14 pub const Settings = @import("./Settings.zig"); │ │15 pub const Auth = @import("./Auth.zig"); │ │16 +pub const Quit = @import("./Quit.zig"); │ │17 │ │18 header: Header, │ │19 user: evt.User.Safe, │ ╰────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────╮ │20 repos: []const evt.Repo, │ │21 settings: Settings, │ │22 auth: Auth, │ │23 +quit: Quit, │ │24 route_name: ui.RoutablePage.Array(evt.User.name_max_len),│ │25 │ │26 const Self = @This(); │ ╰─────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────╮ │74 .repos = repos.items, │ │75 .settings = Settings.init(),│ │76 .auth = Auth.init(), │ │77 + .quit = Quit.init(), │ │78 .route_name = name, │ │79 }; │ │80 } │ ╰────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯