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 "core/interfaces/native/node/gauge_modifier.h"
16 #include "core/pipeline/base/element_register.h"
17 #include "core/components_ng/base/frame_node.h"
18 #include "core/components_ng/pattern/gauge/gauge_model_ng.h"
19 #include "core/components/common/layout/constants.h"
20 
21 namespace OHOS::Ace::NG {
22 constexpr float MIN_VALUE = 0.0f;
23 constexpr float DEFAULT_START_ANGLE = 0.0f;
24 constexpr float DEFAULT_END_ANGLE = 360.0f;
25 constexpr int32_t DEFAULT_STROKE_WIDTH = 4;
26 
SetGaugeValue(ArkUINodeHandle node,ArkUI_Float32 value)27 void SetGaugeValue(ArkUINodeHandle node, ArkUI_Float32 value)
28 {
29     auto* frameNode = reinterpret_cast<FrameNode*>(node);
30     CHECK_NULL_VOID(frameNode);
31     GaugeModelNG::SetValue(frameNode, value);
32 }
33 
ResetGaugeValue(ArkUINodeHandle node)34 void ResetGaugeValue(ArkUINodeHandle node)
35 {
36     auto* frameNode = reinterpret_cast<FrameNode*>(node);
37     CHECK_NULL_VOID(frameNode);
38     GaugeModelNG::SetValue(frameNode, MIN_VALUE);
39 }
40 
SetGaugeStartAngle(ArkUINodeHandle node,ArkUI_Float32 value)41 void SetGaugeStartAngle(ArkUINodeHandle node, ArkUI_Float32 value)
42 {
43     auto* frameNode = reinterpret_cast<FrameNode*>(node);
44     CHECK_NULL_VOID(frameNode);
45     GaugeModelNG::SetStartAngle(frameNode, value);
46 }
47 
ResetGaugeStartAngle(ArkUINodeHandle node)48 void ResetGaugeStartAngle(ArkUINodeHandle node)
49 {
50     auto* frameNode = reinterpret_cast<FrameNode*>(node);
51     CHECK_NULL_VOID(frameNode);
52     GaugeModelNG::SetStartAngle(frameNode, DEFAULT_START_ANGLE);
53 }
54 
SetGaugeEndAngle(ArkUINodeHandle node,ArkUI_Float32 value)55 void SetGaugeEndAngle(ArkUINodeHandle node, ArkUI_Float32 value)
56 {
57     auto* frameNode = reinterpret_cast<FrameNode*>(node);
58     CHECK_NULL_VOID(frameNode);
59     GaugeModelNG::SetEndAngle(frameNode, value);
60 }
61 
ResetGaugeEndAngle(ArkUINodeHandle node)62 void ResetGaugeEndAngle(ArkUINodeHandle node)
63 {
64     auto* frameNode = reinterpret_cast<FrameNode*>(node);
65     CHECK_NULL_VOID(frameNode);
66     GaugeModelNG::SetEndAngle(frameNode, DEFAULT_END_ANGLE);
67 }
68 
SetGaugeStrokeWidth(ArkUINodeHandle node,ArkUI_Float32 value,int32_t unit)69 void SetGaugeStrokeWidth(ArkUINodeHandle node, ArkUI_Float32 value, int32_t unit)
70 {
71     auto* frameNode = reinterpret_cast<FrameNode*>(node);
72     CHECK_NULL_VOID(frameNode);
73     auto unitEnum = static_cast<OHOS::Ace::DimensionUnit>(unit);
74     GaugeModelNG::SetGaugeStrokeWidth(frameNode, Dimension(value, unitEnum));
75 }
76 
ResetGaugeStrokeWidth(ArkUINodeHandle node)77 void ResetGaugeStrokeWidth(ArkUINodeHandle node)
78 {
79     auto* frameNode = reinterpret_cast<FrameNode*>(node);
80     CHECK_NULL_VOID(frameNode);
81     GaugeModelNG::SetGaugeStrokeWidth(frameNode, Dimension(DEFAULT_STROKE_WIDTH, DimensionUnit::VP));
82 }
83 
SetShadowOptions(ArkUINodeHandle node,ArkUI_Float32 radius,ArkUI_Float32 offsetX,ArkUI_Float32 offsetY,ArkUI_Bool isShadowVisible)84 void SetShadowOptions(ArkUINodeHandle node, ArkUI_Float32 radius, ArkUI_Float32 offsetX, ArkUI_Float32 offsetY,
85     ArkUI_Bool isShadowVisible)
86 {
87     auto* frameNode = reinterpret_cast<FrameNode*>(node);
88     CHECK_NULL_VOID(frameNode);
89     NG::GaugeShadowOptions shadowOptions;
90     shadowOptions.radius = radius;
91     shadowOptions.offsetX = offsetX;
92     shadowOptions.offsetY = offsetY;
93     shadowOptions.isShadowVisible = isShadowVisible;
94     GaugeModelNG::SetShadowOptions(frameNode, shadowOptions);
95 }
96 
ResetShadowOptions(ArkUINodeHandle node)97 void ResetShadowOptions(ArkUINodeHandle node)
98 {
99     auto* frameNode = reinterpret_cast<FrameNode*>(node);
100     CHECK_NULL_VOID(frameNode);
101     GaugeModelNG::ResetShadowOptions(frameNode);
102 }
103 
SetIsShowIndicator(ArkUINodeHandle node,ArkUI_Bool isShowIndicator)104 void SetIsShowIndicator(ArkUINodeHandle node, ArkUI_Bool isShowIndicator)
105 {
106     auto* frameNode = reinterpret_cast<FrameNode*>(node);
107     CHECK_NULL_VOID(frameNode);
108     GaugeModelNG::SetIsShowIndicator(frameNode, isShowIndicator);
109 }
SetIndicatorIconPath(ArkUINodeHandle node,const char * iconPath,const char * bundleName,const char * moduleName)110 void SetIndicatorIconPath(ArkUINodeHandle node, const char* iconPath, const char* bundleName, const char* moduleName)
111 
112 {
113     auto* frameNode = reinterpret_cast<FrameNode*>(node);
114     CHECK_NULL_VOID(frameNode);
115     std::string iconPathStr;
116     std::string bundleNameStr;
117     std::string moduleNameStr;
118     if (iconPath != nullptr) {
119         iconPathStr = iconPath;
120     }
121     if (bundleName != nullptr) {
122         bundleNameStr = bundleName;
123     }
124     if (moduleName != nullptr) {
125         moduleNameStr = moduleName;
126     }
127     GaugeModelNG::SetIndicatorIconPath(frameNode, iconPathStr, bundleNameStr, moduleNameStr);
128 }
129 
ResetIndicatorIconPath(ArkUINodeHandle node)130 void ResetIndicatorIconPath(ArkUINodeHandle node)
131 {
132     auto* frameNode = reinterpret_cast<FrameNode*>(node);
133     CHECK_NULL_VOID(frameNode);
134     GaugeModelNG::ResetIndicatorIconPath(frameNode);
135 }
136 
SetIndicatorSpace(ArkUINodeHandle node,const char * spaceStrValue,ArkUI_Float32 spaceValue,int32_t spaceUnit)137 void SetIndicatorSpace(ArkUINodeHandle node, const char* spaceStrValue, ArkUI_Float32 spaceValue, int32_t spaceUnit)
138 {
139     auto* frameNode = reinterpret_cast<FrameNode*>(node);
140     CHECK_NULL_VOID(frameNode);
141     CalcDimension space;
142     auto spaceUnitValue = static_cast<DimensionUnit>(spaceUnit);
143     if (spaceUnitValue == DimensionUnit::CALC) {
144         std::string valueStr;
145         if (spaceStrValue != nullptr) {
146             valueStr = spaceStrValue;
147         }
148         space = CalcDimension(valueStr, spaceUnitValue);
149     } else {
150         space = CalcDimension(spaceValue, spaceUnitValue);
151     }
152     GaugeModelNG::SetIndicatorSpace(frameNode, space);
153 }
154 
ResetIndicatorSpace(ArkUINodeHandle node)155 void ResetIndicatorSpace(ArkUINodeHandle node)
156 {
157     auto* frameNode = reinterpret_cast<FrameNode*>(node);
158     CHECK_NULL_VOID(frameNode);
159     GaugeModelNG::ResetIndicatorSpace(frameNode);
160 }
161 
SetColors(ArkUINodeHandle node,const uint32_t * colors,const ArkUI_Float32 * weight,uint32_t length)162 void SetColors(ArkUINodeHandle node, const uint32_t* colors, const ArkUI_Float32* weight, uint32_t length)
163 {
164     CHECK_NULL_VOID(colors);
165     CHECK_NULL_VOID(weight);
166     auto* frameNode = reinterpret_cast<FrameNode*>(node);
167     CHECK_NULL_VOID(frameNode);
168     std::vector<Color> inputColor(length);
169     std::vector<ArkUI_Float32> weights(length);
170     for (uint32_t i = 0; i < length; i++) {
171         inputColor.at(i) = Color(colors[i]);
172         weights.at(i) = weight[i];
173     }
174     GaugeModelNG::SetColors(frameNode, inputColor, weights);
175 }
176 
ResetColors(ArkUINodeHandle node)177 void ResetColors(ArkUINodeHandle node)
178 {
179     auto* frameNode = reinterpret_cast<FrameNode*>(node);
180     CHECK_NULL_VOID(frameNode);
181     std::vector<Color> inputColor;
182     std::vector<ArkUI_Float32> weights;
183     GaugeModelNG::SetColors(frameNode, inputColor, weights);
184 }
185 
SortColorStopByOffset(std::vector<NG::ColorStopArray> & colors)186 void SortColorStopByOffset(std::vector<NG::ColorStopArray>& colors)
187 {
188     for (auto& colorStopArray : colors) {
189         std::sort(colorStopArray.begin(), colorStopArray.end(),
190             [](const std::pair<Color, Dimension>& left, const std::pair<Color, Dimension>& right) {
191                 return left.second.Value() < right.second.Value();
192             });
193 
194         auto iter = std::unique(colorStopArray.begin(), colorStopArray.end(),
195             [](const std::pair<Color, Dimension>& left, const std::pair<Color, Dimension>& right) {
196                 return left.second.Value() == right.second.Value();
197             });
198         colorStopArray.erase(iter, colorStopArray.end());
199     }
200 }
201 
SetGradientColors(ArkUINodeHandle node,const struct ArkUIGradientType * gradient,uint32_t weightLength)202 void SetGradientColors(ArkUINodeHandle node, const struct ArkUIGradientType* gradient, uint32_t weightLength)
203 {
204     CHECK_NULL_VOID(gradient->gradientLength);
205     CHECK_NULL_VOID(gradient->color);
206     CHECK_NULL_VOID(gradient->offset);
207     auto* frameNode = reinterpret_cast<FrameNode*>(node);
208     CHECK_NULL_VOID(frameNode);
209     std::vector<ArkUI_Float32> weight;
210     if (weightLength > 0 && gradient->weight != nullptr) {
211         weight = std::vector<ArkUI_Float32>(gradient->weight, gradient->weight + weightLength);
212     }
213     std::vector<ColorStopArray> colors(gradient->length);
214     uint32_t pos = 0;
215     for (uint32_t i = 0; i < gradient->length; i++) {
216         if (static_cast<int32_t>(i) >= NG::COLORS_MAX_COUNT) {
217             break;
218         }
219         if (gradient->gradientLength[i] == 0) {
220             colors.at(i) = NG::ColorStopArray { std::make_pair(Color(gradient->color[pos]), Dimension(0.0)) };
221             continue;
222         }
223         ColorStopArray colorStop(gradient->gradientLength[i]);
224         for (uint32_t j = 0; j < gradient->gradientLength[i]; j++, pos++) {
225             colorStop.at(j) = std::make_pair(Color(gradient->color[pos]),
226                 Dimension(gradient->offset[pos].number, static_cast<DimensionUnit>(gradient->offset[pos].unit)));
227         }
228         colors.at(i) = colorStop;
229     }
230     GaugeType type = static_cast<GaugeType>(gradient->type);
231     SortColorStopByOffset(colors);
232     GaugeModelNG::SetGradientColors(frameNode, colors, weight, type);
233 }
234 
ResetGradientColors(ArkUINodeHandle node)235 void ResetGradientColors(ArkUINodeHandle node)
236 {
237     auto* frameNode = reinterpret_cast<FrameNode*>(node);
238     CHECK_NULL_VOID(frameNode);
239     GaugeModelNG::ResetGradientColors(frameNode);
240 }
241 
242 namespace NodeModifier {
GetGaugeModifier()243 const ArkUIGaugeModifier* GetGaugeModifier()
244 {
245     static const ArkUIGaugeModifier modifier = { SetGaugeValue, ResetGaugeValue, SetGaugeStartAngle,
246         ResetGaugeStartAngle, SetGaugeEndAngle, ResetGaugeEndAngle, SetGaugeStrokeWidth, ResetGaugeStrokeWidth,
247         SetShadowOptions, ResetShadowOptions, SetIsShowIndicator,
248         SetIndicatorIconPath, ResetIndicatorIconPath, SetIndicatorSpace, ResetIndicatorSpace,
249         SetColors, ResetColors, SetGradientColors, ResetGradientColors
250     };
251 
252     return &modifier;
253 }
254 
GetCJUIGaugeModifier()255 const CJUIGaugeModifier* GetCJUIGaugeModifier()
256 {
257     static const CJUIGaugeModifier modifier = { SetGaugeValue, ResetGaugeValue, SetGaugeStartAngle,
258         ResetGaugeStartAngle, SetGaugeEndAngle, ResetGaugeEndAngle, SetGaugeStrokeWidth, ResetGaugeStrokeWidth,
259         SetShadowOptions, ResetShadowOptions, SetIsShowIndicator,
260         SetIndicatorIconPath, ResetIndicatorIconPath, SetIndicatorSpace, ResetIndicatorSpace,
261         SetColors, ResetColors, SetGradientColors, ResetGradientColors
262     };
263 
264     return &modifier;
265 }
266 }
267 } // namespace OHOS::Ace::NG