Skip to main content

cursive_tree/model/
tree.rs

1use super::{super::backend::*, depth::*, iterator::*, kind::*, list::*, node::*, path::*, representation::*};
2
3use {
4    cursive::*,
5    std::{cmp::*, marker::*},
6};
7
8//
9// TreeModel
10//
11
12/// Tree model.
13pub struct TreeModel<BackendT, ContextT, ErrorT, IdT, DataT> {
14    /// Roots.
15    pub roots: NodeList<BackendT, ContextT, ErrorT, IdT, DataT>,
16
17    /// Context.
18    pub context: ContextT,
19
20    backend: PhantomData<BackendT>,
21    error: PhantomData<ErrorT>,
22}
23
24impl<BackendT, ContextT, ErrorT, IdT, DataT> TreeModel<BackendT, ContextT, ErrorT, IdT, DataT> {
25    /// Constructor.
26    pub fn new(context: ContextT) -> Self {
27        Self { roots: Default::default(), context, backend: Default::default(), error: Default::default() }
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, ContextT, ErrorT, IdT, DataT> {
39        self.roots.iter(only_expanded)
40    }
41
42    /// Get node at path.
43    pub fn at_path(&self, path: NodePath) -> Option<&Node<BackendT, ContextT, ErrorT, IdT, DataT>>
44    where
45        BackendT: TreeBackend<ContextT, ErrorT, IdT, DataT>,
46    {
47        self.roots.at_path(path)
48    }
49
50    /// Get node at path.
51    pub fn at_path_mut(&mut self, path: NodePath) -> Option<&mut Node<BackendT, ContextT, ErrorT, IdT, DataT>>
52    where
53        BackendT: TreeBackend<ContextT, ErrorT, IdT, DataT>,
54    {
55        self.roots.at_path_mut(path)
56    }
57
58    /// Get node at row.
59    pub fn at_row(&self, row: usize) -> Option<&Node<BackendT, ContextT, ErrorT, IdT, DataT>>
60    where
61        DataT: 'static,
62    {
63        let mut iterator = self.iter(true);
64        let mut current_row: usize = 0;
65        while let Some(node) = iterator.next() {
66            let next_row = current_row + node.representation_size.y;
67            if (row >= current_row) && (row < next_row) {
68                return Some(node);
69            }
70            current_row = next_row;
71        }
72        None
73    }
74
75    /// Find path to node.
76    pub fn path(&self, node: &Node<BackendT, ContextT, ErrorT, IdT, DataT>) -> Option<NodePath>
77    where
78        BackendT: TreeBackend<ContextT, ErrorT, IdT, DataT>,
79    {
80        let mut path = Default::default();
81        if self.roots.fill_path(&mut path, node) { Some(path) } else { None }
82    }
83
84    /// Size.
85    pub fn size(&self) -> XY<usize>
86    where
87        DataT: 'static,
88    {
89        let mut size = XY::from((0, 0));
90        let mut iterator = self.iter(true);
91        while let Some(node) = iterator.next() {
92            size.x = max(size.x, node.depth * 2 + 2 + node.representation_size.x);
93            size.y += node.representation_size.y;
94        }
95        size
96    }
97
98    /// Add a root node.
99    pub fn add_root(&mut self, kind: NodeKind, id: IdT, representation: Representation)
100    where
101        BackendT: TreeBackend<ContextT, ErrorT, IdT, DataT>,
102    {
103        self.roots.add(0, kind, id, representation);
104    }
105
106    /// Insert a root node.
107    pub fn insert_root(&mut self, index: usize, kind: NodeKind, id: IdT, representation: Representation)
108    where
109        BackendT: TreeBackend<ContextT, ErrorT, IdT, DataT>,
110    {
111        self.roots.insert(index, 0, kind, id, representation);
112    }
113
114    /// Fetch nodes from backend.
115    ///
116    /// If depth is [None] will populate the entire tree.
117    ///
118    /// If depth is 0 will do nothing.
119    pub fn populate(&mut self, mut depth: Option<usize>) -> Result<(), ErrorT>
120    where
121        BackendT: TreeBackend<ContextT, ErrorT, IdT, DataT>,
122        ContextT: Clone,
123    {
124        if depth.is_zero() {
125            return Ok(());
126        }
127
128        self.roots = BackendT::roots(self.context.clone())?;
129
130        depth.decrease();
131        if !depth.is_zero() {
132            for node in &mut self.roots {
133                node.populate(depth, self.context.clone())?;
134            }
135        }
136
137        Ok(())
138    }
139
140    /// Remove all nodes.
141    pub fn clear(&mut self) {
142        self.roots.0.clear();
143    }
144}