• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 
16 #include "bridge/declarative_frontend/jsview/js_gauge.h"
17 
18 #include <string>
19 
20 #include "base/log/ace_scoring_log.h"
21 #include "base/memory/ace_type.h"
22 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
23 #include "bridge/declarative_frontend/jsview/js_linear_gradient.h"
24 #include "bridge/declarative_frontend/jsview/js_utils.h"
25 #include "bridge/declarative_frontend/jsview/models/gauge_model_impl.h"
26 #include "core/common/resource/resource_parse_utils.h"
27 #include "core/components_ng/base/view_stack_model.h"
28 #include "core/components_ng/pattern/gauge/gauge_model_ng.h"
29 
30 namespace OHOS::Ace {
31 
32 std::unique_ptr<GaugeModel> GaugeModel::instance_ = nullptr;
33 std::mutex GaugeModel::mutex_;
34 constexpr double DEFAULT_GAUGE_VALUE = 0;
35 constexpr double DEFAULT_GAUGE_MIN = 0;
36 constexpr double DEFAULT_GAUGE_MAX = 100;
37 
GetInstance()38 GaugeModel* GaugeModel::GetInstance()
39 {
40     if (!instance_) {
41         std::lock_guard<std::mutex> lock(mutex_);
42         if (!instance_) {
43 #ifdef NG_BUILD
44             instance_.reset(new NG::GaugeModelNG());
45 #else
46             if (Container::IsCurrentUseNewPipeline()) {
47                 instance_.reset(new NG::GaugeModelNG());
48             } else {
49                 instance_.reset(new Framework::GaugeModelImpl());
50             }
51 #endif
52         }
53     }
54     return instance_.get();
55 }
56 
57 } // namespace OHOS::Ace
58 namespace OHOS::Ace::Framework {
59 constexpr Color ERROR_COLOR = Color(0xFFE84026);
60 constexpr float FIX_ANGLE = 720.0f;
61 
JSBind(BindingTarget globalObj)62 void JSGauge::JSBind(BindingTarget globalObj)
63 {
64     JSClass<JSGauge>::Declare("Gauge");
65     JSClass<JSGauge>::StaticMethod("create", &JSGauge::Create);
66 
67     JSClass<JSGauge>::StaticMethod("value", &JSGauge::SetValue);
68     JSClass<JSGauge>::StaticMethod("startAngle", &JSGauge::SetStartAngle);
69     JSClass<JSGauge>::StaticMethod("endAngle", &JSGauge::SetEndAngle);
70     JSClass<JSGauge>::StaticMethod("colors", &JSGauge::SetColors);
71     JSClass<JSGauge>::StaticMethod("strokeWidth", &JSGauge::SetStrokeWidth);
72     JSClass<JSGauge>::StaticMethod("labelConfig", &JSGauge::SetLabelConfig);
73     JSClass<JSGauge>::StaticMethod("trackShadow", &JSGauge::SetShadowOptions);
74     JSClass<JSGauge>::StaticMethod("indicator", &JSGauge::SetIndicator);
75     JSClass<JSGauge>::StaticMethod("description", &JSGauge::SetDescription);
76     JSClass<JSGauge>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
77     JSClass<JSGauge>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
78     JSClass<JSGauge>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
79     JSClass<JSGauge>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
80     JSClass<JSGauge>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
81     JSClass<JSGauge>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
82     JSClass<JSGauge>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
83     JSClass<JSGauge>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
84 
85     JSClass<JSGauge>::InheritAndBind<JSViewAbstract>(globalObj);
86 }
87 
Create(const JSCallbackInfo & info)88 void JSGauge::Create(const JSCallbackInfo& info)
89 {
90     if (!info[0]->IsObject()) {
91         GaugeModel::GetInstance()->Create(DEFAULT_GAUGE_VALUE, DEFAULT_GAUGE_MIN, DEFAULT_GAUGE_MAX);
92         GaugeModel::GetInstance()->SetIsShowLimitValue(true);
93         return;
94     }
95 
96     auto paramObject = JSRef<JSObject>::Cast(info[0]);
97     auto value = paramObject->GetProperty("value");
98     auto min = paramObject->GetProperty("min");
99     auto max = paramObject->GetProperty("max");
100 
101     double gaugeMin = min->IsNumber() ? min->ToNumber<double>() : DEFAULT_GAUGE_MIN;
102     double gaugeMax = max->IsNumber() ? max->ToNumber<double>() : DEFAULT_GAUGE_MAX;
103     double gaugeValue = value->IsNumber() ? value->ToNumber<double>() : DEFAULT_GAUGE_VALUE;
104     if (LessNotEqual(gaugeMax, gaugeMin)) {
105         gaugeMin = NG::DEFAULT_MIN_VALUE;
106         gaugeMax = NG::DEFAULT_MAX_VALUE;
107     }
108 
109     if (LessNotEqual(gaugeValue, gaugeMin) || GreatNotEqual(gaugeValue, gaugeMax)) {
110         gaugeValue = gaugeMin;
111     }
112     GaugeModel::GetInstance()->Create(gaugeValue, gaugeMin, gaugeMax);
113     if (min->IsNumber() || max->IsNumber()) {
114         GaugeModel::GetInstance()->SetIsShowLimitValue(true);
115     } else {
116         GaugeModel::GetInstance()->SetIsShowLimitValue(false);
117     }
118 }
119 
SetValue(const JSCallbackInfo & info)120 void JSGauge::SetValue(const JSCallbackInfo& info)
121 {
122     float value = NG::DEFAULT_MIN_VALUE;
123     if (info[0]->IsNumber()) {
124         value = info[0]->ToNumber<float>();
125     }
126     GaugeModel::GetInstance()->SetValue(value);
127 }
128 
SetStartAngle(const JSCallbackInfo & info)129 void JSGauge::SetStartAngle(const JSCallbackInfo& info)
130 {
131     float startAngle = NG::DEFAULT_START_DEGREE;
132     if (info[0]->IsNumber()) {
133         startAngle = std::fmod(info[0]->ToNumber<double>(), FIX_ANGLE);
134     }
135     GaugeModel::GetInstance()->SetStartAngle(startAngle);
136 }
137 
SetEndAngle(const JSCallbackInfo & info)138 void JSGauge::SetEndAngle(const JSCallbackInfo& info)
139 {
140     float endAngle = NG::DEFAULT_END_DEGREE;
141     if (info[0]->IsNumber()) {
142         endAngle = std::fmod(info[0]->ToNumber<double>(), FIX_ANGLE);
143     }
144     GaugeModel::GetInstance()->SetEndAngle(endAngle);
145 }
146 
SetColors(const JSCallbackInfo & info)147 void JSGauge::SetColors(const JSCallbackInfo& info)
148 {
149     if (!Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
150         SetGradientColors(info);
151         return;
152     }
153 
154     if (!info[0]->IsArray()) {
155         return;
156     }
157     std::vector<Color> colors;
158     std::vector<double> values;
159     std::vector<float> weights;
160     auto jsColor = JSRef<JSArray>::Cast(info[0]);
161     for (size_t i = 0; i < jsColor->Length(); ++i) {
162         JSRef<JSVal> jsValue = jsColor->GetValueAt(i);
163         if (!jsValue->IsArray()) {
164             return;
165         }
166         JSRef<JSArray> tempColors = jsColor->GetValueAt(i);
167         double value = 0.0;
168         if (tempColors->GetValueAt(1)->IsNumber()) {
169             value = tempColors->GetValueAt(1)->ToNumber<double>();
170         }
171         float weight = 0.0;
172         if (tempColors->GetValueAt(1)->IsNumber()) {
173             weight = tempColors->GetValueAt(1)->ToNumber<float>();
174         }
175         Color selectedColor;
176         if (!ParseJsColor(tempColors->GetValueAt(0), selectedColor)) {
177             selectedColor = ERROR_COLOR;
178         }
179         colors.push_back(selectedColor);
180         values.push_back(value);
181         if (weight > 0) {
182             weights.push_back(weight);
183         } else {
184             weights.push_back(0.0f);
185         }
186     }
187     GaugeModel::GetInstance()->SetColors(colors, weights);
188 }
189 
UpdateConfigChangeFlags(bool useJsLinearGradient,bool useSpecialDefaultIndicator)190 void UpdateConfigChangeFlags(bool useJsLinearGradient, bool useSpecialDefaultIndicator)
191 {
192     if (SystemProperties::ConfigChangePerform()) {
193         GaugeModel::GetInstance()->SetUseGradient(useJsLinearGradient);
194         GaugeModel::GetInstance()->SetUseSpecialDefaultIndicator(useSpecialDefaultIndicator);
195     }
196 }
197 
SetGradientColors(const JSCallbackInfo & info)198 void JSGauge::SetGradientColors(const JSCallbackInfo& info)
199 {
200     if (SystemProperties::ConfigChangePerform()) {
201         GaugeModel::GetInstance()->SetUseGradient(false);
202     }
203     if (info[0]->IsNull() || info[0]->IsUndefined()) {
204         GaugeModel::GetInstance()->ResetGradientColors();
205         return;
206     }
207 
208     NG::GaugeType type = NG::GaugeType::TYPE_CIRCULAR_MULTI_SEGMENT_GRADIENT;
209     std::vector<NG::ColorStopArray> colors;
210     std::vector<float> weights;
211     bool useJsLinearGradient = false;
212     bool useSpecialDefaultIndicator = false;
213     if (info[0]->IsArray()) {
214         auto jsColorsArray = JSRef<JSArray>::Cast(info[0]);
215         if (jsColorsArray->Length() == 0) {
216             GaugeModel::GetInstance()->ResetGradientColors();
217             return;
218         }
219 
220         for (size_t i = 0; i < jsColorsArray->Length(); ++i) {
221             if (static_cast<int32_t>(i) >= NG::COLORS_MAX_COUNT) {
222                 break;
223             }
224             JSRef<JSVal> jsValue = jsColorsArray->GetValueAt(i);
225             if (!jsValue->IsArray()) {
226                 continue;
227             }
228             auto tempColors = JSRef<JSArray>::Cast(jsValue);
229             // Get weight
230             float weight = 0.0;
231             if (tempColors->GetValueAt(1)->IsNumber()) {
232                 weight = tempColors->GetValueAt(1)->ToNumber<float>();
233             }
234             if (NonPositive(weight)) {
235                 continue;
236             }
237             weights.push_back(weight);
238             // Get color
239             JSRef<JSVal> jsColorValue = tempColors->GetValueAt(0);
240             ConvertGradientColor(jsColorValue, colors, type, useJsLinearGradient, useSpecialDefaultIndicator);
241         }
242         type = NG::GaugeType::TYPE_CIRCULAR_MULTI_SEGMENT_GRADIENT;
243         SortColorStopOffset(colors);
244         GaugeModel::GetInstance()->SetGradientColors(colors, weights, type);
245         UpdateConfigChangeFlags(useJsLinearGradient, useSpecialDefaultIndicator);
246         return;
247     }
248     ConvertGradientColor(info[0], colors, type, useJsLinearGradient, useSpecialDefaultIndicator);
249     SortColorStopOffset(colors);
250     GaugeModel::GetInstance()->SetGradientColors(colors, weights, type);
251     UpdateConfigChangeFlags(useJsLinearGradient, useSpecialDefaultIndicator);
252 }
253 
SortColorStopOffset(std::vector<NG::ColorStopArray> & colors)254 void JSGauge::SortColorStopOffset(std::vector<NG::ColorStopArray>& colors)
255 {
256     for (auto& colorStopArray : colors) {
257         std::sort(colorStopArray.begin(), colorStopArray.end(),
258             [](const std::pair<Color, Dimension>& left, const std::pair<Color, Dimension>& right) {
259                 return left.second.Value() < right.second.Value();
260             });
261 
262         auto iter = std::unique(colorStopArray.begin(), colorStopArray.end(),
263             [](const std::pair<Color, Dimension>& left, const std::pair<Color, Dimension>& right) {
264                 return left.second.Value() == right.second.Value();
265             });
266         colorStopArray.erase(iter, colorStopArray.end());
267     }
268 }
269 
ConvertGradientColor(const JsiRef<JsiValue> & itemParam,std::vector<NG::ColorStopArray> & colors,NG::GaugeType & type,bool & useJsLinearGradient,bool & useSpecialDefaultIndicator)270 void JSGauge::ConvertGradientColor(const JsiRef<JsiValue>& itemParam, std::vector<NG::ColorStopArray>& colors,
271     NG::GaugeType& type, bool& useJsLinearGradient, bool& useSpecialDefaultIndicator)
272 {
273     if (!itemParam->IsObject()) {
274         type = NG::GaugeType::TYPE_CIRCULAR_MONOCHROME;
275         return ConvertResourceColor(itemParam, colors, useSpecialDefaultIndicator);
276     }
277 
278     JSLinearGradient* jsLinearGradient = JSRef<JSObject>::Cast(itemParam)->Unwrap<JSLinearGradient>();
279     if (!jsLinearGradient) {
280         type = NG::GaugeType::TYPE_CIRCULAR_MONOCHROME;
281         return ConvertResourceColor(itemParam, colors, useSpecialDefaultIndicator);
282     }
283     useJsLinearGradient = true;
284     type = NG::GaugeType::TYPE_CIRCULAR_SINGLE_SEGMENT_GRADIENT;
285     if (jsLinearGradient->GetGradient().size() == 0) {
286         NG::ColorStopArray colorStopArray;
287         colorStopArray.emplace_back(std::make_pair(ERROR_COLOR, Dimension(0.0)));
288         colors.emplace_back(colorStopArray);
289     } else {
290         colors.emplace_back(jsLinearGradient->GetGradient());
291     }
292 }
293 
ConvertResourceColor(const JsiRef<JsiValue> & itemParam,std::vector<NG::ColorStopArray> & colors,bool & useSpecialDefaultIndicator)294 void JSGauge::ConvertResourceColor(
295     const JsiRef<JsiValue>& itemParam, std::vector<NG::ColorStopArray>& colors, bool& useSpecialDefaultIndicator)
296 {
297     Color color;
298     RefPtr<ResourceObject> resObj;
299     bool state = ParseJsColor(itemParam, color, resObj);
300     if (!state) {
301         color = ERROR_COLOR;
302     }
303     if (SystemProperties::ConfigChangePerform() && state && color.GetResourceId() == 0 && resObj &&
304         resObj->GetId() > 0) {
305         useSpecialDefaultIndicator = true;
306     }
307     NG::ColorStopArray colorStopArray;
308     colorStopArray.emplace_back(std::make_pair(color, Dimension(0.0)));
309     colors.emplace_back(colorStopArray);
310 }
311 
SetStrokeWidth(const JSCallbackInfo & info)312 void JSGauge::SetStrokeWidth(const JSCallbackInfo& info)
313 {
314     CalcDimension strokeWidth;
315     RefPtr<ResourceObject> resObj;
316     if (SystemProperties::ConfigChangePerform()) {
317         bool state = ParseJsDimensionVpNG(info[0], strokeWidth, resObj);
318         GaugeModel::GetInstance()->CreateWithResourceObj(OHOS::Ace::GaugeResourceType::STROKE_WIDTH, resObj);
319         if (state && strokeWidth.Unit() != DimensionUnit::PERCENT) {
320             GaugeModel::GetInstance()->SetStrokeWidth(strokeWidth);
321         } else {
322             GaugeModel::GetInstance()->SetStrokeWidth(CalcDimension(0));
323         }
324     } else {
325         if (!ParseJsDimensionVpNG(info[0], strokeWidth) || strokeWidth.Unit() == DimensionUnit::PERCENT) {
326             strokeWidth = CalcDimension(0);
327         }
328         GaugeModel::GetInstance()->SetStrokeWidth(strokeWidth);
329     }
330 }
331 
SetLabelConfig(const JSCallbackInfo & info)332 void JSGauge::SetLabelConfig(const JSCallbackInfo& info)
333 {
334     if (!info[0]->IsObject()) {
335         return;
336     }
337     auto paramObject = JSRef<JSObject>::Cast(info[0]);
338     auto labelText = paramObject->GetProperty("text");
339     auto labelColor = paramObject->GetProperty("color");
340     Color currentColor;
341     ParseJsColor(labelColor, currentColor);
342     if (labelText->IsString()) {
343         GaugeModel::GetInstance()->SetLabelMarkedText(labelText->ToString());
344     }
345     if (ParseJsColor(labelColor, currentColor)) {
346         GaugeModel::GetInstance()->SetMarkedTextColor(currentColor);
347     }
348 }
349 
HandleShadowRadius(const JSRef<JSVal> & jsRadius,NG::GaugeShadowOptions & shadowOptions)350 void HandleShadowRadius(const JSRef<JSVal>& jsRadius, NG::GaugeShadowOptions& shadowOptions)
351 {
352     RefPtr<ResourceObject> radiusResObj;
353     double radius = 0.0;
354     bool state = JSViewAbstract::ParseJsDouble(jsRadius, radius, radiusResObj);
355     if (radiusResObj) {
356         auto&& radiusUpdateFunc = [](const RefPtr<ResourceObject>& resObj, NG::GaugeShadowOptions& shadowOptions) {
357             double radius = 0.0;
358             if (ResourceParseUtils::ParseResDouble(resObj, radius) && !NonPositive(radius)) {
359                 shadowOptions.radius = radius;
360             } else {
361                 shadowOptions.radius = NG::DEFAULT_GAUGE_SHADOW_RADIUS;
362             }
363         };
364         shadowOptions.AddResource("gauge.shadow.radius", radiusResObj, std::move(radiusUpdateFunc));
365     }
366     if (state && !NonPositive(radius)) {
367         shadowOptions.radius = radius;
368     } else {
369         shadowOptions.radius = NG::DEFAULT_GAUGE_SHADOW_RADIUS;
370     }
371 }
372 
HandleShadowOffsetX(const JSRef<JSVal> & jsOffsetX,NG::GaugeShadowOptions & shadowOptions)373 void HandleShadowOffsetX(const JSRef<JSVal>& jsOffsetX, NG::GaugeShadowOptions& shadowOptions)
374 {
375     RefPtr<ResourceObject> offsetXResObj;
376     double offsetX = 0.0;
377     bool stateX = JSViewAbstract::ParseJsDouble(jsOffsetX, offsetX, offsetXResObj);
378     if (offsetXResObj) {
379         auto&& offsetXUpdateFunc = [](const RefPtr<ResourceObject>& resObj, NG::GaugeShadowOptions& shadowOptions) {
380             double offsetX = 0.0;
381             if (ResourceParseUtils::ParseResDouble(resObj, offsetX)) {
382                 shadowOptions.offsetX = offsetX;
383             } else {
384                 shadowOptions.offsetX = NG::DEFAULT_GAUGE_SHADOW_OFFSETX;
385             }
386         };
387         shadowOptions.AddResource("gauge.shadow.offsetX", offsetXResObj, std::move(offsetXUpdateFunc));
388     }
389     if (stateX) {
390         shadowOptions.offsetX = offsetX;
391     } else {
392         shadowOptions.offsetX = NG::DEFAULT_GAUGE_SHADOW_OFFSETX;
393     }
394 }
395 
HandleShadowOffsetY(const JSRef<JSVal> & jsOffsetY,NG::GaugeShadowOptions & shadowOptions)396 void HandleShadowOffsetY(const JSRef<JSVal>& jsOffsetY, NG::GaugeShadowOptions& shadowOptions)
397 {
398     RefPtr<ResourceObject> offsetYResObj;
399     double offsetY = 0.0;
400     bool stateY = JSViewAbstract::ParseJsDouble(jsOffsetY, offsetY, offsetYResObj);
401     if (offsetYResObj) {
402         auto&& offsetYUpdateFunc = [](const RefPtr<ResourceObject>& resObj, NG::GaugeShadowOptions& shadowOptions) {
403             double offsetY = 0.0;
404             if (ResourceParseUtils::ParseResDouble(resObj, offsetY)) {
405                 shadowOptions.offsetY = offsetY;
406             } else {
407                 shadowOptions.offsetY = NG::DEFAULT_GAUGE_SHADOW_OFFSETY;
408             }
409         };
410         shadowOptions.AddResource("gauge.shadow.offsetY", offsetYResObj, std::move(offsetYUpdateFunc));
411     }
412     if (stateY) {
413         shadowOptions.offsetY = offsetY;
414     } else {
415         shadowOptions.offsetY = NG::DEFAULT_GAUGE_SHADOW_OFFSETY;
416     }
417 }
418 
HandleShadowOptionsWithConfigChange(const JSRef<JSVal> & jsRadius,const JSRef<JSVal> & jsOffsetX,const JSRef<JSVal> & jsOffsetY,NG::GaugeShadowOptions & shadowOptions)419 void HandleShadowOptionsWithConfigChange(const JSRef<JSVal>& jsRadius, const JSRef<JSVal>& jsOffsetX,
420     const JSRef<JSVal>& jsOffsetY, NG::GaugeShadowOptions& shadowOptions)
421 {
422     HandleShadowRadius(jsRadius, shadowOptions);
423     HandleShadowOffsetX(jsOffsetX, shadowOptions);
424     HandleShadowOffsetY(jsOffsetY, shadowOptions);
425     GaugeModel::GetInstance()->SetShadowOptions(shadowOptions);
426 }
427 
SetShadowOptions(const JSCallbackInfo & info)428 void JSGauge::SetShadowOptions(const JSCallbackInfo& info)
429 {
430     NG::GaugeShadowOptions shadowOptions;
431     if (info[0]->IsNull()) {
432         shadowOptions.isShadowVisible = false;
433         GaugeModel::GetInstance()->SetShadowOptions(shadowOptions);
434         return;
435     }
436 
437     if (!info[0]->IsObject()) {
438         GaugeModel::GetInstance()->ResetShadowOptions();
439         return;
440     }
441 
442     auto paramObject = JSRef<JSObject>::Cast(info[0]);
443     JSRef<JSVal> jsRadius = paramObject->GetProperty("radius");
444     JSRef<JSVal> jsOffsetX = paramObject->GetProperty("offsetX");
445     JSRef<JSVal> jsOffsetY = paramObject->GetProperty("offsetY");
446 
447     if (SystemProperties::ConfigChangePerform()) {
448         HandleShadowOptionsWithConfigChange(jsRadius, jsOffsetX, jsOffsetY, shadowOptions);
449     } else {
450         double radius = 0.0;
451         if (!ParseJsDouble(jsRadius, radius)) {
452             radius = NG::DEFAULT_GAUGE_SHADOW_RADIUS;
453         }
454 
455         if (NonPositive(radius)) {
456             radius = NG::DEFAULT_GAUGE_SHADOW_RADIUS;
457         }
458 
459         double offsetX = 0.0;
460         if (!ParseJsDouble(jsOffsetX, offsetX)) {
461             offsetX = NG::DEFAULT_GAUGE_SHADOW_OFFSETX;
462         }
463 
464         double offsetY = 0.0;
465         if (!ParseJsDouble(jsOffsetY, offsetY)) {
466             offsetY = NG::DEFAULT_GAUGE_SHADOW_OFFSETY;
467         }
468 
469         shadowOptions.radius = radius;
470         shadowOptions.offsetX = offsetX;
471         shadowOptions.offsetY = offsetY;
472 
473         GaugeModel::GetInstance()->SetShadowOptions(shadowOptions);
474     }
475 }
476 
SetDescription(const JSCallbackInfo & info)477 void JSGauge::SetDescription(const JSCallbackInfo& info)
478 {
479     if (info[0]->IsNull()) {
480         GaugeModel::GetInstance()->SetIsShowLimitValue(false);
481         GaugeModel::GetInstance()->SetIsShowDescription(false);
482         return;
483     }
484     if (info[0]->IsUndefined() || !info[0]->IsObject()) {
485         GaugeModel::GetInstance()->SetIsShowLimitValue(true);
486         GaugeModel::GetInstance()->SetIsShowDescription(false);
487         return;
488     }
489 
490     auto builderObject = JSRef<JSObject>::Cast(info[0])->GetProperty("builder");
491     if (builderObject->IsFunction()) {
492         GaugeModel::GetInstance()->SetIsShowLimitValue(false);
493         GaugeModel::GetInstance()->SetIsShowDescription(true);
494         ViewStackModel::GetInstance()->NewScope();
495         JsFunction jsBuilderFunc(info.This(), JSRef<JSFunc>::Cast(builderObject));
496         ACE_SCORING_EVENT("Gauge.description.builder");
497         jsBuilderFunc.Execute();
498         auto customNode = ViewStackModel::GetInstance()->Finish();
499         GaugeModel::GetInstance()->SetDescription(customNode);
500     } else {
501         GaugeModel::GetInstance()->SetIsShowLimitValue(true);
502         GaugeModel::GetInstance()->SetIsShowDescription(false);
503     }
504 }
505 
HandleIndicatorIcon(const JSRef<JSVal> & jsIcon)506 void HandleIndicatorIcon(const JSRef<JSVal>& jsIcon)
507 {
508     std::string iconPath;
509     if (SystemProperties::ConfigChangePerform()) {
510         RefPtr<ResourceObject> resObj;
511         bool state = JSViewAbstract::ParseJsMedia(jsIcon, iconPath, resObj);
512         GaugeModel::GetInstance()->CreateWithResourceObj(OHOS::Ace::GaugeResourceType::INDICATOR_ICON, resObj);
513         if (state) {
514             GaugeModel::GetInstance()->SetIndicatorIconPath(iconPath, "", "");
515         } else {
516             GaugeModel::GetInstance()->ResetIndicatorIconPath();
517         }
518     } else {
519         if (JSViewAbstract::ParseJsMedia(jsIcon, iconPath)) {
520             std::string bundleName;
521             std::string moduleName;
522             JSViewAbstract::GetJsMediaBundleInfo(jsIcon, bundleName, moduleName);
523             GaugeModel::GetInstance()->SetIndicatorIconPath(iconPath, bundleName, moduleName);
524         } else {
525             GaugeModel::GetInstance()->ResetIndicatorIconPath();
526         }
527     }
528 }
529 
HandleIndicatorSpace(const JSRef<JSVal> & jsSpace)530 void HandleIndicatorSpace(const JSRef<JSVal>& jsSpace)
531 {
532     CalcDimension space;
533     if (SystemProperties::ConfigChangePerform()) {
534         RefPtr<ResourceObject> resObj;
535         bool state = JSViewAbstract::ParseJsDimensionVpNG(jsSpace, space, resObj, false);
536         GaugeModel::GetInstance()->CreateWithResourceObj(OHOS::Ace::GaugeResourceType::INDICATOR_SPACE, resObj);
537         if (state) {
538             if (space.IsNegative()) {
539                 space = NG::INDICATOR_DISTANCE_TO_TOP;
540             }
541             GaugeModel::GetInstance()->SetIndicatorSpace(space);
542         } else {
543             space = NG::INDICATOR_DISTANCE_TO_TOP;
544             GaugeModel::GetInstance()->SetIndicatorSpace(space);
545         }
546     } else {
547         if (!JSViewAbstract::ParseJsDimensionVpNG(jsSpace, space, false)) {
548             space = NG::INDICATOR_DISTANCE_TO_TOP;
549         }
550         if (space.IsNegative()) {
551             space = NG::INDICATOR_DISTANCE_TO_TOP;
552         }
553         GaugeModel::GetInstance()->SetIndicatorSpace(space);
554     }
555 }
556 
SetIndicator(const JSCallbackInfo & info)557 void JSGauge::SetIndicator(const JSCallbackInfo& info)
558 {
559     if (SystemProperties::ConfigChangePerform()) {
560         GaugeModel::GetInstance()->SetUseSpecialDefaultIndicator(false);
561     }
562     if (info[0]->IsNull()) {
563         GaugeModel::GetInstance()->SetIsShowIndicator(false);
564         return;
565     }
566 
567     if (!info[0]->IsObject()) {
568         GaugeModel::GetInstance()->ResetIndicatorIconPath();
569         GaugeModel::GetInstance()->ResetIndicatorSpace();
570         GaugeModel::GetInstance()->SetIsShowIndicator(true);
571         return;
572     }
573 
574     GaugeModel::GetInstance()->SetIsShowIndicator(true);
575     auto paramObject = JSRef<JSObject>::Cast(info[0]);
576     JSRef<JSVal> jsIcon = paramObject->GetProperty("icon");
577     JSRef<JSVal> jsSpace = paramObject->GetProperty("space");
578 
579     HandleIndicatorIcon(jsIcon);
580     HandleIndicatorSpace(jsSpace);
581 }
582 } // namespace OHOS::Ace::Framework
583