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::hash_map::Entry;
8use hashbrown::{HashMap, HashSet};
9use vizia_storage::{LayoutTreeIterator, TreeIterator};
10
11use crate::animation::{AnimId, Interpolator};
12use crate::cache::CachedData;
13use crate::events::{TimedEvent, TimedEventHandle, TimerState, ViewHandler};
14use crate::prelude::*;
15use crate::resource::{ImageOrSvg, ResourceManager, StoredImage};
16use crate::tree::{focus_backward, focus_forward, is_navigatable};
17use vizia_input::MouseState;
18
19use skia_safe::Matrix;
20
21use crate::text::TextContext;
22#[cfg(feature = "clipboard")]
23use copypasta::ClipboardProvider;
24
25use super::{LocalizationContext, ModelData, DARK_THEME, LIGHT_THEME};
26
27type Views = HashMap<Entity, Box<dyn ViewHandler>>;
28type Models = HashMap<Entity, HashMap<TypeId, Box<dyn ModelData>>>;
29
30pub struct EventContext<'a> {
63 pub(crate) current: Entity,
64 pub(crate) captured: &'a mut Entity,
65 pub(crate) focused: &'a mut Entity,
66 pub(crate) hovered: &'a Entity,
67 pub(crate) triggered: &'a mut Entity,
68 pub(crate) style: &'a mut Style,
69 pub(crate) entity_identifiers: &'a HashMap<String, Entity>,
70 pub cache: &'a mut CachedData,
71 pub(crate) tree: &'a Tree<Entity>,
72 pub(crate) models: &'a mut Models,
73 pub(crate) views: &'a mut Views,
74 pub(crate) listeners:
75 &'a mut HashMap<Entity, Box<dyn Fn(&mut dyn ViewHandler, &mut EventContext, &mut Event)>>,
76 pub(crate) resource_manager: &'a mut ResourceManager,
77 pub(crate) text_context: &'a mut TextContext,
78 pub(crate) modifiers: &'a Modifiers,
79 pub(crate) mouse: &'a MouseState<Entity>,
80 pub(crate) event_queue: &'a mut VecDeque<Event>,
81 pub(crate) event_schedule: &'a mut BinaryHeap<TimedEvent>,
82 pub(crate) next_event_id: &'a mut usize,
83 pub(crate) timers: &'a mut Vec<TimerState>,
84 pub(crate) running_timers: &'a mut BinaryHeap<TimerState>,
85 cursor_icon_locked: &'a mut bool,
86 #[cfg(feature = "clipboard")]
87 clipboard: &'a mut Box<dyn ClipboardProvider>,
88 pub(crate) event_proxy: &'a mut Option<Box<dyn crate::context::EventProxy>>,
89 pub(crate) ignore_default_theme: &'a bool,
90 pub(crate) drop_data: &'a mut Option<DropData>,
91 pub windows: &'a mut HashMap<Entity, WindowState>,
92}
93
94macro_rules! get_length_property {
95 (
96 $(#[$meta:meta])*
97 $name:ident
98 ) => {
99 $(#[$meta])*
100 pub fn $name(&self) -> f32 {
101 if let Some(length) = self.style.$name.get(self.current) {
102 let bounds = self.bounds();
103
104 let px = length.to_pixels(bounds.w.min(bounds.h), self.scale_factor());
105 return px.round();
106 }
107
108 0.0
109 }
110 };
111}
112
113impl<'a> EventContext<'a> {
114 pub fn new(cx: &'a mut Context) -> Self {
116 Self {
117 current: cx.current,
118 captured: &mut cx.captured,
119 focused: &mut cx.focused,
120 hovered: &cx.hovered,
121 triggered: &mut cx.triggered,
122 entity_identifiers: &cx.entity_identifiers,
123 style: &mut cx.style,
124 cache: &mut cx.cache,
125 tree: &cx.tree,
126 models: &mut cx.models,
127 views: &mut cx.views,
128 listeners: &mut cx.listeners,
129 resource_manager: &mut cx.resource_manager,
130 text_context: &mut cx.text_context,
131 modifiers: &cx.modifiers,
132 mouse: &cx.mouse,
133 event_queue: &mut cx.event_queue,
134 event_schedule: &mut cx.event_schedule,
135 next_event_id: &mut cx.next_event_id,
136 timers: &mut cx.timers,
137 running_timers: &mut cx.running_timers,
138 cursor_icon_locked: &mut cx.cursor_icon_locked,
139 #[cfg(feature = "clipboard")]
140 clipboard: &mut cx.clipboard,
141 event_proxy: &mut cx.event_proxy,
142 ignore_default_theme: &cx.ignore_default_theme,
143 drop_data: &mut cx.drop_data,
144 windows: &mut cx.windows,
145 }
146 }
147
148 pub fn new_with_current(cx: &'a mut Context, current: Entity) -> Self {
150 Self {
151 current,
152 captured: &mut cx.captured,
153 focused: &mut cx.focused,
154 hovered: &cx.hovered,
155 triggered: &mut cx.triggered,
156 entity_identifiers: &cx.entity_identifiers,
157 style: &mut cx.style,
158 cache: &mut cx.cache,
159 tree: &cx.tree,
160 models: &mut cx.models,
161 views: &mut cx.views,
162 listeners: &mut cx.listeners,
163 resource_manager: &mut cx.resource_manager,
164 text_context: &mut cx.text_context,
165 modifiers: &cx.modifiers,
166 mouse: &cx.mouse,
167 event_queue: &mut cx.event_queue,
168 event_schedule: &mut cx.event_schedule,
169 next_event_id: &mut cx.next_event_id,
170 timers: &mut cx.timers,
171 running_timers: &mut cx.running_timers,
172 cursor_icon_locked: &mut cx.cursor_icon_locked,
173 #[cfg(feature = "clipboard")]
174 clipboard: &mut cx.clipboard,
175 event_proxy: &mut cx.event_proxy,
176 ignore_default_theme: &cx.ignore_default_theme,
177 drop_data: &mut cx.drop_data,
178 windows: &mut cx.windows,
179 }
180 }
181
182 pub fn get_view<V: View>(&self) -> Option<&V> {
184 self.views.get(&self.current).and_then(|view| view.downcast_ref::<V>())
185 }
186
187 pub fn get_view_with<V: View>(&self, entity: Entity) -> Option<&V> {
189 self.views.get(&entity).and_then(|view| view.downcast_ref::<V>())
190 }
191
192 pub fn close_window(&mut self) {
193 if let Some(state) = self.windows.get_mut(&self.current) {
194 state.should_close = true;
195 }
196 }
197
198 pub fn resolve_entity_identifier(&self, id: &str) -> Option<Entity> {
200 self.entity_identifiers.get(id).cloned()
201 }
202
203 pub fn get_entity_by_element_id(&self, element: &str) -> Option<Entity> {
205 let descendants = LayoutTreeIterator::subtree(self.tree, self.current);
206 for descendant in descendants {
207 if let Some(id) = self.views.get(&descendant).and_then(|view| view.element()) {
208 if id == element {
209 return Some(descendant);
210 }
211 }
212 }
213
214 None
215 }
216
217 pub fn get_entities_by_class(&self, class: &str) -> Vec<Entity> {
219 let mut entities = Vec::new();
220 let descendants = LayoutTreeIterator::subtree(self.tree, self.current);
221 for descendant in descendants {
222 if let Some(class_list) = self.style.classes.get(descendant) {
223 if class_list.contains(class) {
224 entities.push(descendant);
225 }
226 }
227 }
228
229 entities
230 }
231
232 pub fn current(&self) -> Entity {
234 self.current
235 }
236
237 pub fn modifiers(&self) -> &Modifiers {
239 self.modifiers
240 }
241
242 pub fn mouse(&self) -> &MouseState<Entity> {
244 self.mouse
245 }
246
247 pub fn nth_child(&self, n: usize) -> Option<Entity> {
248 self.tree.get_child(self.current, n)
249 }
250
251 pub fn last_child(&self) -> Option<Entity> {
252 self.tree.get_last_child(self.current).copied()
253 }
254
255 pub fn with_current<T>(&mut self, entity: Entity, f: impl FnOnce(&mut Self) -> T) -> T {
256 let prev = self.current();
257 self.current = entity;
258 let ret = (f)(self);
259 self.current = prev;
260 ret
261 }
262
263 pub fn has_drop_data(&self) -> bool {
265 self.drop_data.is_some()
266 }
267
268 pub fn bounds(&self) -> BoundingBox {
270 self.cache.get_bounds(self.current)
271 }
272
273 pub fn scale_factor(&self) -> f32 {
279 self.style.dpi_factor as f32
280 }
281
282 pub fn logical_to_physical(&self, logical: f32) -> f32 {
284 self.style.logical_to_physical(logical)
285 }
286
287 pub fn physical_to_logical(&self, physical: f32) -> f32 {
289 self.style.physical_to_logical(physical)
290 }
291
292 pub fn clip_region(&self) -> BoundingBox {
294 let bounds = self.bounds();
295 let overflowx = self.style.overflowx.get(self.current).copied().unwrap_or_default();
296 let overflowy = self.style.overflowy.get(self.current).copied().unwrap_or_default();
297
298 let scale = self.scale_factor();
301
302 let clip_bounds = self
303 .style
304 .clip_path
305 .get(self.current)
306 .map(|clip| match clip {
307 ClipPath::Auto => bounds,
308 ClipPath::Shape(rect) => bounds.shrink_sides(
309 rect.3.to_pixels(bounds.w, scale),
310 rect.0.to_pixels(bounds.h, scale),
311 rect.1.to_pixels(bounds.w, scale),
312 rect.2.to_pixels(bounds.h, scale),
313 ),
314 })
315 .unwrap_or(bounds);
316
317 let root_bounds: BoundingBox =
318 BoundingBox { x: -f32::MAX / 2.0, y: -f32::MAX / 2.0, w: f32::MAX, h: f32::MAX };
319
320 match (overflowx, overflowy) {
321 (Overflow::Visible, Overflow::Visible) => root_bounds,
322 (Overflow::Hidden, Overflow::Visible) => {
323 let left = clip_bounds.left();
324 let right = clip_bounds.right();
325 let top = root_bounds.top();
326 let bottom = root_bounds.bottom();
327 BoundingBox::from_min_max(left, top, right, bottom)
328 }
329 (Overflow::Visible, Overflow::Hidden) => {
330 let left = root_bounds.left();
331 let right = root_bounds.right();
332 let top = clip_bounds.top();
333 let bottom = clip_bounds.bottom();
334 BoundingBox::from_min_max(left, top, right, bottom)
335 }
336 (Overflow::Hidden, Overflow::Hidden) => clip_bounds,
337 }
338 }
339
340 pub fn transform(&self) -> Matrix {
342 let bounds = self.bounds();
343 let scale_factor = self.scale_factor();
344
345 let mut origin = self
347 .style
348 .transform_origin
349 .get(self.current)
350 .map(|transform_origin| {
351 let mut origin = Matrix::translate(bounds.top_left());
352 let offset = transform_origin.as_transform(bounds, scale_factor);
353 origin = offset * origin;
354 origin
355 })
356 .unwrap_or(Matrix::translate(bounds.center()));
357 let mut transform = origin;
359 origin = origin.invert().unwrap();
360
361 if let Some(translate) = self.style.translate.get(self.current) {
363 transform = transform * translate.as_transform(bounds, scale_factor);
364 }
365
366 if let Some(rotate) = self.style.rotate.get(self.current) {
368 transform = transform * rotate.as_transform(bounds, scale_factor);
369 }
370
371 if let Some(scale) = self.style.scale.get(self.current) {
373 transform = transform * scale.as_transform(bounds, scale_factor);
374 }
375
376 if let Some(transforms) = self.style.transform.get(self.current) {
378 if let Some(animation_state) = self.style.transform.get_active_animation(self.current) {
382 if let Some(start) = animation_state.keyframes.first() {
383 if let Some(end) = animation_state.keyframes.last() {
384 let start_transform = start.value.as_transform(bounds, scale_factor);
385 let end_transform = end.value.as_transform(bounds, scale_factor);
386 let t = animation_state.t;
387 let animated_transform =
388 Matrix::interpolate(&start_transform, &end_transform, t);
389 transform = transform * animated_transform;
390 }
391 }
392 } else {
393 transform = transform * transforms.as_transform(bounds, scale_factor);
394 }
395 }
396
397 transform = transform * origin;
398
399 transform
400 }
401
402 pub fn play_animation(&mut self, anim_id: impl AnimId, duration: Duration, delay: Duration) {
404 if let Some(animation_id) = anim_id.get(self) {
405 self.style.enqueue_animation(self.current, animation_id, duration, delay);
406 }
407 }
408
409 pub fn play_animation_for(
411 &mut self,
412 anim_id: impl AnimId,
413 target: &str,
414 duration: Duration,
415 delay: Duration,
416 ) {
417 if let Some(target_entity) = self.resolve_entity_identifier(target) {
418 if let Some(animation_id) = anim_id.get(self) {
419 self.style.enqueue_animation(target_entity, animation_id, duration, delay)
420 }
421 }
422 }
423
424 pub fn is_animating(&self, anim_id: impl AnimId) -> bool {
426 if let Some(animation_id) = anim_id.get(self) {
427 return self.style.is_animating(self.current, animation_id);
428 }
429
430 false
431 }
432
433 pub fn add_listener<F, W>(&mut self, listener: F)
439 where
440 W: View,
441 F: 'static + Fn(&mut W, &mut EventContext, &mut Event),
442 {
443 self.listeners.insert(
444 self.current,
445 Box::new(move |event_handler, context, event| {
446 if let Some(widget) = event_handler.downcast_mut::<W>() {
447 (listener)(widget, context, event);
448 }
449 }),
450 );
451 }
452
453 pub fn set_language(&mut self, lang: LanguageIdentifier) {
455 if let Some(mut models) = self.models.remove(&Entity::root()) {
456 if let Some(model) = models.get_mut(&TypeId::of::<Environment>()) {
457 model.event(self, &mut Event::new(EnvironmentEvent::SetLocale(lang)));
458 }
459
460 self.models.insert(Entity::root(), models);
461 }
462 }
463
464 pub fn add_image_encoded(&mut self, path: &str, data: &[u8], policy: ImageRetentionPolicy) {
465 let id = if let Some(image_id) = self.resource_manager.image_ids.get(path) {
466 *image_id
467 } else {
468 let id = self.resource_manager.image_id_manager.create();
469 self.resource_manager.image_ids.insert(path.to_owned(), id);
470 id
471 };
472
473 if let Some(image) = skia_safe::Image::from_encoded(skia_safe::Data::new_copy(data)) {
474 match self.resource_manager.images.entry(id) {
475 Entry::Occupied(mut occ) => {
476 occ.get_mut().image = ImageOrSvg::Image(image);
477 occ.get_mut().dirty = true;
478 occ.get_mut().retention_policy = policy;
479 }
480 Entry::Vacant(vac) => {
481 vac.insert(StoredImage {
482 image: ImageOrSvg::Image(image),
483 retention_policy: policy,
484 used: true,
485 dirty: false,
486 observers: HashSet::new(),
487 });
488 }
489 }
490 self.style.needs_relayout();
491 }
492 }
493
494 pub fn capture(&mut self) {
496 *self.captured = self.current;
497 }
498
499 pub fn release(&mut self) {
501 if self.current == *self.captured {
502 *self.captured = Entity::null();
503 }
504 }
505
506 fn set_focus_pseudo_classes(&mut self, focused: Entity, enabled: bool, focus_visible: bool) {
508 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(focused) {
509 pseudo_classes.set(PseudoClassFlags::FOCUS, enabled);
510 if !enabled || focus_visible {
511 pseudo_classes.set(PseudoClassFlags::FOCUS_VISIBLE, enabled);
512 }
513 }
514
515 for ancestor in focused.parent_iter(self.tree) {
516 let entity = ancestor;
517 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(entity) {
518 pseudo_classes.set(PseudoClassFlags::FOCUS_WITHIN, enabled);
519 }
520 }
521 }
522
523 pub fn focus_with_visibility(&mut self, focus_visible: bool) {
525 let old_focus = self.focused();
526 let new_focus = self.current();
527 self.set_focus_pseudo_classes(old_focus, false, focus_visible);
528 if self.current() != self.focused() {
529 self.emit_to(old_focus, WindowEvent::FocusOut);
530 self.emit_to(new_focus, WindowEvent::FocusIn);
531 *self.focused = self.current();
532 }
533 self.set_focus_pseudo_classes(new_focus, true, focus_visible);
534
535 self.emit_custom(Event::new(WindowEvent::FocusVisibility(focus_visible)).target(old_focus));
536 self.emit_custom(Event::new(WindowEvent::FocusVisibility(focus_visible)).target(new_focus));
537
538 self.needs_restyle();
539 }
540
541 pub fn focus(&mut self) {
545 let focused = self.focused();
546 let old_focus_visible = self
547 .style
548 .pseudo_classes
549 .get_mut(focused)
550 .filter(|class| class.contains(PseudoClassFlags::FOCUS_VISIBLE))
551 .is_some();
552 self.focus_with_visibility(old_focus_visible)
553 }
554
555 pub fn focus_next(&mut self) {
557 let lock_focus_to = self.tree.lock_focus_within(*self.focused);
558 let next_focused = if let Some(next_focused) =
559 focus_forward(self.tree, self.style, *self.focused, lock_focus_to)
560 {
561 next_focused
562 } else {
563 TreeIterator::full(self.tree)
564 .find(|node| is_navigatable(self.tree, self.style, *node, lock_focus_to))
565 .unwrap_or(Entity::root())
566 };
567
568 if next_focused != *self.focused {
569 self.event_queue.push_back(
570 Event::new(WindowEvent::FocusOut).target(*self.focused).origin(Entity::root()),
571 );
572 self.event_queue.push_back(
573 Event::new(WindowEvent::FocusIn).target(next_focused).origin(Entity::root()),
574 );
575
576 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(*self.triggered) {
577 pseudo_classes.set(PseudoClassFlags::ACTIVE, false);
578 }
579 self.needs_restyle();
580 *self.triggered = Entity::null();
581 }
582 }
583
584 pub fn focus_prev(&mut self) {
586 let lock_focus_to = self.tree.lock_focus_within(*self.focused);
587 let prev_focused = if let Some(prev_focused) =
588 focus_backward(self.tree, self.style, *self.focused, lock_focus_to)
589 {
590 prev_focused
591 } else {
592 TreeIterator::full(self.tree)
593 .filter(|node| is_navigatable(self.tree, self.style, *node, lock_focus_to))
594 .next_back()
595 .unwrap_or(Entity::root())
596 };
597
598 if prev_focused != *self.focused {
599 self.event_queue.push_back(
600 Event::new(WindowEvent::FocusOut).target(*self.focused).origin(Entity::root()),
601 );
602 self.event_queue.push_back(
603 Event::new(WindowEvent::FocusIn).target(prev_focused).origin(Entity::root()),
604 );
605
606 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(*self.triggered) {
607 pseudo_classes.set(PseudoClassFlags::ACTIVE, false);
608 }
609 self.needs_restyle();
610 *self.triggered = Entity::null();
611 }
612 }
613
614 pub fn hovered(&self) -> Entity {
616 *self.hovered
617 }
618
619 pub fn focused(&self) -> Entity {
621 *self.focused
622 }
623
624 pub fn is_hovered(&self) -> bool {
628 self.hovered() == self.current
629 }
630
631 pub fn is_active(&self) -> bool {
633 if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
634 pseudo_classes.contains(PseudoClassFlags::ACTIVE)
635 } else {
636 false
637 }
638 }
639
640 pub fn is_over(&self) -> bool {
642 if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
643 pseudo_classes.contains(PseudoClassFlags::OVER)
644 } else {
645 false
646 }
647 }
648
649 pub fn is_focused(&self) -> bool {
651 self.focused() == self.current
652 }
653
654 pub fn is_draggable(&self) -> bool {
656 self.style
657 .abilities
658 .get(self.current)
659 .map(|abilities| abilities.contains(Abilities::DRAGGABLE))
660 .unwrap_or_default()
661 }
662
663 pub fn is_disabled(&self) -> bool {
665 self.style.disabled.get(self.current()).cloned().unwrap_or_default()
666 }
667
668 pub fn is_checked(&self) -> bool {
670 if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
671 pseudo_classes.contains(PseudoClassFlags::CHECKED)
672 } else {
673 false
674 }
675 }
676
677 pub fn is_read_only(&self) -> bool {
679 if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
680 pseudo_classes.contains(PseudoClassFlags::READ_ONLY)
681 } else {
682 false
683 }
684 }
685
686 pub fn lock_cursor_icon(&mut self) {
690 *self.cursor_icon_locked = true;
691 }
692
693 pub fn unlock_cursor_icon(&mut self) {
695 *self.cursor_icon_locked = false;
696 let hovered = *self.hovered;
697 let cursor = self.style.cursor.get(hovered).cloned().unwrap_or_default();
698 self.emit(WindowEvent::SetCursor(cursor));
699 }
700
701 pub fn is_cursor_icon_locked(&self) -> bool {
703 *self.cursor_icon_locked
704 }
705
706 pub fn set_drop_data(&mut self, data: impl Into<DropData>) {
708 *self.drop_data = Some(data.into())
709 }
710
711 #[cfg(feature = "clipboard")]
715 pub fn get_clipboard(&mut self) -> Result<String, Box<dyn Error + Send + Sync + 'static>> {
716 self.clipboard.get_contents()
717 }
718
719 #[cfg(feature = "clipboard")]
723 pub fn set_clipboard(
724 &mut self,
725 text: String,
726 ) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
727 self.clipboard.set_contents(text)
728 }
729
730 pub fn toggle_class(&mut self, class_name: &str, applied: bool) {
740 let current = self.current();
741 if let Some(class_list) = self.style.classes.get_mut(current) {
742 if applied {
743 class_list.insert(class_name.to_string());
744 } else {
745 class_list.remove(class_name);
746 }
747 } else if applied {
748 let mut class_list = HashSet::new();
749 class_list.insert(class_name.to_string());
750 self.style.classes.insert(current, class_list);
751 }
752
753 self.needs_restyle();
754 }
755
756 pub fn environment(&self) -> &Environment {
758 self.data::<Environment>().unwrap()
759 }
760
761 pub fn set_theme_mode(&mut self, theme_mode: ThemeMode) {
763 if !self.ignore_default_theme {
764 match theme_mode {
765 ThemeMode::LightMode => {
766 self.resource_manager.themes[2] = String::from(LIGHT_THEME);
767 }
768
769 ThemeMode::DarkMode => {
770 self.resource_manager.themes[2] = String::from(DARK_THEME);
771 }
772 }
773 }
774 }
775
776 pub fn needs_redraw(&mut self) {
778 let parent_window = self.tree.get_parent_window(self.current).unwrap_or(Entity::root());
779 if let Some(window_state) = self.windows.get_mut(&parent_window) {
780 window_state.redraw_list.insert(self.current);
781 }
782 }
783
784 pub fn needs_relayout(&mut self) {
786 self.style.needs_relayout();
787 self.needs_redraw();
788 }
789
790 pub fn needs_restyle(&mut self) {
792 self.style.restyle.insert(self.current).unwrap();
793 let iter = if let Some(parent) = self.tree.get_layout_parent(self.current) {
794 LayoutTreeIterator::subtree(self.tree, parent)
795 } else {
796 LayoutTreeIterator::subtree(self.tree, self.current)
797 };
798
799 for descendant in iter {
800 self.style.restyle.insert(descendant).unwrap();
801 }
802 self.style.needs_restyle(self.current);
803 }
804
805 pub fn reload_styles(&mut self) -> Result<(), std::io::Error> {
807 if self.resource_manager.themes.is_empty() && self.resource_manager.styles.is_empty() {
808 return Ok(());
809 }
810
811 self.style.remove_rules();
812
813 self.style.clear_style_rules();
814
815 let mut overall_theme = String::new();
816
817 for theme in self.resource_manager.themes.iter() {
819 overall_theme += theme;
820 }
821
822 for style_string in self.resource_manager.styles.iter().flat_map(|style| style.get_style())
823 {
824 overall_theme += &style_string;
825 }
826
827 self.style.parse_theme(&overall_theme);
828
829 for entity in self.tree.into_iter() {
830 self.style.needs_restyle(entity);
831 self.style.needs_relayout();
832 self.style.needs_text_update(entity);
834 }
835
836 Ok(())
837 }
838
839 pub fn spawn<F>(&self, target: F)
841 where
842 F: 'static + Send + FnOnce(&mut ContextProxy),
843 {
844 let mut cxp = ContextProxy {
845 current: self.current,
846 event_proxy: self.event_proxy.as_ref().map(|p| p.make_clone()),
847 };
848
849 std::thread::spawn(move || target(&mut cxp));
850 }
851
852 pub fn get_proxy(&self) -> ContextProxy {
854 ContextProxy {
855 current: self.current,
856 event_proxy: self.event_proxy.as_ref().map(|p| p.make_clone()),
857 }
858 }
859
860 pub fn modify<V: View>(&mut self, f: impl FnOnce(&mut V)) {
861 if let Some(view) = self
862 .views
863 .get_mut(&self.current)
864 .and_then(|view_handler| view_handler.downcast_mut::<V>())
865 {
866 (f)(view);
867 }
868 }
869
870 pub fn background_color(&mut self) -> Color {
878 self.style.background_color.get(self.current).copied().unwrap_or_default()
879 }
880
881 pub fn set_id(&mut self, id: &str) {
884 self.style.ids.insert(self.current, id.to_string())
885 }
886
887 pub fn set_hover(&mut self, flag: bool) {
899 let current = self.current();
900 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
901 pseudo_classes.set(PseudoClassFlags::HOVER, flag);
902 }
903
904 self.needs_restyle();
905 }
906
907 pub fn set_active(&mut self, active: bool) {
916 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(self.current) {
917 pseudo_classes.set(PseudoClassFlags::ACTIVE, active);
918 }
919
920 self.needs_restyle();
921 }
922
923 pub fn set_read_only(&mut self, flag: bool) {
924 let current = self.current();
925 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
926 pseudo_classes.set(PseudoClassFlags::READ_ONLY, flag);
927 }
928
929 self.needs_restyle();
930 }
931
932 pub fn set_read_write(&mut self, flag: bool) {
933 let current = self.current();
934 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
935 pseudo_classes.set(PseudoClassFlags::READ_WRITE, flag);
936 }
937
938 self.needs_restyle();
939 }
940
941 pub fn set_checked(&mut self, flag: bool) {
950 let current = self.current();
951 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
952 pseudo_classes.set(PseudoClassFlags::CHECKED, flag);
953 }
954
955 self.needs_restyle();
956 }
957
958 pub fn set_valid(&mut self, flag: bool) {
967 let current = self.current();
968 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
969 pseudo_classes.set(PseudoClassFlags::VALID, flag);
970 pseudo_classes.set(PseudoClassFlags::INVALID, !flag);
971 }
972
973 self.needs_restyle();
974 }
975
976 pub fn set_placeholder_shown(&mut self, flag: bool) {
977 let current = self.current();
978 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
979 pseudo_classes.set(PseudoClassFlags::PLACEHOLDER_SHOWN, flag);
980 }
981
982 self.needs_restyle();
983 }
984
985 pub fn is_valid(&self) -> bool {
987 self.style
988 .pseudo_classes
989 .get(self.current)
990 .map(|pseudo_classes| pseudo_classes.contains(PseudoClassFlags::VALID))
991 .unwrap_or_default()
992 }
993
994 pub fn is_placeholder_shown(&self) -> bool {
995 self.style
996 .pseudo_classes
997 .get(self.current)
998 .map(|pseudo_classes| pseudo_classes.contains(PseudoClassFlags::PLACEHOLDER_SHOWN))
999 .unwrap_or_default()
1000 }
1001
1002 pub fn set_name(&mut self, name: &str) {
1006 self.style.name.insert(self.current, name.to_string());
1007 }
1008
1009 pub fn set_role(&mut self, role: Role) {
1011 self.style.role.insert(self.current, role);
1012 }
1013
1014 pub fn set_live(&mut self, live: Live) {
1021 self.style.live.insert(self.current, live);
1022 }
1023
1024 pub fn labelled_by(&mut self, id: &str) {
1026 if let Some(entity) = self.resolve_entity_identifier(id) {
1027 self.style.labelled_by.insert(self.current, entity);
1028 }
1029 }
1030
1031 pub fn set_hidden(&mut self, hidden: bool) {
1033 self.style.hidden.insert(self.current, hidden)
1034 }
1035
1036 pub fn text_value(&mut self, text: &str) {
1038 self.style.text_value.insert(self.current, text.to_string());
1039 }
1040
1041 pub fn numeric_value(&mut self, value: f64) {
1043 self.style.numeric_value.insert(self.current, value);
1044 }
1045
1046 pub fn set_display(&mut self, display: Display) {
1052 self.style.display.insert(self.current, display);
1053 }
1054
1055 pub fn set_visibility(&mut self, visibility: Visibility) {
1059 self.style.visibility.insert(self.current, visibility);
1060 }
1061
1062 pub fn set_opacity(&mut self, opacity: f32) {
1066 self.style.opacity.insert(self.current, Opacity(opacity));
1067 }
1068
1069 pub fn set_z_index(&mut self, z_index: i32) {
1071 self.style.z_index.insert(self.current, z_index);
1072 }
1073
1074 pub fn set_clip_path(&mut self, clip_path: ClipPath) {
1076 self.style.clip_path.insert(self.current, clip_path);
1077 }
1078
1079 pub fn set_overflowx(&mut self, overflowx: impl Into<Overflow>) {
1081 self.style.overflowx.insert(self.current, overflowx.into());
1082 }
1083
1084 pub fn set_overflowy(&mut self, overflowy: impl Into<Overflow>) {
1086 self.style.overflowy.insert(self.current, overflowy.into());
1087 }
1088
1089 pub fn set_transform(&mut self, transform: impl Into<Vec<Transform>>) {
1093 self.style.transform.insert(self.current, transform.into());
1094 }
1095
1096 pub fn set_transform_origin(&mut self, transform_origin: Translate) {
1098 self.style.transform_origin.insert(self.current, transform_origin);
1099 }
1100
1101 pub fn set_translate(&mut self, translate: impl Into<Translate>) {
1103 self.style.translate.insert(self.current, translate.into());
1104 }
1105
1106 pub fn set_rotate(&mut self, angle: impl Into<Angle>) {
1108 self.style.rotate.insert(self.current, angle.into());
1109 }
1110
1111 pub fn set_scale(&mut self, scale: impl Into<Scale>) {
1113 self.style.scale.insert(self.current, scale.into());
1114 }
1115
1116 pub fn set_backdrop_filter(&mut self, filter: Filter) {
1120 self.style.backdrop_filter.insert(self.current, filter);
1121 }
1122
1123 pub fn set_background_color(&mut self, background_color: Color) {
1130 self.style.background_color.insert(self.current, background_color);
1131 self.needs_redraw();
1132 }
1133
1134 pub fn set_width(&mut self, width: Units) {
1137 self.style.width.insert(self.current, width);
1138 self.needs_relayout();
1139 self.needs_redraw();
1140 }
1141
1142 pub fn set_height(&mut self, height: Units) {
1143 self.style.height.insert(self.current, height);
1144 self.needs_relayout();
1145 self.needs_redraw();
1146 }
1147
1148 pub fn set_max_height(&mut self, height: Units) {
1149 self.style.max_height.insert(self.current, height);
1150 self.needs_relayout();
1151 self.needs_redraw();
1152 }
1153
1154 pub fn set_left(&mut self, left: Units) {
1157 self.style.left.insert(self.current, left);
1158 self.needs_relayout();
1159 self.needs_redraw();
1160 }
1161
1162 pub fn set_top(&mut self, top: Units) {
1163 self.style.top.insert(self.current, top);
1164 self.needs_relayout();
1165 self.needs_redraw();
1166 }
1167
1168 pub fn set_right(&mut self, right: Units) {
1169 self.style.right.insert(self.current, right);
1170 self.needs_relayout();
1171 self.needs_redraw();
1172 }
1173
1174 pub fn set_bottom(&mut self, bottom: Units) {
1175 self.style.bottom.insert(self.current, bottom);
1176 self.needs_relayout();
1177 self.needs_redraw();
1178 }
1179
1180 pub fn set_padding_left(&mut self, padding_left: Units) {
1183 self.style.padding_left.insert(self.current, padding_left);
1184 self.needs_relayout();
1185 self.needs_redraw();
1186 }
1187
1188 pub fn set_padding_top(&mut self, padding_top: Units) {
1189 self.style.padding_top.insert(self.current, padding_top);
1190 self.needs_relayout();
1191 self.needs_redraw();
1192 }
1193
1194 pub fn set_padding_right(&mut self, padding_right: Units) {
1195 self.style.padding_right.insert(self.current, padding_right);
1196 self.needs_relayout();
1197 self.needs_redraw();
1198 }
1199
1200 pub fn set_padding_bottom(&mut self, padding_bottom: Units) {
1201 self.style.padding_bottom.insert(self.current, padding_bottom);
1202 self.needs_relayout();
1203 self.needs_redraw();
1204 }
1205
1206 pub fn set_text(&mut self, text: &str) {
1210 self.style.text.insert(self.current, text.to_owned());
1211 self.style.needs_text_update(self.current);
1212 self.needs_relayout();
1213 self.needs_redraw();
1214 }
1215
1216 pub fn set_pointer_events(&mut self, pointer_events: impl Into<PointerEvents>) {
1217 self.style.pointer_events.insert(self.current, pointer_events.into());
1218 }
1219
1220 get_length_property!(
1222 border_width
1224 );
1225
1226 pub fn font_size(&self) -> f32 {
1228 self.logical_to_physical(
1229 self.style
1230 .font_size
1231 .get(self.current)
1232 .cloned()
1233 .map(|f| f.0.to_px().unwrap())
1234 .unwrap_or(16.0),
1235 )
1236 }
1237
1238 pub fn add_timer(
1269 &mut self,
1270 interval: Duration,
1271 duration: Option<Duration>,
1272 callback: impl Fn(&mut EventContext, TimerAction) + 'static,
1273 ) -> Timer {
1274 let id = Timer(self.timers.len());
1275 self.timers.push(TimerState {
1276 entity: Entity::root(),
1277 id,
1278 time: Instant::now(),
1279 interval,
1280 duration,
1281 start_time: Instant::now(),
1282 callback: Rc::new(callback),
1283 ticking: false,
1284 stopping: false,
1285 });
1286
1287 id
1288 }
1289
1290 pub fn start_timer(&mut self, timer: Timer) {
1294 let current = self.current;
1295 if !self.timer_is_running(timer) {
1296 let timer_state = self.timers[timer.0].clone();
1297 self.running_timers.push(timer_state);
1299 }
1300
1301 self.modify_timer(timer, |timer_state| {
1302 let now = Instant::now();
1303 timer_state.start_time = now;
1304 timer_state.time = now;
1305 timer_state.entity = current;
1306 timer_state.ticking = false;
1307 timer_state.stopping = false;
1308 });
1309 }
1310
1311 pub fn modify_timer(&mut self, timer: Timer, timer_function: impl Fn(&mut TimerState)) {
1313 while let Some(next_timer_state) = self.running_timers.peek() {
1314 if next_timer_state.id == timer {
1315 let mut timer_state = self.running_timers.pop().unwrap();
1316
1317 (timer_function)(&mut timer_state);
1318
1319 self.running_timers.push(timer_state);
1320
1321 return;
1322 }
1323 }
1324
1325 for pending_timer in self.timers.iter_mut() {
1326 if pending_timer.id == timer {
1327 (timer_function)(pending_timer);
1328 }
1329 }
1330 }
1331
1332 pub fn query_timer<T>(
1333 &mut self,
1334 timer: Timer,
1335 timer_function: impl Fn(&TimerState) -> T,
1336 ) -> Option<T> {
1337 while let Some(next_timer_state) = self.running_timers.peek() {
1338 if next_timer_state.id == timer {
1339 let timer_state = self.running_timers.pop().unwrap();
1340
1341 let t = (timer_function)(&timer_state);
1342
1343 self.running_timers.push(timer_state);
1344
1345 return Some(t);
1346 }
1347 }
1348
1349 for pending_timer in self.timers.iter() {
1350 if pending_timer.id == timer {
1351 return Some(timer_function(pending_timer));
1352 }
1353 }
1354
1355 None
1356 }
1357
1358 pub fn timer_is_running(&mut self, timer: Timer) -> bool {
1360 for timer_state in self.running_timers.iter() {
1361 if timer_state.id == timer {
1362 return true;
1363 }
1364 }
1365
1366 false
1367 }
1368
1369 pub fn stop_timer(&mut self, timer: Timer) {
1373 let mut running_timers = self.running_timers.clone();
1374
1375 for timer_state in running_timers.iter() {
1376 if timer_state.id == timer {
1377 self.with_current(timer_state.entity, |cx| {
1378 (timer_state.callback)(cx, TimerAction::Stop);
1379 });
1380 }
1381 }
1382
1383 *self.running_timers =
1384 running_timers.drain().filter(|timer_state| timer_state.id != timer).collect();
1385 }
1386}
1387
1388impl DataContext for EventContext<'_> {
1389 fn data<T: 'static>(&self) -> Option<&T> {
1390 if let Some(t) = <dyn Any>::downcast_ref::<T>(&()) {
1392 return Some(t);
1393 }
1394
1395 for entity in self.current.parent_iter(self.tree) {
1396 if let Some(models) = self.models.get(&entity) {
1398 if let Some(model) = models.get(&TypeId::of::<T>()) {
1399 return model.downcast_ref::<T>();
1400 }
1401 }
1402
1403 if let Some(view_handler) = self.views.get(&entity) {
1405 if let Some(data) = view_handler.downcast_ref::<T>() {
1406 return Some(data);
1407 }
1408 }
1409 }
1410
1411 None
1412 }
1413
1414 fn localization_context(&self) -> Option<LocalizationContext<'_>> {
1415 Some(LocalizationContext::from_event_context(self))
1416 }
1417}
1418
1419impl EmitContext for EventContext<'_> {
1420 fn emit<M: Any + Send>(&mut self, message: M) {
1421 self.event_queue.push_back(
1422 Event::new(message)
1423 .target(self.current)
1424 .origin(self.current)
1425 .propagate(Propagation::Up),
1426 );
1427 }
1428
1429 fn emit_to<M: Any + Send>(&mut self, target: Entity, message: M) {
1430 self.event_queue.push_back(
1431 Event::new(message).target(target).origin(self.current).propagate(Propagation::Direct),
1432 );
1433 }
1434
1435 fn emit_custom(&mut self, event: Event) {
1436 self.event_queue.push_back(event);
1437 }
1438
1439 fn schedule_emit<M: Any + Send>(&mut self, message: M, at: Instant) -> TimedEventHandle {
1440 self.schedule_emit_custom(
1441 Event::new(message)
1442 .target(self.current)
1443 .origin(self.current)
1444 .propagate(Propagation::Up),
1445 at,
1446 )
1447 }
1448 fn schedule_emit_to<M: Any + Send>(
1449 &mut self,
1450 target: Entity,
1451 message: M,
1452 at: Instant,
1453 ) -> TimedEventHandle {
1454 self.schedule_emit_custom(
1455 Event::new(message).target(target).origin(self.current).propagate(Propagation::Direct),
1456 at,
1457 )
1458 }
1459 fn schedule_emit_custom(&mut self, event: Event, at: Instant) -> TimedEventHandle {
1460 let handle = TimedEventHandle(*self.next_event_id);
1461 self.event_schedule.push(TimedEvent { event, time: at, ident: handle });
1462 *self.next_event_id += 1;
1463 handle
1464 }
1465 fn cancel_scheduled(&mut self, handle: TimedEventHandle) {
1466 *self.event_schedule =
1467 self.event_schedule.drain().filter(|item| item.ident != handle).collect();
1468 }
1469}
1470
1471pub trait TreeProps {
1473 fn parent(&self) -> Entity;
1475 fn first_child(&self) -> Entity;
1477 fn parent_window(&self) -> Entity;
1479}
1480
1481impl TreeProps for EventContext<'_> {
1482 fn parent(&self) -> Entity {
1483 self.tree.get_layout_parent(self.current).unwrap()
1484 }
1485
1486 fn first_child(&self) -> Entity {
1487 self.tree.get_layout_first_child(self.current).unwrap()
1488 }
1489
1490 fn parent_window(&self) -> Entity {
1491 self.tree.get_parent_window(self.current).unwrap_or(Entity::root())
1492 }
1493}