1use std::{
4 cell::{LazyCell, RefCell},
5 collections::HashMap,
6 ffi::CString,
7 os::raw::c_void,
8 ptr::NonNull,
9 rc::Rc,
10 sync::{Mutex, OnceLock},
11};
12
13use ohos_arkui_input_binding::sys::ArkUI_NodeHandle;
14use ohos_arkui_input_binding::ArkUIErrorCode;
15#[cfg(feature = "api-20")]
16use ohos_arkui_sys::OH_ArkUI_PreventGestureRecognizerBegin;
17use ohos_arkui_sys::{
18 ArkUI_GestureEvent, ArkUI_GestureEventActionTypeMask, ArkUI_GestureEventTargetInfo,
19 ArkUI_GestureInterruptInfo, ArkUI_GestureInterruptResult, ArkUI_GestureRecognizer,
20 ArkUI_GestureRecognizerHandle, ArkUI_GestureRecognizerHandleArray,
21 ArkUI_NativeAPIVariantKind_ARKUI_NATIVE_GESTURE, ArkUI_NativeGestureAPI_1,
22 ArkUI_ParallelInnerGestureEvent, OH_ArkUI_GestureEventTargetInfo_IsScrollBegin,
23 OH_ArkUI_GestureEventTargetInfo_IsScrollEnd, OH_ArkUI_GestureEvent_GetActionType,
24 OH_ArkUI_GestureEvent_GetNode, OH_ArkUI_GestureEvent_GetRawInputEvent,
25 OH_ArkUI_GestureInterruptInfo_GetGestureEvent, OH_ArkUI_GestureInterruptInfo_GetRecognizer,
26 OH_ArkUI_GestureInterruptInfo_GetSystemFlag,
27 OH_ArkUI_GestureInterruptInfo_GetSystemRecognizerType, OH_ArkUI_LongPress_GetRepeatCount,
28 OH_ArkUI_PanGesture_GetOffsetX, OH_ArkUI_PanGesture_GetOffsetY,
29 OH_ArkUI_PanGesture_GetVelocity, OH_ArkUI_PanGesture_GetVelocityX,
30 OH_ArkUI_PanGesture_GetVelocityY, OH_ArkUI_ParallelInnerGestureEvent_GetConflictRecognizers,
31 OH_ArkUI_ParallelInnerGestureEvent_GetCurrentRecognizer,
32 OH_ArkUI_ParallelInnerGestureEvent_GetUserData, OH_ArkUI_PinchGesture_GetCenterX,
33 OH_ArkUI_PinchGesture_GetCenterY, OH_ArkUI_PinchGesture_GetScale,
34 OH_ArkUI_QueryModuleInterfaceByName, OH_ArkUI_RotationGesture_GetAngle,
35 OH_ArkUI_SwipeGesture_GetAngle, OH_ArkUI_SwipeGesture_GetVelocity,
36};
37#[cfg(feature = "api-18")]
38use ohos_arkui_sys::{
39 ArkUI_NativeGestureAPI_2, OH_ArkUI_GestureInterrupter_GetUserData,
40 OH_ArkUI_GetGestureParam_DirectMask, OH_ArkUI_GetGestureParam_FingerCount,
41 OH_ArkUI_GetGestureParam_angle, OH_ArkUI_GetGestureParam_distance,
42 OH_ArkUI_GetGestureParam_distanceThreshold, OH_ArkUI_GetGestureParam_duration,
43 OH_ArkUI_GetGestureParam_limitFingerCount, OH_ArkUI_GetGestureParam_repeat,
44 OH_ArkUI_GetGestureParam_speed,
45};
46#[cfg(feature = "api-15")]
47use ohos_arkui_sys::{
48 ArkUI_TouchRecognizerHandle, ArkUI_TouchRecognizerHandleArray,
49 OH_ArkUI_GestureInterruptInfo_GetTouchRecognizers, OH_ArkUI_TouchRecognizer_CancelTouch,
50 OH_ArkUI_TouchRecognizer_GetNodeHandle,
51};
52#[cfg(feature = "api-22")]
53use ohos_arkui_sys::{
54 OH_ArkUI_LongPressGesture_GetAllowableMovement, OH_ArkUI_LongPressGesture_SetAllowableMovement,
55};
56#[cfg(feature = "api-19")]
57use ohos_arkui_sys::{
58 OH_ArkUI_PanGesture_GetDistanceByToolType, OH_ArkUI_PanGesture_SetDistanceMap,
59};
60
61use crate::{
62 check_arkui_status, ArkUIError, ArkUIResult, GestureData, GestureEventAction, GestureEventData,
63 GestureInterruptResult, GestureRecognizerState, GestureRecognizerType, InnerGestureData,
64 LongPressGestureData, PanGestureData, PinchGestureData, RotationGestureData, SwipeGestureData,
65};
66
67thread_local! {
68 pub(crate) static ARK_UI_NATIVE_GESTURE_API_1: LazyCell<ArkUINativeGestureAPI1> =
71 LazyCell::new(ArkUINativeGestureAPI1::new);
72
73 #[cfg(feature = "api-18")]
74 pub(crate) static ARK_UI_NATIVE_GESTURE_API_2: LazyCell<ArkUINativeGestureAPI2> =
75 LazyCell::new(ArkUINativeGestureAPI2::new);
76}
77
78struct InnerGestureParallelCallbackContext {
79 callback: Box<dyn Fn(ParallelInnerGestureEventRef) -> Option<GestureRecognizerRef>>,
80}
81
82struct GestureEventTargetCallbackContext {
83 callback: Box<dyn Fn(GestureEventRef)>,
84}
85
86struct GestureInterrupterCallbackContext {
87 callback: Box<dyn Fn(GestureInterruptInfoRef) -> GestureInterruptResult>,
88}
89
90#[cfg(feature = "api-20")]
91struct TouchTestDoneCallbackContext {
92 callback: Box<dyn Fn(GestureEventRef, Vec<GestureRecognizerRef>)>,
93}
94
95struct GestureDisposeNotifyCallbackContext {
96 callback: Box<dyn Fn()>,
97}
98
99type InnerGestureParallelCallbackMap = HashMap<usize, usize>;
100type GestureEventTargetCallbackMap = HashMap<usize, usize>;
101type GestureInterrupterCallbackMap = HashMap<usize, usize>;
102#[cfg(feature = "api-20")]
103type TouchTestDoneCallbackMap = HashMap<usize, usize>;
104type GestureDisposeNotifyCallbackMap = HashMap<usize, usize>;
105
106static INNER_GESTURE_PARALLEL_CALLBACK_CONTEXTS: OnceLock<Mutex<InnerGestureParallelCallbackMap>> =
107 OnceLock::new();
108static GESTURE_EVENT_TARGET_CALLBACK_CONTEXTS: OnceLock<Mutex<GestureEventTargetCallbackMap>> =
109 OnceLock::new();
110static GESTURE_INTERRUPTER_CALLBACK_CONTEXTS: OnceLock<Mutex<GestureInterrupterCallbackMap>> =
111 OnceLock::new();
112#[cfg(feature = "api-20")]
113static TOUCH_TEST_DONE_CALLBACK_CONTEXTS: OnceLock<Mutex<TouchTestDoneCallbackMap>> =
114 OnceLock::new();
115static GESTURE_DISPOSE_NOTIFY_CALLBACK_CONTEXTS: OnceLock<Mutex<GestureDisposeNotifyCallbackMap>> =
116 OnceLock::new();
117
118fn inner_gesture_parallel_callback_contexts() -> &'static Mutex<InnerGestureParallelCallbackMap> {
119 INNER_GESTURE_PARALLEL_CALLBACK_CONTEXTS.get_or_init(|| Mutex::new(HashMap::new()))
120}
121
122fn gesture_event_target_callback_contexts() -> &'static Mutex<GestureEventTargetCallbackMap> {
123 GESTURE_EVENT_TARGET_CALLBACK_CONTEXTS.get_or_init(|| Mutex::new(HashMap::new()))
124}
125
126fn gesture_interrupter_callback_contexts() -> &'static Mutex<GestureInterrupterCallbackMap> {
127 GESTURE_INTERRUPTER_CALLBACK_CONTEXTS.get_or_init(|| Mutex::new(HashMap::new()))
128}
129
130#[cfg(feature = "api-20")]
131fn touch_test_done_callback_contexts() -> &'static Mutex<TouchTestDoneCallbackMap> {
132 TOUCH_TEST_DONE_CALLBACK_CONTEXTS.get_or_init(|| Mutex::new(HashMap::new()))
133}
134
135fn gesture_dispose_notify_callback_contexts() -> &'static Mutex<GestureDisposeNotifyCallbackMap> {
136 GESTURE_DISPOSE_NOTIFY_CALLBACK_CONTEXTS.get_or_init(|| Mutex::new(HashMap::new()))
137}
138
139pub(crate) struct ArkUINativeGestureAPI1(pub(crate) NonNull<ArkUI_NativeGestureAPI_1>);
140
141impl ArkUINativeGestureAPI1 {
142 pub(crate) fn raw(&self) -> *mut ArkUI_NativeGestureAPI_1 {
144 self.0.as_ptr()
145 }
146
147 pub fn new() -> Self {
148 let struct_name = CString::new("ArkUI_NativeGestureAPI_1").unwrap();
149 let raw_ptr = unsafe {
150 OH_ArkUI_QueryModuleInterfaceByName(
151 ArkUI_NativeAPIVariantKind_ARKUI_NATIVE_GESTURE,
152 struct_name.as_ptr().cast(),
153 )
154 };
155 let api = NonNull::new(raw_ptr.cast())
156 .unwrap_or_else(|| panic!("ArkUI_NativeGestureAPI_1 is NULL"));
157 Self(api)
158 }
159
160 pub fn create_long_gesture(
161 &self,
162 finger_number: i32,
163 repeat: bool,
164 duration: i32,
165 ) -> ArkUIResult<ArkUI_GestureRecognizerHandle> {
166 unsafe {
167 if let Some(create_long_press_gesture) = (*self.raw()).createLongPressGesture {
168 let ret = create_long_press_gesture(finger_number, repeat, duration);
169 if ret.is_null() {
170 Err(ArkUIError::new(
171 ArkUIErrorCode::AttributeOrEventNotSupported,
172 "ArkUINativeGestureAPI1::createLongPressGesture is None",
173 ))
174 } else {
175 Ok(ret)
176 }
177 } else {
178 Err(ArkUIError::new(
179 ArkUIErrorCode::AttributeOrEventNotSupported,
180 "ArkUINativeGestureAPI1::createLongPressGesture is None",
181 ))
182 }
183 }
184 }
185
186 pub fn create_tap_gesture(
187 &self,
188 count: i32,
189 finger: i32,
190 ) -> ArkUIResult<ArkUI_GestureRecognizerHandle> {
191 unsafe {
192 if let Some(create_tap_gesture) = (*self.raw()).createTapGesture {
193 let ret = create_tap_gesture(count, finger);
194 if ret.is_null() {
195 Err(ArkUIError::new(
196 ArkUIErrorCode::AttributeOrEventNotSupported,
197 "ArkUINativeGestureAPI1::createTapGesture is None",
198 ))
199 } else {
200 Ok(ret)
201 }
202 } else {
203 Err(ArkUIError::new(
204 ArkUIErrorCode::AttributeOrEventNotSupported,
205 "ArkUINativeGestureAPI1::createTapGesture is None",
206 ))
207 }
208 }
209 }
210
211 pub fn create_tap_gesture_with_distance_threshold(
212 &self,
213 count: i32,
214 finger: i32,
215 distance_threshold: f64,
216 ) -> ArkUIResult<ArkUI_GestureRecognizerHandle> {
217 unsafe {
218 if let Some(create_tap_gesture) = (*self.raw()).createTapGestureWithDistanceThreshold {
219 let ret = create_tap_gesture(count, finger, distance_threshold);
220 if ret.is_null() {
221 Err(ArkUIError::new(
222 ArkUIErrorCode::AttributeOrEventNotSupported,
223 "ArkUINativeGestureAPI1::createTapGestureWithDistanceThreshold is None",
224 ))
225 } else {
226 Ok(ret)
227 }
228 } else {
229 Err(ArkUIError::new(
230 ArkUIErrorCode::AttributeOrEventNotSupported,
231 "ArkUINativeGestureAPI1::createTapGestureWithDistanceThreshold is None",
232 ))
233 }
234 }
235 }
236
237 pub fn create_pan_gesture(
238 &self,
239 finger: i32,
240 direction: crate::GestureDirection,
241 distance: f64,
242 ) -> ArkUIResult<ArkUI_GestureRecognizerHandle> {
243 unsafe {
244 if let Some(create_pan_gesture) = (*self.raw()).createPanGesture {
245 let ret = create_pan_gesture(finger, direction.into(), distance);
246 if ret.is_null() {
247 Err(ArkUIError::new(
248 ArkUIErrorCode::AttributeOrEventNotSupported,
249 "ArkUINativeGestureAPI1::createPanGesture is None",
250 ))
251 } else {
252 Ok(ret)
253 }
254 } else {
255 Err(ArkUIError::new(
256 ArkUIErrorCode::AttributeOrEventNotSupported,
257 "ArkUINativeGestureAPI1::createPanGesture is None",
258 ))
259 }
260 }
261 }
262
263 pub fn create_pinch_gesture(
264 &self,
265 finger: i32,
266 distance: f64,
267 ) -> ArkUIResult<ArkUI_GestureRecognizerHandle> {
268 unsafe {
269 if let Some(create_pinch_gesture) = (*self.raw()).createPinchGesture {
270 let ret = create_pinch_gesture(finger, distance);
271 if ret.is_null() {
272 Err(ArkUIError::new(
273 ArkUIErrorCode::AttributeOrEventNotSupported,
274 "ArkUINativeGestureAPI1::createPinchGesture is None",
275 ))
276 } else {
277 Ok(ret)
278 }
279 } else {
280 Err(ArkUIError::new(
281 ArkUIErrorCode::AttributeOrEventNotSupported,
282 "ArkUINativeGestureAPI1::createPinchGesture is None",
283 ))
284 }
285 }
286 }
287
288 pub fn create_rotation_gesture(
289 &self,
290 finger: i32,
291 angle: f64,
292 ) -> ArkUIResult<ArkUI_GestureRecognizerHandle> {
293 unsafe {
294 if let Some(create_rotation_gesture) = (*self.raw()).createRotationGesture {
295 let ret = create_rotation_gesture(finger, angle);
296 if ret.is_null() {
297 Err(ArkUIError::new(
298 ArkUIErrorCode::AttributeOrEventNotSupported,
299 "ArkUINativeGestureAPI1::createRotationGesture is None",
300 ))
301 } else {
302 Ok(ret)
303 }
304 } else {
305 Err(ArkUIError::new(
306 ArkUIErrorCode::AttributeOrEventNotSupported,
307 "ArkUINativeGestureAPI1::createRotationGesture is None",
308 ))
309 }
310 }
311 }
312
313 pub fn create_swipe_gesture(
314 &self,
315 finger: i32,
316 direction: crate::GestureDirection,
317 speed: f64,
318 ) -> ArkUIResult<ArkUI_GestureRecognizerHandle> {
319 unsafe {
320 if let Some(create_swipe_gesture) = (*self.raw()).createSwipeGesture {
321 let ret = create_swipe_gesture(finger, direction.into(), speed);
322 if ret.is_null() {
323 Err(ArkUIError::new(
324 ArkUIErrorCode::AttributeOrEventNotSupported,
325 "ArkUINativeGestureAPI1::createSwipeGesture is None",
326 ))
327 } else {
328 Ok(ret)
329 }
330 } else {
331 Err(ArkUIError::new(
332 ArkUIErrorCode::AttributeOrEventNotSupported,
333 "ArkUINativeGestureAPI1::createSwipeGesture is None",
334 ))
335 }
336 }
337 }
338
339 pub fn create_gesture_group(
340 &self,
341 mode: crate::GestureGroupMode,
342 ) -> ArkUIResult<ArkUI_GestureRecognizerHandle> {
343 unsafe {
344 if let Some(create_group_gesture) = (*self.raw()).createGroupGesture {
345 let ret = create_group_gesture(mode.into());
346 if ret.is_null() {
347 Err(ArkUIError::new(
348 ArkUIErrorCode::AttributeOrEventNotSupported,
349 "ArkUINativeGestureAPI1::createGroupGesture is None",
350 ))
351 } else {
352 Ok(ret)
353 }
354 } else {
355 Err(ArkUIError::new(
356 ArkUIErrorCode::AttributeOrEventNotSupported,
357 "ArkUINativeGestureAPI1::createGestureGroup is None",
358 ))
359 }
360 }
361 }
362
363 pub fn add_child_gesture(
364 &self,
365 group: ArkUI_GestureRecognizerHandle,
366 child: ArkUI_GestureRecognizerHandle,
367 ) -> ArkUIResult<()> {
368 unsafe {
369 if let Some(add_child_gesture) = (*self.raw()).addChildGesture {
370 check_arkui_status!(add_child_gesture(group, child))
371 } else {
372 Err(ArkUIError::new(
373 ArkUIErrorCode::AttributeOrEventNotSupported,
374 "ArkUINativeGestureAPI1::addChildGesture is None",
375 ))
376 }
377 }
378 }
379
380 pub fn remove_child_gesture(
381 &self,
382 group: ArkUI_GestureRecognizerHandle,
383 child: ArkUI_GestureRecognizerHandle,
384 ) -> ArkUIResult<()> {
385 unsafe {
386 if let Some(remove_child_gesture) = (*self.raw()).removeChildGesture {
387 check_arkui_status!(remove_child_gesture(group, child))
388 } else {
389 Err(ArkUIError::new(
390 ArkUIErrorCode::AttributeOrEventNotSupported,
391 "ArkUINativeGestureAPI1::removeChildGesture is None",
392 ))
393 }
394 }
395 }
396
397 pub fn add_gesture(
398 &self,
399 gesture: ArkUI_GestureRecognizerHandle,
400 node: ArkUI_NodeHandle,
401 mode: crate::GesturePriority,
402 mask: crate::GestureMask,
403 ) -> ArkUIResult<()> {
404 unsafe {
405 if let Some(add_gesture_to_node) = (*self.raw()).addGestureToNode {
406 check_arkui_status!(add_gesture_to_node(node, gesture, mode.into(), mask.into()))
407 } else {
408 Err(ArkUIError::new(
409 ArkUIErrorCode::AttributeOrEventNotSupported,
410 "ArkUINativeGestureAPI1::addGestureToNode is None",
411 ))
412 }
413 }
414 }
415
416 pub fn remove_gesture(
417 &self,
418 gesture: ArkUI_GestureRecognizerHandle,
419 node: ArkUI_NodeHandle,
420 ) -> ArkUIResult<()> {
421 unsafe {
422 if let Some(remove_gesture_from_node) = (*self.raw()).removeGestureFromNode {
423 check_arkui_status!(remove_gesture_from_node(node, gesture))
424 } else {
425 Err(ArkUIError::new(
426 ArkUIErrorCode::AttributeOrEventNotSupported,
427 "ArkUINativeGestureAPI1::removeGestureFromNode is None",
428 ))
429 }
430 }
431 }
432
433 pub(crate) fn dispose_gesture(
434 &self,
435 gesture: ArkUI_GestureRecognizerHandle,
436 ) -> ArkUIResult<()> {
437 unsafe {
438 if let Some(dispose) = (*self.raw()).dispose {
439 dispose(gesture);
440 Ok(())
441 } else {
442 Err(ArkUIError::new(
443 ArkUIErrorCode::AttributeOrEventNotSupported,
444 "ArkUINativeGestureAPI1::dispose is None",
445 ))
446 }
447 }
448 }
449
450 pub fn get_gesture_type(
451 &self,
452 gesture: ArkUI_GestureRecognizerHandle,
453 ) -> ArkUIResult<GestureRecognizerType> {
454 unsafe {
455 if let Some(get_gesture_type) = (*self.raw()).getGestureType {
456 Ok(get_gesture_type(gesture).into())
457 } else {
458 Err(ArkUIError::new(
459 ArkUIErrorCode::AttributeOrEventNotSupported,
460 "ArkUINativeGestureAPI1::getGestureType is None",
461 ))
462 }
463 }
464 }
465
466 fn set_gesture_interrupter_to_node_raw(
467 &self,
468 node: ArkUI_NodeHandle,
469 interrupter: Option<
470 unsafe extern "C" fn(
471 info: *mut ArkUI_GestureInterruptInfo,
472 ) -> ArkUI_GestureInterruptResult,
473 >,
474 ) -> ArkUIResult<()> {
475 unsafe {
476 if let Some(set_gesture_interrupter_to_node) = (*self.raw()).setGestureInterrupterToNode
477 {
478 check_arkui_status!(set_gesture_interrupter_to_node(node, interrupter))
479 } else {
480 Err(ArkUIError::new(
481 ArkUIErrorCode::AttributeOrEventNotSupported,
482 "ArkUINativeGestureAPI1::setGestureInterrupterToNode is None",
483 ))
484 }
485 }
486 }
487
488 pub fn set_gesture_interrupter_to_node<
489 T: Fn(GestureInterruptInfoRef) -> GestureInterruptResult + 'static,
490 >(
491 &self,
492 node: ArkUI_NodeHandle,
493 interrupter: T,
494 ) -> ArkUIResult<()> {
495 let callback = Box::into_raw(Box::new(GestureInterrupterCallbackContext {
496 callback: Box::new(interrupter),
497 }));
498 let result = self.set_gesture_interrupter_to_node_raw(
499 node,
500 Some(gesture_interrupter_callback_trampoline),
501 );
502 if let Err(err) = result {
503 unsafe {
504 drop(Box::from_raw(callback));
505 }
506 return Err(err);
507 }
508 let mut callbacks = match gesture_interrupter_callback_contexts().lock() {
509 Ok(callbacks) => callbacks,
510 Err(poisoned) => poisoned.into_inner(),
511 };
512 if let Some(old) = callbacks.insert(node as usize, callback as usize) {
513 unsafe {
514 drop(Box::from_raw(old as *mut GestureInterrupterCallbackContext));
515 }
516 }
517 Ok(())
518 }
519
520 pub(crate) fn clear_gesture_interrupter_to_node(
521 &self,
522 node: ArkUI_NodeHandle,
523 ) -> ArkUIResult<()> {
524 self.set_gesture_interrupter_to_node_raw(node, None)?;
525 let mut callbacks = match gesture_interrupter_callback_contexts().lock() {
526 Ok(callbacks) => callbacks,
527 Err(poisoned) => poisoned.into_inner(),
528 };
529 if let Some(callback) = callbacks.remove(&(node as usize)) {
530 unsafe {
531 drop(Box::from_raw(
532 callback as *mut GestureInterrupterCallbackContext,
533 ));
534 }
535 }
536 Ok(())
537 }
538
539 fn set_inner_gesture_parallel_to_raw(
540 &self,
541 node: ArkUI_NodeHandle,
542 user_data: *mut c_void,
543 parallel_inner_gesture: Option<
544 unsafe extern "C" fn(
545 event: *mut ArkUI_ParallelInnerGestureEvent,
546 ) -> *mut ArkUI_GestureRecognizer,
547 >,
548 ) -> ArkUIResult<()> {
549 unsafe {
550 if let Some(set_inner_gesture_parallel_to) = (*self.raw()).setInnerGestureParallelTo {
551 check_arkui_status!(set_inner_gesture_parallel_to(
552 node,
553 user_data,
554 parallel_inner_gesture
555 ))
556 } else {
557 Err(ArkUIError::new(
558 ArkUIErrorCode::AttributeOrEventNotSupported,
559 "ArkUINativeGestureAPI1::setInnerGestureParallelTo is None",
560 ))
561 }
562 }
563 }
564
565 pub fn set_inner_gesture_parallel_to<
566 T: Fn(ParallelInnerGestureEventRef) -> Option<GestureRecognizerRef> + 'static,
567 >(
568 &self,
569 node: ArkUI_NodeHandle,
570 parallel_inner_gesture: T,
571 ) -> ArkUIResult<()> {
572 let callback = Box::into_raw(Box::new(InnerGestureParallelCallbackContext {
573 callback: Box::new(parallel_inner_gesture),
574 }));
575 let result = self.set_inner_gesture_parallel_to_raw(
576 node,
577 callback.cast(),
578 Some(inner_gesture_parallel_callback_trampoline),
579 );
580 if let Err(err) = result {
581 unsafe {
582 drop(Box::from_raw(callback));
583 }
584 return Err(err);
585 }
586 let mut callbacks = match inner_gesture_parallel_callback_contexts().lock() {
587 Ok(callbacks) => callbacks,
588 Err(poisoned) => poisoned.into_inner(),
589 };
590 if let Some(old) = callbacks.insert(node as usize, callback as usize) {
591 unsafe {
592 drop(Box::from_raw(
593 old as *mut InnerGestureParallelCallbackContext,
594 ));
595 }
596 }
597 Ok(())
598 }
599
600 pub(crate) fn clear_inner_gesture_parallel_to(
601 &self,
602 node: ArkUI_NodeHandle,
603 ) -> ArkUIResult<()> {
604 self.set_inner_gesture_parallel_to_raw(node, std::ptr::null_mut(), None)?;
605 let mut callbacks = match inner_gesture_parallel_callback_contexts().lock() {
606 Ok(callbacks) => callbacks,
607 Err(poisoned) => poisoned.into_inner(),
608 };
609 if let Some(callback) = callbacks.remove(&(node as usize)) {
610 unsafe {
611 drop(Box::from_raw(
612 callback as *mut InnerGestureParallelCallbackContext,
613 ));
614 }
615 }
616 Ok(())
617 }
618
619 #[cfg(feature = "api-20")]
620 pub fn prevent_gesture_recognizer_begin(
621 &self,
622 recognizer: ArkUI_GestureRecognizerHandle,
623 ) -> ArkUIResult<()> {
624 unsafe { check_arkui_status!(OH_ArkUI_PreventGestureRecognizerBegin(recognizer)) }
625 }
626
627 pub(crate) fn set_gesture_event_to_target(
628 &self,
629 gesture: ArkUI_GestureRecognizerHandle,
630 action_type: ArkUI_GestureEventActionTypeMask,
631 extra_params: Rc<RefCell<InnerGestureData>>,
632 ) -> ArkUIResult<()> {
633 self.set_gesture_event_target_raw(
634 gesture,
635 action_type,
636 Box::into_raw(Box::new(extra_params)) as *mut c_void,
637 Some(target_receiver),
638 )
639 }
640
641 fn set_gesture_event_target_raw(
642 &self,
643 gesture: ArkUI_GestureRecognizerHandle,
644 action_type: ArkUI_GestureEventActionTypeMask,
645 extra_params: *mut c_void,
646 target_receiver: Option<
647 unsafe extern "C" fn(event: *mut ArkUI_GestureEvent, extra_params: *mut c_void),
648 >,
649 ) -> ArkUIResult<()> {
650 unsafe {
651 if let Some(set_gesture_event_to_target) = (*self.raw()).setGestureEventTarget {
652 check_arkui_status!(set_gesture_event_to_target(
653 gesture,
654 action_type,
655 extra_params,
656 target_receiver
657 ))
658 } else {
659 Err(ArkUIError::new(
660 ArkUIErrorCode::AttributeOrEventNotSupported,
661 "ArkUINativeGestureAPI1::setGestureEventTarget is None",
662 ))
663 }
664 }
665 }
666
667 pub(crate) fn set_gesture_event_target<T: Fn(GestureEventRef) + 'static>(
668 &self,
669 gesture: ArkUI_GestureRecognizerHandle,
670 action_type: ArkUI_GestureEventActionTypeMask,
671 target_receiver: T,
672 ) -> ArkUIResult<()> {
673 let callback = Box::into_raw(Box::new(GestureEventTargetCallbackContext {
674 callback: Box::new(target_receiver),
675 }));
676 let result = self.set_gesture_event_target_raw(
677 gesture,
678 action_type,
679 callback.cast(),
680 Some(gesture_event_target_callback_trampoline),
681 );
682 if let Err(err) = result {
683 unsafe {
684 drop(Box::from_raw(callback));
685 }
686 return Err(err);
687 }
688 let mut callbacks = match gesture_event_target_callback_contexts().lock() {
689 Ok(callbacks) => callbacks,
690 Err(poisoned) => poisoned.into_inner(),
691 };
692 if let Some(old) = callbacks.insert(gesture as usize, callback as usize) {
693 unsafe {
694 drop(Box::from_raw(old as *mut GestureEventTargetCallbackContext));
695 }
696 }
697 Ok(())
698 }
699
700 pub fn clear_gesture_event_target(
701 &self,
702 gesture: ArkUI_GestureRecognizerHandle,
703 action_type: ArkUI_GestureEventActionTypeMask,
704 ) -> ArkUIResult<()> {
705 self.set_gesture_event_target_raw(gesture, action_type, std::ptr::null_mut(), None)?;
706 let mut callbacks = match gesture_event_target_callback_contexts().lock() {
707 Ok(callbacks) => callbacks,
708 Err(poisoned) => poisoned.into_inner(),
709 };
710 if let Some(callback) = callbacks.remove(&(gesture as usize)) {
711 unsafe {
712 drop(Box::from_raw(
713 callback as *mut GestureEventTargetCallbackContext,
714 ));
715 }
716 }
717 Ok(())
718 }
719}
720
721impl Default for ArkUINativeGestureAPI1 {
722 fn default() -> Self {
723 Self::new()
724 }
725}
726
727#[cfg(feature = "api-18")]
728pub(crate) struct ArkUINativeGestureAPI2(pub(crate) NonNull<ArkUI_NativeGestureAPI_2>);
729
730#[cfg(feature = "api-18")]
731impl ArkUINativeGestureAPI2 {
732 pub(crate) fn raw(&self) -> *mut ArkUI_NativeGestureAPI_2 {
733 self.0.as_ptr()
734 }
735
736 pub fn new() -> Self {
737 let struct_name = CString::new("ArkUI_NativeGestureAPI_2").unwrap();
738 let raw_ptr = unsafe {
739 OH_ArkUI_QueryModuleInterfaceByName(
740 ArkUI_NativeAPIVariantKind_ARKUI_NATIVE_GESTURE,
741 struct_name.as_ptr().cast(),
742 )
743 };
744 let api = NonNull::new(raw_ptr.cast())
745 .unwrap_or_else(|| panic!("ArkUI_NativeGestureAPI_2 is NULL"));
746 Self(api)
747 }
748
749 fn set_gesture_interrupter_to_node_raw(
750 &self,
751 node: ArkUI_NodeHandle,
752 user_data: *mut c_void,
753 interrupter: Option<
754 unsafe extern "C" fn(
755 info: *mut ArkUI_GestureInterruptInfo,
756 ) -> ArkUI_GestureInterruptResult,
757 >,
758 ) -> ArkUIResult<()> {
759 unsafe {
760 if let Some(set_gesture_interrupter_to_node) = (*self.raw()).setGestureInterrupterToNode
761 {
762 check_arkui_status!(set_gesture_interrupter_to_node(
763 node,
764 user_data,
765 interrupter
766 ))
767 } else {
768 Err(ArkUIError::new(
769 ArkUIErrorCode::AttributeOrEventNotSupported,
770 "ArkUINativeGestureAPI2::setGestureInterrupterToNode is None",
771 ))
772 }
773 }
774 }
775
776 pub fn set_gesture_interrupter_to_node<
777 T: Fn(GestureInterruptInfoRef) -> GestureInterruptResult + 'static,
778 >(
779 &self,
780 node: ArkUI_NodeHandle,
781 interrupter: T,
782 ) -> ArkUIResult<()> {
783 let callback = Box::into_raw(Box::new(GestureInterrupterCallbackContext {
784 callback: Box::new(interrupter),
785 }));
786 let result = self.set_gesture_interrupter_to_node_raw(
787 node,
788 callback.cast(),
789 Some(gesture_interrupter_callback_trampoline),
790 );
791 if let Err(err) = result {
792 unsafe {
793 drop(Box::from_raw(callback));
794 }
795 return Err(err);
796 }
797 let mut callbacks = match gesture_interrupter_callback_contexts().lock() {
798 Ok(callbacks) => callbacks,
799 Err(poisoned) => poisoned.into_inner(),
800 };
801 if let Some(old) = callbacks.insert(node as usize, callback as usize) {
802 unsafe {
803 drop(Box::from_raw(old as *mut GestureInterrupterCallbackContext));
804 }
805 }
806 Ok(())
807 }
808
809 pub(crate) fn clear_gesture_interrupter_to_node(
810 &self,
811 node: ArkUI_NodeHandle,
812 ) -> ArkUIResult<()> {
813 self.set_gesture_interrupter_to_node_raw(node, std::ptr::null_mut(), None)?;
814 let mut callbacks = match gesture_interrupter_callback_contexts().lock() {
815 Ok(callbacks) => callbacks,
816 Err(poisoned) => poisoned.into_inner(),
817 };
818 if let Some(callback) = callbacks.remove(&(node as usize)) {
819 unsafe {
820 drop(Box::from_raw(
821 callback as *mut GestureInterrupterCallbackContext,
822 ));
823 }
824 }
825 Ok(())
826 }
827}
828
829#[cfg(feature = "api-18")]
830impl Default for ArkUINativeGestureAPI2 {
831 fn default() -> Self {
832 Self::new()
833 }
834}
835
836fn read_buffer_string<F>(mut reader: F) -> ArkUIResult<String>
837where
838 F: FnMut(*mut std::os::raw::c_char, i32, *mut i32) -> i32,
839{
840 let mut write_length = 0;
841 let mut buffer = vec![0u8; 256];
842 let mut status = reader(
843 buffer.as_mut_ptr().cast(),
844 buffer.len() as i32,
845 &mut write_length,
846 );
847 if write_length > buffer.len() as i32 {
848 buffer.resize(write_length as usize, 0);
849 status = reader(
850 buffer.as_mut_ptr().cast(),
851 buffer.len() as i32,
852 &mut write_length,
853 );
854 }
855 check_arkui_status!(status)?;
856 let mut end = (write_length as usize).min(buffer.len());
857 if end == 0 {
858 end = buffer.iter().position(|v| *v == 0).unwrap_or(0);
859 } else if buffer.get(end.saturating_sub(1)).copied() == Some(0) {
860 end -= 1;
861 }
862 Ok(String::from_utf8_lossy(&buffer[..end]).into_owned())
863}
864
865fn collect_gesture_recognizers(
866 recognizers: ArkUI_GestureRecognizerHandleArray,
867 count: i32,
868) -> Vec<GestureRecognizerRef> {
869 if recognizers.is_null() || count <= 0 {
870 return Vec::new();
871 }
872 let handles = unsafe { std::slice::from_raw_parts(recognizers, count as usize) };
873 handles
874 .iter()
875 .filter_map(|handle| GestureRecognizerRef::from_handle(*handle))
876 .collect()
877}
878
879#[derive(Clone, Copy, Debug)]
880pub struct GestureEventRef {
882 raw: NonNull<ArkUI_GestureEvent>,
883}
884
885impl GestureEventRef {
886 pub(crate) fn from_raw(raw: *mut ArkUI_GestureEvent) -> Option<Self> {
887 NonNull::new(raw).map(|raw| Self { raw })
888 }
889
890 pub(crate) fn from_const_raw(raw: *const ArkUI_GestureEvent) -> Option<Self> {
891 Self::from_raw(raw.cast_mut())
892 }
893
894 fn raw(&self) -> *mut ArkUI_GestureEvent {
895 self.raw.as_ptr()
896 }
897
898 pub fn raw_input_event(&self) -> Option<ohos_arkui_input_binding::ArkUIInputEvent> {
899 let raw_input_event = unsafe { OH_ArkUI_GestureEvent_GetRawInputEvent(self.raw()) };
900 if raw_input_event.is_null() {
901 None
902 } else {
903 Some(ohos_arkui_input_binding::ArkUIInputEvent::from_raw(
904 raw_input_event.cast_mut(),
905 ))
906 }
907 }
908
909 pub fn node(&self) -> Option<crate::ArkUINode> {
910 let node = unsafe { OH_ArkUI_GestureEvent_GetNode(self.raw()) };
911 crate::ArkUINode::from_raw_handle(node)
912 }
913}
914
915#[derive(Clone, Copy, Debug)]
916pub struct GestureEventTargetInfoRef {
918 raw: NonNull<ArkUI_GestureEventTargetInfo>,
919}
920
921impl GestureEventTargetInfoRef {
922 fn from_raw(raw: *mut ArkUI_GestureEventTargetInfo) -> Option<Self> {
923 NonNull::new(raw).map(|raw| Self { raw })
924 }
925
926 fn raw(&self) -> *mut ArkUI_GestureEventTargetInfo {
927 self.raw.as_ptr()
928 }
929
930 pub fn is_scroll_begin(&self) -> ArkUIResult<bool> {
931 let mut ret = false;
932 check_arkui_status!(unsafe {
933 OH_ArkUI_GestureEventTargetInfo_IsScrollBegin(self.raw(), &mut ret)
934 })?;
935 Ok(ret)
936 }
937
938 pub fn is_scroll_end(&self) -> ArkUIResult<bool> {
939 let mut ret = false;
940 check_arkui_status!(unsafe {
941 OH_ArkUI_GestureEventTargetInfo_IsScrollEnd(self.raw(), &mut ret)
942 })?;
943 Ok(ret)
944 }
945}
946
947#[derive(Clone, Copy, Debug)]
948pub struct GestureRecognizerRef {
950 raw: NonNull<ArkUI_GestureRecognizer>,
951}
952
953impl GestureRecognizerRef {
954 pub(crate) fn from_raw(raw: *mut ArkUI_GestureRecognizer) -> Option<Self> {
955 NonNull::new(raw).map(|raw| Self { raw })
956 }
957
958 pub(crate) fn from_handle(handle: ArkUI_GestureRecognizerHandle) -> Option<Self> {
959 Self::from_raw(handle)
960 }
961
962 pub(crate) fn raw(&self) -> *mut ArkUI_GestureRecognizer {
963 self.raw.as_ptr()
964 }
965
966 pub(crate) fn as_handle(&self) -> ArkUI_GestureRecognizerHandle {
967 self.raw()
968 }
969
970 pub fn set_enabled(&self, enabled: bool) -> ArkUIResult<()> {
971 unsafe {
972 check_arkui_status!(ohos_arkui_sys::OH_ArkUI_SetGestureRecognizerEnabled(
973 self.raw(),
974 enabled
975 ))
976 }
977 }
978
979 #[cfg(feature = "api-15")]
980 pub fn set_limit_finger_count(&self, limit_finger_count: bool) -> ArkUIResult<()> {
981 unsafe {
982 check_arkui_status!(
983 ohos_arkui_sys::OH_ArkUI_SetGestureRecognizerLimitFingerCount(
984 self.raw(),
985 limit_finger_count
986 )
987 )
988 }
989 }
990
991 pub fn enabled(&self) -> bool {
992 unsafe { ohos_arkui_sys::OH_ArkUI_GetGestureRecognizerEnabled(self.raw()) }
993 }
994
995 pub fn state(&self) -> ArkUIResult<GestureRecognizerState> {
996 let mut state =
997 ohos_arkui_sys::ArkUI_GestureRecognizerState_ARKUI_GESTURE_RECOGNIZER_STATE_READY;
998 unsafe {
999 check_arkui_status!(ohos_arkui_sys::OH_ArkUI_GetGestureRecognizerState(
1000 self.raw(),
1001 &mut state
1002 ))
1003 }?;
1004 Ok(state.into())
1005 }
1006
1007 pub fn event_target_info(&self) -> ArkUIResult<GestureEventTargetInfoRef> {
1008 let mut info = std::ptr::null_mut();
1009 unsafe {
1010 check_arkui_status!(ohos_arkui_sys::OH_ArkUI_GetGestureEventTargetInfo(
1011 self.raw(),
1012 &mut info
1013 ))
1014 }?;
1015 GestureEventTargetInfoRef::from_raw(info).ok_or_else(|| {
1016 ArkUIError::new(
1017 ArkUIErrorCode::ParamInvalid,
1018 "OH_ArkUI_GetGestureEventTargetInfo returned null",
1019 )
1020 })
1021 }
1022
1023 pub fn pan_direction_mask(&self) -> ArkUIResult<crate::GestureDirection> {
1024 let mut direction_mask: ohos_arkui_sys::ArkUI_GestureDirectionMask = 0;
1025 unsafe {
1026 check_arkui_status!(ohos_arkui_sys::OH_ArkUI_GetPanGestureDirectionMask(
1027 self.raw(),
1028 &mut direction_mask
1029 ))
1030 }?;
1031 Ok(direction_mask.into())
1032 }
1033
1034 pub fn is_built_in(&self) -> bool {
1035 unsafe { ohos_arkui_sys::OH_ArkUI_IsBuiltInGesture(self.raw()) }
1036 }
1037
1038 pub fn tag(&self) -> ArkUIResult<String> {
1039 read_buffer_string(|buffer, buffer_size, write_length| unsafe {
1040 ohos_arkui_sys::OH_ArkUI_GetGestureTag(self.raw(), buffer, buffer_size, write_length)
1041 })
1042 }
1043
1044 pub fn bind_node_id(&self) -> ArkUIResult<String> {
1045 read_buffer_string(|buffer, buffer_size, write_length| unsafe {
1046 ohos_arkui_sys::OH_ArkUI_GetGestureBindNodeId(
1047 self.raw(),
1048 buffer,
1049 buffer_size,
1050 write_length,
1051 )
1052 })
1053 }
1054
1055 pub fn is_valid(&self) -> bool {
1056 unsafe { ohos_arkui_sys::OH_ArkUI_IsGestureRecognizerValid(self.raw()) }
1057 }
1058
1059 pub fn set_dispose_notify<T: Fn() + 'static>(&self, callback: T) -> ArkUIResult<()> {
1060 let callback = Box::into_raw(Box::new(GestureDisposeNotifyCallbackContext {
1061 callback: Box::new(callback),
1062 }));
1063 let result = unsafe {
1064 check_arkui_status!(
1065 ohos_arkui_sys::OH_ArkUI_SetArkUIGestureRecognizerDisposeNotify(
1066 self.raw(),
1067 Some(gesture_dispose_notify_callback_trampoline),
1068 callback.cast(),
1069 )
1070 )
1071 };
1072 if let Err(err) = result {
1073 unsafe {
1074 drop(Box::from_raw(callback));
1075 }
1076 return Err(err);
1077 }
1078 let mut callbacks = match gesture_dispose_notify_callback_contexts().lock() {
1079 Ok(callbacks) => callbacks,
1080 Err(poisoned) => poisoned.into_inner(),
1081 };
1082 if let Some(old) = callbacks.insert(self.as_handle() as usize, callback as usize) {
1083 unsafe {
1084 drop(Box::from_raw(
1085 old as *mut GestureDisposeNotifyCallbackContext,
1086 ));
1087 }
1088 }
1089 Ok(())
1090 }
1091
1092 pub fn clear_dispose_notify(&self) -> ArkUIResult<()> {
1093 unsafe {
1094 check_arkui_status!(
1095 ohos_arkui_sys::OH_ArkUI_SetArkUIGestureRecognizerDisposeNotify(
1096 self.raw(),
1097 None,
1098 std::ptr::null_mut(),
1099 )
1100 )
1101 }?;
1102 let mut callbacks = match gesture_dispose_notify_callback_contexts().lock() {
1103 Ok(callbacks) => callbacks,
1104 Err(poisoned) => poisoned.into_inner(),
1105 };
1106 if let Some(callback) = callbacks.remove(&(self.as_handle() as usize)) {
1107 unsafe {
1108 drop(Box::from_raw(
1109 callback as *mut GestureDisposeNotifyCallbackContext,
1110 ));
1111 }
1112 }
1113 Ok(())
1114 }
1115
1116 #[cfg(feature = "api-19")]
1117 pub fn set_distance_map(
1118 &self,
1119 tool_type_array: &mut [i32],
1120 distance_array: &mut [f64],
1121 ) -> ArkUIResult<()> {
1122 if tool_type_array.len() != distance_array.len() {
1123 return Err(ArkUIError::new(
1124 ArkUIErrorCode::ParamInvalid,
1125 "tool_type_array and distance_array must have the same length",
1126 ));
1127 }
1128 check_arkui_status!(unsafe {
1129 OH_ArkUI_PanGesture_SetDistanceMap(
1130 self.as_handle(),
1131 tool_type_array.len() as i32,
1132 tool_type_array.as_mut_ptr(),
1133 distance_array.as_mut_ptr(),
1134 )
1135 })
1136 }
1137
1138 #[cfg(feature = "api-19")]
1139 pub fn distance_by_tool_type(&self, tool_type: i32) -> ArkUIResult<f64> {
1140 let mut distance = 0f64;
1141 check_arkui_status!(unsafe {
1142 OH_ArkUI_PanGesture_GetDistanceByToolType(self.as_handle(), tool_type, &mut distance)
1143 })?;
1144 Ok(distance)
1145 }
1146
1147 #[cfg(feature = "api-18")]
1148 pub fn param_direct_mask(&self) -> ArkUIResult<crate::GestureDirection> {
1149 let mut direction_mask = 0;
1150 check_arkui_status!(unsafe {
1151 OH_ArkUI_GetGestureParam_DirectMask(self.as_handle(), &mut direction_mask)
1152 })?;
1153 Ok(direction_mask.into())
1154 }
1155
1156 #[cfg(feature = "api-18")]
1157 pub fn param_finger_count(&self) -> ArkUIResult<i32> {
1158 let mut finger = 0;
1159 check_arkui_status!(unsafe {
1160 OH_ArkUI_GetGestureParam_FingerCount(self.as_handle(), &mut finger)
1161 })?;
1162 Ok(finger)
1163 }
1164
1165 #[cfg(feature = "api-18")]
1166 pub fn param_limit_finger_count(&self) -> ArkUIResult<bool> {
1167 let mut limited = false;
1168 check_arkui_status!(unsafe {
1169 OH_ArkUI_GetGestureParam_limitFingerCount(self.as_handle(), &mut limited)
1170 })?;
1171 Ok(limited)
1172 }
1173
1174 #[cfg(feature = "api-18")]
1175 pub fn param_repeat(&self) -> ArkUIResult<bool> {
1176 let mut repeat = false;
1177 check_arkui_status!(unsafe {
1178 OH_ArkUI_GetGestureParam_repeat(self.as_handle(), &mut repeat)
1179 })?;
1180 Ok(repeat)
1181 }
1182
1183 #[cfg(feature = "api-18")]
1184 pub fn param_distance(&self) -> ArkUIResult<f64> {
1185 let mut distance = 0f64;
1186 check_arkui_status!(unsafe {
1187 OH_ArkUI_GetGestureParam_distance(self.as_handle(), &mut distance)
1188 })?;
1189 Ok(distance)
1190 }
1191
1192 #[cfg(feature = "api-18")]
1193 pub fn param_speed(&self) -> ArkUIResult<f64> {
1194 let mut speed = 0f64;
1195 check_arkui_status!(unsafe {
1196 OH_ArkUI_GetGestureParam_speed(self.as_handle(), &mut speed)
1197 })?;
1198 Ok(speed)
1199 }
1200
1201 #[cfg(feature = "api-18")]
1202 pub fn param_duration(&self) -> ArkUIResult<i32> {
1203 let mut duration = 0;
1204 check_arkui_status!(unsafe {
1205 OH_ArkUI_GetGestureParam_duration(self.as_handle(), &mut duration)
1206 })?;
1207 Ok(duration)
1208 }
1209
1210 #[cfg(feature = "api-18")]
1211 pub fn param_angle(&self) -> ArkUIResult<f64> {
1212 let mut angle = 0f64;
1213 check_arkui_status!(unsafe {
1214 OH_ArkUI_GetGestureParam_angle(self.as_handle(), &mut angle)
1215 })?;
1216 Ok(angle)
1217 }
1218
1219 #[cfg(feature = "api-18")]
1220 pub fn param_distance_threshold(&self) -> ArkUIResult<f64> {
1221 let mut distance_threshold = 0f64;
1222 check_arkui_status!(unsafe {
1223 OH_ArkUI_GetGestureParam_distanceThreshold(self.as_handle(), &mut distance_threshold)
1224 })?;
1225 Ok(distance_threshold)
1226 }
1227
1228 #[cfg(feature = "api-22")]
1229 pub fn set_allowable_movement(&self, allowable_movement: f64) -> ArkUIResult<()> {
1230 check_arkui_status!(unsafe {
1231 OH_ArkUI_LongPressGesture_SetAllowableMovement(self.as_handle(), allowable_movement)
1232 })
1233 }
1234
1235 #[cfg(feature = "api-22")]
1236 pub fn allowable_movement(&self) -> ArkUIResult<f64> {
1237 let mut allowable_movement = 0f64;
1238 check_arkui_status!(unsafe {
1239 OH_ArkUI_LongPressGesture_GetAllowableMovement(
1240 self.as_handle(),
1241 &mut allowable_movement,
1242 )
1243 })?;
1244 Ok(allowable_movement)
1245 }
1246}
1247
1248#[derive(Clone, Copy, Debug)]
1249pub struct GestureInterruptInfoRef {
1251 raw: NonNull<ArkUI_GestureInterruptInfo>,
1252}
1253
1254impl GestureInterruptInfoRef {
1255 pub(crate) fn from_raw(raw: *mut ArkUI_GestureInterruptInfo) -> Option<Self> {
1256 NonNull::new(raw).map(|raw| Self { raw })
1257 }
1258
1259 pub(crate) fn from_const_raw(raw: *const ArkUI_GestureInterruptInfo) -> Option<Self> {
1260 Self::from_raw(raw.cast_mut())
1261 }
1262
1263 fn raw(&self) -> *mut ArkUI_GestureInterruptInfo {
1264 self.raw.as_ptr()
1265 }
1266
1267 pub fn system_flag(&self) -> bool {
1268 unsafe { OH_ArkUI_GestureInterruptInfo_GetSystemFlag(self.raw()) }
1269 }
1270
1271 pub fn recognizer(&self) -> Option<GestureRecognizerRef> {
1272 let recognizer = unsafe { OH_ArkUI_GestureInterruptInfo_GetRecognizer(self.raw()) };
1273 GestureRecognizerRef::from_raw(recognizer)
1274 }
1275
1276 pub fn gesture_event(&self) -> Option<GestureEventRef> {
1277 let gesture_event = unsafe { OH_ArkUI_GestureInterruptInfo_GetGestureEvent(self.raw()) };
1278 GestureEventRef::from_raw(gesture_event)
1279 }
1280
1281 pub fn system_recognizer_type(&self) -> Option<crate::GestureRecognizerType> {
1282 let recognizer_type =
1283 unsafe { OH_ArkUI_GestureInterruptInfo_GetSystemRecognizerType(self.raw()) };
1284 if recognizer_type < 0 {
1285 None
1286 } else {
1287 crate::GestureRecognizerType::try_from_raw(
1288 recognizer_type as ohos_arkui_sys::ArkUI_GestureRecognizerType,
1289 )
1290 }
1291 }
1292
1293 pub fn response_recognizers(&self) -> ArkUIResult<Vec<GestureRecognizerRef>> {
1294 let mut response_chain: ArkUI_GestureRecognizerHandleArray = std::ptr::null_mut();
1295 let mut count = 0;
1296 unsafe {
1297 check_arkui_status!(
1298 ohos_arkui_sys::OH_ArkUI_GetResponseRecognizersFromInterruptInfo(
1299 self.raw(),
1300 &mut response_chain,
1301 &mut count
1302 )
1303 )
1304 }?;
1305 Ok(collect_gesture_recognizers(response_chain, count))
1306 }
1307
1308 #[cfg(feature = "api-15")]
1309 pub fn touch_recognizers(&self) -> ArkUIResult<Vec<TouchRecognizerRef>> {
1310 let mut recognizers: ArkUI_TouchRecognizerHandleArray = std::ptr::null_mut();
1311 let mut size = 0;
1312 check_arkui_status!(unsafe {
1313 OH_ArkUI_GestureInterruptInfo_GetTouchRecognizers(
1314 self.raw(),
1315 &mut recognizers,
1316 &mut size,
1317 )
1318 })?;
1319 if recognizers.is_null() || size <= 0 {
1320 return Ok(Vec::new());
1321 }
1322 let handles = unsafe { std::slice::from_raw_parts(recognizers, size as usize) };
1323 Ok(handles
1324 .iter()
1325 .filter_map(|handle| TouchRecognizerRef::from_handle(*handle))
1326 .collect())
1327 }
1328}
1329
1330#[cfg(feature = "api-15")]
1331#[derive(Clone, Copy, Debug)]
1332pub struct TouchRecognizerRef {
1334 raw: NonNull<c_void>,
1335}
1336
1337#[cfg(feature = "api-15")]
1338impl TouchRecognizerRef {
1339 pub(crate) fn from_handle(handle: ArkUI_TouchRecognizerHandle) -> Option<Self> {
1340 NonNull::new(handle.cast()).map(|raw| Self { raw })
1341 }
1342
1343 fn raw(&self) -> ArkUI_TouchRecognizerHandle {
1344 self.raw.as_ptr().cast()
1345 }
1346
1347 pub fn node(&self) -> Option<crate::ArkUINode> {
1348 let node = unsafe { OH_ArkUI_TouchRecognizer_GetNodeHandle(self.raw()) };
1349 crate::ArkUINode::from_raw_handle(node)
1350 }
1351
1352 pub fn cancel_touch(&self, info: GestureInterruptInfoRef) -> ArkUIResult<()> {
1353 check_arkui_status!(unsafe { OH_ArkUI_TouchRecognizer_CancelTouch(self.raw(), info.raw()) })
1354 }
1355}
1356
1357#[derive(Clone, Copy, Debug)]
1358pub struct ParallelInnerGestureEventRef {
1360 raw: NonNull<ArkUI_ParallelInnerGestureEvent>,
1361}
1362
1363impl ParallelInnerGestureEventRef {
1364 pub(crate) fn from_raw(raw: *mut ArkUI_ParallelInnerGestureEvent) -> Option<Self> {
1365 NonNull::new(raw).map(|raw| Self { raw })
1366 }
1367
1368 fn raw(&self) -> *mut ArkUI_ParallelInnerGestureEvent {
1369 self.raw.as_ptr()
1370 }
1371
1372 pub fn user_data(&self) -> Option<NonNull<c_void>> {
1373 NonNull::new(unsafe { OH_ArkUI_ParallelInnerGestureEvent_GetUserData(self.raw()) })
1374 }
1375
1376 pub fn current_recognizer(&self) -> Option<GestureRecognizerRef> {
1377 let recognizer =
1378 unsafe { OH_ArkUI_ParallelInnerGestureEvent_GetCurrentRecognizer(self.raw()) };
1379 GestureRecognizerRef::from_raw(recognizer)
1380 }
1381
1382 pub fn conflict_recognizers(&self) -> ArkUIResult<Vec<GestureRecognizerRef>> {
1383 let mut array: ArkUI_GestureRecognizerHandleArray = std::ptr::null_mut();
1384 let mut size = 0;
1385 check_arkui_status!(unsafe {
1386 OH_ArkUI_ParallelInnerGestureEvent_GetConflictRecognizers(
1387 self.raw(),
1388 &mut array,
1389 &mut size,
1390 )
1391 })?;
1392 Ok(collect_gesture_recognizers(array, size))
1393 }
1394}
1395
1396#[cfg(feature = "api-20")]
1397fn set_touch_test_done_callback_raw(
1398 node: &crate::ArkUINode,
1399 user_data: *mut c_void,
1400 touch_test_done: Option<
1401 unsafe extern "C" fn(
1402 event: *mut ArkUI_GestureEvent,
1403 recognizers: ArkUI_GestureRecognizerHandleArray,
1404 count: i32,
1405 user_data: *mut c_void,
1406 ),
1407 >,
1408) -> ArkUIResult<()> {
1409 unsafe {
1410 check_arkui_status!(ohos_arkui_sys::OH_ArkUI_SetTouchTestDoneCallback(
1411 node.raw(),
1412 user_data,
1413 touch_test_done
1414 ))
1415 }
1416}
1417
1418impl crate::ArkUIHandle {
1419 #[cfg(feature = "api-20")]
1420 pub fn set_touch_test_done_callback<
1421 T: Fn(GestureEventRef, Vec<GestureRecognizerRef>) + 'static,
1422 >(
1423 &self,
1424 node: &crate::ArkUINode,
1425 touch_test_done: T,
1426 ) -> ArkUIResult<()> {
1427 let _ = self.raw();
1428 let callback = Box::into_raw(Box::new(TouchTestDoneCallbackContext {
1429 callback: Box::new(touch_test_done),
1430 }));
1431 let result = set_touch_test_done_callback_raw(
1432 node,
1433 callback.cast(),
1434 Some(touch_test_done_callback_trampoline),
1435 );
1436 if let Err(err) = result {
1437 unsafe {
1438 drop(Box::from_raw(callback));
1439 }
1440 return Err(err);
1441 }
1442 let mut callbacks = match touch_test_done_callback_contexts().lock() {
1443 Ok(callbacks) => callbacks,
1444 Err(poisoned) => poisoned.into_inner(),
1445 };
1446 if let Some(old) = callbacks.insert(node.raw() as usize, callback as usize) {
1447 unsafe {
1448 drop(Box::from_raw(old as *mut TouchTestDoneCallbackContext));
1449 }
1450 }
1451 Ok(())
1452 }
1453
1454 #[cfg(feature = "api-20")]
1455 pub(crate) fn clear_touch_test_done_callback(
1456 &self,
1457 node: &crate::ArkUINode,
1458 ) -> ArkUIResult<()> {
1459 let _ = self.raw();
1460 set_touch_test_done_callback_raw(node, std::ptr::null_mut(), None)?;
1461 let mut callbacks = match touch_test_done_callback_contexts().lock() {
1462 Ok(callbacks) => callbacks,
1463 Err(poisoned) => poisoned.into_inner(),
1464 };
1465 if let Some(callback) = callbacks.remove(&(node.raw() as usize)) {
1466 unsafe {
1467 drop(Box::from_raw(callback as *mut TouchTestDoneCallbackContext));
1468 }
1469 }
1470 Ok(())
1471 }
1472}
1473
1474unsafe extern "C" fn inner_gesture_parallel_callback_trampoline(
1475 event: *mut ArkUI_ParallelInnerGestureEvent,
1476) -> *mut ArkUI_GestureRecognizer {
1477 let Some(event) = ParallelInnerGestureEventRef::from_raw(event) else {
1478 return std::ptr::null_mut();
1479 };
1480 let user_data = unsafe { OH_ArkUI_ParallelInnerGestureEvent_GetUserData(event.raw()) };
1481 if user_data.is_null() {
1482 return std::ptr::null_mut();
1483 }
1484 let callback = unsafe { &*(user_data as *mut InnerGestureParallelCallbackContext) };
1485 match (callback.callback)(event) {
1486 Some(recognizer) => recognizer.as_handle(),
1487 None => std::ptr::null_mut(),
1488 }
1489}
1490
1491unsafe extern "C" fn gesture_event_target_callback_trampoline(
1492 event: *mut ArkUI_GestureEvent,
1493 extra_params: *mut c_void,
1494) {
1495 if extra_params.is_null() {
1496 return;
1497 }
1498 let Some(event) = GestureEventRef::from_raw(event) else {
1499 return;
1500 };
1501 let callback = unsafe { &*(extra_params as *mut GestureEventTargetCallbackContext) };
1502 (callback.callback)(event);
1503}
1504
1505unsafe extern "C" fn gesture_interrupter_callback_trampoline(
1506 info: *mut ArkUI_GestureInterruptInfo,
1507) -> ArkUI_GestureInterruptResult {
1508 let Some(info) = GestureInterruptInfoRef::from_raw(info) else {
1509 return GestureInterruptResult::Continue.into();
1510 };
1511
1512 #[cfg(feature = "api-18")]
1513 let user_data = unsafe { OH_ArkUI_GestureInterrupter_GetUserData(info.raw()) };
1514 #[cfg(feature = "api-18")]
1515 if !user_data.is_null() {
1516 let callback = unsafe { &*(user_data as *mut GestureInterrupterCallbackContext) };
1517 return (callback.callback)(info).into();
1518 }
1519
1520 let Some(node_handle) = info
1521 .gesture_event()
1522 .and_then(|event| event.node())
1523 .map(|node| node.raw())
1524 else {
1525 return GestureInterruptResult::Continue.into();
1526 };
1527
1528 let callback = {
1529 let callbacks = match gesture_interrupter_callback_contexts().lock() {
1530 Ok(callbacks) => callbacks,
1531 Err(poisoned) => poisoned.into_inner(),
1532 };
1533 callbacks.get(&(node_handle as usize)).copied()
1534 };
1535 let Some(callback) = callback else {
1536 return GestureInterruptResult::Continue.into();
1537 };
1538 let callback = unsafe { &*(callback as *const GestureInterrupterCallbackContext) };
1539 (callback.callback)(info).into()
1540}
1541
1542#[cfg(feature = "api-20")]
1543unsafe extern "C" fn touch_test_done_callback_trampoline(
1544 event: *mut ArkUI_GestureEvent,
1545 recognizers: ArkUI_GestureRecognizerHandleArray,
1546 count: i32,
1547 user_data: *mut c_void,
1548) {
1549 if user_data.is_null() {
1550 return;
1551 }
1552 let Some(event) = GestureEventRef::from_raw(event) else {
1553 return;
1554 };
1555 let callback = unsafe { &*(user_data as *mut TouchTestDoneCallbackContext) };
1556 (callback.callback)(event, collect_gesture_recognizers(recognizers, count));
1557}
1558
1559unsafe extern "C" fn gesture_dispose_notify_callback_trampoline(
1560 recognizer: *mut ArkUI_GestureRecognizer,
1561 user_data: *mut c_void,
1562) {
1563 if user_data.is_null() {
1564 return;
1565 }
1566 let callback = unsafe { Box::from_raw(user_data as *mut GestureDisposeNotifyCallbackContext) };
1567 (callback.callback)();
1568 let mut callbacks = match gesture_dispose_notify_callback_contexts().lock() {
1569 Ok(callbacks) => callbacks,
1570 Err(poisoned) => poisoned.into_inner(),
1571 };
1572 if !recognizer.is_null() {
1573 callbacks.remove(&(recognizer as usize));
1574 } else {
1575 callbacks.retain(|_, value| *value != user_data as usize);
1576 }
1577}
1578
1579unsafe extern "C" fn target_receiver(event: *mut ArkUI_GestureEvent, extra_params: *mut c_void) {
1580 let user_data: &Rc<RefCell<InnerGestureData>> =
1581 &*(extra_params as *const Rc<RefCell<InnerGestureData>>);
1582
1583 let data = user_data.borrow_mut();
1584 let event_action_type: GestureEventAction = OH_ArkUI_GestureEvent_GetActionType(event).into();
1585
1586 let event_data: GestureData = match data.gesture_type {
1587 GestureRecognizerType::LongPressGesture => {
1588 let repeat = OH_ArkUI_LongPress_GetRepeatCount(event);
1589 GestureData::LongPress(LongPressGestureData { repeat })
1590 }
1591 GestureRecognizerType::TapGesture => GestureData::Tap,
1592 GestureRecognizerType::PanGesture => {
1593 let velocity = OH_ArkUI_PanGesture_GetVelocity(event);
1594 let velocity_x = OH_ArkUI_PanGesture_GetVelocityX(event);
1595 let velocity_y = OH_ArkUI_PanGesture_GetVelocityY(event);
1596 let offset_x = OH_ArkUI_PanGesture_GetOffsetX(event);
1597 let offset_y = OH_ArkUI_PanGesture_GetOffsetY(event);
1598 GestureData::Pan(PanGestureData {
1599 velocity,
1600 velocity_x,
1601 velocity_y,
1602 offset_x,
1603 offset_y,
1604 })
1605 }
1606 GestureRecognizerType::PinchGesture => {
1607 let scale = OH_ArkUI_PinchGesture_GetScale(event);
1608 let center_x = OH_ArkUI_PinchGesture_GetCenterX(event);
1609 let center_y = OH_ArkUI_PinchGesture_GetCenterY(event);
1610 GestureData::Pinch(PinchGestureData {
1611 scale,
1612 center_x,
1613 center_y,
1614 })
1615 }
1616 GestureRecognizerType::RotationGesture => {
1617 let angle = OH_ArkUI_RotationGesture_GetAngle(event);
1618 GestureData::Rotation(RotationGestureData { angle })
1619 }
1620 GestureRecognizerType::SwipeGesture => {
1621 let angle = OH_ArkUI_SwipeGesture_GetAngle(event);
1622 let velocity = OH_ArkUI_SwipeGesture_GetVelocity(event);
1623 GestureData::Swipe(SwipeGestureData { angle, velocity })
1624 }
1625 _ => unreachable!("Invalid gesture type"),
1626 };
1627
1628 if let Some(event) = data.gesture_callback.as_ref() {
1629 event(GestureEventData {
1630 data: data.user_data,
1631 event_action_type,
1632 event_action_data: event_data,
1633 });
1634 }
1635}