diff options
author | 2020-03-13 08:57:52 +0100 | |
---|---|---|
committer | 2020-03-13 08:57:52 +0100 | |
commit | b9f184fda4e5cd60b20b9f35cfbb81a6cf1fbd65 (patch) | |
tree | fccde59ee6a6d018b119333d5c63f5d35fe5aa78 /native/src/widget | |
parent | 0b12d706e3767c04b89d4d2692c31ff9fa715cc9 (diff) | |
download | iced-b9f184fda4e5cd60b20b9f35cfbb81a6cf1fbd65.tar.gz iced-b9f184fda4e5cd60b20b9f35cfbb81a6cf1fbd65.tar.bz2 iced-b9f184fda4e5cd60b20b9f35cfbb81a6cf1fbd65.zip |
Draft `PaneGrid::focus_adjacent`
Diffstat (limited to 'native/src/widget')
-rw-r--r-- | native/src/widget/pane_grid.rs | 91 |
1 files changed, 83 insertions, 8 deletions
diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs index 78057bda..d93f8738 100644 --- a/native/src/widget/pane_grid.rs +++ b/native/src/widget/pane_grid.rs @@ -319,6 +319,14 @@ enum FocusedPane { Some { pane: Pane, focus: Focus }, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Direction { + Top, + Bottom, + Left, + Right, +} + impl<T> State<T> { pub fn new(first_pane_state: T) -> (Self, Pane) { let first_pane = Pane(0); @@ -370,13 +378,20 @@ impl<T> State<T> { } } - pub fn focus(&mut self, pane: Pane) { + pub fn focus(&mut self, pane: &Pane) { self.internal.focused_pane = FocusedPane::Some { - pane, + pane: *pane, focus: Focus::Idle, }; } + pub fn focus_adjacent(&mut self, pane: &Pane, direction: Direction) { + if let Some(pane) = self.internal.layout.find_adjacent(pane, direction) + { + self.focus(&pane); + } + } + pub fn split_vertically(&mut self, pane: &Pane, state: T) -> Option<Pane> { self.split(Split::Vertical, pane, state) } @@ -452,15 +467,17 @@ enum Node { Pane(Pane), } +#[derive(Debug)] +enum Branch { + First, + Second, +} + impl Node { fn find(&mut self, pane: &Pane) -> Option<&mut Node> { match self { Node::Split { a, b, .. } => { - if let Some(node) = a.find(pane) { - Some(node) - } else { - b.find(pane) - } + a.find(pane).or_else(move || b.find(pane)) } Node::Pane(p) => { if p == pane { @@ -472,6 +489,64 @@ impl Node { } } + fn find_adjacent( + &mut self, + pane: &Pane, + direction: Direction, + ) -> Option<Pane> { + let (pane, _) = self.find_split(pane, &|kind, branch, a, b| match ( + direction, kind, branch, + ) { + (Direction::Top, Split::Vertical, Branch::Second) + | (Direction::Left, Split::Horizontal, Branch::Second) => { + Some(a.first_pane()) + } + (Direction::Bottom, Split::Vertical, Branch::First) + | (Direction::Right, Split::Horizontal, Branch::First) => { + Some(b.first_pane()) + } + _ => None, + }); + + pane + } + + fn find_split<T>( + &mut self, + pane: &Pane, + callback: &impl Fn(Split, Branch, &Node, &Node) -> Option<T>, + ) -> (Option<T>, bool) { + match self { + Node::Split { a, b, kind, .. } => { + let kind = *kind; + let (result, found) = a.find_split(pane, callback); + + if result.is_some() { + (result, found) + } else if found { + (callback(kind, Branch::First, a, b), true) + } else { + let (result, found) = b.find_split(pane, callback); + + if result.is_some() { + (result, found) + } else if found { + (callback(kind, Branch::Second, a, b), true) + } else { + (None, false) + } + } + } + Node::Pane(p) => { + if p == pane { + (None, true) + } else { + (None, false) + } + } + } + } + fn split(&mut self, kind: Split, new_pane: Pane) { *self = Node::Split { kind, @@ -567,7 +642,7 @@ impl Node { } } -#[derive(Debug, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum Split { Horizontal, Vertical, |