1#![deny(missing_docs)]
2use std::{any::Any, cell::RefCell, collections::HashSet, rc::Rc};
8
9use floem_reactive::Scope;
10use peniko::kurbo::{Affine, Point, Rect, RoundedRect, Size};
11use smallvec::smallvec;
12use taffy::{Layout, NodeId};
13use winit::window::WindowId;
14
15use ui_events::pointer::PointerId;
16
17use super::{IntoView, StackOffset, VIEW_STORAGE, View, ViewState, ViewStorage};
18
19thread_local! {
20 static PENDING_SCOPE_REPARENTS: RefCell<HashSet<ViewId>> = RefCell::new(HashSet::new());
23}
24use crate::context::EventCallbackConfig;
25use crate::event::listener::EventListenerKey;
26use crate::event::{RouteKind, listener};
27use crate::style::recalc::StyleReason;
28use crate::view::LayoutTree;
29use crate::window::handle::get_current_view;
30use crate::{BoxTree, ElementId, FocusNavMeta};
31use crate::{
32 ScreenLayout,
33 action::add_update_message,
34 animate::{AnimStateCommand, Animation},
35 context::EventCallback,
36 message::{
37 CENTRAL_DEFERRED_UPDATE_MESSAGES, CENTRAL_UPDATE_MESSAGES, DeferredChild, DeferredChildren,
38 DeferredReactiveSetup, UpdateMessage,
39 },
40 platform::menu::Menu,
41 style::{Focusable, PointerEvents, Style, StyleClassRef, StyleSelector},
42 window::tracking::window_id_for_root,
43};
44
45use super::AnyView;
46
47#[allow(unused)]
48pub struct NotThreadSafe(*const ());
49
50#[derive(Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
57#[repr(transparent)]
58pub struct ViewId(
59 pub(crate) slotmap::KeyData,
60 std::marker::PhantomData<NotThreadSafe>,
61);
62impl std::fmt::Debug for ViewId {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 let debug_name = self.debug_name();
65 let mut start = f.debug_struct("ViewId");
66
67 if !debug_name.is_empty() {
68 start.field("id", &self.0).field("debug_name", &debug_name)
69 } else {
70 start.field("id", &self.0)
71 }
72 .finish()
73 }
74}
75impl slotmap::__impl::From<slotmap::KeyData> for ViewId {
76 fn from(k: slotmap::KeyData) -> Self {
77 ViewId(k, std::marker::PhantomData)
78 }
79}
80unsafe impl slotmap::Key for ViewId {
81 fn data(&self) -> slotmap::KeyData {
82 self.0
83 }
84}
85
86fn request_structural_selector_restyle(children: &[ViewId]) {
87 for child in children {
88 child.request_style(StyleReason::full_recalc());
89 }
90}
91
92impl ViewId {
93 pub fn new() -> ViewId {
95 VIEW_STORAGE.with_borrow_mut(|s| {
96 let root = get_current_view();
97 let new = s.view_ids.insert(());
98 s.root.insert(new, root);
99 new
100 })
101 }
102
103 pub(crate) fn new_root() -> ViewId {
104 VIEW_STORAGE.with_borrow_mut(|s| {
105 let new = s.view_ids.insert(());
106 s.root.insert(new, new);
107 new
108 })
109 }
110
111 pub fn debug_name(&self) -> String {
115 let state_names = self
116 .state()
117 .try_borrow()
118 .ok()
119 .map(|state| state.debug_name.iter().rev().cloned().collect::<Vec<_>>())
120 .unwrap_or_default();
121
122 let view_name = self
123 .view()
124 .try_borrow()
125 .ok()
126 .map(|view| View::debug_name(view.as_ref()).to_string())
127 .unwrap_or_default();
128
129 state_names
130 .into_iter()
131 .chain(std::iter::once(view_name))
132 .collect::<Vec<_>>()
133 .join(" - ")
134 }
135
136 pub fn is_valid(&self) -> bool {
141 VIEW_STORAGE.with_borrow(|s| s.view_ids.contains_key(*self))
142 }
143
144 pub fn remove(&self) {
149 let element_id = self.get_element_id();
150 if let Some(scope) = self.take_children_scope() {
152 scope.dispose();
153 }
154 if let Some(keyed_children) = self.take_keyed_children() {
156 for (_child_id, scope) in keyed_children {
157 scope.dispose();
158 }
159 }
160 let parent = self.parent();
162 VIEW_STORAGE.with_borrow_mut(|s| {
163 let taffy_node = s.state(*self).borrow().layout_id;
165 s.taffy_to_view.remove(&taffy_node);
166
167 s.root.remove(*self);
170 s.overlays.remove(*self);
172 if let Some(Some(parent)) = s.parent.get(*self)
174 && let Some(children) = s.children.get_mut(*parent)
175 {
176 children.retain(|c| c != self);
177 }
178 s.children.remove(*self);
182 s.parent.remove(*self);
183 s.states.remove(*self);
184 s.views.remove(*self);
185 s.view_ids.remove(*self);
187 });
188 let parent_element_id = parent.map(|p| p.get_element_id());
191 {
192 let _element_id = element_id;
193 let _parent_element_id = parent_element_id;
194 crate::event::clear_hit_test_cache();
197 };
198 }
199
200 pub(crate) fn register_overlay(&self) {
205 let root_id = self.root();
206 VIEW_STORAGE.with_borrow_mut(|s| {
207 s.overlays.insert(*self, root_id);
208 if let Some(logical_parent_id) = s.parent.get(*self).and_then(|p| *p) {
209 let this_element_id = s.state(*self).borrow().element_id;
210 let parent_element_id =
211 box_tree_parent_element_id_for_child(s, logical_parent_id, *self);
212 let box_tree = s.box_tree(*self);
213 box_tree
214 .borrow_mut()
215 .reparent(this_element_id.0, Some(parent_element_id.0));
216 }
217 });
218 }
219
220 #[expect(dead_code)] pub(crate) fn unregister_overlay(&self) {
223 VIEW_STORAGE.with_borrow_mut(|s| {
224 s.overlays.remove(*self);
225 if let Some(logical_parent_id) = s.parent.get(*self).and_then(|p| *p) {
226 let this_element_id = s.state(*self).borrow().element_id;
227 let parent_element_id = s.state(logical_parent_id).borrow().element_id;
228 let box_tree = s.box_tree(*self);
229 box_tree
230 .borrow_mut()
231 .reparent(this_element_id.0, Some(parent_element_id.0));
232 }
233 });
234 }
235
236 pub fn taffy(&self) -> Rc<RefCell<LayoutTree>> {
239 VIEW_STORAGE.with_borrow_mut(|s| s.taffy.clone())
240 }
241
242 pub fn box_tree(&self) -> Rc<RefCell<BoxTree>> {
244 VIEW_STORAGE.with_borrow_mut(|s| s.box_tree(*self))
245 }
246
247 pub fn new_taffy_node(&self) -> NodeId {
249 self.taffy()
250 .borrow_mut()
251 .new_leaf(taffy::style::Style::DEFAULT)
252 .unwrap()
253 }
254
255 pub fn set_taffy_style(&self, node: NodeId, style: taffy::Style) {
257 let _ = self.taffy().borrow_mut().set_style(node, style);
258 }
259
260 pub fn taffy_layout(&self, node: NodeId) -> Option<taffy::Layout> {
262 self.taffy().borrow().layout(node).cloned().ok()
263 }
264
265 pub fn mark_view_layout_dirty(&self) -> taffy::TaffyResult<()> {
267 let node = self.taffy_node();
268 self.taffy().borrow_mut().mark_dirty(node)
269 }
270 pub fn taffy_node(&self) -> NodeId {
272 self.state().borrow().layout_id
273 }
274
275 pub fn set_transform(&self, transform: Affine) {
277 self.state().borrow_mut().transform = transform;
278 self.request_box_tree_update_for_view();
279 }
280
281 pub(crate) fn state(&self) -> Rc<RefCell<ViewState>> {
282 VIEW_STORAGE.with_borrow_mut(|s| s.state(*self))
283 }
284
285 pub(crate) fn view(&self) -> Rc<RefCell<Box<dyn View>>> {
287 VIEW_STORAGE.with_borrow(|s| {
288 s.views.get(*self).cloned().unwrap_or_else(|| {
289 s.stale_view.clone()
291 })
292 })
293 }
294
295 pub fn add_child(&self, child: Box<dyn View>) {
297 let child_id = child.id();
298 let child_element_id = child_id.get_element_id();
299 VIEW_STORAGE.with_borrow_mut(|s| {
300 s.children.entry(*self).unwrap().or_default().push(child_id);
301 s.parent.insert(child_id, Some(*self));
302 s.views.insert(child_id, Rc::new(RefCell::new(child)));
303 let parent_element_id = box_tree_parent_element_id_for_child(s, *self, child_id);
304 s.box_tree(child_id)
305 .borrow_mut()
306 .reparent(child_element_id.0, Some(parent_element_id.0));
307 let child_taffy_node = s.state(child_id).borrow().layout_id;
308 let this_taffy_node = s.state(*self).borrow().layout_id;
309 let _ = s
310 .taffy
311 .borrow_mut()
312 .add_child(this_taffy_node, child_taffy_node);
313 });
314 reparent_scope_if_needed(child_id, *self);
317 request_structural_selector_restyle(&self.children());
318 }
319
320 pub fn append_children(&self, children: Vec<Box<dyn View>>) {
328 let child_ids: Vec<ViewId> = children.iter().map(|c| c.id()).collect();
329 VIEW_STORAGE.with_borrow_mut(|s| {
330 let this_taffy_node = s.state(*self).borrow().layout_id;
331 let child_element_ids: Vec<_> = children
332 .iter()
333 .map(|c| s.state(c.id()).borrow().element_id)
334 .collect();
335 let child_taffy_nodes: Vec<_> = children
336 .iter()
337 .map(|c| s.state(c.id()).borrow().layout_id)
338 .collect();
339
340 let box_tree = s.box_tree(*self);
341 let layout_tree = s.taffy.clone();
342
343 for ((child, child_element_id), child_taffy_node) in children
344 .into_iter()
345 .zip(child_element_ids)
346 .zip(child_taffy_nodes)
347 {
348 let child_id = child.id();
349 s.children.entry(*self).unwrap().or_default().push(child_id);
350 s.parent.insert(child_id, Some(*self));
351 s.views.insert(child_id, Rc::new(RefCell::new(child)));
352 let parent_element_id = box_tree_parent_element_id_for_child(s, *self, child_id);
353 box_tree
354 .borrow_mut()
355 .reparent(child_element_id.0, Some(parent_element_id.0));
356 let _ = layout_tree
357 .borrow_mut()
358 .add_child(this_taffy_node, child_taffy_node);
359 }
360 });
361 for child_id in child_ids {
363 reparent_scope_if_needed(child_id, *self);
364 }
365 request_structural_selector_restyle(&self.children());
366 }
367
368 pub fn set_children<const N: usize, V: IntoView>(&self, children: [V; N]) {
371 let children_ids: Vec<ViewId> = VIEW_STORAGE.with_borrow_mut(|s| {
372 let mut children_ids = Vec::new();
373 let mut children_nodes = Vec::with_capacity(children.len());
374 let box_tree = s.box_tree(*self);
375 let layout_tree = s.taffy.clone();
376 for child in children {
377 let child_view = child.into_view();
378 let child_view_id = child_view.id();
379 let child_element_id = s.state(child_view_id).borrow().element_id;
380 let child_taffy_node = s.state(child_view_id).borrow().layout_id;
381 children_nodes.push(child_taffy_node);
382 children_ids.push(child_view_id);
383 s.parent.insert(child_view_id, Some(*self));
384 s.views
385 .insert(child_view_id, Rc::new(RefCell::new(child_view.into_any())));
386 let parent_element_id =
387 box_tree_parent_element_id_for_child(s, *self, child_view_id);
388
389 box_tree
390 .borrow_mut()
391 .reparent(child_element_id.0, Some(parent_element_id.0));
392 }
393 s.children.insert(*self, children_ids.clone());
394 let this_taffy_node = s.state(*self).borrow().layout_id;
395 let _ = layout_tree
396 .borrow_mut()
397 .set_children(this_taffy_node, &children_nodes);
398 children_ids
399 });
400 for child_id in children_ids {
402 reparent_scope_if_needed(child_id, *self);
403 }
404 request_structural_selector_restyle(&self.children());
405 }
406
407 pub fn set_children_vec(&self, children: Vec<impl IntoView>) {
410 self.set_children_iter(children.into_iter().map(|c| c.into_any()));
411 }
412
413 pub fn set_children_iter(&self, children: impl Iterator<Item = Box<dyn View>>) {
420 let children_ids: Vec<ViewId> = VIEW_STORAGE.with_borrow_mut(|s| {
421 let mut children_ids = Vec::new();
422 let mut children_nodes = Vec::new();
423 let box_tree = s.box_tree(*self);
424 let layout_tree = s.taffy.clone();
425 for child_view in children {
426 let child_view_id = child_view.id();
427 let child_element_id = s.state(child_view_id).borrow().element_id;
428 let child_taffy_node = s.state(child_view_id).borrow().layout_id;
429 children_ids.push(child_view_id);
430 children_nodes.push(child_taffy_node);
431 s.parent.insert(child_view_id, Some(*self));
432 s.views
433 .insert(child_view_id, Rc::new(RefCell::new(child_view)));
434 let parent_element_id =
435 box_tree_parent_element_id_for_child(s, *self, child_view_id);
436 box_tree
437 .borrow_mut()
438 .reparent(child_element_id.0, Some(parent_element_id.0));
439 }
440 s.children.insert(*self, children_ids.clone());
441 let this_taffy_node = s.state(*self).borrow().layout_id;
442 let _ = layout_tree
443 .borrow_mut()
444 .set_children(this_taffy_node, &children_nodes);
445 children_ids
446 });
447 for child_id in children_ids {
449 reparent_scope_if_needed(child_id, *self);
450 }
451 request_structural_selector_restyle(&self.children());
452 }
453
454 pub fn set_view(&self, view: Box<dyn View>) {
456 VIEW_STORAGE.with_borrow_mut(|s| {
457 if s.view_ids.contains_key(*self) {
458 s.views.insert(*self, Rc::new(RefCell::new(view)));
459 }
460 });
461 }
462
463 pub fn set_parent(&self, parent: ViewId) {
465 VIEW_STORAGE.with_borrow_mut(|s| {
466 if s.view_ids.contains_key(*self) {
467 let this_element_id = s.state(*self).borrow().element_id;
468 s.parent.insert(*self, Some(parent));
469 let parent_element_id = box_tree_parent_element_id_for_child(s, parent, *self);
470 let box_tree = s.box_tree(*self);
471 box_tree
472 .borrow_mut()
473 .reparent(this_element_id.0, Some(parent_element_id.0));
474 }
475 });
476 }
477
478 pub fn set_children_ids(&self, children: Vec<ViewId>) {
480 VIEW_STORAGE.with_borrow_mut(|s| {
481 if !s.view_ids.contains_key(*self) {
482 return;
483 }
484
485 let this_taffy_node = s.state(*self).borrow().layout_id;
486
487 let child_element_ids: Vec<_> = children
488 .iter()
489 .map(|&child_id| s.state(child_id).borrow().element_id)
490 .collect();
491 let taffy_children: Vec<_> = children
492 .iter()
493 .map(|&child_id| s.state(child_id).borrow().layout_id)
494 .collect();
495
496 let box_tree = s.box_tree(*self);
497 let layout_tree = s.taffy.clone();
498 for (&child_id, child_element_id) in children.iter().zip(child_element_ids) {
499 s.parent.insert(child_id, Some(*self));
500 let parent_element_id = box_tree_parent_element_id_for_child(s, *self, child_id);
501 box_tree
502 .borrow_mut()
503 .reparent(child_element_id.0, Some(parent_element_id.0));
504 }
505
506 let _ = layout_tree
507 .borrow_mut()
508 .set_children(this_taffy_node, &taffy_children);
509 s.children.insert(*self, children);
510 });
511 request_structural_selector_restyle(&self.children());
512 }
513
514 pub fn children(&self) -> Vec<ViewId> {
516 VIEW_STORAGE.with_borrow(|s| s.children.get(*self).cloned().unwrap_or_default())
517 }
518
519 pub fn with_children<R>(&self, mut children: impl FnMut(&[ViewId]) -> R) -> R {
521 VIEW_STORAGE.with_borrow(|s| children(s.children.get(*self).map_or(&[], |v| v)))
522 }
523
524 pub fn parent(&self) -> Option<ViewId> {
526 VIEW_STORAGE.with_borrow(|s| s.parent.get(*self).cloned().flatten())
527 }
528
529 pub fn root(&self) -> ViewId {
531 VIEW_STORAGE.with_borrow(|s| {
532 *s.root.get(*self).expect(
533 "all view ids are entered into the root map and have a root id upon creation",
534 )
535 })
536 }
537
538 pub(crate) fn try_root(&self) -> Option<ViewId> {
540 VIEW_STORAGE.with_borrow(|s| s.root.get(*self).copied())
541 }
542
543 pub fn get_size(&self) -> Option<Size> {
545 self.get_layout()
546 .map(|l| Size::new(l.size.width as f64, l.size.height as f64))
547 }
548
549 pub fn parent_size(&self) -> Option<Size> {
551 let parent_id = self.parent()?;
552 parent_id.get_size()
553 }
554
555 pub fn get_layout(&self) -> Option<Layout> {
557 let widget_parent = self.parent().map(|id| id.state().borrow().layout_id);
558
559 let taffy = self.taffy();
560 let mut node = self.state().borrow().layout_id;
561 let mut layout = *taffy.borrow().layout(node).ok()?;
562
563 loop {
564 let parent = taffy.borrow().parent(node);
565
566 if parent == widget_parent {
567 break;
568 }
569
570 node = parent?;
571
572 layout.location = layout.location + taffy.borrow().layout(node).ok()?.location;
573 }
574
575 Some(layout)
576 }
577
578 pub fn get_element_id(&self) -> ElementId {
582 self.state().borrow().element_id
583 }
584
585 pub fn get_visual_transform(&self) -> peniko::kurbo::Affine {
597 let element_id = self.get_element_id();
598 VIEW_STORAGE.with_borrow_mut(|s| {
599 s.box_tree(*self)
600 .borrow_mut()
601 .world_transform(element_id.0)
602 .unwrap_or_default()
603 })
604 }
605
606 pub fn get_visual_rect(&self) -> Rect {
612 let element_id = self.get_element_id();
613 VIEW_STORAGE.with_borrow_mut(|s| {
614 s.box_tree(*self)
615 .borrow_mut()
616 .world_bounds(element_id.0)
617 .unwrap_or_default()
618 })
619 }
620
621 pub fn get_visual_rect_no_clip(&self) -> Rect {
623 let element_id = self.get_element_id();
624 let transform = self.get_visual_transform();
625 VIEW_STORAGE.with_borrow_mut(|s| {
626 let box_tree = s.box_tree(*self);
627
628 transform.transform_rect_bbox(
629 box_tree
630 .borrow()
631 .local_bounds(element_id.0)
632 .unwrap_or_default(),
633 )
634 })
635 }
636
637 pub fn get_visual_origin(&self) -> peniko::kurbo::Point {
639 let element_id = self.get_element_id();
640 VIEW_STORAGE
641 .with_borrow_mut(|s| {
642 s.box_tree(*self)
643 .borrow_mut()
644 .world_bounds(element_id.0)
645 .unwrap_or_default()
646 })
647 .origin()
648 }
649
650 pub fn get_layout_rect(&self) -> Rect {
656 self.get_layout()
657 .map(|l| Rect {
658 x0: f64::from(l.location.x),
659 y0: f64::from(l.location.y),
660 x1: f64::from(l.location.x + l.size.width),
661 y1: f64::from(l.location.y + l.size.height),
662 })
663 .unwrap_or_default()
664 }
665
666 pub fn get_content_rect(&self) -> Rect {
672 self.get_layout()
673 .map(|l| Rect {
674 x0: f64::from(l.content_box_x()),
675 y0: f64::from(l.content_box_y()),
676 x1: f64::from(l.content_box_x() + l.content_box_width()),
677 y1: f64::from(l.content_box_y() + l.content_box_height()),
678 })
679 .unwrap_or_default()
680 }
681
682 pub fn get_layout_rect_local(&self) -> Rect {
684 self.get_layout()
685 .map(|l| Rect {
686 x0: 0.0,
687 y0: 0.0,
688 x1: f64::from(l.size.width),
689 y1: f64::from(l.size.height),
690 })
691 .unwrap_or_default()
692 }
693
694 pub fn get_content_rect_local(&self) -> Rect {
703 self.get_layout()
704 .map(|r| {
705 let x0 = f64::from(r.border.left + r.padding.left);
706 let y0 = f64::from(r.border.top + r.padding.top);
707 let x1 = x0 + f64::from(r.content_box_width());
708 let y1 = y0 + f64::from(r.content_box_height());
709 Rect { x0, y0, x1, y1 }
710 })
711 .unwrap_or_default()
712 }
713
714 pub fn get_content_rect_relative(
721 &self,
722 child_node: taffy::NodeId,
723 parent_node: taffy::NodeId,
724 ) -> Option<Rect> {
725 let taffy = self.taffy();
726 let taffy = taffy.borrow();
727 let mut node = child_node;
728 let mut child_layout = *taffy.layout(node).ok()?;
729
730 loop {
732 let current_parent = taffy.parent(node);
733
734 if current_parent == Some(parent_node) {
735 break;
736 }
737
738 node = current_parent?;
739 child_layout.location = child_layout.location + taffy.layout(node).ok()?.location;
740 }
741
742 Some(Rect::from_origin_size(
744 (
745 f64::from(child_layout.content_box_x()),
746 f64::from(child_layout.content_box_y()),
747 ),
748 (
749 f64::from(child_layout.content_box_width()),
750 f64::from(child_layout.content_box_height()),
751 ),
752 ))
753 }
754
755 pub fn set_child_translation(&self, child_translation: peniko::kurbo::Vec2) -> bool {
759 let state = self.state();
760 let needs_box_tree_update = {
761 let mut state = state.borrow_mut();
762 if state.child_translation != child_translation {
763 state.child_translation = child_translation;
764 true
765 } else {
766 false
767 }
768 };
769 if needs_box_tree_update {
770 for child in self.children() {
771 child.request_box_tree_update_for_view();
772 }
773 }
774 needs_box_tree_update
775 }
776
777 pub fn get_child_translation(&self) -> peniko::kurbo::Vec2 {
779 self.state().borrow().child_translation
780 }
781
782 pub fn set_box_tree_clip(&self, clip: Option<RoundedRect>) {
784 let element_id = self.get_element_id();
785 VIEW_STORAGE.with_borrow_mut(|s| {
786 let box_tree = s.box_tree(*self);
787 box_tree.borrow_mut().set_local_clip(element_id.0, clip);
788 })
789 }
790
791 pub fn is_hidden(&self) -> bool {
793 let state = self.state();
794 let state = state.borrow();
795 state.visibility.is_hidden()
796 }
797
798 pub fn pointer_events_none(&self) -> bool {
800 let state = self.state();
801 let state = state.borrow();
802 state
803 .computed_style
804 .builtin()
805 .pointer_events()
806 .map(|p| p == PointerEvents::None)
807 .unwrap_or(false)
808 }
809
810 pub fn is_disabled(&self) -> bool {
814 self.state().borrow_mut().style_interaction_cx.disabled
815 }
816
817 pub fn is_selected(&self) -> bool {
822 self.state().borrow().parent_set_style_interaction.selected
823 }
824
825 pub fn can_focus(&self) -> bool {
829 self.state()
830 .borrow()
831 .computed_style
832 .get(Focusable)
833 .is_focusable()
834 }
835
836 pub fn request_all(&self) {
839 add_update_message(UpdateMessage::RequestStyle(
840 self.get_element_id(),
841 StyleReason::full_recalc(),
842 ));
843 self.request_layout();
844 self.request_box_tree_commit();
845 self.add_update_message(UpdateMessage::RequestPaint);
846 }
847
848 pub fn request_layout(&self) {
850 add_update_message(UpdateMessage::RequestLayout);
851 }
852
853 pub fn request_mark_view_layout_dirty(&self) {
855 add_update_message(UpdateMessage::MarkViewLayoutDirty(*self));
856 }
857
858 pub fn request_box_tree_update(&self) {
861 add_update_message(UpdateMessage::RequestBoxTreeUpdate);
862 }
863
864 pub fn request_box_tree_update_for_view(&self) {
868 add_update_message(UpdateMessage::RequestBoxTreeUpdateForView(*self));
869 }
870
871 pub fn request_box_tree_commit(&self) {
874 add_update_message(UpdateMessage::RequestBoxTreeCommit);
875 }
876
877 pub fn window_id(&self) -> Option<WindowId> {
879 window_id_for_root(self.root())
880 }
881
882 pub fn request_paint(&self) {
884 self.add_update_message(UpdateMessage::RequestPaint);
885 }
886
887 pub fn request_style(&self, reason: StyleReason) {
889 self.add_update_message(UpdateMessage::RequestStyle(self.get_element_id(), reason));
890 }
891
892 #[deprecated(note = "use `id.request_style(StyleReasonSet::view_style())` directly instead")]
896 pub fn request_view_style(&self) {
897 self.request_style(StyleReason::view_style());
898 }
899
900 pub fn request_focus(&self) {
902 self.add_update_message(UpdateMessage::Focus(self.get_element_id()));
903 }
904
905 pub fn clear_focus(&self) {
907 self.add_update_message(UpdateMessage::ClearFocus);
908 }
909
910 pub fn update_context_menu(&self, menu: impl Fn() -> Menu + 'static) {
912 self.state().borrow_mut().context_menu = Some(Rc::new(menu));
913 }
914
915 pub fn update_popout_menu(&self, menu: impl Fn() -> Menu + 'static) {
919 self.state().borrow_mut().popout_menu = Some(Rc::new(menu));
920 }
921
922 pub fn set_pointer_capture(&self, pointer_id: PointerId) {
956 self.add_update_message(UpdateMessage::SetPointerCapture {
957 element_id: self.get_element_id(),
958 pointer_id,
959 });
960 }
961
962 pub fn release_pointer_capture(&self, pointer_id: PointerId) {
971 self.add_update_message(UpdateMessage::ReleasePointerCapture {
972 element_id: self.get_element_id(),
973 pointer_id,
974 });
975 }
976
977 pub fn inspect(&self) {
979 self.add_update_message(UpdateMessage::Inspect);
980 }
981
982 pub fn scroll_to(&self, rect: Option<Rect>) {
985 self.add_update_message(UpdateMessage::ScrollTo {
986 id: self.get_element_id(),
987 rect,
988 });
989 }
990
991 pub(crate) fn transition_anim_complete(&self) {
992 self.add_update_message(UpdateMessage::ViewTransitionAnimComplete(*self));
993 }
994
995 pub(crate) fn update_animation(&self, offset: StackOffset<Animation>, animation: Animation) {
996 let state = self.state();
997 state.borrow_mut().animations.set(offset, animation);
998 self.request_style(StyleReason::animation());
999 }
1000
1001 pub(crate) fn update_animation_state(
1002 &self,
1003 offset: StackOffset<Animation>,
1004 command: AnimStateCommand,
1005 ) {
1006 let view_state = self.state();
1007 view_state
1008 .borrow_mut()
1009 .animations
1010 .update(offset, move |anim| anim.transition(command));
1011 self.request_style(StyleReason::animation());
1012 }
1013
1014 pub fn update_state(&self, state: impl Any) {
1016 self.add_update_message(UpdateMessage::State {
1017 id: *self,
1018 state: Box::new(state),
1019 });
1020 }
1021
1022 pub(crate) fn add_event_listener(
1024 &self,
1025 listener: EventListenerKey,
1026 action: Box<EventCallback>,
1027 config: EventCallbackConfig,
1028 ) {
1029 add_update_message(crate::message::UpdateMessage::RegisterListener(
1030 listener, *self,
1031 ));
1032 let state = self.state();
1033 state
1034 .borrow_mut()
1035 .add_event_listener(listener, action, config);
1036 }
1037
1038 pub fn add_cleanup_listener(&self, action: Rc<dyn Fn()>) {
1040 let state = self.state();
1041 state.borrow_mut().add_cleanup_listener(action);
1042 }
1043
1044 pub fn get_combined_style(&self) -> Style {
1070 self.state().borrow().combined_style.clone()
1071 }
1072
1073 pub fn add_class(&self, class: StyleClassRef) {
1075 let state = self.state();
1076 state.borrow_mut().classes.push(class);
1077 self.request_style(StyleReason::class_cx(smallvec![class]));
1078 }
1079
1080 pub fn remove_class(&self, class: StyleClassRef) {
1082 let state = self.state();
1083 state.borrow_mut().classes.retain_mut(|c| *c != class);
1084 self.request_style(StyleReason::class_cx(smallvec![class]));
1085 }
1086
1087 pub(crate) fn update_style(&self, offset: StackOffset<Style>, style: Style) {
1088 let state = VIEW_STORAGE.with_borrow(|s| s.states.get(*self).cloned());
1089 if let Some(state) = state {
1090 state.borrow_mut().style.set(offset, style);
1091 self.request_style(StyleReason::full_recalc());
1092 }
1093 }
1094
1095 pub fn set_cursor(&self, cursor: Option<crate::style::CursorStyle>) {
1099 self.state().borrow_mut().user_cursor = cursor;
1100 }
1101
1102 pub fn disable_default_event(&self, event: EventListenerKey) {
1106 self.state()
1107 .borrow_mut()
1108 .disable_default_events
1109 .insert(event);
1110 }
1111
1112 pub fn remove_disable_default_event(&self, event: EventListenerKey) {
1114 self.state()
1115 .borrow_mut()
1116 .disable_default_events
1117 .remove(&event);
1118 }
1119
1120 pub fn window_visible(&self, visible: bool) {
1123 self.add_update_message(UpdateMessage::WindowVisible(visible));
1124 }
1125
1126 pub fn request_remove_views(&self, view_ids: Vec<ViewId>) {
1132 if !view_ids.is_empty() {
1133 self.add_update_message(UpdateMessage::RemoveViews(view_ids));
1134 }
1135 }
1136
1137 pub fn add_child_deferred(&self, child_fn: impl FnOnce() -> AnyView + 'static) {
1143 self.add_update_message(UpdateMessage::AddChild {
1144 parent_id: *self,
1145 child: DeferredChild::new(child_fn),
1146 });
1147 }
1148
1149 pub fn add_children_deferred(&self, children_fn: impl FnOnce() -> Vec<AnyView> + 'static) {
1155 self.add_update_message(UpdateMessage::AddChildren {
1156 parent_id: *self,
1157 children: DeferredChildren::new(children_fn),
1158 });
1159 }
1160
1161 pub fn setup_reactive_children_deferred(&self, setup: impl FnOnce() + 'static) {
1167 self.add_update_message(UpdateMessage::SetupReactiveChildren {
1168 setup: DeferredReactiveSetup::new(*self, setup),
1169 });
1170 }
1171
1172 fn add_update_message(&self, msg: UpdateMessage) {
1173 let _ = CENTRAL_UPDATE_MESSAGES.try_with(|msgs| {
1174 let mut msgs = msgs.borrow_mut();
1175 msgs.push((*self, msg));
1176 });
1177 }
1178
1179 pub fn update_state_deferred(&self, state: impl Any) {
1182 CENTRAL_DEFERRED_UPDATE_MESSAGES.with_borrow_mut(|msgs| {
1183 msgs.push((*self, Box::new(state)));
1184 });
1185 }
1186
1187 pub fn screen_layout(&self) -> Option<ScreenLayout> {
1189 crate::layout::try_create_screen_layout(self)
1190 }
1191
1192 pub fn set_style_parent(&self, parent_id: ViewId) {
1195 self.state().borrow_mut().style_cx_parent = Some(parent_id);
1196 }
1197
1198 pub fn clear_style_parent(&self) {
1200 self.state().borrow_mut().style_cx_parent = None;
1201 }
1202
1203 pub fn set_children_scope(&self, scope: Scope) {
1208 self.state().borrow_mut().children_scope = Some(scope);
1209 }
1210
1211 pub fn take_children_scope(&self) -> Option<Scope> {
1215 self.state().borrow_mut().children_scope.take()
1216 }
1217
1218 pub fn set_keyed_children(&self, children: Vec<(ViewId, Scope)>) {
1223 self.state().borrow_mut().keyed_children = Some(children);
1224 }
1225
1226 pub fn take_keyed_children(&self) -> Option<Vec<(ViewId, Scope)>> {
1230 self.state().borrow_mut().keyed_children.take()
1231 }
1232
1233 pub fn set_scope(&self, scope: Scope) {
1242 self.state().borrow_mut().scope = Some(scope);
1243 }
1244
1245 pub fn scope(&self) -> Option<Scope> {
1247 self.state().borrow().scope
1248 }
1249
1250 pub fn find_scope(&self) -> Option<Scope> {
1255 if let Some(scope) = self.scope() {
1257 return Some(scope);
1258 }
1259 let mut current = self.parent();
1261 while let Some(parent_id) = current {
1262 if let Some(scope) = parent_id.scope() {
1263 return Some(scope);
1264 }
1265 current = parent_id.parent();
1266 }
1267 None
1268 }
1269
1270 pub fn get_local_clip(&self) -> Option<RoundedRect> {
1272 let element_id = self.get_element_id();
1273 VIEW_STORAGE
1274 .with_borrow_mut(|s| {
1275 let box_tree = s.box_tree(*self);
1276 box_tree.borrow().local_clip(element_id.0)
1277 })
1278 .flatten()
1279 }
1280
1281 pub fn create_child_element_id(&self, z_index: i32) -> ElementId {
1285 let parent_box_node = self.get_element_id();
1286 VIEW_STORAGE.with_borrow_mut(|s| {
1287 let box_tree = s.box_tree(*self);
1288 let child_element_id = box_tree.borrow_mut().push_child(
1289 Some(parent_box_node.0),
1290 understory_box_tree::LocalNode::default(),
1291 );
1292 let element_id = ElementId(child_element_id, *self, false);
1293 box_tree
1294 .borrow_mut()
1295 .set_element_meta(child_element_id, Some(crate::ElementMeta::new(element_id)));
1296 box_tree.borrow_mut().set_z_index(child_element_id, z_index);
1297 element_id
1298 })
1299 }
1300
1301 pub fn focus_nav_meta_for_element(&self, element_id: ElementId) -> Option<FocusNavMeta> {
1303 let box_tree = self.box_tree();
1304 box_tree.borrow().focus_nav_meta(element_id.0)
1305 }
1306
1307 pub fn set_focus_nav_meta_for_element(
1311 &self,
1312 element_id: ElementId,
1313 focus: FocusNavMeta,
1314 ) -> bool {
1315 debug_assert_eq!(
1316 element_id.owning_id(),
1317 *self,
1318 "element must be owned by this view"
1319 );
1320 let box_tree = self.box_tree();
1321 let mut box_tree = box_tree.borrow_mut();
1322 if !box_tree.set_focus_nav_meta(element_id.0, focus) {
1323 return false;
1324 }
1325 crate::bump_focus_nav_meta_revision();
1326 true
1327 }
1328
1329 pub fn set_focusable_for_element(&self, element_id: ElementId, focusable: bool) -> bool {
1333 debug_assert_eq!(
1334 element_id.owning_id(),
1335 *self,
1336 "element must be owned by this view"
1337 );
1338 let box_tree = self.box_tree();
1339 let mut box_tree = box_tree.borrow_mut();
1340 if !box_tree.set_focusable(element_id.0, focusable) {
1341 return false;
1342 }
1343 crate::bump_focus_nav_meta_revision();
1344 true
1345 }
1346
1347 pub fn set_keyboard_navigable_for_element(
1351 &self,
1352 element_id: ElementId,
1353 keyboard_navigable: bool,
1354 ) -> bool {
1355 debug_assert_eq!(
1356 element_id.owning_id(),
1357 *self,
1358 "element must be owned by this view"
1359 );
1360 let box_tree = self.box_tree();
1361 let mut box_tree = box_tree.borrow_mut();
1362 if !box_tree.set_keyboard_navigable(element_id.0, keyboard_navigable) {
1363 return false;
1364 }
1365 crate::bump_focus_nav_meta_revision();
1366 true
1367 }
1368
1369 pub fn set_focus_group_for_element(
1371 &self,
1372 element_id: ElementId,
1373 group: Option<understory_focus::FocusSymbol>,
1374 ) -> bool {
1375 let Some(mut focus) = self.focus_nav_meta_for_element(element_id) else {
1376 return false;
1377 };
1378 focus.group = group;
1379 self.set_focus_nav_meta_for_element(element_id, focus)
1380 }
1381
1382 pub fn register_listener(&self, key: listener::EventListenerKey) {
1388 self.add_update_message(UpdateMessage::RegisterListener(key, *self));
1389 }
1390
1391 pub fn remove_listener(&self, key: listener::EventListenerKey) {
1393 self.add_update_message(UpdateMessage::RemoveListener(key, *self));
1394 }
1395
1396 pub(crate) fn get_layout_window_origin(&self) -> Point {
1397 let element_id = self.get_element_id();
1398 VIEW_STORAGE.with_borrow_mut(|s| {
1399 s.box_tree(*self)
1400 .borrow_mut()
1401 .world_transform(element_id.0)
1402 .unwrap_or_default()
1403 * Point::ZERO
1404 })
1405 }
1406
1407 pub fn route_event(&self, event: crate::event::Event, route_kind: RouteKind) {
1455 self.route_event_with_caused_by(event, route_kind, None);
1456 }
1457
1458 pub fn route_event_with_caused_by(
1469 &self,
1470 event: crate::event::Event,
1471 route_kind: RouteKind,
1472 caused_by: Option<crate::event::Event>,
1473 ) {
1474 self.add_update_message(UpdateMessage::RouteEvent {
1475 id: self.get_element_id(),
1476 event: Box::new(event),
1477 route_kind,
1478 triggered_by: caused_by.map(Box::new),
1479 });
1480 }
1481}
1482
1483impl From<ViewId> for ElementId {
1484 fn from(value: ViewId) -> Self {
1485 value.get_element_id()
1486 }
1487}
1488
1489fn reparent_scope_if_needed(child_id: ViewId, parent_id: ViewId) {
1503 let child_scope = child_id.scope();
1505 if let Some(child_scope) = child_scope {
1506 if let Some(parent_scope) = parent_id.find_scope() {
1508 if child_scope != parent_scope {
1510 child_scope.set_parent(parent_scope);
1512 }
1513 } else {
1514 PENDING_SCOPE_REPARENTS.with_borrow_mut(|pending| {
1517 pending.insert(child_id);
1518 });
1519 }
1520 }
1521}
1522
1523pub fn process_pending_scope_reparents() {
1529 let has_pending = PENDING_SCOPE_REPARENTS.with_borrow(|pending| !pending.is_empty());
1531 if !has_pending {
1532 return;
1533 }
1534
1535 PENDING_SCOPE_REPARENTS.with_borrow_mut(|pending| {
1536 pending.retain(|child_id| {
1537 if !child_id.is_valid() {
1540 return false; }
1542
1543 let child_scope = child_id.scope();
1545 if let Some(child_scope) = child_scope {
1546 if let Some(parent_id) = child_id.parent()
1548 && let Some(parent_scope) = parent_id.find_scope()
1549 {
1550 if child_scope != parent_scope {
1552 child_scope.set_parent(parent_scope);
1553 }
1554 return false; }
1556 true } else {
1558 false }
1560 });
1561 });
1562}
1563
1564fn box_tree_parent_element_id_for_child(
1565 storage: &mut ViewStorage,
1566 logical_parent_id: ViewId,
1567 child_id: ViewId,
1568) -> ElementId {
1569 if storage.overlays.contains_key(child_id) {
1570 let root_id = *storage
1571 .root
1572 .get(child_id)
1573 .expect("all view ids are created with a root");
1574 storage.state(root_id).borrow().element_id
1575 } else {
1576 storage.state(logical_parent_id).borrow().element_id
1577 }
1578}
1579
1580impl ViewId {
1581 pub fn parent_set_selected(&self) {
1585 let changed = {
1586 let state = self.state();
1587 let mut state = state.borrow_mut();
1588 if !state.parent_set_style_interaction.selected {
1589 state.parent_set_style_interaction.selected = true;
1590 true
1591 } else {
1592 false
1593 }
1594 };
1595 if changed {
1596 self.request_style(StyleReason::with_selector(StyleSelector::Selected));
1597 }
1598 }
1599
1600 pub fn parent_clear_selected(&self) {
1604 let changed = {
1605 let state = self.state();
1606 let mut state = state.borrow_mut();
1607 if state.parent_set_style_interaction.selected {
1608 state.parent_set_style_interaction.selected = false;
1609 true
1610 } else {
1611 false
1612 }
1613 };
1614 if changed {
1615 self.request_style(StyleReason::with_selector(StyleSelector::Selected));
1616 }
1617 }
1618
1619 pub fn parent_set_disabled(&self) {
1623 let changed = {
1624 let state = self.state();
1625 let mut state = state.borrow_mut();
1626 if !state.parent_set_style_interaction.disabled {
1627 state.parent_set_style_interaction.disabled = true;
1628 true
1629 } else {
1630 false
1631 }
1632 };
1633 if changed {
1634 self.request_style(StyleReason::with_selector(StyleSelector::Disabled));
1635 }
1636 }
1637
1638 pub fn parent_clear_disabled(&self) {
1642 let changed = {
1643 let state = self.state();
1644 let mut state = state.borrow_mut();
1645 if state.parent_set_style_interaction.disabled {
1646 state.parent_set_style_interaction.disabled = false;
1647 true
1648 } else {
1649 false
1650 }
1651 };
1652 if changed {
1653 self.request_style(StyleReason::with_selector(StyleSelector::Disabled));
1654 }
1655 }
1656
1657 pub fn set_hidden(&self) {
1662 use crate::view::state::VisibilityPhase;
1663 let changed = {
1664 let state = self.state();
1665 let mut state = state.borrow_mut();
1666 if !state.parent_set_style_interaction.hidden {
1667 state.parent_set_style_interaction.hidden = true;
1668 state.visibility.phase = VisibilityPhase::Hidden;
1669 true
1670 } else {
1671 false
1672 }
1673 };
1674 if changed {
1675 self.request_style(StyleReason::visibility());
1676 }
1677 }
1678
1679 pub fn set_visible(&self) {
1683 use crate::view::state::VisibilityPhase;
1684 let changed = {
1685 let state = self.state();
1686 let mut state = state.borrow_mut();
1687 if state.parent_set_style_interaction.hidden {
1688 state.parent_set_style_interaction.hidden = false;
1689 state.visibility.phase = VisibilityPhase::Initial;
1691 true
1692 } else {
1693 false
1694 }
1695 };
1696 if changed {
1697 self.request_style(StyleReason::visibility());
1698 }
1699 }
1700}