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}