Skip to main content

cursive_tree/view/
selection.rs

1use super::{
2    super::{backend::*, model::*},
3    tree::*,
4};
5
6use std::cmp::*;
7
8impl<BackendT, ContextT, ErrorT, IdT, DataT> TreeView<BackendT, ContextT, ErrorT, IdT, DataT>
9where
10    BackendT: 'static + TreeBackend<ContextT, ErrorT, IdT, DataT> + Send + Sync,
11    DataT: 'static + Send + Sync,
12{
13    /// The selected node.
14    pub fn selected_node(&self) -> Option<&Node<BackendT, ContextT, ErrorT, IdT, DataT>> {
15        self.selected_row.and_then(|selected_row| self.model.at_row(selected_row))
16    }
17
18    /// The selected path.
19    pub fn selected_path(&self) -> Option<NodePath> {
20        self.selected_node().and_then(|node| self.model.path(node))
21    }
22
23    /// The selected node.
24    pub fn selected_node_mut(&mut self) -> Option<&mut Node<BackendT, ContextT, ErrorT, IdT, DataT>> {
25        self.selected_path().and_then(|path| self.model.at_path_mut(path))
26    }
27
28    /// Whether the row is selected.
29    pub fn is_selected(&self, row: usize) -> bool {
30        // TODO: nodes can have heights > 1
31        self.selected_row.map(|selected_row| selected_row == row).unwrap_or_default()
32    }
33
34    /// Select top row.
35    pub fn select_top(&mut self) {
36        if self.model.is_empty() {
37            self.selected_row = None;
38            return;
39        }
40
41        let height = self.model.size().y;
42
43        if height == 0 {
44            self.selected_row = None;
45            return;
46        }
47
48        self.selected_row = Some(0);
49    }
50
51    /// Select bottom row.
52    pub fn select_bottom(&mut self) {
53        if self.model.is_empty() {
54            self.selected_row = None;
55            return;
56        }
57
58        let height = self.model.size().y;
59
60        if height == 0 {
61            self.selected_row = None;
62            return;
63        }
64
65        self.selected_row = Some(height - 1);
66    }
67
68    /// Move selection by delta rows.
69    pub fn move_selection(&mut self, delta: isize) {
70        if delta == 0 {
71            return;
72        }
73
74        if self.model.is_empty() {
75            self.selected_row = None;
76            return;
77        }
78
79        let height = self.model.size().y;
80
81        if height == 0 {
82            self.selected_row = None;
83            return;
84        }
85
86        if height == 1 {
87            self.selected_row = Some(0);
88            return;
89        }
90
91        match self.selected_row {
92            Some(selected_row) => {
93                if delta > 0 {
94                    let delta = delta as usize;
95                    self.selected_row = Some(min(selected_row + delta, height - 1));
96                } else {
97                    let delta = -delta as usize;
98                    if selected_row > delta {
99                        self.selected_row = Some(selected_row - delta);
100                    } else {
101                        self.selected_row = Some(0);
102                    }
103                }
104            }
105
106            None => self.selected_row = Some(0),
107        }
108    }
109}