╭ changed ─────────────╮ │src/ui/Repo/Header.zig│ ╰──────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │46 scroll: wgt.Scroll(ui.Widget), │ │47 data: *const Self, │ │48 tab_ids: std.AutoArrayHashMapUnmanaged(usize, void), │ │49 + tabs_id: usize, │ │50 + first_group_width: usize, │ │51 │ │52 pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session) !View { │ │53 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = .hidden, .rounded_corners = true, .direction = .horiz });│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │54 errdefer box.deinit(allocator); │ │55 │ │56 + var title_box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .horiz });│ │57 + var title_box_owned = false; │ │58 + errdefer if (!title_box_owned) title_box.deinit(allocator); │ │59 + │ │60 + var tabs_box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .horiz }); │ │61 + var tabs_box_owned = false; │ │62 + errdefer if (!tabs_box_owned) tabs_box.deinit(allocator); │ │63 + │ │64 var tab_ids: std.AutoArrayHashMapUnmanaged(usize, void) = .empty; │ │65 errdefer tab_ids.deinit(allocator); │ │66 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │68 const ref_name = std.Uri.percentDecodeInPlace(try aa.dupe(u8, data.ref_or_oid_value)); │ │69 const bottom_label = try ui.clippedBottomLabel(try aa.alloc(u8, ui.clipped_bottom_label_max_len), ref_name);│ │70 const bottom_label_width = try xitui.width.displayWidth(bottom_label); │ │71 + var first_group_width = try data.title.width(); │ │72 │ │73 // the user's name (local mode has no user pages to link to) │ │74 if (!session.data.is_local) { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │79 errdefer text_box.deinit(allocator); │ │80 text_box.getFocus().focusable = true; │ │81 text_box.getFocus().kind = .{ .custom = link }; │ │71 - try box.children.put(allocator, text_box.getFocus().id, .{ │ │82 + first_group_width += try xitui.width.displayWidth(text) + 2; │ │83 + try title_box.children.put(allocator, text_box.getFocus().id, .{│ │84 .widget = .{ .text_box = text_box }, │ │85 .rect = null, │ │86 .min_size = null, │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────╮ │75 - .flex = .shrink,│ │87 }); │ │88 } │ │89 │ ╰────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │90 // local routes carry no identity, so their urls come out elided │ │91 const identity = if (session.data.is_local) "" else try std.fmt.allocPrint(aa, "{s}/{s}", .{ data.owner_name, data.name });│ │92 │ │82 - // title sits to the left of the tabs; it links to the repo's files root │ │83 - // (the bare route, so it resolves to the default branch). │ │93 + // title links to the repo's files root (the bare route, so it resolves │ │94 + // to the default branch). │ │95 { │ │96 const files_root_route = ui.RoutablePage.repoFilesRoute(identity, null, "", "", 0) orelse return error.RouteTooLong; │ │97 const title_link = try std.fmt.allocPrint(aa, "a:{s}", .{try files_root_route.toUrl(session.page_arena)}); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │ 99 errdefer title_view.deinit(allocator); │ │100 title_view.getFocus().focusable = true; │ │101 title_view.getFocus().kind = .{ .custom = title_link }; │ │ 91 - // shrink the title when there is not enough space │ │ 92 - try box.children.put(allocator, title_view.getFocus().id, .{ │ │102 + try title_box.children.put(allocator, title_view.getFocus().id, .{│ │103 .widget = .{ .title = title_view }, │ │104 .rect = null, │ │105 .min_size = null, │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────╮ │ 96 - .flex = .shrink,│ │106 }); │ │107 } │ │108 │ ╰─────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────╮ │110 { │ │111 var text = try wgt.Text(ui.Widget).init(allocator, " "); │ │112 errdefer text.deinit(allocator); │ │104 - try box.children.put(allocator, text.getFocus().id, .{ │ │113 + try tabs_box.children.put(allocator, text.getFocus().id, .{│ │114 .widget = .{ .text = text }, │ │115 .rect = null, │ │116 .min_size = .{ .width = 1, .height = null }, │ ╰────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │165 text_box.getFocus().kind = .{ .custom = files_link }; │ │166 try tab_ids.put(allocator, text_box.getFocus().id, {}); │ │167 if (std.mem.eql(u8, files_link, current_link)) selected_tab = text_box.getFocus().id; │ │159 - try box.children.put(allocator, text_box.getFocus().id, .{ │ │168 + try tabs_box.children.put(allocator, text_box.getFocus().id, .{ │ │169 .widget = .{ .text_box = text_box }, │ │170 .rect = null, │ │171 .min_size = .{ .width = @max("files".len, bottom_label_width) + 2, .height = null },│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯