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