agg_gui/widget/app/
pointer.rs1use super::tree_paths::widget_at_path;
6use crate::event::{Event, Modifiers, MouseButton};
7use crate::geometry::Point;
8use crate::widget::tree::{active_modal_path, dispatch_event, hit_test_subtree};
9use crate::widget::tree_inspector::set_current_mouse_world;
10use crate::widget::{App, Widget};
11
12impl App {
13 pub(crate) fn extend_modal_path(&self, modal_path: &[usize], pos_in_root: Point) -> Vec<usize> {
18 let mut widget: &dyn Widget = self.root.as_ref();
19 let mut pos = pos_in_root;
20 for &index in modal_path {
21 let Some(child) = widget.children().get(index) else {
22 return modal_path.to_vec();
23 };
24 let bounds = child.bounds();
25 if let Some(t) = widget.child_transform() {
26 t.inverse_transform(&mut pos.x, &mut pos.y);
27 }
28 pos = Point::new(pos.x - bounds.x, pos.y - bounds.y);
29 widget = child.as_ref();
30 }
31 let mut full = modal_path.to_vec();
32 if let Some(sub_path) = hit_test_subtree(widget, pos) {
33 full.extend(sub_path);
34 }
35 full
36 }
37
38 pub fn on_mouse_move(&mut self, screen_x: f64, screen_y: f64) {
40 crate::cursor::reset_cursor_icon();
42 let screen = self.flip_y(screen_x, screen_y);
43 if crate::widgets::on_screen_keyboard::handle_software_keyboard_mouse_move(screen) {
44 self.drain_keyboard_synthetic_keys();
45 return;
46 }
47 let pos = super::keyboard_scroll::lift_to_world(screen);
48 set_current_mouse_world(pos);
49 if let Some(path) = active_modal_path(self.root.as_ref()) {
50 let path = self.extend_modal_path(&path, pos);
51 let event = Event::MouseMove { pos };
52 dispatch_event(&mut self.root, &path, &event, pos);
53 self.hovered = Some(path);
54 return;
55 }
56 self.dispatch_mouse_move(pos);
57 }
58
59 pub fn on_mouse_down(
61 &mut self,
62 screen_x: f64,
63 screen_y: f64,
64 button: MouseButton,
65 mods: Modifiers,
66 ) {
67 let screen = self.flip_y(screen_x, screen_y);
68 if crate::widgets::on_screen_keyboard::handle_software_keyboard_mouse_down(
73 screen, button, mods,
74 ) {
75 return;
76 }
77 let pos = super::keyboard_scroll::lift_to_world(screen);
78 set_current_mouse_world(pos);
79 crate::widgets::tooltip::controller::on_pointer_down();
82 crate::animation::bump_pointer_press_epoch();
86 let modal_path = active_modal_path(self.root.as_ref());
87 let event = Event::MouseDown {
88 pos,
89 button,
90 modifiers: mods,
91 };
92 if let Some(path) = modal_path {
93 let path = self.extend_modal_path(&path, pos);
97 if widget_at_path(&mut self.root, &path).is_focusable() {
98 self.set_focus(Some(path.clone()));
99 } else {
100 self.set_focus(None);
101 }
102 if dispatch_event(&mut self.root, &path, &event, pos).is_consumed() {
103 self.captured = Some(path);
104 }
105 return;
106 }
107 let hit = self.compute_hit(pos);
108
109 if let Some(ref path) = hit {
111 let w = widget_at_path(&mut self.root, path);
112 if w.is_focusable() {
113 self.set_focus(Some(path.clone()));
114 } else {
115 self.set_focus(None);
116 }
117 } else {
118 self.set_focus(None);
119 }
120
121 if let Some(mut path) = hit {
122 let result = dispatch_event(&mut self.root, &path, &event, pos);
123 if result.is_consumed() {
124 self.maybe_bring_to_front(&mut path);
125 let capture_path = self.compute_hit(pos).unwrap_or(path);
126 self.captured = Some(capture_path);
127 }
128 }
129 }
135
136 pub fn on_mouse_up(
138 &mut self,
139 screen_x: f64,
140 screen_y: f64,
141 button: MouseButton,
142 mods: Modifiers,
143 ) {
144 let screen = self.flip_y(screen_x, screen_y);
145 if crate::widgets::on_screen_keyboard::handle_software_keyboard_mouse_up(
150 screen, button, mods,
151 ) {
152 self.captured = None;
153 self.drain_keyboard_synthetic_keys();
154 return;
155 }
156 let pos = super::keyboard_scroll::lift_to_world(screen);
157 set_current_mouse_world(pos);
158 crate::widgets::tooltip::controller::on_pointer_up();
159 let event = Event::MouseUp {
160 pos,
161 button,
162 modifiers: mods,
163 };
164 if let Some(path) = active_modal_path(self.root.as_ref()) {
165 let path = self
168 .captured
169 .take()
170 .unwrap_or_else(|| self.extend_modal_path(&path, pos));
171 dispatch_event(&mut self.root, &path, &event, pos);
172 return;
173 }
174 if let Some(path) = self.captured.take() {
176 dispatch_event(&mut self.root, &path, &event, pos);
177 } else {
178 let hit = self.compute_hit(pos);
179 if let Some(path) = hit {
180 dispatch_event(&mut self.root, &path, &event, pos);
181 }
182 }
183 }
184}