dioxus_gestures/state/gestures/
hover.rs1use std::{cell::RefCell, rc::Rc};
2
3use dioxus::{html::PointerData, prelude::Event};
4
5use crate::state::{
6 events::PointerEventReceiver,
7 gestures::pointer::{IncrementalOffsetPointer, InitialPointer, OffsetPointer, PointerId},
8};
9
10#[derive(Clone)]
11pub struct HoverGestureState {
12 hover: Hover,
13 pointers: Vec<HoverState>,
14}
15
16#[derive(Clone)]
17pub struct HoverState {
18 pointer: HoverPointerState,
19}
20
21#[derive(Clone)]
22pub struct HoverPointerState {
23 id: PointerId,
24 initial_state: Rc<PointerData>,
25 previous_state: Rc<PointerData>,
26}
27
28#[derive(Default, Clone)]
67pub struct Hover {
68 pub on_start: Option<Rc<RefCell<dyn FnMut(())>>>,
69 pub on_end: Option<Rc<RefCell<dyn FnMut(())>>>,
70 pub on_cancel: Option<Rc<RefCell<dyn FnMut(())>>>,
71 pub on_pointer_appear: Option<Rc<RefCell<dyn FnMut(HoverPointerAppearData)>>>,
72 pub on_pointer_update: Option<Rc<RefCell<dyn FnMut(HoverPointerUpdateData)>>>,
73 pub on_pointer_disappear: Option<Rc<RefCell<dyn FnMut(HoverPointerDisappearData)>>>,
74 pub on_pointer_cancel: Option<Rc<RefCell<dyn FnMut(HoverPointerCancelData)>>>,
75}
76
77impl Hover {
78 pub fn on_start(mut self, handler: impl FnMut(()) + 'static) -> Self {
79 self.on_start = Some(Rc::new(RefCell::new(handler)));
80 self
81 }
82
83 pub fn on_end(mut self, handler: impl FnMut(()) + 'static) -> Self {
84 self.on_end = Some(Rc::new(RefCell::new(handler)));
85 self
86 }
87
88 pub fn on_cancel(mut self, handler: impl FnMut(()) + 'static) -> Self {
89 self.on_cancel = Some(Rc::new(RefCell::new(handler)));
90 self
91 }
92
93 pub fn on_pointer_appear(
94 mut self,
95 handler: impl FnMut(HoverPointerAppearData) + 'static,
96 ) -> Self {
97 self.on_pointer_appear = Some(Rc::new(RefCell::new(handler)));
98 self
99 }
100
101 pub fn on_pointer_update(
102 mut self,
103 handler: impl FnMut(HoverPointerUpdateData) + 'static,
104 ) -> Self {
105 self.on_pointer_update = Some(Rc::new(RefCell::new(handler)));
106 self
107 }
108
109 pub fn on_pointer_disappear(
110 mut self,
111 handler: impl FnMut(HoverPointerDisappearData) + 'static,
112 ) -> Self {
113 self.on_pointer_disappear = Some(Rc::new(RefCell::new(handler)));
114 self
115 }
116
117 pub fn on_pointer_cancel(
118 mut self,
119 handler: impl FnMut(HoverPointerCancelData) + 'static,
120 ) -> Self {
121 self.on_pointer_cancel = Some(Rc::new(RefCell::new(handler)));
122 self
123 }
124}
125
126pub struct HoverPointerAppearData {
127 pub pointer: InitialPointer,
128}
129
130pub struct HoverPointerUpdateData {
131 pub pointer: IncrementalOffsetPointer,
132}
133
134pub struct HoverPointerDisappearData {
135 pub pointer: OffsetPointer,
136}
137
138pub struct HoverPointerCancelData {
139 pub pointer: OffsetPointer,
140}
141
142impl HoverGestureState {
143 pub fn new(hover: Hover) -> Self {
144 Self {
145 hover,
146 pointers: Vec::new(),
147 }
148 }
149
150 fn add_hover_event(&mut self, pointer_data: Rc<PointerData>) {
151 let is_first = self.pointers.is_empty();
152 self.pointers.push(HoverState {
153 pointer: HoverPointerState {
154 id: PointerId::from(pointer_data.pointer_id()),
155 initial_state: Rc::clone(&pointer_data),
156 previous_state: Rc::clone(&pointer_data),
157 },
158 });
159
160 if is_first {
161 if let Some(handler) = &self.hover.on_start {
162 handler.borrow_mut()(());
163 }
164 }
165
166 if let Some(handler) = &self.hover.on_pointer_appear {
167 handler.borrow_mut()(HoverPointerAppearData {
168 pointer: InitialPointer { data: pointer_data },
169 });
170 }
171 }
172
173 fn update_known_hover_event(&mut self, index: usize, pointer_data: Rc<PointerData>) {
174 let initial_data = Rc::clone(&self.pointers[index].pointer.initial_state);
175 let preceding_data = Rc::clone(&self.pointers[index].pointer.previous_state);
176 self.pointers[index].pointer.previous_state = Rc::clone(&pointer_data);
177 if let Some(handler) = &self.hover.on_pointer_update {
178 handler.borrow_mut()(HoverPointerUpdateData {
179 pointer: IncrementalOffsetPointer {
180 initial_data,
181 preceding_data,
182 current_data: pointer_data,
183 },
184 });
185 }
186 }
187
188 fn remove_known_hover_event(&mut self, index: usize, pointer_data: Rc<PointerData>) {
189 let hover = self.pointers.remove(index);
190 let initial_data = hover.pointer.initial_state;
191 if let Some(handler) = &self.hover.on_pointer_disappear {
192 handler.borrow_mut()(HoverPointerDisappearData {
193 pointer: OffsetPointer {
194 initial_data,
195 final_data: pointer_data,
196 },
197 });
198 }
199
200 if self.pointers.is_empty() {
201 if let Some(handler) = &self.hover.on_end {
202 handler.borrow_mut()(());
203 }
204 }
205 }
206
207 fn cancel_known_hover_event(&mut self, index: usize, pointer_data: Rc<PointerData>) {
208 let hover = self.pointers.remove(index);
209 let initial_data = hover.pointer.initial_state;
210 if let Some(handler) = &self.hover.on_pointer_cancel {
211 handler.borrow_mut()(HoverPointerCancelData {
212 pointer: OffsetPointer {
213 initial_data,
214 final_data: pointer_data,
215 },
216 });
217 }
218
219 if self.pointers.is_empty() {
220 if let Some(handler) = &self.hover.on_cancel {
221 handler.borrow_mut()(())
222 }
223 }
224 }
225
226 fn add_or_update(&mut self, event: &Event<PointerData>) {
227 let pointer_data = event.data();
228 let pointer_id = pointer_data.pointer_id();
229 let associated_hover_event = self
230 .pointers
231 .iter()
232 .position(|p| p.pointer.id.is_equal_i32(pointer_id));
233 match associated_hover_event {
234 Some(position) => {
235 self.update_known_hover_event(position, pointer_data);
236 }
237 None => {
238 self.add_hover_event(pointer_data);
239 }
240 };
241 }
242
243 fn remove(&mut self, event: &Event<PointerData>) {
244 let pointer_data = event.data();
245 let pointer_id = pointer_data.pointer_id();
246 let associated_hover_event = self
247 .pointers
248 .iter()
249 .position(|p| p.pointer.id.is_equal_i32(pointer_id));
250 match associated_hover_event {
251 Some(position) => {
252 self.remove_known_hover_event(position, pointer_data);
253 }
254 None => {}
255 };
256 }
257
258 fn cancel(&mut self, event: &Event<PointerData>) {
259 let pointer_data = event.data();
260 let pointer_id = pointer_data.pointer_id();
261 let associated_hover_event = self
262 .pointers
263 .iter()
264 .position(|p| p.pointer.id.is_equal_i32(pointer_id));
265 match associated_hover_event {
266 Some(position) => {
267 self.cancel_known_hover_event(position, pointer_data);
268 }
269 None => {}
270 };
271 }
272}
273
274impl PointerEventReceiver<&Event<PointerData>> for HoverGestureState {
275 fn pointer_over(&mut self, _: &Event<PointerData>) {}
276
277 fn pointer_enter(&mut self, event: &Event<PointerData>) {
278 self.add_or_update(event);
279 }
280
281 fn pointer_down(&mut self, event: &Event<PointerData>) {
282 self.add_or_update(event);
283 }
284
285 fn pointer_move(&mut self, event: &Event<PointerData>) {
286 self.add_or_update(event);
287 }
288
289 fn pointer_up(&mut self, event: &Event<PointerData>) {
290 self.add_or_update(event);
291 }
292
293 fn pointer_cancel(&mut self, event: &Event<PointerData>) {
294 self.cancel(event);
295 }
296
297 fn pointer_out(&mut self, _: &Event<PointerData>) {}
298
299 fn pointer_leave(&mut self, event: &Event<PointerData>) {
300 self.remove(event);
301 }
302}