gravel_frontend_fltk/
scroll.rs

1use std::cmp;
2
3/// Handles scrolling logic.
4///
5/// The view is always an integer offset from the top, thus
6/// never displaying a partial item.
7pub struct Scroll {
8	length: i32,
9	max_view_size: i32,
10	cursor: i32,
11	scroll: i32,
12}
13
14impl Scroll {
15	/// Creates a new instance.
16	/// - `length`: number of items in the list
17	/// - `max_view_size`: number of items that can be displayed at once
18	pub fn new(length: i32, max_view_size: i32) -> Self {
19		Self {
20			length,
21			max_view_size,
22			cursor: 0,
23			scroll: 0,
24		}
25	}
26
27	/// Move the cursor up by one item.
28	pub fn cursor_up(&mut self) {
29		if self.cursor <= 0 {
30			self.bottom();
31		} else {
32			self.cursor -= 1;
33			self.scroll = cmp::min(self.scroll, self.cursor);
34		}
35	}
36
37	/// Move the cursor down by one item.
38	pub fn cursor_down(&mut self) {
39		if self.cursor >= self.length - 1 {
40			self.top();
41		} else {
42			self.cursor += 1;
43			self.scroll = cmp::max(self.scroll, self.cursor - self.view_size() + 1);
44		}
45	}
46
47	/// Move the view up one page.
48	pub fn page_up(&mut self) {
49		if self.scroll - self.view_size() <= 0 {
50			self.top();
51		} else {
52			self.scroll = self.scroll() - self.view_size();
53			self.cursor = self.scroll;
54		}
55	}
56
57	/// Move the view down one page.
58	pub fn page_down(&mut self) {
59		if self.scroll + self.view_size() * 2 >= self.length {
60			self.bottom();
61		} else {
62			self.scroll = self.scroll() + self.view_size();
63			self.cursor = self.scroll + self.view_size() - 1;
64		}
65	}
66
67	/// Move the view and cursor to the top.
68	pub fn top(&mut self) {
69		self.cursor = 0;
70		self.scroll = 0;
71	}
72
73	/// Move the view and cursor to the bottom.
74	pub fn bottom(&mut self) {
75		self.cursor = self.length - 1;
76		self.scroll = self.length - self.view_size();
77	}
78
79	/// Set the number of items in the list.
80	pub fn set_length(&mut self, length: i32) {
81		self.length = length;
82		self.top();
83	}
84
85	/// Gets the number of items that fit inside the view.
86	pub fn view_size(&self) -> i32 {
87		cmp::min(self.length, self.max_view_size)
88	}
89
90	/// Gets the cursor position.
91	pub fn cursor(&self) -> i32 {
92		self.cursor
93	}
94
95	/// Gets the views offset from the top of the list.
96	pub fn scroll(&self) -> i32 {
97		self.scroll
98	}
99
100	/// Gets the length of the list.
101	pub fn length(&self) -> i32 {
102		self.length
103	}
104}