sql_cli/ui/utils/
scroll_utils.rs1pub fn calculate_horizontal_scroll(cursor_pos: usize, terminal_width: u16) -> u16 {
4 let inner_width = terminal_width.saturating_sub(3) as usize; if cursor_pos >= inner_width {
7 (cursor_pos + 1).saturating_sub(inner_width) as u16
9 } else {
10 0
11 }
12}
13
14pub fn update_scroll_offset(cursor_pos: usize, current_offset: u16, visible_width: usize) -> u16 {
16 if cursor_pos < current_offset as usize {
18 cursor_pos as u16
19 }
20 else if cursor_pos >= current_offset as usize + visible_width {
22 (cursor_pos + 1).saturating_sub(visible_width) as u16
23 }
24 else {
26 current_offset
27 }
28}
29
30pub fn calculate_visible_range(
32 total_items: usize,
33 viewport_start: usize,
34 viewport_size: usize,
35) -> (usize, usize) {
36 let start = viewport_start.min(total_items);
37 let end = (viewport_start + viewport_size).min(total_items);
38 (start, end)
39}
40
41pub fn calculate_page_jump(
43 current_pos: usize,
44 page_size: usize,
45 total_items: usize,
46 direction_up: bool,
47) -> usize {
48 if direction_up {
49 current_pos.saturating_sub(page_size)
50 } else {
51 (current_pos + page_size).min(total_items.saturating_sub(1))
52 }
53}
54
55pub fn calculate_centered_viewport(
58 target_pos: usize,
59 viewport_size: usize,
60 total_items: usize,
61) -> usize {
62 if total_items <= viewport_size {
63 0
65 } else if target_pos < viewport_size / 2 {
66 0
68 } else if target_pos > total_items.saturating_sub(viewport_size / 2) {
69 total_items.saturating_sub(viewport_size)
71 } else {
72 target_pos.saturating_sub(viewport_size / 2)
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_horizontal_scroll() {
83 assert_eq!(calculate_horizontal_scroll(5, 80), 0);
85
86 assert_eq!(calculate_horizontal_scroll(100, 80), 24); }
89
90 #[test]
91 fn test_update_scroll_offset() {
92 assert_eq!(update_scroll_offset(5, 10, 20), 5);
94
95 assert_eq!(update_scroll_offset(15, 10, 20), 10);
97
98 assert_eq!(update_scroll_offset(35, 10, 20), 16); }
101
102 #[test]
103 fn test_visible_range() {
104 assert_eq!(calculate_visible_range(100, 10, 20), (10, 30));
105 assert_eq!(calculate_visible_range(100, 90, 20), (90, 100));
106 assert_eq!(calculate_visible_range(5, 0, 10), (0, 5));
107 }
108
109 #[test]
110 fn test_page_jump() {
111 assert_eq!(calculate_page_jump(50, 10, 100, true), 40);
113 assert_eq!(calculate_page_jump(5, 10, 100, true), 0);
114
115 assert_eq!(calculate_page_jump(50, 10, 100, false), 60);
117 assert_eq!(calculate_page_jump(95, 10, 100, false), 99);
118 }
119
120 #[test]
121 fn test_centered_viewport() {
122 assert_eq!(calculate_centered_viewport(5, 20, 10), 0);
124
125 assert_eq!(calculate_centered_viewport(5, 20, 100), 0);
127
128 assert_eq!(calculate_centered_viewport(95, 20, 100), 80);
130
131 assert_eq!(calculate_centered_viewport(50, 20, 100), 40);
133 }
134}