summaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-03-13 08:57:52 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-03-13 08:57:52 +0100
commitb9f184fda4e5cd60b20b9f35cfbb81a6cf1fbd65 (patch)
treefccde59ee6a6d018b119333d5c63f5d35fe5aa78 /native
parent0b12d706e3767c04b89d4d2692c31ff9fa715cc9 (diff)
downloadiced-b9f184fda4e5cd60b20b9f35cfbb81a6cf1fbd65.tar.gz
iced-b9f184fda4e5cd60b20b9f35cfbb81a6cf1fbd65.tar.bz2
iced-b9f184fda4e5cd60b20b9f35cfbb81a6cf1fbd65.zip
Draft `PaneGrid::focus_adjacent`
Diffstat (limited to 'native')
-rw-r--r--native/src/widget/pane_grid.rs91
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,