lgui_core/core/view/tree/
scene.rs1use 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}