Skip to main content

nf_rated/render/tui/
stateful_list.rs

1use 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}