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}