1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "frameworks/bridge/declarative_frontend/jsview/js_gesture.h"
17
18 #include "frameworks/base/log/ace_scoring_log.h"
19 #include "frameworks/bridge/declarative_frontend/engine/functions/js_gesture_function.h"
20 #include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
21 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
22 #include "frameworks/core/components/gesture_listener/gesture_component.h"
23 #include "frameworks/core/components_ng/base/view_stack_processor.h"
24 #include "frameworks/core/components_ng/gestures/gesture_group.h"
25 #include "frameworks/core/components_ng/gestures/long_press_gesture.h"
26 #include "frameworks/core/components_ng/gestures/pan_gesture.h"
27 #include "frameworks/core/components_ng/gestures/pinch_gesture.h"
28 #include "frameworks/core/components_ng/gestures/recognizers/exclusive_recognizer.h"
29 #include "frameworks/core/components_ng/gestures/recognizers/parallel_recognizer.h"
30 #include "frameworks/core/components_ng/gestures/rotation_gesture.h"
31 #include "frameworks/core/components_ng/gestures/swipe_gesture.h"
32 #include "frameworks/core/components_ng/gestures/tap_gesture.h"
33 #include "frameworks/core/gestures/exclusive_recognizer.h"
34 #include "frameworks/core/gestures/gesture_group.h"
35 #include "frameworks/core/gestures/long_press_gesture.h"
36 #include "frameworks/core/gestures/pan_gesture.h"
37 #include "frameworks/core/gestures/parallel_recognizer.h"
38 #include "frameworks/core/gestures/pinch_gesture.h"
39 #include "frameworks/core/gestures/rotation_gesture.h"
40 #include "frameworks/core/gestures/slide_gesture.h"
41 #include "frameworks/core/gestures/tap_gesture.h"
42 #include "frameworks/core/gestures/timeout_gesture.h"
43
44 namespace OHOS::Ace::Framework {
45
46 namespace {
47 constexpr int32_t DEFAULT_TAP_FINGER = 1;
48 constexpr int32_t DEFAULT_TAP_COUNT = 1;
49 constexpr int32_t DEFAULT_LONG_PRESS_FINGER = 1;
50 constexpr int32_t DEFAULT_LONG_PRESS_DURATION = 500;
51 constexpr int32_t DEFAULT_PINCH_FINGER = 2;
52 constexpr double DEFAULT_PINCH_DISTANCE = 3.0;
53 constexpr int32_t DEFAULT_PAN_FINGER = 1;
54 constexpr double DEFAULT_PAN_DISTANCE = 5.0;
55 constexpr int32_t DEFAULT_SLIDE_FINGER = DEFAULT_PAN_FINGER;
56 constexpr double DEFAULT_SLIDE_SPEED = 100.0;
57 constexpr int32_t DEFAULT_ROTATION_FINGER = 2;
58 constexpr double DEFAULT_ROTATION_ANGLE = 1.0;
59
60 constexpr char GESTURE_FINGERS[] = "fingers";
61 constexpr char GESTURE_DISTANCE[] = "distance";
62 constexpr char GESTURE_SPEED[] = "speed";
63 constexpr char TAP_COUNT[] = "count";
64 constexpr char LONG_PRESS_REPEAT[] = "repeat";
65 constexpr char LONG_PRESS_DURATION[] = "duration";
66 constexpr char PAN_DIRECTION[] = "direction";
67 constexpr char SWIPE_DIRECTION[] = "direction";
68 constexpr char ROTATION_ANGLE[] = "angle";
69 } // namespace
70
Create(const JSCallbackInfo & info)71 void JSGesture::Create(const JSCallbackInfo& info)
72 {
73 LOGD("JS gesture create");
74 RefPtr<GestureProcessor> gestureProcessor;
75 if (Container::IsCurrentUseNewPipeline()) {
76 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
77 } else {
78 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
79 }
80
81 GesturePriority priority = GesturePriority::Low;
82 if (info.Length() > 0 && info[0]->IsNumber()) {
83 int32_t priorityNum = info[0]->ToNumber<int32_t>();
84 if (priorityNum > static_cast<int32_t>(GesturePriority::Begin) &&
85 priorityNum < static_cast<int32_t>(GesturePriority::End)) {
86 priority = static_cast<GesturePriority>(priorityNum);
87 }
88 }
89 gestureProcessor->SetPriority(priority);
90
91 GestureMask gestureMask = GestureMask::Normal;
92 if (info.Length() > 1 && info[1]->IsNumber()) {
93 int32_t gestureMaskNum = info[1]->ToNumber<int32_t>();
94 if (gestureMaskNum > static_cast<int32_t>(GestureMask::Begin) &&
95 gestureMaskNum < static_cast<int32_t>(GestureMask::End)) {
96 gestureMask = static_cast<GestureMask>(gestureMaskNum);
97 }
98 }
99 gestureProcessor->SetGestureMask(gestureMask);
100 }
101
Finish()102 void JSGesture::Finish()
103 {
104 LOGD("JS gesture finish");
105 RefPtr<GestureProcessor> gestureProcessor;
106 if (Container::IsCurrentUseNewPipeline()) {
107 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
108 NG::ViewStackProcessor::GetInstance()->ResetGestureProcessor();
109
110 auto gesture = gestureProcessor->FinishGestureNG();
111 if (!gesture) {
112 LOGE("gesture is not exist when component finish");
113 return;
114 }
115 gesture->SetGestureMask(gestureProcessor->GetGestureMask());
116 gesture->SetPriority(gestureProcessor->GetPriority());
117 auto gestureEventHub = NG::ViewStackProcessor::GetInstance()->GetMainFrameNodeGestureEventHub();
118 if (gestureEventHub) {
119 gestureEventHub->AddGesture(gesture);
120 }
121 return;
122 }
123
124 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
125 auto gesture = gestureProcessor->FinishGesture();
126 if (!gesture) {
127 LOGE("gesture is not exist when component finish");
128 return;
129 }
130 gesture->SetGestureMask(gestureProcessor->GetGestureMask());
131 gesture->SetPriority(gestureProcessor->GetPriority());
132 auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
133 boxComponent->AddGesture(gestureProcessor->GetPriority(), gesture);
134 }
135
Pop()136 void JSGesture::Pop()
137 {
138 LOGD("JS gesture pop");
139 RefPtr<GestureProcessor> gestureProcessor;
140 if (Container::IsCurrentUseNewPipeline()) {
141 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
142 gestureProcessor->PopGestureNG();
143 } else {
144 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
145 gestureProcessor->PopGesture();
146 };
147 }
148
Create(const JSCallbackInfo & args)149 void JSTapGesture::Create(const JSCallbackInfo& args)
150 {
151 LOGD("JSTapGesture Create");
152 int32_t countNum = DEFAULT_TAP_COUNT;
153 int32_t fingersNum = DEFAULT_TAP_FINGER;
154 if (args.Length() > 0 && args[0]->IsObject()) {
155 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
156 JSRef<JSVal> count = obj->GetProperty(TAP_COUNT);
157 JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
158
159 if (count->IsNumber()) {
160 int32_t countNumber = count->ToNumber<int32_t>();
161 countNum = countNumber <= DEFAULT_TAP_COUNT ? DEFAULT_TAP_COUNT : countNumber;
162 }
163 if (fingers->IsNumber()) {
164 int32_t fingersNumber = fingers->ToNumber<int32_t>();
165 fingersNum = fingersNumber <= DEFAULT_TAP_FINGER ? DEFAULT_TAP_FINGER : fingersNumber;
166 }
167 }
168
169 LOGD("JS Tap gesture created with count %{public}d, fingers %{public}d", countNum, fingersNum);
170 RefPtr<GestureProcessor> gestureProcessor;
171 if (Container::IsCurrentUseNewPipeline()) {
172 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
173 auto gesture = AceType::MakeRefPtr<NG::TapGesture>(countNum, fingersNum);
174 gestureProcessor->PushGestureNG(gesture);
175 } else {
176 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
177 auto gesture = AceType::MakeRefPtr<TapGesture>(countNum, fingersNum);
178 gestureProcessor->PushGesture(gesture);
179 }
180 }
181
Create(const JSCallbackInfo & args)182 void JSLongPressGesture::Create(const JSCallbackInfo& args)
183 {
184 LOGD("JSLongPressGesture Create");
185 int32_t fingersNum = DEFAULT_LONG_PRESS_FINGER;
186 bool repeatResult = false;
187 int32_t durationNum = DEFAULT_LONG_PRESS_DURATION;
188 if (args.Length() > 0 && args[0]->IsObject()) {
189 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
190 JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
191 JSRef<JSVal> repeat = obj->GetProperty(LONG_PRESS_REPEAT);
192 JSRef<JSVal> duration = obj->GetProperty(LONG_PRESS_DURATION);
193
194 if (fingers->IsNumber()) {
195 int32_t fingersNumber = fingers->ToNumber<int32_t>();
196 fingersNum = fingersNumber <= DEFAULT_LONG_PRESS_FINGER ? DEFAULT_LONG_PRESS_FINGER : fingersNumber;
197 }
198 if (repeat->IsBoolean()) {
199 repeatResult = repeat->ToBoolean();
200 }
201 if (duration->IsNumber()) {
202 int32_t durationNumber = duration->ToNumber<int32_t>();
203 durationNum = durationNumber <= 0 ? DEFAULT_LONG_PRESS_DURATION : durationNumber;
204 }
205 }
206
207 RefPtr<GestureProcessor> gestureProcessor;
208 if (Container::IsCurrentUseNewPipeline()) {
209 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
210 auto gesture = AceType::MakeRefPtr<NG::LongPressGesture>(fingersNum, repeatResult, durationNum);
211 gestureProcessor->PushGestureNG(gesture);
212 } else {
213 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
214 auto gesture = AceType::MakeRefPtr<LongPressGesture>(fingersNum, repeatResult, durationNum);
215 gestureProcessor->PushGesture(gesture);
216 }
217 }
218
Create(const JSCallbackInfo & args)219 void JSPanGesture::Create(const JSCallbackInfo& args)
220 {
221 LOGD("JSPanGesture Create");
222 int32_t fingersNum = DEFAULT_PAN_FINGER;
223 double distanceNum = DEFAULT_PAN_DISTANCE;
224 PanDirection panDirection;
225 RefPtr<GestureProcessor> gestureProcessor;
226 if (Container::IsCurrentUseNewPipeline()) {
227 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
228 if (args.Length() <= 0 || !args[0]->IsObject()) {
229 auto gesture = AceType::MakeRefPtr<NG::PanGesture>(fingersNum, panDirection, distanceNum);
230 gestureProcessor->PushGestureNG(gesture);
231 return;
232 }
233 } else {
234 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
235 if (args.Length() <= 0 || !args[0]->IsObject()) {
236 auto gesture = AceType::MakeRefPtr<PanGesture>(fingersNum, panDirection, distanceNum);
237 gestureProcessor->PushGesture(gesture);
238 return;
239 }
240 }
241
242 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
243 JSPanGestureOption* panGestureOption = obj->Unwrap<JSPanGestureOption>();
244
245 if (Container::IsCurrentUseNewPipeline()) {
246 if (panGestureOption != nullptr) {
247 auto gesture = AceType::MakeRefPtr<NG::PanGesture>(panGestureOption->GetPanGestureOption());
248 gestureProcessor->PushGestureNG(gesture);
249 return;
250 }
251 } else {
252 if (panGestureOption != nullptr) {
253 auto gesture = AceType::MakeRefPtr<PanGesture>(panGestureOption->GetPanGestureOption());
254 gestureProcessor->PushGesture(gesture);
255 return;
256 }
257 }
258
259 JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
260 JSRef<JSVal> distance = obj->GetProperty(GESTURE_DISTANCE);
261 JSRef<JSVal> directionNum = obj->GetProperty(PAN_DIRECTION);
262
263 if (fingers->IsNumber()) {
264 int32_t fingersNumber = fingers->ToNumber<int32_t>();
265 fingersNum = fingersNumber <= DEFAULT_PAN_FINGER ? DEFAULT_PAN_FINGER : fingersNumber;
266 }
267 if (distance->IsNumber()) {
268 double distanceNumber = distance->ToNumber<double>();
269 distanceNum = LessNotEqual(distanceNumber, 0.0) ? DEFAULT_PAN_DISTANCE : distanceNumber;
270 }
271 if (directionNum->IsNumber()) {
272 uint32_t directNum = directionNum->ToNumber<uint32_t>();
273 if (directNum >= static_cast<uint32_t>(PanDirection::NONE) &&
274 directNum <= static_cast<uint32_t>(PanDirection::ALL)) {
275 panDirection.type = directNum;
276 }
277 }
278
279 if (Container::IsCurrentUseNewPipeline()) {
280 auto gesture = AceType::MakeRefPtr<NG::PanGesture>(fingersNum, panDirection, distanceNum);
281 gestureProcessor->PushGestureNG(gesture);
282 } else {
283 auto gesture = AceType::MakeRefPtr<PanGesture>(fingersNum, panDirection, distanceNum);
284 gestureProcessor->PushGesture(gesture);
285 }
286 }
287
Create(const JSCallbackInfo & args)288 void JSSwipeGesture::Create(const JSCallbackInfo& args)
289 {
290 LOGD("JSSwipeGesture Create");
291 int32_t fingersNum = DEFAULT_SLIDE_FINGER;
292 double speedNum = DEFAULT_SLIDE_SPEED;
293 SwipeDirection slideDirection;
294 RefPtr<GestureProcessor> gestureProcessor;
295 if (Container::IsCurrentUseNewPipeline()) {
296 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
297 if (args.Length() <= 0 || !args[0]->IsObject()) {
298 auto gesture = AceType::MakeRefPtr<NG::SwipeGesture>(fingersNum, slideDirection, speedNum);
299 gestureProcessor->PushGestureNG(gesture);
300 return;
301 }
302 } else {
303 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
304 if (args.Length() <= 0 || !args[0]->IsObject()) {
305 auto gesture = AceType::MakeRefPtr<SwipeGesture>(fingersNum, slideDirection, speedNum);
306 gestureProcessor->PushGesture(gesture);
307 return;
308 }
309 };
310
311 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
312 JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
313 JSRef<JSVal> speed = obj->GetProperty(GESTURE_SPEED);
314 JSRef<JSVal> directionNum = obj->GetProperty(SWIPE_DIRECTION);
315
316 if (fingers->IsNumber()) {
317 int32_t fingersNumber = fingers->ToNumber<int32_t>();
318 fingersNum = fingersNumber <= DEFAULT_PAN_FINGER ? DEFAULT_PAN_FINGER : fingersNumber;
319 }
320 if (speed->IsNumber()) {
321 double speedNumber = speed->ToNumber<double>();
322 speedNum = LessNotEqual(speedNumber, 0.0) ? DEFAULT_SLIDE_SPEED : speedNumber;
323 }
324 if (directionNum->IsNumber()) {
325 uint32_t directNum = directionNum->ToNumber<uint32_t>();
326 if (directNum >= static_cast<uint32_t>(SwipeDirection::NONE) &&
327 directNum <= static_cast<uint32_t>(SwipeDirection::ALL)) {
328 slideDirection.type = directNum;
329 }
330 }
331
332 if (Container::IsCurrentUseNewPipeline()) {
333 auto gesture = AceType::MakeRefPtr<NG::SwipeGesture>(fingersNum, slideDirection, speedNum);
334 gestureProcessor->PushGestureNG(gesture);
335 } else {
336 auto gesture = AceType::MakeRefPtr<SwipeGesture>(fingersNum, slideDirection, speedNum);
337 gestureProcessor->PushGesture(gesture);
338 }
339 }
340
Create(const JSCallbackInfo & args)341 void JSPinchGesture::Create(const JSCallbackInfo& args)
342 {
343 LOGD("JSPinchGesture Create");
344 int32_t fingersNum = DEFAULT_PINCH_FINGER;
345 double distanceNum = DEFAULT_PINCH_DISTANCE;
346 if (args.Length() > 0 && args[0]->IsObject()) {
347 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
348 JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
349 JSRef<JSVal> distance = obj->GetProperty(GESTURE_DISTANCE);
350
351 if (fingers->IsNumber()) {
352 int32_t fingersNumber = fingers->ToNumber<int32_t>();
353 fingersNum = fingersNumber <= DEFAULT_PINCH_FINGER ? DEFAULT_PINCH_FINGER : fingersNumber;
354 }
355 if (distance->IsNumber()) {
356 double distanceNumber = distance->ToNumber<double>();
357 distanceNum = LessNotEqual(distanceNumber, 0.0) ? DEFAULT_PINCH_DISTANCE : distanceNumber;
358 }
359 }
360
361 RefPtr<GestureProcessor> gestureProcessor;
362 if (Container::IsCurrentUseNewPipeline()) {
363 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
364 auto gesture = AceType::MakeRefPtr<NG::PinchGesture>(fingersNum, distanceNum);
365 gestureProcessor->PushGestureNG(gesture);
366 } else {
367 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
368 auto gesture = AceType::MakeRefPtr<PinchGesture>(fingersNum, distanceNum);
369 gestureProcessor->PushGesture(gesture);
370 };
371 }
372
Create(const JSCallbackInfo & args)373 void JSRotationGesture::Create(const JSCallbackInfo& args)
374 {
375 LOGD("JSRotationGesture Create");
376 double angleNum = DEFAULT_ROTATION_ANGLE;
377 int32_t fingersNum = DEFAULT_ROTATION_FINGER;
378 if (args.Length() > 0 && args[0]->IsObject()) {
379 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
380 JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
381 JSRef<JSVal> angle = obj->GetProperty(ROTATION_ANGLE);
382
383 if (fingers->IsNumber()) {
384 int32_t fingersNumber = fingers->ToNumber<int32_t>();
385 fingersNum = fingersNumber <= DEFAULT_ROTATION_FINGER ? DEFAULT_ROTATION_FINGER : fingersNumber;
386 }
387 if (angle->IsNumber()) {
388 double angleNumber = angle->ToNumber<double>();
389 angleNum = LessNotEqual(angleNumber, 0.0) ? DEFAULT_ROTATION_ANGLE : angleNumber;
390 }
391 }
392
393 RefPtr<GestureProcessor> gestureProcessor;
394 if (Container::IsCurrentUseNewPipeline()) {
395 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
396 auto gesture = AceType::MakeRefPtr<NG::RotationGesture>(fingersNum, angleNum);
397 gestureProcessor->PushGestureNG(gesture);
398 } else {
399 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
400 auto gesture = AceType::MakeRefPtr<RotationGesture>(fingersNum, angleNum);
401 gestureProcessor->PushGesture(gesture);
402 };
403 }
404
Create(const JSCallbackInfo & args)405 void JSGestureGroup::Create(const JSCallbackInfo& args)
406 {
407 int32_t gestureMode = 0;
408 if (args.Length() > 0 && args[0]->IsNumber()) {
409 gestureMode = args[0]->ToNumber<int32_t>();
410 }
411
412 LOGD("Js Gesture group create with mode %{public}d", gestureMode);
413 RefPtr<GestureProcessor> gestureProcessor;
414 if (Container::IsCurrentUseNewPipeline()) {
415 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
416 auto gesture = AceType::MakeRefPtr<NG::GestureGroup>(static_cast<GestureMode>(gestureMode));
417 gestureProcessor->PushGestureNG(gesture);
418 } else {
419 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
420 auto gesture = AceType::MakeRefPtr<GestureGroup>(static_cast<GestureMode>(gestureMode));
421 gestureProcessor->PushGesture(gesture);
422 };
423 }
424
JsHandlerOnGestureEvent(JSGestureEvent action,const JSCallbackInfo & args)425 void JSGesture::JsHandlerOnGestureEvent(JSGestureEvent action, const JSCallbackInfo& args)
426 {
427 if (args.Length() < 1 || !args[0]->IsFunction()) {
428 LOGE("args is not js function");
429 return;
430 }
431
432 RefPtr<GestureProcessor> gestureProcessor;
433 if (Container::IsCurrentUseNewPipeline()) {
434 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
435 auto gesture = gestureProcessor->TopGestureNG();
436 if (!gesture) {
437 LOGE("top gesture is illegal");
438 return;
439 }
440 RefPtr<JsGestureFunction> handlerFunc = AceType::MakeRefPtr<JsGestureFunction>(JSRef<JSFunc>::Cast(args[0]));
441
442 if (action == JSGestureEvent::CANCEL) {
443 auto onActionCancelFunc = [execCtx = args.GetExecutionContext(), func = std::move(handlerFunc)]() {
444 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
445 auto info = GestureEvent();
446 ACE_SCORING_EVENT("Gesture.onCancel");
447 func->Execute(info);
448 };
449 gesture->SetOnActionCancelId(onActionCancelFunc);
450 return;
451 }
452
453 auto onActionFunc = [execCtx = args.GetExecutionContext(), func = std::move(handlerFunc)](GestureEvent& info) {
454 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
455 ACE_SCORING_EVENT("Gesture.onActionCancel");
456 func->Execute(info);
457 };
458
459 switch (action) {
460 case JSGestureEvent::ACTION:
461 gesture->SetOnActionId(onActionFunc);
462 break;
463 case JSGestureEvent::START:
464 gesture->SetOnActionStartId(onActionFunc);
465 break;
466 case JSGestureEvent::UPDATE:
467 gesture->SetOnActionUpdateId(onActionFunc);
468 break;
469 case JSGestureEvent::END:
470 gesture->SetOnActionEndId(onActionFunc);
471 break;
472 default:
473 LOGW("Unknown gesture action %{public}d", action);
474 break;
475 }
476 return;
477 }
478
479 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
480 auto gesture = gestureProcessor->TopGesture();
481 if (!gesture) {
482 LOGE("top gesture is illegal");
483 return;
484 }
485 RefPtr<JsGestureFunction> handlerFunc = AceType::MakeRefPtr<JsGestureFunction>(JSRef<JSFunc>::Cast(args[0]));
486 RefPtr<V2::InspectorFunctionImpl> impl;
487 auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
488 if (!inspector) {
489 LOGE("fail to get inspector for on handle event");
490 return;
491 }
492 impl = inspector->GetInspectorFunctionImpl();
493
494 if (action == JSGestureEvent::CANCEL) {
495 auto onActionCancelFunc = [execCtx = args.GetExecutionContext(), func = std::move(handlerFunc), impl]() {
496 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
497 auto info = GestureEvent();
498 if (impl) {
499 impl->UpdateEventInfo(info);
500 }
501 ACE_SCORING_EVENT("Gesture.onCancel");
502 func->Execute(info);
503 };
504 gesture->SetOnActionCancelId(onActionCancelFunc);
505 return;
506 }
507
508 auto onActionFunc = [execCtx = args.GetExecutionContext(), func = std::move(handlerFunc), impl](
509 GestureEvent& info) {
510 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
511 if (impl) {
512 impl->UpdateEventInfo(info);
513 }
514 ACE_SCORING_EVENT("Gesture.onActionCancel");
515 func->Execute(info);
516 };
517
518 switch (action) {
519 case JSGestureEvent::ACTION:
520 gesture->SetOnActionId(onActionFunc);
521 break;
522 case JSGestureEvent::START:
523 gesture->SetOnActionStartId(onActionFunc);
524 break;
525 case JSGestureEvent::UPDATE:
526 gesture->SetOnActionUpdateId(onActionFunc);
527 break;
528 case JSGestureEvent::END:
529 gesture->SetOnActionEndId(onActionFunc);
530 break;
531 default:
532 LOGW("Unknown gesture action %{public}d", action);
533 break;
534 }
535 }
536
JsHandlerOnAction(const JSCallbackInfo & args)537 void JSGesture::JsHandlerOnAction(const JSCallbackInfo& args)
538 {
539 JSGesture::JsHandlerOnGestureEvent(JSGestureEvent::ACTION, args);
540 }
JsHandlerOnActionStart(const JSCallbackInfo & args)541 void JSGesture::JsHandlerOnActionStart(const JSCallbackInfo& args)
542 {
543 JSGesture::JsHandlerOnGestureEvent(JSGestureEvent::START, args);
544 }
JsHandlerOnActionUpdate(const JSCallbackInfo & args)545 void JSGesture::JsHandlerOnActionUpdate(const JSCallbackInfo& args)
546 {
547 JSGesture::JsHandlerOnGestureEvent(JSGestureEvent::UPDATE, args);
548 }
549
JsHandlerOnActionEnd(const JSCallbackInfo & args)550 void JSGesture::JsHandlerOnActionEnd(const JSCallbackInfo& args)
551 {
552 JSGesture::JsHandlerOnGestureEvent(JSGestureEvent::END, args);
553 }
JsHandlerOnActionCancel(const JSCallbackInfo & args)554 void JSGesture::JsHandlerOnActionCancel(const JSCallbackInfo& args)
555 {
556 JSGesture::JsHandlerOnGestureEvent(JSGestureEvent::CANCEL, args);
557 }
558
JSBind(BindingTarget globalObj)559 void JSPanGestureOption::JSBind(BindingTarget globalObj)
560 {
561 JSClass<JSPanGestureOption>::Declare("PanGestureOption");
562 JSClass<JSPanGestureOption>::CustomMethod("setDirection", &JSPanGestureOption::SetDirection);
563 JSClass<JSPanGestureOption>::CustomMethod("setDistance", &JSPanGestureOption::SetDistance);
564 JSClass<JSPanGestureOption>::CustomMethod("setFingers", &JSPanGestureOption::SetFingers);
565 JSClass<JSPanGestureOption>::Bind(globalObj, &JSPanGestureOption::Constructor, &JSPanGestureOption::Destructor);
566
567 JSClass<JSPanGestureOption>::Declare("PanGestureOptions");
568 JSClass<JSPanGestureOption>::CustomMethod("setDirection", &JSPanGestureOption::SetDirection);
569 JSClass<JSPanGestureOption>::CustomMethod("setDistance", &JSPanGestureOption::SetDistance);
570 JSClass<JSPanGestureOption>::CustomMethod("setFingers", &JSPanGestureOption::SetFingers);
571 JSClass<JSPanGestureOption>::Bind(globalObj, &JSPanGestureOption::Constructor, &JSPanGestureOption::Destructor);
572 }
573
SetDirection(const JSCallbackInfo & args)574 void JSPanGestureOption::SetDirection(const JSCallbackInfo& args)
575 {
576 if (args.Length() > 0 && args[0]->IsNumber()) {
577 PanDirection direction = { args[0]->ToNumber<int32_t>() };
578 panGestureOption_->SetDirection(direction);
579 }
580 }
581
SetDistance(const JSCallbackInfo & args)582 void JSPanGestureOption::SetDistance(const JSCallbackInfo& args)
583 {
584 if (args.Length() > 0 && args[0]->IsNumber()) {
585 auto distance = args[0]->ToNumber<double>();
586 panGestureOption_->SetDistance(distance);
587 }
588 }
589
SetFingers(const JSCallbackInfo & args)590 void JSPanGestureOption::SetFingers(const JSCallbackInfo& args)
591 {
592 if (args.Length() > 0 && args[0]->IsNumber()) {
593 auto fingers = args[0]->ToNumber<int32_t>();
594 panGestureOption_->SetFingers(fingers);
595 }
596 }
597
Constructor(const JSCallbackInfo & args)598 void JSPanGestureOption::Constructor(const JSCallbackInfo& args)
599 {
600 auto panGestureOption = Referenced::MakeRefPtr<JSPanGestureOption>();
601 panGestureOption->IncRefCount();
602 RefPtr<PanGestureOption> option = AceType::MakeRefPtr<PanGestureOption>();
603
604 int32_t fingersNum = DEFAULT_PAN_FINGER;
605 double distanceNum = DEFAULT_PAN_DISTANCE;
606 PanDirection panDirection;
607
608 if (args.Length() > 0 && args[0]->IsObject()) {
609 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
610 JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
611 JSRef<JSVal> distance = obj->GetProperty(GESTURE_DISTANCE);
612 JSRef<JSVal> directionNum = obj->GetProperty(PAN_DIRECTION);
613
614 if (fingers->IsNumber()) {
615 int32_t fingersNumber = fingers->ToNumber<int32_t>();
616 fingersNum = fingersNumber <= DEFAULT_PAN_FINGER ? DEFAULT_PAN_FINGER : fingersNumber;
617 }
618 if (distance->IsNumber()) {
619 double distanceNumber = distance->ToNumber<double>();
620 distanceNum = LessNotEqual(distanceNumber, 0.0) ? DEFAULT_PAN_DISTANCE : distanceNumber;
621 }
622 if (directionNum->IsNumber()) {
623 uint32_t directNum = directionNum->ToNumber<uint32_t>();
624 if (directNum >= static_cast<uint32_t>(PanDirection::NONE) &&
625 directNum <= static_cast<uint32_t>(PanDirection::ALL)) {
626 panDirection.type = directNum;
627 }
628 }
629 }
630 option->SetDirection(panDirection);
631 option->SetDistance(distanceNum);
632 option->SetFingers(fingersNum);
633
634 panGestureOption->SetPanGestureOption(option);
635 args.SetReturnValue(Referenced::RawPtr(panGestureOption));
636 }
637
Destructor(JSPanGestureOption * panGestureOption)638 void JSPanGestureOption::Destructor(JSPanGestureOption* panGestureOption)
639 {
640 if (panGestureOption != nullptr) {
641 panGestureOption->DecRefCount();
642 }
643 }
644
JSBind(BindingTarget globalObj)645 void JSGesture::JSBind(BindingTarget globalObj)
646 {
647 JSClass<JSGesture>::Declare("Gesture");
648 MethodOptions opt = MethodOptions::NONE;
649 JSClass<JSGesture>::StaticMethod("create", &JSGesture::Create, opt);
650 JSClass<JSGesture>::StaticMethod("pop", &JSGesture::Finish);
651 JSClass<JSGesture>::Bind<>(globalObj);
652
653 JSClass<JSTapGesture>::Declare("TapGesture");
654 JSClass<JSTapGesture>::StaticMethod("create", &JSTapGesture::Create, opt);
655 JSClass<JSTapGesture>::StaticMethod("pop", &JSGesture::Pop);
656 JSClass<JSTapGesture>::StaticMethod("onAction", &JSGesture::JsHandlerOnAction);
657 JSClass<JSTapGesture>::StaticMethod("onActionUpdate", &JSGesture::JsHandlerOnActionUpdate);
658 JSClass<JSTapGesture>::Bind<>(globalObj);
659
660 JSClass<JSLongPressGesture>::Declare("LongPressGesture");
661 JSClass<JSLongPressGesture>::StaticMethod("create", &JSLongPressGesture::Create, opt);
662 JSClass<JSLongPressGesture>::StaticMethod("pop", &JSGesture::Pop);
663 JSClass<JSLongPressGesture>::StaticMethod("onAction", &JSGesture::JsHandlerOnAction);
664 JSClass<JSLongPressGesture>::StaticMethod("onActionEnd", &JSGesture::JsHandlerOnActionEnd);
665 JSClass<JSLongPressGesture>::StaticMethod("onActionCancel", &JSGesture::JsHandlerOnActionCancel);
666 JSClass<JSLongPressGesture>::StaticMethod("onActionUpdate", &JSGesture::JsHandlerOnActionUpdate);
667 JSClass<JSLongPressGesture>::Bind(globalObj);
668
669 JSClass<JSPanGesture>::Declare("PanGesture");
670 JSClass<JSPanGesture>::StaticMethod("create", &JSPanGesture::Create, opt);
671 JSClass<JSPanGesture>::StaticMethod("pop", &JSGesture::Pop);
672 JSClass<JSPanGesture>::StaticMethod("onActionStart", &JSGesture::JsHandlerOnActionStart);
673 JSClass<JSPanGesture>::StaticMethod("onActionUpdate", &JSGesture::JsHandlerOnActionUpdate);
674 JSClass<JSPanGesture>::StaticMethod("onActionEnd", &JSGesture::JsHandlerOnActionEnd);
675 JSClass<JSPanGesture>::StaticMethod("onActionCancel", &JSGesture::JsHandlerOnActionCancel);
676 JSClass<JSPanGesture>::Bind(globalObj);
677
678 JSClass<JSSwipeGesture>::Declare("SwipeGesture");
679 JSClass<JSSwipeGesture>::StaticMethod("create", &JSSwipeGesture::Create, opt);
680 JSClass<JSSwipeGesture>::StaticMethod("pop", &JSGesture::Pop);
681 JSClass<JSSwipeGesture>::StaticMethod("onAction", &JSGesture::JsHandlerOnAction);
682 JSClass<JSSwipeGesture>::Bind(globalObj);
683
684 JSClass<JSPinchGesture>::Declare("PinchGesture");
685 JSClass<JSPinchGesture>::StaticMethod("create", &JSPinchGesture::Create, opt);
686 JSClass<JSPinchGesture>::StaticMethod("pop", &JSGesture::Pop);
687 JSClass<JSPinchGesture>::StaticMethod("onActionStart", &JSGesture::JsHandlerOnActionStart);
688 JSClass<JSPinchGesture>::StaticMethod("onActionUpdate", &JSGesture::JsHandlerOnActionUpdate);
689 JSClass<JSPinchGesture>::StaticMethod("onActionEnd", &JSGesture::JsHandlerOnActionEnd);
690 JSClass<JSPinchGesture>::StaticMethod("onActionCancel", &JSGesture::JsHandlerOnActionCancel);
691 JSClass<JSPinchGesture>::Bind(globalObj);
692
693 JSClass<JSRotationGesture>::Declare("RotationGesture");
694 JSClass<JSRotationGesture>::StaticMethod("create", &JSRotationGesture::Create, opt);
695 JSClass<JSRotationGesture>::StaticMethod("pop", &JSGesture::Pop);
696 JSClass<JSRotationGesture>::StaticMethod("onActionStart", &JSGesture::JsHandlerOnActionStart);
697 JSClass<JSRotationGesture>::StaticMethod("onActionUpdate", &JSGesture::JsHandlerOnActionUpdate);
698 JSClass<JSRotationGesture>::StaticMethod("onActionEnd", &JSGesture::JsHandlerOnActionEnd);
699 JSClass<JSRotationGesture>::StaticMethod("onActionCancel", &JSGesture::JsHandlerOnActionCancel);
700 JSClass<JSRotationGesture>::Bind(globalObj);
701
702 JSClass<JSGestureGroup>::Declare("GestureGroup");
703 JSClass<JSGestureGroup>::StaticMethod("create", &JSGestureGroup::Create, opt);
704 JSClass<JSGestureGroup>::StaticMethod("pop", &JSGesture::Pop);
705 JSClass<JSGestureGroup>::StaticMethod("onCancel", &JSGesture::JsHandlerOnActionCancel);
706 JSClass<JSGestureGroup>::Bind<>(globalObj);
707
708 JSClass<JSTimeoutGesture>::Declare("TimeoutGesture");
709 JSClass<JSTimeoutGesture>::StaticMethod("create", &JSTimeoutGesture::Create, opt);
710 JSClass<JSTimeoutGesture>::StaticMethod("pop", &JSGesture::Pop);
711
712 JSClass<JSTimeoutGesture>::Bind<>(globalObj);
713 }
714
Create(const JSCallbackInfo & args)715 void JSTimeoutGesture::Create(const JSCallbackInfo& args)
716 {
717 LOGD("JSTimeoutGesture::Create()");
718 if (!args[0]->IsNumber()) {
719 return;
720 }
721
722 RefPtr<GestureProcessor> gestureProcessor;
723 if (Container::IsCurrentUseNewPipeline()) {
724 gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
725 } else {
726 gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
727 };
728 auto gesture = AceType::MakeRefPtr<TimeoutGesture>(std::chrono::duration<float>(args[0]->ToNumber<float>()));
729 gestureProcessor->PushGesture(gesture);
730 }
731
JSBind(BindingTarget globalObj)732 void JSTimeoutGesture::JSBind(BindingTarget globalObj)
733 {
734 JSClass<JSTimeoutGesture>::Declare("TimeoutGesture");
735 MethodOptions opt = MethodOptions::NONE;
736 JSClass<JSTimeoutGesture>::StaticMethod("create", &JSTimeoutGesture::Create, opt);
737 JSClass<JSTimeoutGesture>::StaticMethod("pop", &JSGesture::Pop);
738
739 JSClass<JSTimeoutGesture>::Bind<>(globalObj);
740 }
741
742 }; // namespace OHOS::Ace::Framework
743