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