╭ changed ─────────────╮ │src/ui/Repo/Events.zig│ ╰──────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │536 - var status = try wgt.TextBox(ui.Widget).init(allocator, data.status, .{ .border_style = .hidden, .wrap_kind = .none }); │ │537 - errdefer status.deinit(allocator); │ │538 - try box.children.put(allocator, status.getFocus().id, .{ .widget = .{ .text_box = status }, .rect = null, .min_size = null, .shrink = true }); │ │539 - return .{ .box = box, .session = session, .button_id = button_id }; │ │590 + if (data.header.sync_status) |status_text| { │ │591 + var status = try wgt.TextBox(ui.Widget).init(allocator, status_text, .{ .border_style = .hidden, .wrap_kind = .none }); │ │592 + errdefer status.deinit(allocator); │ │593 + try box.children.put(allocator, status.getFocus().id, .{ .widget = .{ .text_box = status }, .rect = null, .min_size = null, .shrink = true });│ │594 + } │ │595 + box.getFocus().child_id = tab_ids[@intFromEnum(data.view)]; │ │596 + return .{ .box = box, .session = session, .tab_ids = tab_ids, .button_id = button_id }; │ │597 } │ │598 │ │599 pub fn deinit(self: *Header.View, allocator: std.mem.Allocator) void { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │602 │ │603 pub fn build(self: *Header.View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void {│ │604 self.clearGrid(); │ │605 + for (self.tab_ids) |id| { │ │606 + const child = self.box.children.getPtr(id) orelse continue; │ │607 + const tab = switch (child.widget) { │ │608 + .text_box => |*text_box| text_box, │ │609 + else => continue, │ │610 + }; │ │611 + tab.options.border_style = if (self.box.getFocus().child_id == id) .single else .hidden; │ │612 + } │ │613 try self.box.build(allocator, constraint, root_focus); │ │614 } │ │615 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │616 pub fn input(self: *Header.View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { │ │552 - const button_id = self.button_id orelse return; │ │553 - if (!self.session.is_terminal) return; │ │554 - if (self.session.host_request != null) return; │ │617 + const selected = self.box.getFocus().child_id orelse return; │ │618 + const current = self.box.children.getIndex(selected) orelse return; │ │619 + const count = 2 + @as(usize, @intFromBool(self.button_id != null)); │ │620 + if (inp.moveTab(key, current, count)) |next| { │ │621 + root_focus.setFocus(self.box.children.keys()[next]); │ │622 + return; │ │623 + } │ │624 switch (key) { │ │556 - .enter => self.requestSync(), │ │557 - .mouse => |mouse| if (inp.leftClickOn(root_focus, button_id, mouse)) self.requestSync(), │ │625 + .enter => if (self.syncFocused()) self.requestSync(), │ │626 + .mouse => |mouse| if (self.button_id) |id| if (inp.leftClickOn(root_focus, id, mouse)) self.requestSync(),│ │627 else => {}, │ │628 } │ │629 _ = allocator; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │630 } │ │631 │ │632 fn requestSync(self: *Header.View) void { │ │633 + if (!self.session.is_terminal) return; │ │634 + if (self.session.host_request != null) return; │ │635 self.session.host_request = .sync_events; │ │636 const button_id = self.button_id orelse return; │ │637 const child = self.box.children.getPtr(button_id) orelse return;│ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────╮ │646 }; │ │647 } │ │648 │ │578 - pub fn focusButton(self: *Header.View, root_focus: *Focus) bool { │ │649 + fn syncFocused(self: *Header.View) bool { │ │650 const button_id = self.button_id orelse return false; │ │580 - root_focus.setFocus(button_id); │ │581 - return true; │ │651 + return self.box.getFocus().child_id == button_id; │ │652 + } │ │653 + │ │654 + pub fn getSelectedIndex(self: *Header.View) ?usize { │ │655 + const id = self.box.getFocus().child_id orelse return null; │ │656 + return std.mem.indexOfScalar(usize, &self.tab_ids, id); │ │657 } │ │658 │ │584 - pub fn isFocusable(self: *Header.View) bool { │ │585 - return self.button_id != null; │ │659 + pub fn focusCurrent(self: *Header.View, root_focus: *Focus) void { │ │660 + root_focus.setFocus(self.box.getFocus().child_id orelse self.tab_ids[0]);│ │661 } │ │662 │ │663 pub fn clearGrid(self: *Header.View) void { │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────╮ │691 session.data.sync_failure = null; │ │692 switch (session.data.current_page) { │ │693 .repo_events => |route| { │ │619 - if (ui.RoutablePage.repoEventsRoute(route.name.slice(), null, "")) |first| │ │694 + if (ui.RoutablePage.repoEventsRoute(route.name.slice(), route.view, null, "")) |first|│ │695 session.data.current_page = first; │ │696 }, │ │697 else => {}, │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────╯