╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ CloneUrl.zig ─────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
72 url_input.getFocus().focusable = true; 73 try url_input.setContent(allocator, protocols[0].url); 74 box.getFocus().child_id = url_input.getFocus().id; 75 try box.children.put(allocator, url_input.getFocus().id, .{ .widget = .{ .text_input = url_input }, .rect = null, .min_size = .{ .width = max_url_len + 2, .height = 3 } }); 76 77 return .{ .box = box, .session = session, .protocols = protocols, .protocol_count = protocol_count }; 78 } 79 80 pub fn minWidth(self: *const View) usize { 81 var width: usize = 0; 82 var max_url_len: usize = 0; 83 for (self.protocols[0..self.protocol_count]) |protocol| { 84 width += protocol.name.len + 2; 85 max_url_len = @max(max_url_len, protocol.url.len); 86 } 87 return width + max_url_len + 2; 88 } 89 90 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { 91 self.box.deinit(allocator); 92 } 93 94 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void { 95 self.clearGrid(); 96 97 if (root_focus.grandchild_id) |id| { 98 var clicked: ?usize = null; 99 for (0..self.protocol_count) |i| { 100 if (id == self.protocolLabel(i).getFocus().id) clicked = i; 101 } 102 if (clicked) |selected| { 103 if (selected != self.selected) { 104 self.selected = selected; 105 try self.urlInput().setContent(allocator, self.protocols[selected].url); 106 } 107 root_focus.setFocus(self.urlInput().getFocus().id); 108 } 109 } 110 111 const focused = root_focus.grandchild_id == self.urlInput().getFocus().id; 112 for (0..self.protocol_count) |i| { 113 self.protocolLabel(i).options.border_style = if (i == self.selected) 114 (if (focused) .double else .single) 115 else 116 .hidden; 117 } 118 self.urlInput().options.border_style = .single; 119 self.urlInput().cursor = 0; 120 self.urlInput().scroll_offset = 0; 121 try self.box.build(allocator, constraint, root_focus); 122 123 if (!self.session.is_terminal) { 124 const aa = self.session.arena.allocator(); 125 const id = self.urlInput().getFocus().id; 126 try self.session.text_inputs.put(aa, id, self.urlInput()); 127 try self.session.input_values.put(aa, id, self.protocols[self.selected].url); 128 } 129 } 130 131 pub fn input(self: *View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { 132 const next = switch (key) { 133 .arrow_left => if (self.selected > 0) self.selected - 1 else return, 134 .arrow_right => if (self.selected + 1 < self.protocol_count) self.selected + 1 else return, 135 .enter => { 136 if (self.session.is_terminal) self.session.host_request = .{ .show_copyable_text = self.protocols[self.selected].copyable_text }; 137 return; 138 }, 139 .mouse => |mouse| blk: { 140 for (0..self.protocol_count) |i| { 141 if (inp.leftClickOn(root_focus, self.protocolLabel(i).getFocus().id, mouse)) break :blk i; 142 } 143 if (self.session.is_terminal and !mouse.ctrl and inp.leftClickOn(root_focus, self.urlInput().getFocus().id, mouse)) 144 self.session.host_request = .{ .show_copyable_text = self.protocols[self.selected].copyable_text }; 145 return; 146 }, 147 else => return, 148 }; 149 self.selected = next; 150 try self.urlInput().setContent(allocator, self.protocols[next].url); 151 } 152 153 fn urlInput(self: *View) *wgt.TextInput(ui.Widget) { 154 return &self.box.children.values()[self.protocol_count].widget.text_input; 155 } 156 157 fn protocolLabel(self: *View, index: usize) *wgt.TextBox(ui.Widget) { 158 return &self.box.children.values()[index].widget.text_box; 159 } 160 161 pub fn clearGrid(self: *View) void { 162 self.box.clearGrid(); 163 } 164 165 pub fn getGrid(self: View) ?Grid { 166 return self.box.getGrid(); 167 } 168 169 pub fn getFocus(self: *View) *Focus { 170 return self.box.getFocus(); 171 } 172 }; 173