1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_scroll_bridge.h"
17 
18 #include "base/log/log.h"
19 #include "base/utils/string_utils.h"
20 #include "base/utils/utils.h"
21 #include "bridge/declarative_frontend/jsview/js_scroller.h"
22 #include "core/components_ng/pattern/scroll/scroll_model.h"
23 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
24 #include "frameworks/core/components/scroll_bar/scroll_proxy.h"
25 
26 namespace OHOS::Ace::NG {
27 constexpr int NUM_0 = 0;
28 constexpr int NUM_1 = 1;
29 constexpr int NUM_2 = 2;
30 constexpr double FRICTION_DEFAULT = 0.6;
31 constexpr int32_t FROWARD_INITIAL_VALUE = 0;
32 constexpr int32_t BACKWARD_INITIAL_VALUE = 0;
33 
ParsePagination(const EcmaVM * vm,const Local<JSValueRef> & paginationValue,std::vector<ArkUI_Float32> & vPaginationValue,std::vector<int32_t> & vPaginationUnit)34 bool ParsePagination(const EcmaVM* vm, const Local<JSValueRef>& paginationValue,
35     std::vector<ArkUI_Float32>& vPaginationValue,
36     std::vector<int32_t>& vPaginationUnit)
37 {
38     uint32_t pLength = 0;
39     if (paginationValue->IsArray(vm)) {
40         auto paginationArray = panda::Local<panda::ArrayRef>(paginationValue);
41         pLength = paginationArray->Length(vm);
42         if (pLength <= 0) {
43             return false;
44         }
45         for (uint32_t i = 0; i < pLength; i++) {
46             CalcDimension dims;
47             Local<JSValueRef> xValue = panda::ArrayRef::GetValueAt(vm, paginationArray, i);
48             if (!ArkTSUtils::ParseJsDimensionVpNG(vm, xValue, dims, true)) {
49                 return false;
50             }
51             vPaginationValue.push_back(static_cast<ArkUI_Float32>(dims.Value()));
52             vPaginationUnit.push_back(static_cast<int32_t>(dims.Unit()));
53         }
54     } else {
55         CalcDimension intervalSize;
56         if (!ArkTSUtils::ParseJsDimensionVp(vm, paginationValue, intervalSize) || intervalSize.IsNegative()) {
57             intervalSize = CalcDimension(0.0);
58         }
59         vPaginationValue.push_back(static_cast<ArkUI_Float32>(intervalSize.Value()));
60         vPaginationUnit.push_back(static_cast<int32_t>(intervalSize.Unit()));
61     }
62 
63     return true;
64 }
65 
SetNestedScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)66 ArkUINativeModuleValue ScrollBridge::SetNestedScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
67 {
68     EcmaVM* vm = runtimeCallInfo->GetVM();
69     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
70     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
71     Local<JSValueRef> scrollForwardValue = runtimeCallInfo->GetCallArgRef(1);  // 1: index of scroll forward value
72     Local<JSValueRef> scrollBackwardValue = runtimeCallInfo->GetCallArgRef(2); // 2: index of scroll backward value
73     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
74     auto froward = 0;
75     auto backward = 0;
76     ArkTSUtils::ParseJsInteger(vm, scrollForwardValue, froward);
77     if (froward < static_cast<int32_t>(NestedScrollMode::SELF_ONLY) ||
78         froward > static_cast<int32_t>(NestedScrollMode::PARALLEL)) {
79         froward = FROWARD_INITIAL_VALUE;
80     }
81     ArkTSUtils::ParseJsInteger(vm, scrollBackwardValue, backward);
82     if (backward < static_cast<int32_t>(NestedScrollMode::SELF_ONLY) ||
83         backward > static_cast<int32_t>(NestedScrollMode::PARALLEL)) {
84         backward = BACKWARD_INITIAL_VALUE;
85     }
86     GetArkUINodeModifiers()->getScrollModifier()->setScrollNestedScroll(nativeNode, froward, backward);
87     return panda::JSValueRef::Undefined(vm);
88 }
89 
ResetNestedScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)90 ArkUINativeModuleValue ScrollBridge::ResetNestedScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
91 {
92     EcmaVM* vm = runtimeCallInfo->GetVM();
93     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
94     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
95     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
96     GetArkUINodeModifiers()->getScrollModifier()->resetScrollNestedScroll(nativeNode);
97     return panda::JSValueRef::Undefined(vm);
98 }
99 
SetEnableScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)100 ArkUINativeModuleValue ScrollBridge::SetEnableScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
101 {
102     EcmaVM* vm = runtimeCallInfo->GetVM();
103     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
104     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
105     Local<JSValueRef> isEnabledArg = runtimeCallInfo->GetCallArgRef(1);
106     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
107     bool isEnabled = isEnabledArg->IsBoolean() ? isEnabledArg->ToBoolean(vm)->Value() : true;
108     GetArkUINodeModifiers()->getScrollModifier()->setScrollEnableScroll(nativeNode, isEnabled);
109     return panda::JSValueRef::Undefined(vm);
110 }
111 
ResetEnableScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)112 ArkUINativeModuleValue ScrollBridge::ResetEnableScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
113 {
114     EcmaVM* vm = runtimeCallInfo->GetVM();
115     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
116     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
117     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
118     GetArkUINodeModifiers()->getScrollModifier()->resetScrollEnableScroll(nativeNode);
119     return panda::JSValueRef::Undefined(vm);
120 }
121 
SetFriction(ArkUIRuntimeCallInfo * runtimeCallInfo)122 ArkUINativeModuleValue ScrollBridge::SetFriction(ArkUIRuntimeCallInfo* runtimeCallInfo)
123 {
124     EcmaVM* vm = runtimeCallInfo->GetVM();
125     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
126     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
127     Local<JSValueRef> scrollFrictionArg = runtimeCallInfo->GetCallArgRef(1);
128     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
129     double friction = FRICTION_DEFAULT;
130     if (!ArkTSUtils::ParseJsDouble(vm, scrollFrictionArg, friction)) {
131         GetArkUINodeModifiers()->getScrollModifier()->resetScrollFriction(nativeNode);
132     } else {
133         GetArkUINodeModifiers()->getScrollModifier()->setScrollFriction(nativeNode,
134             static_cast<ArkUI_Float32>(friction));
135     }
136     return panda::JSValueRef::Undefined(vm);
137 }
138 
ResetFriction(ArkUIRuntimeCallInfo * runtimeCallInfo)139 ArkUINativeModuleValue ScrollBridge::ResetFriction(ArkUIRuntimeCallInfo* runtimeCallInfo)
140 {
141     EcmaVM* vm = runtimeCallInfo->GetVM();
142     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
143     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
144     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
145     GetArkUINodeModifiers()->getScrollModifier()->resetScrollFriction(nativeNode);
146     return panda::JSValueRef::Undefined(vm);
147 }
148 
SetScrollSnap(ArkUIRuntimeCallInfo * runtimeCallInfo)149 ArkUINativeModuleValue ScrollBridge::SetScrollSnap(ArkUIRuntimeCallInfo* runtimeCallInfo)
150 {
151     EcmaVM* vm = runtimeCallInfo->GetVM();
152     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
153     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
154     Local<JSValueRef> snapAlignValue = runtimeCallInfo->GetCallArgRef(1);         // 1: index of snap align value
155     Local<JSValueRef> paginationValue = runtimeCallInfo->GetCallArgRef(2);        // 2: index of pagination value
156     Local<JSValueRef> enableSnapToStartValue = runtimeCallInfo->GetCallArgRef(3); // 3: index of enableSnapToStart value
157     Local<JSValueRef> enableSnapToEndValue = runtimeCallInfo->GetCallArgRef(4);   // 4: index of enableSnapToEnd value
158     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
159     auto snapAlign = static_cast<int32_t>(ScrollSnapAlign::NONE);
160     if (snapAlignValue->IsNull() || snapAlignValue->IsUndefined() ||
161         !ArkTSUtils::ParseJsInteger(vm, snapAlignValue, snapAlign) ||
162         snapAlign < static_cast<int32_t>(ScrollSnapAlign::NONE) ||
163         snapAlign > static_cast<int32_t>(ScrollSnapAlign::END)) {
164         snapAlign = static_cast<int32_t>(ScrollSnapAlign::NONE);
165     }
166     std::vector<ArkUI_Float32> vPaginationValue;
167     std::vector<int32_t> vPaginationUnit;
168     if (!ParsePagination(vm, paginationValue, vPaginationValue, vPaginationUnit)) {
169         GetArkUINodeModifiers()->getScrollModifier()->resetScrollScrollSnap(nativeNode);
170         return panda::JSValueRef::Undefined(vm);
171     }
172     bool isArray = true;
173     if (!paginationValue->IsArray(vm)) {
174         isArray = false;
175     }
176     auto pLength = vPaginationValue.size();
177     vPaginationUnit.push_back(snapAlign);
178     vPaginationUnit.push_back(static_cast<int32_t>(enableSnapToStartValue->ToBoolean(vm)->Value()));
179     vPaginationUnit.push_back(static_cast<int32_t>(enableSnapToEndValue->ToBoolean(vm)->Value()));
180     vPaginationUnit.push_back(static_cast<int32_t>(isArray));
181     auto uLength = pLength + 4;
182     GetArkUINodeModifiers()->getScrollModifier()->setScrollScrollSnap(
183         nativeNode, vPaginationValue.data(), pLength, vPaginationUnit.data(), uLength);
184     return panda::JSValueRef::Undefined(vm);
185 }
186 
ResetScrollSnap(ArkUIRuntimeCallInfo * runtimeCallInfo)187 ArkUINativeModuleValue ScrollBridge::ResetScrollSnap(ArkUIRuntimeCallInfo* runtimeCallInfo)
188 {
189     EcmaVM* vm = runtimeCallInfo->GetVM();
190     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
191     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
192     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
193     GetArkUINodeModifiers()->getScrollModifier()->resetScrollScrollSnap(nativeNode);
194     return panda::JSValueRef::Undefined(vm);
195 }
196 
SetScrollBar(ArkUIRuntimeCallInfo * runtimeCallInfo)197 ArkUINativeModuleValue ScrollBridge::SetScrollBar(ArkUIRuntimeCallInfo* runtimeCallInfo)
198 {
199     EcmaVM* vm = runtimeCallInfo->GetVM();
200     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
201     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
202     Local<JSValueRef> jsValue = runtimeCallInfo->GetCallArgRef(1);
203     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
204     auto value = static_cast<int32_t>(DisplayMode::AUTO);
205     if (!jsValue->IsUndefined()) {
206         ArkTSUtils::ParseJsInteger(vm, jsValue, value);
207     }
208     GetArkUINodeModifiers()->getScrollModifier()->setScrollScrollBar(nativeNode, value);
209     return panda::JSValueRef::Undefined(vm);
210 }
211 
ResetScrollBar(ArkUIRuntimeCallInfo * runtimeCallInfo)212 ArkUINativeModuleValue ScrollBridge::ResetScrollBar(ArkUIRuntimeCallInfo* runtimeCallInfo)
213 {
214     EcmaVM* vm = runtimeCallInfo->GetVM();
215     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
216     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
217     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
218     GetArkUINodeModifiers()->getScrollModifier()->resetScrollScrollBar(nativeNode);
219     return panda::JSValueRef::Undefined(vm);
220 }
221 
SetScrollable(ArkUIRuntimeCallInfo * runtimeCallInfo)222 ArkUINativeModuleValue ScrollBridge::SetScrollable(ArkUIRuntimeCallInfo* runtimeCallInfo)
223 {
224     EcmaVM* vm = runtimeCallInfo->GetVM();
225     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
226     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
227     Local<JSValueRef> scrollDirectionArg = runtimeCallInfo->GetCallArgRef(1);
228     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
229     if (scrollDirectionArg->IsUndefined() || scrollDirectionArg->IsNull()) {
230         GetArkUINodeModifiers()->getScrollModifier()->resetScrollScrollable(nativeNode);
231         return panda::JSValueRef::Undefined(vm);
232     }
233 
234     int32_t scrollDirection = scrollDirectionArg->Int32Value(vm);
235     if (scrollDirection != static_cast<int32_t>(Axis::VERTICAL) &&
236         scrollDirection != static_cast<int32_t>(Axis::HORIZONTAL) &&
237         scrollDirection != static_cast<int32_t>(Axis::FREE) && scrollDirection != static_cast<int32_t>(Axis::NONE)) {
238         GetArkUINodeModifiers()->getScrollModifier()->resetScrollScrollable(nativeNode);
239     } else {
240         GetArkUINodeModifiers()->getScrollModifier()->setScrollScrollable(nativeNode, scrollDirection);
241     }
242 
243     return panda::JSValueRef::Undefined(vm);
244 }
245 
ResetScrollable(ArkUIRuntimeCallInfo * runtimeCallInfo)246 ArkUINativeModuleValue ScrollBridge::ResetScrollable(ArkUIRuntimeCallInfo* runtimeCallInfo)
247 {
248     EcmaVM* vm = runtimeCallInfo->GetVM();
249     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
250     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
251     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
252     GetArkUINodeModifiers()->getScrollModifier()->resetScrollScrollable(nativeNode);
253     return panda::JSValueRef::Undefined(vm);
254 }
255 
SetScrollBarColor(ArkUIRuntimeCallInfo * runtimeCallInfo)256 ArkUINativeModuleValue ScrollBridge::SetScrollBarColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
257 {
258     EcmaVM* vm = runtimeCallInfo->GetVM();
259     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
260     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
261     Local<JSValueRef> barcolorArg = runtimeCallInfo->GetCallArgRef(1);
262     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
263     Color color;
264     if (!ArkTSUtils::ParseJsColorAlpha(vm, barcolorArg, color)) {
265         GetArkUINodeModifiers()->getScrollModifier()->resetScrollScrollBarColor(nativeNode);
266     } else {
267         GetArkUINodeModifiers()->getScrollModifier()->setScrollScrollBarColor(nativeNode, color.GetValue());
268     }
269 
270     return panda::JSValueRef::Undefined(vm);
271 }
272 
ResetScrollBarColor(ArkUIRuntimeCallInfo * runtimeCallInfo)273 ArkUINativeModuleValue ScrollBridge::ResetScrollBarColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
274 {
275     EcmaVM* vm = runtimeCallInfo->GetVM();
276     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
277     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
278     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
279     GetArkUINodeModifiers()->getScrollModifier()->resetScrollScrollBarColor(nativeNode);
280     return panda::JSValueRef::Undefined(vm);
281 }
282 
SetScrollBarWidth(ArkUIRuntimeCallInfo * runtimeCallInfo)283 ArkUINativeModuleValue ScrollBridge::SetScrollBarWidth(ArkUIRuntimeCallInfo* runtimeCallInfo)
284 {
285     EcmaVM* vm = runtimeCallInfo->GetVM();
286     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
287     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
288     Local<JSValueRef> scrollBarArg = runtimeCallInfo->GetCallArgRef(1);
289     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
290     CalcDimension scrollBarWidth;
291     if (!ArkTSUtils::ParseJsDimensionVpNG(vm, scrollBarArg, scrollBarWidth, false)) {
292         GetArkUINodeModifiers()->getScrollModifier()->resetScrollScrollBarWidth(nativeNode);
293     } else {
294         if (LessNotEqual(scrollBarWidth.Value(), 0.0)) {
295             GetArkUINodeModifiers()->getScrollModifier()->resetScrollScrollBarWidth(nativeNode);
296         } else {
297             GetArkUINodeModifiers()->getScrollModifier()->setScrollScrollBarWidth(
298                 nativeNode, scrollBarWidth.Value(), static_cast<int32_t>(scrollBarWidth.Unit()));
299         }
300     }
301 
302     return panda::JSValueRef::Undefined(vm);
303 }
304 
ResetScrollBarWidth(ArkUIRuntimeCallInfo * runtimeCallInfo)305 ArkUINativeModuleValue ScrollBridge::ResetScrollBarWidth(ArkUIRuntimeCallInfo* runtimeCallInfo)
306 {
307     EcmaVM* vm = runtimeCallInfo->GetVM();
308     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
309     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
310     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
311     GetArkUINodeModifiers()->getScrollModifier()->resetScrollScrollBarWidth(nativeNode);
312     return panda::JSValueRef::Undefined(vm);
313 }
314 
SetEdgeEffect(ArkUIRuntimeCallInfo * runtimeCallInfo)315 ArkUINativeModuleValue ScrollBridge::SetEdgeEffect(ArkUIRuntimeCallInfo* runtimeCallInfo)
316 {
317     EcmaVM* vm = runtimeCallInfo->GetVM();
318     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
319     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
320     Local<JSValueRef> effectArg = runtimeCallInfo->GetCallArgRef(1);    // 1: index of effect value
321     Local<JSValueRef> isEffectArg = runtimeCallInfo->GetCallArgRef(2);  // 2: index of isEffect value
322     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
323     int32_t effect = static_cast<int32_t>(EdgeEffect::NONE);
324     if (!effectArg->IsUndefined() && !effectArg->IsNull()) {
325         effect = effectArg->Int32Value(vm);
326     }
327 
328     if (effect != static_cast<int32_t>(EdgeEffect::SPRING) && effect != static_cast<int32_t>(EdgeEffect::NONE) &&
329         effect != static_cast<int32_t>(EdgeEffect::FADE)) {
330         effect = static_cast<int32_t>(EdgeEffect::NONE);
331     }
332 
333     if (isEffectArg->IsUndefined() || isEffectArg->IsNull()) {
334         GetArkUINodeModifiers()->getScrollModifier()->setScrollEdgeEffect(nativeNode, effect, true);
335     } else {
336         GetArkUINodeModifiers()->getScrollModifier()->setScrollEdgeEffect(
337             nativeNode, effect, isEffectArg->ToBoolean(vm)->Value());
338     }
339 
340     return panda::JSValueRef::Undefined(vm);
341 }
342 
ResetEdgeEffect(ArkUIRuntimeCallInfo * runtimeCallInfo)343 ArkUINativeModuleValue ScrollBridge::ResetEdgeEffect(ArkUIRuntimeCallInfo* runtimeCallInfo)
344 {
345     EcmaVM* vm = runtimeCallInfo->GetVM();
346     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
347     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
348     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
349     GetArkUINodeModifiers()->getScrollModifier()->resetScrollEdgeEffect(nativeNode);
350     return panda::JSValueRef::Undefined(vm);
351 }
352 
SetFadingEdge(ArkUIRuntimeCallInfo * runtimeCallInfo)353 ArkUINativeModuleValue ScrollBridge::SetFadingEdge(ArkUIRuntimeCallInfo* runtimeCallInfo)
354 {
355     EcmaVM* vm = runtimeCallInfo->GetVM();
356     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
357     Local<JSValueRef> frameNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
358     Local<JSValueRef> fadingEdgeArg = runtimeCallInfo->GetCallArgRef(NUM_1);
359     Local<JSValueRef> fadingEdgeLengthArg = runtimeCallInfo->GetCallArgRef(NUM_2);
360 
361     auto nativeNode = nodePtr(frameNodeArg->ToNativePointer(vm)->Value());
362 
363     CalcDimension fadingEdgeLength = Dimension(32.0f, DimensionUnit::VP); // default value
364 
365     if (fadingEdgeArg->IsUndefined() || fadingEdgeArg->IsNull()) {
366         GetArkUINodeModifiers()->getScrollModifier()->resetScrollFadingEdge(nativeNode);
367     } else {
368         bool fadingEdge = fadingEdgeArg->ToBoolean(vm)->Value();
369         if (!fadingEdgeLengthArg->IsUndefined() && !fadingEdgeLengthArg->IsNull() &&
370             fadingEdgeLengthArg->IsObject(vm)) {
371             ArkTSUtils::ParseJsLengthMetrics(vm, fadingEdgeLengthArg, fadingEdgeLength);
372         }
373         GetArkUINodeModifiers()->getScrollModifier()->setScrollFadingEdge(
374             nativeNode, fadingEdge, fadingEdgeLength.Value(), static_cast<int32_t>(fadingEdgeLength.Unit()));
375     }
376     return panda::JSValueRef::Undefined(vm);
377 }
ResetFadingEdge(ArkUIRuntimeCallInfo * runtimeCallInfo)378 ArkUINativeModuleValue ScrollBridge::ResetFadingEdge(ArkUIRuntimeCallInfo* runtimeCallInfo)
379 {
380     EcmaVM* vm = runtimeCallInfo->GetVM();
381     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
382     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
383     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
384     GetArkUINodeModifiers()->getScrollModifier()->resetScrollFadingEdge(nativeNode);
385 
386     return panda::JSValueRef::Undefined(vm);
387 }
388 
SetEnablePaging(ArkUIRuntimeCallInfo * runtimeCallInfo)389 ArkUINativeModuleValue ScrollBridge::SetEnablePaging(ArkUIRuntimeCallInfo* runtimeCallInfo)
390 {
391     EcmaVM* vm = runtimeCallInfo->GetVM();
392     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
393     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
394     Local<JSValueRef> enablePagingArg = runtimeCallInfo->GetCallArgRef(1);
395     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
396     bool enablePaging;
397     if (enablePagingArg->IsBoolean()) {
398         enablePaging = enablePagingArg->ToBoolean(vm)->Value();
399         GetArkUINodeModifiers()->getScrollModifier()->setScrollEnablePaging(nativeNode, enablePaging);
400     } else {
401         GetArkUINodeModifiers()->getScrollModifier()->resetScrollEnablePaging(nativeNode);
402     }
403     return panda::JSValueRef::Undefined(vm);
404 }
405 
ResetEnablePaging(ArkUIRuntimeCallInfo * runtimeCallInfo)406 ArkUINativeModuleValue ScrollBridge::ResetEnablePaging(ArkUIRuntimeCallInfo* runtimeCallInfo)
407 {
408     EcmaVM* vm = runtimeCallInfo->GetVM();
409     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
410     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
411     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
412     GetArkUINodeModifiers()->getScrollModifier()->resetScrollEnablePaging(nativeNode);
413     return panda::JSValueRef::Undefined(vm);
414 }
415 
SetInitialOffset(ArkUIRuntimeCallInfo * runtimeCallInfo)416 ArkUINativeModuleValue ScrollBridge::SetInitialOffset(ArkUIRuntimeCallInfo* runtimeCallInfo)
417 {
418     EcmaVM* vm = runtimeCallInfo->GetVM();
419     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
420     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
421     Local<JSValueRef> xOffsetArg = runtimeCallInfo->GetCallArgRef(NUM_1);
422     Local<JSValueRef> yOffsetArg = runtimeCallInfo->GetCallArgRef(NUM_2);
423     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
424 
425     CalcDimension x;
426     ArkTSUtils::ParseJsDimensionVpNG(vm, xOffsetArg, x, false);
427     CalcDimension y;
428     ArkTSUtils::ParseJsDimensionVpNG(vm, yOffsetArg, y, false);
429 
430     GetArkUINodeModifiers()->getScrollModifier()->setScrollInitialOffset(nativeNode, x.Value(),
431         static_cast<int32_t>(x.Unit()), y.Value(), static_cast<int32_t>(y.Unit()));
432     return panda::JSValueRef::Undefined(vm);
433 }
434 
ResetInitialOffset(ArkUIRuntimeCallInfo * runtimeCallInfo)435 ArkUINativeModuleValue ScrollBridge::ResetInitialOffset(ArkUIRuntimeCallInfo* runtimeCallInfo)
436 {
437     EcmaVM* vm = runtimeCallInfo->GetVM();
438     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
439     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
440     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
441     GetArkUINodeModifiers()->getScrollModifier()->resetScrollInitialOffset(nativeNode);
442     return panda::JSValueRef::Undefined(vm);
443 }
444 
SetFlingSpeedLimit(ArkUIRuntimeCallInfo * runtimeCallInfo)445 ArkUINativeModuleValue ScrollBridge::SetFlingSpeedLimit(ArkUIRuntimeCallInfo* runtimeCallInfo)
446 {
447     EcmaVM* vm = runtimeCallInfo->GetVM();
448     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
449     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
450     Local<JSValueRef> flingSpeedLimitArg = runtimeCallInfo->GetCallArgRef(NUM_1);
451     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
452     double max = -1.0;
453     if (!ArkTSUtils::ParseJsDouble(vm, flingSpeedLimitArg, max)) {
454         GetArkUINodeModifiers()->getScrollModifier()->resetScrollFlingSpeedLimit(nativeNode);
455     } else {
456         GetArkUINodeModifiers()->getScrollModifier()->setScrollFlingSpeedLimit(nativeNode,
457             static_cast<ArkUI_Float32>(max));
458     }
459     return panda::JSValueRef::Undefined(vm);
460 }
461 
ResetFlingSpeedLimit(ArkUIRuntimeCallInfo * runtimeCallInfo)462 ArkUINativeModuleValue ScrollBridge::ResetFlingSpeedLimit(ArkUIRuntimeCallInfo* runtimeCallInfo)
463 {
464     EcmaVM* vm = runtimeCallInfo->GetVM();
465     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
466     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
467     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
468     GetArkUINodeModifiers()->getScrollModifier()->resetScrollFlingSpeedLimit(nativeNode);
469     return panda::JSValueRef::Undefined(vm);
470 }
471 
SetScrollInitialize(ArkUIRuntimeCallInfo * runtimeCallInfo)472 ArkUINativeModuleValue ScrollBridge::SetScrollInitialize(ArkUIRuntimeCallInfo* runtimeCallInfo)
473 {
474     EcmaVM* vm = runtimeCallInfo->GetVM();
475     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
476     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
477     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
478 
479     Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
480     if (!info[1]->IsNull() && info[1]->IsObject()) {
481         Framework::JSScroller* jsScroller =
482             Framework::JSRef<Framework::JSObject>::Cast(info[1])->Unwrap<Framework::JSScroller>();
483         if (jsScroller) {
484             jsScroller->SetInstanceId(Container::CurrentId());
485             auto positionController = GetArkUINodeModifiers()->getScrollModifier()->getScroll(nativeNode);
486             auto nodePositionController =
487                 AceType::Claim(reinterpret_cast<OHOS::Ace::ScrollControllerBase*>(positionController));
488             jsScroller->SetController(nodePositionController);
489             // Init scroll bar proxy.
490             auto proxy = jsScroller->GetScrollBarProxy();
491             if (!proxy) {
492                 proxy = ScrollModel::GetInstance()->CreateScrollBarProxy();
493                 jsScroller->SetScrollBarProxy(proxy);
494             }
495             auto proxyPtr = reinterpret_cast<ArkUINodeHandle>(OHOS::Ace::AceType::RawPtr(proxy));
496             GetArkUINodeModifiers()->getScrollModifier()->setScrollBarProxy(nativeNode, proxyPtr);
497         }
498     }
499     return panda::JSValueRef::Undefined(vm);
500 }
501 
ResetScrollInitialize(ArkUIRuntimeCallInfo * runtimeCallInfo)502 ArkUINativeModuleValue ScrollBridge::ResetScrollInitialize(ArkUIRuntimeCallInfo* runtimeCallInfo)
503 {
504     EcmaVM* vm = runtimeCallInfo->GetVM();
505     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
506     return panda::JSValueRef::Undefined(vm);
507 }
508 
SetScrollOnScrollStart(ArkUIRuntimeCallInfo * runtimeCallInfo)509 ArkUINativeModuleValue ScrollBridge::SetScrollOnScrollStart(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     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
515     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
516     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
517         GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnScrollStart(nativeNode);
518         return panda::JSValueRef::Undefined(vm);
519     }
520     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
521     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
522     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
523 
524     std::function<void()> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
525         panda::LocalScope pandaScope(vm);
526         panda::TryCatch trycatch(vm);
527         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
528         func->Call(vm, func.ToLocal(), nullptr, 0);
529     };
530     GetArkUINodeModifiers()->getScrollModifier()->setScrollOnScrollStart(
531         nativeNode, reinterpret_cast<void*>(&callback));
532     return panda::JSValueRef::Undefined(vm);
533 }
534 
ResetScrollOnScrollStart(ArkUIRuntimeCallInfo * runtimeCallInfo)535 ArkUINativeModuleValue ScrollBridge::ResetScrollOnScrollStart(ArkUIRuntimeCallInfo* runtimeCallInfo)
536 {
537     EcmaVM* vm = runtimeCallInfo->GetVM();
538     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
539     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
540     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
541     GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnScrollStart(nativeNode);
542     return panda::JSValueRef::Undefined(vm);
543 }
544 
SetScrollOnScrollEnd(ArkUIRuntimeCallInfo * runtimeCallInfo)545 ArkUINativeModuleValue ScrollBridge::SetScrollOnScrollEnd(ArkUIRuntimeCallInfo* runtimeCallInfo)
546 {
547     EcmaVM *vm = runtimeCallInfo->GetVM();
548     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
549     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
550     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
551     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
552     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
553         GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnScrollEnd(nativeNode);
554         return panda::JSValueRef::Undefined(vm);
555     }
556     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
557     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
558     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
559     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
560         panda::LocalScope pandaScope(vm);
561         panda::TryCatch trycatch(vm);
562         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
563         func->Call(vm, func.ToLocal(), nullptr, 0);
564     };
565     GetArkUINodeModifiers()->getScrollModifier()->setScrollOnScrollEnd(nativeNode, reinterpret_cast<void*>(&callback));
566     return panda::JSValueRef::Undefined(vm);
567 }
568 
ResetScrollOnScrollEnd(ArkUIRuntimeCallInfo * runtimeCallInfo)569 ArkUINativeModuleValue ScrollBridge::ResetScrollOnScrollEnd(ArkUIRuntimeCallInfo* runtimeCallInfo)
570 {
571     EcmaVM* vm = runtimeCallInfo->GetVM();
572     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
573     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
574     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
575     GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnScrollEnd(nativeNode);
576     return panda::JSValueRef::Undefined(vm);
577 }
578 
SetScrollOnScrollStop(ArkUIRuntimeCallInfo * runtimeCallInfo)579 ArkUINativeModuleValue ScrollBridge::SetScrollOnScrollStop(ArkUIRuntimeCallInfo* runtimeCallInfo)
580 {
581     EcmaVM *vm = runtimeCallInfo->GetVM();
582     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
583     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
584     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
585     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
586     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
587         GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnScrollStop(nativeNode);
588         return panda::JSValueRef::Undefined(vm);
589     }
590     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
591     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
592     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
593     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
594         panda::LocalScope pandaScope(vm);
595         panda::TryCatch trycatch(vm);
596         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
597         func->Call(vm, func.ToLocal(), nullptr, 0);
598     };
599     GetArkUINodeModifiers()->getScrollModifier()->setScrollOnScrollStop(nativeNode, reinterpret_cast<void*>(&callback));
600     return panda::JSValueRef::Undefined(vm);
601 }
602 
ResetScrollOnScrollStop(ArkUIRuntimeCallInfo * runtimeCallInfo)603 ArkUINativeModuleValue ScrollBridge::ResetScrollOnScrollStop(ArkUIRuntimeCallInfo* runtimeCallInfo)
604 {
605     EcmaVM* vm = runtimeCallInfo->GetVM();
606     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
607     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
608     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
609     GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnScrollStop(nativeNode);
610     return panda::JSValueRef::Undefined(vm);
611 }
612 
SetScrollOnScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)613 ArkUINativeModuleValue ScrollBridge::SetScrollOnScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
614 {
615     EcmaVM* vm = runtimeCallInfo->GetVM();
616     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
617     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
618     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
619     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
620     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
621         GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnScroll(nativeNode);
622         return panda::JSValueRef::Undefined(vm);
623     }
624     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
625     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
626     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
627     std::function<void(OHOS::Ace::Dimension, OHOS::Ace::Dimension)> callback =
628         [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
629         OHOS::Ace::Dimension xOffset, OHOS::Ace::Dimension yOffset) {
630         panda::LocalScope pandaScope(vm);
631         panda::TryCatch trycatch(vm);
632         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
633 
634         panda::Local<panda::NumberRef> xOffsetParam = panda::NumberRef::New(
635             vm, static_cast<double>(xOffset.ConvertToVp()));
636         panda::Local<panda::NumberRef> yOffsetParam = panda::NumberRef::New(
637             vm, static_cast<double>(yOffset.ConvertToVp()));
638         panda::Local<panda::JSValueRef> params[2] = { xOffsetParam, yOffsetParam }; // 2: Array .length
639         func->Call(vm, func.ToLocal(), params, 2); // 2: Array length
640     };
641     GetArkUINodeModifiers()->getScrollModifier()->setScrollOnScroll(nativeNode,
642         reinterpret_cast<void*>(&callback));
643     return panda::JSValueRef::Undefined(vm);
644 }
645 
ResetScrollOnScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)646 ArkUINativeModuleValue ScrollBridge::ResetScrollOnScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
647 {
648     EcmaVM* vm = runtimeCallInfo->GetVM();
649     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
650     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
651     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
652     GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnScroll(nativeNode);
653     return panda::JSValueRef::Undefined(vm);
654 }
655 
SetScrollOnScrollEdge(ArkUIRuntimeCallInfo * runtimeCallInfo)656 ArkUINativeModuleValue ScrollBridge::SetScrollOnScrollEdge(ArkUIRuntimeCallInfo* runtimeCallInfo)
657 {
658     EcmaVM* vm = runtimeCallInfo->GetVM();
659     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
660     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
661     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
662     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
663     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
664         GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnScrollEdge(nativeNode);
665         return panda::JSValueRef::Undefined(vm);
666     }
667     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
668     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
669     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
670     std::function<void(OHOS::Ace::NG::ScrollEdge)> callback =
671         [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
672         OHOS::Ace::NG::ScrollEdge edge) {
673         panda::LocalScope pandaScope(vm);
674         panda::TryCatch trycatch(vm);
675         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
676 
677         panda::Local<panda::NumberRef> edgeParam = panda::NumberRef::New(vm, static_cast<int32_t>(edge));
678         panda::Local<panda::JSValueRef> params[1] = { edgeParam }; // 1: Array length
679         func->Call(vm, func.ToLocal(), params, 1); // 1: Array length
680     };
681     GetArkUINodeModifiers()->getScrollModifier()->setScrollOnScrollEdge(nativeNode,
682         reinterpret_cast<void*>(&callback));
683     return panda::JSValueRef::Undefined(vm);
684 }
685 
ResetScrollOnScrollEdge(ArkUIRuntimeCallInfo * runtimeCallInfo)686 ArkUINativeModuleValue ScrollBridge::ResetScrollOnScrollEdge(ArkUIRuntimeCallInfo* runtimeCallInfo)
687 {
688     EcmaVM* vm = runtimeCallInfo->GetVM();
689     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
690     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
691     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
692     GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnScrollEdge(nativeNode);
693     return panda::JSValueRef::Undefined(vm);
694 }
695 
SetScrollOnDidScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)696 ArkUINativeModuleValue ScrollBridge::SetScrollOnDidScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
697 {
698     EcmaVM* vm = runtimeCallInfo->GetVM();
699     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
700     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
701     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
702     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
703     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
704         GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnDidScroll(nativeNode);
705         return panda::JSValueRef::Undefined(vm);
706     }
707     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
708     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
709     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
710     std::function<void(Dimension, Dimension, ScrollState)> callback =
711         [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
712         Dimension xOffset, Dimension yOffset, ScrollState state) {
713         panda::LocalScope pandaScope(vm);
714         panda::TryCatch trycatch(vm);
715         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
716 
717         panda::Local<panda::NumberRef> xOffsetParam = panda::NumberRef::New(
718             vm, static_cast<double>(xOffset.ConvertToVp()));
719         panda::Local<panda::NumberRef> yOffsetParam = panda::NumberRef::New(
720             vm, static_cast<double>(yOffset.ConvertToVp()));
721         panda::Local<panda::NumberRef> stateParam = panda::NumberRef::New(vm, static_cast<int32_t>(state));
722          // 3: Array length
723         panda::Local<panda::JSValueRef> params[3] = { xOffsetParam, yOffsetParam, stateParam };
724         func->Call(vm, func.ToLocal(), params, 3); // 3: Array length
725     };
726     GetArkUINodeModifiers()->getScrollModifier()->setScrollOnDidScrollCallBack(nativeNode,
727         reinterpret_cast<void*>(&callback));
728     return panda::JSValueRef::Undefined(vm);
729 }
730 
ResetScrollOnDidScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)731 ArkUINativeModuleValue ScrollBridge::ResetScrollOnDidScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
732 {
733     EcmaVM* vm = runtimeCallInfo->GetVM();
734     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
735     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
736     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
737     GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnDidScroll(nativeNode);
738     return panda::JSValueRef::Undefined(vm);
739 }
740 
SetScrollOnWillScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)741 ArkUINativeModuleValue ScrollBridge::SetScrollOnWillScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
742 {
743     EcmaVM* vm = runtimeCallInfo->GetVM();
744     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
745     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
746     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
747     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
748     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
749         GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnWillScrollCallBack(nativeNode);
750         return panda::JSValueRef::Undefined(vm);
751     }
752     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
753     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
754     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
755     std::function<TwoDimensionScrollResult(Dimension, Dimension, ScrollState, ScrollSource)> callback =
756         [vm, frameNode, func = panda::CopyableGlobal(vm, func)](Dimension xOffset,
757             Dimension yOffset, ScrollState state, ScrollSource scrollState) -> TwoDimensionScrollResult {
758         panda::LocalScope pandaScope(vm);
759         panda::TryCatch trycatch(vm);
760         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
761 
762         panda::Local<panda::NumberRef> xOffsetParam = panda::NumberRef::New(
763             vm, static_cast<double>(xOffset.ConvertToVp()));
764         panda::Local<panda::NumberRef> yOffsetParam = panda::NumberRef::New(
765             vm, static_cast<double>(yOffset.ConvertToVp()));
766         panda::Local<panda::NumberRef> stateParam = panda::NumberRef::New(vm, static_cast<double>(state));
767         panda::Local<panda::NumberRef> sourceParam = panda::NumberRef::New(vm, static_cast<double>(scrollState));
768          // 4: Array length
769         panda::Local<panda::JSValueRef> params[4] = { xOffsetParam, yOffsetParam, stateParam, sourceParam};
770         auto result = func->Call(vm, func.ToLocal(), params, 4); // 4: Array length
771         NG::TwoDimensionScrollResult scrollRes { .xOffset = xOffset, .yOffset = yOffset };
772 
773         if (result->IsObject(vm)) {
774             auto resultObj = result->ToObject(vm);
775             panda::Local<panda::JSValueRef> x = resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "xOffset"));
776             panda::Local<panda::JSValueRef> y = resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, "yOffset"));
777             if (x->IsNumber()) {
778                 scrollRes.xOffset = Dimension(x->ToNumber(vm)->Value(), DimensionUnit::VP);
779             }
780             if (y->IsNumber()) {
781                 scrollRes.yOffset = Dimension(y->ToNumber(vm)->Value(), DimensionUnit::VP);
782             }
783         }
784         return scrollRes;
785     };
786     GetArkUINodeModifiers()->getScrollModifier()->setScrollOnWillScrollCallBack(nativeNode,
787         reinterpret_cast<void*>(&callback));
788     return panda::JSValueRef::Undefined(vm);
789 }
790 
ResetScrollOnWillScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)791 ArkUINativeModuleValue ScrollBridge::ResetScrollOnWillScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
792 {
793     EcmaVM* vm = runtimeCallInfo->GetVM();
794     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
795     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
796     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
797     GetArkUINodeModifiers()->getScrollModifier()->resetScrollOnWillScrollCallBack(nativeNode);
798     return panda::JSValueRef::Undefined(vm);
799 }
800 
SetScrollOnScrollFrameBegin(ArkUIRuntimeCallInfo * runtimeCallInfo)801 ArkUINativeModuleValue ScrollBridge::SetScrollOnScrollFrameBegin(ArkUIRuntimeCallInfo* runtimeCallInfo)
802 {
803     EcmaVM* vm = runtimeCallInfo->GetVM();
804     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
805     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
806     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
807     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
808     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
809         GetArkUINodeModifiers()->getScrollModifier()->resetOnScrollFrameBeginCallBack(nativeNode);
810         return panda::JSValueRef::Undefined(vm);
811     }
812     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
813     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
814     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
815     std::function<ScrollFrameResult(Dimension, ScrollState)> callback = [vm, frameNode,
816         func = panda::CopyableGlobal(vm, func)](Dimension offset, ScrollState state) -> ScrollFrameResult {
817         panda::LocalScope pandaScope(vm);
818         panda::TryCatch trycatch(vm);
819         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
820 
821         panda::Local<panda::NumberRef> offsetParam = panda::NumberRef::New(
822             vm, static_cast<double>(offset.ConvertToVp()));
823         panda::Local<panda::NumberRef> stateParam = panda::NumberRef::New(vm, static_cast<double>(state));
824          // 2: Array length
825         panda::Local<panda::JSValueRef> params[2] = { offsetParam, stateParam };
826         auto value = func->Call(vm, func.ToLocal(), params, 2); // 2: Array length
827 
828         OHOS::Ace::ScrollFrameResult scrollRes { .offset = offset };
829         if (value->IsNumber()) {
830             scrollRes.offset = Dimension(value->ToNumber(vm)->Value(), DimensionUnit::VP);
831         }
832         if (value->IsObject(vm)) {
833             auto resultObj = value->ToObject(vm);
834             panda::Local<panda::JSValueRef> remain = resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm,
835                 "offsetRemain"));
836             if (remain->IsNumber()) {
837                 scrollRes.offset = Dimension(remain->ToNumber(vm)->Value(), DimensionUnit::VP);
838             }
839         }
840         return scrollRes;
841     };
842     GetArkUINodeModifiers()->getScrollModifier()->setOnScrollFrameBeginCallBack(nativeNode,
843         reinterpret_cast<void*>(&callback));
844     return panda::JSValueRef::Undefined(vm);
845 }
846 
ResetScrollOnScrollFrameBegin(ArkUIRuntimeCallInfo * runtimeCallInfo)847 ArkUINativeModuleValue ScrollBridge::ResetScrollOnScrollFrameBegin(ArkUIRuntimeCallInfo* runtimeCallInfo)
848 {
849     EcmaVM* vm = runtimeCallInfo->GetVM();
850     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
851     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
852     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
853     GetArkUINodeModifiers()->getScrollModifier()->resetOnScrollFrameBeginCallBack(nativeNode);
854     return panda::JSValueRef::Undefined(vm);
855 }
856 } // namespace OHOS::Ace::NG
857