1 /*
2 * Copyright (c) 2024 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 "bridge/cj_frontend/interfaces/cj_ffi/cj_gesture_ffi.h"
17
18 #include "bridge/cj_frontend/cppview/gesture.h"
19 #include "cj_lambda.h"
20 #include "bridge/cj_frontend/interfaces/cj_ffi/utils.h"
21 #include "frameworks/core/components_ng/base/view_stack_processor.h"
22 #include "frameworks/core/components_ng/gestures/gesture_group.h"
23 #include "frameworks/core/components_ng/gestures/long_press_gesture.h"
24 #include "frameworks/core/components_ng/gestures/pan_gesture.h"
25 #include "frameworks/core/components_ng/gestures/pinch_gesture.h"
26 #include "frameworks/core/components_ng/gestures/recognizers/exclusive_recognizer.h"
27 #include "frameworks/core/components_ng/gestures/recognizers/parallel_recognizer.h"
28 #include "frameworks/core/components_ng/gestures/rotation_gesture.h"
29 #include "frameworks/core/components_ng/gestures/swipe_gesture.h"
30 #include "frameworks/core/components_ng/gestures/tap_gesture.h"
31
32 using namespace OHOS::FFI;
33 using namespace OHOS::Ace;
34 using namespace OHOS::Ace::Framework;
35
36 namespace {
37 constexpr int32_t DEFAULT_TAP_FINGER = 1;
38 constexpr int32_t MAX_TAP_FINGER = 10;
39 constexpr int32_t DEFAULT_TAP_COUNT = 1;
40 constexpr int32_t DEFAULT_LONG_PRESS_FINGER = 1;
41 constexpr int32_t MAX_LONG_PRESS_FINGER = 10;
42 constexpr int32_t DEFAULT_PINCH_FINGER = 2;
43 constexpr int32_t MAX_PINCH_FINGER = 5;
44 constexpr double DEFAULT_PINCH_DISTANCE = 3.0;
45 constexpr int32_t DEFAULT_ROTATION_FINGER = 2;
46 constexpr int32_t MAX_ROTATION_FINGER = 5;
47 constexpr double DEFAULT_ROTATION_ANGLE = 1.0;
48 constexpr int32_t MAX_PAN_FINGER = 10;
49 constexpr int32_t MAX_SLIDE_FINGER = 10;
50
51 const std::vector<GesturePriority> GESTURE_PRIORITY = { GesturePriority::Low, GesturePriority::High,
52 GesturePriority::Parallel };
53
54 const std::vector<GestureMask> GESTURE_MASK = { GestureMask::Normal, GestureMask::IgnoreInternal };
55
56 const std::vector<GestureMode> GROUP_GESTURE_MODE = { GestureMode::Sequence, GestureMode::Parallel,
57 GestureMode::Exclusive };
58
59 enum class GestureEventType { ACTION, START, UPDATE, END, CANCEL };
60
FormatGestureEvenFunction(void (* callback)(CJGestureEvent info))61 std::function<void(const GestureEvent& event)> FormatGestureEvenFunction(void (*callback)(CJGestureEvent info))
62 {
63 std::function<void(const GestureEvent& event)> result = [ffiOnAction = CJLambda::Create(callback)](
64 const GestureEvent& event) -> void {
65 CJGestureEvent ffiGestureEvent {};
66 CJEventTarget ffiEventTarget {};
67 CJArea ffiArea {};
68 CJPosition ffiPosition {};
69 CJPosition ffiGlobalPosition {};
70
71 const auto& eventTarget = event.GetTarget();
72 ffiArea.width = eventTarget.area.GetWidth().ConvertToVp();
73 ffiArea.height = eventTarget.area.GetHeight().ConvertToVp();
74 const auto& localOffset = eventTarget.area.GetOffset();
75 const auto& origin = eventTarget.origin;
76 ffiPosition.x = localOffset.GetX().ConvertToVp();
77 ffiPosition.y = localOffset.GetY().ConvertToVp();
78 ffiGlobalPosition.x = origin.GetX().ConvertToVp() + localOffset.GetX().ConvertToVp();
79 ffiGlobalPosition.y = origin.GetX().ConvertToVp() + localOffset.GetY().ConvertToVp();
80
81 ffiArea.globalPosition = &ffiGlobalPosition;
82 ffiArea.position = &ffiPosition;
83
84 ffiEventTarget.area = &ffiArea;
85
86 auto& fingerList = event.GetFingerList();
87 ffiGestureEvent.fingerListSize = static_cast<int32_t>(fingerList.size());
88 ffiGestureEvent.fingerList = new CJFingerInfo[fingerList.size()];
89 TransformNativeCJFingerInfo(ffiGestureEvent.fingerList, fingerList);
90
91 ffiGestureEvent.target = &ffiEventTarget;
92 ffiGestureEvent.timestamp = event.GetTimeStamp().time_since_epoch().count();
93 ffiGestureEvent.repeat = event.GetRepeat();
94 ffiGestureEvent.source = static_cast<int32_t>(event.GetSourceDevice());
95 ffiGestureEvent.offsetX = event.GetOffsetX();
96 ffiGestureEvent.offsetY = event.GetOffsetY();
97 ffiGestureEvent.scale = event.GetScale();
98 ffiGestureEvent.pinchCenterX = event.GetPinchCenter().GetX();
99 ffiGestureEvent.pinchCenterY = event.GetPinchCenter().GetY();
100 ffiGestureEvent.angle = event.GetAngle();
101 ffiGestureEvent.speed = event.GetSpeed();
102
103 ffiOnAction(ffiGestureEvent);
104 };
105 return result;
106 }
107
FormatGestureEvenFunction(void (* callback)())108 std::function<void(const GestureEvent& event)> FormatGestureEvenFunction(void (*callback)())
109 {
110 std::function<void(const GestureEvent& event)> result = [ffiOnAction = CJLambda::Create(callback)](
111 const GestureEvent& event) -> void { ffiOnAction(); };
112 return result;
113 }
114
HandlerOnGestureEvent(const GestureEventType & action,const std::function<void (const GestureEvent & event)> & callback)115 void HandlerOnGestureEvent(
116 const GestureEventType& action, const std::function<void(const GestureEvent& event)>& callback)
117 {
118 RefPtr<GestureProcessor> gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
119 auto gesture = gestureProcessor->TopGestureNG();
120 if (!gesture) {
121 LOGE("top gesture is illegal");
122 return;
123 }
124
125 if (action == GestureEventType::CANCEL) {
126 auto onActionCancelFunc = [callback = std::move(callback)]() {
127 auto info = GestureEvent();
128 callback(info);
129 };
130 gesture->SetOnActionCancelId(onActionCancelFunc);
131 return;
132 }
133
134 auto onActionFunc = [callback = std::move(callback)](GestureEvent& info) {
135 callback(info);
136 };
137
138 switch (action) {
139 case GestureEventType::ACTION:
140 gesture->SetOnActionId(onActionFunc);
141 break;
142 case GestureEventType::START:
143 gesture->SetOnActionStartId(onActionFunc);
144 break;
145 case GestureEventType::UPDATE:
146 gesture->SetOnActionUpdateId(onActionFunc);
147 break;
148 case GestureEventType::END:
149 gesture->SetOnActionEndId(onActionFunc);
150 break;
151 default:
152 LOGW("Gesture: Unknown gesture action %{public}d", action);
153 break;
154 }
155 }
156
157 } // namespace
158
159 extern "C" {
FfiOHOSAceFrameworkGestureCreate(int32_t priority,int32_t mask)160 void FfiOHOSAceFrameworkGestureCreate(int32_t priority, int32_t mask)
161 {
162 if (!Utils::CheckParamsValid(priority, GESTURE_PRIORITY.size())) {
163 LOGE("invalid value for gesturePriority");
164 return;
165 }
166 if (!Utils::CheckParamsValid(mask, GESTURE_MASK.size())) {
167 LOGE("invalid value for gestureMask");
168 return;
169 }
170
171 RefPtr<GestureProcessor> gestureProcessor =
172 NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
173 gestureProcessor->SetPriority(GESTURE_PRIORITY[priority]);
174 gestureProcessor->SetGestureMask(GESTURE_MASK[mask]);
175 }
176
FfiOHOSAceFrameworkGestureOnAction(void (* callback)(CJGestureEvent info))177 void FfiOHOSAceFrameworkGestureOnAction(void (*callback)(CJGestureEvent info))
178 {
179 HandlerOnGestureEvent(GestureEventType::ACTION, FormatGestureEvenFunction(callback));
180 }
181
FfiOHOSAceFrameworkGestureOnActionStart(void (* callback)(CJGestureEvent info))182 void FfiOHOSAceFrameworkGestureOnActionStart(void (*callback)(CJGestureEvent info))
183 {
184 HandlerOnGestureEvent(GestureEventType::START, FormatGestureEvenFunction(callback));
185 }
186
FfiOHOSAceFrameworkGestureOnActionUpdate(void (* callback)(CJGestureEvent info))187 void FfiOHOSAceFrameworkGestureOnActionUpdate(void (*callback)(CJGestureEvent info))
188 {
189 HandlerOnGestureEvent(GestureEventType::UPDATE, FormatGestureEvenFunction(callback));
190 }
191
FfiOHOSAceFrameworkGestureOnActionEnd(void (* callback)(CJGestureEvent info))192 void FfiOHOSAceFrameworkGestureOnActionEnd(void (*callback)(CJGestureEvent info))
193 {
194 HandlerOnGestureEvent(GestureEventType::END, FormatGestureEvenFunction(callback));
195 }
196
FfiOHOSAceFrameworkGestureOnActionCancel(void (* callback)())197 void FfiOHOSAceFrameworkGestureOnActionCancel(void (*callback)())
198 {
199 HandlerOnGestureEvent(GestureEventType::CANCEL, FormatGestureEvenFunction(callback));
200 }
201
FfiOHOSAceFrameworkGestureFinish()202 void FfiOHOSAceFrameworkGestureFinish()
203 {
204 RefPtr<GestureProcessor> gestureProcessor =
205 NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
206 NG::ViewStackProcessor::GetInstance()->ResetGestureProcessor();
207
208 auto gesture = gestureProcessor->FinishGestureNG();
209 if (!gesture) {
210 LOGE("gesture is not exist when component finish");
211 return;
212 }
213 gesture->SetGestureMask(gestureProcessor->GetGestureMask());
214 gesture->SetPriority(gestureProcessor->GetPriority());
215 auto gestureEventHub = NG::ViewStackProcessor::GetInstance()->GetMainFrameNodeGestureEventHub();
216 if (gestureEventHub) {
217 gestureEventHub->AddGesture(gesture);
218 }
219 }
220
FfiOHOSAceFrameworkGesturePop()221 void FfiOHOSAceFrameworkGesturePop()
222 {
223 RefPtr<GestureProcessor> gestureProcessor =
224 NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
225 gestureProcessor->PopGestureNG();
226 }
227
228 // tapGesture
FfiOHOSAceFrameworkTapGestureCreate(int32_t count,int32_t fingers)229 void FfiOHOSAceFrameworkTapGestureCreate(int32_t count, int32_t fingers)
230 {
231 RefPtr<GestureProcessor> gestureProcessor =
232 NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
233
234 int32_t countNum = Utils::CheckMin(DEFAULT_TAP_COUNT, DEFAULT_TAP_COUNT, count);
235 int32_t fingersNum = Utils::CheckRange(DEFAULT_TAP_FINGER, MAX_TAP_FINGER, DEFAULT_TAP_FINGER, fingers);
236
237 auto gesture = AceType::MakeRefPtr<NG::TapGesture>(countNum, fingersNum);
238 gestureProcessor->PushGestureNG(gesture);
239 }
240
241 // LongPressGesture
FfiOHOSAceFrameworkLongPressGestureCreate(int32_t fingers,bool repeat,int32_t duration)242 void FfiOHOSAceFrameworkLongPressGestureCreate(int32_t fingers, bool repeat, int32_t duration)
243 {
244 RefPtr<GestureProcessor> gestureProcessor =
245 NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
246
247 int32_t fingersNum =
248 Utils::CheckRange(DEFAULT_LONG_PRESS_FINGER, MAX_LONG_PRESS_FINGER, DEFAULT_LONG_PRESS_FINGER, fingers);
249 int32_t durationNum = Utils::CheckMin(0, DEFAULT_LONG_PRESS_DURATION, duration);
250
251 auto gesture = AceType::MakeRefPtr<NG::LongPressGesture>(fingersNum, repeat, durationNum);
252 gestureProcessor->PushGestureNG(gesture);
253 }
254
255 // PinchPressGesture
FfiOHOSAceFrameworkPinchGestureCreate(int32_t fingers,double distance)256 void FfiOHOSAceFrameworkPinchGestureCreate(int32_t fingers, double distance)
257 {
258 RefPtr<GestureProcessor> gestureProcessor =
259 NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
260
261 int32_t fingersNum =
262 Utils::CheckRange(DEFAULT_PINCH_FINGER, MAX_PINCH_FINGER, DEFAULT_PINCH_FINGER, fingers);
263 double distanceNum = Utils::CheckMin(0.0, DEFAULT_PINCH_DISTANCE, distance);
264
265 auto gesture = AceType::MakeRefPtr<NG::PinchGesture>(fingersNum, distanceNum);
266 gestureProcessor->PushGestureNG(gesture);
267 }
268
269 // SwipeGesture
FfiOHOSAceFrameworkSwipeGestureCreate(int32_t fingers,uint32_t direction,double speed)270 void FfiOHOSAceFrameworkSwipeGestureCreate(int32_t fingers, uint32_t direction, double speed)
271 {
272 OHOS::Ace::SwipeDirection swipeDirection;
273 swipeDirection.type = direction;
274
275 RefPtr<GestureProcessor> gestureProcessor =
276 NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
277
278 int32_t fingersNum =
279 Utils::CheckRange(DEFAULT_SLIDE_FINGER, MAX_SLIDE_FINGER, DEFAULT_SLIDE_FINGER, fingers);
280 double speedNum = Utils::CheckMin(0.0, DEFAULT_SLIDE_SPEED, speed);
281
282 auto gesture = AceType::MakeRefPtr<NG::SwipeGesture>(fingersNum, swipeDirection, speedNum);
283 gestureProcessor->PushGestureNG(gesture);
284 }
285
286 // RotationGesture
FfiOHOSAceFrameworkRotationGestureCreate(int32_t fingers,double angle)287 void FfiOHOSAceFrameworkRotationGestureCreate(int32_t fingers, double angle)
288 {
289 RefPtr<GestureProcessor> gestureProcessor =
290 NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
291
292 int32_t fingersNum =
293 Utils::CheckRange(DEFAULT_ROTATION_FINGER, MAX_ROTATION_FINGER, DEFAULT_ROTATION_FINGER, fingers);
294 double angleNum = Utils::CheckMin(0.0, DEFAULT_ROTATION_ANGLE, angle);
295
296 auto gesture = AceType::MakeRefPtr<NG::RotationGesture>(fingersNum, angleNum);
297 gestureProcessor->PushGestureNG(gesture);
298 }
299
300 // PanGesture
FfiOHOSAceFrameworkPanGestureCreate(int32_t fingers,uint32_t direction,double distance)301 void FfiOHOSAceFrameworkPanGestureCreate(int32_t fingers, uint32_t direction, double distance)
302 {
303 OHOS::Ace::PanDirection panDirection;
304 panDirection.type = direction;
305
306 RefPtr<GestureProcessor> gestureProcessor =
307 NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
308
309 int32_t fingersNum =
310 Utils::CheckRange(DEFAULT_PAN_FINGER, MAX_PAN_FINGER, DEFAULT_PAN_FINGER, fingers);
311 double distanceNum = Utils::CheckMin(0.0, DEFAULT_PAN_DISTANCE.Value(), distance);
312
313 auto gesture = AceType::MakeRefPtr<NG::PanGesture>(fingersNum, panDirection, distanceNum);
314 gestureProcessor->PushGestureNG(gesture);
315 }
316
FfiOHOSAceFrameworkPanGestureCreateWithOptions(int64_t OptionID)317 void FfiOHOSAceFrameworkPanGestureCreateWithOptions(int64_t OptionID)
318 {
319 auto panGestureOption = FFIData::GetData<NativePanGestureOption>(OptionID);
320 if (panGestureOption == nullptr) {
321 LOGE("FfiGesture: invalid PanGestureOptions ID");
322 } else {
323 RefPtr<GestureProcessor> gestureProcessor =
324 NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
325
326 auto gesture = AceType::MakeRefPtr<NG::PanGesture>(panGestureOption->GetPanGestureOption());
327 gestureProcessor->PushGestureNG(gesture);
328 }
329 }
330
331 // GestureGroup
FfiOHOSAceFrameworkGestureGroupCreate(int32_t mode)332 void FfiOHOSAceFrameworkGestureGroupCreate(int32_t mode)
333 {
334 if (!Utils::CheckParamsValid(mode, GROUP_GESTURE_MODE.size())) {
335 LOGE("invalid value for gesture group mode");
336 return;
337 }
338
339 RefPtr<GestureProcessor> gestureProcessor =
340 NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
341 auto gesture = AceType::MakeRefPtr<NG::GestureGroup>(GROUP_GESTURE_MODE[mode]);
342 gestureProcessor->PushGestureNG(gesture);
343 }
344
FfiOHOSAceFrameworkPanGestureOptionsCtor(int32_t fingers,uint32_t direction,double distance)345 int64_t FfiOHOSAceFrameworkPanGestureOptionsCtor(int32_t fingers, uint32_t direction, double distance)
346 {
347 OHOS::Ace::PanDirection panDirection;
348 panDirection.type = direction;
349
350 int32_t fingersNum = Utils::CheckRange(DEFAULT_PAN_FINGER, MAX_PAN_FINGER, DEFAULT_PAN_FINGER, fingers);
351 double distanceNum = Utils::CheckMin(0.0, DEFAULT_PAN_DISTANCE.Value(), distance);
352
353 auto ret_ = FFIData::Create<NativePanGestureOption>(fingersNum, panDirection, distanceNum);
354 if (ret_ == nullptr) {
355 return FFI_ERROR_CODE;
356 }
357 return ret_->GetID();
358 }
359
FfiOHOSAceFrameworkPanGestureOptionsSetFingers(int64_t selfID,int32_t fingers)360 void FfiOHOSAceFrameworkPanGestureOptionsSetFingers(int64_t selfID, int32_t fingers)
361 {
362 auto self = FFIData::GetData<NativePanGestureOption>(selfID);
363 if (self != nullptr) {
364 self->SetFingers(fingers);
365 } else {
366 LOGE("FfiGesture: invalid PanGestureOptions ID");
367 }
368 }
369
FfiOHOSAceFrameworkPanGestureOptionsSetDirection(int64_t selfID,uint32_t direction)370 void FfiOHOSAceFrameworkPanGestureOptionsSetDirection(int64_t selfID, uint32_t direction)
371 {
372 OHOS::Ace::PanDirection panDirection;
373 panDirection.type = direction;
374
375 auto self = FFIData::GetData<NativePanGestureOption>(selfID);
376 if (self != nullptr) {
377 self->SetDirection(panDirection);
378 } else {
379 LOGE("FfiGesture: invalid PanGestureOptions ID");
380 }
381 }
382
FfiOHOSAceFrameworkPanGestureOptionsSetDistance(int64_t selfID,double distance)383 void FfiOHOSAceFrameworkPanGestureOptionsSetDistance(int64_t selfID, double distance)
384 {
385 auto self = FFIData::GetData<NativePanGestureOption>(selfID);
386 if (self != nullptr) {
387 self->SetDistance(distance);
388 } else {
389 LOGE("FfiGesture: invalid PanGestureOptions ID");
390 }
391 }
392 }
393