1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "bridge/declarative_frontend/jsview/js_water_flow_sections.h"
17
18 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
19 #include "core/components_ng/pattern/waterflow/water_flow_sections.h"
20
21 namespace OHOS::Ace::Framework {
SetMarginProperty(const JSRef<JSObject> & paddingObj,NG::MarginProperty & margin)22 bool SetMarginProperty(const JSRef<JSObject>& paddingObj, NG::MarginProperty& margin)
23 {
24 std::optional<CalcDimension> left;
25 std::optional<CalcDimension> right;
26 std::optional<CalcDimension> top;
27 std::optional<CalcDimension> bottom;
28 JSViewAbstract::ParseMarginOrPaddingCorner(paddingObj, top, bottom, left, right);
29 bool isMarginObject = false;
30 if (top.has_value()) {
31 if (top.value().Unit() == DimensionUnit::CALC) {
32 margin.top = NG::CalcLength(top.value().CalcValue());
33 } else {
34 margin.top = NG::CalcLength(top.value());
35 }
36 isMarginObject = true;
37 }
38 if (bottom.has_value()) {
39 if (bottom.value().Unit() == DimensionUnit::CALC) {
40 margin.bottom = NG::CalcLength(bottom.value().CalcValue());
41 } else {
42 margin.bottom = NG::CalcLength(bottom.value());
43 }
44 isMarginObject = true;
45 }
46 if (left.has_value()) {
47 if (left.value().Unit() == DimensionUnit::CALC) {
48 margin.left = NG::CalcLength(left.value().CalcValue());
49 } else {
50 margin.left = NG::CalcLength(left.value());
51 }
52 isMarginObject = true;
53 }
54 if (right.has_value()) {
55 if (right.value().Unit() == DimensionUnit::CALC) {
56 margin.right = NG::CalcLength(right.value().CalcValue());
57 } else {
58 margin.right = NG::CalcLength(right.value());
59 }
60 isMarginObject = true;
61 }
62 return isMarginObject;
63 }
64
ParseMargin(const JSRef<JSVal> & jsValue,NG::MarginProperty & margin)65 void ParseMargin(const JSRef<JSVal>& jsValue, NG::MarginProperty& margin)
66 {
67 if (jsValue->IsObject()) {
68 auto marginObj = JSRef<JSObject>::Cast(jsValue);
69 if (SetMarginProperty(marginObj, margin)) {
70 return;
71 }
72 }
73
74 CalcDimension length;
75 if (!JSViewAbstract::ParseJsDimensionVp(jsValue, length)) {
76 length.Reset();
77 }
78 if (length.Unit() == DimensionUnit::CALC) {
79 margin.SetEdges(NG::CalcLength(length.CalcValue()));
80 } else {
81 margin.SetEdges(NG::CalcLength(length));
82 }
83 }
84
85 namespace {
ParseGaps(const JSRef<JSObject> & obj,NG::WaterFlowSections::Section & section)86 void ParseGaps(const JSRef<JSObject>& obj, NG::WaterFlowSections::Section& section)
87 {
88 if (obj->HasProperty("columnsGap")) {
89 auto columnsGap = obj->GetProperty("columnsGap");
90 CalcDimension colGap;
91 if (!JSViewAbstract::ParseJsDimensionVp(columnsGap, colGap) || colGap.Value() < 0) {
92 colGap.SetValue(0.0);
93 }
94 section.columnsGap = colGap;
95 }
96
97 if (obj->HasProperty("rowsGap")) {
98 auto rowsGap = obj->GetProperty("rowsGap");
99 CalcDimension rowGap;
100 if (!JSViewAbstract::ParseJsDimensionVp(rowsGap, rowGap) || rowGap.Value() < 0) {
101 rowGap.SetValue(0.0);
102 }
103 section.rowsGap = rowGap;
104 }
105
106 if (obj->HasProperty("margin")) {
107 auto margin = obj->GetProperty("margin");
108 NG::MarginProperty marginProperty;
109 ParseMargin(margin, marginProperty);
110 section.margin = marginProperty;
111 }
112 }
113 } // namespace
114
ParseSectionOptions(const JSCallbackInfo & args,const JSRef<JSVal> & jsValue,NG::WaterFlowSections::Section & section)115 bool JSWaterFlowSections::ParseSectionOptions(
116 const JSCallbackInfo& args, const JSRef<JSVal>& jsValue, NG::WaterFlowSections::Section& section)
117 {
118 if (!jsValue->IsObject()) {
119 LOGW("The arg must be object");
120 return false;
121 }
122
123 JSRef<JSObject> obj = JSRef<JSObject>::Cast(jsValue);
124 if (!obj->HasProperty("itemsCount")) {
125 return false;
126 }
127 auto itemsCount = obj->GetProperty("itemsCount");
128 JSViewAbstract::ParseJsInteger(itemsCount, section.itemsCount);
129 if (section.itemsCount < 0) {
130 LOGW("itemsCount can not be less than 0");
131 return false;
132 }
133
134 if (obj->HasProperty("crossCount")) {
135 auto crossCount = obj->GetProperty("crossCount");
136 int32_t crossCountValue = 1;
137 JSViewAbstract::ParseJsInteger(crossCount, crossCountValue);
138 if (crossCountValue <= 0) {
139 crossCountValue = 1;
140 }
141 section.crossCount = crossCountValue;
142 }
143
144 ParseGaps(obj, section);
145
146 if (!obj->HasProperty("onGetItemMainSizeByIndex")) {
147 return true;
148 }
149 auto getSizeByIndex = obj->GetProperty("onGetItemMainSizeByIndex");
150 if (!getSizeByIndex->IsFunction()) {
151 return true;
152 }
153
154 auto onGetItemMainSizeByIndex = [execCtx = args.GetExecutionContext(),
155 func = AceType::MakeRefPtr<JsFunction>(
156 JSRef<JSObject>(), JSRef<JSFunc>::Cast(getSizeByIndex))](int32_t index) {
157 JSRef<JSVal> itemIndex = JSRef<JSVal>::Make(ToJSValue(index));
158 auto result = func->ExecuteJS(1, &itemIndex);
159 if (!result->IsNumber()) {
160 return 0.0f;
161 }
162
163 return result->ToNumber<float>();
164 };
165 section.onGetItemMainSizeByIndex = std::move(onGetItemMainSizeByIndex);
166 return true;
167 }
168 } // namespace OHOS::Ace::Framework
169