╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Undo.zig ─────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
647 .arrow_right, .enter => if (self.selected() != null) self.focusDetail(root_focus), 648 // when the window is too narrow to lay out the detail pane beside 649 // the list, a click on a row opens it like enter. the detail was 650 // swapped to the just-selected row above. 651 .mouse => |mouse| if (self.selected() != null and self.contentBox().children.values()[1].rect == null and ui.widget.clickOnSelectedRow(&self.listScroll().child.box, root_focus, mouse)) { 652 self.focusDetail(root_focus); 653 }, 654 else => {}, 655 } 656 } 657 658 // enter the detail pane, landing on the way back to the list when it shows 659 fn focusDetail(self: *View, root_focus: *Focus) void { 660 if (ui.widget.listBackId(self.detailFrame()) != null) return ui.widget.focusListBack(self.detailFrame(), root_focus); 661 root_focus.setFocus(self.detailScroll().getFocus().id); 662 } 663 664 fn focusList(self: *View, root_focus: *Focus) void { 665 root_focus.setFocus(self.listScroll().getFocus().id); 666 } 667 668 // the confirm button submits the form the web renderer posts 669 fn clearInput(self: *View, key: Key, root_focus: *Focus) !void { 670 const center = &self.box.children.values()[content_index].widget.center; 671 const button_id = center.child.box.getFocus().child_id orelse return; 672 if (!inp.activated(root_focus, button_id, key) or !self.data.handle.canUndo()) return; 673 self.requestUndo(ui.RoutablePage.repoUndoClearRoute(self.data.identity) orelse return error.RouteTooLong); 674 } 675 676 fn contentAtTop(self: *View) bool { 677 const scroll = if (self.detailActive()) self.detailScroll() else self.listScroll(); 678 const rows = &scroll.child.box; 679 const id = rows.getFocus().child_id orelse return true; 680 return rows.children.getIndex(id) == 0 and scroll.y == 0; 681 } 682 683 // moving up from the sub header returns to the page's tabs 684 pub fn atTop(self: *View) bool { 685 return self.headerActive(); 686 } 687 688 // arriving from the page's tabs lands on the sub header, not the content 689 pub fn focusHeader(self: *View, root_focus: *Focus) bool { 690 root_focus.setFocus(self.headerBox().getFocus().id); 691 return true; 692 } 693 pub fn deinit(self: *View, allocator: std.mem.Allocator) void { 694 self.box.deinit(allocator); 695 } 696 pub fn clearGrid(self: *View) void { 697 self.box.clearGrid(); 698 } 699 pub fn getGrid(self: View) ?Grid { 700 return self.box.getGrid(); 701 } 702 pub fn getFocus(self: *View) *Focus { 703 return self.box.getFocus(); 704 } 705 }; 706