ratatui_kit/components/scroll_view/
state.rs1use crossterm::event::{Event, KeyCode, KeyEventKind, MouseEventKind};
2use ratatui::layout::{Position, Size};
3
4#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Hash)]
5pub struct ScrollViewState {
6 pub(crate) offset: Position,
8 pub(crate) size: Option<Size>,
10 pub(crate) page_size: Option<Size>,
12}
13
14impl ScrollViewState {
15 pub fn new() -> Self {
17 Self::default()
18 }
19
20 pub fn with_offset(offset: Position) -> Self {
22 Self {
23 offset,
24 ..Default::default()
25 }
26 }
27
28 pub const fn set_offset(&mut self, offset: Position) {
30 self.offset = offset;
31 }
32
33 pub const fn offset(&self) -> Position {
35 self.offset
36 }
37
38 pub const fn scroll_up(&mut self) {
40 self.offset.y = self.offset.y.saturating_sub(1);
41 }
42
43 pub const fn scroll_down(&mut self) {
45 self.offset.y = self.offset.y.saturating_add(1);
46 }
47
48 pub fn scroll_page_down(&mut self) {
50 let page_size = self.page_size.map_or(1, |size| size.height);
51 self.offset.y = self.offset.y.saturating_add(page_size).saturating_sub(1);
53 }
54
55 pub fn scroll_page_up(&mut self) {
57 let page_size = self.page_size.map_or(1, |size| size.height);
58 self.offset.y = self.offset.y.saturating_add(1).saturating_sub(page_size);
60 }
61
62 pub const fn scroll_left(&mut self) {
64 self.offset.x = self.offset.x.saturating_sub(1);
65 }
66
67 pub const fn scroll_right(&mut self) {
69 self.offset.x = self.offset.x.saturating_add(1);
70 }
71
72 pub const fn scroll_to_top(&mut self) {
74 self.offset = Position::ORIGIN;
75 }
76
77 pub fn scroll_to_bottom(&mut self) {
79 let bottom = self
81 .size
82 .map_or(u16::MAX, |size| size.height.saturating_sub(1));
83 self.offset.y = bottom;
84 }
85
86 pub fn handle_event(&mut self, event: &Event) {
87 match event {
88 Event::Key(key) if key.kind == KeyEventKind::Press => match key.code {
89 KeyCode::Up | KeyCode::Char('k') => {
90 self.scroll_up();
91 }
92 KeyCode::Down | KeyCode::Char('j') => {
93 self.scroll_down();
94 }
95 KeyCode::Left | KeyCode::Char('h') => {
96 self.scroll_left();
97 }
98 KeyCode::Right | KeyCode::Char('l') => {
99 self.scroll_right();
100 }
101 KeyCode::PageUp => {
102 self.scroll_page_up();
103 }
104 KeyCode::PageDown => {
105 self.scroll_page_down();
106 }
107 KeyCode::Home => {
108 self.scroll_to_top();
109 }
110 KeyCode::End => {
111 self.scroll_to_bottom();
112 }
113 _ => {}
114 },
115 Event::Mouse(event) => match event.kind {
116 MouseEventKind::ScrollDown => {
117 self.scroll_down();
118 }
119 MouseEventKind::ScrollUp => {
120 self.scroll_up();
121 }
122 MouseEventKind::ScrollLeft => {
123 self.scroll_left();
124 }
125 MouseEventKind::ScrollRight => {
126 self.scroll_right();
127 }
128 _ => {}
129 },
130 _ => {}
131 }
132 }
133}