diff options
author | 2020-03-14 05:26:59 +0100 | |
---|---|---|
committer | 2020-03-14 05:27:27 +0100 | |
commit | 5c8ec4504b6541cdc588b91a6b2c7100b4a7cc77 (patch) | |
tree | 7d780613c258c02078813f5c7d8163d07acd1341 /native/src/widget/pane_grid/node.rs | |
parent | 460565056e6787d5cc7cb0d1d49c9e8ff1f77850 (diff) | |
download | iced-5c8ec4504b6541cdc588b91a6b2c7100b4a7cc77.tar.gz iced-5c8ec4504b6541cdc588b91a6b2c7100b4a7cc77.tar.bz2 iced-5c8ec4504b6541cdc588b91a6b2c7100b4a7cc77.zip |
Create module boundaries for `pane_grid` logic
Diffstat (limited to 'native/src/widget/pane_grid/node.rs')
-rw-r--r-- | native/src/widget/pane_grid/node.rs | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/native/src/widget/pane_grid/node.rs b/native/src/widget/pane_grid/node.rs new file mode 100644 index 00000000..a9aa7fdc --- /dev/null +++ b/native/src/widget/pane_grid/node.rs @@ -0,0 +1,128 @@ +use crate::{ + pane_grid::{Pane, Split}, + Rectangle, Size, +}; + +use std::collections::HashMap; + +#[derive(Debug, Clone, Hash)] +pub enum Node { + Split { + kind: Split, + ratio: u32, + a: Box<Node>, + b: Box<Node>, + }, + Pane(Pane), +} + +impl Node { + pub fn find(&mut self, pane: &Pane) -> Option<&mut Node> { + match self { + Node::Split { a, b, .. } => { + a.find(pane).or_else(move || b.find(pane)) + } + Node::Pane(p) => { + if p == pane { + Some(self) + } else { + None + } + } + } + } + + pub fn split(&mut self, kind: Split, new_pane: Pane) { + *self = Node::Split { + kind, + ratio: 500_000, + a: Box::new(self.clone()), + b: Box::new(Node::Pane(new_pane)), + }; + } + + pub fn update(&mut self, f: &impl Fn(&mut Node)) { + match self { + Node::Split { a, b, .. } => { + a.update(f); + b.update(f); + } + _ => {} + } + + f(self); + } + + pub 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, + spacing: f32, + size: Size, + ) -> HashMap<Pane, Rectangle> { + let mut regions = HashMap::new(); + + self.compute_regions( + spacing / 2.0, + &Rectangle { + x: 0.0, + y: 0.0, + width: size.width, + height: size.height, + }, + &mut regions, + ); + + regions + } + + pub fn pane(&self) -> Option<Pane> { + match self { + Node::Split { .. } => None, + Node::Pane(pane) => Some(*pane), + } + } + + pub fn first_pane(&self) -> Pane { + match self { + Node::Split { a, .. } => a.first_pane(), + Node::Pane(pane) => *pane, + } + } + + fn compute_regions( + &self, + halved_spacing: f32, + current: &Rectangle, + regions: &mut HashMap<Pane, Rectangle>, + ) { + match self { + Node::Split { kind, ratio, a, b } => { + let ratio = *ratio as f32 / 1_000_000.0; + let (region_a, region_b) = + kind.apply(current, ratio, halved_spacing); + + a.compute_regions(halved_spacing, ®ion_a, regions); + b.compute_regions(halved_spacing, ®ion_b, regions); + } + Node::Pane(pane) => { + let _ = regions.insert(*pane, *current); + } + } + } +} |