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