1use crate::{
 2    AnyElement, App, Bounds, Element, GlobalElementId, InspectorElementId, IntoElement, LayoutId,
 3    Pixels, Window,
 4};
 5
 6/// Builds a `Deferred` element, which delays the layout and paint of its child.
 7pub fn deferred(child: impl IntoElement) -> Deferred {
 8    Deferred {
 9        child: Some(child.into_any_element()),
10        priority: 0,
11    }
12}
13
14/// An element which delays the painting of its child until after all of
15/// its ancestors, while keeping its layout as part of the current element tree.
16pub struct Deferred {
17    child: Option<AnyElement>,
18    priority: usize,
19}
20
21impl Deferred {
22    /// Sets the `priority` value of the `deferred` element, which
23    /// determines the drawing order relative to other deferred elements,
24    /// with higher values being drawn on top.
25    pub const fn with_priority(mut self, priority: usize) -> Self {
26        self.priority = priority;
27        self
28    }
29}
30
31impl Element for Deferred {
32    type RequestLayoutState = ();
33    type PrepaintState = ();
34
35    fn id(&self) -> Option<crate::ElementId> {
36        None
37    }
38
39    fn source_location(&self) -> Option<&'static core::panic::Location<'static>> {
40        None
41    }
42
43    fn request_layout(
44        &mut self,
45        _id: Option<&GlobalElementId>,
46        _inspector_id: Option<&InspectorElementId>,
47        window: &mut Window,
48        cx: &mut App,
49    ) -> (LayoutId, ()) {
50        let layout_id = self.child.as_mut().unwrap().request_layout(window, cx);
51        (layout_id, ())
52    }
53
54    fn prepaint(
55        &mut self,
56        _id: Option<&GlobalElementId>,
57        _inspector_id: Option<&InspectorElementId>,
58        _bounds: Bounds<Pixels>,
59        _request_layout: &mut Self::RequestLayoutState,
60        window: &mut Window,
61        _cx: &mut App,
62    ) {
63        let child = self.child.take().unwrap();
64        let element_offset = window.element_offset();
65        window.defer_draw(child, element_offset, self.priority)
66    }
67
68    fn paint(
69        &mut self,
70        _id: Option<&GlobalElementId>,
71        _inspector_id: Option<&InspectorElementId>,
72        _bounds: Bounds<Pixels>,
73        _request_layout: &mut Self::RequestLayoutState,
74        _prepaint: &mut Self::PrepaintState,
75        _window: &mut Window,
76        _cx: &mut App,
77    ) {
78    }
79}
80
81impl IntoElement for Deferred {
82    type Element = Self;
83
84    fn into_element(self) -> Self::Element {
85        self
86    }
87}
88
89impl Deferred {
90    /// Sets a priority for the element. A higher priority conceptually means painting the element
91    /// on top of deferred draws with a lower priority (i.e. closer to the viewer).
92    pub const fn priority(mut self, priority: usize) -> Self {
93        self.priority = priority;
94        self
95    }
96}