Skip to main content

uzor_core/widgets/dropdown/
input.rs

1//! Dropdown input adapter - Contract/Connector for dropdown event handling
2
3use crate::types::Rect;
4
5/// Input handler adapter for dropdown events
6pub trait DropdownInputHandler {
7    fn hit_test_dropdown(&self, dropdown_rect: &Rect, mouse_pos: (f64, f64)) -> bool {
8        let (mouse_x, mouse_y) = mouse_pos;
9        mouse_x >= dropdown_rect.x
10            && mouse_x <= dropdown_rect.x + dropdown_rect.width
11            && mouse_y >= dropdown_rect.y
12            && mouse_y <= dropdown_rect.y + dropdown_rect.height
13    }
14
15    fn hit_test_item(&self, item_rect: &Rect, mouse_pos: (f64, f64)) -> bool {
16        let (mouse_x, mouse_y) = mouse_pos;
17        mouse_x >= item_rect.x
18            && mouse_x <= item_rect.x + item_rect.width
19            && mouse_y >= item_rect.y
20            && mouse_y <= item_rect.y + item_rect.height
21    }
22
23    fn mouse_to_item_index(
24        &self,
25        mouse_y: f64,
26        popup_y: f64,
27        item_height: f64,
28        item_count: usize,
29    ) -> Option<usize> {
30        if item_height <= 0.0 || item_count == 0 {
31            return None;
32        }
33
34        let relative_y = mouse_y - popup_y;
35        if relative_y < 0.0 {
36            return None;
37        }
38
39        let index = (relative_y / item_height) as usize;
40        if index < item_count {
41            Some(index)
42        } else {
43            None
44        }
45    }
46
47    fn is_close_click(&self, mouse_pos: (f64, f64), popup_rect: &Rect) -> bool {
48        let (mouse_x, mouse_y) = mouse_pos;
49        !(mouse_x >= popup_rect.x
50            && mouse_x <= popup_rect.x + popup_rect.width
51            && mouse_y >= popup_rect.y
52            && mouse_y <= popup_rect.y + popup_rect.height)
53    }
54
55    fn mouse_to_grid_item_index(
56        &self,
57        mouse_pos: (f64, f64),
58        popup_rect: &Rect,
59        item_size: f64,
60        columns: usize,
61        item_count: usize,
62    ) -> Option<usize> {
63        if item_size <= 0.0 || columns == 0 || item_count == 0 {
64            return None;
65        }
66
67        let (mouse_x, mouse_y) = mouse_pos;
68        let relative_x = mouse_x - popup_rect.x;
69        let relative_y = mouse_y - popup_rect.y;
70
71        if relative_x < 0.0 || relative_y < 0.0 {
72            return None;
73        }
74
75        let col = (relative_x / item_size) as usize;
76        let row = (relative_y / item_size) as usize;
77
78        if col >= columns {
79            return None;
80        }
81
82        let index = row * columns + col;
83        if index < item_count {
84            Some(index)
85        } else {
86            None
87        }
88    }
89}
90
91/// Default implementation of DropdownInputHandler
92#[derive(Clone, Copy, Debug, Default)]
93pub struct DefaultDropdownInputHandler;
94
95impl DropdownInputHandler for DefaultDropdownInputHandler {}