diff options
-rw-r--r-- | examples/panes/src/main.rs | 7 | ||||
-rw-r--r-- | native/src/widget/panes.rs | 50 |
2 files changed, 54 insertions, 3 deletions
diff --git a/examples/panes/src/main.rs b/examples/panes/src/main.rs index b34ce205..34206a2c 100644 --- a/examples/panes/src/main.rs +++ b/examples/panes/src/main.rs @@ -29,6 +29,7 @@ enum Message { Clock(panes::Pane, clock::Message), Stopwatch(panes::Pane, stopwatch::Message), Split(panes::Split), + Close, } impl Application for Launcher { @@ -75,6 +76,11 @@ impl Application for Launcher { self.panes.split(kind, &pane, state); } } + Message::Close => { + if let Some(pane) = self.panes.focused_pane() { + self.panes.close(&pane); + } + } } Command::none() @@ -102,6 +108,7 @@ impl Application for Launcher { .map(|_| Message::Split(panes::Split::Horizontal)), events::key_released(keyboard::KeyCode::V) .map(|_| Message::Split(panes::Split::Vertical)), + events::key_released(keyboard::KeyCode::Q).map(|_| Message::Close), panes_subscriptions, ]) } diff --git a/native/src/widget/panes.rs b/native/src/widget/panes.rs index 22fa2b5a..2ffb2226 100644 --- a/native/src/widget/panes.rs +++ b/native/src/widget/panes.rs @@ -199,6 +199,10 @@ impl<T> State<T> { ) } + pub fn len(&self) -> usize { + self.panes.len() + } + pub fn get_mut(&mut self, pane: &Pane) -> Option<&mut T> { self.panes.get_mut(pane) } @@ -252,6 +256,15 @@ impl<T> State<T> { Some(new_pane) } + + pub fn close(&mut self, pane: &Pane) -> Option<T> { + if let Some(sibling) = self.internal.layout.remove(pane) { + self.internal.focused_pane = Some(sibling); + self.panes.remove(pane) + } else { + None + } + } } #[derive(Debug, Clone, Hash)] @@ -266,7 +279,7 @@ enum Node { } impl Node { - pub fn find(&mut self, pane: &Pane) -> Option<&mut Node> { + fn find(&mut self, pane: &Pane) -> Option<&mut Node> { match self { Node::Split { a, b, .. } => { if let Some(node) = a.find(pane) { @@ -285,7 +298,7 @@ impl Node { } } - pub fn split(&mut self, kind: Split, new_pane: Pane) { + fn split(&mut self, kind: Split, new_pane: Pane) { *self = Node::Split { kind, ratio: 500_000, @@ -294,6 +307,23 @@ impl Node { }; } + fn remove(&mut self, pane: &Pane) -> Option<Pane> { + match self { + Node::Split { a, b, .. } => { + if a.pane() == Some(*pane) { + *self = *b.clone(); + Some(self.first_pane()) + } else if b.pane() == Some(*pane) { + *self = *a.clone(); + Some(self.first_pane()) + } else { + a.remove(pane).or_else(|| b.remove(pane)) + } + } + Node::Pane(_) => None, + } + } + pub fn regions(&self, size: Size) -> HashMap<Pane, Rectangle> { let mut regions = HashMap::new(); @@ -310,6 +340,20 @@ impl Node { regions } + fn pane(&self) -> Option<Pane> { + match self { + Node::Split { .. } => None, + Node::Pane(pane) => Some(*pane), + } + } + + fn first_pane(&self) -> Pane { + match self { + Node::Split { a, .. } => a.first_pane(), + Node::Pane(pane) => *pane, + } + } + fn compute_regions( &self, current: &Rectangle, @@ -330,7 +374,7 @@ impl Node { } } -#[derive(Debug, Clone, Copy, Hash)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub enum Split { Horizontal, Vertical, |