vizia_core/context/
event.rs

1use std::any::{Any, TypeId};
2use std::collections::{BinaryHeap, VecDeque};
3#[cfg(feature = "clipboard")]
4use std::error::Error;
5use std::rc::Rc;
6
7use hashbrown::{HashMap, HashSet};
8use vizia_storage::{LayoutTreeIterator, TreeIterator};
9
10use crate::animation::{AnimId, Interpolator};
11use crate::cache::CachedData;
12use crate::events::{TimedEvent, TimedEventHandle, TimerState, ViewHandler};
13use crate::prelude::*;
14use crate::resource::ResourceManager;
15use crate::tree::{focus_backward, focus_forward, is_navigatable};
16use vizia_input::MouseState;
17
18use skia_safe::Matrix;
19
20use crate::text::TextContext;
21#[cfg(feature = "clipboard")]
22use copypasta::ClipboardProvider;
23
24use super::{LocalizationContext, ModelData, DARK_THEME, LIGHT_THEME};
25
26type Views = HashMap<Entity, Box<dyn ViewHandler>>;
27type Models = HashMap<Entity, HashMap<TypeId, Box<dyn ModelData>>>;
28
29/// A context used when handling events.
30///
31/// The [`EventContext`] is provided by the [`event`](crate::prelude::View::event) method in [`View`], or the [`event`](crate::model::Model::event) method in [`Model`], and can be used to mutably access the
32/// desired style and layout properties of the current view.
33///
34/// # Example
35/// ```
36/// # use vizia_core::prelude::*;
37/// # use vizia_core::vg;
38/// # let cx = &mut Context::default();
39///
40/// pub struct CustomView {}
41///
42/// impl CustomView {
43///     pub fn new(cx: &mut Context) -> Handle<Self> {
44///         Self{}.build(cx, |_|{})
45///     }
46/// }
47///
48/// impl View for CustomView {
49///     fn event(&mut self, cx: &mut EventContext, event: &mut Event) {
50///         event.map(|window_event, _| match window_event {
51///             WindowEvent::Press{..} => {
52///                 // Change the view background color to red when pressed.
53///                 cx.set_background_color(Color::red());
54///             }
55///
56///             _=> {}
57///         });
58///     }
59/// }
60/// ```
61pub struct EventContext<'a> {
62    pub(crate) current: Entity,
63    pub(crate) captured: &'a mut Entity,
64    pub(crate) focused: &'a mut Entity,
65    pub(crate) hovered: &'a Entity,
66    pub(crate) triggered: &'a mut Entity,
67    pub(crate) style: &'a mut Style,
68    pub(crate) entity_identifiers: &'a HashMap<String, Entity>,
69    pub cache: &'a mut CachedData,
70    pub(crate) tree: &'a Tree<Entity>,
71    pub(crate) models: &'a mut Models,
72    pub(crate) views: &'a mut Views,
73    pub(crate) listeners:
74        &'a mut HashMap<Entity, Box<dyn Fn(&mut dyn ViewHandler, &mut EventContext, &mut Event)>>,
75    pub(crate) resource_manager: &'a mut ResourceManager,
76    pub(crate) text_context: &'a mut TextContext,
77    pub(crate) modifiers: &'a Modifiers,
78    pub(crate) mouse: &'a MouseState<Entity>,
79    pub(crate) event_queue: &'a mut VecDeque<Event>,
80    pub(crate) event_schedule: &'a mut BinaryHeap<TimedEvent>,
81    pub(crate) next_event_id: &'a mut usize,
82    pub(crate) timers: &'a mut Vec<TimerState>,
83    pub(crate) running_timers: &'a mut BinaryHeap<TimerState>,
84    cursor_icon_locked: &'a mut bool,
85    #[cfg(feature = "clipboard")]
86    clipboard: &'a mut Box<dyn ClipboardProvider>,
87    pub(crate) event_proxy: &'a mut Option<Box<dyn crate::context::EventProxy>>,
88    pub(crate) ignore_default_theme: &'a bool,
89    pub(crate) drop_data: &'a mut Option<DropData>,
90    pub windows: &'a mut HashMap<Entity, WindowState>,
91}
92
93macro_rules! get_length_property {
94    (
95        $(#[$meta:meta])*
96        $name:ident
97    ) => {
98        $(#[$meta])*
99        pub fn $name(&self) -> f32 {
100            if let Some(length) = self.style.$name.get(self.current) {
101                let bounds = self.bounds();
102
103                let px = length.to_pixels(bounds.w.min(bounds.h), self.scale_factor());
104                return px.round();
105            }
106
107            0.0
108        }
109    };
110}
111
112impl<'a> EventContext<'a> {
113    /// Creates a new [EventContext].
114    pub fn new(cx: &'a mut Context) -> Self {
115        Self {
116            current: cx.current,
117            captured: &mut cx.captured,
118            focused: &mut cx.focused,
119            hovered: &cx.hovered,
120            triggered: &mut cx.triggered,
121            entity_identifiers: &cx.entity_identifiers,
122            style: &mut cx.style,
123            cache: &mut cx.cache,
124            tree: &cx.tree,
125            models: &mut cx.models,
126            views: &mut cx.views,
127            listeners: &mut cx.listeners,
128            resource_manager: &mut cx.resource_manager,
129            text_context: &mut cx.text_context,
130            modifiers: &cx.modifiers,
131            mouse: &cx.mouse,
132            event_queue: &mut cx.event_queue,
133            event_schedule: &mut cx.event_schedule,
134            next_event_id: &mut cx.next_event_id,
135            timers: &mut cx.timers,
136            running_timers: &mut cx.running_timers,
137            cursor_icon_locked: &mut cx.cursor_icon_locked,
138            #[cfg(feature = "clipboard")]
139            clipboard: &mut cx.clipboard,
140            event_proxy: &mut cx.event_proxy,
141            ignore_default_theme: &cx.ignore_default_theme,
142            drop_data: &mut cx.drop_data,
143            windows: &mut cx.windows,
144        }
145    }
146
147    /// Creates a new [EventContext] with the given current [Entity].
148    pub fn new_with_current(cx: &'a mut Context, current: Entity) -> Self {
149        Self {
150            current,
151            captured: &mut cx.captured,
152            focused: &mut cx.focused,
153            hovered: &cx.hovered,
154            triggered: &mut cx.triggered,
155            entity_identifiers: &cx.entity_identifiers,
156            style: &mut cx.style,
157            cache: &mut cx.cache,
158            tree: &cx.tree,
159            models: &mut cx.models,
160            views: &mut cx.views,
161            listeners: &mut cx.listeners,
162            resource_manager: &mut cx.resource_manager,
163            text_context: &mut cx.text_context,
164            modifiers: &cx.modifiers,
165            mouse: &cx.mouse,
166            event_queue: &mut cx.event_queue,
167            event_schedule: &mut cx.event_schedule,
168            next_event_id: &mut cx.next_event_id,
169            timers: &mut cx.timers,
170            running_timers: &mut cx.running_timers,
171            cursor_icon_locked: &mut cx.cursor_icon_locked,
172            #[cfg(feature = "clipboard")]
173            clipboard: &mut cx.clipboard,
174            event_proxy: &mut cx.event_proxy,
175            ignore_default_theme: &cx.ignore_default_theme,
176            drop_data: &mut cx.drop_data,
177            windows: &mut cx.windows,
178        }
179    }
180
181    /// Returns a reference to the current view associated with the event context.
182    pub fn get_view<V: View>(&self) -> Option<&V> {
183        self.views.get(&self.current).and_then(|view| view.downcast_ref::<V>())
184    }
185
186    /// Returns a reference to the specified view by entity.
187    pub fn get_view_with<V: View>(&self, entity: Entity) -> Option<&V> {
188        self.views.get(&entity).and_then(|view| view.downcast_ref::<V>())
189    }
190
191    pub fn close_window(&mut self) {
192        if let Some(state) = self.windows.get_mut(&self.current) {
193            state.should_close = true;
194        }
195    }
196
197    /// Returns the [Entity] id associated with the given identifier.
198    pub fn resolve_entity_identifier(&self, id: &str) -> Option<Entity> {
199        self.entity_identifiers.get(id).cloned()
200    }
201
202    /// Returns the [Entity] id of the current view.
203    pub fn current(&self) -> Entity {
204        self.current
205    }
206
207    /// Returns a reference to the keyboard modifiers state.
208    pub fn modifiers(&self) -> &Modifiers {
209        self.modifiers
210    }
211
212    /// Returns a reference to the mouse state.
213    pub fn mouse(&self) -> &MouseState<Entity> {
214        self.mouse
215    }
216
217    pub fn nth_child(&self, n: usize) -> Option<Entity> {
218        self.tree.get_child(self.current, n)
219    }
220
221    pub fn last_child(&self) -> Option<Entity> {
222        self.tree.get_last_child(self.current).copied()
223    }
224
225    pub fn with_current<T>(&mut self, entity: Entity, f: impl FnOnce(&mut Self) -> T) -> T {
226        let prev = self.current();
227        self.current = entity;
228        let ret = (f)(self);
229        self.current = prev;
230        ret
231    }
232
233    /// Returns true if in a drop state.
234    pub fn has_drop_data(&self) -> bool {
235        self.drop_data.is_some()
236    }
237
238    /// Returns the bounds of the current view.
239    pub fn bounds(&self) -> BoundingBox {
240        self.cache.get_bounds(self.current)
241    }
242
243    // pub fn set_bounds(&mut self, bounds: BoundingBox) {
244    //     self.cache.set_bounds(self.current, bounds);
245    // }
246
247    /// Returns the scale factor.
248    pub fn scale_factor(&self) -> f32 {
249        self.style.dpi_factor as f32
250    }
251
252    /// Converts logical points to physical pixels.
253    pub fn logical_to_physical(&self, logical: f32) -> f32 {
254        self.style.logical_to_physical(logical)
255    }
256
257    /// Convert physical pixels to logical points.
258    pub fn physical_to_logical(&self, physical: f32) -> f32 {
259        self.style.physical_to_logical(physical)
260    }
261
262    /// Returns the clip bounds of the current view.
263    pub fn clip_region(&self) -> BoundingBox {
264        let bounds = self.bounds();
265        let overflowx = self.style.overflowx.get(self.current).copied().unwrap_or_default();
266        let overflowy = self.style.overflowy.get(self.current).copied().unwrap_or_default();
267
268        // let root_bounds = self.cache.get_bounds(Entity::root());
269
270        let scale = self.scale_factor();
271
272        let clip_bounds = self
273            .style
274            .clip_path
275            .get(self.current)
276            .map(|clip| match clip {
277                ClipPath::Auto => bounds,
278                ClipPath::Shape(rect) => bounds.shrink_sides(
279                    rect.3.to_pixels(bounds.w, scale),
280                    rect.0.to_pixels(bounds.h, scale),
281                    rect.1.to_pixels(bounds.w, scale),
282                    rect.2.to_pixels(bounds.h, scale),
283                ),
284            })
285            .unwrap_or(bounds);
286
287        let root_bounds: BoundingBox =
288            BoundingBox { x: -f32::MAX / 2.0, y: -f32::MAX / 2.0, w: f32::MAX, h: f32::MAX };
289
290        match (overflowx, overflowy) {
291            (Overflow::Visible, Overflow::Visible) => root_bounds,
292            (Overflow::Hidden, Overflow::Visible) => {
293                let left = clip_bounds.left();
294                let right = clip_bounds.right();
295                let top = root_bounds.top();
296                let bottom = root_bounds.bottom();
297                BoundingBox::from_min_max(left, top, right, bottom)
298            }
299            (Overflow::Visible, Overflow::Hidden) => {
300                let left = root_bounds.left();
301                let right = root_bounds.right();
302                let top = clip_bounds.top();
303                let bottom = clip_bounds.bottom();
304                BoundingBox::from_min_max(left, top, right, bottom)
305            }
306            (Overflow::Hidden, Overflow::Hidden) => clip_bounds,
307        }
308    }
309
310    /// Returns the 2D transform of the current view.
311    pub fn transform(&self) -> Matrix {
312        let bounds = self.bounds();
313        let scale_factor = self.scale_factor();
314
315        // Apply transform origin.
316        let mut origin = self
317            .style
318            .transform_origin
319            .get(self.current)
320            .map(|transform_origin| {
321                let mut origin = Matrix::translate(bounds.top_left());
322                let offset = transform_origin.as_transform(bounds, scale_factor);
323                origin = offset * origin;
324                origin
325            })
326            .unwrap_or(Matrix::translate(bounds.center()));
327        // transform = origin * transform;
328        let mut transform = origin;
329        origin = origin.invert().unwrap();
330
331        // Apply translation.
332        if let Some(translate) = self.style.translate.get(self.current) {
333            transform = transform * translate.as_transform(bounds, scale_factor);
334        }
335
336        // Apply rotation.
337        if let Some(rotate) = self.style.rotate.get(self.current) {
338            transform = transform * rotate.as_transform(bounds, scale_factor);
339        }
340
341        // Apply scaling.
342        if let Some(scale) = self.style.scale.get(self.current) {
343            transform = transform * scale.as_transform(bounds, scale_factor);
344        }
345
346        // Apply transform functions.
347        if let Some(transforms) = self.style.transform.get(self.current) {
348            // Check if the transform is currently animating
349            // Get the animation state
350            // Manually interpolate the value to get the overall transform for the current frame
351            if let Some(animation_state) = self.style.transform.get_active_animation(self.current) {
352                if let Some(start) = animation_state.keyframes.first() {
353                    if let Some(end) = animation_state.keyframes.last() {
354                        let start_transform = start.value.as_transform(bounds, scale_factor);
355                        let end_transform = end.value.as_transform(bounds, scale_factor);
356                        let t = animation_state.t;
357                        let animated_transform =
358                            Matrix::interpolate(&start_transform, &end_transform, t);
359                        transform = transform * animated_transform;
360                    }
361                }
362            } else {
363                transform = transform * transforms.as_transform(bounds, scale_factor);
364            }
365        }
366
367        transform = transform * origin;
368
369        transform
370    }
371
372    /// Trigger an animation with the given id to play on the current view.
373    pub fn play_animation(&mut self, anim_id: impl AnimId, duration: Duration, delay: Duration) {
374        if let Some(animation_id) = anim_id.get(self) {
375            self.style.enqueue_animation(self.current, animation_id, duration, delay);
376        }
377    }
378
379    /// Trigger an animation with the given id to play on a target view.
380    pub fn play_animation_for(
381        &mut self,
382        anim_id: impl AnimId,
383        target: &str,
384        duration: Duration,
385        delay: Duration,
386    ) {
387        if let Some(target_entity) = self.resolve_entity_identifier(target) {
388            if let Some(animation_id) = anim_id.get(self) {
389                self.style.enqueue_animation(target_entity, animation_id, duration, delay)
390            }
391        }
392    }
393
394    /// Returns true if the current view is currently animating with the given animation id.
395    pub fn is_animating(&self, anim_id: impl AnimId) -> bool {
396        if let Some(animation_id) = anim_id.get(self) {
397            return self.style.is_animating(self.current, animation_id);
398        }
399
400        false
401    }
402
403    /// Add a listener to an entity.
404    ///
405    /// A listener can be used to handle events which would not normally propagate to the entity.
406    /// For example, mouse events when a different entity has captured them. Useful for things like
407    /// closing a popup when clicking outside of its bounding box.
408    pub fn add_listener<F, W>(&mut self, listener: F)
409    where
410        W: View,
411        F: 'static + Fn(&mut W, &mut EventContext, &mut Event),
412    {
413        self.listeners.insert(
414            self.current,
415            Box::new(move |event_handler, context, event| {
416                if let Some(widget) = event_handler.downcast_mut::<W>() {
417                    (listener)(widget, context, event);
418                }
419            }),
420        );
421    }
422
423    /// Sets the language used by the application for localization.
424    pub fn set_language(&mut self, lang: LanguageIdentifier) {
425        if let Some(mut models) = self.models.remove(&Entity::root()) {
426            if let Some(model) = models.get_mut(&TypeId::of::<Environment>()) {
427                model.event(self, &mut Event::new(EnvironmentEvent::SetLocale(lang)));
428            }
429
430            self.models.insert(Entity::root(), models);
431        }
432    }
433
434    /// Capture mouse input for the current view.
435    pub fn capture(&mut self) {
436        *self.captured = self.current;
437    }
438
439    /// Release mouse input capture for the current view.
440    pub fn release(&mut self) {
441        if self.current == *self.captured {
442            *self.captured = Entity::null();
443        }
444    }
445
446    /// Enables or disables PseudoClassFlags for the focus of an entity
447    fn set_focus_pseudo_classes(&mut self, focused: Entity, enabled: bool, focus_visible: bool) {
448        if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(focused) {
449            pseudo_classes.set(PseudoClassFlags::FOCUS, enabled);
450            if !enabled || focus_visible {
451                pseudo_classes.set(PseudoClassFlags::FOCUS_VISIBLE, enabled);
452            }
453        }
454
455        for ancestor in focused.parent_iter(self.tree) {
456            let entity = ancestor;
457            if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(entity) {
458                pseudo_classes.set(PseudoClassFlags::FOCUS_WITHIN, enabled);
459            }
460        }
461    }
462
463    /// Sets application focus to the current view with the specified focus visibility.
464    pub fn focus_with_visibility(&mut self, focus_visible: bool) {
465        let old_focus = self.focused();
466        let new_focus = self.current();
467        self.set_focus_pseudo_classes(old_focus, false, focus_visible);
468        if self.current() != self.focused() {
469            self.emit_to(old_focus, WindowEvent::FocusOut);
470            self.emit_to(new_focus, WindowEvent::FocusIn);
471            *self.focused = self.current();
472        }
473        self.set_focus_pseudo_classes(new_focus, true, focus_visible);
474
475        self.emit_custom(Event::new(WindowEvent::FocusVisibility(focus_visible)).target(old_focus));
476        self.emit_custom(Event::new(WindowEvent::FocusVisibility(focus_visible)).target(new_focus));
477
478        self.needs_restyle();
479    }
480
481    /// Sets application focus to the current view using the previous focus visibility.
482    ///
483    /// Focused elements receive keyboard input events and can be selected with the `:focus` CSS pseudo-class selector.
484    pub fn focus(&mut self) {
485        let focused = self.focused();
486        let old_focus_visible = self
487            .style
488            .pseudo_classes
489            .get_mut(focused)
490            .filter(|class| class.contains(PseudoClassFlags::FOCUS_VISIBLE))
491            .is_some();
492        self.focus_with_visibility(old_focus_visible)
493    }
494
495    /// Moves the keyboard focus to the next navigable view.
496    pub fn focus_next(&mut self) {
497        let lock_focus_to = self.tree.lock_focus_within(*self.focused);
498        let next_focused = if let Some(next_focused) =
499            focus_forward(self.tree, self.style, *self.focused, lock_focus_to)
500        {
501            next_focused
502        } else {
503            TreeIterator::full(self.tree)
504                .find(|node| is_navigatable(self.tree, self.style, *node, lock_focus_to))
505                .unwrap_or(Entity::root())
506        };
507
508        if next_focused != *self.focused {
509            self.event_queue.push_back(
510                Event::new(WindowEvent::FocusOut).target(*self.focused).origin(Entity::root()),
511            );
512            self.event_queue.push_back(
513                Event::new(WindowEvent::FocusIn).target(next_focused).origin(Entity::root()),
514            );
515
516            if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(*self.triggered) {
517                pseudo_classes.set(PseudoClassFlags::ACTIVE, false);
518            }
519            self.needs_restyle();
520            *self.triggered = Entity::null();
521        }
522    }
523
524    /// Moves the keyboard focus to the previous navigable view.
525    pub fn focus_prev(&mut self) {
526        let lock_focus_to = self.tree.lock_focus_within(*self.focused);
527        let prev_focused = if let Some(prev_focused) =
528            focus_backward(self.tree, self.style, *self.focused, lock_focus_to)
529        {
530            prev_focused
531        } else {
532            TreeIterator::full(self.tree)
533                .filter(|node| is_navigatable(self.tree, self.style, *node, lock_focus_to))
534                .next_back()
535                .unwrap_or(Entity::root())
536        };
537
538        if prev_focused != *self.focused {
539            self.event_queue.push_back(
540                Event::new(WindowEvent::FocusOut).target(*self.focused).origin(Entity::root()),
541            );
542            self.event_queue.push_back(
543                Event::new(WindowEvent::FocusIn).target(prev_focused).origin(Entity::root()),
544            );
545
546            if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(*self.triggered) {
547                pseudo_classes.set(PseudoClassFlags::ACTIVE, false);
548            }
549            self.needs_restyle();
550            *self.triggered = Entity::null();
551        }
552    }
553
554    /// Returns the currently hovered view.
555    pub fn hovered(&self) -> Entity {
556        *self.hovered
557    }
558
559    /// Returns the currently focused view.
560    pub fn focused(&self) -> Entity {
561        *self.focused
562    }
563
564    // PseudoClass Getters
565
566    /// Returns true if the current view is being hovered.
567    pub fn is_hovered(&self) -> bool {
568        self.hovered() == self.current
569    }
570
571    /// Returns true if the current view is active.
572    pub fn is_active(&self) -> bool {
573        if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
574            pseudo_classes.contains(PseudoClassFlags::ACTIVE)
575        } else {
576            false
577        }
578    }
579
580    /// Returns true if the mouse cursor is over the current view.
581    pub fn is_over(&self) -> bool {
582        if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
583            pseudo_classes.contains(PseudoClassFlags::OVER)
584        } else {
585            false
586        }
587    }
588
589    /// Returns true if the current view is focused.
590    pub fn is_focused(&self) -> bool {
591        self.focused() == self.current
592    }
593
594    /// Returns true if the current view can be dragged in a drag and drop operation.
595    pub fn is_draggable(&self) -> bool {
596        self.style
597            .abilities
598            .get(self.current)
599            .map(|abilities| abilities.contains(Abilities::DRAGGABLE))
600            .unwrap_or_default()
601    }
602
603    /// Returns true if the current view is disabled.
604    pub fn is_disabled(&self) -> bool {
605        self.style.disabled.get(self.current()).cloned().unwrap_or_default()
606    }
607
608    /// Returns true if the current view is checked.
609    pub fn is_checked(&self) -> bool {
610        if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
611            pseudo_classes.contains(PseudoClassFlags::CHECKED)
612        } else {
613            false
614        }
615    }
616
617    /// Returns true if the view is in a read-only state.
618    pub fn is_read_only(&self) -> bool {
619        if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
620            pseudo_classes.contains(PseudoClassFlags::READ_ONLY)
621        } else {
622            false
623        }
624    }
625
626    //
627
628    /// Prevents the cursor icon from changing until the lock is released.
629    pub fn lock_cursor_icon(&mut self) {
630        *self.cursor_icon_locked = true;
631    }
632
633    /// Releases any cursor icon lock, allowing the cursor icon to be changed.
634    pub fn unlock_cursor_icon(&mut self) {
635        *self.cursor_icon_locked = false;
636        let hovered = *self.hovered;
637        let cursor = self.style.cursor.get(hovered).cloned().unwrap_or_default();
638        self.emit(WindowEvent::SetCursor(cursor));
639    }
640
641    /// Returns true if the cursor icon is locked.
642    pub fn is_cursor_icon_locked(&self) -> bool {
643        *self.cursor_icon_locked
644    }
645
646    /// Sets the drop data of the current view.
647    pub fn set_drop_data(&mut self, data: impl Into<DropData>) {
648        *self.drop_data = Some(data.into())
649    }
650
651    /// Get the contents of the system clipboard.
652    ///
653    /// This may fail for a variety of backend-specific reasons.
654    #[cfg(feature = "clipboard")]
655    pub fn get_clipboard(&mut self) -> Result<String, Box<dyn Error + Send + Sync + 'static>> {
656        self.clipboard.get_contents()
657    }
658
659    /// Set the contents of the system clipboard.
660    ///
661    /// This may fail for a variety of backend-specific reasons.
662    #[cfg(feature = "clipboard")]
663    pub fn set_clipboard(
664        &mut self,
665        text: String,
666    ) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
667        self.clipboard.set_contents(text)
668    }
669
670    /// Toggles the addition/removal of a class name for the current view.
671    ///
672    /// # Example
673    /// ```rust
674    /// # use vizia_core::prelude::*;
675    /// # let context = &mut Context::default();
676    /// # let mut cx = &mut EventContext::new(context);
677    /// cx.toggle_class("foo", true);
678    /// ```
679    pub fn toggle_class(&mut self, class_name: &str, applied: bool) {
680        let current = self.current();
681        if let Some(class_list) = self.style.classes.get_mut(current) {
682            if applied {
683                class_list.insert(class_name.to_string());
684            } else {
685                class_list.remove(class_name);
686            }
687        } else if applied {
688            let mut class_list = HashSet::new();
689            class_list.insert(class_name.to_string());
690            self.style.classes.insert(current, class_list);
691        }
692
693        self.needs_restyle();
694    }
695
696    /// Returns a reference to the [Environment] model.
697    pub fn environment(&self) -> &Environment {
698        self.data::<Environment>().unwrap()
699    }
700
701    /// Sets the current [theme mode](ThemeMode).
702    pub fn set_theme_mode(&mut self, theme_mode: ThemeMode) {
703        if !self.ignore_default_theme {
704            match theme_mode {
705                ThemeMode::LightMode => {
706                    self.resource_manager.themes[2] = String::from(LIGHT_THEME);
707                }
708
709                ThemeMode::DarkMode => {
710                    self.resource_manager.themes[2] = String::from(DARK_THEME);
711                }
712            }
713        }
714    }
715
716    /// Marks the current view as needing to be redrawn.
717    pub fn needs_redraw(&mut self) {
718        let parent_window = self.tree.get_parent_window(self.current).unwrap_or(Entity::root());
719        if let Some(window_state) = self.windows.get_mut(&parent_window) {
720            window_state.redraw_list.insert(self.current);
721        }
722    }
723
724    /// Marks the current view as needing a layout computation.
725    pub fn needs_relayout(&mut self) {
726        self.style.needs_relayout();
727        self.needs_redraw();
728    }
729
730    /// Marks the current view as needing to be restyled.
731    pub fn needs_restyle(&mut self) {
732        self.style.restyle.insert(self.current).unwrap();
733        let iter = if let Some(parent) = self.tree.get_layout_parent(self.current) {
734            LayoutTreeIterator::subtree(self.tree, parent)
735        } else {
736            LayoutTreeIterator::subtree(self.tree, self.current)
737        };
738
739        for descendant in iter {
740            self.style.restyle.insert(descendant).unwrap();
741        }
742        self.style.needs_restyle(self.current);
743    }
744
745    /// Reloads the stylesheets linked to the application.
746    pub fn reload_styles(&mut self) -> Result<(), std::io::Error> {
747        if self.resource_manager.themes.is_empty() && self.resource_manager.styles.is_empty() {
748            return Ok(());
749        }
750
751        self.style.remove_rules();
752
753        self.style.clear_style_rules();
754
755        let mut overall_theme = String::new();
756
757        // Reload built-in themes
758        for theme in self.resource_manager.themes.iter() {
759            overall_theme += theme;
760        }
761
762        for style_string in self.resource_manager.styles.iter().flat_map(|style| style.get_style())
763        {
764            overall_theme += &style_string;
765        }
766
767        self.style.parse_theme(&overall_theme);
768
769        for entity in self.tree.into_iter() {
770            self.style.needs_restyle(entity);
771            self.style.needs_relayout();
772            //self.style.needs_redraw(entity);
773            self.style.needs_text_update(entity);
774        }
775
776        Ok(())
777    }
778
779    /// Spawns a thread and provides a [ContextProxy] for sending events back to the main UI thread.
780    pub fn spawn<F>(&self, target: F)
781    where
782        F: 'static + Send + FnOnce(&mut ContextProxy),
783    {
784        let mut cxp = ContextProxy {
785            current: self.current,
786            event_proxy: self.event_proxy.as_ref().map(|p| p.make_clone()),
787        };
788
789        std::thread::spawn(move || target(&mut cxp));
790    }
791
792    /// Returns a [ContextProxy] which can be moved between threads and used to send events back to the main UI thread.
793    pub fn get_proxy(&self) -> ContextProxy {
794        ContextProxy {
795            current: self.current,
796            event_proxy: self.event_proxy.as_ref().map(|p| p.make_clone()),
797        }
798    }
799
800    pub fn modify<V: View>(&mut self, f: impl FnOnce(&mut V)) {
801        if let Some(view) = self
802            .views
803            .get_mut(&self.current)
804            .and_then(|view_handler| view_handler.downcast_mut::<V>())
805        {
806            (f)(view);
807        }
808    }
809
810    // TODO: Abstract this to shared trait for all contexts
811
812    // Getters
813
814    /// Returns the background color of the view.
815    ///
816    /// Returns a transparent color if the view does not have a background color.
817    pub fn background_color(&mut self) -> Color {
818        self.style.background_color.get(self.current).copied().unwrap_or_default()
819    }
820
821    // Setters
822
823    pub fn set_id(&mut self, id: &str) {
824        self.style.ids.insert(self.current, id.to_string())
825    }
826
827    // Pseudoclass Setters
828
829    /// Sets the hover state of the current view.
830    ///
831    /// Hovered elements can be selected with the `:hover` CSS pseudo-class selector:
832    /// ```css
833    /// element:hover {
834    ///     background-color: red;
835    /// }
836    /// ```
837    /// Typically this is set by the hover system and should not be set manually.
838    pub fn set_hover(&mut self, flag: bool) {
839        let current = self.current();
840        if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
841            pseudo_classes.set(PseudoClassFlags::HOVER, flag);
842        }
843
844        self.needs_restyle();
845    }
846
847    /// Set the active state for the current view.
848    ///
849    /// Active elements can be selected with the `:active` CSS pseudo-class selector:
850    /// ```css
851    /// element:active {
852    ///     background-color: red;
853    /// }
854    /// ```
855    pub fn set_active(&mut self, active: bool) {
856        if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(self.current) {
857            pseudo_classes.set(PseudoClassFlags::ACTIVE, active);
858        }
859
860        self.needs_restyle();
861    }
862
863    pub fn set_read_only(&mut self, flag: bool) {
864        let current = self.current();
865        if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
866            pseudo_classes.set(PseudoClassFlags::READ_ONLY, flag);
867        }
868
869        self.needs_restyle();
870    }
871
872    pub fn set_read_write(&mut self, flag: bool) {
873        let current = self.current();
874        if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
875            pseudo_classes.set(PseudoClassFlags::READ_WRITE, flag);
876        }
877
878        self.needs_restyle();
879    }
880
881    /// Sets the checked state of the current view.
882    ///
883    /// Checked elements can be selected with the `:checked` CSS pseudo-class selector:
884    /// ```css
885    /// element:checked {
886    ///     background-color: red;
887    /// }
888    /// ```
889    pub fn set_checked(&mut self, flag: bool) {
890        let current = self.current();
891        if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
892            pseudo_classes.set(PseudoClassFlags::CHECKED, flag);
893        }
894
895        self.needs_restyle();
896    }
897
898    /// Sets the valid state of the current view.
899    ///
900    /// Checked elements can be selected with the `:checked` CSS pseudo-class selector:
901    /// ```css
902    /// element:checked {
903    ///     background-color: red;
904    /// }
905    /// ```
906    pub fn set_valid(&mut self, flag: bool) {
907        let current = self.current();
908        if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
909            pseudo_classes.set(PseudoClassFlags::VALID, flag);
910            pseudo_classes.set(PseudoClassFlags::INVALID, !flag);
911        }
912
913        self.needs_restyle();
914    }
915
916    pub fn set_placeholder_shown(&mut self, flag: bool) {
917        let current = self.current();
918        if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
919            pseudo_classes.set(PseudoClassFlags::PLACEHOLDER_SHOWN, flag);
920        }
921
922        self.needs_restyle();
923    }
924
925    // TODO: Move me
926    pub fn is_valid(&self) -> bool {
927        self.style
928            .pseudo_classes
929            .get(self.current)
930            .map(|pseudo_classes| pseudo_classes.contains(PseudoClassFlags::VALID))
931            .unwrap_or_default()
932    }
933
934    pub fn is_placeholder_shown(&self) -> bool {
935        self.style
936            .pseudo_classes
937            .get(self.current)
938            .map(|pseudo_classes| pseudo_classes.contains(PseudoClassFlags::PLACEHOLDER_SHOWN))
939            .unwrap_or_default()
940    }
941
942    // Accessibility Properties
943
944    /// Sets the accessibility name of the view.
945    pub fn set_name(&mut self, name: &str) {
946        self.style.name.insert(self.current, name.to_string());
947    }
948
949    /// Sets the accessibility role of the view.
950    pub fn set_role(&mut self, role: Role) {
951        self.style.role.insert(self.current, role);
952    }
953
954    // /// Sets the accessibility default action verb of the view.
955    // pub fn set_default_action_verb(&mut self, default_action_verb: DefaultActionVerb) {
956    //     self.style.default_action_verb.insert(self.current, default_action_verb);
957    // }
958
959    /// Sets the view to be an accessibility live region.
960    pub fn set_live(&mut self, live: Live) {
961        self.style.live.insert(self.current, live);
962    }
963
964    /// Sets the view, by id name, which labels the current view for accessibility.  
965    pub fn labelled_by(&mut self, id: &str) {
966        if let Some(entity) = self.resolve_entity_identifier(id) {
967            self.style.labelled_by.insert(self.current, entity);
968        }
969    }
970
971    /// Sets whether the view should be explicitely hidden from accessibility.
972    pub fn set_hidden(&mut self, hidden: bool) {
973        self.style.hidden.insert(self.current, hidden)
974    }
975
976    /// Sets a text value used for accessbility for the current view.
977    pub fn text_value(&mut self, text: &str) {
978        self.style.text_value.insert(self.current, text.to_string());
979    }
980
981    /// Sets a numeric value used for accessibility for the current view.
982    pub fn numeric_value(&mut self, value: f64) {
983        self.style.numeric_value.insert(self.current, value);
984    }
985
986    // DISPLAY
987
988    /// Sets the display type of the current view.
989    ///
990    /// A display value of `Display::None` causes the view to be ignored by both layout and rendering.
991    pub fn set_display(&mut self, display: Display) {
992        self.style.display.insert(self.current, display);
993    }
994
995    /// Sets the visibility of the current view.
996    ///
997    /// The layout system will still compute the size and position of an invisible (hidden) view.
998    pub fn set_visibility(&mut self, visibility: Visibility) {
999        self.style.visibility.insert(self.current, visibility);
1000    }
1001
1002    /// Sets the opacity of the current view.
1003    ///
1004    /// Expects a number between 0.0 (transparent) and 1.0 (opaque).
1005    pub fn set_opacity(&mut self, opacity: f32) {
1006        self.style.opacity.insert(self.current, Opacity(opacity));
1007    }
1008
1009    /// Sets the z-index of the current view.
1010    pub fn set_z_index(&mut self, z_index: i32) {
1011        self.style.z_index.insert(self.current, z_index);
1012    }
1013
1014    /// Sets the clip path of the current view.
1015    pub fn set_clip_path(&mut self, clip_path: ClipPath) {
1016        self.style.clip_path.insert(self.current, clip_path);
1017    }
1018
1019    /// Sets the overflow type on the horizontal axis of the current view.
1020    pub fn set_overflowx(&mut self, overflowx: impl Into<Overflow>) {
1021        self.style.overflowx.insert(self.current, overflowx.into());
1022    }
1023
1024    /// Sets the overflow type on the vertical axis of the current view.
1025    pub fn set_overflowy(&mut self, overflowy: impl Into<Overflow>) {
1026        self.style.overflowy.insert(self.current, overflowy.into());
1027    }
1028
1029    // TRANSFORM
1030
1031    /// Sets the transform of the current view.
1032    pub fn set_transform(&mut self, transform: impl Into<Vec<Transform>>) {
1033        self.style.transform.insert(self.current, transform.into());
1034    }
1035
1036    /// Sets the transform origin of the current view.
1037    pub fn set_transform_origin(&mut self, transform_origin: Translate) {
1038        self.style.transform_origin.insert(self.current, transform_origin);
1039    }
1040
1041    /// Sets the translation of the current view.
1042    pub fn set_translate(&mut self, translate: impl Into<Translate>) {
1043        self.style.translate.insert(self.current, translate.into());
1044    }
1045
1046    /// Sets the rotation of the current view.
1047    pub fn set_rotate(&mut self, angle: impl Into<Angle>) {
1048        self.style.rotate.insert(self.current, angle.into());
1049    }
1050
1051    /// Sets the scale of the current view.
1052    pub fn set_scale(&mut self, scale: impl Into<Scale>) {
1053        self.style.scale.insert(self.current, scale.into());
1054    }
1055
1056    // FILTER
1057
1058    /// Sets the backdrop filter of the current view.
1059    pub fn set_backdrop_filter(&mut self, filter: Filter) {
1060        self.style.backdrop_filter.insert(self.current, filter);
1061    }
1062
1063    // BOX SHADOW
1064
1065    // TODO
1066
1067    // BACKGROUND
1068
1069    pub fn set_background_color(&mut self, background_color: Color) {
1070        self.style.background_color.insert(self.current, background_color);
1071        self.needs_redraw();
1072    }
1073
1074    // SIZE
1075
1076    pub fn set_width(&mut self, width: Units) {
1077        self.style.width.insert(self.current, width);
1078        self.needs_relayout();
1079        self.needs_redraw();
1080    }
1081
1082    pub fn set_height(&mut self, height: Units) {
1083        self.style.height.insert(self.current, height);
1084        self.needs_relayout();
1085        self.needs_redraw();
1086    }
1087
1088    pub fn set_max_height(&mut self, height: Units) {
1089        self.style.max_height.insert(self.current, height);
1090        self.needs_relayout();
1091        self.needs_redraw();
1092    }
1093
1094    // SPACE
1095
1096    pub fn set_left(&mut self, left: Units) {
1097        self.style.left.insert(self.current, left);
1098        self.needs_relayout();
1099        self.needs_redraw();
1100    }
1101
1102    pub fn set_top(&mut self, top: Units) {
1103        self.style.top.insert(self.current, top);
1104        self.needs_relayout();
1105        self.needs_redraw();
1106    }
1107
1108    pub fn set_right(&mut self, right: Units) {
1109        self.style.right.insert(self.current, right);
1110        self.needs_relayout();
1111        self.needs_redraw();
1112    }
1113
1114    pub fn set_bottom(&mut self, bottom: Units) {
1115        self.style.bottom.insert(self.current, bottom);
1116        self.needs_relayout();
1117        self.needs_redraw();
1118    }
1119
1120    // PADDING
1121
1122    pub fn set_padding_left(&mut self, padding_left: Units) {
1123        self.style.padding_left.insert(self.current, padding_left);
1124        self.needs_relayout();
1125        self.needs_redraw();
1126    }
1127
1128    pub fn set_padding_top(&mut self, padding_top: Units) {
1129        self.style.padding_top.insert(self.current, padding_top);
1130        self.needs_relayout();
1131        self.needs_redraw();
1132    }
1133
1134    pub fn set_padding_right(&mut self, padding_right: Units) {
1135        self.style.padding_right.insert(self.current, padding_right);
1136        self.needs_relayout();
1137        self.needs_redraw();
1138    }
1139
1140    pub fn set_padding_bottom(&mut self, padding_bottom: Units) {
1141        self.style.padding_bottom.insert(self.current, padding_bottom);
1142        self.needs_relayout();
1143        self.needs_redraw();
1144    }
1145
1146    // TEXT
1147
1148    /// Sets the text of the current view.
1149    pub fn set_text(&mut self, text: &str) {
1150        self.style.text.insert(self.current, text.to_owned());
1151        self.style.needs_text_update(self.current);
1152        self.needs_relayout();
1153        self.needs_redraw();
1154    }
1155
1156    pub fn set_pointer_events(&mut self, pointer_events: impl Into<PointerEvents>) {
1157        self.style.pointer_events.insert(self.current, pointer_events.into());
1158    }
1159
1160    // GETTERS
1161    get_length_property!(
1162        /// Returns the border width of the current view in physical pixels.
1163        border_width
1164    );
1165
1166    /// Returns the font-size of the current view in physical pixels.
1167    pub fn font_size(&self) -> f32 {
1168        self.logical_to_physical(
1169            self.style.font_size.get(self.current).copied().map(|f| f.0).unwrap_or(16.0),
1170        )
1171    }
1172
1173    /// Adds a timer to the application.
1174    ///
1175    /// `interval` - The time between ticks of the timer.
1176    /// `duration` - An optional duration for the timer. Pass `None` for a continuos timer.
1177    /// `callback` - A callback which is called on when the timer is started, ticks, and stops. Disambiguated by the `TimerAction` parameter of the callback.
1178    ///
1179    /// Returns a `Timer` id which can be used to start and stop the timer.  
1180    ///
1181    /// # Example
1182    /// Creates a timer which calls the provided callback every second for 5 seconds:
1183    /// ```rust
1184    /// # use vizia_core::prelude::*;
1185    /// # use instant::{Instant, Duration};
1186    /// # let cx = &mut Context::default();
1187    /// let timer = cx.add_timer(Duration::from_secs(1), Some(Duration::from_secs(5)), |cx, reason|{
1188    ///     match reason {
1189    ///         TimerAction::Start => {
1190    ///             debug!("Start timer");
1191    ///         }
1192    ///     
1193    ///         TimerAction::Tick(delta) => {
1194    ///             debug!("Tick timer: {:?}", delta);
1195    ///         }
1196    ///
1197    ///         TimerAction::Stop => {
1198    ///             debug!("Stop timer");
1199    ///         }
1200    ///     }
1201    /// });
1202    /// ```
1203    pub fn add_timer(
1204        &mut self,
1205        interval: Duration,
1206        duration: Option<Duration>,
1207        callback: impl Fn(&mut EventContext, TimerAction) + 'static,
1208    ) -> Timer {
1209        let id = Timer(self.timers.len());
1210        self.timers.push(TimerState {
1211            entity: Entity::root(),
1212            id,
1213            time: Instant::now(),
1214            interval,
1215            duration,
1216            start_time: Instant::now(),
1217            callback: Rc::new(callback),
1218            ticking: false,
1219            stopping: false,
1220        });
1221
1222        id
1223    }
1224
1225    /// Starts a timer with the provided timer id.
1226    ///
1227    /// Events sent within the timer callback provided in `add_timer()` will target the current view.
1228    pub fn start_timer(&mut self, timer: Timer) {
1229        let current = self.current;
1230        if !self.timer_is_running(timer) {
1231            let timer_state = self.timers[timer.0].clone();
1232            // Copy timer state from pending to playing
1233            self.running_timers.push(timer_state);
1234        }
1235
1236        self.modify_timer(timer, |timer_state| {
1237            let now = Instant::now();
1238            timer_state.start_time = now;
1239            timer_state.time = now;
1240            timer_state.entity = current;
1241            timer_state.ticking = false;
1242            timer_state.stopping = false;
1243        });
1244    }
1245
1246    /// Modifies the state of an existing timer with the provided `Timer` id.
1247    pub fn modify_timer(&mut self, timer: Timer, timer_function: impl Fn(&mut TimerState)) {
1248        while let Some(next_timer_state) = self.running_timers.peek() {
1249            if next_timer_state.id == timer {
1250                let mut timer_state = self.running_timers.pop().unwrap();
1251
1252                (timer_function)(&mut timer_state);
1253
1254                self.running_timers.push(timer_state);
1255
1256                return;
1257            }
1258        }
1259
1260        for pending_timer in self.timers.iter_mut() {
1261            if pending_timer.id == timer {
1262                (timer_function)(pending_timer);
1263            }
1264        }
1265    }
1266
1267    pub fn query_timer<T>(
1268        &mut self,
1269        timer: Timer,
1270        timer_function: impl Fn(&TimerState) -> T,
1271    ) -> Option<T> {
1272        while let Some(next_timer_state) = self.running_timers.peek() {
1273            if next_timer_state.id == timer {
1274                let timer_state = self.running_timers.pop().unwrap();
1275
1276                let t = (timer_function)(&timer_state);
1277
1278                self.running_timers.push(timer_state);
1279
1280                return Some(t);
1281            }
1282        }
1283
1284        for pending_timer in self.timers.iter() {
1285            if pending_timer.id == timer {
1286                return Some(timer_function(pending_timer));
1287            }
1288        }
1289
1290        None
1291    }
1292
1293    /// Returns true if the timer with the provided timer id is currently running.
1294    pub fn timer_is_running(&mut self, timer: Timer) -> bool {
1295        for timer_state in self.running_timers.iter() {
1296            if timer_state.id == timer {
1297                return true;
1298            }
1299        }
1300
1301        false
1302    }
1303
1304    /// Stops the timer with the given timer id.
1305    ///
1306    /// Any events emitted in response to the timer stopping, as determined by the callback provided in `add_timer()`, will target the view which called `start_timer()`.
1307    pub fn stop_timer(&mut self, timer: Timer) {
1308        let mut running_timers = self.running_timers.clone();
1309
1310        for timer_state in running_timers.iter() {
1311            if timer_state.id == timer {
1312                self.with_current(timer_state.entity, |cx| {
1313                    (timer_state.callback)(cx, TimerAction::Stop);
1314                });
1315            }
1316        }
1317
1318        *self.running_timers =
1319            running_timers.drain().filter(|timer_state| timer_state.id != timer).collect();
1320    }
1321}
1322
1323impl DataContext for EventContext<'_> {
1324    fn data<T: 'static>(&self) -> Option<&T> {
1325        // Return data for the static model.
1326        if let Some(t) = <dyn Any>::downcast_ref::<T>(&()) {
1327            return Some(t);
1328        }
1329
1330        for entity in self.current.parent_iter(self.tree) {
1331            // Return model data.
1332            if let Some(models) = self.models.get(&entity) {
1333                if let Some(model) = models.get(&TypeId::of::<T>()) {
1334                    return model.downcast_ref::<T>();
1335                }
1336            }
1337
1338            // Return view data.
1339            if let Some(view_handler) = self.views.get(&entity) {
1340                if let Some(data) = view_handler.downcast_ref::<T>() {
1341                    return Some(data);
1342                }
1343            }
1344        }
1345
1346        None
1347    }
1348
1349    fn localization_context(&self) -> Option<LocalizationContext<'_>> {
1350        Some(LocalizationContext::from_event_context(self))
1351    }
1352}
1353
1354impl EmitContext for EventContext<'_> {
1355    fn emit<M: Any + Send>(&mut self, message: M) {
1356        self.event_queue.push_back(
1357            Event::new(message)
1358                .target(self.current)
1359                .origin(self.current)
1360                .propagate(Propagation::Up),
1361        );
1362    }
1363
1364    fn emit_to<M: Any + Send>(&mut self, target: Entity, message: M) {
1365        self.event_queue.push_back(
1366            Event::new(message).target(target).origin(self.current).propagate(Propagation::Direct),
1367        );
1368    }
1369
1370    fn emit_custom(&mut self, event: Event) {
1371        self.event_queue.push_back(event);
1372    }
1373
1374    fn schedule_emit<M: Any + Send>(&mut self, message: M, at: Instant) -> TimedEventHandle {
1375        self.schedule_emit_custom(
1376            Event::new(message)
1377                .target(self.current)
1378                .origin(self.current)
1379                .propagate(Propagation::Up),
1380            at,
1381        )
1382    }
1383    fn schedule_emit_to<M: Any + Send>(
1384        &mut self,
1385        target: Entity,
1386        message: M,
1387        at: Instant,
1388    ) -> TimedEventHandle {
1389        self.schedule_emit_custom(
1390            Event::new(message).target(target).origin(self.current).propagate(Propagation::Direct),
1391            at,
1392        )
1393    }
1394    fn schedule_emit_custom(&mut self, event: Event, at: Instant) -> TimedEventHandle {
1395        let handle = TimedEventHandle(*self.next_event_id);
1396        self.event_schedule.push(TimedEvent { event, time: at, ident: handle });
1397        *self.next_event_id += 1;
1398        handle
1399    }
1400    fn cancel_scheduled(&mut self, handle: TimedEventHandle) {
1401        *self.event_schedule =
1402            self.event_schedule.drain().filter(|item| item.ident != handle).collect();
1403    }
1404}
1405
1406/// Trait for querying properties of the tree from a context.
1407pub trait TreeProps {
1408    /// Returns the entity id of the parent of the current view.
1409    fn parent(&self) -> Entity;
1410    /// Returns the entity id of the first_child of the current view.
1411    fn first_child(&self) -> Entity;
1412    /// Returns the entity id of the parent window of the current view.
1413    fn parent_window(&self) -> Entity;
1414}
1415
1416impl TreeProps for EventContext<'_> {
1417    fn parent(&self) -> Entity {
1418        self.tree.get_layout_parent(self.current).unwrap()
1419    }
1420
1421    fn first_child(&self) -> Entity {
1422        self.tree.get_layout_first_child(self.current).unwrap()
1423    }
1424
1425    fn parent_window(&self) -> Entity {
1426        self.tree.get_parent_window(self.current).unwrap_or(Entity::root())
1427    }
1428}