Skip to main content

chatty_rs/app/ui/
scroll.rs

1use ratatui::widgets::ScrollbarState;
2
3#[derive(Debug, Default)]
4pub struct Scroll {
5    list_len: usize,
6    viewport_len: usize,
7    pub position: usize,
8    pub scrollbar_state: ScrollbarState,
9}
10
11impl Scroll {
12    pub fn up(&mut self) {
13        self.position = self.position.saturating_sub(1);
14        self.scrollbar_state.prev();
15    }
16
17    pub fn page_up(&mut self) {
18        [..10].iter().for_each(|_| self.up());
19    }
20
21    pub fn down(&mut self) {
22        let mut clamp = 0_usize;
23        if self.list_len > self.viewport_len {
24            clamp = self.list_len - self.viewport_len + 1;
25        }
26
27        self.position = self
28            .position
29            .saturating_add(1)
30            .clamp(0, clamp.saturating_sub(1));
31        self.scrollbar_state.next();
32    }
33
34    pub fn page_down(&mut self) {
35        [..10].iter().for_each(|_| self.down());
36    }
37
38    fn get_position_as_if_last(&self) -> usize {
39        let mut pos = 0;
40        if self.list_len > self.viewport_len {
41            pos = self.list_len - self.viewport_len;
42        }
43        pos
44    }
45
46    pub fn is_position_at_last(&self) -> bool {
47        self.position == self.get_position_as_if_last()
48    }
49
50    pub fn last(&mut self) {
51        self.position = self.get_position_as_if_last();
52        self.scrollbar_state.last();
53    }
54
55    pub fn set_state(&mut self, list_len: usize, viewport_len: usize) {
56        self.list_len = list_len;
57        self.viewport_len = viewport_len;
58        let mut content_len = list_len.saturating_sub(viewport_len);
59        if content_len == 0 {
60            content_len = 1;
61        }
62        self.scrollbar_state = self.scrollbar_state.content_length(content_len);
63    }
64}