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