keyboard_navigation.rs

 1use gpui::{Focusable, actions};
 2
 3actions!(
 4    keyboard_navigation,
 5    [NextRow, PreviousRow, NextColumn, PreviousColumn]
 6);
 7
 8/// Implement this trait to enable grid-like keyboard navigation for a layout.
 9///
10/// This trait allows you to navigate through a layout of rows with mixed column
11/// lengths. In example, a layout might have rows with 5, 1 and 3 columns.
12///
13/// Moving up or down between rows will focus the first element in the next or previous row.
14/// Moving left or right between columns will focus the next or previous element in the same row.
15///
16/// Wrapping can be enabled via `vertical_wrapping` and `horizontal_wrapping` respectively.
17pub trait KeyboardNavigation: Focusable {
18    fn has_focus(&self) -> bool;
19    /// The focused row. Always has a value to allow for "focused inactive" states.
20    fn focused_row(&self) -> usize;
21    /// The focused column. Always has a value to allow for "focused inactive" states.
22    fn focused_column(&self) -> usize;
23    /// Focus the first focusable element in the layout.
24    fn focus_first(&self);
25    /// Focus the next row, wrapping back to the first row if necessary.
26    ///
27    /// Is a no-op if wrapping is not enabled.
28    fn focus_next_row(&self);
29    /// Focus the previous row, wrapping back to the last row if necessary.
30    ///
31    /// Is a no-op if wrapping is not enabled.
32    fn focus_previous_row(&self);
33    /// Focus the next column, wrapping back to the first column if necessary.
34    ///
35    /// Is a no-op if wrapping is not enabled.
36    fn focus_next_column(&self);
37    /// Focus the previous column, wrapping back to the last column if necessary.
38    ///
39    /// Is a no-op if wrapping is not enabled.
40    fn focus_previous_column(&self);
41    /// Focus the row at the given index.
42    fn focus_row_index(&self, index: usize);
43    /// Focus the column at the given index.
44    fn focus_column_index(&self, ix: usize);
45    /// When reaching the last row, should moving down wrap
46    /// back to the first row, and vice versa?
47    fn vertical_wrap(&self) -> bool {
48        false
49    }
50    /// When reaching the last column, should moving right wrap
51    /// back to the first column, and vice versa?
52    fn horizontal_wrap(&self) -> bool {
53        false
54    }
55}
56
57pub struct NavigationRow {}
58
59pub struct NavigationColumn {}