use ratatui::layout::Rect;
use crate::widgets::markdown_widget::state::scroll_state::ScrollState;
pub fn click_to_offset(click_y: u16, area: Rect, scroll: &ScrollState) -> usize {
let track_height = area.height;
if track_height == 0 {
return 0;
}
let relative_y = click_y.saturating_sub(area.y);
let ratio = relative_y as f64 / track_height as f64;
let max_scroll = scroll.total_lines.saturating_sub(scroll.viewport_height);
(ratio * max_scroll as f64).round() as usize
}
pub fn is_in_scrollbar_area(x: u16, y: u16, area: Rect) -> bool {
x >= area.x && x < area.x + area.width && y >= area.y && y < area.y + area.height
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_click_at_top() {
let area = Rect::new(0, 0, 1, 20);
let scroll = ScrollState {
scroll_offset: 0,
viewport_height: 10,
total_lines: 100,
current_line: 1,
filter: None,
filter_mode: false,
};
let offset = click_to_offset(0, area, &scroll);
assert_eq!(offset, 0);
}
#[test]
fn test_click_at_bottom() {
let area = Rect::new(0, 0, 1, 20);
let scroll = ScrollState {
scroll_offset: 0,
viewport_height: 10,
total_lines: 100,
current_line: 1,
filter: None,
filter_mode: false,
};
let offset = click_to_offset(19, area, &scroll);
assert!(offset >= 80);
}
#[test]
fn test_click_at_middle() {
let area = Rect::new(0, 0, 1, 20);
let scroll = ScrollState {
scroll_offset: 0,
viewport_height: 10,
total_lines: 100,
current_line: 1,
filter: None,
filter_mode: false,
};
let offset = click_to_offset(10, area, &scroll);
assert!(offset >= 40 && offset <= 50);
}
#[test]
fn test_is_in_area() {
let area = Rect::new(10, 5, 2, 15);
assert!(is_in_scrollbar_area(10, 5, area));
assert!(is_in_scrollbar_area(11, 10, area));
assert!(!is_in_scrollbar_area(9, 5, area));
assert!(!is_in_scrollbar_area(12, 5, area));
assert!(!is_in_scrollbar_area(10, 4, area));
assert!(!is_in_scrollbar_area(10, 20, area));
}
}