Skip to main content

lgui_core/core/view/tree/
scene.rs

1use super::*;
2
3impl HostTree {
4    pub(crate) fn has_shadow_ancestor(&self, id: &UiId) -> bool {
5        self.shadow_root(id).is_some()
6    }
7
8    fn shadow_root(&self, id: &UiId) -> Option<&UiNode> {
9        let mut current = self.node(id);
10        let mut root = None;
11        while let Some(node) = current {
12            if node.shadow.is_some() {
13                root = Some(node);
14            }
15            current = node.parent.as_ref().and_then(|parent| self.node(parent));
16            if node.render_phase == super::super::RenderPhase::Popup
17                && current.is_some_and(|parent| parent.render_phase != node.render_phase)
18            {
19                break;
20            }
21        }
22        root
23    }
24
25    pub fn paint_bounds(&self, ids: impl IntoIterator<Item = UiId>) -> Option<UiRect> {
26        ids.into_iter()
27            .filter_map(|id| {
28                let node = self.node(&id)?;
29                let mut bounds = node_dirty_bounds(node);
30                if let Some(root) = self.shadow_root(&id) {
31                    for command in crate::core::compile_scene_root(self, &root.id).commands() {
32                        bounds = bounds.union(command.paint_bounds());
33                    }
34                }
35                Some(bounds)
36            })
37            .reduce(UiRect::union)
38    }
39
40    pub fn full_paint_bounds(&self) -> Option<UiRect> {
41        let bounds = self
42            .nodes
43            .iter()
44            .map(|node| node.paint_bounds)
45            .reduce(UiRect::union);
46        self.nodes
47            .iter()
48            .filter(|node| node.shadow.is_some())
49            .fold(bounds, |bounds, node| {
50                crate::core::compile_scene_root(self, &node.id)
51                    .commands()
52                    .iter()
53                    .fold(bounds, |bounds, command| {
54                        Some(bounds.map_or(command.paint_bounds(), |bounds| {
55                            bounds.union(command.paint_bounds())
56                        }))
57                    })
58            })
59    }
60
61    pub fn scene(&self) -> Scene {
62        compile_scene(self)
63    }
64}
65
66fn node_dirty_bounds(node: &UiNode) -> UiRect {
67    let (x, y) = node.animation_outset;
68    node.paint_bounds.inflate(x, y)
69}