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