use ratatui::layout::Rect;
use std::time::{Duration, Instant};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MouseZone {
PickerItem(usize),
ListItem(usize),
}
const DOUBLE_CLICK_WINDOW: Duration = Duration::from_millis(400);
#[derive(Default)]
pub struct MouseMap {
zones: Vec<(Rect, MouseZone)>,
pub picker_area: Option<Rect>,
last_click: Option<(MouseZone, Instant)>,
}
impl MouseMap {
pub fn clear(&mut self) {
self.zones.clear();
self.picker_area = None;
}
pub fn register(&mut self, rect: Rect, zone: MouseZone) {
if rect.width > 0 && rect.height > 0 {
self.zones.push((rect, zone));
}
}
pub fn set_picker_area(&mut self, rect: Rect) {
self.picker_area = Some(rect);
}
pub fn hit_test(&self, x: u16, y: u16) -> Option<MouseZone> {
self.zones
.iter()
.rev()
.find(|(r, _)| x >= r.x && x < r.right() && y >= r.y && y < r.bottom())
.map(|(_, z)| *z)
}
pub fn is_double_click(&mut self, zone: MouseZone) -> bool {
let now = Instant::now();
let double = self
.last_click
.take()
.is_some_and(|(z, t)| z == zone && now.duration_since(t) <= DOUBLE_CLICK_WINDOW);
if !double {
self.last_click = Some((zone, now));
}
double
}
}