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/cj_frontend/interfaces/cj_ffi/cj_gauge_ffi.h"
17
18 #include "cj_lambda.h"
19 #include "base/log/ace_scoring_log.h"
20 #include "base/memory/ace_type.h"
21 #include "core/common/container.h"
22 #include "core/components_ng/base/view_stack_model.h"
23 #include "core/components_ng/pattern/gauge/gauge_model_ng.h"
24
25 using namespace OHOS::Ace;
26
27 namespace {
28 const std::string INDICATOR_DEFAULT = "default";
29 const std::string INDICATOR_NULL = "null";
30 } // namespace
31 extern "C" {
FFICJCreateVectorColorStop(int64_t size)32 VectorColorStops FFICJCreateVectorColorStop(int64_t size)
33 {
34 LOGI("Create ColorStop Vector");
35 return new std::vector<ColorStop>(size);
36 }
37
FFICJVectorColorStopSetElement(VectorColorStops vec,int64_t index,ColorStop colorStop)38 void FFICJVectorColorStopSetElement(VectorColorStops vec, int64_t index, ColorStop colorStop)
39 {
40 LOGI("ColorStop Vector Set Element");
41 auto actualVec = reinterpret_cast<std::vector<ColorStop>*>(vec);
42 (*actualVec)[index] = colorStop;
43 LOGI("ColorStop Vector Set Element Success");
44 }
45
FFICJVectorColorStopDelete(VectorColorStops vec)46 void FFICJVectorColorStopDelete(VectorColorStops vec)
47 {
48 auto actualVec = reinterpret_cast<std::vector<ColorStop>*>(vec);
49 delete actualVec;
50 }
51
FFICJCreateVectorGaugeLinearGradient(int64_t size)52 VecLinearGradientHandle FFICJCreateVectorGaugeLinearGradient(int64_t size)
53 {
54 LOGI("Create VectorGaugeLinearGradient Vector");
55 return new std::vector<VectorColorStops>(size);
56 }
57
FFICJVectorGaugeLinearGradientSetElement(VecLinearGradientHandle vec,int64_t index,VectorColorStops vectorColorStops)58 void FFICJVectorGaugeLinearGradientSetElement(
59 VecLinearGradientHandle vec, int64_t index, VectorColorStops vectorColorStops)
60 {
61 LOGI("VectorGaugeLinearGradient Vector Set Element");
62 auto actualVec = reinterpret_cast<std::vector<VectorColorStops>*>(vec);
63 (*actualVec)[index] = vectorColorStops;
64 LOGI("VectorGaugeLinearGradient Vector Set Element Success");
65 }
66
FFICJVectorGaugeLinearGradientDelete(VecLinearGradientHandle vec)67 void FFICJVectorGaugeLinearGradientDelete(VecLinearGradientHandle vec)
68 {
69 auto actualVec = reinterpret_cast<std::vector<VectorColorStops>*>(vec);
70 delete actualVec;
71 }
72
FfiOHOSAceFrameworkGaugeCreate(double gaugeValue,double gaugeMin,double gaugeMax)73 void FfiOHOSAceFrameworkGaugeCreate(double gaugeValue, double gaugeMin, double gaugeMax)
74 {
75 if (gaugeMin >= gaugeMax) {
76 gaugeMin = NG::DEFAULT_MIN_VALUE;
77 gaugeMax = NG::DEFAULT_MAX_VALUE;
78 }
79 if (gaugeValue < gaugeMin || gaugeValue > gaugeMax) {
80 gaugeValue = gaugeMin;
81 }
82 GaugeModel::GetInstance()->Create(gaugeValue, gaugeMin, gaugeMax);
83 GaugeModel::GetInstance()->SetIsShowLimitValue(true);
84 }
85
FfiOHOSAceFrameworkGaugeSetValue(double value)86 void FfiOHOSAceFrameworkGaugeSetValue(double value)
87 {
88 GaugeModel::GetInstance()->SetValue(value);
89 }
90
FfiOHOSAceFrameworkGaugeSetStartAngle(double startAngle)91 void FfiOHOSAceFrameworkGaugeSetStartAngle(double startAngle)
92 {
93 GaugeModel::GetInstance()->SetStartAngle(startAngle);
94 }
95
FfiOHOSAceFrameworkGaugeSetEndAngle(double endAngle)96 void FfiOHOSAceFrameworkGaugeSetEndAngle(double endAngle)
97 {
98 GaugeModel::GetInstance()->SetEndAngle(endAngle);
99 }
100
SortColorStopOffset(std::vector<NG::ColorStopArray> & colors)101 void SortColorStopOffset(std::vector<NG::ColorStopArray>& colors)
102 {
103 for (auto& colorStopArray : colors) {
104 std::sort(colorStopArray.begin(), colorStopArray.end(),
105 [](const std::pair<Color, Dimension>& left, const std::pair<Color, Dimension>& right) {
106 return left.second.Value() < right.second.Value();
107 });
108
109 auto iter = std::unique(colorStopArray.begin(), colorStopArray.end(),
110 [](const std::pair<Color, Dimension>& left, const std::pair<Color, Dimension>& right) {
111 return left.second.Value() == right.second.Value();
112 });
113 colorStopArray.erase(iter, colorStopArray.end());
114 }
115 }
116
FfiOHOSAceFrameworkGaugeSetColors(VectorUInt32Ptr gaugeColors,VectorFloat32Ptr gaugeWeights)117 void FfiOHOSAceFrameworkGaugeSetColors(VectorUInt32Ptr gaugeColors, VectorFloat32Ptr gaugeWeights)
118 {
119 if (!Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
120 FfiOHOSAceFrameworkGaugeSetColorsV2(gaugeColors, gaugeWeights);
121 return;
122 }
123 const auto& vecColor = *reinterpret_cast<std::vector<uint32_t>*>(gaugeColors);
124 const auto& vecWeight = *reinterpret_cast<std::vector<float>*>(gaugeWeights);
125 if (vecColor.size() != vecWeight.size()) {
126 LOGE("gauge colors not match weights");
127 return;
128 }
129 std::vector<Color> colors;
130 for (size_t i = 0; i < vecColor.size(); ++i) {
131 colors.push_back(Color(vecColor[i]));
132 }
133 GaugeModel::GetInstance()->SetColors(colors, vecWeight);
134 }
135
FfiOHOSAceFrameworkGaugeSetColorsV2(VectorUInt32Ptr gaugeColors,VectorFloat32Ptr gaugeWeights)136 void FfiOHOSAceFrameworkGaugeSetColorsV2(VectorUInt32Ptr gaugeColors, VectorFloat32Ptr gaugeWeights)
137 {
138 NG::GaugeType type = NG::GaugeType::TYPE_CIRCULAR_MULTI_SEGMENT_GRADIENT;
139 std::vector<NG::ColorStopArray> colors;
140 std::vector<float> weights;
141 const auto& vecColor = *reinterpret_cast<std::vector<uint32_t>*>(gaugeColors);
142 const auto& vecWeight = *reinterpret_cast<std::vector<float>*>(gaugeWeights);
143 if (vecColor.size() != vecWeight.size()) {
144 LOGE("gauge colors not match weights");
145 return;
146 }
147 if (vecColor.size() <= 0) {
148 GaugeModel::GetInstance()->ResetGradientColors();
149 return;
150 }
151 if (vecColor.size() > 1) {
152 for (size_t i = 0; i < vecColor.size(); ++i) {
153 NG::ColorStopArray colorStopArray;
154 colorStopArray.emplace_back(std::make_pair(Color(vecColor[i]), Dimension(vecWeight[i], DimensionUnit::VP)));
155 colors.emplace_back(colorStopArray);
156 }
157 GaugeModel::GetInstance()->SetGradientColors(colors, weights, type);
158 return;
159 }
160 type = NG::GaugeType::TYPE_CIRCULAR_MONOCHROME;
161 NG::ColorStopArray colorStopArray;
162 colorStopArray.emplace_back(std::make_pair(Color(vecColor[0]), Dimension(vecWeight[0], DimensionUnit::VP)));
163 colors.emplace_back(colorStopArray);
164 GaugeModel::GetInstance()->SetGradientColors(colors, weights, type);
165 }
166
FfiOHOSAceFrameworkGaugeSetLinearGradientColors(VecLinearGradientHandle linearGradients,VectorUInt32Ptr weight)167 void FfiOHOSAceFrameworkGaugeSetLinearGradientColors(VecLinearGradientHandle linearGradients, VectorUInt32Ptr weight)
168 {
169 NG::GaugeType type = NG::GaugeType::TYPE_CIRCULAR_MULTI_SEGMENT_GRADIENT;
170 std::vector<NG::ColorStopArray> colors;
171 std::vector<float> weights;
172 auto vecLinearGradients = *reinterpret_cast<std::vector<VectorColorStops>*>(linearGradients);
173 auto vecWeight = *reinterpret_cast<std::vector<float>*>(weight);
174 if (vecLinearGradients.size() != vecWeight.size()) {
175 LOGE("gauge colors not match weights");
176 return;
177 }
178 if (vecLinearGradients.size() <= 0) {
179 GaugeModel::GetInstance()->ResetGradientColors();
180 return;
181 }
182 if (vecLinearGradients.size() > 1) {
183 for (size_t i = 0; i < vecLinearGradients.size(); i++) {
184 if (vecWeight[i] <= 0) {
185 continue;
186 }
187 weights.emplace_back(vecWeight[i]);
188 auto vecColorStops = *reinterpret_cast<std::vector<ColorStop>*>(vecLinearGradients[i]);
189 if (vecColorStops.size() <= 1) {
190 continue;
191 }
192 NG::ColorStopArray colorStopArray;
193 for (size_t j = 0; j < vecColorStops.size(); j++) {
194 colorStopArray.emplace_back(std::make_pair(
195 Color(vecColorStops[j].color), Dimension(vecColorStops[j].offset, DimensionUnit::VP)));
196 }
197 colors.emplace_back(colorStopArray);
198 }
199 SortColorStopOffset(colors);
200 GaugeModel::GetInstance()->SetGradientColors(colors, weights, type);
201 return;
202 }
203 type = NG::GaugeType::TYPE_CIRCULAR_SINGLE_SEGMENT_GRADIENT;
204 NG::ColorStopArray colorStopArray;
205 auto vecColorStops = *reinterpret_cast<std::vector<ColorStop>*>(vecLinearGradients[0]);
206 for (size_t i = 0; i < vecColorStops.size(); i++) {
207 colorStopArray.emplace_back(
208 std::make_pair(Color(vecColorStops[i].color), Dimension(vecColorStops[i].offset, DimensionUnit::VP)));
209 }
210 colors.emplace_back(colorStopArray);
211 SortColorStopOffset(colors);
212 GaugeModel::GetInstance()->SetGradientColors(colors, weights, type);
213 }
214
FfiOHOSAceFrameworkGaugeSetShadowOptions(double radius,double offsetX,double offsetY)215 void FfiOHOSAceFrameworkGaugeSetShadowOptions(double radius, double offsetX, double offsetY)
216 {
217 NG::GaugeShadowOptions shadowOptions;
218 if (radius < 0) {
219 radius = NG::DEFAULT_GAUGE_SHADOW_RADIUS;
220 }
221 if (offsetX < 0) {
222 offsetX = NG::DEFAULT_GAUGE_SHADOW_OFFSETX;
223 }
224 if (offsetY < 0) {
225 offsetY = NG::DEFAULT_GAUGE_SHADOW_OFFSETY;
226 }
227 shadowOptions.radius = radius;
228 shadowOptions.offsetX = offsetX;
229 shadowOptions.offsetY = offsetY;
230
231 GaugeModel::GetInstance()->SetShadowOptions(shadowOptions);
232 }
233
FfiOHOSAceFrameworkGaugeSetStrokeWidth(double strokeWidth,int32_t strokeUnit)234 void FfiOHOSAceFrameworkGaugeSetStrokeWidth(double strokeWidth, int32_t strokeUnit)
235 {
236 Dimension strokeDimWidth(strokeWidth, static_cast<DimensionUnit>(strokeUnit));
237 GaugeModel::GetInstance()->SetStrokeWidth(strokeDimWidth);
238 }
239
FfiOHOSAceFrameworkGaugeSetIndicator(const char * icon,double size)240 void FfiOHOSAceFrameworkGaugeSetIndicator(const char* icon, double size)
241 {
242 std::string iconPath = icon;
243 if (icon == INDICATOR_NULL) {
244 GaugeModel::GetInstance()->SetIsShowIndicator(false);
245 return;
246 }
247 if (icon == INDICATOR_DEFAULT) {
248 GaugeModel::GetInstance()->ResetIndicatorIconPath();
249 } else {
250 std::string bundleName;
251 std::string moduleName;
252 GaugeModel::GetInstance()->SetIndicatorIconPath(iconPath, bundleName, moduleName);
253 }
254
255 CalcDimension space;
256 if (size < 0) {
257 space = NG::INDICATOR_DISTANCE_TO_TOP;
258 } else {
259 space = CalcDimension(size, DimensionUnit::VP);
260 }
261 GaugeModel::GetInstance()->SetIndicatorSpace(space);
262 }
263
FfiOHOSAceFrameworkGaugeSetDescription(void (* builder)())264 void FfiOHOSAceFrameworkGaugeSetDescription(void (*builder)())
265 {
266 GaugeModel::GetInstance()->SetIsShowLimitValue(false);
267 GaugeModel::GetInstance()->SetIsShowDescription(true);
268 // parse builder
269 auto buildFunc = CJLambda::Create(builder);
270 RefPtr<AceType> customNode;
271 {
272 ViewStackModel::GetInstance()->NewScope();
273 buildFunc();
274 customNode = ViewStackModel::GetInstance()->Finish();
275 }
276 GaugeModel::GetInstance()->SetDescription(customNode);
277 }
278 }
279