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