freya_core/events/
measurer.rs

1use crate::{
2    element::EventMeasurementContext,
3    events::{
4        emittable::EmmitableEvent,
5        name::EventName,
6        platform::PlatformEvent,
7    },
8    node_id::NodeId,
9    prelude::Color,
10    style::fill::Fill,
11    tree::Tree,
12};
13
14pub struct EventsMeasurerAdapter<'a> {
15    pub tree: &'a mut Tree,
16    pub scale_factor: f64,
17}
18
19impl ragnarok::EventsMeasurer for EventsMeasurerAdapter<'_> {
20    type Key = NodeId;
21    type Name = EventName;
22    type Source = PlatformEvent;
23    type Emmitable = EmmitableEvent;
24
25    fn get_listeners_of(&self, name: &Self::Name) -> impl Iterator<Item = &Self::Key> {
26        self.tree
27            .listeners
28            .get(name)
29            .map(|l| l.iter())
30            .unwrap_or_else(|| [].iter())
31    }
32
33    fn is_listening_to(&self, key: &Self::Key, name: &Self::Name) -> bool {
34        self.tree
35            .listeners
36            .get(name)
37            .map(|listeners| listeners.contains(key))
38            .unwrap_or_default()
39    }
40
41    fn get_layers(&self) -> impl Iterator<Item = (&i16, impl Iterator<Item = &Self::Key>)> {
42        self.tree
43            .layers
44            .iter()
45            .map(|(layer, nodes)| (layer, nodes.iter()))
46    }
47
48    fn is_point_inside(&self, key: &Self::Key, cursor: ragnarok::CursorPoint) -> bool {
49        let element = self.tree.elements.get(key).unwrap();
50        let Some(layout_node) = self.tree.layout.get(key) else {
51            return false;
52        };
53
54        // Make sure the cursor is inside the element
55        if !element.is_point_inside(EventMeasurementContext {
56            cursor,
57            layout_node,
58            scale_factor: self.scale_factor,
59        }) {
60            return false;
61        }
62
63        let effect_state = self.tree.effect_state.get(key);
64
65        if let Some(effect_state) = effect_state {
66            // Make sure the cursor is inside all the inherited clips of the element
67            for node_id in effect_state.clips.iter() {
68                let element = self.tree.elements.get(node_id).unwrap();
69                let layout_node = self.tree.layout.get(node_id).unwrap();
70                if !element.is_point_inside(EventMeasurementContext {
71                    cursor,
72                    layout_node,
73                    scale_factor: self.scale_factor,
74                }) {
75                    return false;
76                }
77            }
78        }
79
80        true
81    }
82
83    fn is_node_parent_of(&self, key: &Self::Key, parent: Self::Key) -> bool {
84        let mut head = Some(key);
85        while let Some(id) = head.take() {
86            if let Some(parent_id) = self.tree.parents.get(id) {
87                if *parent_id == parent {
88                    return true;
89                }
90
91                head = Some(parent_id)
92            }
93        }
94        false
95    }
96
97    fn is_node_transparent(&self, key: &Self::Key) -> bool {
98        let element = self.tree.elements.get(key).unwrap();
99        element.style().background == Fill::Color(Color::TRANSPARENT)
100    }
101
102    fn try_area_of(&self, key: &Self::Key) -> Option<ragnarok::Area> {
103        self.tree
104            .layout
105            .get(key)
106            .map(|layout| layout.visible_area())
107    }
108
109    fn new_emmitable_event(
110        &self,
111        key: Self::Key,
112        name: Self::Name,
113        source: Self::Source,
114        area: Option<ragnarok::Area>,
115    ) -> Self::Emmitable {
116        EmmitableEvent::new(key, name, source, area, self.scale_factor)
117    }
118}