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