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