Skip to main content

fret_ui/tree/
ui_tree_input_snapshot.rs

1use super::*;
2
3impl<H: UiHost> UiTree<H> {
4    pub fn captured_for(&self, pointer_id: PointerId) -> Option<NodeId> {
5        self.captured.get(&pointer_id).copied()
6    }
7
8    pub fn captured(&self) -> Option<NodeId> {
9        self.captured_for(PointerId(0))
10    }
11
12    pub fn any_captured_node(&self) -> Option<NodeId> {
13        self.captured.values().copied().next()
14    }
15
16    pub fn input_arbitration_snapshot(&self) -> UiInputArbitrationSnapshot {
17        let (_active, barrier_root) = self.active_input_layers();
18        let (_focus_active, focus_barrier_root) = self.active_focus_layers();
19
20        let (pointer_occlusion_layer, pointer_occlusion) = self
21            .topmost_pointer_occlusion_layer(barrier_root)
22            .map(|(layer, occlusion)| (Some(layer), occlusion))
23            .unwrap_or((None, PointerOcclusion::None));
24
25        let mut pointer_capture_active = false;
26        let mut pointer_capture_layer: Option<UiLayerId> = None;
27        let mut pointer_capture_multiple_layers = false;
28        for &node in self.captured.values() {
29            pointer_capture_active = true;
30            let Some(layer) = self.node_layer(node) else {
31                pointer_capture_layer = None;
32                pointer_capture_multiple_layers = true;
33                break;
34            };
35
36            match pointer_capture_layer {
37                None => pointer_capture_layer = Some(layer),
38                Some(prev) => {
39                    if prev != layer {
40                        pointer_capture_layer = None;
41                        pointer_capture_multiple_layers = true;
42                        break;
43                    }
44                }
45            }
46        }
47
48        UiInputArbitrationSnapshot {
49            modal_barrier_root: barrier_root,
50            focus_barrier_root,
51            pointer_occlusion,
52            pointer_occlusion_layer,
53            pointer_capture_active,
54            pointer_capture_layer,
55            pointer_capture_multiple_layers,
56        }
57    }
58
59    pub(super) fn window_input_arbitration_snapshot(
60        &self,
61    ) -> fret_runtime::WindowInputArbitrationSnapshot {
62        let snapshot = self.input_arbitration_snapshot();
63        fret_runtime::WindowInputArbitrationSnapshot {
64            modal_barrier_root: snapshot.modal_barrier_root,
65            focus_barrier_root: snapshot.focus_barrier_root,
66            pointer_occlusion: match snapshot.pointer_occlusion {
67                PointerOcclusion::None => fret_runtime::WindowPointerOcclusion::None,
68                PointerOcclusion::BlockMouse => fret_runtime::WindowPointerOcclusion::BlockMouse,
69                PointerOcclusion::BlockMouseExceptScroll => {
70                    fret_runtime::WindowPointerOcclusion::BlockMouseExceptScroll
71                }
72            },
73            pointer_occlusion_root: snapshot
74                .pointer_occlusion_layer
75                .and_then(|layer| self.layers.get(layer).map(|l| l.root)),
76            pointer_capture_active: snapshot.pointer_capture_active,
77            pointer_capture_root: snapshot
78                .pointer_capture_layer
79                .and_then(|layer| self.layers.get(layer).map(|l| l.root)),
80            pointer_capture_multiple_roots: snapshot.pointer_capture_multiple_layers
81                || (snapshot.pointer_capture_active && snapshot.pointer_capture_layer.is_none()),
82        }
83    }
84}