• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "base/log/log_wrapper.h"
19 #include "bridge/declarative_frontend/jsview/models/gesture_model_impl.h"
20 #include "core/components_ng/base/view_stack_model.h"
21 #include "core/components_ng/pattern/gesture/gesture_model_ng.h"
22 #include "frameworks/base/log/ace_scoring_log.h"
23 #include "frameworks/bridge/declarative_frontend/engine/functions/js_gesture_function.h"
24 #include "frameworks/core/gestures/timeout_gesture.h"
25 
26 namespace OHOS::Ace {
27 std::unique_ptr<GestureModel> GestureModel::instance_ = nullptr;
28 std::mutex GestureModel::mutex_;
GetInstance()29 GestureModel* GestureModel::GetInstance()
30 {
31     if (!instance_) {
32         std::lock_guard<std::mutex> lock(mutex_);
33         if (!instance_) {
34 #ifdef NG_BUILD
35             instance_.reset(new NG::GestureModelNG());
36 #else
37             if (Container::IsCurrentUseNewPipeline()) {
38                 instance_.reset(new NG::GestureModelNG());
39             } else {
40                 instance_.reset(new Framework::GestureModelImpl());
41             }
42 #endif
43         }
44     }
45     return instance_.get();
46 }
47 
48 std::unique_ptr<TapGestureModel> TapGestureModel::instance_ = nullptr;
49 std::mutex TapGestureModel::mutex_;
GetInstance()50 TapGestureModel* TapGestureModel::GetInstance()
51 {
52     if (!instance_) {
53         std::lock_guard<std::mutex> lock(mutex_);
54         if (!instance_) {
55 #ifdef NG_BUILD
56             instance_.reset(new NG::TapGestureModelNG());
57 #else
58             if (Container::IsCurrentUseNewPipeline()) {
59                 instance_.reset(new NG::TapGestureModelNG());
60             } else {
61                 instance_.reset(new Framework::TapGestureModelImpl());
62             }
63 #endif
64         }
65     }
66     return instance_.get();
67 }
68 
69 std::unique_ptr<LongPressGestureModel> LongPressGestureModel::instance_ = nullptr;
70 std::mutex LongPressGestureModel::mutex_;
GetInstance()71 LongPressGestureModel* LongPressGestureModel::GetInstance()
72 {
73     if (!instance_) {
74         std::lock_guard<std::mutex> lock(mutex_);
75         if (!instance_) {
76 #ifdef NG_BUILD
77             instance_.reset(new NG::LongPressGestureModelNG());
78 #else
79             if (Container::IsCurrentUseNewPipeline()) {
80                 instance_.reset(new NG::LongPressGestureModelNG());
81             } else {
82                 instance_.reset(new Framework::LongPressGestureModelImpl());
83             }
84 #endif
85         }
86     }
87     return instance_.get();
88 }
89 
90 std::unique_ptr<PanGestureModel> PanGestureModel::instance_ = nullptr;
91 std::mutex PanGestureModel::mutex_;
GetInstance()92 PanGestureModel* PanGestureModel::GetInstance()
93 {
94     if (!instance_) {
95         std::lock_guard<std::mutex> lock(mutex_);
96         if (!instance_) {
97 #ifdef NG_BUILD
98             instance_.reset(new NG::PanGestureModelNG());
99 #else
100             if (Container::IsCurrentUseNewPipeline()) {
101                 instance_.reset(new NG::PanGestureModelNG());
102             } else {
103                 instance_.reset(new Framework::PanGestureModelImpl());
104             }
105 #endif
106         }
107     }
108     return instance_.get();
109 }
110 
111 std::unique_ptr<SwipeGestureModel> SwipeGestureModel::instance_ = nullptr;
112 std::mutex SwipeGestureModel::mutex_;
GetInstance()113 SwipeGestureModel* SwipeGestureModel::GetInstance()
114 {
115     if (!instance_) {
116         std::lock_guard<std::mutex> lock(mutex_);
117         if (!instance_) {
118 #ifdef NG_BUILD
119             instance_.reset(new NG::SwipeGestureModelNG());
120 #else
121             if (Container::IsCurrentUseNewPipeline()) {
122                 instance_.reset(new NG::SwipeGestureModelNG());
123             } else {
124                 instance_.reset(new Framework::SwipeGestureModelImpl());
125             }
126 #endif
127         }
128     }
129     return instance_.get();
130 }
131 
132 std::unique_ptr<PinchGestureModel> PinchGestureModel::instance_ = nullptr;
133 std::mutex PinchGestureModel::mutex_;
GetInstance()134 PinchGestureModel* PinchGestureModel::GetInstance()
135 {
136     if (!instance_) {
137         std::lock_guard<std::mutex> lock(mutex_);
138         if (!instance_) {
139 #ifdef NG_BUILD
140             instance_.reset(new NG::PinchGestureModelNG());
141 #else
142             if (Container::IsCurrentUseNewPipeline()) {
143                 instance_.reset(new NG::PinchGestureModelNG());
144             } else {
145                 instance_.reset(new Framework::PinchGestureModelImpl());
146             }
147 #endif
148         }
149     }
150     return instance_.get();
151 }
152 
153 std::unique_ptr<RotationGestureModel> RotationGestureModel::instance_ = nullptr;
154 std::mutex RotationGestureModel::mutex_;
GetInstance()155 RotationGestureModel* RotationGestureModel::GetInstance()
156 {
157     if (!instance_) {
158         std::lock_guard<std::mutex> lock(mutex_);
159         if (!instance_) {
160 #ifdef NG_BUILD
161             instance_.reset(new NG::RotationGestureModelNG());
162 #else
163             if (Container::IsCurrentUseNewPipeline()) {
164                 instance_.reset(new NG::RotationGestureModelNG());
165             } else {
166                 instance_.reset(new Framework::RotationGestureModelImpl());
167             }
168 #endif
169         }
170     }
171     return instance_.get();
172 }
173 
174 std::unique_ptr<GestureGroupModel> GestureGroupModel::instance_ = nullptr;
175 std::mutex GestureGroupModel::mutex_;
GetInstance()176 GestureGroupModel* GestureGroupModel::GetInstance()
177 {
178     if (!instance_) {
179         std::lock_guard<std::mutex> lock(mutex_);
180         if (!instance_) {
181 #ifdef NG_BUILD
182             instance_.reset(new NG::GestureGroupModelNG());
183 #else
184             if (Container::IsCurrentUseNewPipeline()) {
185                 instance_.reset(new NG::GestureGroupModelNG());
186             } else {
187                 instance_.reset(new Framework::GestureGroupModelImpl());
188             }
189 #endif
190         }
191     }
192     return instance_.get();
193 }
194 
195 std::unique_ptr<TimeoutGestureModel> TimeoutGestureModel::instance_ = nullptr;
196 std::mutex TimeoutGestureModel::mutex_;
GetInstance()197 TimeoutGestureModel* TimeoutGestureModel::GetInstance()
198 {
199     if (!instance_) {
200         std::lock_guard<std::mutex> lock(mutex_);
201         if (!instance_) {
202 #ifdef NG_BUILD
203             instance_.reset(new NG::TimeoutGestureModelNG());
204 #else
205             if (Container::IsCurrentUseNewPipeline()) {
206                 instance_.reset(new NG::TimeoutGestureModelNG());
207             } else {
208                 instance_.reset(new Framework::TimeoutGestureModelImpl());
209             }
210 #endif
211         }
212     }
213     return instance_.get();
214 }
215 } // namespace OHOS::Ace
216 
217 namespace OHOS::Ace::Framework {
218 namespace {
219 constexpr int32_t DEFAULT_TAP_FINGER = 1;
220 constexpr int32_t DEFAULT_TAP_COUNT = 1;
221 constexpr double DEFAULT_TAP_DISTANCE = std::numeric_limits<double>::infinity();
222 constexpr int32_t DEFAULT_LONG_PRESS_FINGER = 1;
223 constexpr int32_t DEFAULT_LONG_PRESS_DURATION = 500;
224 constexpr int32_t DEFAULT_PINCH_FINGER = 2;
225 constexpr int32_t DEFAULT_MAX_PINCH_FINGER = 5;
226 constexpr double DEFAULT_PINCH_DISTANCE = 5.0;
227 constexpr int32_t DEFAULT_PAN_FINGER = 1;
228 constexpr int32_t DEFAULT_MAX_PAN_FINGERS = 10;
229 constexpr Dimension DEFAULT_PAN_DISTANCE = 5.0_vp;
230 constexpr int32_t DEFAULT_SLIDE_FINGER = DEFAULT_PAN_FINGER;
231 constexpr double DEFAULT_SLIDE_SPEED = 100.0;
232 constexpr int32_t DEFAULT_ROTATION_FINGER = 2;
233 constexpr double DEFAULT_ROTATION_ANGLE = 1.0;
234 
235 constexpr char GESTURE_FINGERS[] = "fingers";
236 constexpr char GESTURE_DISTANCE[] = "distance";
237 constexpr char TAP_GESTURE_DISTANCE[] = "distanceThreshold";
238 constexpr char GESTURE_SPEED[] = "speed";
239 constexpr char TAP_COUNT[] = "count";
240 constexpr char LONG_PRESS_REPEAT[] = "repeat";
241 constexpr char LONG_PRESS_DURATION[] = "duration";
242 constexpr char PAN_DIRECTION[] = "direction";
243 constexpr char SWIPE_DIRECTION[] = "direction";
244 constexpr char ROTATION_ANGLE[] = "angle";
245 constexpr char LIMIT_FINGER_COUNT[] = "isFingerCountLimited";
246 } // namespace
247 
Create(const JSCallbackInfo & info)248 void JSGesture::Create(const JSCallbackInfo& info)
249 {
250     int32_t priorityNum = 0;
251     if (info.Length() > 0) {
252         auto jsPriorityNum = info[0];
253         if (jsPriorityNum->IsNumber()) {
254             priorityNum = jsPriorityNum->ToNumber<int32_t>();
255         }
256     }
257 
258     int32_t gestureMaskNum = 0;
259     if (info.Length() > 1) {
260         auto jsGestureMaskNum = info[1];
261         if (jsGestureMaskNum->IsNumber()) {
262             gestureMaskNum = jsGestureMaskNum->ToNumber<int32_t>();
263         }
264     }
265 
266     GestureModel::GetInstance()->Create(priorityNum, gestureMaskNum);
267 }
268 
Finish()269 void JSGesture::Finish()
270 {
271     if (ViewStackModel::GetInstance()->IsPrebuilding()) {
272         return ViewStackModel::GetInstance()->PushPrebuildCompCmd("[JSGesture][pop]", &JSGesture::Finish);
273     }
274     GestureModel::GetInstance()->Finish();
275 }
276 
Pop()277 void JSGesture::Pop()
278 {
279     if (ViewStackModel::GetInstance()->IsPrebuilding()) {
280         return ViewStackModel::GetInstance()->PushPrebuildCompCmd("[JSGesture][pop]", &JSGesture::Pop);
281     }
282     GestureModel::GetInstance()->Pop();
283 }
284 
Create(const JSCallbackInfo & args)285 void JSTapGesture::Create(const JSCallbackInfo& args)
286 {
287     int32_t countNum = DEFAULT_TAP_COUNT;
288     int32_t fingersNum = DEFAULT_TAP_FINGER;
289     double distanceThresholdNum = DEFAULT_TAP_DISTANCE;
290     bool isLimitFingerCount = false;
291     if (args.Length() > 0 && args[0]->IsObject()) {
292         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
293         JSRef<JSVal> count = obj->GetProperty(TAP_COUNT);
294         JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
295         JSRef<JSVal> distanceThreshold = obj->GetProperty(TAP_GESTURE_DISTANCE);
296         JSRef<JSVal> limitFingerCount = obj->GetProperty(LIMIT_FINGER_COUNT);
297 
298         if (count->IsNumber()) {
299             int32_t countNumber = count->ToNumber<int32_t>();
300             countNum = countNumber <= DEFAULT_TAP_COUNT ? DEFAULT_TAP_COUNT : countNumber;
301         }
302         if (fingers->IsNumber()) {
303             int32_t fingersNumber = fingers->ToNumber<int32_t>();
304             fingersNum = fingersNumber <= DEFAULT_TAP_FINGER ? DEFAULT_TAP_FINGER : fingersNumber;
305         }
306         if (distanceThreshold->IsNumber()) {
307             double distanceThresholdNumber = distanceThreshold->ToNumber<double>();
308             distanceThresholdNum = distanceThresholdNumber < 0? DEFAULT_TAP_DISTANCE : distanceThresholdNumber;
309             distanceThresholdNum = Dimension(distanceThresholdNum, DimensionUnit::VP).ConvertToPx();
310         }
311         if (limitFingerCount->IsBoolean()) {
312             isLimitFingerCount = limitFingerCount->ToBoolean();
313         }
314     }
315 
316     TapGestureModel::GetInstance()->Create(countNum, fingersNum, distanceThresholdNum, isLimitFingerCount);
317 }
318 
Create(const JSCallbackInfo & args)319 void JSLongPressGesture::Create(const JSCallbackInfo& args)
320 {
321     int32_t fingersNum = DEFAULT_LONG_PRESS_FINGER;
322     bool repeatResult = false;
323     int32_t durationNum = DEFAULT_LONG_PRESS_DURATION;
324     bool isLimitFingerCount = false;
325     if (args.Length() > 0 && args[0]->IsObject()) {
326         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
327         JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
328         JSRef<JSVal> repeat = obj->GetProperty(LONG_PRESS_REPEAT);
329         JSRef<JSVal> duration = obj->GetProperty(LONG_PRESS_DURATION);
330         JSRef<JSVal> limitFingerCount = obj->GetProperty(LIMIT_FINGER_COUNT);
331 
332         if (fingers->IsNumber()) {
333             int32_t fingersNumber = fingers->ToNumber<int32_t>();
334             fingersNum = fingersNumber <= DEFAULT_LONG_PRESS_FINGER ? DEFAULT_LONG_PRESS_FINGER : fingersNumber;
335         }
336         if (repeat->IsBoolean()) {
337             repeatResult = repeat->ToBoolean();
338         }
339         if (duration->IsNumber()) {
340             int32_t durationNumber = duration->ToNumber<int32_t>();
341             durationNum = durationNumber <= 0 ? DEFAULT_LONG_PRESS_DURATION : durationNumber;
342         }
343         if (limitFingerCount->IsBoolean()) {
344             isLimitFingerCount = limitFingerCount->ToBoolean();
345         }
346     }
347     LongPressGestureModel::GetInstance()->Create(fingersNum, repeatResult, durationNum, isLimitFingerCount);
348 }
349 
Create(const JSCallbackInfo & args)350 void JSPanGesture::Create(const JSCallbackInfo& args)
351 {
352     int32_t fingersNum = DEFAULT_PAN_FINGER;
353     double distanceNum = DEFAULT_PAN_DISTANCE.ConvertToPx();
354     bool isLimitFingerCount = false;
355     PanDirection panDirection;
356     if (args.Length() <= 0 || !args[0]->IsObject()) {
357         PanGestureModel::GetInstance()->Create(fingersNum, panDirection, distanceNum, isLimitFingerCount);
358         return;
359     }
360 
361     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
362     JSPanGestureOption* panGestureOption = obj->Unwrap<JSPanGestureOption>();
363 
364     if (panGestureOption != nullptr) {
365         RefPtr<PanGestureOption> refPanGestureOption = panGestureOption->GetPanGestureOption();
366         PanGestureModel::GetInstance()->SetPanGestureOption(refPanGestureOption);
367         return;
368     }
369 
370     JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
371     JSRef<JSVal> distance = obj->GetProperty(GESTURE_DISTANCE);
372     JSRef<JSVal> directionNum = obj->GetProperty(PAN_DIRECTION);
373     JSRef<JSVal> limitFingerCount = obj->GetProperty(LIMIT_FINGER_COUNT);
374 
375     if (fingers->IsNumber()) {
376         int32_t fingersNumber = fingers->ToNumber<int32_t>();
377         fingersNum = fingersNumber <= DEFAULT_PAN_FINGER ? DEFAULT_PAN_FINGER : fingersNumber;
378     }
379     if (distance->IsNumber()) {
380         double distanceNumber = distance->ToNumber<double>();
381         Dimension dimension =
382             LessNotEqual(distanceNumber, 0.0) ? DEFAULT_PAN_DISTANCE : Dimension(distanceNumber, DimensionUnit::VP);
383         distanceNum = dimension.ConvertToPx();
384     }
385     if (directionNum->IsNumber()) {
386         uint32_t directNum = directionNum->ToNumber<uint32_t>();
387         if (directNum >= static_cast<uint32_t>(PanDirection::NONE) &&
388             directNum <= static_cast<uint32_t>(PanDirection::ALL)) {
389             panDirection.type = directNum;
390         }
391     }
392     if (limitFingerCount->IsBoolean()) {
393             isLimitFingerCount = limitFingerCount->ToBoolean();
394     }
395 
396     PanGestureModel::GetInstance()->Create(fingersNum, panDirection, distanceNum, isLimitFingerCount);
397 }
398 
Create(const JSCallbackInfo & args)399 void JSSwipeGesture::Create(const JSCallbackInfo& args)
400 {
401     int32_t fingersNum = DEFAULT_SLIDE_FINGER;
402     double speedNum = DEFAULT_SLIDE_SPEED;
403     SwipeDirection slideDirection;
404     bool isLimitFingerCount = false;
405 
406     if (args.Length() <= 0 || !args[0]->IsObject()) {
407         SwipeGestureModel::GetInstance()->Create(fingersNum, slideDirection, speedNum, isLimitFingerCount);
408         return;
409     }
410 
411     JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
412     JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
413     JSRef<JSVal> speed = obj->GetProperty(GESTURE_SPEED);
414     JSRef<JSVal> directionNum = obj->GetProperty(SWIPE_DIRECTION);
415     JSRef<JSVal> limitFingerCount = obj->GetProperty(LIMIT_FINGER_COUNT);
416 
417     if (fingers->IsNumber()) {
418         int32_t fingersNumber = fingers->ToNumber<int32_t>();
419         fingersNum = fingersNumber <= DEFAULT_PAN_FINGER ? DEFAULT_PAN_FINGER : fingersNumber;
420     }
421     if (speed->IsNumber()) {
422         double speedNumber = speed->ToNumber<double>();
423         speedNum = LessOrEqual(speedNumber, 0.0) ? DEFAULT_SLIDE_SPEED : speedNumber;
424     }
425     if (directionNum->IsNumber()) {
426         uint32_t directNum = directionNum->ToNumber<uint32_t>();
427         if (directNum >= static_cast<uint32_t>(SwipeDirection::NONE) &&
428             directNum <= static_cast<uint32_t>(SwipeDirection::ALL)) {
429             slideDirection.type = directNum;
430         }
431     }
432     if (limitFingerCount->IsBoolean()) {
433             isLimitFingerCount = limitFingerCount->ToBoolean();
434     }
435 
436     SwipeGestureModel::GetInstance()->Create(fingersNum, slideDirection, speedNum, isLimitFingerCount);
437 }
438 
Create(const JSCallbackInfo & args)439 void JSPinchGesture::Create(const JSCallbackInfo& args)
440 {
441     int32_t fingersNum = DEFAULT_PINCH_FINGER;
442     double distanceNum = DEFAULT_PINCH_DISTANCE;
443     bool isLimitFingerCount = false;
444     if (args.Length() > 0 && args[0]->IsObject()) {
445         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
446         JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
447         JSRef<JSVal> distance = obj->GetProperty(GESTURE_DISTANCE);
448         JSRef<JSVal> limitFingerCount = obj->GetProperty(LIMIT_FINGER_COUNT);
449 
450         if (fingers->IsNumber()) {
451             int32_t fingersNumber = fingers->ToNumber<int32_t>();
452             fingersNum = fingersNumber <= DEFAULT_PINCH_FINGER ? DEFAULT_PINCH_FINGER : fingersNumber;
453             fingersNum = fingersNum > DEFAULT_MAX_PINCH_FINGER ? DEFAULT_PINCH_FINGER : fingersNum;
454         }
455         if (distance->IsNumber()) {
456             double distanceNumber = distance->ToNumber<double>();
457             distanceNum = LessNotEqual(distanceNumber, 0.0) ? DEFAULT_PINCH_DISTANCE : distanceNumber;
458         }
459         if (limitFingerCount->IsBoolean()) {
460             isLimitFingerCount = limitFingerCount->ToBoolean();
461         }
462     }
463 
464     PinchGestureModel::GetInstance()->Create(fingersNum, distanceNum, isLimitFingerCount);
465 }
466 
Create(const JSCallbackInfo & args)467 void JSRotationGesture::Create(const JSCallbackInfo& args)
468 {
469     double angleNum = DEFAULT_ROTATION_ANGLE;
470     int32_t fingersNum = DEFAULT_ROTATION_FINGER;
471     bool isLimitFingerCount = false;
472     if (args.Length() > 0 && args[0]->IsObject()) {
473         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
474         JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
475         JSRef<JSVal> angle = obj->GetProperty(ROTATION_ANGLE);
476         JSRef<JSVal> limitFingerCount = obj->GetProperty(LIMIT_FINGER_COUNT);
477 
478         if (fingers->IsNumber()) {
479             int32_t fingersNumber = fingers->ToNumber<int32_t>();
480             fingersNum = fingersNumber <= DEFAULT_ROTATION_FINGER ? DEFAULT_ROTATION_FINGER : fingersNumber;
481         }
482         if (angle->IsNumber()) {
483             double angleNumber = angle->ToNumber<double>();
484             angleNum = LessNotEqual(angleNumber, 0.0) ? DEFAULT_ROTATION_ANGLE : angleNumber;
485         }
486         if (limitFingerCount->IsBoolean()) {
487             isLimitFingerCount = limitFingerCount->ToBoolean();
488         }
489     }
490 
491     RotationGestureModel::GetInstance()->Create(fingersNum, angleNum, isLimitFingerCount);
492 }
493 
Create(const JSCallbackInfo & args)494 void JSGestureGroup::Create(const JSCallbackInfo& args)
495 {
496     int32_t gestureMode = 0;
497     if (args.Length() > 0) {
498         auto jsGestureMode = args[0];
499         if (jsGestureMode->IsNumber()) {
500             gestureMode = jsGestureMode->ToNumber<int32_t>();
501         }
502     }
503 
504     GestureGroupModel::GetInstance()->Create(gestureMode);
505 }
506 
JsHandlerOnGestureEvent(Ace::GestureEventAction action,const JSCallbackInfo & args)507 void JSGesture::JsHandlerOnGestureEvent(Ace::GestureEventAction action, const JSCallbackInfo& args)
508 {
509     if (args.Length() < 1 || !args[0]->IsFunction()) {
510         return;
511     }
512 
513     RefPtr<JsGestureFunction> handlerFunc = AceType::MakeRefPtr<JsGestureFunction>(JSRef<JSFunc>::Cast(args[0]));
514 
515     if (action == Ace::GestureEventAction::CANCEL) {
516         auto onActionCancelFunc = [execCtx = args.GetExecutionContext(), func = std::move(handlerFunc)](
517                                       GestureEvent& info) {
518             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
519             ACE_SCORING_EVENT("Gesture.onCancel");
520             func->Execute(info);
521         };
522         GestureModel::GetInstance()->SetOnGestureEvent(onActionCancelFunc);
523         return;
524     }
525 
526     auto onActionFunc = [execCtx = args.GetExecutionContext(), func = std::move(handlerFunc)](GestureEvent& info) {
527         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
528         ACE_SCORING_EVENT("Gesture.onActionCancel");
529         func->Execute(info);
530     };
531 
532     GestureModel::GetInstance()->SetOnActionFunc(onActionFunc, action);
533 }
534 
SetTag(const JSCallbackInfo & args)535 void JSGesture::SetTag(const JSCallbackInfo& args)
536 {
537     std::string tag;
538     if (args.Length() > 0) {
539         auto jsTag = args[0];
540         if (jsTag->IsString()) {
541             tag = jsTag->ToString();
542         }
543     }
544     GestureModel::GetInstance()->SetTag(tag);
545 }
546 
SetAllowedTypes(const JSCallbackInfo & args)547 void JSGesture::SetAllowedTypes(const JSCallbackInfo& args)
548 {
549     if (args.Length() < 1) {
550         return;
551     }
552 
553     JSRef<JSVal> jsTypes = args[0];
554     if (!jsTypes->IsArray()) {
555         return;
556     }
557     JSRef<JSArray> jsTypesArr = JSRef<JSArray>::Cast(jsTypes);
558     std::set<SourceTool> allowedTypes{};
559     auto typesArrLength = jsTypesArr->Length();
560     for (size_t i = 0; i < typesArrLength; ++i) {
561         auto type = jsTypesArr->GetValueAt(i);
562         if (type->IsNumber()) {
563             allowedTypes.insert(static_cast<SourceTool>(type->ToNumber<int32_t>()));
564         }
565     }
566     if (allowedTypes.empty()) {
567         return;
568     }
569     GestureModel::GetInstance()->SetAllowedTypes(allowedTypes);
570 }
571 
JsHandlerOnAction(const JSCallbackInfo & args)572 void JSGesture::JsHandlerOnAction(const JSCallbackInfo& args)
573 {
574     JSGesture::JsHandlerOnGestureEvent(Ace::GestureEventAction::ACTION, args);
575 }
JsHandlerOnActionStart(const JSCallbackInfo & args)576 void JSGesture::JsHandlerOnActionStart(const JSCallbackInfo& args)
577 {
578     JSGesture::JsHandlerOnGestureEvent(Ace::GestureEventAction::START, args);
579 }
JsHandlerOnActionUpdate(const JSCallbackInfo & args)580 void JSGesture::JsHandlerOnActionUpdate(const JSCallbackInfo& args)
581 {
582     JSGesture::JsHandlerOnGestureEvent(Ace::GestureEventAction::UPDATE, args);
583 }
584 
JsHandlerOnActionEnd(const JSCallbackInfo & args)585 void JSGesture::JsHandlerOnActionEnd(const JSCallbackInfo& args)
586 {
587     JSGesture::JsHandlerOnGestureEvent(Ace::GestureEventAction::END, args);
588 }
JsHandlerOnActionCancel(const JSCallbackInfo & args)589 void JSGesture::JsHandlerOnActionCancel(const JSCallbackInfo& args)
590 {
591     JSGesture::JsHandlerOnGestureEvent(Ace::GestureEventAction::CANCEL, args);
592 }
593 
JSBind(BindingTarget globalObj)594 void JSPanGestureOption::JSBind(BindingTarget globalObj)
595 {
596     JSClass<JSPanGestureOption>::Declare("PanGestureOption");
597     JSClass<JSPanGestureOption>::CustomMethod("setDirection", &JSPanGestureOption::SetDirection);
598     JSClass<JSPanGestureOption>::CustomMethod("setDistance", &JSPanGestureOption::SetDistance);
599     JSClass<JSPanGestureOption>::CustomMethod("setFingers", &JSPanGestureOption::SetFingers);
600     JSClass<JSPanGestureOption>::Bind(globalObj, &JSPanGestureOption::Constructor, &JSPanGestureOption::Destructor);
601 
602     JSClass<JSPanGestureOption>::Declare("PanGestureOptions");
603     JSClass<JSPanGestureOption>::CustomMethod("setDirection", &JSPanGestureOption::SetDirection);
604     JSClass<JSPanGestureOption>::CustomMethod("setDistance", &JSPanGestureOption::SetDistance);
605     JSClass<JSPanGestureOption>::CustomMethod("setFingers", &JSPanGestureOption::SetFingers);
606     JSClass<JSPanGestureOption>::CustomMethod("getDirection", &JSPanGestureOption::GetDirection);
607     JSClass<JSPanGestureOption>::CustomMethod("getDistance", &JSPanGestureOption::GetDistance);
608     JSClass<JSPanGestureOption>::Bind(globalObj, &JSPanGestureOption::Constructor, &JSPanGestureOption::Destructor);
609 }
610 
SetDirection(const JSCallbackInfo & args)611 void JSPanGestureOption::SetDirection(const JSCallbackInfo& args)
612 {
613     if (args.Length() > 0 && args[0]->IsNumber()) {
614         PanDirection direction = { args[0]->ToNumber<int32_t>() };
615         panGestureOption_->SetDirection(direction);
616     } else {
617         PanDirection directionAll = { PanDirection::ALL };
618         panGestureOption_->SetDirection(directionAll);
619     }
620 }
621 
SetDistance(const JSCallbackInfo & args)622 void JSPanGestureOption::SetDistance(const JSCallbackInfo& args)
623 {
624     if (args.Length() > 0 && args[0]->IsNumber()) {
625         auto distance = args[0]->ToNumber<double>();
626         Dimension dimension =
627             LessNotEqual(distance, 0.0) ? DEFAULT_PAN_DISTANCE : Dimension(distance, DimensionUnit::VP);
628         panGestureOption_->SetDistance(dimension.ConvertToPx());
629     } else {
630         panGestureOption_->SetDistance(DEFAULT_PAN_DISTANCE.ConvertToPx());
631     }
632 }
633 
SetFingers(const JSCallbackInfo & args)634 void JSPanGestureOption::SetFingers(const JSCallbackInfo& args)
635 {
636     if (args.Length() > 0 && args[0]->IsNumber()) {
637         auto fingers = args[0]->ToNumber<int32_t>();
638         fingers = fingers <= DEFAULT_PAN_FINGER ? DEFAULT_PAN_FINGER : fingers;
639         fingers = fingers > DEFAULT_MAX_PAN_FINGERS ? DEFAULT_PAN_FINGER : fingers;
640         panGestureOption_->SetFingers(fingers);
641     } else {
642         panGestureOption_->SetFingers(DEFAULT_PAN_FINGER);
643     }
644 }
645 
GetDirection(const JSCallbackInfo & args)646 void JSPanGestureOption::GetDirection(const JSCallbackInfo& args)
647 {
648     PanDirection direction = { PanDirection::NONE };
649     if (panGestureOption_) {
650         direction = panGestureOption_->GetDirection();
651     }
652     args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(static_cast<int32_t>(direction.type))));
653 }
654 
GetDistance(const JSCallbackInfo & args)655 void JSPanGestureOption::GetDistance(const JSCallbackInfo& args)
656 {
657     double distance = 5;
658     double distance_new = distance;
659     if (panGestureOption_) {
660         distance = panGestureOption_->GetDistance();
661         auto context = PipelineContext::GetCurrentContextSafely();
662         CHECK_NULL_VOID(context);
663         distance_new = context->ConvertPxToVp(Dimension(distance, DimensionUnit::PX));
664     }
665     args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(static_cast<double>(distance_new))));
666 }
667 
Constructor(const JSCallbackInfo & args)668 void JSPanGestureOption::Constructor(const JSCallbackInfo& args)
669 {
670     auto panGestureOption = Referenced::MakeRefPtr<JSPanGestureOption>();
671     panGestureOption->IncRefCount();
672     RefPtr<PanGestureOption> option = AceType::MakeRefPtr<PanGestureOption>();
673 
674     int32_t fingersNum = DEFAULT_PAN_FINGER;
675     double distanceNum = DEFAULT_PAN_DISTANCE.ConvertToPx();
676     bool isLimitFingerCount = false;
677     PanDirection panDirection;
678 
679     if (args.Length() > 0 && args[0]->IsObject()) {
680         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
681         JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
682         JSRef<JSVal> distance = obj->GetProperty(GESTURE_DISTANCE);
683         JSRef<JSVal> directionNum = obj->GetProperty(PAN_DIRECTION);
684         JSRef<JSVal> limitFingerCount = obj->GetProperty(LIMIT_FINGER_COUNT);
685 
686         if (fingers->IsNumber()) {
687             int32_t fingersNumber = fingers->ToNumber<int32_t>();
688             fingersNum = fingersNumber <= DEFAULT_PAN_FINGER ? DEFAULT_PAN_FINGER : fingersNumber;
689         }
690         if (distance->IsNumber()) {
691             double distanceNumber = distance->ToNumber<double>();
692             Dimension dimension =
693                 LessNotEqual(distanceNumber, 0.0) ? DEFAULT_PAN_DISTANCE : Dimension(distanceNumber, DimensionUnit::VP);
694             distanceNum = dimension.ConvertToPx();
695         }
696         if (directionNum->IsNumber()) {
697             uint32_t directNum = directionNum->ToNumber<uint32_t>();
698             if (directNum >= static_cast<uint32_t>(PanDirection::NONE) &&
699                 directNum <= static_cast<uint32_t>(PanDirection::ALL)) {
700                 panDirection.type = directNum;
701             }
702         }
703         if (limitFingerCount->IsBoolean()) {
704             isLimitFingerCount = limitFingerCount->ToBoolean();
705         }
706     }
707     option->SetDirection(panDirection);
708     option->SetDistance(distanceNum);
709     option->SetFingers(fingersNum);
710     option->SetIsLimitFingerCount(isLimitFingerCount);
711 
712     panGestureOption->SetPanGestureOption(option);
713     args.SetReturnValue(Referenced::RawPtr(panGestureOption));
714 }
715 
Destructor(JSPanGestureOption * panGestureOption)716 void JSPanGestureOption::Destructor(JSPanGestureOption* panGestureOption)
717 {
718     if (panGestureOption != nullptr) {
719         panGestureOption->DecRefCount();
720     }
721 }
722 
JSBind(BindingTarget globalObj)723 void JSGesture::JSBind(BindingTarget globalObj)
724 {
725     JSClass<JSGesture>::Declare("Gesture");
726     MethodOptions opt = MethodOptions::NONE;
727     JSClass<JSGesture>::StaticMethod("create", &JSGesture::Create, opt);
728     JSClass<JSGesture>::StaticMethod("pop", &JSGesture::Finish);
729     JSClass<JSGesture>::Bind<>(globalObj);
730 
731     JSClass<JSTapGesture>::Declare("TapGesture");
732     JSClass<JSTapGesture>::StaticMethod("create", &JSTapGesture::Create, opt);
733     JSClass<JSTapGesture>::StaticMethod("tag", &JSGesture::SetTag, opt);
734     JSClass<JSTapGesture>::StaticMethod("allowedTypes", &JSGesture::SetAllowedTypes);
735     JSClass<JSTapGesture>::StaticMethod("pop", &JSGesture::Pop);
736     JSClass<JSTapGesture>::StaticMethod("onAction", &JSGesture::JsHandlerOnAction);
737     JSClass<JSTapGesture>::StaticMethod("onActionUpdate", &JSGesture::JsHandlerOnActionUpdate);
738     JSClass<JSTapGesture>::Bind<>(globalObj);
739 
740     JSClass<JSLongPressGesture>::Declare("LongPressGesture");
741     JSClass<JSLongPressGesture>::StaticMethod("create", &JSLongPressGesture::Create, opt);
742     JSClass<JSLongPressGesture>::StaticMethod("tag", &JSGesture::SetTag, opt);
743     JSClass<JSLongPressGesture>::StaticMethod("allowedTypes", &JSGesture::SetAllowedTypes);
744     JSClass<JSLongPressGesture>::StaticMethod("pop", &JSGesture::Pop);
745     JSClass<JSLongPressGesture>::StaticMethod("onAction", &JSGesture::JsHandlerOnAction);
746     JSClass<JSLongPressGesture>::StaticMethod("onActionEnd", &JSGesture::JsHandlerOnActionEnd);
747     JSClass<JSLongPressGesture>::StaticMethod("onActionCancel", &JSGesture::JsHandlerOnActionCancel);
748     JSClass<JSLongPressGesture>::StaticMethod("onActionUpdate", &JSGesture::JsHandlerOnActionUpdate);
749     JSClass<JSLongPressGesture>::Bind(globalObj);
750 
751     JSClass<JSPanGesture>::Declare("PanGesture");
752     JSClass<JSPanGesture>::StaticMethod("create", &JSPanGesture::Create, opt);
753     JSClass<JSPanGesture>::StaticMethod("tag", &JSGesture::SetTag, opt);
754     JSClass<JSPanGesture>::StaticMethod("allowedTypes", &JSGesture::SetAllowedTypes);
755     JSClass<JSPanGesture>::StaticMethod("pop", &JSGesture::Pop);
756     JSClass<JSPanGesture>::StaticMethod("onActionStart", &JSGesture::JsHandlerOnActionStart);
757     JSClass<JSPanGesture>::StaticMethod("onActionUpdate", &JSGesture::JsHandlerOnActionUpdate);
758     JSClass<JSPanGesture>::StaticMethod("onActionEnd", &JSGesture::JsHandlerOnActionEnd);
759     JSClass<JSPanGesture>::StaticMethod("onActionCancel", &JSGesture::JsHandlerOnActionCancel);
760     JSClass<JSPanGesture>::Bind(globalObj);
761 
762     JSClass<JSSwipeGesture>::Declare("SwipeGesture");
763     JSClass<JSSwipeGesture>::StaticMethod("create", &JSSwipeGesture::Create, opt);
764     JSClass<JSSwipeGesture>::StaticMethod("tag", &JSGesture::SetTag, opt);
765     JSClass<JSSwipeGesture>::StaticMethod("allowedTypes", &JSGesture::SetAllowedTypes);
766     JSClass<JSSwipeGesture>::StaticMethod("pop", &JSGesture::Pop);
767     JSClass<JSSwipeGesture>::StaticMethod("onAction", &JSGesture::JsHandlerOnAction);
768     JSClass<JSSwipeGesture>::Bind(globalObj);
769 
770     JSClass<JSPinchGesture>::Declare("PinchGesture");
771     JSClass<JSPinchGesture>::StaticMethod("create", &JSPinchGesture::Create, opt);
772     JSClass<JSPinchGesture>::StaticMethod("tag", &JSGesture::SetTag, opt);
773     JSClass<JSPinchGesture>::StaticMethod("allowedTypes", &JSGesture::SetAllowedTypes);
774     JSClass<JSPinchGesture>::StaticMethod("pop", &JSGesture::Pop);
775     JSClass<JSPinchGesture>::StaticMethod("onActionStart", &JSGesture::JsHandlerOnActionStart);
776     JSClass<JSPinchGesture>::StaticMethod("onActionUpdate", &JSGesture::JsHandlerOnActionUpdate);
777     JSClass<JSPinchGesture>::StaticMethod("onActionEnd", &JSGesture::JsHandlerOnActionEnd);
778     JSClass<JSPinchGesture>::StaticMethod("onActionCancel", &JSGesture::JsHandlerOnActionCancel);
779     JSClass<JSPinchGesture>::Bind(globalObj);
780 
781     JSClass<JSRotationGesture>::Declare("RotationGesture");
782     JSClass<JSRotationGesture>::StaticMethod("create", &JSRotationGesture::Create, opt);
783     JSClass<JSRotationGesture>::StaticMethod("tag", &JSGesture::SetTag, opt);
784     JSClass<JSRotationGesture>::StaticMethod("allowedTypes", &JSGesture::SetAllowedTypes);
785     JSClass<JSRotationGesture>::StaticMethod("pop", &JSGesture::Pop);
786     JSClass<JSRotationGesture>::StaticMethod("onActionStart", &JSGesture::JsHandlerOnActionStart);
787     JSClass<JSRotationGesture>::StaticMethod("onActionUpdate", &JSGesture::JsHandlerOnActionUpdate);
788     JSClass<JSRotationGesture>::StaticMethod("onActionEnd", &JSGesture::JsHandlerOnActionEnd);
789     JSClass<JSRotationGesture>::StaticMethod("onActionCancel", &JSGesture::JsHandlerOnActionCancel);
790     JSClass<JSRotationGesture>::Bind(globalObj);
791 
792     JSClass<JSGestureGroup>::Declare("GestureGroup");
793     JSClass<JSGestureGroup>::StaticMethod("create", &JSGestureGroup::Create, opt);
794     JSClass<JSGestureGroup>::StaticMethod("pop", &JSGesture::Pop);
795     JSClass<JSGestureGroup>::StaticMethod("onCancel", &JSGesture::JsHandlerOnActionCancel);
796     JSClass<JSGestureGroup>::Bind<>(globalObj);
797 
798     JSClass<JSTimeoutGesture>::Declare("TimeoutGesture");
799     JSClass<JSTimeoutGesture>::StaticMethod("create", &JSTimeoutGesture::Create, opt);
800     JSClass<JSTimeoutGesture>::StaticMethod("pop", &JSGesture::Pop);
801 
802     JSClass<JSTimeoutGesture>::Bind<>(globalObj);
803 }
804 
Create(const JSCallbackInfo & args)805 void JSTimeoutGesture::Create(const JSCallbackInfo& args)
806 {
807     auto jsGesture = args[0];
808     if (!jsGesture->IsNumber()) {
809         return;
810     }
811 
812     RefPtr<GestureProcessor> gestureProcessor;
813     gestureProcessor = TimeoutGestureModel::GetInstance()->GetGestureProcessor();
814     auto gesture = AceType::MakeRefPtr<TimeoutGesture>(std::chrono::duration<float>(jsGesture->ToNumber<float>()));
815     gestureProcessor->PushGesture(gesture);
816 }
817 
JSBind(BindingTarget globalObj)818 void JSTimeoutGesture::JSBind(BindingTarget globalObj)
819 {
820     JSClass<JSTimeoutGesture>::Declare("TimeoutGesture");
821     MethodOptions opt = MethodOptions::NONE;
822     JSClass<JSTimeoutGesture>::StaticMethod("create", &JSTimeoutGesture::Create, opt);
823     JSClass<JSTimeoutGesture>::StaticMethod("pop", &JSGesture::Pop);
824 
825     JSClass<JSTimeoutGesture>::Bind<>(globalObj);
826 }
827 }; // namespace OHOS::Ace::Framework
828