╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Home.zig ─────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
106 self.getFocus().child_id = box.children.keys()[header_index]; 107 return self; 108 } 109 110 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { 111 self.box.deinit(allocator); 112 } 113 114 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void { 115 self.clearGrid(); 116 const header = &self.box.children.values()[header_index].widget.home_header; 117 const stack = &self.box.children.values()[stack_index].widget.stack; 118 119 // each header tab maps 1:1 to a stack child by position 120 if (header.getSelectedIndex()) |index| { 121 stack.getFocus().child_id = stack.children.keys()[index]; 122 switch (index) { 123 0 => self.session.data.current_page = .home_users, 124 1 => self.session.data.current_page = .home_repos, 125 2 => self.session.data.current_page = .home_settings, 126 3 => self.session.data.current_page = .home_auth, 127 // the quit tab is tty-only and not a route, so leave current_page 128 // alone (nothing to mirror into the url). 129 else => {}, 130 } 131 } 132 try self.box.build(allocator, constraint, root_focus); 133 } 134 135 pub fn input(self: *View, allocator: std.mem.Allocator, key: inp.Key, root_focus: *Focus) !void { 136 if (self.getFocus().child_id) |child_id| { 137 if (self.box.children.getIndex(child_id)) |current_index| { 138 const child = &self.box.children.values()[current_index].widget; 139 var index = current_index; 140 141 const Direction = enum { up, down, none }; 142 const direction: Direction = switch (key) { 143 .arrow_up => .up, 144 .arrow_down => .down, 145 .mouse => |mouse| if (mouse.action == .scroll) 146 (if (mouse.action.scroll == .up) .up else .down) 147 else 148 .none, 149 else => .none, 150 }; 151 152 switch (direction) { 153 .up => { 154 switch (child.*) { 155 .home_header => { 156 try child.input(allocator, key, root_focus); 157 }, 158 .stack => { 159 if (child.stack.getSelected()) |selected_widget| { 160 const at_top = switch (selected_widget.*) { 161 .home_users => |*v| v.getSelectedIndex() == 0, 162 .home_repos => |*v| v.getSelectedIndex() == 0, 163 .home_settings => |*v| v.getSelectedIndex() == 0, 164 .home_auth => |*v| v.getSelectedIndex() == 0, 165 .quit => |*v| v.getSelectedIndex() == 0, 166 else => false, 167 }; 168 if (at_top) { 169 index = header_index; 170 } else { 171 try child.input(allocator, key, root_focus); 172 } 173 } 174 }, 175 else => {}, 176 } 177 }, 178 .down => { 179 switch (child.*) { 180 .home_header => { 181 index = stack_index; 182 }, 183 .stack => { 184 try child.input(allocator, key, root_focus); 185 }, 186 else => {}, 187 } 188 }, 189 .none => { 190 try child.input(allocator, key, root_focus); 191 }, 192 } 193 194 if (index != current_index) { 195 try root_focus.setFocus(self.box.children.keys()[index]); 196 } 197 } 198 } 199 } 200 201 pub fn clearGrid(self: *View) void { 202 self.box.clearGrid(); 203 } 204 205 pub fn getGrid(self: View) ?Grid { 206 return self.box.getGrid(); 207 } 208 209 pub fn getFocus(self: *View) *Focus { 210 return self.box.getFocus(); 211 } 212 }; 213