╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ CloneUrl.zig ─────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
98 }); 99 errdefer text_input.deinit(allocator); 100 text_input.getFocus().focusable = true; 101 try text_input.setContent(allocator, protocols[0].text); 102 box.getFocus().child_id = text_input.getFocus().id; 103 try box.children.put(allocator, text_input.getFocus().id, .{ .widget = .{ .text_input = text_input }, .rect = null, .min_size = .{ .width = max_text_len + 2, .height = 3 } }); 104 105 return .{ .box = box, .session = session, .protocols = protocols, .protocol_count = protocol_count }; 106 } 107 108 pub fn minWidth(self: *const View) usize { 109 var width: usize = 0; 110 var max_text_len: usize = 0; 111 for (self.protocols[0..self.protocol_count]) |protocol| { 112 width += protocol.name.len + 2; 113 max_text_len = @max(max_text_len, protocol.text.len); 114 } 115 return width + max_text_len + 2; 116 } 117 118 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { 119 self.box.deinit(allocator); 120 } 121 122 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void { 123 self.clearGrid(); 124 125 if (root_focus.grandchild_id) |id| { 126 var clicked: ?usize = null; 127 for (0..self.protocol_count) |i| { 128 if (id == self.protocolLabel(i).getFocus().id) clicked = i; 129 } 130 if (clicked) |selected| { 131 if (selected != self.selected) { 132 self.selected = selected; 133 try self.textInput().setContent(allocator, self.protocols[selected].text); 134 } 135 root_focus.setFocus(self.textInput().getFocus().id); 136 } 137 } 138 139 const focused = root_focus.grandchild_id == self.textInput().getFocus().id; 140 for (0..self.protocol_count) |i| { 141 self.protocolLabel(i).options.border_style = if (i == self.selected) 142 (if (focused) .double else .single) 143 else 144 .hidden; 145 } 146 self.textInput().options.border_style = .single; 147 self.textInput().cursor = 0; 148 self.textInput().scroll_offset = 0; 149 try self.box.build(allocator, constraint, root_focus); 150 151 if (!self.session.is_terminal) { 152 const aa = self.session.arena.allocator(); 153 const id = self.textInput().getFocus().id; 154 try self.session.text_inputs.put(aa, id, self.textInput()); 155 try self.session.input_values.put(aa, id, self.protocols[self.selected].text); 156 } 157 } 158 159 pub fn input(self: *View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { 160 const next = switch (key) { 161 .arrow_left => if (self.selected > 0) self.selected - 1 else return, 162 .arrow_right => if (self.selected + 1 < self.protocol_count) self.selected + 1 else return, 163 .enter => { 164 if (self.session.is_terminal) self.session.host_request = .{ .show_copyable_text = self.protocols[self.selected].copyable_text }; 165 return; 166 }, 167 .mouse => |mouse| blk: { 168 for (0..self.protocol_count) |i| { 169 if (inp.leftClickOn(root_focus, self.protocolLabel(i).getFocus().id, mouse)) break :blk i; 170 } 171 if (self.session.is_terminal and !mouse.ctrl and inp.leftClickOn(root_focus, self.textInput().getFocus().id, mouse)) 172 self.session.host_request = .{ .show_copyable_text = self.protocols[self.selected].copyable_text }; 173 return; 174 }, 175 else => return, 176 }; 177 self.selected = next; 178 try self.textInput().setContent(allocator, self.protocols[next].text); 179 } 180 181 fn textInput(self: *View) *wgt.TextInput(ui.Widget) { 182 return &self.box.children.values()[self.protocol_count].widget.text_input; 183 } 184 185 fn protocolLabel(self: *View, index: usize) *wgt.TextBox(ui.Widget) { 186 return &self.box.children.values()[index].widget.text_box; 187 } 188 189 pub fn clearGrid(self: *View) void { 190 self.box.clearGrid(); 191 } 192 193 pub fn getGrid(self: View) ?Grid { 194 return self.box.getGrid(); 195 } 196 197 pub fn getFocus(self: *View) *Focus { 198 return self.box.getFocus(); 199 } 200 }; 201