tuix_core/events/event_manager.rs
1use crate::{Builder, CursorIcon, Entity, Event, IntoBranchIterator, IntoParentIterator, IntoTreeIterator, PropSet, Propagation, State, Tree, TreeExt, Visibility, WindowEvent, tree};
2
3use crate::EventHandler;
4
5use std::{
6 collections::{hash_map::DefaultHasher, HashMap, VecDeque},
7 convert::TryInto,
8 println,
9};
10
11use std::time::{Duration, Instant};
12
13use femtovg::{
14 renderer::OpenGl, Align, Baseline, Canvas, Color, FillRule, FontId, ImageFlags, ImageId,
15 LineCap, LineJoin, Paint, Path, Renderer, Solidity,
16};
17
18use fnv::FnvHashMap;
19
20pub struct EventManager {
21
22 // Queue of events to be processed
23 pub event_queue: Vec<Event>,
24
25 // A copy of the tree for iteration
26 pub tree: Tree,
27
28 prev_width: f32,
29 prev_height: f32,
30 prev_dpi_factor: f64,
31}
32
33impl EventManager {
34 pub fn new() -> Self {
35 EventManager {
36 event_queue: Vec::new(),
37
38 tree: Tree::new(),
39
40 prev_width: 0.0,
41 prev_height: 0.0,
42 prev_dpi_factor: 1.0,
43 }
44 }
45
46 pub fn flush_events(&mut self, state: &mut State) -> bool {
47 let mut needs_redraw = false;
48
49 if state.tree.changed {
50 self.tree = state.tree.clone();
51 state.tree.changed = false;
52 }
53
54 // Clear the event queue in the event manager
55 self.event_queue.clear();
56
57 // Remove widgets that should be removed
58 // for entity in state.removed_entities.iter() {
59 // self.event_handlers.remove(entity);
60 // }
61
62 //state.removed_entities.clear();
63
64 // Move events from state to event manager
65 self.event_queue.extend(state.event_queue.drain(0..));
66
67 // Sort the events by order
68 self.event_queue.sort_by_cached_key(|event| event.order);
69
70 // Loop over the events in the event queue
71 'events: for event in self.event_queue.iter_mut() {
72 //println!("Event: {:?}", event);
73
74 // Send events to any listeners
75 let listeners = state.listeners.iter().map(|(entity, _)| *entity).collect::<Vec<Entity>>();
76 for entity in listeners {
77 if let Some(listener) = state.listeners.remove(&entity) {
78 if let Some(mut event_handler) = state.event_handlers.remove(&entity) {
79 (listener)(event_handler.as_mut(), state, entity, event);
80
81 state.event_handlers.insert(entity, event_handler);
82 }
83
84
85 state.listeners.insert(entity, listener);
86 }
87
88 if event.consumed {
89 continue 'events;
90 }
91 }
92
93 // Skip events with no target unless they are set to propagate to all entities
94 if event.target == Entity::null() && event.propagation != Propagation::All {
95 continue 'events;
96 }
97
98 if let Some(window_event) = event.message.downcast::<WindowEvent>() {
99 match window_event {
100 WindowEvent::Redraw => {
101 needs_redraw = true;
102 }
103
104 _ => {}
105 }
106 }
107
108 // Define the target to prevent multiple mutable borrows error
109 let target = event.target;
110
111 // A null entity as target means send event to all entities
112 if event.propagation == Propagation::All {
113 for entity in self.tree.into_iter() {
114 if let Some(mut event_handler) = state.event_handlers.remove(&entity) {
115 event_handler.on_event_(state, entity, event);
116
117 state.event_handlers.insert(entity, event_handler);
118
119 if event.consumed {
120 break;
121 }
122 }
123 }
124 continue 'events;
125 }
126
127 // Propagate down from root to target (not including target)
128 if event.propagation == Propagation::Down || event.propagation == Propagation::DownUp {
129 // Construct the list of widgets to walk down by going up from the target
130 let ancestors: Vec<Entity> = event
131 .target
132 .parent_iter(&self.tree)
133 .collect::<Vec<Entity>>();
134
135 // Walk down the list of ancestors
136 for entity in ancestors.iter().rev() {
137 // Skip the window
138 if *entity == Entity::root() {
139 continue;
140 }
141
142 // Stop before the target entity
143 if *entity == event.target {
144 break;
145 }
146
147 // Send event to all ancestors before the target
148 if let Some(mut event_handler) = state.event_handlers.remove(&entity) {
149 event_handler.on_event_(state, *entity, event);
150
151 state.event_handlers.insert(*entity, event_handler);
152
153 // Skip to the next event if the current event is consumed
154 if event.consumed {
155 continue 'events;
156 }
157 }
158 }
159 }
160
161 // Direct
162 if event.propagation != Propagation::Fall {
163 // Send event to target
164 if let Some(mut event_handler) = state.event_handlers.remove(&event.target) {
165 event_handler.on_event_(state, event.target, event);
166
167 state.event_handlers.insert(event.target, event_handler);
168 // if let Some(test) = self.callbacks.get_mut(&event.target) {
169 // (test)(event_handler, state, event.target);
170 // }
171
172 if event.consumed {
173 continue 'events;
174 }
175 }
176 }
177
178 // Propagate up from target to root (not including target)
179 if event.propagation == Propagation::Up || event.propagation == Propagation::DownUp {
180 // Walk up the tree from parent to parent
181 for entity in target.parent_iter(&self.tree) {
182 // Skip the target entity
183 if entity == event.target {
184 continue;
185 }
186
187 // Send event to all entities before the target
188 if let Some(mut event_handler) = state.event_handlers.remove(&entity) {
189 event_handler.on_event_(state, entity, event);
190
191 state.event_handlers.insert(entity, event_handler);
192 // Skip to the next event if the current event is consumed
193 if event.consumed {
194 continue 'events;
195 }
196 }
197 }
198 }
199
200 // Propagate down from target to leaf of current branch
201 if event.propagation == Propagation::Fall {
202 // Walk tree from the target down the branch
203 for entity in target.branch_iter(&self.tree) {
204 // Skip the target entity
205 if entity == event.target {
206 continue;
207 }
208
209 // Send event to all entities after the target on the same branch
210 if let Some(mut event_handler) = state.event_handlers.remove(&entity) {
211 event_handler.on_event_(state, entity, event);
212
213 state.event_handlers.insert(entity, event_handler);
214 // Skip to the next event if the current event is consumed
215 if event.consumed {
216 continue 'events;
217 }
218 }
219 }
220 }
221 }
222
223 return needs_redraw;
224 }
225
226 pub fn draw(&mut self, state: &mut State, canvas: &mut Canvas<OpenGl>) {
227 //let dpi_factor = window.handle.window().scale_factor();
228 //let size = window.handle.window().inner_size();
229
230 // for (resource, image_or_id) in state.resource_manager.image_ids.iter_mut() {
231 // match image_or_id {
232 // ImageOrId::Image(data, width, height) => {
233 // image_or_id =
234 // }
235 // }
236 // }
237
238 // state
239 // .resource_manager
240 // .image_ids
241 // .iter_mut()
242 // .for_each(|(_, image_or_id)| {
243 // match image_or_id {
244 // ImageOrId::Image(image) => {
245 // //let img = image.clone();
246 // //let image: femtovg::ImageSource = (&img).try_into().unwrap();
247 // let image: femtovg::ImageSource = (&*image).try_into().unwrap();
248 // *image_or_id =
249 // ImageOrId::Id(canvas.create_image(image, ImageFlags::empty()).unwrap())
250 // }
251 // _ => {}
252 // }
253 // });
254
255 let width = state.data.get_width(Entity::root());
256 let height = state.data.get_height(Entity::root());
257 // TODO: Move this to the window widget
258 let dpi_factor = 1.0;
259
260 // Set the canvas size
261 if (self.prev_width != width
262 || self.prev_height != height
263 || self.prev_dpi_factor != dpi_factor)
264 {
265 canvas.set_size(width as u32, height as u32, dpi_factor as f32);
266 }
267
268 // Get the desired window background color
269 let background_color: femtovg::Color = state
270 .style
271 .background_color
272 .get(Entity::root())
273 .cloned()
274 .unwrap_or_default()
275 .into();
276
277 // Clear the canvas
278 canvas.clear_rect(0, 0, width as u32, height as u32, background_color);
279
280 //canvas.save();
281 // Reset any canvas transforms
282 canvas.reset();
283
284 // Sort the tree by z order
285 let mut draw_tree: Vec<Entity> = self.tree.into_iter().collect();
286 draw_tree.sort_by_cached_key(|entity| state.data.get_z_order(*entity));
287
288 // Call the on_draw() method for each widget
289 for entity in draw_tree.into_iter() {
290
291 // Skip window
292 if entity == Entity::root() {
293 continue;
294 }
295
296 // Skip invisible widgets
297 if state.data.get_visibility(entity) == Visibility::Invisible {
298 continue;
299 }
300
301 // Skip widgets that have 0 opacity
302 if state.data.get_opacity(entity) == 0.0 {
303 continue;
304 }
305
306 //let bounds = state.data.get_bounds(entity);
307
308 // Skip widgets with no width or no height
309 // if bounds.w == 0.0 || bounds.h == 0.0 {
310 // continue;
311 // }
312
313 let mut clip_region = state.data.get_clip_region(entity);
314 canvas.scissor(
315 clip_region.x,
316 clip_region.y,
317 clip_region.w,
318 clip_region.h,
319 );
320
321 // Apply transformations
322 let mut transform = state.data.get_transform(entity);
323
324
325 canvas.save();
326 canvas.set_transform(transform[0], transform[1], transform[2], transform[3], transform[4], transform[5]);
327
328 if let Some(mut event_handler) = state.event_handlers.remove(&entity) {
329 //let start = std::time::Instant::now();
330 event_handler.on_draw_(state, entity, canvas);
331 //println!("{:.2?} seconds for whatever you did.", start.elapsed());
332 state.event_handlers.insert(entity, event_handler);
333 }
334
335 canvas.restore();
336 }
337
338 //canvas.restore();
339
340 // Send the canvas to the GPU to draw
341 canvas.flush();
342 }
343}