╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Commits.zig│ ╰───────────────────────╯ ╭──────────────────────────────────────────────────────────────────╮ │313 diffed_index: ?usize, │ │314 │ │315 + const sub_header_index: usize = 0; │ │316 + const content_index: usize = 1; │ │317 + // indices within the content box (the horizontal split).│ │318 const list_index: usize = 0; │ │319 const diff_index: usize = 1; │ │320 const list_max_width: usize = 40; │ ╰──────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │321 const diff_min_width: usize = 40; │ │322 │ │323 pub fn init(allocator: std.mem.Allocator, data: *const Self, session: *ui.Session) !View { │ │324 + var outer = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .vert }); │ │325 + errdefer outer.deinit(allocator); │ │326 + │ │327 + // the ref banner at the top. │ │328 + { │ │329 + var sub_header = try SubHeader.View.init(allocator, &data.sub_header, session); │ │330 + errdefer sub_header.deinit(allocator); │ │331 + try outer.children.put(allocator, sub_header.getFocus().id, .{ .widget = .{ .repo_sub_header = sub_header }, .rect = null, .min_size = .{ .width = null, .height = 3 } });│ │332 + } │ │333 + │ │334 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .horiz }); │ │335 errdefer box.deinit(allocator); │ │336 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │364 break :blk2 try wgt.Scroll(ui.Widget).init(allocator, .{ .box = diff_inner }, .{ .direction = .both, .web_native = !session.is_terminal }); │ │365 }; │ │366 errdefer diff_scroll.deinit(allocator); │ │347 - var outer = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = .hidden, .direction = .vert }); │ │348 - errdefer outer.deinit(allocator); │ │349 - try outer.children.put(allocator, diff_scroll.getFocus().id, .{ .widget = .{ .scroll = diff_scroll }, .rect = null, .min_size = null }); │ │350 - break :blk outer; │ │367 + var frame = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = .hidden, .direction = .vert }); │ │368 + errdefer frame.deinit(allocator); │ │369 + try frame.children.put(allocator, diff_scroll.getFocus().id, .{ .widget = .{ .scroll = diff_scroll }, .rect = null, .min_size = null }); │ │370 + break :blk frame; │ │371 }; │ │372 errdefer diff_outer.deinit(allocator); │ │373 try box.children.put(allocator, diff_outer.getFocus().id, .{ .widget = .{ .box = diff_outer }, .rect = null, .min_size = .{ .width = diff_min_width, .height = null } });│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │374 } │ │375 │ │376 box.getFocus().child_id = box.children.keys()[list_index]; │ │377 + try outer.children.put(allocator, box.getFocus().id, .{ .widget = .{ .box = box }, .rect = null, .min_size = null });│ │378 + │ │379 + // focus lives in the split; the banner isn't focusable. │ │380 + outer.getFocus().child_id = outer.children.keys()[content_index]; │ │381 │ │382 return .{ │ │359 - .box = box, │ │383 + .box = outer, │ │384 .data = data, │ │385 .session = session, │ │386 .diffed_index = null, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────╮ │431 │ │432 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { │ │433 self.box.deinit(allocator); │ │434 + } │ │435 + │ │436 + fn contentBox(self: *View) *wgt.Box(ui.Widget) { │ │437 + return &self.box.children.values()[content_index].widget.box;│ │438 } │ │439 │ │440 fn listScroll(self: *View) *wgt.Scroll(ui.Widget) { │ ╰──────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │413 - return &self.box.children.values()[list_index].widget.scroll; │ │441 + return &self.contentBox().children.values()[list_index].widget.scroll;│ │442 } │ │443 │ │444 fn listBox(self: *View) *wgt.Box(ui.Widget) { │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │446 } │ │447 │ │448 fn diffOuter(self: *View) *wgt.Box(ui.Widget) { │ │421 - return &self.box.children.values()[diff_index].widget.box; │ │449 + return &self.contentBox().children.values()[diff_index].widget.box;│ │450 } │ │451 │ │452 fn diffScroll(self: *View) *wgt.Scroll(ui.Widget) { │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │458 } │ │459 │ │460 fn diffActive(self: *View) bool { │ │433 - const cid = self.box.getFocus().child_id orelse return false; │ │434 - return self.box.children.getIndex(cid) == diff_index; │ │461 + const content = self.contentBox(); │ │462 + const cid = content.getFocus().child_id orelse return false; │ │463 + return content.children.getIndex(cid) == diff_index; │ │464 } │ │465 │ │466 // the selected commit's index, or null when the "next" row is selected.│ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │518 // the box drops the diff when the width can't hold both minimums, so when │ │519 // it's that narrow we lift the cap and let the list fill the whole width. │ │520 const both_panes_fit = if (constraint.max_size.width) |w| w >= list_max_width + diff_min_width else true; │ │492 - self.box.children.values()[list_index].max_size = if (both_panes_fit) .{ .width = list_max_width, .height = null } else null; │ │521 + self.contentBox().children.values()[list_index].max_size = if (both_panes_fit) .{ .width = list_max_width, .height = null } else null;│ │522 │ │523 // the web bounds the layout to the browser viewport like the terminal; │ │524 // each Scroll's web-native mode hands its full content to a real │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────╮ │759 // the diff pane wasn't laid out last build (too narrow to show beside │ │760 // the list), so its hunks aren't in the focus tree yet. select the pane│ │761 // at the box level, and the hunk will be focused after the next build. │ │733 - self.box.getFocus().child_id = self.diffOuter().getFocus().id; │ │762 + self.contentBox().getFocus().child_id = self.diffOuter().getFocus().id; │ │763 } │ │764 │ │765 fn focusList(self: *View, root_focus: *Focus) !void { │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯