nf_rated/render/tui/
stateful_list.rs1use tui::widgets::ListState;
2
3pub struct StatefulList<T> {
4 pub state: ListState,
5 pub items: Vec<T>,
6}
7
8impl<T> StatefulList<T> {
9 pub fn new() -> StatefulList<T> {
10 StatefulList {
11 state: ListState::default(),
12 items: Vec::new(),
13 }
14 }
15
16 pub fn with_items(items: Vec<T>) -> StatefulList<T> {
17 StatefulList {
18 state: ListState::default(),
19 items,
20 }
21 }
22
23 pub fn advance_by(&mut self, delta: i32) {
24 let nitems = self.items.len() as i32;
25 let i = match self.state.selected() {
26 Some(i) => {
27 if (i as i32) >= nitems - delta {
28 0
29 } else {
30 i as i32 + delta
31 }
32 }
33 None => 0,
34 };
35 let clamped = if i < 0 {
36 (nitems + i).max(0)
37 } else {
38 if i > nitems {
39 nitems - i
40 } else {
41 i
42 }
43 };
44 self.state.select(Some(clamped as usize));
45 }
46
47 pub fn next(&mut self) {
48 self.advance_by(1)
49 }
50
51 pub fn next_page(&mut self, height: i32) {
52 self.advance_by(height)
53 }
54
55 pub fn previous(&mut self) {
56 self.advance_by(-1)
57 }
58
59 pub fn previous_page(&mut self, height: i32) {
60 self.advance_by(-height)
61 }
62
63 pub fn unselect(&mut self) {
64 self.state.select(None);
65 }
66}