Skip to main content

cursive_tree/view/
tree.rs

1use super::{
2    super::{backend::*, model::*},
3    actions::*,
4};
5
6use {cursive::*, event::*};
7
8//
9// TreeView
10//
11
12/// Tree view.
13///
14/// Nodes can be leaves (no children) or branches (potentially have children) and can have custom
15/// data (`DataT`) attached to them. Their labels can be stylized with multiple colors and effects.
16///
17/// Event handling (configurable):
18///
19/// * Up/Down keys: move selection
20/// * PgUp/PgDown keys: move selection by 10 (configurable)
21/// * Left/Right keys: collapse/expand selected branch node
22/// * Enter key: toggle selected branch node collapse/expand
23/// * "-"/"+" keys: collapse/expand selected branch and all children recursively
24/// * "<"/">" keys: collapse/expand all nodes
25/// * Mouse click on node: select
26/// * Mouse click to the left of the node: toggle branch collapse/expand
27///
28/// The view's data and behavior are backed by a [TreeBackend]. The nodes are stored and managed by
29/// a [TreeModel]. The model can be populated in advance and can also fetch data from the backend
30/// on demand, e.g. when a branch node is expanded.
31pub struct TreeView<BackendT>
32where
33    BackendT: TreeBackend,
34{
35    /// Tree model.
36    pub model: TreeModel<BackendT>,
37
38    pub(crate) selected_row: Option<usize>,
39    pub(crate) page: usize,
40    pub(crate) debug: bool,
41    pub(crate) actions: Actions,
42}
43
44impl<BackendT> TreeView<BackendT>
45where
46    BackendT: TreeBackend,
47{
48    /// Page size for
49    /// [SelectUpPage](Action::SelectUpPage)/[SelectDownPage](Action::SelectDownPage).
50    pub fn page(&self) -> usize {
51        self.page
52    }
53
54    /// Set page size for
55    /// [SelectUpPage](Action::SelectUpPage)/[SelectDownPage](Action::SelectDownPage).
56    pub fn set_page(&mut self, page: usize) {
57        self.page = page;
58    }
59
60    /// Set page size for
61    /// [SelectUpPage](Action::SelectUpPage)/[SelectDownPage](Action::SelectDownPage).
62    ///
63    /// Chainable.
64    pub fn with_page(self, page: usize) -> Self {
65        self.with(|self_| self_.set_page(page))
66    }
67
68    /// Debug mode.
69    pub fn debug(&self) -> bool {
70        self.debug
71    }
72
73    /// Set debug mode.
74    pub fn set_debug(&mut self, debug: bool) {
75        self.debug = debug;
76    }
77
78    /// Set debug mode.
79    ///
80    /// Chainable.
81    pub fn with_debug(self, debug: bool) -> Self {
82        self.with(|self_| self_.set_debug(debug))
83    }
84
85    /// Action map.
86    pub fn actions(&self) -> &Actions {
87        &self.actions
88    }
89
90    /// Action map.
91    pub fn actions_mut(&mut self) -> &mut Actions {
92        &mut self.actions
93    }
94
95    /// Set action map.
96    pub fn set_actions(&mut self, actions: Actions) {
97        self.actions = actions;
98    }
99
100    /// Set action map.
101    ///
102    /// Chainable.
103    pub fn with_actions(self, actions: Actions) -> Self {
104        self.with(|self_| self_.set_actions(actions))
105    }
106
107    /// Set action.
108    ///
109    /// Note that actions can be associated with more than one event.
110    pub fn set_action<EventT>(&mut self, action: Action, event: EventT)
111    where
112        EventT: Into<Event>,
113    {
114        self.actions.insert(event.into(), action);
115    }
116
117    /// Set action.
118    ///
119    /// Note that actions can be associated with more than one event.
120    ///
121    /// Chainable.
122    pub fn with_action<EventT>(self, action: Action, event: EventT) -> Self
123    where
124        EventT: Into<Event>,
125    {
126        self.with(|self_| self_.set_action(action, event))
127    }
128
129    /// Remove action.
130    ///
131    /// Will remove all associated events.
132    ///
133    /// Return true if removed.
134    pub fn remove_action(&mut self, action: Action) -> bool {
135        action.remove(&mut self.actions)
136    }
137
138    /// Remove action.
139    ///
140    /// Will remove all associated events.
141    ///
142    /// Chainable.
143    pub fn without_action(self, action: Action) -> Self {
144        self.with(|self_| _ = self_.remove_action(action))
145    }
146}
147
148impl<BackendT> From<TreeModel<BackendT>> for TreeView<BackendT>
149where
150    BackendT: TreeBackend,
151{
152    fn from(model: TreeModel<BackendT>) -> Self {
153        Self { model, selected_row: None, page: 10, debug: false, actions: Action::defaults() }
154    }
155}