Skip to main content

promkit_widgets/tree/
tree.rs

1use crate::cursor::Cursor;
2
3use super::node::{Kind, Node};
4
5/// A `Tree` structure that manages a collection of nodes in a hierarchical manner.
6/// It utilizes a cursor to navigate and manipulate the nodes within the tree.
7#[derive(Clone)]
8pub struct Tree {
9    root: Node,
10    cursor: Cursor<Vec<Kind>>,
11}
12
13impl Tree {
14    /// Creates a new `Tree` with a given root node.
15    ///
16    /// # Arguments
17    ///
18    /// * `root` - The root node of the tree.
19    pub fn new(root: Node) -> Self {
20        Self {
21            root: root.clone(),
22            cursor: Cursor::new(root.flatten_visibles(), 0, false),
23        }
24    }
25
26    /// Returns a vector of all nodes in the tree, represented with their depth information.
27    pub fn kinds(&self) -> Vec<Kind> {
28        self.cursor.contents().clone()
29    }
30
31    /// Returns the current position of the cursor within the tree.
32    pub fn position(&self) -> usize {
33        self.cursor.position()
34    }
35
36    /// Retrieves the data of the current node pointed by the cursor, along with its path from the root.
37    pub fn get(&self) -> Vec<String> {
38        let kind = self.cursor.contents()[self.position()].clone();
39        match kind {
40            Kind::Folded { id, path } | Kind::Unfolded { id, path } => {
41                let mut ret = self.root.get_waypoints(&path);
42                ret.push(id.to_string());
43                ret
44            }
45        }
46    }
47
48    /// Toggles the state of the current node and updates the cursor position accordingly.
49    pub fn toggle(&mut self) {
50        let path = match self.cursor.contents()[self.position()].clone() {
51            Kind::Folded { path, .. } => path,
52            Kind::Unfolded { path, .. } => path,
53        };
54        self.root.toggle(&path);
55        self.cursor = Cursor::new(self.root.flatten_visibles(), self.position(), false);
56    }
57
58    /// Moves the cursor backward in the tree, if possible.
59    ///
60    /// Returns `true` if the cursor was successfully moved backward, `false` otherwise.
61    pub fn backward(&mut self) -> bool {
62        self.cursor.backward()
63    }
64
65    /// Moves the cursor forward in the tree, if possible.
66    ///
67    /// Returns `true` if the cursor was successfully moved forward, `false` otherwise.
68    pub fn forward(&mut self) -> bool {
69        self.cursor.forward()
70    }
71
72    /// Moves the cursor to the head of the tree.
73    pub fn move_to_head(&mut self) {
74        self.cursor.move_to_head()
75    }
76
77    /// Moves the cursor to the tail of the tree.
78    pub fn move_to_tail(&mut self) {
79        self.cursor.move_to_tail()
80    }
81}