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;
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, Rect};
20
21use crate::text::TextContext;
22#[cfg(feature = "clipboard")]
23use copypasta::ClipboardProvider;
24
25use super::{LocalizationContext, ModelData};
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 #[cfg(feature = "tokio")]
79 pub(crate) task_runtime: &'a super::TaskRuntime,
80 #[cfg(feature = "tokio")]
81 pub(crate) named_tasks: &'a super::NamedTaskMap,
82 pub(crate) modifiers: &'a Modifiers,
83 pub(crate) mouse: &'a MouseState<Entity>,
84 pub(crate) event_queue: &'a mut VecDeque<Event>,
85 pub(crate) event_schedule: &'a mut BinaryHeap<TimedEvent>,
86 pub(crate) next_event_id: &'a mut usize,
87 pub(crate) timers: &'a mut Vec<TimerState>,
88 pub(crate) running_timers: &'a mut BinaryHeap<TimerState>,
89 cursor_icon_locked: &'a mut bool,
90 #[cfg(feature = "clipboard")]
91 clipboards: &'a mut HashMap<Entity, Box<dyn ClipboardProvider>>,
92 pub(crate) event_proxy: &'a mut Option<Box<dyn crate::context::EventProxy>>,
93 pub(crate) drop_data: &'a mut Option<DropData>,
94 pub(crate) active_drag_view: &'a mut Option<Entity>,
95 pub windows: &'a mut HashMap<Entity, WindowState>,
96}
97
98impl<'a> EventContext<'a> {
99 pub fn new(cx: &'a mut Context) -> Self {
101 Self {
102 current: cx.current,
103 captured: &mut cx.captured,
104 focused: &mut cx.focused,
105 hovered: &cx.hovered,
106 triggered: &mut cx.triggered,
107 entity_identifiers: &cx.entity_identifiers,
108 style: &mut cx.style,
109 cache: &mut cx.cache,
110 tree: &cx.tree,
111 models: &mut cx.models,
112 views: &mut cx.views,
113 listeners: &mut cx.listeners,
114 resource_manager: &mut cx.resource_manager,
115 text_context: &mut cx.text_context,
116 #[cfg(feature = "tokio")]
117 task_runtime: &cx.task_runtime,
118 #[cfg(feature = "tokio")]
119 named_tasks: &cx.named_tasks,
120 modifiers: &cx.modifiers,
121 mouse: &cx.mouse,
122 event_queue: &mut cx.event_queue,
123 event_schedule: &mut cx.event_schedule,
124 next_event_id: &mut cx.next_event_id,
125 timers: &mut cx.timers,
126 running_timers: &mut cx.running_timers,
127 cursor_icon_locked: &mut cx.cursor_icon_locked,
128 #[cfg(feature = "clipboard")]
129 clipboards: &mut cx.clipboards,
130 event_proxy: &mut cx.event_proxy,
131 drop_data: &mut cx.drop_data,
132 active_drag_view: &mut cx.active_drag_view,
133 windows: &mut cx.windows,
134 }
135 }
136
137 pub fn new_with_current(cx: &'a mut Context, current: Entity) -> Self {
139 Self {
140 current,
141 captured: &mut cx.captured,
142 focused: &mut cx.focused,
143 hovered: &cx.hovered,
144 triggered: &mut cx.triggered,
145 entity_identifiers: &cx.entity_identifiers,
146 style: &mut cx.style,
147 cache: &mut cx.cache,
148 tree: &cx.tree,
149 models: &mut cx.models,
150 views: &mut cx.views,
151 listeners: &mut cx.listeners,
152 resource_manager: &mut cx.resource_manager,
153 text_context: &mut cx.text_context,
154 #[cfg(feature = "tokio")]
155 task_runtime: &cx.task_runtime,
156 #[cfg(feature = "tokio")]
157 named_tasks: &cx.named_tasks,
158 modifiers: &cx.modifiers,
159 mouse: &cx.mouse,
160 event_queue: &mut cx.event_queue,
161 event_schedule: &mut cx.event_schedule,
162 next_event_id: &mut cx.next_event_id,
163 timers: &mut cx.timers,
164 running_timers: &mut cx.running_timers,
165 cursor_icon_locked: &mut cx.cursor_icon_locked,
166 #[cfg(feature = "clipboard")]
167 clipboards: &mut cx.clipboards,
168 event_proxy: &mut cx.event_proxy,
169 drop_data: &mut cx.drop_data,
170 active_drag_view: &mut cx.active_drag_view,
171 windows: &mut cx.windows,
172 }
173 }
174
175 pub fn get_view<V: View>(&self) -> Option<&V> {
177 self.views.get(&self.current).and_then(|view| view.downcast_ref::<V>())
178 }
179
180 pub fn get_view_with<V: View>(&self, entity: Entity) -> Option<&V> {
182 self.views.get(&entity).and_then(|view| view.downcast_ref::<V>())
183 }
184
185 pub fn close_window(&mut self) {
186 if let Some(state) = self.windows.get_mut(&self.current) {
187 state.should_close = true;
188 }
189 }
190
191 pub fn resolve_entity_identifier(&self, id: &str) -> Option<Entity> {
193 self.entity_identifiers.get(id).cloned()
194 }
195
196 pub fn get_entity_by_element_id(&self, element: &str) -> Option<Entity> {
198 let descendants = LayoutTreeIterator::subtree(self.tree, self.current);
199 for descendant in descendants {
200 if let Some(id) = self.views.get(&descendant).and_then(|view| view.element()) {
201 if id == element {
202 return Some(descendant);
203 }
204 }
205 }
206
207 None
208 }
209
210 pub fn get_entities_by_class(&self, class: &str) -> Vec<Entity> {
212 let mut entities = Vec::new();
213 let descendants = LayoutTreeIterator::subtree(self.tree, self.current);
214 for descendant in descendants {
215 if let Some(class_list) = self.style.classes.get(descendant) {
216 if class_list.contains(class) {
217 entities.push(descendant);
218 }
219 }
220 }
221
222 entities
223 }
224
225 pub fn current(&self) -> Entity {
227 self.current
228 }
229
230 pub fn modifiers(&self) -> &Modifiers {
232 self.modifiers
233 }
234
235 pub fn mouse(&self) -> &MouseState<Entity> {
237 self.mouse
238 }
239
240 pub fn nth_child(&self, n: usize) -> Option<Entity> {
241 self.tree.get_child(self.current, n)
242 }
243
244 pub fn last_child(&self) -> Option<Entity> {
245 self.tree.get_last_child(self.current).copied()
246 }
247
248 pub fn with_current<T>(&mut self, entity: Entity, f: impl FnOnce(&mut Self) -> T) -> T {
249 let prev = self.current();
250 self.current = entity;
251 let ret = (f)(self);
252 self.current = prev;
253 ret
254 }
255
256 pub fn has_drop_data(&self) -> bool {
258 self.drop_data.is_some()
259 }
260
261 pub fn drop_data(&self) -> Option<&DropData> {
263 self.drop_data.as_ref()
264 }
265
266 pub fn active_drag_view(&self) -> Option<Entity> {
268 *self.active_drag_view
269 }
270
271 pub fn set_active_drag_view(&mut self, drag_view: Option<Entity>) {
273 *self.active_drag_view = drag_view;
274 }
275
276 pub fn bounds(&self) -> BoundingBox {
278 self.cache.get_bounds(self.current)
279 }
280
281 pub fn transformed_bounds(&self, entity: Entity) -> BoundingBox {
283 let bounds = self.cache.get_bounds(entity);
284
285 if let Some(transform) = self.cache.transform.get(entity).copied() {
286 if transform == Matrix::new_identity() {
289 return bounds;
290 }
291
292 let (rect, _) = transform.map_rect(Rect::from(bounds));
293 rect.into()
294 } else {
295 bounds
296 }
297 }
298
299 pub fn transformed_bounds_snapped(&self, entity: Entity) -> BoundingBox {
301 let bounds = self.transformed_bounds(entity);
302 BoundingBox::from_min_max(
303 bounds.left().floor(),
304 bounds.top().floor(),
305 bounds.right().ceil(),
306 bounds.bottom().ceil(),
307 )
308 }
309
310 pub fn parent_transformed_bounds(&self) -> BoundingBox {
312 self.transformed_bounds(self.parent())
313 }
314
315 pub fn scale_factor(&self) -> f32 {
321 self.style.dpi_factor as f32
322 }
323
324 pub fn logical_to_physical(&self, logical: f32) -> f32 {
326 self.style.logical_to_physical(logical)
327 }
328
329 pub fn physical_to_logical(&self, physical: f32) -> f32 {
331 self.style.physical_to_logical(physical)
332 }
333
334 pub fn clip_region(&self) -> BoundingBox {
336 let current_window = if self.tree.is_window(self.current) {
337 self.current
338 } else {
339 self.tree.get_parent_window(self.current).unwrap_or(Entity::root())
340 };
341
342 let window_bounds = self.cache.get_bounds(current_window);
343
344 if let Some(clip_path) = self.cache.clip_path.get(self.current) {
346 return clip_path
347 .clone()
348 .map(|clip_path| Into::<BoundingBox>::into(*clip_path.bounds()))
349 .unwrap_or(window_bounds);
350 }
351
352 if self.style.ignore_clipping.get(self.current).copied().unwrap_or(false) {
353 return window_bounds;
354 }
355
356 let mut current = self.current;
357 while let Some(parent) = self.tree.get_parent(current) {
358 if let Some(clip_path) = self.cache.clip_path.get(parent) {
360 return clip_path
361 .clone()
362 .map(|clip_path| Into::<BoundingBox>::into(*clip_path.bounds()))
363 .unwrap_or(window_bounds);
364 }
365
366 if self.style.ignore_clipping.get(parent).copied().unwrap_or(false) {
367 return window_bounds;
368 }
369
370 if parent == current_window {
371 break;
372 }
373
374 current = parent;
375 }
376
377 window_bounds
378 }
379
380 pub fn transform(&self) -> Matrix {
382 self.cache.transform.get(self.current).copied().unwrap_or_default()
383 }
384
385 pub fn play_animation(&mut self, anim_id: impl AnimId, duration: Duration, delay: Duration) {
387 if let Some(animation_id) = anim_id.get(self) {
388 self.style.enqueue_animation(self.current, animation_id, duration, delay);
389 }
390 }
391
392 pub fn play_animation_for(
394 &mut self,
395 anim_id: impl AnimId,
396 target: &str,
397 duration: Duration,
398 delay: Duration,
399 ) {
400 if let Some(target_entity) = self.resolve_entity_identifier(target) {
401 if let Some(animation_id) = anim_id.get(self) {
402 self.style.enqueue_animation(target_entity, animation_id, duration, delay)
403 }
404 }
405 }
406
407 pub fn is_animating(&self, anim_id: impl AnimId) -> bool {
409 if let Some(animation_id) = anim_id.get(self) {
410 return self.style.is_animating(self.current, animation_id);
411 }
412
413 false
414 }
415
416 pub fn add_listener<F, W>(&mut self, listener: F)
422 where
423 W: View,
424 F: 'static + Fn(&mut W, &mut EventContext, &mut Event),
425 {
426 self.listeners.insert(
427 self.current,
428 Box::new(move |event_handler, context, event| {
429 if let Some(widget) = event_handler.downcast_mut::<W>() {
430 (listener)(widget, context, event);
431 }
432 }),
433 );
434 }
435
436 pub fn set_language(&mut self, lang: LanguageIdentifier) {
438 if let Some(mut models) = self.models.remove(&Entity::root()) {
439 if let Some(model) = models.get_mut(&TypeId::of::<Environment>()) {
440 model.event(self, &mut Event::new(EnvironmentEvent::SetLocale(lang)));
441 }
442
443 self.models.insert(Entity::root(), models);
444 }
445 }
446
447 pub fn add_image_encoded(&mut self, path: &str, data: &[u8], policy: ImageRetentionPolicy) {
448 let id = if let Some(image_id) = self.resource_manager.image_ids.get(path) {
449 *image_id
450 } else {
451 let id = self.resource_manager.image_id_manager.create();
452 self.resource_manager.image_ids.insert(path.to_owned(), id);
453 id
454 };
455
456 if let Some(image) = skia_safe::Image::from_encoded(skia_safe::Data::new_copy(data)) {
457 match self.resource_manager.images.entry(id) {
458 Entry::Occupied(mut occ) => {
459 occ.get_mut().image = ImageOrSvg::Image(image);
460 occ.get_mut().dirty = true;
461 occ.get_mut().retention_policy = policy;
462 }
463 Entry::Vacant(vac) => {
464 vac.insert(StoredImage {
465 image: ImageOrSvg::Image(image),
466 retention_policy: policy,
467 used: true,
468 dirty: false,
469 observers: HashSet::new(),
470 });
471 }
472 }
473 let observers: Vec<Entity> = self
476 .resource_manager
477 .images
478 .get(&id)
479 .map(|img| img.observers.iter().copied().collect())
480 .unwrap_or_default();
481 for observer in observers {
482 self.style.needs_relayout(observer);
483 }
484 self.style.needs_relayout(self.current);
485 }
486 }
487
488 pub fn capture(&mut self) {
490 *self.captured = self.current;
491 }
492
493 pub fn release(&mut self) {
495 if self.current == *self.captured {
496 *self.captured = Entity::null();
497 }
498 }
499
500 fn set_focus_pseudo_classes(&mut self, focused: Entity, enabled: bool, focus_visible: bool) {
502 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(focused) {
503 pseudo_classes.set(PseudoClassFlags::FOCUS, enabled);
504 if !enabled || focus_visible {
505 pseudo_classes.set(PseudoClassFlags::FOCUS_VISIBLE, enabled);
506 }
507 }
508
509 for ancestor in focused.parent_iter(self.tree) {
510 let entity = ancestor;
511 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(entity) {
512 pseudo_classes.set(PseudoClassFlags::FOCUS_WITHIN, enabled);
513 }
514 self.style.needs_restyle(entity);
515 }
516 }
517
518 pub fn focus_with_visibility(&mut self, focus_visible: bool) {
520 let focusable = self.current == Entity::root()
521 || self
522 .style
523 .abilities
524 .get(self.current)
525 .is_some_and(|abilities| abilities.contains(Abilities::FOCUSABLE));
526 if !focusable {
527 return;
528 }
529
530 let old_focus = self.focused();
531 let new_focus = self.current();
532 self.set_focus_pseudo_classes(old_focus, false, focus_visible);
533 if self.current() != self.focused() {
534 self.emit_to(old_focus, WindowEvent::FocusOut);
535 self.emit_to(new_focus, WindowEvent::FocusIn);
536 *self.focused = self.current();
537 }
538 self.set_focus_pseudo_classes(new_focus, true, focus_visible);
539
540 self.emit_custom(Event::new(WindowEvent::FocusVisibility(focus_visible)).target(old_focus));
541 self.emit_custom(Event::new(WindowEvent::FocusVisibility(focus_visible)).target(new_focus));
542
543 self.needs_restyle();
544 }
545
546 pub fn focus(&mut self) {
550 let focused = self.focused();
551 let old_focus_visible = self
552 .style
553 .pseudo_classes
554 .get_mut(focused)
555 .filter(|class| class.contains(PseudoClassFlags::FOCUS_VISIBLE))
556 .is_some();
557 self.focus_with_visibility(old_focus_visible)
558 }
559
560 pub fn focus_next(&mut self) {
562 let lock_focus_to = self.tree.lock_focus_within(*self.focused);
563 let next_focused = if let Some(next_focused) =
564 focus_forward(self.tree, self.style, *self.focused, lock_focus_to)
565 {
566 next_focused
567 } else {
568 TreeIterator::full(self.tree)
569 .find(|node| is_navigatable(self.tree, self.style, *node, lock_focus_to))
570 .unwrap_or(Entity::root())
571 };
572
573 if next_focused != *self.focused {
574 self.event_queue.push_back(
575 Event::new(WindowEvent::FocusOut).target(*self.focused).origin(Entity::root()),
576 );
577 self.event_queue.push_back(
578 Event::new(WindowEvent::FocusIn).target(next_focused).origin(Entity::root()),
579 );
580
581 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(*self.triggered) {
582 pseudo_classes.set(PseudoClassFlags::ACTIVE, false);
583 }
584 self.needs_restyle();
585 *self.triggered = Entity::null();
586 }
587 }
588
589 pub fn focus_prev(&mut self) {
591 let lock_focus_to = self.tree.lock_focus_within(*self.focused);
592 let prev_focused = if let Some(prev_focused) =
593 focus_backward(self.tree, self.style, *self.focused, lock_focus_to)
594 {
595 prev_focused
596 } else {
597 TreeIterator::full(self.tree)
598 .rfind(|node| is_navigatable(self.tree, self.style, *node, lock_focus_to))
599 .unwrap_or(Entity::root())
600 };
601
602 if prev_focused != *self.focused {
603 self.event_queue.push_back(
604 Event::new(WindowEvent::FocusOut).target(*self.focused).origin(Entity::root()),
605 );
606 self.event_queue.push_back(
607 Event::new(WindowEvent::FocusIn).target(prev_focused).origin(Entity::root()),
608 );
609
610 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(*self.triggered) {
611 pseudo_classes.set(PseudoClassFlags::ACTIVE, false);
612 }
613 self.needs_restyle();
614 *self.triggered = Entity::null();
615 }
616 }
617
618 pub fn hovered(&self) -> Entity {
620 *self.hovered
621 }
622
623 pub fn focused(&self) -> Entity {
625 *self.focused
626 }
627
628 pub fn is_hovered(&self) -> bool {
632 self.hovered() == self.current
633 }
634
635 pub fn is_active(&self) -> bool {
637 if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
638 pseudo_classes.contains(PseudoClassFlags::ACTIVE)
639 } else {
640 false
641 }
642 }
643
644 pub fn is_over(&self) -> bool {
646 if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
647 pseudo_classes.contains(PseudoClassFlags::OVER)
648 } else {
649 false
650 }
651 }
652
653 pub fn is_focused(&self) -> bool {
655 self.focused() == self.current
656 }
657
658 pub fn is_draggable(&self) -> bool {
660 self.style
661 .abilities
662 .get(self.current)
663 .map(|abilities| abilities.contains(Abilities::DRAGGABLE))
664 .unwrap_or_default()
665 }
666
667 pub fn is_disabled(&self) -> bool {
669 self.style.disabled.get(self.current()).cloned().unwrap_or_default()
670 }
671
672 pub fn is_checked(&self) -> bool {
674 if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
675 pseudo_classes.contains(PseudoClassFlags::CHECKED)
676 } else {
677 false
678 }
679 }
680
681 pub fn is_read_only(&self) -> bool {
683 if let Some(pseudo_classes) = self.style.pseudo_classes.get(self.current) {
684 pseudo_classes.contains(PseudoClassFlags::READ_ONLY)
685 } else {
686 false
687 }
688 }
689
690 pub fn lock_cursor_icon(&mut self) {
694 *self.cursor_icon_locked = true;
695 }
696
697 pub fn unlock_cursor_icon(&mut self) {
699 *self.cursor_icon_locked = false;
700 let hovered = *self.hovered;
701 let cursor = self.style.cursor.get(hovered).cloned().unwrap_or_default();
702 self.emit(WindowEvent::SetCursor(cursor));
703 }
704
705 pub fn is_cursor_icon_locked(&self) -> bool {
707 *self.cursor_icon_locked
708 }
709
710 pub fn set_drop_data(&mut self, data: impl Into<DropData>) {
712 *self.drop_data = Some(data.into())
713 }
714
715 #[cfg(feature = "clipboard")]
719 pub fn get_clipboard(&mut self) -> Result<String, Box<dyn Error + Send + Sync + 'static>> {
720 self.current_window_clipboard().get_contents()
721 }
722
723 #[cfg(feature = "clipboard")]
727 pub fn set_clipboard(
728 &mut self,
729 text: String,
730 ) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
731 self.current_window_clipboard().set_contents(text)
732 }
733
734 #[cfg(feature = "clipboard")]
735 fn current_window_clipboard(&mut self) -> &mut Box<dyn ClipboardProvider> {
736 let window = if self.tree.is_window(self.current) {
737 self.current
738 } else {
739 self.tree.get_parent_window(self.current).unwrap_or(Entity::root())
740 };
741
742 self.clipboards.entry(window).or_insert_with(super::default_clipboard_provider)
743 }
744
745 pub fn toggle_class(&mut self, class_name: &str, applied: bool) {
755 let current = self.current();
756 if let Some(class_list) = self.style.classes.get_mut(current) {
757 if applied {
758 class_list.insert(class_name.to_string());
759 } else {
760 class_list.remove(class_name);
761 }
762 } else if applied {
763 let mut class_list = HashSet::new();
764 class_list.insert(class_name.to_string());
765 self.style.classes.insert(current, class_list);
766 }
767
768 self.needs_restyle();
769 }
770
771 pub fn environment(&self) -> &Environment {
773 self.data::<Environment>()
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(self.current);
787 self.needs_redraw();
788 }
789
790 pub fn needs_restyle(&mut self) {
792 if self.current == Entity::null() || self.style.restyle.contains(&self.current) {
793 return;
794 }
795
796 self.style.restyle.insert(self.current);
797 let iter = if let Some(parent) = self.tree.get_layout_parent(self.current) {
798 LayoutTreeIterator::subtree(self.tree, parent)
799 } else {
800 LayoutTreeIterator::subtree(self.tree, self.current)
801 };
802
803 for descendant in iter {
804 self.style.restyle.insert(descendant);
805 }
806 self.style.needs_restyle(self.current);
807 }
808
809 pub fn needs_retransform(&mut self) {
810 self.style.needs_retransform(self.current);
811 let iter = LayoutTreeIterator::subtree(self.tree, self.current);
812 for descendant in iter {
813 self.style.needs_retransform(descendant);
814 }
815 }
816
817 pub fn needs_reclip(&mut self) {
818 self.style.needs_reclip(self.current);
819 let iter = LayoutTreeIterator::subtree(self.tree, self.current);
820 for descendant in iter {
821 self.style.needs_reclip(descendant);
822 }
823 }
824
825 pub fn reload_styles(&mut self) -> Result<(), std::io::Error> {
827 if self.resource_manager.styles.is_empty() {
828 return Ok(());
829 }
830
831 self.style.remove_rules();
832
833 self.style.clear_style_rules();
834
835 let mut overall_theme = String::new();
836
837 for style_string in self.resource_manager.styles.iter().flat_map(|style| style.get_style())
838 {
839 overall_theme += &style_string;
840 }
841
842 self.style.parse_theme(&overall_theme);
843
844 self.style.needs_relayout(Entity::root());
845
846 for entity in self.tree.into_iter() {
847 self.style.needs_restyle(entity);
848
849 self.style.needs_text_update(entity);
851 }
852
853 Ok(())
854 }
855
856 pub fn spawn<F>(&self, target: F)
858 where
859 F: 'static + Send + FnOnce(&mut ContextProxy),
860 {
861 let mut cxp = ContextProxy {
862 current: self.current,
863 event_proxy: self.event_proxy.as_ref().map(|p| p.make_clone()),
864 };
865
866 std::thread::spawn(move || target(&mut cxp));
867 }
868
869 pub fn get_proxy(&self) -> ContextProxy {
871 ContextProxy {
872 current: self.current,
873 event_proxy: self.event_proxy.as_ref().map(|p| p.make_clone()),
874 }
875 }
876
877 #[cfg(feature = "tokio")]
901 pub fn add_task<T, E>(&self, task: TaskBuilder<T, E>) -> TaskHandle
902 where
903 T: Send + 'static,
904 E: Send + 'static,
905 {
906 task.add_to_event_context(self)
907 }
908
909 pub fn modify<V: View>(&mut self, f: impl FnOnce(&mut V)) {
910 if let Some(view) = self
911 .views
912 .get_mut(&self.current)
913 .and_then(|view_handler| view_handler.downcast_mut::<V>())
914 {
915 (f)(view);
916 }
917 }
918
919 pub fn background_color(&mut self) -> Color {
927 self.style.background_color.get(self.current).copied().unwrap_or_default()
928 }
929
930 pub fn set_id(&mut self, id: &str) {
933 self.style.ids.insert(self.current, id.to_string())
934 }
935
936 pub fn set_hover(&mut self, flag: bool) {
948 let current = self.current();
949 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
950 pseudo_classes.set(PseudoClassFlags::HOVER, flag);
951 }
952
953 self.needs_restyle();
954 }
955
956 pub fn set_active(&mut self, active: bool) {
965 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(self.current) {
966 pseudo_classes.set(PseudoClassFlags::ACTIVE, active);
967 }
968
969 self.needs_restyle();
970 }
971
972 pub fn set_read_only(&mut self, flag: bool) {
973 let current = self.current();
974 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
975 pseudo_classes.set(PseudoClassFlags::READ_ONLY, flag);
976 }
977
978 self.needs_restyle();
979 }
980
981 pub fn set_read_write(&mut self, flag: bool) {
982 let current = self.current();
983 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
984 pseudo_classes.set(PseudoClassFlags::READ_WRITE, flag);
985 }
986
987 self.needs_restyle();
988 }
989
990 pub fn set_checked(&mut self, flag: bool) {
999 let current = self.current();
1000 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
1001 pseudo_classes.set(PseudoClassFlags::CHECKED, flag);
1002 }
1003
1004 self.needs_restyle();
1005 }
1006
1007 pub fn set_valid(&mut self, flag: bool) {
1016 let current = self.current();
1017 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
1018 pseudo_classes.set(PseudoClassFlags::VALID, flag);
1019 pseudo_classes.set(PseudoClassFlags::INVALID, !flag);
1020 }
1021
1022 self.needs_restyle();
1023 }
1024
1025 pub fn set_placeholder_shown(&mut self, flag: bool) {
1026 let current = self.current();
1027 if let Some(pseudo_classes) = self.style.pseudo_classes.get_mut(current) {
1028 pseudo_classes.set(PseudoClassFlags::PLACEHOLDER_SHOWN, flag);
1029 }
1030
1031 self.needs_restyle();
1032 }
1033
1034 pub fn is_valid(&self) -> bool {
1036 self.style
1037 .pseudo_classes
1038 .get(self.current)
1039 .map(|pseudo_classes| pseudo_classes.contains(PseudoClassFlags::VALID))
1040 .unwrap_or_default()
1041 }
1042
1043 pub fn is_placeholder_shown(&self) -> bool {
1044 self.style
1045 .pseudo_classes
1046 .get(self.current)
1047 .map(|pseudo_classes| pseudo_classes.contains(PseudoClassFlags::PLACEHOLDER_SHOWN))
1048 .unwrap_or_default()
1049 }
1050
1051 pub fn set_name(&mut self, name: &str) {
1055 self.style.name.insert(self.current, name.to_string());
1056 }
1057
1058 pub fn set_role(&mut self, role: Role) {
1060 self.style.role.insert(self.current, role);
1061 }
1062
1063 pub fn set_live(&mut self, live: Live) {
1070 self.style.live.insert(self.current, live);
1071 }
1072
1073 pub fn labelled_by(&mut self, id: &str) {
1075 self.style.labelled_by.insert(self.current, id.to_string());
1076 }
1077
1078 pub fn described_by(&mut self, id: &str) {
1080 self.style.described_by.insert(self.current, id.to_string());
1081 }
1082
1083 pub fn controls(&mut self, id: &str) {
1085 self.style.controls.insert(self.current, id.to_string());
1086 }
1087
1088 pub fn set_hidden(&mut self, hidden: bool) {
1090 self.style.hidden.insert(self.current, hidden)
1091 }
1092
1093 pub fn text_value(&mut self, text: &str) {
1095 self.style.text_value.insert(self.current, text.to_string());
1096 }
1097
1098 pub fn numeric_value(&mut self, value: f64) {
1100 self.style.numeric_value.insert(self.current, value);
1101 }
1102
1103 pub fn set_display(&mut self, display: Display) {
1109 self.style.display.insert(self.current, display);
1110 }
1111
1112 pub fn set_visibility(&mut self, visibility: Visibility) {
1116 self.style.visibility.insert(self.current, visibility);
1117 }
1118
1119 pub fn set_opacity(&mut self, opacity: f32) {
1123 self.style.opacity.insert(self.current, Opacity(opacity));
1124 }
1125
1126 pub fn set_z_index(&mut self, z_index: i32) {
1128 self.style.z_index.insert(self.current, z_index);
1129 }
1130
1131 pub fn set_clip_path(&mut self, clip_path: ClipPath) {
1133 self.style.clip_path.insert(self.current, clip_path);
1134 self.needs_reclip();
1135 self.needs_redraw();
1136 }
1137
1138 pub fn set_overflowx(&mut self, overflowx: impl Into<Overflow>) {
1140 self.style.overflowx.insert(self.current, overflowx.into());
1141 self.needs_reclip();
1142 self.needs_redraw();
1143 }
1144
1145 pub fn set_overflowy(&mut self, overflowy: impl Into<Overflow>) {
1147 self.style.overflowy.insert(self.current, overflowy.into());
1148 self.needs_reclip();
1149 self.needs_redraw();
1150 }
1151
1152 pub fn set_transform(&mut self, transform: impl Into<Vec<Transform>>) {
1156 self.style.transform.insert(self.current, transform.into());
1157 self.needs_retransform();
1158 self.needs_redraw();
1159 }
1160
1161 pub fn set_transform_origin(&mut self, transform_origin: Translate) {
1163 self.style.transform_origin.insert(self.current, transform_origin);
1164 self.needs_retransform();
1165 self.needs_redraw();
1166 }
1167
1168 pub fn set_translate(&mut self, translate: impl Into<Translate>) {
1170 self.style.translate.insert(self.current, translate.into());
1171 self.needs_retransform();
1172 self.needs_redraw();
1173 }
1174
1175 pub fn set_rotate(&mut self, angle: impl Into<Angle>) {
1177 self.style.rotate.insert(self.current, angle.into());
1178 self.needs_retransform();
1179 self.needs_redraw();
1180 }
1181
1182 pub fn set_scale(&mut self, scale: impl Into<Scale>) {
1184 self.style.scale.insert(self.current, scale.into());
1185 self.needs_retransform();
1186 self.needs_redraw();
1187 }
1188
1189 pub fn set_filter(&mut self, filter: Filter) {
1193 self.style.filter.insert(self.current, filter);
1194 self.needs_redraw();
1195 }
1196
1197 pub fn set_backdrop_filter(&mut self, filter: Filter) {
1199 self.style.backdrop_filter.insert(self.current, filter);
1200 self.needs_redraw();
1201 }
1202
1203 pub fn set_background_color(&mut self, background_color: Color) {
1210 self.style.background_color.insert(self.current, background_color);
1211 self.needs_redraw();
1212 }
1213
1214 pub fn set_width(&mut self, width: Units) {
1217 self.style.width.insert(self.current, width);
1218 self.needs_relayout();
1219 self.needs_redraw();
1220 }
1221
1222 pub fn set_height(&mut self, height: Units) {
1223 self.style.height.insert(self.current, height);
1224 self.needs_relayout();
1225 self.needs_redraw();
1226 }
1227
1228 pub fn set_max_height(&mut self, height: Units) {
1229 self.style.max_height.insert(self.current, height);
1230 self.needs_relayout();
1231 self.needs_redraw();
1232 }
1233
1234 pub fn set_left(&mut self, left: Units) {
1237 self.style.left.insert(self.current, left);
1238 self.needs_relayout();
1239 self.needs_redraw();
1240 }
1241
1242 pub fn set_top(&mut self, top: Units) {
1243 self.style.top.insert(self.current, top);
1244 self.needs_relayout();
1245 self.needs_redraw();
1246 }
1247
1248 pub fn set_right(&mut self, right: Units) {
1249 self.style.right.insert(self.current, right);
1250 self.needs_relayout();
1251 self.needs_redraw();
1252 }
1253
1254 pub fn set_bottom(&mut self, bottom: Units) {
1255 self.style.bottom.insert(self.current, bottom);
1256 self.needs_relayout();
1257 self.needs_redraw();
1258 }
1259
1260 pub fn set_padding_left(&mut self, padding_left: Units) {
1263 self.style.padding_left.insert(self.current, padding_left);
1264 self.needs_relayout();
1265 self.needs_redraw();
1266 }
1267
1268 pub fn set_padding_top(&mut self, padding_top: Units) {
1269 self.style.padding_top.insert(self.current, padding_top);
1270 self.needs_relayout();
1271 self.needs_redraw();
1272 }
1273
1274 pub fn set_padding_right(&mut self, padding_right: Units) {
1275 self.style.padding_right.insert(self.current, padding_right);
1276 self.needs_relayout();
1277 self.needs_redraw();
1278 }
1279
1280 pub fn set_padding_bottom(&mut self, padding_bottom: Units) {
1281 self.style.padding_bottom.insert(self.current, padding_bottom);
1282 self.needs_relayout();
1283 self.needs_redraw();
1284 }
1285
1286 pub fn set_text(&mut self, text: &str) {
1290 self.style.text.insert(self.current, text.to_owned());
1291 self.style.needs_text_update(self.current);
1292 self.needs_relayout();
1293 self.needs_redraw();
1294 }
1295
1296 pub fn set_pointer_events(&mut self, pointer_events: impl Into<PointerEvents>) {
1297 self.style.pointer_events.insert(self.current, pointer_events.into());
1298 }
1299
1300 pub fn border_top_width(&self) -> f32 {
1304 if let Some(length) = self.style.border_top_width.get(self.current) {
1305 let bounds = self.bounds();
1306 return length.to_pixels(bounds.w.min(bounds.h), self.scale_factor()).round();
1307 }
1308 0.0
1309 }
1310
1311 pub fn border_right_width(&self) -> f32 {
1313 if let Some(length) = self.style.border_right_width.get(self.current) {
1314 let bounds = self.bounds();
1315 return length.to_pixels(bounds.w.min(bounds.h), self.scale_factor()).round();
1316 }
1317 0.0
1318 }
1319
1320 pub fn border_bottom_width(&self) -> f32 {
1322 if let Some(length) = self.style.border_bottom_width.get(self.current) {
1323 let bounds = self.bounds();
1324 return length.to_pixels(bounds.w.min(bounds.h), self.scale_factor()).round();
1325 }
1326 0.0
1327 }
1328
1329 pub fn border_left_width(&self) -> f32 {
1331 if let Some(length) = self.style.border_left_width.get(self.current) {
1332 let bounds = self.bounds();
1333 return length.to_pixels(bounds.w.min(bounds.h), self.scale_factor()).round();
1334 }
1335 0.0
1336 }
1337
1338 pub fn border_width(&self) -> f32 {
1341 self.border_top_width()
1342 }
1343
1344 pub fn font_size(&self) -> f32 {
1346 self.logical_to_physical(
1347 self.style
1348 .font_size
1349 .get(self.current)
1350 .cloned()
1351 .map(|f| f.0.to_px().unwrap())
1352 .unwrap_or(16.0),
1353 )
1354 }
1355
1356 pub fn add_timer(
1387 &mut self,
1388 interval: Duration,
1389 duration: Option<Duration>,
1390 callback: impl Fn(&mut EventContext, TimerAction) + 'static,
1391 ) -> Timer {
1392 let id = Timer(self.timers.len());
1393 self.timers.push(TimerState {
1394 entity: Entity::root(),
1395 id,
1396 time: Instant::now(),
1397 interval,
1398 duration,
1399 start_time: Instant::now(),
1400 callback: Rc::new(callback),
1401 ticking: false,
1402 stopping: false,
1403 });
1404
1405 id
1406 }
1407
1408 pub fn start_timer(&mut self, timer: Timer) {
1412 let current = self.current;
1413 if !self.timer_is_running(timer) {
1414 let timer_state = self.timers[timer.0].clone();
1415 self.running_timers.push(timer_state);
1417 }
1418
1419 self.modify_timer(timer, |timer_state| {
1420 let now = Instant::now();
1421 timer_state.start_time = now;
1422 timer_state.time = now;
1423 timer_state.entity = current;
1424 timer_state.ticking = false;
1425 timer_state.stopping = false;
1426 });
1427 }
1428
1429 pub fn modify_timer(&mut self, timer: Timer, timer_function: impl Fn(&mut TimerState)) {
1431 while let Some(next_timer_state) = self.running_timers.peek() {
1432 if next_timer_state.id == timer {
1433 let mut timer_state = self.running_timers.pop().unwrap();
1434
1435 (timer_function)(&mut timer_state);
1436
1437 self.running_timers.push(timer_state);
1438
1439 return;
1440 }
1441 }
1442
1443 for pending_timer in self.timers.iter_mut() {
1444 if pending_timer.id == timer {
1445 (timer_function)(pending_timer);
1446 }
1447 }
1448 }
1449
1450 pub fn query_timer<T>(
1451 &mut self,
1452 timer: Timer,
1453 timer_function: impl Fn(&TimerState) -> T,
1454 ) -> Option<T> {
1455 while let Some(next_timer_state) = self.running_timers.peek() {
1456 if next_timer_state.id == timer {
1457 let timer_state = self.running_timers.pop().unwrap();
1458
1459 let t = (timer_function)(&timer_state);
1460
1461 self.running_timers.push(timer_state);
1462
1463 return Some(t);
1464 }
1465 }
1466
1467 for pending_timer in self.timers.iter() {
1468 if pending_timer.id == timer {
1469 return Some(timer_function(pending_timer));
1470 }
1471 }
1472
1473 None
1474 }
1475
1476 pub fn timer_is_running(&mut self, timer: Timer) -> bool {
1478 for timer_state in self.running_timers.iter() {
1479 if timer_state.id == timer {
1480 return true;
1481 }
1482 }
1483
1484 false
1485 }
1486
1487 pub fn stop_timer(&mut self, timer: Timer) {
1491 let mut running_timers = self.running_timers.clone();
1492
1493 for timer_state in running_timers.iter() {
1494 if timer_state.id == timer {
1495 self.with_current(timer_state.entity, |cx| {
1496 (timer_state.callback)(cx, TimerAction::Stop);
1497 });
1498 }
1499 }
1500
1501 *self.running_timers =
1502 running_timers.drain().filter(|timer_state| timer_state.id != timer).collect();
1503 }
1504}
1505
1506impl DataContext for EventContext<'_> {
1507 fn try_data<T: 'static>(&self) -> Option<&T> {
1508 if let Some(t) = <dyn Any>::downcast_ref::<T>(&()) {
1510 return Some(t);
1511 }
1512
1513 for entity in self.current.parent_iter(self.tree) {
1514 if let Some(models) = self.models.get(&entity) {
1516 if let Some(model) = models.get(&TypeId::of::<T>()) {
1517 return model.downcast_ref::<T>();
1518 }
1519 }
1520
1521 if let Some(view_handler) = self.views.get(&entity) {
1523 if let Some(data) = view_handler.downcast_ref::<T>() {
1524 return Some(data);
1525 }
1526 }
1527 }
1528
1529 None
1530 }
1531
1532 fn localization_context(&self) -> Option<LocalizationContext<'_>> {
1533 Some(LocalizationContext::from_event_context(self))
1534 }
1535}
1536
1537impl EmitContext for EventContext<'_> {
1538 fn emit<M: Any>(&mut self, message: M) {
1539 self.event_queue.push_back(
1540 Event::new(message)
1541 .target(self.current)
1542 .origin(self.current)
1543 .propagate(Propagation::Up),
1544 );
1545 }
1546
1547 fn emit_to<M: Any>(&mut self, target: Entity, message: M) {
1548 self.event_queue.push_back(
1549 Event::new(message).target(target).origin(self.current).propagate(Propagation::Direct),
1550 );
1551 }
1552
1553 fn emit_custom(&mut self, event: Event) {
1554 self.event_queue.push_back(event);
1555 }
1556
1557 fn schedule_emit<M: Any>(&mut self, message: M, at: Instant) -> TimedEventHandle {
1558 self.schedule_emit_custom(
1559 Event::new(message)
1560 .target(self.current)
1561 .origin(self.current)
1562 .propagate(Propagation::Up),
1563 at,
1564 )
1565 }
1566 fn schedule_emit_to<M: Any>(
1567 &mut self,
1568 target: Entity,
1569 message: M,
1570 at: Instant,
1571 ) -> TimedEventHandle {
1572 self.schedule_emit_custom(
1573 Event::new(message).target(target).origin(self.current).propagate(Propagation::Direct),
1574 at,
1575 )
1576 }
1577 fn schedule_emit_custom(&mut self, event: Event, at: Instant) -> TimedEventHandle {
1578 let handle = TimedEventHandle(*self.next_event_id);
1579 self.event_schedule.push(TimedEvent { event, time: at, ident: handle });
1580 *self.next_event_id += 1;
1581 handle
1582 }
1583 fn cancel_scheduled(&mut self, handle: TimedEventHandle) {
1584 *self.event_schedule =
1585 self.event_schedule.drain().filter(|item| item.ident != handle).collect();
1586 }
1587}
1588
1589pub trait TreeProps {
1591 fn parent(&self) -> Entity;
1593 fn first_child(&self) -> Entity;
1595 fn parent_window(&self) -> Entity;
1597}
1598
1599impl TreeProps for EventContext<'_> {
1600 fn parent(&self) -> Entity {
1601 self.tree.get_layout_parent(self.current).unwrap()
1602 }
1603
1604 fn first_child(&self) -> Entity {
1605 self.tree.get_layout_first_child(self.current).unwrap()
1606 }
1607
1608 fn parent_window(&self) -> Entity {
1609 self.tree.get_parent_window(self.current).unwrap_or(Entity::root())
1610 }
1611}