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 #ifndef FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_FUNCTION_JS_SHOULD_BUILT_IN_RECOGNIZER_PARALLEL_WITH_FUNCTION_H
17 #define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_FUNCTION_JS_SHOULD_BUILT_IN_RECOGNIZER_PARALLEL_WITH_FUNCTION_H
18 
19 #include "base/memory/referenced.h"
20 #include "bridge/declarative_frontend/jsview/js_gesture.h"
21 #include "core/components_ng/gestures/recognizers/gesture_recognizer.h"
22 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
23 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
24 #include "core/gestures/gesture_info.h"
25 #include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h"
26 
27 namespace OHOS::Ace::Framework {
28 enum class GestureRecognizerState {
29     UNKNOWN = -1,
30     READY = 0,
31     DETECTING = 1,
32     PENDING = 2,
33     BLOCKED = 3,
34     SUCCEED = 4,
35     FAIL = 5,
36 };
37 
38 class JSEventTargetInfo : public Referenced {
39 public:
40     static void JSBind(BindingTarget globalObj);
41 
SetInspectorId(const std::string & inspectorId)42     void SetInspectorId(const std::string& inspectorId)
43     {
44         inspectorId_ = inspectorId;
45     }
46 
GetInspectorId(const JSCallbackInfo & args)47     void GetInspectorId(const JSCallbackInfo& args)
48     {
49         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(inspectorId_)));
50     }
51 
52 private:
Constructor(const JSCallbackInfo & args)53     static void Constructor(const JSCallbackInfo& args)
54     {
55         auto jsEventTarget = Referenced::MakeRefPtr<JSEventTargetInfo>();
56         jsEventTarget->IncRefCount();
57         args.SetReturnValue(Referenced::RawPtr(jsEventTarget));
58     }
59 
Destructor(JSEventTargetInfo * jsEventTarget)60     static void Destructor(JSEventTargetInfo* jsEventTarget)
61     {
62         if (jsEventTarget != nullptr) {
63             jsEventTarget->DecRefCount();
64         }
65     }
66 
67     std::string inspectorId_;
68 };
69 
70 class JSScrollableTargetInfo : public JSEventTargetInfo {
71 public:
72     static void JSBind(BindingTarget globalObj);
73 
SetPattern(const WeakPtr<NG::Pattern> & pattern)74     void SetPattern(const WeakPtr<NG::Pattern>& pattern)
75     {
76         pattern_ = pattern;
77     }
78 
IsBegin(const JSCallbackInfo & args)79     void IsBegin(const JSCallbackInfo& args)
80     {
81         auto pattern = pattern_.Upgrade();
82         if (!pattern) {
83             args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(false)));
84             return;
85         }
86         auto scrollablePattern = AceType::DynamicCast<NG::ScrollablePattern>(pattern);
87         if (scrollablePattern) {
88             args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(scrollablePattern->IsAtTop())));
89             return;
90         }
91         auto swiperPattern = AceType::DynamicCast<NG::SwiperPattern>(pattern);
92         if (swiperPattern) {
93             args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(swiperPattern->IsAtStart())));
94         }
95     }
96 
IsEnd(const JSCallbackInfo & args)97     void IsEnd(const JSCallbackInfo& args)
98     {
99         auto pattern = pattern_.Upgrade();
100         if (!pattern) {
101             args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(false)));
102             return;
103         }
104         auto scrollablePattern = AceType::DynamicCast<NG::ScrollablePattern>(pattern);
105         if (scrollablePattern) {
106             args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(scrollablePattern->IsAtBottom())));
107             return;
108         }
109         auto swiperPattern = AceType::DynamicCast<NG::SwiperPattern>(pattern);
110         if (swiperPattern) {
111             args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(swiperPattern->IsAtEnd())));
112         }
113     }
114 
115 private:
Constructor(const JSCallbackInfo & args)116     static void Constructor(const JSCallbackInfo& args)
117     {
118         auto jsScrollableTargetInfo = Referenced::MakeRefPtr<JSScrollableTargetInfo>();
119         jsScrollableTargetInfo->IncRefCount();
120         args.SetReturnValue(Referenced::RawPtr(jsScrollableTargetInfo));
121     }
122 
Destructor(JSScrollableTargetInfo * jsScrollableTargetInfo)123     static void Destructor(JSScrollableTargetInfo* jsScrollableTargetInfo)
124     {
125         if (jsScrollableTargetInfo != nullptr) {
126             jsScrollableTargetInfo->DecRefCount();
127         }
128     }
129 
130     WeakPtr<NG::Pattern> pattern_;
131 };
132 
133 class JSGestureRecognizer : public Referenced {
134 public:
135     static void JSBind(BindingTarget globalObj);
136 
SetRecognizer(const RefPtr<NG::NGGestureRecognizer> & recognizer)137     void SetRecognizer(const RefPtr<NG::NGGestureRecognizer>& recognizer)
138     {
139         recognizer_ = recognizer;
140     }
141 
GetRecognizer()142     WeakPtr<NG::NGGestureRecognizer> GetRecognizer()
143     {
144         return recognizer_;
145     }
146 
GetTag(const JSCallbackInfo & args)147     void GetTag(const JSCallbackInfo& args)
148     {
149         std::string tag;
150         auto recognizer = recognizer_.Upgrade();
151         if (recognizer) {
152             auto gestureInfo = recognizer->GetGestureInfo();
153             if (gestureInfo->GetTag().has_value()) {
154                 tag = gestureInfo->GetTag().value();
155             }
156         }
157         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(tag)));
158     }
159 
GetType(const JSCallbackInfo & args)160     void GetType(const JSCallbackInfo& args)
161     {
162         GestureTypeName type = GestureTypeName::UNKNOWN;
163         auto recognizer = recognizer_.Upgrade();
164         if (recognizer) {
165             auto gestureInfo = recognizer->GetGestureInfo();
166             type = gestureInfo->GetRecognizerType();
167         }
168         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(static_cast<int32_t>(type))));
169     }
170 
IsBuiltInRecognizer(const JSCallbackInfo & args)171     void IsBuiltInRecognizer(const JSCallbackInfo& args)
172     {
173         bool isBuiltIn = false;
174         auto recognizer = recognizer_.Upgrade();
175         if (recognizer) {
176             auto gestureInfo = recognizer->GetGestureInfo();
177             isBuiltIn = gestureInfo->IsSystemGesture();
178         }
179         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(isBuiltIn)));
180     }
181 
SetEnabled(const JSCallbackInfo & args)182     void SetEnabled(const JSCallbackInfo& args)
183     {
184         auto recognizer = recognizer_.Upgrade();
185         CHECK_NULL_VOID(recognizer);
186         bool enabled = true;
187         if (args[0]->IsBoolean()) {
188             enabled = args[0]->ToBoolean();
189         }
190         recognizer->SetEnabled(enabled);
191     }
192 
IsEnabled(const JSCallbackInfo & args)193     void IsEnabled(const JSCallbackInfo& args)
194     {
195         bool isEnabled = false;
196         auto recognizer = recognizer_.Upgrade();
197         if (recognizer) {
198             isEnabled = recognizer->IsEnabled();
199         }
200         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(isEnabled)));
201     }
202 
GetEventTargetInfo(const JSCallbackInfo & args)203     void GetEventTargetInfo(const JSCallbackInfo& args)
204     {
205         auto recognizer = recognizer_.Upgrade();
206         if (!recognizer) {
207             args.SetReturnValue(JSClass<JSEventTargetInfo>::NewInstance());
208             return;
209         }
210         auto attachNode = recognizer->GetAttachedNode().Upgrade();
211         if (!attachNode) {
212             args.SetReturnValue(JSClass<JSEventTargetInfo>::NewInstance());
213             return;
214         }
215         RefPtr<NG::Pattern> pattern;
216         auto scrollablePattern = attachNode->GetPattern<NG::ScrollablePattern>();
217         if (scrollablePattern) {
218             pattern = scrollablePattern;
219         }
220         auto swiperPattern = attachNode->GetPattern<NG::SwiperPattern>();
221         if (swiperPattern) {
222             pattern = swiperPattern;
223         }
224         if (pattern) {
225             JSRef<JSObject> scrollableTargetObj = JSClass<JSScrollableTargetInfo>::NewInstance();
226             auto scrollableTarget = Referenced::Claim(scrollableTargetObj->Unwrap<JSScrollableTargetInfo>());
227             scrollableTarget->SetPattern(pattern);
228             scrollableTarget->SetInspectorId(attachNode->GetInspectorIdValue(""));
229             args.SetReturnValue(scrollableTargetObj);
230             return;
231         }
232         JSRef<JSObject> eventTargetObj = JSClass<JSEventTargetInfo>::NewInstance();
233         auto eventTarget = Referenced::Claim(eventTargetObj->Unwrap<JSEventTargetInfo>());
234         eventTarget->SetInspectorId(attachNode->GetInspectorIdValue(""));
235         args.SetReturnValue(eventTargetObj);
236     }
237 
GetRefereeState(const JSCallbackInfo & args)238     void GetRefereeState(const JSCallbackInfo& args)
239     {
240         GestureRecognizerState state = GestureRecognizerState::FAIL;
241         auto recognizer = recognizer_.Upgrade();
242         if (recognizer) {
243             state = ConvertRefereeState(recognizer->GetRefereeState());
244         }
245         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(static_cast<int32_t>(state))));
246     }
247 
IsValid(const JSCallbackInfo & args)248     void IsValid(const JSCallbackInfo& args)
249     {
250         bool isValid = false;
251         auto recognizer = recognizer_.Upgrade();
252         if (recognizer && recognizer->IsInResponseLinkRecognizers()) {
253             isValid = true;
254         }
255         args.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(isValid)));
256     }
257 
ConvertRefereeState(NG::RefereeState state)258     static GestureRecognizerState ConvertRefereeState(NG::RefereeState state)
259     {
260         switch (state) {
261             case NG::RefereeState::READY:
262                 return GestureRecognizerState::READY;
263             case NG::RefereeState::DETECTING:
264                 return GestureRecognizerState::DETECTING;
265             case NG::RefereeState::PENDING:
266                 return GestureRecognizerState::PENDING;
267             case NG::RefereeState::PENDING_BLOCKED:
268             case NG::RefereeState::SUCCEED_BLOCKED:
269                 return GestureRecognizerState::BLOCKED;
270             case NG::RefereeState::SUCCEED:
271                 return GestureRecognizerState::SUCCEED;
272             case NG::RefereeState::FAIL:
273                 return GestureRecognizerState::FAIL;
274             default:
275                 return GestureRecognizerState::UNKNOWN;
276         }
277     }
278 
279 private:
Constructor(const JSCallbackInfo & args)280     static void Constructor(const JSCallbackInfo& args)
281     {
282         auto jsGestureRecognizer = Referenced::MakeRefPtr<JSGestureRecognizer>();
283         jsGestureRecognizer->IncRefCount();
284         args.SetReturnValue(Referenced::RawPtr(jsGestureRecognizer));
285     }
286 
Destructor(JSGestureRecognizer * jsGestureRecognizer)287     static void Destructor(JSGestureRecognizer* jsGestureRecognizer)
288     {
289         if (jsGestureRecognizer != nullptr) {
290             jsGestureRecognizer->DecRefCount();
291         }
292     }
293 
294     WeakPtr<NG::NGGestureRecognizer> recognizer_;
295 };
296 
297 class JSPanRecognizer : public JSGestureRecognizer {
298 public:
299     static void JSBind(BindingTarget globalObj);
300 
SetPanGestureOptions(int32_t fingers,double distance,PanDirection direction)301     void SetPanGestureOptions(int32_t fingers, double distance, PanDirection direction)
302     {
303         panGestureOption_ = AceType::MakeRefPtr<PanGestureOption>();
304         panGestureOption_->SetFingers(fingers);
305         panGestureOption_->SetDistance(distance);
306         panGestureOption_->SetDirection(direction);
307     }
308 
GetPanGestureOptions(const JSCallbackInfo & args)309     void GetPanGestureOptions(const JSCallbackInfo& args)
310     {
311         JSRef<JSObject> panGestureOptionObj = JSClass<JSPanGestureOption>::NewInstance();
312         auto panGestureOption = Referenced::Claim(panGestureOptionObj->Unwrap<JSPanGestureOption>());
313         panGestureOption->SetPanGestureOption(panGestureOption_);
314         args.SetReturnValue(panGestureOptionObj);
315     }
316 
317 private:
Constructor(const JSCallbackInfo & args)318     static void Constructor(const JSCallbackInfo& args)
319     {
320         auto jsPanRecognizer = Referenced::MakeRefPtr<JSPanRecognizer>();
321         jsPanRecognizer->IncRefCount();
322         args.SetReturnValue(Referenced::RawPtr(jsPanRecognizer));
323     }
324 
Destructor(JSPanRecognizer * jsPanRecognizer)325     static void Destructor(JSPanRecognizer* jsPanRecognizer)
326     {
327         if (jsPanRecognizer != nullptr) {
328             jsPanRecognizer->DecRefCount();
329         }
330     }
331 
332     RefPtr<PanGestureOption> panGestureOption_;
333 };
334 
335 class JsShouldBuiltInRecognizerParallelWithFunction : public JsFunction {
DECLARE_ACE_TYPE(JsShouldBuiltInRecognizerParallelWithFunction,JsFunction)336     DECLARE_ACE_TYPE(JsShouldBuiltInRecognizerParallelWithFunction, JsFunction)
337 
338 public:
339     explicit JsShouldBuiltInRecognizerParallelWithFunction(const JSRef<JSFunc>& jsFunction)
340         : JsFunction(JSRef<JSObject>(), jsFunction)
341     {}
342 
343     ~JsShouldBuiltInRecognizerParallelWithFunction() override = default;
344 
Execute()345     void Execute() override
346     {
347         ExecuteJS();
348     }
349 
350     RefPtr<NG::NGGestureRecognizer> Execute(
351         const RefPtr<NG::NGGestureRecognizer>& current, const std::vector<RefPtr<NG::NGGestureRecognizer>>& others);
352     static JSRef<JSObject> CreateRecognizerObject(const RefPtr<NG::NGGestureRecognizer>& target);
353 };
354 } // namespace OHOS::Ace::Framework
355 
356 #endif // FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_ENGINE_FUNCTION_JS_SHOULD_BUILT_IN_RECOGNIZER_PARALLEL_WITH_FUNCTION_H
357