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