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