• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/declarative_frontend/engine/jsi/nativeModule/arkts_native_scrollable_bridge.h"
17 
18 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
19 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
20 #include "core/components_ng/pattern/scrollable/scrollable_model_ng.h"
21 
22 namespace OHOS::Ace::NG {
SetContentClip(ArkUIRuntimeCallInfo * runtimeCallInfo)23 ArkUINativeModuleValue ScrollableBridge::SetContentClip(ArkUIRuntimeCallInfo* runtimeCallInfo)
24 {
25     EcmaVM* vm = runtimeCallInfo->GetVM();
26     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
27     CHECK_NULL_RETURN(nativeNodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
28     auto* node = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
29 
30     Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
31     if (info[1]->IsObject()) {
32         auto* clipShape = Framework::JSRef<Framework::JSObject>::Cast(info[1])->Unwrap<Framework::JSShapeAbstract>();
33         if (clipShape) {
34             ScrollableModelNG::SetContentClip(reinterpret_cast<FrameNode*>(node), ContentClipMode::CUSTOM,
35                 AceType::DynamicCast<ShapeRect>(clipShape->GetBasicShape()));
36             return panda::JSValueRef::Undefined(vm);
37         }
38     } else if (info[1]->IsNumber()) {
39         GetArkUINodeModifiers()->getScrollableModifier()->setContentClip(node, info[1]->ToNumber<int32_t>());
40         return panda::JSValueRef::Undefined(vm);
41     }
42 
43     GetArkUINodeModifiers()->getScrollableModifier()->resetContentClip(node);
44     return panda::JSValueRef::Undefined(vm);
45 }
46 
ResetContentClip(ArkUIRuntimeCallInfo * runtimeCallInfo)47 ArkUINativeModuleValue ScrollableBridge::ResetContentClip(ArkUIRuntimeCallInfo* runtimeCallInfo)
48 {
49     EcmaVM* vm = runtimeCallInfo->GetVM();
50     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
51     CHECK_NULL_RETURN(nativeNodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
52     auto* node = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
53     GetArkUINodeModifiers()->getScrollableModifier()->resetContentClip(node);
54     return panda::JSValueRef::Undefined(vm);
55 }
56 
SetEdgeEffect(ArkUIRuntimeCallInfo * runtimeCallInfo)57 ArkUINativeModuleValue ScrollableBridge::SetEdgeEffect(ArkUIRuntimeCallInfo* runtimeCallInfo)
58 {
59     EcmaVM* vm = runtimeCallInfo->GetVM();
60     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
61     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
62     Local<JSValueRef> arg_effect = runtimeCallInfo->GetCallArgRef(1);
63     Local<JSValueRef> alwaysEnabledArg = runtimeCallInfo->GetCallArgRef(2); // 2: index of alwaysEnabled value
64     Local<JSValueRef> effectEdgeArg = runtimeCallInfo->GetCallArgRef(3); // 3: index of effectEdge value
65 
66     CHECK_NULL_RETURN(node->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
67     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
68     EdgeEffect effect = EdgeEffect::NONE;
69     bool alwaysEnabled = false;
70     int32_t effectEdge = static_cast<int32_t>(EffectEdge::ALL);
71     if (!arg_effect->IsUndefined() && !arg_effect->IsNull()) {
72         effect = static_cast<EdgeEffect>(arg_effect->Int32Value(vm));
73     }
74     if (effect < EdgeEffect::SPRING || effect > EdgeEffect::NONE) {
75         effect = EdgeEffect::NONE;
76     }
77 
78     if (!alwaysEnabledArg->IsUndefined() && !alwaysEnabledArg->IsNull()) {
79         alwaysEnabled = alwaysEnabledArg->ToBoolean(vm)->Value();
80     }
81     if (!effectEdgeArg->IsUndefined() && !effectEdgeArg->IsNull()) {
82         effectEdge = effectEdgeArg->Int32Value(vm);
83     }
84     if (effectEdge < static_cast<int32_t>(EffectEdge::START) || effectEdge > static_cast<int32_t>(EffectEdge::END)) {
85         effectEdge = static_cast<int32_t>(EffectEdge::ALL);
86     }
87 
88     GetArkUINodeModifiers()->getScrollableModifier()->setEdgeEffect(
89         nativeNode, static_cast<int32_t>(effect), alwaysEnabled, effectEdge);
90     return panda::JSValueRef::Undefined(vm);
91 }
92 
ResetEdgeEffect(ArkUIRuntimeCallInfo * runtimeCallInfo)93 ArkUINativeModuleValue ScrollableBridge::ResetEdgeEffect(ArkUIRuntimeCallInfo* runtimeCallInfo)
94 {
95     EcmaVM* vm = runtimeCallInfo->GetVM();
96     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
97     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
98     CHECK_NULL_RETURN(node->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
99     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
100     GetArkUINodeModifiers()->getScrollableModifier()->resetEdgeEffect(nativeNode);
101     return panda::JSValueRef::Undefined(vm);
102 }
103 
SetFadingEdge(ArkUIRuntimeCallInfo * runtimeCallInfo)104 ArkUINativeModuleValue ScrollableBridge::SetFadingEdge(ArkUIRuntimeCallInfo* runtimeCallInfo)
105 {
106     EcmaVM* vm = runtimeCallInfo->GetVM();
107     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
108     Local<JSValueRef> frameNodeArg = runtimeCallInfo->GetCallArgRef(0);
109     Local<JSValueRef> fadingEdgeArg = runtimeCallInfo->GetCallArgRef(1);
110     Local<JSValueRef> fadingEdgeLengthArg = runtimeCallInfo->GetCallArgRef(2);
111     CHECK_NULL_RETURN(frameNodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
112     auto nativeNode = nodePtr(frameNodeArg->ToNativePointer(vm)->Value());
113     CalcDimension fadingEdgeLength = Dimension(32.0f, DimensionUnit::VP); // default value
114     if (fadingEdgeArg->IsUndefined() || fadingEdgeArg->IsNull()) {
115         GetArkUINodeModifiers()->getScrollableModifier()->resetFadingEdge(nativeNode);
116     } else {
117         bool fadingEdge = fadingEdgeArg->ToBoolean(vm)->Value();
118         if (!fadingEdgeLengthArg->IsUndefined() && !fadingEdgeLengthArg->IsNull() &&
119             fadingEdgeLengthArg->IsObject(vm)) {
120             ArkTSUtils::ParseJsLengthMetrics(vm, fadingEdgeLengthArg, fadingEdgeLength);
121         }
122         GetArkUINodeModifiers()->getScrollableModifier()->setFadingEdge(
123             nativeNode, fadingEdge, fadingEdgeLength.Value(), static_cast<int32_t>(fadingEdgeLength.Unit()));
124     }
125     return panda::JSValueRef::Undefined(vm);
126 }
127 
ResetFadingEdge(ArkUIRuntimeCallInfo * runtimeCallInfo)128 ArkUINativeModuleValue ScrollableBridge::ResetFadingEdge(ArkUIRuntimeCallInfo* runtimeCallInfo)
129 {
130     EcmaVM* vm = runtimeCallInfo->GetVM();
131     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
132     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
133     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
134     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
135     GetArkUINodeModifiers()->getScrollableModifier()->resetFadingEdge(nativeNode);
136     return panda::JSValueRef::Undefined(vm);
137 }
138 
SetOnReachStart(ArkUIRuntimeCallInfo * runtimeCallInfo)139 ArkUINativeModuleValue ScrollableBridge::SetOnReachStart(ArkUIRuntimeCallInfo* runtimeCallInfo)
140 {
141     EcmaVM* vm = runtimeCallInfo->GetVM();
142     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
143     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
144     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
145     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
146     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
147     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
148         GetArkUINodeModifiers()->getScrollableModifier()->resetOnReachStartCallBack(nativeNode);
149         return panda::JSValueRef::Undefined(vm);
150     }
151     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
152     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
153     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
154     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
155         panda::LocalScope pandaScope(vm);
156         panda::TryCatch trycatch(vm);
157         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
158         func->Call(vm, func.ToLocal(), nullptr, 0);
159     };
160 
161     GetArkUINodeModifiers()->getScrollableModifier()->setOnReachStartCallBack(
162         nativeNode, reinterpret_cast<void*>(&callback));
163     return panda::JSValueRef::Undefined(vm);
164 }
165 
ResetOnReachStart(ArkUIRuntimeCallInfo * runtimeCallInfo)166 ArkUINativeModuleValue ScrollableBridge::ResetOnReachStart(ArkUIRuntimeCallInfo* runtimeCallInfo)
167 {
168     EcmaVM* vm = runtimeCallInfo->GetVM();
169     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
170     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
171     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
172     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
173     GetArkUINodeModifiers()->getScrollableModifier()->resetOnReachStartCallBack(nativeNode);
174     return panda::JSValueRef::Undefined(vm);
175 }
176 
SetOnReachEnd(ArkUIRuntimeCallInfo * runtimeCallInfo)177 ArkUINativeModuleValue ScrollableBridge::SetOnReachEnd(ArkUIRuntimeCallInfo* runtimeCallInfo)
178 {
179     EcmaVM* vm = runtimeCallInfo->GetVM();
180     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
181     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
182     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
183     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
184     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
185     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
186         GetArkUINodeModifiers()->getScrollableModifier()->resetOnReachEndCallBack(nativeNode);
187         return panda::JSValueRef::Undefined(vm);
188     }
189     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
190     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
191     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
192     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
193         panda::LocalScope pandaScope(vm);
194         panda::TryCatch trycatch(vm);
195         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
196         func->Call(vm, func.ToLocal(), nullptr, 0);
197     };
198 
199     GetArkUINodeModifiers()->getScrollableModifier()->setOnReachEndCallBack(
200         nativeNode, reinterpret_cast<void*>(&callback));
201     return panda::JSValueRef::Undefined(vm);
202 }
203 
ResetOnReachEnd(ArkUIRuntimeCallInfo * runtimeCallInfo)204 ArkUINativeModuleValue ScrollableBridge::ResetOnReachEnd(ArkUIRuntimeCallInfo* runtimeCallInfo)
205 {
206     EcmaVM* vm = runtimeCallInfo->GetVM();
207     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
208     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
209     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
210     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
211     GetArkUINodeModifiers()->getScrollableModifier()->resetOnReachEndCallBack(nativeNode);
212     return panda::JSValueRef::Undefined(vm);
213 }
214 
SetOnWillScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)215 ArkUINativeModuleValue ScrollableBridge::SetOnWillScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
216 {
217     EcmaVM* vm = runtimeCallInfo->GetVM();
218     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
219     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
220     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
221     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
222     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
223     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
224         GetArkUINodeModifiers()->getScrollableModifier()->resetOnWillScrollCallBack(nativeNode);
225         return panda::JSValueRef::Undefined(vm);
226     }
227     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
228     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
229     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
230     std::function<ScrollFrameResult(CalcDimension, ScrollState, ScrollSource)> callback =
231         [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
232             const CalcDimension& scrollOffset, const ScrollState& scrollState, ScrollSource scrollSource) {
233             panda::LocalScope pandaScope(vm);
234             panda::TryCatch trycatch(vm);
235             PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
236 
237             panda::Local<panda::NumberRef> offsetParam =
238                 panda::NumberRef::New(vm, static_cast<double>(scrollOffset.ConvertToVp()));
239             panda::Local<panda::NumberRef> stateParam = panda::NumberRef::New(vm, static_cast<int32_t>(scrollState));
240             panda::Local<panda::NumberRef> sourceParam = panda::NumberRef::New(vm, static_cast<int32_t>(scrollSource));
241             // 3: Array length
242             panda::Local<panda::JSValueRef> params[3] = { offsetParam, stateParam, sourceParam };
243             auto result = func->Call(vm, func.ToLocal(), params, 3); // 3: Array length
244             ScrollFrameResult scrollRes { .offset = scrollOffset };
245 
246             if (result->IsObject(vm)) {
247                 auto resultObj = result->ToObject(vm);
248                 panda::Local<panda::JSValueRef> dxRemainValue =
249                     resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "offsetRemain"));
250                 if (dxRemainValue->IsNumber()) {
251                     scrollRes.offset = Dimension(dxRemainValue->ToNumber(vm)->Value(), DimensionUnit::VP);
252                 }
253             }
254             return scrollRes;
255         };
256     GetArkUINodeModifiers()->getScrollableModifier()->setOnWillScrollCallBack(
257         nativeNode, reinterpret_cast<void*>(&callback));
258     return panda::JSValueRef::Undefined(vm);
259 }
260 
ResetOnWillScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)261 ArkUINativeModuleValue ScrollableBridge::ResetOnWillScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
262 {
263     EcmaVM* vm = runtimeCallInfo->GetVM();
264     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
265     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
266     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
267     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
268     GetArkUINodeModifiers()->getScrollableModifier()->resetOnWillScrollCallBack(nativeNode);
269     return panda::JSValueRef::Undefined(vm);
270 }
271 
SetOnDidScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)272 ArkUINativeModuleValue ScrollableBridge::SetOnDidScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
273 {
274     EcmaVM* vm = runtimeCallInfo->GetVM();
275     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
276     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
277     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
278     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
279     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
280     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
281         GetArkUINodeModifiers()->getScrollableModifier()->resetOnDidScrollCallBack(nativeNode);
282         return panda::JSValueRef::Undefined(vm);
283     }
284     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
285     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
286     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
287     std::function<void(Dimension, ScrollState)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
288                                                                const CalcDimension& scrollOffset,
289                                                                const ScrollState& scrollState) {
290         panda::LocalScope pandaScope(vm);
291         panda::TryCatch trycatch(vm);
292         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
293 
294         panda::Local<panda::NumberRef> offsetParam =
295             panda::NumberRef::New(vm, static_cast<double>(scrollOffset.ConvertToVp()));
296         panda::Local<panda::NumberRef> stateParam = panda::NumberRef::New(vm, static_cast<int32_t>(scrollState));
297         // 2: Array length
298         panda::Local<panda::JSValueRef> params[2] = { offsetParam, stateParam };
299         func->Call(vm, func.ToLocal(), params, 2); // 2: Array length
300     };
301     GetArkUINodeModifiers()->getScrollableModifier()->setOnDidScrollCallBack(
302         nativeNode, reinterpret_cast<void*>(&callback));
303     return panda::JSValueRef::Undefined(vm);
304 }
305 
ResetOnDidScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)306 ArkUINativeModuleValue ScrollableBridge::ResetOnDidScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
307 {
308     EcmaVM* vm = runtimeCallInfo->GetVM();
309     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
310     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
311     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
312     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
313     GetArkUINodeModifiers()->getScrollableModifier()->resetOnDidScrollCallBack(nativeNode);
314     return panda::JSValueRef::Undefined(vm);
315 }
316 
SetOnScrollFrameBegin(ArkUIRuntimeCallInfo * runtimeCallInfo)317 ArkUINativeModuleValue ScrollableBridge::SetOnScrollFrameBegin(ArkUIRuntimeCallInfo* runtimeCallInfo)
318 {
319     EcmaVM* vm = runtimeCallInfo->GetVM();
320     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
321     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
322     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
323     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
324     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
325     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
326         GetArkUINodeModifiers()->getScrollableModifier()->resetOnScrollFrameBeginCallBack(nativeNode);
327         return panda::JSValueRef::Undefined(vm);
328     }
329     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
330     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
331     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
332     std::function<ScrollFrameResult(Dimension, ScrollState)> callback =
333         [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
334             Dimension offset, ScrollState state) -> ScrollFrameResult {
335         panda::LocalScope pandaScope(vm);
336         panda::TryCatch trycatch(vm);
337         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
338 
339         panda::Local<panda::NumberRef> offsetParam =
340             panda::NumberRef::New(vm, static_cast<double>(offset.ConvertToVp()));
341         panda::Local<panda::NumberRef> stateParam = panda::NumberRef::New(vm, static_cast<double>(state));
342         // 2: Array length
343         panda::Local<panda::JSValueRef> params[2] = { offsetParam, stateParam };
344         auto value = func->Call(vm, func.ToLocal(), params, 2); // 2: Array length
345 
346         OHOS::Ace::ScrollFrameResult scrollRes { .offset = offset };
347         if (value->IsObject(vm)) {
348             auto resultObj = value->ToObject(vm);
349             panda::Local<panda::JSValueRef> remain =
350                 resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "offsetRemain"));
351             if (remain->IsNumber()) {
352                 scrollRes.offset = Dimension(remain->ToNumber(vm)->Value(), DimensionUnit::VP);
353             }
354         }
355         return scrollRes;
356     };
357     GetArkUINodeModifiers()->getScrollableModifier()->setOnScrollFrameBeginCallBack(
358         nativeNode, reinterpret_cast<void*>(&callback));
359     return panda::JSValueRef::Undefined(vm);
360 }
361 
ResetOnScrollFrameBegin(ArkUIRuntimeCallInfo * runtimeCallInfo)362 ArkUINativeModuleValue ScrollableBridge::ResetOnScrollFrameBegin(ArkUIRuntimeCallInfo* runtimeCallInfo)
363 {
364     EcmaVM* vm = runtimeCallInfo->GetVM();
365     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
366     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
367     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
368     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
369     GetArkUINodeModifiers()->getScrollableModifier()->resetOnScrollFrameBeginCallBack(nativeNode);
370     return panda::JSValueRef::Undefined(vm);
371 }
372 
SetOnScrollStart(ArkUIRuntimeCallInfo * runtimeCallInfo)373 ArkUINativeModuleValue ScrollableBridge::SetOnScrollStart(ArkUIRuntimeCallInfo* runtimeCallInfo)
374 {
375     EcmaVM* vm = runtimeCallInfo->GetVM();
376     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
377     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
378     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
379     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
380     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
381     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
382         GetArkUINodeModifiers()->getScrollableModifier()->resetOnScrollStartCallBack(nativeNode);
383         return panda::JSValueRef::Undefined(vm);
384     }
385     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
386     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
387     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
388 
389     std::function<void()> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
390         panda::LocalScope pandaScope(vm);
391         panda::TryCatch trycatch(vm);
392         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
393         func->Call(vm, func.ToLocal(), nullptr, 0);
394     };
395     GetArkUINodeModifiers()->getScrollableModifier()->setOnScrollStartCallBack(
396         nativeNode, reinterpret_cast<void*>(&callback));
397     return panda::JSValueRef::Undefined(vm);
398 }
399 
ResetOnScrollStart(ArkUIRuntimeCallInfo * runtimeCallInfo)400 ArkUINativeModuleValue ScrollableBridge::ResetOnScrollStart(ArkUIRuntimeCallInfo* runtimeCallInfo)
401 {
402     EcmaVM* vm = runtimeCallInfo->GetVM();
403     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
404     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
405     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
406     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
407     GetArkUINodeModifiers()->getScrollableModifier()->resetOnScrollStartCallBack(nativeNode);
408     return panda::JSValueRef::Undefined(vm);
409 }
410 
SetOnScrollStop(ArkUIRuntimeCallInfo * runtimeCallInfo)411 ArkUINativeModuleValue ScrollableBridge::SetOnScrollStop(ArkUIRuntimeCallInfo* runtimeCallInfo)
412 {
413     EcmaVM* vm = runtimeCallInfo->GetVM();
414     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
415     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
416     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
417     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
418     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
419     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
420         GetArkUINodeModifiers()->getScrollableModifier()->resetOnScrollStopCallBack(nativeNode);
421         return panda::JSValueRef::Undefined(vm);
422     }
423     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
424     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
425     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
426     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
427         panda::LocalScope pandaScope(vm);
428         panda::TryCatch trycatch(vm);
429         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
430         func->Call(vm, func.ToLocal(), nullptr, 0);
431     };
432     GetArkUINodeModifiers()->getScrollableModifier()->setOnScrollStopCallBack(
433         nativeNode, reinterpret_cast<void*>(&callback));
434     return panda::JSValueRef::Undefined(vm);
435 }
436 
ResetOnScrollStop(ArkUIRuntimeCallInfo * runtimeCallInfo)437 ArkUINativeModuleValue ScrollableBridge::ResetOnScrollStop(ArkUIRuntimeCallInfo* runtimeCallInfo)
438 {
439     EcmaVM* vm = runtimeCallInfo->GetVM();
440     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
441     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
442     CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
443     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
444     GetArkUINodeModifiers()->getScrollableModifier()->resetOnScrollStopCallBack(nativeNode);
445     return panda::JSValueRef::Undefined(vm);
446 }
447 
SetFlingSpeedLimit(ArkUIRuntimeCallInfo * runtimeCallInfo)448 ArkUINativeModuleValue ScrollableBridge::SetFlingSpeedLimit(ArkUIRuntimeCallInfo* runtimeCallInfo)
449 {
450     EcmaVM* vm = runtimeCallInfo->GetVM();
451     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
452     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
453     Local<JSValueRef> arg_flingSpeedLimit = runtimeCallInfo->GetCallArgRef(1);
454 
455     double flingSpeedLimit = -1.0f;
456     CHECK_NULL_RETURN(node->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
457     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
458     if (!ArkTSUtils::ParseJsDouble(vm, arg_flingSpeedLimit, flingSpeedLimit)) {
459         flingSpeedLimit = -1.0f;
460     }
461     GetArkUINodeModifiers()->getScrollableModifier()->setFlingSpeedLimit(nativeNode, flingSpeedLimit);
462     return panda::JSValueRef::Undefined(vm);
463 }
464 
ResetFlingSpeedLimit(ArkUIRuntimeCallInfo * runtimeCallInfo)465 ArkUINativeModuleValue ScrollableBridge::ResetFlingSpeedLimit(ArkUIRuntimeCallInfo* runtimeCallInfo)
466 {
467     EcmaVM* vm = runtimeCallInfo->GetVM();
468     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
469     Local<JSValueRef> node = runtimeCallInfo->GetCallArgRef(0);
470     CHECK_NULL_RETURN(node->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
471     auto nativeNode = nodePtr(node->ToNativePointer(vm)->Value());
472     GetArkUINodeModifiers()->getScrollableModifier()->resetFlingSpeedLimit(nativeNode);
473     return panda::JSValueRef::Undefined(vm);
474 }
475 
SetBackToTop(ArkUIRuntimeCallInfo * runtimeCallInfo)476 ArkUINativeModuleValue ScrollableBridge::SetBackToTop(ArkUIRuntimeCallInfo* runtimeCallInfo)
477 {
478     EcmaVM* vm = runtimeCallInfo->GetVM();
479     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
480     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
481     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
482     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
483     if (secondArg->IsBoolean()) {
484         bool boolValue = secondArg->ToBoolean(vm)->Value();
485         GetArkUINodeModifiers()->getScrollableModifier()->setBackToTop(nativeNode, boolValue);
486     } else {
487         GetArkUINodeModifiers()->getScrollableModifier()->resetBackToTop(nativeNode);
488     }
489     return panda::JSValueRef::Undefined(vm);
490 }
491 
ResetBackToTop(ArkUIRuntimeCallInfo * runtimeCallInfo)492 ArkUINativeModuleValue ScrollableBridge::ResetBackToTop(ArkUIRuntimeCallInfo* runtimeCallInfo)
493 {
494     EcmaVM* vm = runtimeCallInfo->GetVM();
495     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
496     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
497     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
498     GetArkUINodeModifiers()->getScrollableModifier()->resetBackToTop(nativeNode);
499     return panda::JSValueRef::Undefined(vm);
500 }
501 } // namespace OHOS::Ace::NG
502