╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭────────────────────────────────────────────────────────────────────╮ │1747 description: []const u8, │ │1748 target_branch: []const u8, │ │1749 source_branch: []const u8 = "", │ │1750 - branch_source: bool = false, │ │1750 + source_kind: Repo.Patches.Source.Kind = .fork,│ │1751 } = null, │ │1752 }, │ │1753 discussion: struct { │ ╰────────────────────────────────────────────────────────────────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Patches.zig│ ╰───────────────────────╯ ╭──────────────────────────────────────────╮ │2 const builtin = @import("builtin"); │ │3 const evt = @import("../../event.zig");│ │4 const ui = @import("../../ui.zig"); │ │5 +const inp = @import("../input.zig"); │ │6 const xit = @import("xit"); │ │7 const rp = xit.repo; │ │8 const hash = xit.hash; │ ╰──────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │20 pub const Source = struct { │ │21 box: wgt.Box(ui.Widget), │ │22 session: *ui.Session, │ │22 - existing: bool, │ │23 - input_index: usize, │ │23 + selected: Kind, │ │24 + selectors: std.enums.EnumMap(Kind, usize), │ │25 + │ │26 + pub const Kind = enum { fork, branch }; │ │27 │ │25 - pub fn init(allocator: std.mem.Allocator, session: *ui.Session, initial: []const u8, existing: bool) !Source { │ │28 + pub fn init(allocator: std.mem.Allocator, session: *ui.Session, initial: []const u8, initial_kind: Kind) !Source { │ │29 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .horiz }); │ │30 errdefer box.deinit(allocator); │ │31 + const selected: Kind = if (session.data.host_kind == .local) .branch else initial_kind; │ │32 + var selectors: std.enums.EnumMap(Kind, usize) = .{}; │ │33 if (session.data.host_kind != .local) { │ │29 - for ([_][]const u8{ "from a new fork", "from an existing branch" }) |label| { │ │34 + for (std.enums.values(Kind)) |kind| { │ │35 + const label = switch (kind) { │ │36 + .fork => "from a new fork", │ │37 + .branch => "from an existing branch", │ │38 + }; │ │39 var selector = try wgt.TextBox.init(allocator, label, .{ .border_style = .single, .rounded_corners = true, .wrap_kind = .none });│ │40 errdefer selector.deinit(allocator); │ │41 selector.getFocus().mode = .all; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │42 try box.children.put(allocator, selector.getFocus().id, .{ .widget = .{ .text_box = selector }, .rect = null, .min_size = .{ .width = label.len + 2, .height = 3 } }); │ │43 + selectors.put(kind, selector.getFocus().id); │ │44 } │ │45 } │ │36 - const input_index = box.children.count(); │ │46 var input_box = try wgt.TextInput.init(allocator, .{ .label = " source branch ", .name = "source_branch", .rounded_corners = true, .visible_width = null, .render_content = session.is_terminal });│ │47 errdefer input_box.deinit(allocator); │ │48 input_box.getFocus().mode = .all; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │49 try input_box.setContent(allocator, initial); │ │50 try box.children.put(allocator, input_box.getFocus().id, .{ .widget = .{ .text_input = input_box }, .rect = null, .min_size = .{ .width = 15, .height = 3 } });│ │42 - box.getFocus().child_id = box.children.keys()[if (existing and input_index > 0) input_index - 1 else 0]; │ │43 - return .{ .box = box, .session = session, .existing = existing or input_index == 0, .input_index = input_index }; │ │51 + box.getFocus().child_id = selectors.get(selected) orelse input_box.getFocus().id; │ │52 + return .{ .box = box, .session = session, .selected = selected, .selectors = selectors }; │ │53 } │ │54 │ │55 pub fn field(self: *Source) *wgt.TextInput { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────╮ │47 - return &self.box.children.values()[self.input_index].widget.text_input;│ │56 + for (self.box.children.values()) |*child| switch (child.widget) { │ │57 + .text_input => |*text_input| return text_input, │ │58 + else => {}, │ │59 + }; │ │60 + unreachable; │ │61 } │ │62 + │ │63 pub fn deinit(self: *Source, allocator: std.mem.Allocator) void { │ │64 self.box.deinit(allocator); │ │65 } │ ╰───────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────╮ │66 + │ │67 pub fn clearGrid(self: *Source) void {│ │68 self.box.clearGrid(); │ │69 } │ ╰──────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────╮ │70 + │ │71 pub fn getGrid(self: Source) ?xitui.grid.Grid {│ │72 return self.box.getGrid(); │ │73 } │ ╰───────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────╮ │74 + │ │75 pub fn getFocus(self: *Source) *xitui.focus.Focus {│ │76 return self.box.getFocus(); │ │77 } │ ╰───────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │78 │ │79 pub fn build(self: *Source, allocator: std.mem.Allocator, constraint: xitui.layout.Constraint, root_focus: *xitui.focus.Focus) !void {│ │80 self.clearGrid(); │ │64 - self.box.children.values()[self.input_index].hidden = !self.existing; │ │65 - for (self.box.children.values()[0..self.input_index], 0..) |*child, i| { │ │66 - child.widget.text_box.options.border_style = if ((i == self.input_index - 1) == self.existing) .single else .hidden; │ │67 - } │ │81 + for (self.box.children.keys(), self.box.children.values()) |id, *child| switch (child.widget) { │ │82 + .text_input => child.hidden = switch (self.selected) { │ │83 + .fork => true, │ │84 + .branch => false, │ │85 + }, │ │86 + .text_box => |*selector| selector.options.border_style = if (id == self.selectors.get(self.selected)) .single else .hidden, │ │87 + else => {}, │ │88 + }; │ │89 try self.box.build(allocator, constraint, root_focus); │ │90 if (!self.session.is_terminal) { │ │91 try self.session.text_inputs.put(self.session.arena.allocator(), self.field().getFocus().id, self.field()); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯