use crate::types::Rect;
pub trait PopupInputHandler {
fn hit_test(&self, popup_rect: &Rect, mouse_pos: (f64, f64)) -> bool {
let (mouse_x, mouse_y) = mouse_pos;
mouse_x >= popup_rect.x
&& mouse_x <= popup_rect.x + popup_rect.width
&& mouse_y >= popup_rect.y
&& mouse_y <= popup_rect.y + popup_rect.height
}
fn is_outside_click(&self, mouse_pos: (f64, f64), popup_rect: &Rect) -> bool {
!self.hit_test(popup_rect, mouse_pos)
}
fn mouse_to_item_index(
&self,
mouse_y: f64,
popup_y: f64,
item_height: f64,
item_count: usize,
padding_vertical: f64,
) -> Option<usize> {
let relative_y = mouse_y - popup_y - padding_vertical;
if relative_y < 0.0 {
return None;
}
let index = (relative_y / item_height) as usize;
if index < item_count {
Some(index)
} else {
None
}
}
fn mouse_to_color_index(
&self,
mouse_pos: (f64, f64),
popup_rect: &Rect,
grid_cols: usize,
swatch_size: f64,
grid_spacing: f64,
padding: f64,
) -> Option<usize> {
let (mouse_x, mouse_y) = mouse_pos;
let grid_x = mouse_x - popup_rect.x - padding;
let grid_y = mouse_y - popup_rect.y - padding;
if grid_x < 0.0 || grid_y < 0.0 {
return None;
}
let cell_size = swatch_size + grid_spacing;
let col = (grid_x / cell_size) as usize;
let row = (grid_y / cell_size) as usize;
let local_x = grid_x - (col as f64 * cell_size);
let local_y = grid_y - (row as f64 * cell_size);
if local_x > swatch_size || local_y > swatch_size {
return None; }
if col >= grid_cols {
return None;
}
Some(row * grid_cols + col)
}
fn adjust_position_to_screen(
&self,
pos: (f64, f64),
size: (f64, f64),
screen: (f64, f64),
) -> (f64, f64) {
let (mut x, mut y) = pos;
let (width, height) = size;
let (screen_width, screen_height) = screen;
if x + width > screen_width {
x = (x - width).max(0.0);
}
if x < 0.0 {
x = 0.0;
}
if y + height > screen_height {
y = (y - height).max(0.0);
}
if y < 0.0 {
y = 0.0;
}
(x, y)
}
}
#[derive(Clone, Copy, Debug, Default)]
pub struct DefaultPopupInputHandler;
impl PopupInputHandler for DefaultPopupInputHandler {
}