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> TreeView<BackendT>
9where
10    BackendT: TreeBackend,
11{
12    /// The selected row.
13    pub fn selected_row(&self) -> Option<usize> {
14        self.selected_row
15    }
16
17    /// The selected node.
18    pub fn selected_node(&self) -> Option<&Node<BackendT>> {
19        self.selected_row.and_then(|selected_row| self.model.at_row(selected_row))
20    }
21
22    /// The selected path.
23    pub fn selected_path(&self) -> Option<NodePath> {
24        self.selected_node().and_then(|node| self.model.path(node))
25    }
26
27    /// The selected node.
28    pub fn selected_node_mut(&mut self) -> Option<&mut Node<BackendT>> {
29        self.selected_path().and_then(|path| self.model.at_path_mut(path))
30    }
31
32    /// Whether the row is selected.
33    pub fn is_selected(&self, row: usize) -> bool {
34        self.selected_row.map(|selected_row| selected_row == row).unwrap_or_default()
35    }
36
37    /// Set selected row.
38    ///
39    /// If the row is invalid will set the selection to [None].
40    pub fn select_row(&mut self, row: usize) {
41        if self.model.is_empty() {
42            self.selected_row = None;
43            return;
44        }
45
46        self.selected_row = if row < self.model.extents().y { Some(row) } else { None };
47    }
48
49    /// Select top row.
50    pub fn select_top(&mut self) {
51        if self.model.is_empty() {
52            self.selected_row = None;
53            return;
54        }
55
56        let height = self.model.extents().y;
57
58        if height == 0 {
59            self.selected_row = None;
60            return;
61        }
62
63        self.selected_row = Some(0);
64    }
65
66    /// Select bottom row.
67    pub fn select_bottom(&mut self) {
68        if self.model.is_empty() {
69            self.selected_row = None;
70            return;
71        }
72
73        let height = self.model.extents().y;
74
75        if height == 0 {
76            self.selected_row = None;
77            return;
78        }
79
80        self.selected_row = Some(height - 1);
81    }
82
83    /// Move selection by delta rows.
84    pub fn move_selection(&mut self, delta: isize) {
85        if delta == 0 {
86            return;
87        }
88
89        if self.model.is_empty() {
90            self.selected_row = None;
91            return;
92        }
93
94        let height = self.model.extents().y;
95
96        if height == 0 {
97            self.selected_row = None;
98            return;
99        }
100
101        if height == 1 {
102            self.selected_row = Some(0);
103            return;
104        }
105
106        match self.selected_row {
107            Some(selected_row) => {
108                if delta > 0 {
109                    let delta = delta as usize;
110                    self.selected_row = Some(min(selected_row + delta, height - 1));
111                } else {
112                    let delta = -delta as usize;
113                    if selected_row > delta {
114                        self.selected_row = Some(selected_row - delta);
115                    } else {
116                        self.selected_row = Some(0);
117                    }
118                }
119            }
120
121            None => self.selected_row = Some(0),
122        }
123    }
124}