1 /*
2  * Copyright (c) 2022 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_COMPONENTS_NG_PROPERTIES_BORDER_PROPERTY_H
17 #define FOUNDATION_ACE_FRAMEWORKS_COMPONENTS_NG_PROPERTIES_BORDER_PROPERTY_H
18 
19 #include <optional>
20 
21 #include "base/geometry/dimension.h"
22 #include "base/json/json_util.h"
23 #include "core/components/common/layout/constants.h"
24 #include "core/components/common/properties/color.h"
25 
26 namespace OHOS::Ace::NG {
27 class InspectorFilter;
28 
29 template<typename T>
30 struct BorderRadiusPropertyT {
31     std::optional<T> radiusTopLeft;
32     std::optional<T> radiusTopRight;
33     std::optional<T> radiusBottomRight;
34     std::optional<T> radiusBottomLeft;
35 
SetRadiusBorderRadiusPropertyT36     void SetRadius(const T& borderRadius)
37     {
38         radiusTopLeft = borderRadius;
39         radiusTopRight = borderRadius;
40         radiusBottomLeft = borderRadius;
41         radiusBottomRight = borderRadius;
42     }
43 
44     bool operator==(const BorderRadiusPropertyT& value) const
45     {
46         return (radiusTopLeft == value.radiusTopLeft) && (radiusTopRight == value.radiusTopRight) &&
47                (radiusBottomLeft == value.radiusBottomLeft) && (radiusBottomRight == value.radiusBottomRight);
48     }
49 
UpdateWithCheckBorderRadiusPropertyT50     bool UpdateWithCheck(const BorderRadiusPropertyT& value)
51     {
52         bool isModified = false;
53         if (value.radiusTopLeft.has_value() && (radiusTopLeft != value.radiusTopLeft)) {
54             radiusTopLeft = value.radiusTopLeft;
55             isModified = true;
56         }
57         if (value.radiusTopRight.has_value() && (radiusTopRight != value.radiusTopRight)) {
58             radiusTopRight = value.radiusTopRight;
59             isModified = true;
60         }
61         if (value.radiusBottomLeft.has_value() && (radiusBottomLeft != value.radiusBottomLeft)) {
62             radiusBottomLeft = value.radiusBottomLeft;
63             isModified = true;
64         }
65         if (value.radiusBottomRight.has_value() && (radiusBottomRight != value.radiusBottomRight)) {
66             radiusBottomRight = value.radiusBottomRight;
67             isModified = true;
68         }
69         return isModified;
70     }
71 
ToStringBorderRadiusPropertyT72     std::string ToString() const
73     {
74         std::string str;
75         str.append("radiusTopLeft: [").append(radiusTopLeft.has_value() ? radiusTopLeft->ToString() : "NA").append("]");
76         str.append("radiusTopRight: [")
77             .append(radiusTopRight.has_value() ? radiusTopRight->ToString() : "NA")
78             .append("]");
79         str.append("radiusBottomLeft: [")
80             .append(radiusBottomLeft.has_value() ? radiusBottomLeft->ToString() : "NA")
81             .append("]");
82         str.append("radiusBottomRight: [")
83             .append(radiusBottomRight.has_value() ? radiusBottomRight->ToString() : "NA")
84             .append("]");
85         return str;
86     }
87 };
88 
89 template<>
90 struct BorderRadiusPropertyT<Dimension> {
91     std::optional<Dimension> radiusTopLeft;
92     std::optional<Dimension> radiusTopRight;
93     std::optional<Dimension> radiusBottomRight;
94     std::optional<Dimension> radiusBottomLeft;
95     std::optional<Dimension> radiusTopStart;
96     std::optional<Dimension> radiusTopEnd;
97     std::optional<Dimension> radiusBottomEnd;
98     std::optional<Dimension> radiusBottomStart;
99     bool multiValued = true;
100 
101     BorderRadiusPropertyT<Dimension>() = default;
102     explicit BorderRadiusPropertyT<Dimension>(Dimension radius)
103         : radiusTopLeft(radius), radiusTopRight(radius), radiusBottomRight(radius), radiusBottomLeft(radius)
104     {}
105     BorderRadiusPropertyT<Dimension>(
106         Dimension radiusTopLeft, Dimension radiusTopRight, Dimension radiusBottomRight, Dimension radiusBottomLeft)
107         : radiusTopLeft(radiusTopLeft), radiusTopRight(radiusTopRight), radiusBottomRight(radiusBottomRight),
108           radiusBottomLeft(radiusBottomLeft)
109     {}
110 
111     bool operator==(const BorderRadiusPropertyT<Dimension>& value) const;
112 
113     void SetRadius(const Dimension& borderRadius);
114 
115     bool UpdateWithCheck(const BorderRadiusPropertyT<Dimension>& value);
116 
117     void ToJsonValue(std::unique_ptr<JsonValue>& json, std::unique_ptr<JsonValue>& borderJson,
118         const InspectorFilter& filter, bool isOutline = false) const;
119 
120     std::string ToString() const
121     {
122         std::string str;
123         str.append("radiusTopLeft: [").append(radiusTopLeft.has_value() ? radiusTopLeft->ToString() : "NA").append("]");
124         str.append("radiusTopRight: [")
125             .append(radiusTopRight.has_value() ? radiusTopRight->ToString() : "NA")
126             .append("]");
127         str.append("radiusBottomLeft: [")
128             .append(radiusBottomLeft.has_value() ? radiusBottomLeft->ToString() : "NA")
129             .append("]");
130         str.append("radiusBottomRight: [")
131             .append(radiusBottomRight.has_value() ? radiusBottomRight->ToString() : "NA")
132             .append("]");
133         return str;
134     }
135 };
136 
137 template<>
138 struct BorderRadiusPropertyT<float> {
139     std::optional<float> radiusTopLeft;
140     std::optional<float> radiusTopRight;
141     std::optional<float> radiusBottomRight;
142     std::optional<float> radiusBottomLeft;
143 
144     bool operator==(const BorderRadiusPropertyT<float>& value) const
145     {
146         if (radiusTopLeft.has_value() ^ value.radiusTopLeft.has_value()) {
147             return false;
148         }
149         if (!NearEqual(radiusTopLeft.value_or(0), value.radiusTopLeft.value_or(0))) {
150             return false;
151         }
152         if (radiusTopRight.has_value() ^ value.radiusTopRight.has_value()) {
153             return false;
154         }
155         if (!NearEqual(radiusTopRight.value_or(0), value.radiusTopRight.value_or(0))) {
156             return false;
157         }
158         if (radiusBottomLeft.has_value() ^ value.radiusBottomLeft.has_value()) {
159             return false;
160         }
161         if (!NearEqual(radiusBottomLeft.value_or(0), value.radiusBottomLeft.value_or(0))) {
162             return false;
163         }
164         if (radiusBottomRight.has_value() ^ value.radiusBottomRight.has_value()) {
165             return false;
166         }
167         if (!NearEqual(radiusBottomRight.value_or(0), value.radiusBottomRight.value_or(0))) {
168             return false;
169         }
170         return true;
171     }
172 
173     std::string ToString() const
174     {
175         std::string str;
176         str.append("radiusTopLeft: [")
177             .append(radiusTopLeft.has_value() ? std::to_string(radiusTopLeft.value()) : "NA")
178             .append("]");
179         str.append("radiusTopRight: [")
180             .append(radiusTopRight.has_value() ? std::to_string(radiusTopRight.value()) : "NA")
181             .append("]");
182         str.append("radiusBottomLeft: [")
183             .append(radiusBottomLeft.has_value() ? std::to_string(radiusBottomLeft.value()) : "NA")
184             .append("]");
185         str.append("radiusBottomRight: [")
186             .append(radiusBottomRight.has_value() ? std::to_string(radiusBottomRight.value()) : "NA")
187             .append("]");
188         return str;
189     }
190 };
191 
192 struct BorderColorProperty {
193     std::optional<Color> leftColor;
194     std::optional<Color> rightColor;
195     std::optional<Color> topColor;
196     std::optional<Color> bottomColor;
197     std::optional<Color> startColor;
198     std::optional<Color> endColor;
199     bool multiValued = false;
200 
201     void SetColor(const Color& borderColor)
202     {
203         leftColor = borderColor;
204         rightColor = borderColor;
205         topColor = borderColor;
206         bottomColor = borderColor;
207     }
208 
209     bool operator==(const BorderColorProperty& value) const
210     {
211         return (leftColor == value.leftColor) && (rightColor == value.rightColor) && (topColor == value.topColor) &&
212                (bottomColor == value.bottomColor);
213     }
214 
215     std::string ToString() const;
216 
217     void ToJsonValue(std::unique_ptr<JsonValue>& json, std::unique_ptr<JsonValue>& borderJson,
218         const InspectorFilter& filter, bool isOutline = false) const;
219 };
220 
221 template<typename T>
222 struct BorderWidthPropertyT {
223     std::optional<T> leftDimen;
224     std::optional<T> topDimen;
225     std::optional<T> rightDimen;
226     std::optional<T> bottomDimen;
227 
228     void SetBorderWidth(const T& borderWidth)
229     {
230         leftDimen = borderWidth;
231         rightDimen = borderWidth;
232         topDimen = borderWidth;
233         bottomDimen = borderWidth;
234     }
235 
236     bool operator==(const BorderWidthPropertyT& value) const
237     {
238         return (leftDimen == value.leftDimen) && (rightDimen == value.rightDimen) && (topDimen == value.topDimen) &&
239                (bottomDimen == value.bottomDimen);
240     }
241 
242     bool UpdateWithCheck(const BorderWidthPropertyT& value)
243     {
244         bool isModified = false;
245         if (value.leftDimen.has_value() && (leftDimen != value.leftDimen)) {
246             leftDimen = value.leftDimen;
247             isModified = true;
248         }
249         if (value.rightDimen.has_value() && (rightDimen != value.rightDimen)) {
250             rightDimen = value.rightDimen;
251             isModified = true;
252         }
253         if (value.topDimen.has_value() && (topDimen != value.topDimen)) {
254             topDimen = value.topDimen;
255             isModified = true;
256         }
257         if (value.bottomDimen.has_value() && (bottomDimen != value.bottomDimen)) {
258             bottomDimen = value.bottomDimen;
259             isModified = true;
260         }
261         return isModified;
262     }
263 };
264 
265 template<>
266 struct BorderWidthPropertyT<Dimension> {
267     std::optional<Dimension> leftDimen;
268     std::optional<Dimension> topDimen;
269     std::optional<Dimension> rightDimen;
270     std::optional<Dimension> bottomDimen;
271     std::optional<Dimension> startDimen;
272     std::optional<Dimension> endDimen;
273     bool multiValued = false;
274 
275     void SetBorderWidth(const Dimension& borderWidth);
276 
277     bool operator==(const BorderWidthPropertyT& value) const;
278 
279     bool UpdateWithCheck(const BorderWidthPropertyT& value);
280 
281     void ToJsonValue(std::unique_ptr<JsonValue>& json, std::unique_ptr<JsonValue>& borderJson,
282         const InspectorFilter& filter, bool isOutline = false) const;
283 
284     void ToDashJsonValue(std::unique_ptr<JsonValue>& json, std::unique_ptr<JsonValue>& borderJson,
285         const InspectorFilter& filter, const std::string& keyValue) const;
286 
287     std::string ToString() const;
288 };
289 
290 template<>
291 struct BorderWidthPropertyT<float> {
292     std::optional<float> leftDimen;
293     std::optional<float> topDimen;
294     std::optional<float> rightDimen;
295     std::optional<float> bottomDimen;
296 
297     bool operator==(const BorderWidthPropertyT<float>& value) const
298     {
299         if (leftDimen.has_value() ^ value.leftDimen.has_value()) {
300             return false;
301         }
302         if (!NearEqual(leftDimen.value_or(0), value.leftDimen.value_or(0))) {
303             return false;
304         }
305         if (rightDimen.has_value() ^ value.rightDimen.has_value()) {
306             return false;
307         }
308         if (!NearEqual(rightDimen.value_or(0), value.rightDimen.value_or(0))) {
309             return false;
310         }
311         if (topDimen.has_value() ^ value.topDimen.has_value()) {
312             return false;
313         }
314         if (!NearEqual(topDimen.value_or(0), value.topDimen.value_or(0))) {
315             return false;
316         }
317         if (bottomDimen.has_value() ^ value.bottomDimen.has_value()) {
318             return false;
319         }
320         if (!NearEqual(bottomDimen.value_or(0), value.bottomDimen.value_or(0))) {
321             return false;
322         }
323         return true;
324     }
325 
326     std::string ToString() const
327     {
328         std::string str;
329         str.append("[").append(leftDimen.has_value() ? std::to_string(leftDimen.value()) : "NA");
330         str.append(",").append(rightDimen.has_value() ? std::to_string(rightDimen.value()) : "NA");
331         str.append(",").append(topDimen.has_value() ? std::to_string(topDimen.value()) : "NA");
332         str.append(",")
333             .append(bottomDimen.has_value() ? std::to_string(bottomDimen.value()) : "NA")
334             .append("]");
335         return str;
336     }
337 };
338 
339 struct BorderStyleProperty {
340     std::optional<BorderStyle> styleLeft;
341     std::optional<BorderStyle> styleRight;
342     std::optional<BorderStyle> styleTop;
343     std::optional<BorderStyle> styleBottom;
344     bool multiValued = false;
345 
346     void SetBorderStyle(const BorderStyle& borderStyle);
347 
348     bool operator==(const BorderStyleProperty& value) const;
349 
350     void ToJsonValue(std::unique_ptr<JsonValue>& json, std::unique_ptr<JsonValue>& borderJson,
351         const InspectorFilter& filter, bool isOutline = false) const;
352 };
353 
354 using BorderRadiusPropertyF = BorderRadiusPropertyT<float>;
355 using BorderRadiusProperty = BorderRadiusPropertyT<Dimension>;
356 using BorderWidthPropertyF = BorderWidthPropertyT<float>;
357 using BorderWidthProperty = BorderWidthPropertyT<Dimension>;
358 
359 } // namespace OHOS::Ace::NG
360 
361 #endif // FOUNDATION_ACE_FRAMEWORKS_COMPONENTS_NG_PROPERTIES_BORDER_PROPERTY_H
362