╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Files.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
863 // `value` arrives url-encoded, so decode it for display. 864 pub fn init(aa: std.mem.Allocator, ref_or_oid: ui.RoutablePage.RefOrOid, value: []const u8) !Header { 865 const decoded = std.Uri.percentDecodeInPlace(try aa.dupe(u8, value)); 866 return .{ 867 .content = try std.fmt.allocPrint(aa, "{s} {s}", .{ @tagName(ref_or_oid), decoded }), 868 }; 869 } 870 871 pub const View = struct { 872 box: wgt.Box(ui.Widget), 873 data: *const Header, 874 875 pub fn init(allocator: std.mem.Allocator, data: *const Header, session: *ui.Session, identity: []const u8) !Header.View { 876 var box = try wgt.Box(ui.Widget).init(allocator, .{ .border_style = null, .direction = .horiz }); 877 errdefer box.deinit(allocator); 878 879 if (!session.data.is_local and (session.data.clone_http_port != null or session.data.clone_ssh_port != null)) { 880 var clone_url = try ui.CloneUrl.View.init(allocator, session, identity); 881 errdefer clone_url.deinit(allocator); 882 const min_width = clone_url.minWidth(); 883 box.getFocus().child_id = clone_url.getFocus().id; 884 try box.children.put(allocator, clone_url.getFocus().id, .{ .widget = .{ .clone_url = clone_url }, .rect = null, .min_size = .{ .width = min_width, .height = 3 } }); 885 } 886 887 var spacer = try ui.Spacer.init(allocator); 888 errdefer spacer.deinit(allocator); 889 try box.children.put(allocator, spacer.getFocus().id, .{ .widget = .{ .spacer = spacer }, .rect = null, .min_size = null }); 890 891 var text_box = try wgt.TextBox(ui.Widget).init(allocator, data.content, .{ .border_style = .hidden, .wrap_kind = .none }); 892 errdefer text_box.deinit(allocator); 893 try box.children.put(allocator, text_box.getFocus().id, .{ .widget = .{ .text_box = text_box }, .rect = null, .min_size = null, .shrink = true }); 894 895 return .{ .box = box, .data = data }; 896 } 897 898 pub fn deinit(self: *Header.View, allocator: std.mem.Allocator) void { 899 self.box.deinit(allocator); 900 } 901 902 pub fn build(self: *Header.View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void { 903 self.clearGrid(); 904 try self.box.build(allocator, constraint, root_focus); 905 } 906 907 pub fn input(self: *Header.View, allocator: std.mem.Allocator, key: Key, root_focus: *Focus) !void { 908 const clone_url = self.cloneUrl() orelse return; 909 try clone_url.input(allocator, key, root_focus); 910 } 911 912 pub fn focusCloneUrl(self: *Header.View, root_focus: *Focus) bool { 913 const clone_url = self.cloneUrl() orelse return false; 914 root_focus.setFocus(clone_url.getFocus().id); 915 return true; 916 } 917 918 pub fn hasCloneUrl(self: *Header.View) bool { 919 return self.cloneUrl() != null; 920 } 921 922 fn cloneUrl(self: *Header.View) ?*ui.CloneUrl.View { 923 for (self.box.children.values()) |*child| switch (child.widget) { 924 .clone_url => |*clone_url| return clone_url, 925 else => {}, 926 }; 927 return null; 928 } 929 930 pub fn clearGrid(self: *Header.View) void { 931 self.box.clearGrid(); 932 } 933 934 pub fn getGrid(self: Header.View) ?Grid { 935 return self.box.getGrid(); 936 } 937 938 pub fn getFocus(self: *Header.View) *Focus { 939 return self.box.getFocus(); 940 } 941 }; 942 }; 943