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 s.box_tree(*self)
213 .borrow_mut()
214 .reparent(this_element_id.0, Some(parent_element_id.0));
215 }
216 });
217 }
218
219 #[expect(dead_code)] pub(crate) fn unregister_overlay(&self) {
222 VIEW_STORAGE.with_borrow_mut(|s| {
223 s.overlays.remove(*self);
224 if let Some(logical_parent_id) = s.parent.get(*self).and_then(|p| *p) {
225 let this_element_id = s.state(*self).borrow().element_id;
226 let parent_element_id = s.state(logical_parent_id).borrow().element_id;
227 s.box_tree(*self)
228 .borrow_mut()
229 .reparent(this_element_id.0, Some(parent_element_id.0));
230 }
231 });
232 }
233
234 pub fn taffy(&self) -> Rc<RefCell<LayoutTree>> {
237 VIEW_STORAGE.with_borrow_mut(|s| s.taffy.clone())
238 }
239
240 pub fn box_tree(&self) -> Rc<RefCell<BoxTree>> {
242 VIEW_STORAGE.with_borrow_mut(|s| s.box_tree(*self))
243 }
244
245 pub fn new_taffy_node(&self) -> NodeId {
247 self.taffy()
248 .borrow_mut()
249 .new_leaf(taffy::style::Style::DEFAULT)
250 .unwrap()
251 }
252
253 pub fn set_taffy_style(&self, node: NodeId, style: taffy::Style) {
255 let _ = self.taffy().borrow_mut().set_style(node, style);
256 }
257
258 pub fn taffy_layout(&self, node: NodeId) -> Option<taffy::Layout> {
260 self.taffy().borrow().layout(node).cloned().ok()
261 }
262
263 pub fn mark_view_layout_dirty(&self) -> taffy::TaffyResult<()> {
265 let node = self.taffy_node();
266 self.taffy().borrow_mut().mark_dirty(node)
267 }
268 pub fn taffy_node(&self) -> NodeId {
270 self.state().borrow().layout_id
271 }
272
273 pub fn set_transform(&self, transform: Affine) {
275 self.state().borrow_mut().transform = transform;
276 self.request_box_tree_update_for_view();
277 }
278
279 pub(crate) fn state(&self) -> Rc<RefCell<ViewState>> {
280 VIEW_STORAGE.with_borrow_mut(|s| s.state(*self))
281 }
282
283 pub(crate) fn view(&self) -> Rc<RefCell<Box<dyn View>>> {
285 VIEW_STORAGE.with_borrow(|s| {
286 s.views.get(*self).cloned().unwrap_or_else(|| {
287 s.stale_view.clone()
289 })
290 })
291 }
292
293 pub fn add_child(&self, child: Box<dyn View>) {
295 let child_id = child.id();
296 let child_element_id = child_id.get_element_id();
297 VIEW_STORAGE.with_borrow_mut(|s| {
298 s.children.entry(*self).unwrap().or_default().push(child_id);
299 s.parent.insert(child_id, Some(*self));
300 s.views.insert(child_id, Rc::new(RefCell::new(child)));
301 let parent_element_id = box_tree_parent_element_id_for_child(s, *self, child_id);
302 s.box_tree(child_id)
303 .borrow_mut()
304 .reparent(child_element_id.0, Some(parent_element_id.0));
305 let child_taffy_node = s.state(child_id).borrow().layout_id;
306 let this_taffy_node = s.state(*self).borrow().layout_id;
307 let _ = s
308 .taffy
309 .borrow_mut()
310 .add_child(this_taffy_node, child_taffy_node);
311 });
312 reparent_scope_if_needed(child_id, *self);
315 request_structural_selector_restyle(&self.children());
316 }
317
318 pub fn append_children(&self, children: Vec<Box<dyn View>>) {
326 let child_ids: Vec<ViewId> = children.iter().map(|c| c.id()).collect();
327 VIEW_STORAGE.with_borrow_mut(|s| {
328 let this_taffy_node = s.state(*self).borrow().layout_id;
329 let child_element_ids: Vec<_> = children
330 .iter()
331 .map(|c| s.state(c.id()).borrow().element_id)
332 .collect();
333 let child_taffy_nodes: Vec<_> = children
334 .iter()
335 .map(|c| s.state(c.id()).borrow().layout_id)
336 .collect();
337
338 let box_tree = s.box_tree(*self);
339 let layout_tree = s.taffy.clone();
340
341 for ((child, child_element_id), child_taffy_node) in children
342 .into_iter()
343 .zip(child_element_ids)
344 .zip(child_taffy_nodes)
345 {
346 let child_id = child.id();
347 s.children.entry(*self).unwrap().or_default().push(child_id);
348 s.parent.insert(child_id, Some(*self));
349 s.views.insert(child_id, Rc::new(RefCell::new(child)));
350 let parent_element_id = box_tree_parent_element_id_for_child(s, *self, child_id);
351 box_tree
352 .borrow_mut()
353 .reparent(child_element_id.0, Some(parent_element_id.0));
354 let _ = layout_tree
355 .borrow_mut()
356 .add_child(this_taffy_node, child_taffy_node);
357 }
358 });
359 for child_id in child_ids {
361 reparent_scope_if_needed(child_id, *self);
362 }
363 request_structural_selector_restyle(&self.children());
364 }
365
366 pub fn set_children<const N: usize, V: IntoView>(&self, children: [V; N]) {
369 let children_ids: Vec<ViewId> = VIEW_STORAGE.with_borrow_mut(|s| {
370 let mut children_ids = Vec::new();
371 let mut children_nodes = Vec::with_capacity(children.len());
372 let box_tree = s.box_tree(*self);
373 let layout_tree = s.taffy.clone();
374 for child in children {
375 let child_view = child.into_view();
376 let child_view_id = child_view.id();
377 let child_element_id = s.state(child_view_id).borrow().element_id;
378 let child_taffy_node = s.state(child_view_id).borrow().layout_id;
379 children_nodes.push(child_taffy_node);
380 children_ids.push(child_view_id);
381 s.parent.insert(child_view_id, Some(*self));
382 s.views
383 .insert(child_view_id, Rc::new(RefCell::new(child_view.into_any())));
384 let parent_element_id =
385 box_tree_parent_element_id_for_child(s, *self, child_view_id);
386
387 box_tree
388 .borrow_mut()
389 .reparent(child_element_id.0, Some(parent_element_id.0));
390 }
391 s.children.insert(*self, children_ids.clone());
392 let this_taffy_node = s.state(*self).borrow().layout_id;
393 let _ = layout_tree
394 .borrow_mut()
395 .set_children(this_taffy_node, &children_nodes);
396 children_ids
397 });
398 for child_id in children_ids {
400 reparent_scope_if_needed(child_id, *self);
401 }
402 request_structural_selector_restyle(&self.children());
403 }
404
405 pub fn set_children_vec(&self, children: Vec<impl IntoView>) {
408 self.set_children_iter(children.into_iter().map(|c| c.into_any()));
409 }
410
411 pub fn set_children_iter(&self, children: impl Iterator<Item = Box<dyn View>>) {
418 let children_ids: Vec<ViewId> = VIEW_STORAGE.with_borrow_mut(|s| {
419 let mut children_ids = Vec::new();
420 let mut children_nodes = Vec::new();
421 let box_tree = s.box_tree(*self);
422 let layout_tree = s.taffy.clone();
423 for child_view in children {
424 let child_view_id = child_view.id();
425 let child_element_id = s.state(child_view_id).borrow().element_id;
426 let child_taffy_node = s.state(child_view_id).borrow().layout_id;
427 children_ids.push(child_view_id);
428 children_nodes.push(child_taffy_node);
429 s.parent.insert(child_view_id, Some(*self));
430 s.views
431 .insert(child_view_id, Rc::new(RefCell::new(child_view)));
432 let parent_element_id =
433 box_tree_parent_element_id_for_child(s, *self, child_view_id);
434 box_tree
435 .borrow_mut()
436 .reparent(child_element_id.0, Some(parent_element_id.0));
437 }
438 s.children.insert(*self, children_ids.clone());
439 let this_taffy_node = s.state(*self).borrow().layout_id;
440 let _ = layout_tree
441 .borrow_mut()
442 .set_children(this_taffy_node, &children_nodes);
443 children_ids
444 });
445 for child_id in children_ids {
447 reparent_scope_if_needed(child_id, *self);
448 }
449 request_structural_selector_restyle(&self.children());
450 }
451
452 pub fn set_view(&self, view: Box<dyn View>) {
454 VIEW_STORAGE.with_borrow_mut(|s| {
455 if s.view_ids.contains_key(*self) {
456 s.views.insert(*self, Rc::new(RefCell::new(view)));
457 }
458 });
459 }
460
461 pub fn set_parent(&self, parent: ViewId) {
463 VIEW_STORAGE.with_borrow_mut(|s| {
464 if s.view_ids.contains_key(*self) {
465 let this_element_id = s.state(*self).borrow().element_id;
466 s.parent.insert(*self, Some(parent));
467 let parent_element_id = box_tree_parent_element_id_for_child(s, parent, *self);
468 let box_tree = s.box_tree(*self);
469 box_tree
470 .borrow_mut()
471 .reparent(this_element_id.0, Some(parent_element_id.0));
472 }
473 });
474 }
475
476 pub fn set_children_ids(&self, children: Vec<ViewId>) {
478 VIEW_STORAGE.with_borrow_mut(|s| {
479 if !s.view_ids.contains_key(*self) {
480 return;
481 }
482
483 let this_taffy_node = s.state(*self).borrow().layout_id;
484
485 let child_element_ids: Vec<_> = children
486 .iter()
487 .map(|&child_id| s.state(child_id).borrow().element_id)
488 .collect();
489 let taffy_children: Vec<_> = children
490 .iter()
491 .map(|&child_id| s.state(child_id).borrow().layout_id)
492 .collect();
493
494 let box_tree = s.box_tree(*self);
495 let layout_tree = s.taffy.clone();
496 for (&child_id, child_element_id) in children.iter().zip(child_element_ids) {
497 s.parent.insert(child_id, Some(*self));
498 let parent_element_id = box_tree_parent_element_id_for_child(s, *self, child_id);
499 box_tree
500 .borrow_mut()
501 .reparent(child_element_id.0, Some(parent_element_id.0));
502 }
503
504 let _ = layout_tree
505 .borrow_mut()
506 .set_children(this_taffy_node, &taffy_children);
507 s.children.insert(*self, children);
508 });
509 request_structural_selector_restyle(&self.children());
510 }
511
512 pub fn children(&self) -> Vec<ViewId> {
514 VIEW_STORAGE.with_borrow(|s| s.children.get(*self).cloned().unwrap_or_default())
515 }
516
517 pub fn with_children<R>(&self, mut children: impl FnMut(&[ViewId]) -> R) -> R {
519 VIEW_STORAGE.with_borrow(|s| children(s.children.get(*self).map_or(&[], |v| v)))
520 }
521
522 pub fn parent(&self) -> Option<ViewId> {
524 VIEW_STORAGE.with_borrow(|s| s.parent.get(*self).cloned().flatten())
525 }
526
527 pub fn root(&self) -> ViewId {
529 VIEW_STORAGE.with_borrow(|s| {
530 *s.root.get(*self).expect(
531 "all view ids are entered into the root map and have a root id upon creation",
532 )
533 })
534 }
535
536 pub(crate) fn try_root(&self) -> Option<ViewId> {
538 VIEW_STORAGE.with_borrow(|s| s.root.get(*self).copied())
539 }
540
541 pub fn get_size(&self) -> Option<Size> {
543 self.get_layout()
544 .map(|l| Size::new(l.size.width as f64, l.size.height as f64))
545 }
546
547 pub fn parent_size(&self) -> Option<Size> {
549 let parent_id = self.parent()?;
550 parent_id.get_size()
551 }
552
553 pub fn get_scroll_cx(&self) -> peniko::kurbo::Vec2 {
555 self.state().borrow().scroll_cx
556 }
557
558 pub fn get_layout(&self) -> Option<Layout> {
560 let widget_parent = self.parent().map(|id| id.state().borrow().layout_id);
561
562 let taffy = self.taffy();
563 let mut node = self.state().borrow().layout_id;
564 let mut layout = *taffy.borrow().layout(node).ok()?;
565
566 loop {
567 let parent = taffy.borrow().parent(node);
568
569 if parent == widget_parent {
570 break;
571 }
572
573 node = parent?;
574
575 layout.location = layout.location + taffy.borrow().layout(node).ok()?.location;
576 }
577
578 Some(layout)
579 }
580
581 pub fn get_element_id(&self) -> ElementId {
585 self.state().borrow().element_id
586 }
587
588 pub fn get_visual_transform(&self) -> peniko::kurbo::Affine {
600 let element_id = self.get_element_id();
601 VIEW_STORAGE.with_borrow_mut(|s| {
602 s.box_tree(*self)
603 .borrow_mut()
604 .get_or_compute_world_transform(element_id.0)
605 .unwrap_or_default()
606 })
607 }
608
609 pub fn get_visual_rect(&self) -> Rect {
615 let element_id = self.get_element_id();
616 VIEW_STORAGE.with_borrow_mut(|s| {
617 s.box_tree(*self)
618 .borrow_mut()
619 .get_or_compute_world_bounds(element_id.0)
620 .unwrap_or_default()
621 })
622 }
623
624 pub fn get_visual_rect_no_clip(&self) -> Rect {
626 let element_id = self.get_element_id();
627 let transform = self.get_visual_transform();
628 VIEW_STORAGE.with_borrow_mut(|s| {
629 let box_tree = s.box_tree(*self);
630
631 transform.transform_rect_bbox(
632 box_tree
633 .borrow()
634 .local_bounds(element_id.0)
635 .unwrap_or_default(),
636 )
637 })
638 }
639
640 pub fn get_visual_origin(&self) -> peniko::kurbo::Point {
642 let element_id = self.get_element_id();
643 VIEW_STORAGE
644 .with_borrow_mut(|s| {
645 s.box_tree(*self)
646 .borrow_mut()
647 .get_or_compute_world_bounds(element_id.0)
648 .unwrap_or_default()
649 })
650 .origin()
651 }
652
653 pub fn get_layout_rect(&self) -> Rect {
659 self.get_layout()
660 .map(|l| Rect {
661 x0: f64::from(l.location.x),
662 y0: f64::from(l.location.y),
663 x1: f64::from(l.location.x + l.size.width),
664 y1: f64::from(l.location.y + l.size.height),
665 })
666 .unwrap_or_default()
667 }
668
669 pub fn get_content_rect(&self) -> Rect {
675 self.get_layout()
676 .map(|l| Rect {
677 x0: f64::from(l.content_box_x()),
678 y0: f64::from(l.content_box_y()),
679 x1: f64::from(l.content_box_x() + l.content_box_width()),
680 y1: f64::from(l.content_box_y() + l.content_box_height()),
681 })
682 .unwrap_or_default()
683 }
684
685 pub fn get_layout_rect_local(&self) -> Rect {
687 self.get_layout()
688 .map(|l| Rect {
689 x0: 0.0,
690 y0: 0.0,
691 x1: f64::from(l.size.width),
692 y1: f64::from(l.size.height),
693 })
694 .unwrap_or_default()
695 }
696
697 pub fn get_content_rect_local(&self) -> Rect {
706 self.get_layout()
707 .map(|r| {
708 let x0 = f64::from(r.border.left + r.padding.left);
709 let y0 = f64::from(r.border.top + r.padding.top);
710 let x1 = x0 + f64::from(r.content_box_width());
711 let y1 = y0 + f64::from(r.content_box_height());
712 Rect { x0, y0, x1, y1 }
713 })
714 .unwrap_or_default()
715 }
716
717 pub fn get_content_rect_relative(
724 &self,
725 child_node: taffy::NodeId,
726 parent_node: taffy::NodeId,
727 ) -> Option<Rect> {
728 let taffy = self.taffy();
729 let taffy = taffy.borrow();
730 let mut node = child_node;
731 let mut child_layout = *taffy.layout(node).ok()?;
732
733 loop {
735 let current_parent = taffy.parent(node);
736
737 if current_parent == Some(parent_node) {
738 break;
739 }
740
741 node = current_parent?;
742 child_layout.location = child_layout.location + taffy.layout(node).ok()?.location;
743 }
744
745 Some(Rect::from_origin_size(
747 (
748 f64::from(child_layout.content_box_x()),
749 f64::from(child_layout.content_box_y()),
750 ),
751 (
752 f64::from(child_layout.content_box_width()),
753 f64::from(child_layout.content_box_height()),
754 ),
755 ))
756 }
757
758 pub fn set_child_translation(&self, child_translation: peniko::kurbo::Vec2) -> bool {
762 let state = self.state();
763 let needs_box_tree_update = {
764 let mut state = state.borrow_mut();
765 if state.child_translation != child_translation {
766 state.child_translation = child_translation;
767 true
768 } else {
769 false
770 }
771 };
772 if needs_box_tree_update {
773 for child in self.children() {
774 child.request_box_tree_update_for_view();
775 }
776 }
777 needs_box_tree_update
778 }
779
780 pub fn get_child_translation(&self) -> peniko::kurbo::Vec2 {
782 self.state().borrow().child_translation
783 }
784
785 pub fn set_box_tree_clip(&self, clip: Option<RoundedRect>) {
787 let element_id = self.get_element_id();
788 VIEW_STORAGE.with_borrow_mut(|s| {
789 let box_tree = s.box_tree(*self);
790 box_tree.borrow_mut().set_local_clip(element_id.0, clip)
791 })
792 }
793
794 pub fn is_hidden(&self) -> bool {
796 let state = self.state();
797 let state = state.borrow();
798 state.visibility.is_hidden()
799 }
800
801 pub fn pointer_events_none(&self) -> bool {
803 let state = self.state();
804 let state = state.borrow();
805 state
806 .computed_style
807 .builtin()
808 .pointer_events()
809 .map(|p| p == PointerEvents::None)
810 .unwrap_or(false)
811 }
812
813 pub fn is_disabled(&self) -> bool {
817 self.state().borrow_mut().style_interaction_cx.disabled
818 }
819
820 pub fn is_selected(&self) -> bool {
825 self.state().borrow().parent_set_style_interaction.selected
826 }
827
828 pub fn can_focus(&self) -> bool {
832 self.state()
833 .borrow()
834 .computed_style
835 .get(Focusable)
836 .is_focusable()
837 }
838
839 pub fn request_all(&self) {
842 add_update_message(UpdateMessage::RequestStyle(
843 self.get_element_id(),
844 StyleReason::full_recalc(),
845 ));
846 self.request_layout();
847 self.request_box_tree_commit();
848 self.add_update_message(UpdateMessage::RequestPaint);
849 }
850
851 pub fn request_layout(&self) {
853 add_update_message(UpdateMessage::RequestLayout);
854 }
855
856 pub fn request_mark_view_layout_dirty(&self) {
858 add_update_message(UpdateMessage::MarkViewLayoutDirty(*self));
859 }
860
861 pub fn request_box_tree_update(&self) {
864 add_update_message(UpdateMessage::RequestBoxTreeUpdate);
865 }
866
867 pub fn request_box_tree_update_for_view(&self) {
871 add_update_message(UpdateMessage::RequestBoxTreeUpdateForView(*self));
872 }
873
874 pub fn request_box_tree_commit(&self) {
877 add_update_message(UpdateMessage::RequestBoxTreeCommit);
878 }
879
880 pub fn window_id(&self) -> Option<WindowId> {
882 window_id_for_root(self.root())
883 }
884
885 pub fn request_paint(&self) {
887 self.add_update_message(UpdateMessage::RequestPaint);
888 }
889
890 pub fn request_style(&self, reason: StyleReason) {
892 self.add_update_message(UpdateMessage::RequestStyle(self.get_element_id(), reason));
893 }
894
895 #[deprecated(note = "use `id.request_style(StyleReasonSet::view_style())` directly instead")]
899 pub fn request_view_style(&self) {
900 self.request_style(StyleReason::view_style());
901 }
902
903 pub fn request_focus(&self) {
905 self.add_update_message(UpdateMessage::Focus(self.get_element_id()));
906 }
907
908 pub fn clear_focus(&self) {
910 self.add_update_message(UpdateMessage::ClearFocus);
911 }
912
913 pub fn update_context_menu(&self, menu: impl Fn() -> Menu + 'static) {
915 self.state().borrow_mut().context_menu = Some(Rc::new(menu));
916 }
917
918 pub fn update_popout_menu(&self, menu: impl Fn() -> Menu + 'static) {
922 self.state().borrow_mut().popout_menu = Some(Rc::new(menu));
923 }
924
925 pub fn set_pointer_capture(&self, pointer_id: PointerId) {
959 self.add_update_message(UpdateMessage::SetPointerCapture {
960 element_id: self.get_element_id(),
961 pointer_id,
962 });
963 }
964
965 pub fn release_pointer_capture(&self, pointer_id: PointerId) {
974 self.add_update_message(UpdateMessage::ReleasePointerCapture {
975 element_id: self.get_element_id(),
976 pointer_id,
977 });
978 }
979
980 pub fn inspect(&self) {
982 self.add_update_message(UpdateMessage::Inspect);
983 }
984
985 pub fn scroll_to(&self, rect: Option<Rect>) {
988 self.add_update_message(UpdateMessage::ScrollTo {
989 id: self.get_element_id(),
990 rect,
991 });
992 }
993
994 pub(crate) fn transition_anim_complete(&self) {
995 self.add_update_message(UpdateMessage::ViewTransitionAnimComplete(*self));
996 }
997
998 pub(crate) fn update_animation(&self, offset: StackOffset<Animation>, animation: Animation) {
999 let state = self.state();
1000 state.borrow_mut().animations.set(offset, animation);
1001 self.request_style(StyleReason::animation());
1002 }
1003
1004 pub(crate) fn update_animation_state(
1005 &self,
1006 offset: StackOffset<Animation>,
1007 command: AnimStateCommand,
1008 ) {
1009 let view_state = self.state();
1010 view_state
1011 .borrow_mut()
1012 .animations
1013 .update(offset, move |anim| anim.transition(command));
1014 self.request_style(StyleReason::animation());
1015 }
1016
1017 pub fn update_state(&self, state: impl Any) {
1019 self.add_update_message(UpdateMessage::State {
1020 id: *self,
1021 state: Box::new(state),
1022 });
1023 }
1024
1025 pub(crate) fn add_event_listener(
1027 &self,
1028 listener: EventListenerKey,
1029 action: Box<EventCallback>,
1030 config: EventCallbackConfig,
1031 ) {
1032 add_update_message(crate::message::UpdateMessage::RegisterListener(
1033 listener, *self,
1034 ));
1035 let state = self.state();
1036 state
1037 .borrow_mut()
1038 .add_event_listener(listener, action, config);
1039 }
1040
1041 pub fn add_cleanup_listener(&self, action: Rc<dyn Fn()>) {
1043 let state = self.state();
1044 state.borrow_mut().add_cleanup_listener(action);
1045 }
1046
1047 pub fn get_combined_style(&self) -> Style {
1073 self.state().borrow().combined_style.clone()
1074 }
1075
1076 pub fn add_class(&self, class: StyleClassRef) {
1078 let state = self.state();
1079 state.borrow_mut().classes.push(class);
1080 self.request_style(StyleReason::class_cx(smallvec![class]));
1081 }
1082
1083 pub fn remove_class(&self, class: StyleClassRef) {
1085 let state = self.state();
1086 state.borrow_mut().classes.retain_mut(|c| *c != class);
1087 self.request_style(StyleReason::class_cx(smallvec![class]));
1088 }
1089
1090 pub(crate) fn update_style(&self, offset: StackOffset<Style>, style: Style) {
1091 let state = VIEW_STORAGE.with_borrow(|s| s.states.get(*self).cloned());
1092 if let Some(state) = state {
1093 state.borrow_mut().style.set(offset, style);
1094 self.request_style(StyleReason::full_recalc());
1095 }
1096 }
1097
1098 pub fn set_cursor(&self, cursor: Option<crate::style::CursorStyle>) {
1102 self.state().borrow_mut().user_cursor = cursor;
1103 }
1104
1105 pub fn disable_default_event(&self, event: EventListenerKey) {
1109 self.state()
1110 .borrow_mut()
1111 .disable_default_events
1112 .insert(event);
1113 }
1114
1115 pub fn remove_disable_default_event(&self, event: EventListenerKey) {
1117 self.state()
1118 .borrow_mut()
1119 .disable_default_events
1120 .remove(&event);
1121 }
1122
1123 pub fn window_visible(&self, visible: bool) {
1126 self.add_update_message(UpdateMessage::WindowVisible(visible));
1127 }
1128
1129 pub fn request_remove_views(&self, view_ids: Vec<ViewId>) {
1135 if !view_ids.is_empty() {
1136 self.add_update_message(UpdateMessage::RemoveViews(view_ids));
1137 }
1138 }
1139
1140 pub fn add_child_deferred(&self, child_fn: impl FnOnce() -> AnyView + 'static) {
1146 self.add_update_message(UpdateMessage::AddChild {
1147 parent_id: *self,
1148 child: DeferredChild::new(child_fn),
1149 });
1150 }
1151
1152 pub fn add_children_deferred(&self, children_fn: impl FnOnce() -> Vec<AnyView> + 'static) {
1158 self.add_update_message(UpdateMessage::AddChildren {
1159 parent_id: *self,
1160 children: DeferredChildren::new(children_fn),
1161 });
1162 }
1163
1164 pub fn setup_reactive_children_deferred(&self, setup: impl FnOnce() + 'static) {
1170 self.add_update_message(UpdateMessage::SetupReactiveChildren {
1171 setup: DeferredReactiveSetup::new(*self, setup),
1172 });
1173 }
1174
1175 fn add_update_message(&self, msg: UpdateMessage) {
1176 let _ = CENTRAL_UPDATE_MESSAGES.try_with(|msgs| {
1177 let mut msgs = msgs.borrow_mut();
1178 msgs.push((*self, msg));
1179 });
1180 }
1181
1182 pub fn update_state_deferred(&self, state: impl Any) {
1185 CENTRAL_DEFERRED_UPDATE_MESSAGES.with_borrow_mut(|msgs| {
1186 msgs.push((*self, Box::new(state)));
1187 });
1188 }
1189
1190 pub fn screen_layout(&self) -> Option<ScreenLayout> {
1192 crate::layout::try_create_screen_layout(self)
1193 }
1194
1195 pub fn set_style_parent(&self, parent_id: ViewId) {
1198 self.state().borrow_mut().style_cx_parent = Some(parent_id);
1199 }
1200
1201 pub fn clear_style_parent(&self) {
1203 self.state().borrow_mut().style_cx_parent = None;
1204 }
1205
1206 pub fn set_children_scope(&self, scope: Scope) {
1211 self.state().borrow_mut().children_scope = Some(scope);
1212 }
1213
1214 pub fn take_children_scope(&self) -> Option<Scope> {
1218 self.state().borrow_mut().children_scope.take()
1219 }
1220
1221 pub fn set_keyed_children(&self, children: Vec<(ViewId, Scope)>) {
1226 self.state().borrow_mut().keyed_children = Some(children);
1227 }
1228
1229 pub fn take_keyed_children(&self) -> Option<Vec<(ViewId, Scope)>> {
1233 self.state().borrow_mut().keyed_children.take()
1234 }
1235
1236 pub fn set_scope(&self, scope: Scope) {
1245 self.state().borrow_mut().scope = Some(scope);
1246 }
1247
1248 pub fn scope(&self) -> Option<Scope> {
1250 self.state().borrow().scope
1251 }
1252
1253 pub fn find_scope(&self) -> Option<Scope> {
1258 if let Some(scope) = self.scope() {
1260 return Some(scope);
1261 }
1262 let mut current = self.parent();
1264 while let Some(parent_id) = current {
1265 if let Some(scope) = parent_id.scope() {
1266 return Some(scope);
1267 }
1268 current = parent_id.parent();
1269 }
1270 None
1271 }
1272
1273 pub fn get_local_clip(&self) -> Option<RoundedRect> {
1275 let element_id = self.get_element_id();
1276 VIEW_STORAGE
1277 .with_borrow_mut(|s| {
1278 let box_tree = s.box_tree(*self);
1279 box_tree.borrow().local_clip(element_id.0)
1280 })
1281 .flatten()
1282 }
1283
1284 pub fn create_child_element_id(&self, z_index: i32) -> ElementId {
1288 let parent_box_node = self.get_element_id();
1289 VIEW_STORAGE.with_borrow_mut(|s| {
1290 let box_tree = s.box_tree(*self);
1291 let child_element_id = box_tree.borrow_mut().push_child(
1292 Some(parent_box_node.0),
1293 understory_box_tree::LocalNode::default(),
1294 );
1295 let element_id = ElementId(child_element_id, *self, false);
1296 box_tree
1297 .borrow_mut()
1298 .set_meta(child_element_id, Some(crate::ElementMeta::new(element_id)));
1299 box_tree.borrow_mut().set_z_index(child_element_id, z_index);
1300 element_id
1301 })
1302 }
1303
1304 pub fn focus_nav_meta_for_element(&self, element_id: ElementId) -> Option<FocusNavMeta> {
1306 let box_tree = self.box_tree();
1307 box_tree
1308 .borrow()
1309 .meta(element_id.0)
1310 .flatten()
1311 .map(|m| m.focus)
1312 }
1313
1314 pub fn set_focus_nav_meta_for_element(
1318 &self,
1319 element_id: ElementId,
1320 focus: FocusNavMeta,
1321 ) -> bool {
1322 debug_assert_eq!(
1323 element_id.owning_id(),
1324 *self,
1325 "element must be owned by this view"
1326 );
1327 let box_tree = self.box_tree();
1328 let mut box_tree = box_tree.borrow_mut();
1329 let Some(mut meta) = box_tree.meta(element_id.0).flatten() else {
1330 return false;
1331 };
1332 meta.focus = focus;
1333 box_tree.set_meta(element_id.0, Some(meta));
1334 crate::bump_focus_nav_meta_revision();
1335 true
1336 }
1337
1338 pub fn set_focus_group_for_element(
1340 &self,
1341 element_id: ElementId,
1342 group: Option<understory_focus::FocusSymbol>,
1343 ) -> bool {
1344 let Some(mut focus) = self.focus_nav_meta_for_element(element_id) else {
1345 return false;
1346 };
1347 focus.group = group;
1348 self.set_focus_nav_meta_for_element(element_id, focus)
1349 }
1350
1351 pub fn register_listener(&self, key: listener::EventListenerKey) {
1357 self.add_update_message(UpdateMessage::RegisterListener(key, *self));
1358 }
1359
1360 pub fn remove_listener(&self, key: listener::EventListenerKey) {
1362 self.add_update_message(UpdateMessage::RemoveListener(key, *self));
1363 }
1364
1365 pub(crate) fn get_layout_window_origin(&self) -> Point {
1366 self.state().borrow().layout_window_origin
1367 }
1368
1369 pub fn route_event(&self, event: crate::event::Event, route_kind: RouteKind) {
1417 self.route_event_with_caused_by(event, route_kind, None);
1418 }
1419
1420 pub fn route_event_with_caused_by(
1431 &self,
1432 event: crate::event::Event,
1433 route_kind: RouteKind,
1434 caused_by: Option<crate::event::Event>,
1435 ) {
1436 self.add_update_message(UpdateMessage::RouteEvent {
1437 id: self.get_element_id(),
1438 event: Box::new(event),
1439 route_kind,
1440 triggered_by: caused_by.map(Box::new),
1441 });
1442 }
1443}
1444
1445impl From<ViewId> for ElementId {
1446 fn from(value: ViewId) -> Self {
1447 value.get_element_id()
1448 }
1449}
1450
1451fn reparent_scope_if_needed(child_id: ViewId, parent_id: ViewId) {
1465 let child_scope = child_id.scope();
1467 if let Some(child_scope) = child_scope {
1468 if let Some(parent_scope) = parent_id.find_scope() {
1470 if child_scope != parent_scope {
1472 child_scope.set_parent(parent_scope);
1474 }
1475 } else {
1476 PENDING_SCOPE_REPARENTS.with_borrow_mut(|pending| {
1479 pending.insert(child_id);
1480 });
1481 }
1482 }
1483}
1484
1485pub fn process_pending_scope_reparents() {
1491 let has_pending = PENDING_SCOPE_REPARENTS.with_borrow(|pending| !pending.is_empty());
1493 if !has_pending {
1494 return;
1495 }
1496
1497 PENDING_SCOPE_REPARENTS.with_borrow_mut(|pending| {
1498 pending.retain(|child_id| {
1499 if !child_id.is_valid() {
1502 return false; }
1504
1505 let child_scope = child_id.scope();
1507 if let Some(child_scope) = child_scope {
1508 if let Some(parent_id) = child_id.parent()
1510 && let Some(parent_scope) = parent_id.find_scope()
1511 {
1512 if child_scope != parent_scope {
1514 child_scope.set_parent(parent_scope);
1515 }
1516 return false; }
1518 true } else {
1520 false }
1522 });
1523 });
1524}
1525
1526fn box_tree_parent_element_id_for_child(
1527 storage: &mut ViewStorage,
1528 logical_parent_id: ViewId,
1529 child_id: ViewId,
1530) -> ElementId {
1531 if storage.overlays.contains_key(child_id) {
1532 let root_id = *storage
1533 .root
1534 .get(child_id)
1535 .expect("all view ids are created with a root");
1536 storage.state(root_id).borrow().element_id
1537 } else {
1538 storage.state(logical_parent_id).borrow().element_id
1539 }
1540}
1541
1542impl ViewId {
1543 pub fn parent_set_selected(&self) {
1547 let changed = {
1548 let state = self.state();
1549 let mut state = state.borrow_mut();
1550 if !state.parent_set_style_interaction.selected {
1551 state.parent_set_style_interaction.selected = true;
1552 true
1553 } else {
1554 false
1555 }
1556 };
1557 if changed {
1558 self.request_style(StyleReason::with_selector(StyleSelector::Selected));
1559 }
1560 }
1561
1562 pub fn parent_clear_selected(&self) {
1566 let changed = {
1567 let state = self.state();
1568 let mut state = state.borrow_mut();
1569 if state.parent_set_style_interaction.selected {
1570 state.parent_set_style_interaction.selected = false;
1571 true
1572 } else {
1573 false
1574 }
1575 };
1576 if changed {
1577 self.request_style(StyleReason::with_selector(StyleSelector::Selected));
1578 }
1579 }
1580
1581 pub fn parent_set_disabled(&self) {
1585 let changed = {
1586 let state = self.state();
1587 let mut state = state.borrow_mut();
1588 if !state.parent_set_style_interaction.disabled {
1589 state.parent_set_style_interaction.disabled = true;
1590 true
1591 } else {
1592 false
1593 }
1594 };
1595 if changed {
1596 self.request_style(StyleReason::with_selector(StyleSelector::Disabled));
1597 }
1598 }
1599
1600 pub fn parent_clear_disabled(&self) {
1604 let changed = {
1605 let state = self.state();
1606 let mut state = state.borrow_mut();
1607 if state.parent_set_style_interaction.disabled {
1608 state.parent_set_style_interaction.disabled = false;
1609 true
1610 } else {
1611 false
1612 }
1613 };
1614 if changed {
1615 self.request_style(StyleReason::with_selector(StyleSelector::Disabled));
1616 }
1617 }
1618
1619 pub fn set_hidden(&self) {
1624 use crate::view::state::VisibilityPhase;
1625 let changed = {
1626 let state = self.state();
1627 let mut state = state.borrow_mut();
1628 if !state.parent_set_style_interaction.hidden {
1629 state.parent_set_style_interaction.hidden = true;
1630 state.visibility.phase = VisibilityPhase::Hidden;
1631 true
1632 } else {
1633 false
1634 }
1635 };
1636 if changed {
1637 self.request_style(StyleReason::visibility());
1638 }
1639 }
1640
1641 pub fn set_visible(&self) {
1645 use crate::view::state::VisibilityPhase;
1646 let changed = {
1647 let state = self.state();
1648 let mut state = state.borrow_mut();
1649 if state.parent_set_style_interaction.hidden {
1650 state.parent_set_style_interaction.hidden = false;
1651 state.visibility.phase = VisibilityPhase::Initial;
1653 true
1654 } else {
1655 false
1656 }
1657 };
1658 if changed {
1659 self.request_style(StyleReason::visibility());
1660 }
1661 }
1662}