Skip to main content

cursive_tree/model/
tree.rs

1use super::{super::backend::*, depth::*, iterator::*, kind::*, list::*, node::*, path::*, representation::*};
2
3use {cursive::*, std::cmp::*};
4
5//
6// TreeModel
7//
8
9/// Tree model.
10pub struct TreeModel<BackendT>
11where
12    BackendT: TreeBackend,
13{
14    /// Roots.
15    pub roots: NodeList<BackendT>,
16
17    /// Context.
18    pub context: BackendT::Context,
19}
20
21impl<BackendT> TreeModel<BackendT>
22where
23    BackendT: TreeBackend,
24{
25    /// Constructor.
26    pub fn new(context: BackendT::Context) -> Self {
27        Self { roots: Default::default(), context }
28    }
29
30    /// Whether we have no nodes.
31    pub fn is_empty(&self) -> bool {
32        self.roots.0.is_empty()
33    }
34
35    /// Iterate nodes in visual order from top to bottom.
36    ///
37    /// When only_expanded is true will skip the children of collapsed branches.
38    pub fn iter(&self, only_expanded: bool) -> NodeIterator<'_, BackendT> {
39        self.roots.iter(only_expanded)
40    }
41
42    /// Get node at path.
43    pub fn at_path(&self, path: NodePath) -> Option<&Node<BackendT>> {
44        self.roots.at_path(path)
45    }
46
47    /// Get node at path.
48    pub fn at_path_mut(&mut self, path: NodePath) -> Option<&mut Node<BackendT>> {
49        self.roots.at_path_mut(path)
50    }
51
52    /// Get node at row.
53    pub fn at_row(&self, row: usize) -> Option<&Node<BackendT>> {
54        let mut iterator = self.iter(true);
55        let mut current_row: usize = 0;
56        while let Some(node) = iterator.next() {
57            let next_row = current_row + node.representation_size.y;
58            if (row >= current_row) && (row < next_row) {
59                return Some(node);
60            }
61            current_row = next_row;
62        }
63        None
64    }
65
66    /// Find path to node.
67    pub fn path(&self, node: &Node<BackendT>) -> Option<NodePath> {
68        let mut path = Default::default();
69        if self.roots.fill_path(&mut path, node) { Some(path) } else { None }
70    }
71
72    /// Size.
73    pub fn size(&self) -> Vec2 {
74        let mut size = XY::from((0, 0));
75        let mut iterator = self.iter(true);
76        while let Some(node) = iterator.next() {
77            size.x = max(size.x, node.depth * 2 + 2 + node.representation_size.x);
78            size.y += node.representation_size.y;
79        }
80        size
81    }
82
83    /// Add a root node.
84    pub fn add_root(&mut self, kind: NodeKind, id: BackendT::ID, representation: Representation) {
85        self.roots.add(0, kind, id, representation);
86    }
87
88    /// Insert a root node.
89    pub fn insert_root(&mut self, index: usize, kind: NodeKind, id: BackendT::ID, representation: Representation) {
90        self.roots.insert(index, 0, kind, id, representation);
91    }
92
93    /// Fetch nodes from backend.
94    ///
95    /// If depth is [None] will populate the entire tree.
96    ///
97    /// If depth is 0 will do nothing.
98    pub fn populate(&mut self, mut depth: Option<usize>) -> Result<(), BackendT::Error>
99    where
100        BackendT::Context: Clone,
101    {
102        if depth.is_zero() {
103            return Ok(());
104        }
105
106        self.roots = BackendT::roots(self.context.clone())?;
107
108        depth.decrease();
109        if !depth.is_zero() {
110            for node in &mut self.roots {
111                node.populate(depth, self.context.clone())?;
112            }
113        }
114
115        Ok(())
116    }
117
118    /// Remove all nodes.
119    pub fn clear(&mut self) {
120        self.roots.0.clear();
121    }
122}