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 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_water_flow_bridge.h"
16
17 #include "base/utils/string_utils.h"
18 #include "base/utils/utils.h"
19 #include "bridge/declarative_frontend/jsview/js_scroller.h"
20 #include "bridge/declarative_frontend/jsview/js_water_flow.h"
21 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
22 #include "core/components_ng/pattern/scrollable/scrollable_controller.h"
23 #include "core/components_ng/pattern/waterflow/water_flow_model_ng.h"
24
25 namespace OHOS::Ace::NG {
26 namespace {
27 constexpr double FRICTION_DEFAULT = -1.0;
28 constexpr double DIMENSION_DEFAULT = 0.0;
29 constexpr int32_t DISPLAY_MODE_SIZE = 3;
30 constexpr int32_t NUM_0 = 0;
31 constexpr int32_t NUM_1 = 1;
32 constexpr int32_t NUM_2 = 2;
33 constexpr int32_t NUM_3 = 3;
34 constexpr int32_t NUM_4 = 4;
35 const std::vector<FlexDirection> LAYOUT_DIRECTION = { FlexDirection::ROW, FlexDirection::COLUMN,
36 FlexDirection::ROW_REVERSE, FlexDirection::COLUMN_REVERSE };
37
SetItemConstraintSizeSendParams(CalcDimension & doubleValue,std::string & calcStrValue)38 void SetItemConstraintSizeSendParams(CalcDimension& doubleValue, std::string& calcStrValue)
39 {
40 if (doubleValue.Unit() == DimensionUnit::CALC) {
41 calcStrValue = doubleValue.CalcValue();
42 doubleValue.SetValue(DIMENSION_DEFAULT);
43 }
44 }
45 } // namespace
46
ResetColumnsTemplate(ArkUIRuntimeCallInfo * runtimeCallInfo)47 ArkUINativeModuleValue WaterFlowBridge::ResetColumnsTemplate(ArkUIRuntimeCallInfo* runtimeCallInfo)
48 {
49 EcmaVM* vm = runtimeCallInfo->GetVM();
50 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
51 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
52 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
53 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
54 GetArkUINodeModifiers()->getWaterFlowModifier()->resetColumnsTemplate(nativeNode);
55 return panda::JSValueRef::Undefined(vm);
56 }
57
SetColumnsTemplate(ArkUIRuntimeCallInfo * runtimeCallInfo)58 ArkUINativeModuleValue WaterFlowBridge::SetColumnsTemplate(ArkUIRuntimeCallInfo* runtimeCallInfo)
59 {
60 EcmaVM* vm = runtimeCallInfo->GetVM();
61 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
62 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
63 Local<JSValueRef> columnsTemplateArg = runtimeCallInfo->GetCallArgRef(NUM_1);
64 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
65 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
66 std::string columnsTemplateValue = columnsTemplateArg->ToString(vm)->ToString(vm);
67 GetArkUINodeModifiers()->getWaterFlowModifier()->setColumnsTemplate(nativeNode, columnsTemplateValue.c_str());
68 return panda::JSValueRef::Undefined(vm);
69 }
70
ResetRowsTemplate(ArkUIRuntimeCallInfo * runtimeCallInfo)71 ArkUINativeModuleValue WaterFlowBridge::ResetRowsTemplate(ArkUIRuntimeCallInfo* runtimeCallInfo)
72 {
73 EcmaVM* vm = runtimeCallInfo->GetVM();
74 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
75 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
76 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
77 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
78 GetArkUINodeModifiers()->getWaterFlowModifier()->resetRowsTemplate(nativeNode);
79 return panda::JSValueRef::Undefined(vm);
80 }
81
SetRowsTemplate(ArkUIRuntimeCallInfo * runtimeCallInfo)82 ArkUINativeModuleValue WaterFlowBridge::SetRowsTemplate(ArkUIRuntimeCallInfo* runtimeCallInfo)
83 {
84 EcmaVM* vm = runtimeCallInfo->GetVM();
85 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
86 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
87 Local<JSValueRef> rowsTemplateArg = runtimeCallInfo->GetCallArgRef(NUM_1);
88 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
89 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
90 std::string rowsTemplateValue = rowsTemplateArg->ToString(vm)->ToString(vm);
91 GetArkUINodeModifiers()->getWaterFlowModifier()->setRowsTemplate(nativeNode, rowsTemplateValue.c_str());
92 return panda::JSValueRef::Undefined(vm);
93 }
94
SetEnableScrollInteraction(ArkUIRuntimeCallInfo * runtimeCallInfo)95 ArkUINativeModuleValue WaterFlowBridge::SetEnableScrollInteraction(ArkUIRuntimeCallInfo* runtimeCallInfo)
96 {
97 EcmaVM* vm = runtimeCallInfo->GetVM();
98 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
99 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
100 Local<JSValueRef> enableScrollInteractionArg = runtimeCallInfo->GetCallArgRef(NUM_1);
101 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
102 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
103 if (enableScrollInteractionArg->IsUndefined() || !enableScrollInteractionArg->IsBoolean()) {
104 GetArkUINodeModifiers()->getWaterFlowModifier()->setWaterFlowEnableScrollInteraction(nativeNode, true);
105 return panda::JSValueRef::Undefined(vm);
106 }
107 bool flag = enableScrollInteractionArg->ToBoolean(vm)->Value();
108 GetArkUINodeModifiers()->getWaterFlowModifier()->setWaterFlowEnableScrollInteraction(nativeNode, flag);
109 return panda::JSValueRef::Undefined(vm);
110 }
111
ResetEnableScrollInteraction(ArkUIRuntimeCallInfo * runtimeCallInfo)112 ArkUINativeModuleValue WaterFlowBridge::ResetEnableScrollInteraction(ArkUIRuntimeCallInfo* runtimeCallInfo)
113 {
114 EcmaVM* vm = runtimeCallInfo->GetVM();
115 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
116 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
117 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
118 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
119 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowEnableScrollInteraction(nativeNode);
120 return panda::JSValueRef::Undefined(vm);
121 }
122
ResetColumnsGap(ArkUIRuntimeCallInfo * runtimeCallInfo)123 ArkUINativeModuleValue WaterFlowBridge::ResetColumnsGap(ArkUIRuntimeCallInfo* runtimeCallInfo)
124 {
125 EcmaVM* vm = runtimeCallInfo->GetVM();
126 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
127 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
128 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
129 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
130 GetArkUINodeModifiers()->getWaterFlowModifier()->resetColumnsGap(nativeNode);
131 return panda::JSValueRef::Undefined(vm);
132 }
133
SetColumnsGap(ArkUIRuntimeCallInfo * runtimeCallInfo)134 ArkUINativeModuleValue WaterFlowBridge::SetColumnsGap(ArkUIRuntimeCallInfo* runtimeCallInfo)
135 {
136 EcmaVM* vm = runtimeCallInfo->GetVM();
137 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
138 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
139 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
140 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
141 Local<JSValueRef> columnsGapArg = runtimeCallInfo->GetCallArgRef(NUM_1);
142
143 CalcDimension columnsGap;
144 std::string calcStr;
145 if (columnsGapArg->IsUndefined() || !ArkTSUtils::ParseJsDimensionVpNG(vm, columnsGapArg, columnsGap)) {
146 GetArkUINodeModifiers()->getWaterFlowModifier()->resetColumnsGap(nativeNode);
147 } else {
148 if (LessNotEqual(columnsGap.Value(), DIMENSION_DEFAULT)) {
149 columnsGap.SetValue(DIMENSION_DEFAULT);
150 }
151
152 if (columnsGap.Unit() == DimensionUnit::CALC) {
153 GetArkUINodeModifiers()->getWaterFlowModifier()->setColumnsGap(
154 nativeNode, NUM_0, static_cast<int32_t>(columnsGap.Unit()), columnsGap.CalcValue().c_str());
155 } else {
156 GetArkUINodeModifiers()->getWaterFlowModifier()->setColumnsGap(
157 nativeNode, columnsGap.Value(), static_cast<int32_t>(columnsGap.Unit()), calcStr.c_str());
158 }
159 }
160 return panda::JSValueRef::Undefined(vm);
161 }
162
ResetRowsGap(ArkUIRuntimeCallInfo * runtimeCallInfo)163 ArkUINativeModuleValue WaterFlowBridge::ResetRowsGap(ArkUIRuntimeCallInfo* runtimeCallInfo)
164 {
165 EcmaVM* vm = runtimeCallInfo->GetVM();
166 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
167 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
168 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
169 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
170 GetArkUINodeModifiers()->getWaterFlowModifier()->resetRowsGap(nativeNode);
171 return panda::JSValueRef::Undefined(vm);
172 }
173
SetRowsGap(ArkUIRuntimeCallInfo * runtimeCallInfo)174 ArkUINativeModuleValue WaterFlowBridge::SetRowsGap(ArkUIRuntimeCallInfo* runtimeCallInfo)
175 {
176 EcmaVM* vm = runtimeCallInfo->GetVM();
177 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
178 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
179 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
180 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
181 Local<JSValueRef> rowsGapArg = runtimeCallInfo->GetCallArgRef(NUM_1);
182
183 CalcDimension rowGap;
184 std::string calcStr;
185 if (rowsGapArg->IsUndefined() || !ArkTSUtils::ParseJsDimensionVpNG(vm, rowsGapArg, rowGap)) {
186 GetArkUINodeModifiers()->getWaterFlowModifier()->resetRowsGap(nativeNode);
187 } else {
188 if (LessNotEqual(rowGap.Value(), DIMENSION_DEFAULT)) {
189 rowGap.SetValue(DIMENSION_DEFAULT);
190 }
191 if (rowGap.Unit() == DimensionUnit::CALC) {
192 GetArkUINodeModifiers()->getWaterFlowModifier()->setRowsGap(
193 nativeNode, 0, static_cast<int32_t>(rowGap.Unit()), rowGap.CalcValue().c_str());
194 } else {
195 GetArkUINodeModifiers()->getWaterFlowModifier()->setRowsGap(
196 nativeNode, rowGap.Value(), static_cast<int32_t>(rowGap.Unit()), calcStr.c_str());
197 }
198 }
199 return panda::JSValueRef::Undefined(vm);
200 }
201
SetItemConstraintSize(ArkUIRuntimeCallInfo * runtimeCallInfo)202 ArkUINativeModuleValue WaterFlowBridge::SetItemConstraintSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
203 {
204 EcmaVM* vm = runtimeCallInfo->GetVM();
205 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
206 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
207 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
208 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
209 Local<JSValueRef> minWidthValue = runtimeCallInfo->GetCallArgRef(NUM_1);
210 Local<JSValueRef> maxWidthValue = runtimeCallInfo->GetCallArgRef(NUM_2);
211 Local<JSValueRef> minHeightValue = runtimeCallInfo->GetCallArgRef(NUM_3);
212 Local<JSValueRef> maxHeightValue = runtimeCallInfo->GetCallArgRef(NUM_4);
213 CalcDimension minWidth;
214 CalcDimension maxWidth;
215 CalcDimension minHeight;
216 CalcDimension maxHeight;
217 std::string calcMinWidthStr;
218 std::string calcMaxWidthStr;
219 std::string calcMinHeightStr;
220 std::string calcMaxHeightStr;
221 if (minWidthValue->IsUndefined() || !ArkTSUtils::ParseJsDimensionVp(vm, minWidthValue, minWidth, false)) {
222 GetArkUINodeModifiers()->getWaterFlowModifier()->resetItemMinWidth(nativeNode);
223 } else {
224 SetItemConstraintSizeSendParams(minWidth, calcMinWidthStr);
225 GetArkUINodeModifiers()->getWaterFlowModifier()->setItemMinWidth(
226 nativeNode, minWidth.Value(), static_cast<int32_t>(minWidth.Unit()), calcMinWidthStr.c_str());
227 }
228 if (maxWidthValue->IsUndefined() || !ArkTSUtils::ParseJsDimensionVp(vm, maxWidthValue, maxWidth, false)) {
229 GetArkUINodeModifiers()->getWaterFlowModifier()->resetItemMaxWidth(nativeNode);
230 } else {
231 SetItemConstraintSizeSendParams(maxWidth, calcMaxWidthStr);
232 GetArkUINodeModifiers()->getWaterFlowModifier()->setItemMaxWidth(
233 nativeNode, maxWidth.Value(), static_cast<int32_t>(maxWidth.Unit()), calcMaxWidthStr.c_str());
234 }
235 if (minHeightValue->IsUndefined() || !ArkTSUtils::ParseJsDimensionVp(vm, minHeightValue, minHeight, false)) {
236 GetArkUINodeModifiers()->getWaterFlowModifier()->resetItemMinHeight(nativeNode);
237 } else {
238 SetItemConstraintSizeSendParams(minHeight, calcMinHeightStr);
239 GetArkUINodeModifiers()->getWaterFlowModifier()->setItemMinHeight(
240 nativeNode, minHeight.Value(), static_cast<int32_t>(minHeight.Unit()), calcMinHeightStr.c_str());
241 }
242 if (maxHeightValue->IsUndefined() || !ArkTSUtils::ParseJsDimensionVp(vm, maxHeightValue, maxHeight, false)) {
243 GetArkUINodeModifiers()->getWaterFlowModifier()->resetItemMaxHeight(nativeNode);
244 } else {
245 SetItemConstraintSizeSendParams(maxHeight, calcMaxHeightStr);
246 GetArkUINodeModifiers()->getWaterFlowModifier()->setItemMaxHeight(
247 nativeNode, maxHeight.Value(), static_cast<int32_t>(maxHeight.Unit()), calcMaxHeightStr.c_str());
248 }
249 return panda::JSValueRef::Undefined(vm);
250 }
251
ResetItemConstraintSize(ArkUIRuntimeCallInfo * runtimeCallInfo)252 ArkUINativeModuleValue WaterFlowBridge::ResetItemConstraintSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
253 {
254 EcmaVM* vm = runtimeCallInfo->GetVM();
255 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
256 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
257 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
258 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
259 GetArkUINodeModifiers()->getWaterFlowModifier()->resetItemMaxHeight(nativeNode);
260 GetArkUINodeModifiers()->getWaterFlowModifier()->resetItemMaxWidth(nativeNode);
261 GetArkUINodeModifiers()->getWaterFlowModifier()->resetItemMinHeight(nativeNode);
262 GetArkUINodeModifiers()->getWaterFlowModifier()->resetItemMinWidth(nativeNode);
263 return panda::JSValueRef::Undefined(vm);
264 }
265
SetLayoutDirection(ArkUIRuntimeCallInfo * runtimeCallInfo)266 ArkUINativeModuleValue WaterFlowBridge::SetLayoutDirection(ArkUIRuntimeCallInfo* runtimeCallInfo)
267 {
268 EcmaVM* vm = runtimeCallInfo->GetVM();
269 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
270 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
271 Local<JSValueRef> layoutDirectionArg = runtimeCallInfo->GetCallArgRef(NUM_1);
272 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
273 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
274 auto value = static_cast<int32_t>(FlexDirection::COLUMN);
275 if (!layoutDirectionArg->IsUndefined()) {
276 ArkTSUtils::ParseJsInteger(vm, layoutDirectionArg, value);
277 }
278 if (value >= NUM_0 && value < static_cast<int32_t>(LAYOUT_DIRECTION.size())) {
279 GetArkUINodeModifiers()->getWaterFlowModifier()->setLayoutDirection(nativeNode, value);
280 } else {
281 GetArkUINodeModifiers()->getWaterFlowModifier()->resetLayoutDirection(nativeNode);
282 }
283 return panda::JSValueRef::Undefined(vm);
284 }
285
ResetLayoutDirection(ArkUIRuntimeCallInfo * runtimeCallInfo)286 ArkUINativeModuleValue WaterFlowBridge::ResetLayoutDirection(ArkUIRuntimeCallInfo* runtimeCallInfo)
287 {
288 EcmaVM* vm = runtimeCallInfo->GetVM();
289 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
290 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
291 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
292 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
293 GetArkUINodeModifiers()->getWaterFlowModifier()->resetLayoutDirection(nativeNode);
294 return panda::JSValueRef::Undefined(vm);
295 }
296
SetNestedScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)297 ArkUINativeModuleValue WaterFlowBridge::SetNestedScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
298 {
299 EcmaVM* vm = runtimeCallInfo->GetVM();
300 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
301 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
302 Local<JSValueRef> scrollForwardValue = runtimeCallInfo->GetCallArgRef(NUM_1);
303 Local<JSValueRef> scrollBackwardValue = runtimeCallInfo->GetCallArgRef(NUM_2);
304 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
305 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
306 int32_t froward = NUM_0;
307 int32_t backward = NUM_0;
308 ArkTSUtils::ParseJsInteger(vm, scrollForwardValue, froward);
309 if (froward < static_cast<int32_t>(NestedScrollMode::SELF_ONLY) ||
310 froward > static_cast<int32_t>(NestedScrollMode::PARALLEL)) {
311 froward = NUM_0;
312 }
313 ArkTSUtils::ParseJsInteger(vm, scrollBackwardValue, backward);
314 if (backward < static_cast<int32_t>(NestedScrollMode::SELF_ONLY) ||
315 backward > static_cast<int32_t>(NestedScrollMode::PARALLEL)) {
316 backward = NUM_0;
317 }
318 GetArkUINodeModifiers()->getWaterFlowModifier()->setWaterFlowNestedScroll(nativeNode, froward, backward);
319 return panda::JSValueRef::Undefined(vm);
320 }
321
ResetNestedScroll(ArkUIRuntimeCallInfo * runtimeCallInfo)322 ArkUINativeModuleValue WaterFlowBridge::ResetNestedScroll(ArkUIRuntimeCallInfo* runtimeCallInfo)
323 {
324 EcmaVM* vm = runtimeCallInfo->GetVM();
325 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
326 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
327 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
328 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
329 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowNestedScroll(nativeNode);
330 return panda::JSValueRef::Undefined(vm);
331 }
332
SetFriction(ArkUIRuntimeCallInfo * runtimeCallInfo)333 ArkUINativeModuleValue WaterFlowBridge::SetFriction(ArkUIRuntimeCallInfo *runtimeCallInfo)
334 {
335 EcmaVM *vm = runtimeCallInfo->GetVM();
336 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
337 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
338 Local<JSValueRef> frictionArg = runtimeCallInfo->GetCallArgRef(NUM_1);
339 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
340 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
341 double friction = FRICTION_DEFAULT;
342 if (!ArkTSUtils::ParseJsDouble(vm, frictionArg, friction)) {
343 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowFriction(nativeNode);
344 } else {
345 GetArkUINodeModifiers()->getWaterFlowModifier()->setWaterFlowFriction(nativeNode,
346 static_cast<ArkUI_Float32>(friction));
347 }
348 return panda::JSValueRef::Undefined(vm);
349 }
350
ResetFriction(ArkUIRuntimeCallInfo * runtimeCallInfo)351 ArkUINativeModuleValue WaterFlowBridge::ResetFriction(ArkUIRuntimeCallInfo *runtimeCallInfo)
352 {
353 EcmaVM *vm = runtimeCallInfo->GetVM();
354 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
355 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
356 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
357 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
358 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowFriction(nativeNode);
359 return panda::JSValueRef::Undefined(vm);
360 }
361
SetScrollBar(ArkUIRuntimeCallInfo * runtimeCallInfo)362 ArkUINativeModuleValue WaterFlowBridge::SetScrollBar(ArkUIRuntimeCallInfo* runtimeCallInfo)
363 {
364 EcmaVM* vm = runtimeCallInfo->GetVM();
365 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
366 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
367 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
368 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
369 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
370 int32_t barState = 0;
371 if (!ArkTSUtils::ParseJsInteger(vm, secondArg, barState) || barState < 0 || barState >= DISPLAY_MODE_SIZE) {
372 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowScrollBar(nativeNode);
373 } else {
374 GetArkUINodeModifiers()->getWaterFlowModifier()->setWaterFlowScrollBar(nativeNode, barState);
375 }
376 return panda::JSValueRef::Undefined(vm);
377 }
378
ResetScrollBar(ArkUIRuntimeCallInfo * runtimeCallInfo)379 ArkUINativeModuleValue WaterFlowBridge::ResetScrollBar(ArkUIRuntimeCallInfo* runtimeCallInfo)
380 {
381 EcmaVM* vm = runtimeCallInfo->GetVM();
382 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
383 Local<JSValueRef> argNode = runtimeCallInfo->GetCallArgRef(NUM_0);
384 CHECK_NULL_RETURN(argNode->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
385 auto nativeNode = nodePtr(argNode->ToNativePointer(vm)->Value());
386 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowScrollBar(nativeNode);
387 return panda::JSValueRef::Undefined(vm);
388 }
389
SetScrollBarWidth(ArkUIRuntimeCallInfo * runtimeCallInfo)390 ArkUINativeModuleValue WaterFlowBridge::SetScrollBarWidth(ArkUIRuntimeCallInfo* runtimeCallInfo)
391 {
392 EcmaVM* vm = runtimeCallInfo->GetVM();
393 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
394 Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
395 Local<JSValueRef> scrollBarArg = runtimeCallInfo->GetCallArgRef(NUM_1);
396 CHECK_NULL_RETURN(nativeNodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
397 auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
398
399 CalcDimension scrollBarWidth;
400 if (!ArkTSUtils::ParseJsDimension(vm, scrollBarArg, scrollBarWidth, DimensionUnit::VP) || scrollBarArg->IsNull() ||
401 scrollBarArg->IsUndefined() || (scrollBarArg->IsString(vm) && scrollBarWidth.ToString().empty()) ||
402 LessNotEqual(scrollBarWidth.Value(), 0.0) || scrollBarWidth.Unit() == DimensionUnit::PERCENT) {
403 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowScrollBarWidth(nativeNode);
404 } else {
405 GetArkUINodeModifiers()->getWaterFlowModifier()->setWaterFlowScrollBarWidth(
406 nativeNode, scrollBarWidth.ToString().c_str());
407 }
408 return panda::JSValueRef::Undefined(vm);
409 }
410
ResetScrollBarWidth(ArkUIRuntimeCallInfo * runtimeCallInfo)411 ArkUINativeModuleValue WaterFlowBridge::ResetScrollBarWidth(ArkUIRuntimeCallInfo* runtimeCallInfo)
412 {
413 EcmaVM* vm = runtimeCallInfo->GetVM();
414 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
415 Local<JSValueRef> argNode = runtimeCallInfo->GetCallArgRef(NUM_0);
416 CHECK_NULL_RETURN(argNode->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
417 auto nativeNode = nodePtr(argNode->ToNativePointer(vm)->Value());
418 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowScrollBarWidth(nativeNode);
419 return panda::JSValueRef::Undefined(vm);
420 }
421
SetScrollBarColor(ArkUIRuntimeCallInfo * runtimeCallInfo)422 ArkUINativeModuleValue WaterFlowBridge::SetScrollBarColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
423 {
424 EcmaVM* vm = runtimeCallInfo->GetVM();
425 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
426 Local<JSValueRef> argNode = runtimeCallInfo->GetCallArgRef(NUM_0);
427 Local<JSValueRef> argColor = runtimeCallInfo->GetCallArgRef(NUM_1);
428 CHECK_NULL_RETURN(argNode->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
429 auto nativeNode = nodePtr(argNode->ToNativePointer(vm)->Value());
430 std::string color = "";
431 if (!ArkTSUtils::ParseJsString(vm, argColor, color) || argColor->IsUndefined() || color.empty()) {
432 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowScrollBarColor(nativeNode);
433 } else {
434 GetArkUINodeModifiers()->getWaterFlowModifier()->setWaterFlowScrollBarColor(nativeNode, color.c_str());
435 }
436 return panda::JSValueRef::Undefined(vm);
437 }
438
ResetScrollBarColor(ArkUIRuntimeCallInfo * runtimeCallInfo)439 ArkUINativeModuleValue WaterFlowBridge::ResetScrollBarColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
440 {
441 EcmaVM* vm = runtimeCallInfo->GetVM();
442 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
443 Local<JSValueRef> argNode = runtimeCallInfo->GetCallArgRef(NUM_0);
444 CHECK_NULL_RETURN(argNode->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
445 auto nativeNode = nodePtr(argNode->ToNativePointer(vm)->Value());
446 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowScrollBarColor(nativeNode);
447 return panda::JSValueRef::Undefined(vm);
448 }
449
SetCachedCount(ArkUIRuntimeCallInfo * runtimeCallInfo)450 ArkUINativeModuleValue WaterFlowBridge::SetCachedCount(ArkUIRuntimeCallInfo* runtimeCallInfo)
451 {
452 EcmaVM* vm = runtimeCallInfo->GetVM();
453 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
454 Local<JSValueRef> argNode = runtimeCallInfo->GetCallArgRef(NUM_0);
455 Local<JSValueRef> argCachedCount = runtimeCallInfo->GetCallArgRef(NUM_1);
456 Local<JSValueRef> argShow = runtimeCallInfo->GetCallArgRef(NUM_2);
457 CHECK_NULL_RETURN(argNode->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
458 auto* nativeNode = nodePtr(argNode->ToNativePointer(vm)->Value());
459 int32_t cachedCount = 0;
460 if (!ArkTSUtils::ParseJsInteger(vm, argCachedCount, cachedCount) || cachedCount < 0) {
461 GetArkUINodeModifiers()->getWaterFlowModifier()->resetCachedCount(nativeNode);
462 } else {
463 GetArkUINodeModifiers()->getWaterFlowModifier()->setCachedCount(nativeNode, cachedCount);
464 }
465
466 bool show = !argShow.IsNull() && argShow->IsTrue();
467 GetArkUINodeModifiers()->getWaterFlowModifier()->setShowCached(nativeNode, show);
468 return panda::JSValueRef::Undefined(vm);
469 }
470
ResetCachedCount(ArkUIRuntimeCallInfo * runtimeCallInfo)471 ArkUINativeModuleValue WaterFlowBridge::ResetCachedCount(ArkUIRuntimeCallInfo* runtimeCallInfo)
472 {
473 EcmaVM* vm = runtimeCallInfo->GetVM();
474 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
475 Local<JSValueRef> argNode = runtimeCallInfo->GetCallArgRef(NUM_0);
476 CHECK_NULL_RETURN(argNode->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
477 auto nativeNode = nodePtr(argNode->ToNativePointer(vm)->Value());
478 GetArkUINodeModifiers()->getWaterFlowModifier()->resetCachedCount(nativeNode);
479 GetArkUINodeModifiers()->getWaterFlowModifier()->resetShowCached(nativeNode);
480 return panda::JSValueRef::Undefined(vm);
481 }
482
SetWaterFlowScroller(ArkUIRuntimeCallInfo * runtimeCallInfo)483 void SetWaterFlowScroller(ArkUIRuntimeCallInfo* runtimeCallInfo)
484 {
485 EcmaVM* vm = runtimeCallInfo->GetVM();
486 CHECK_NULL_VOID(vm);
487 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
488 CHECK_NULL_VOID(nodeArg->IsNativePointer(vm));
489 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
490
491 Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
492 if (!info[1]->IsNull() && info[1]->IsObject()) {
493 Framework::JSScroller* jsScroller =
494 Framework::JSRef<Framework::JSObject>::Cast(info[1])->Unwrap<Framework::JSScroller>();
495 if (jsScroller) {
496 jsScroller->SetInstanceId(Container::CurrentId());
497 auto positionController = GetArkUINodeModifiers()->getWaterFlowModifier()->getScrollController(nativeNode);
498 auto nodePositionController =
499 AceType::Claim(reinterpret_cast<OHOS::Ace::ScrollControllerBase*>(positionController));
500 jsScroller->SetController(nodePositionController);
501 // Init scroll bar proxy.
502 auto proxy = jsScroller->GetScrollBarProxy();
503 if (!proxy) {
504 proxy = WaterFlowModel::GetInstance()->CreateScrollBarProxy();
505 jsScroller->SetScrollBarProxy(proxy);
506 }
507 auto proxyPtr = reinterpret_cast<ArkUINodeHandle>(AceType::RawPtr(proxy));
508 GetArkUINodeModifiers()->getWaterFlowModifier()->setWaterFlowScroller(
509 nativeNode, positionController, proxyPtr);
510 }
511 } else {
512 auto positionController = AceType::MakeRefPtr<ScrollableController>();
513 auto controller = reinterpret_cast<ArkUINodeHandle>(AceType::RawPtr(positionController));
514 auto proxy = WaterFlowModel::GetInstance()->CreateScrollBarProxy();
515 auto proxyPtr = reinterpret_cast<ArkUINodeHandle>(AceType::RawPtr(proxy));
516 GetArkUINodeModifiers()->getWaterFlowModifier()->setWaterFlowScroller(
517 nativeNode, controller, proxyPtr);
518 }
519 }
520
SetWaterFlowSections(ArkUIRuntimeCallInfo * runtimeCallInfo)521 void SetWaterFlowSections(ArkUIRuntimeCallInfo* runtimeCallInfo)
522 {
523 EcmaVM* vm = runtimeCallInfo->GetVM();
524 CHECK_NULL_VOID(vm);
525 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
526 CHECK_NULL_VOID(nodeArg->IsNativePointer(vm));
527 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
528 Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
529 Framework::JSRef<Framework::JSVal> sectionsArgs = info[2]; //2 is the index of sections
530 if (!sectionsArgs->IsNull() && sectionsArgs->IsObject()) {
531 auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
532 Framework::JSWaterFlow::UpdateWaterFlowSectionsByFrameNode(frameNode, info, sectionsArgs);
533 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterflowFooter(nativeNode);
534 } else {
535 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowSections(nativeNode);
536 }
537 }
538
SetWaterFlowFooter(ArkUIRuntimeCallInfo * runtimeCallInfo)539 void SetWaterFlowFooter(ArkUIRuntimeCallInfo* runtimeCallInfo)
540 {
541 EcmaVM* vm = runtimeCallInfo->GetVM();
542 CHECK_NULL_VOID(vm);
543 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
544 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
545 Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
546 Framework::JSRef<Framework::JSVal> footerContentArgs = info[4]; // 4 is the index of footerContent
547 auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
548 if (!footerContentArgs->IsNull() && footerContentArgs->IsObject()) {
549 Framework::JSWaterFlow::UpdateWaterFlowFooter(frameNode, footerContentArgs);
550 }
551 }
552
SetWaterFlowInitialize(ArkUIRuntimeCallInfo * runtimeCallInfo)553 ArkUINativeModuleValue WaterFlowBridge::SetWaterFlowInitialize(ArkUIRuntimeCallInfo* runtimeCallInfo)
554 {
555 EcmaVM* vm = runtimeCallInfo->GetVM();
556 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
557 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
558 Local<JSValueRef> layoutModeArgs = runtimeCallInfo->GetCallArgRef(3); //3 is the index of layoutMode
559 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
560 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
561
562 SetWaterFlowScroller(runtimeCallInfo);
563
564 if (layoutModeArgs->IsUndefined() || layoutModeArgs->IsNull() || !layoutModeArgs->IsNumber()) {
565 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowLayoutMode(nativeNode);
566 SetWaterFlowFooter(runtimeCallInfo);
567 SetWaterFlowSections(runtimeCallInfo);
568 } else {
569 uint32_t layoutMode = layoutModeArgs->Uint32Value(vm);
570 if (layoutMode < static_cast<uint32_t>(NG::WaterFlowLayoutMode::TOP_DOWN) ||
571 layoutMode > static_cast<uint32_t>(NG::WaterFlowLayoutMode::SLIDING_WINDOW)) {
572 layoutMode = static_cast<uint32_t>(NG::WaterFlowLayoutMode::TOP_DOWN);
573 }
574 GetArkUINodeModifiers()->getWaterFlowModifier()->setWaterFlowLayoutMode(nativeNode, layoutMode);
575 if (layoutMode != static_cast<uint32_t>(NG::WaterFlowLayoutMode::SLIDING_WINDOW)) {
576 SetWaterFlowFooter(runtimeCallInfo);
577 SetWaterFlowSections(runtimeCallInfo);
578 }
579 }
580
581 return panda::JSValueRef::Undefined(vm);
582 }
583
ResetWaterFlowInitialize(ArkUIRuntimeCallInfo * runtimeCallInfo)584 ArkUINativeModuleValue WaterFlowBridge::ResetWaterFlowInitialize(ArkUIRuntimeCallInfo* runtimeCallInfo)
585 {
586 EcmaVM* vm = runtimeCallInfo->GetVM();
587 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
588 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
589 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
590 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
591
592 auto positionController = AceType::MakeRefPtr<ScrollableController>();
593 auto controller = reinterpret_cast<ArkUINodeHandle>(AceType::RawPtr(positionController));
594 auto proxy = WaterFlowModel::GetInstance()->CreateScrollBarProxy();
595 auto proxyPtr = reinterpret_cast<ArkUINodeHandle>(OHOS::Ace::AceType::RawPtr(proxy));
596 GetArkUINodeModifiers()->getWaterFlowModifier()->setWaterFlowScroller(
597 nativeNode, controller, proxyPtr);
598 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowSections(nativeNode);
599 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterFlowLayoutMode(nativeNode);
600 GetArkUINodeModifiers()->getWaterFlowModifier()->resetWaterflowFooter(nativeNode);
601 return panda::JSValueRef::Undefined(vm);
602 }
603
SetOnWaterFlowScrollIndex(ArkUIRuntimeCallInfo * runtimeCallInfo)604 ArkUINativeModuleValue WaterFlowBridge::SetOnWaterFlowScrollIndex(ArkUIRuntimeCallInfo* runtimeCallInfo)
605 {
606 EcmaVM* vm = runtimeCallInfo->GetVM();
607 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
608 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
609 Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
610 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
611 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
612 if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
613 GetArkUINodeModifiers()->getWaterFlowModifier()->resetOnWaterFlowScrollIndex(nativeNode);
614 return panda::JSValueRef::Undefined(vm);
615 }
616 auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
617 CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
618 panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
619
620 std::function<void(int32_t, int32_t)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
621 const int32_t first, const int32_t last) {
622 panda::LocalScope pandaScope(vm);
623 panda::TryCatch trycatch(vm);
624 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
625
626 panda::Local<panda::NumberRef> firstParam = panda::NumberRef::New(vm, first);
627 panda::Local<panda::NumberRef> lastParam = panda::NumberRef::New(vm, last);
628 // 2: Array length
629 panda::Local<panda::JSValueRef> params[2] = { firstParam, lastParam };
630 func->Call(vm, func.ToLocal(), params, 2); // 2: Array length
631 };
632 GetArkUINodeModifiers()->getWaterFlowModifier()->setOnWaterFlowScrollIndexCallBack(
633 nativeNode, reinterpret_cast<void*>(&callback));
634 return panda::JSValueRef::Undefined(vm);
635 }
636
ResetOnWaterFlowScrollIndex(ArkUIRuntimeCallInfo * runtimeCallInfo)637 ArkUINativeModuleValue WaterFlowBridge::ResetOnWaterFlowScrollIndex(ArkUIRuntimeCallInfo* runtimeCallInfo)
638 {
639 EcmaVM* vm = runtimeCallInfo->GetVM();
640 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
641 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
642 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
643 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
644 GetArkUINodeModifiers()->getWaterFlowModifier()->resetOnWaterFlowScrollIndex(nativeNode);
645 return panda::JSValueRef::Undefined(vm);
646 }
647 } // namespace OHOS::Ace::NG