╭ changed ──────╮ │src/test/ui.zig│ ╰───────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │1 const std = @import("std"); │ │2 const ui = @import("../ui.zig"); │ │3 const Commits = @import("../ui/Repo/Commits.zig"); │ │4 +const SubHeader = @import("../ui/Repo/SubHeader.zig"); │ │5 │ │6 // the "next" row at the bottom of the commits list must be recognized as a │ │7 // cross-page link (so a click navigates), exactly like the diff pane's "next".│ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │22 .{ .oid = oid0, .date = "2024-01-01", .message = "first", .hunks = &.{}, .window_start = 0, .has_prev = false, .has_more = false },│ │23 }, │ │24 .next_start = next_oid, │ │25 + .sub_header = try SubHeader.init(arena.allocator(), .object, oid0), │ │26 }; │ │27 │ │28 var session = ui.Session{ .arena = &arena, .page_arena = &arena, .is_terminal = true }; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────╮ │37 .max_size = .{ .width = 120, .height = 60 }, │ │38 }, root_focus); │ │39 │ │38 - // the "next" row is the last child of the list box. │ │39 - const lb = &view.box.children.values()[0].widget.scroll.child.box; │ │40 + // the "next" row is the last child of the list box: the view's outer box │ │41 + // holds the sub-header then the list/diff split, whose first child is the │ │42 + // list scroll. │ │43 + const content = &view.box.children.values()[1].widget.box; │ │44 + const lb = &content.children.values()[0].widget.scroll.child.box; │ │45 const next_id = lb.children.keys()[lb.children.count() - 1]; │ │46 │ │47 const route = ui.crossPageLink(root_focus, next_id, session.data.current_page);│ ╰───────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭───────────────────────────────────────────────╮ │1056 home_header: Home.Header.View, │ │1057 user_header: User.Header.View, │ │1058 repo_header: Repo.Header.View, │ │1059 + repo_sub_header: Repo.SubHeader.View,│ │1060 repo_files: Repo.Files.View, │ │1061 repo_commits: Repo.Commits.View, │ │1062 repo_refs: Repo.Refs.View, │ ╰───────────────────────────────────────────────╯ ╭ changed ──────╮ │src/ui/Repo.zig│ ╰───────────────╯ ╭──────────────────────────────────────────────────────────╮ │10 const Focus = xitui.focus.Focus; │ │11 │ │12 pub const Header = @import("./Repo/Header.zig"); │ │13 +pub const SubHeader = @import("./Repo/SubHeader.zig");│ │14 pub const Files = @import("./Repo/Files.zig"); │ │15 pub const Commits = @import("./Repo/Commits.zig"); │ │16 pub const Refs = @import("./Repo/Refs.zig"); │ ╰──────────────────────────────────────────────────────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Commits.zig│ ╰───────────────────────╯ ╭────────────────────────────────────────────────╮ │11 const inp = xitui.input; │ │12 const Grid = xitui.grid.Grid; │ │13 const Focus = xitui.focus.Focus; │ │14 + │ │15 +const SubHeader = @import("SubHeader.zig"); │ │16 │ │17 const RefOrOid = ui.RoutablePage.RefOrOid; │ │18 const hex_len = ui.ResolvedRefOrOid.hex_len;│ ╰────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────╮ │51 commits: []const Commit, │ │52 // the first oid of the next page, or null when this is the last page.│ │53 next_start: ?[]const u8, │ │54 +// the "viewing <ref> <value>" banner shown above the log. │ │55 +sub_header: SubHeader, │ │56 │ │57 const Self = @This(); │ │58 │ ╰──────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────╮ │147 .ref_or_oid_value = resolved.value, │ │148 .commits = try aa.dupe(Commit, buf[0..count]), │ │149 .next_start = next_start, │ │150 + .sub_header = try SubHeader.init(aa, resolved.ref_or_oid, resolved.value),│ │151 }; │ │152 } │ │153 │ ╰───────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────╮ │159 .ref_or_oid_value = try aa.dupe(u8, value), │ │160 .commits = &.{}, │ │161 .next_start = null, │ │162 + .sub_header = try SubHeader.init(aa, ref_or_oid, value),│ │163 }; │ │164 } │ │165 │ ╰─────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────╮ │303 } │ │304 │ │305 pub const View = struct { │ │300 - // a horizontal split: the commit list on the left and a diff pane on the │ │301 - // right showing the selected commit's diff │ │302 - box: wgt.Box(ui.Widget), // horiz: [list_index] = list scroll, [diff_index] = diff pane│ │306 + // a vertical stack: the "viewing <ref>" banner on top, then a horizontal │ │307 + // split with the commit list on the left and a diff pane on the right │ │308 + // showing the selected commit's diff. │ │309 + box: wgt.Box(ui.Widget), // vert: [sub_header_index] = banner, [content_index] = split │ │310 data: *const Self, │ │311 session: *ui.Session, │ │312 // the commit whose diff the pane currently shows (index into data.commits). │ ╰────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯