╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Home.zig ─────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
85 86 { 87 var stack = wgt.Stack(ui.Widget).init(allocator); 88 errdefer stack.deinit(allocator); 89 90 { 91 var users_view = try Users.View.init(allocator, &data.users); 92 errdefer users_view.deinit(allocator); 93 try stack.children.put(allocator, users_view.getFocus().id, .{ .home_users = users_view }); 94 } 95 96 { 97 var repos_view = try Repos.View.init(allocator, &data.repos); 98 errdefer repos_view.deinit(allocator); 99 try stack.children.put(allocator, repos_view.getFocus().id, .{ .home_repos = repos_view }); 100 } 101 102 { 103 var auth_view = try Auth.View.init(allocator, &data.auth, session, users_tab_id); 104 errdefer auth_view.deinit(allocator); 105 try stack.children.put(allocator, auth_view.getFocus().id, .{ .home_auth = auth_view }); 106 } 107 108 try box.children.put(allocator, stack.getFocus().id, .{ .widget = .{ .stack = stack }, .rect = null, .min_size = null }); 109 } 110 111 var self = View{ 112 .box = box, 113 .data = data, 114 .session = session, 115 }; 116 self.getFocus().child_id = box.children.keys()[header_index]; 117 return self; 118 } 119 120 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { 121 self.box.deinit(allocator); 122 } 123 124 pub fn build(self: *View, allocator: std.mem.Allocator, constraint: layout.Constraint, root_focus: *Focus) !void { 125 self.clearGrid(); 126 const header = &self.box.children.values()[header_index].widget.home_header; 127 const stack = &self.box.children.values()[stack_index].widget.stack; 128 129 // each header tab maps 1:1 to a stack child by position 130 if (header.getSelectedIndex()) |index| { 131 stack.getFocus().child_id = stack.children.keys()[index]; 132 self.session.data.current_page = switch (index) { 133 0 => .home_users, 134 1 => .home_repos, 135 2 => .home_auth, 136 else => .home_users, 137 }; 138 } 139 try self.box.build(allocator, constraint, root_focus); 140 } 141 142 pub fn input(self: *View, allocator: std.mem.Allocator, key: inp.Key, root_focus: *Focus) !void { 143 if (self.getFocus().child_id) |child_id| { 144 if (self.box.children.getIndex(child_id)) |current_index| { 145 const child = &self.box.children.values()[current_index].widget; 146 var index = current_index; 147 148 const Direction = enum { up, down, none }; 149 const direction: Direction = switch (key) { 150 .arrow_up => .up, 151 .arrow_down => .down, 152 .mouse => |mouse| if (mouse.action == .scroll) 153 (if (mouse.action.scroll == .up) .up else .down) 154 else 155 .none, 156 else => .none, 157 }; 158 159 switch (direction) { 160 .up => { 161 switch (child.*) { 162 .home_header => { 163 try child.input(allocator, key, root_focus); 164 }, 165 .stack => { 166 if (child.stack.getSelected()) |selected_widget| { 167 const at_top = switch (selected_widget.*) { 168 .home_users => |*v| v.getSelectedIndex() == 0, 169 .home_repos => |*v| v.getSelectedIndex() == 0, 170 .home_auth => |*v| v.getSelectedIndex() == 0, 171 else => false, 172 }; 173 if (at_top) { 174 index = header_index; 175 } else { 176 try child.input(allocator, key, root_focus); 177 } 178 } 179 }, 180 else => {}, 181 } 182 }, 183 .down => { 184 switch (child.*) { 185 .home_header => { 186 index = stack_index; 187 }, 188 .stack => { 189 try child.input(allocator, key, root_focus); 190 }, 191 else => {}, 192 } 193 }, 194 .none => { 195 try child.input(allocator, key, root_focus); 196 }, 197 } 198 199 if (index != current_index) { 200 try root_focus.setFocus(self.box.children.keys()[index]); 201 } 202 } 203 } 204 } 205 206 pub fn clearGrid(self: *View) void { 207 self.box.clearGrid(); 208 } 209 210 pub fn getGrid(self: View) ?Grid { 211 return self.box.getGrid(); 212 } 213 214 pub fn getFocus(self: *View) *Focus { 215 return self.box.getFocus(); 216 } 217 }; 218