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