chatty_rs/app/ui/
scroll.rs1use 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}