Skip to main content

ferroui_base/rendering/composition/
element_composition_preview.rs

1use super::CompositionVisual;
2use crate::Visual;
3use std::rc::Rc;
4
5/// Access to the composition visuals of the visuals of the visual tree.
6pub struct ElementComposition;
7
8impl ElementComposition {
9    /// Gets the composition visual of a visual; `None` while the visual is
10    /// not attached to a compositor.
11    pub fn get_element_visual(visual: &Visual) -> Option<Rc<CompositionVisual>> {
12        visual.composition_visual().map(|v| (*v).clone())
13    }
14
15    /// Sets a composition visual that is shown as the last child of the
16    /// composition visual of `visual`.
17    pub fn set_element_child_visual(visual: &Visual, composition_visual: Option<Rc<CompositionVisual>>) {
18        if let (Some(child), Some(own)) = (&composition_visual, visual.composition_visual()) {
19            if !Rc::ptr_eq(child.compositor(), own.compositor()) {
20                panic!("Composition visuals belong to different compositor instances");
21            }
22        }
23
24        // Un-parent the previous child here rather than waiting for the renderer to
25        // reconcile the children, because that sync may never run again for this element:
26        // a child cleared from on_detached_from_visual_tree is cleared before
27        // detach_from_compositor discards the element's composition visual, and a child
28        // left parented there cannot be attached anywhere else.
29        if let Some(old_child) = visual.child_composition_visual() {
30            if !composition_visual.as_ref().is_some_and(|child| Rc::ptr_eq(child, &old_child)) {
31                if let Some(own) = visual.composition_visual() {
32                    own.children().remove(&old_child);
33                }
34            }
35        }
36
37        visual.set_child_composition_visual(composition_visual);
38        if let Some(source) = visual.presentation_source() {
39            source.renderer().recalculate_children(visual);
40        }
41    }
42
43    /// Gets the composition visual set with
44    /// [`set_element_child_visual`](Self::set_element_child_visual).
45    pub fn get_element_child_visual(visual: &Visual) -> Option<Rc<CompositionVisual>> {
46        visual.child_composition_visual()
47    }
48}