• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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_progress.h"
17 
18 #include "base/utils/utils.h"
19 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
20 #include "bridge/declarative_frontend/jsview/js_linear_gradient.h"
21 #include "bridge/declarative_frontend/jsview/models/progress_model_impl.h"
22 #include "core/components/common/properties/color.h"
23 #include "core/components/progress/progress_theme.h"
24 #include "core/components/text/text_theme.h"
25 #include "core/components_ng/pattern/progress/progress_model_ng.h"
26 
27 namespace OHOS::Ace {
28 
29 std::unique_ptr<ProgressModel> ProgressModel::instance_ = nullptr;
30 std::mutex ProgressModel::mutex_;
31 ProgressType g_progressType = ProgressType::LINEAR;
32 
GetInstance()33 ProgressModel* ProgressModel::GetInstance()
34 {
35 #ifdef NG_BUILD
36     static NG::ProgressModelNG instance;
37     return &instance;
38 #else
39     if (Container::IsCurrentUseNewPipeline()) {
40         static NG::ProgressModelNG instance;
41         return &instance;
42     } else {
43         static Framework::ProgressModelImpl instance;
44         return &instance;
45     }
46 #endif
47 }
48 
49 } // namespace OHOS::Ace
50 
51 namespace OHOS::Ace::Framework {
Create(const JSCallbackInfo & info)52 void JSProgress::Create(const JSCallbackInfo& info)
53 {
54     if (!info[0]->IsObject()) {
55         return;
56     }
57     auto paramObject = JSRef<JSObject>::Cast(info[0]);
58 
59     auto value = 0;
60     auto jsValue = paramObject->GetProperty("value");
61     if (jsValue->IsNumber()) {
62         value = jsValue->ToNumber<double>();
63     }
64 
65     auto total = 100;
66     auto jsTotal = paramObject->GetProperty("total");
67     if (jsTotal->IsNumber() && jsTotal->ToNumber<int>() > 0) {
68         total = jsTotal->ToNumber<int>();
69     }
70 
71     if (value > total) {
72         value = total;
73     } else if (value < 0) {
74         value = 0;
75     }
76 
77     auto jsStyle = paramObject->GetProperty("type");
78     if (jsStyle->IsNull() || jsStyle->IsUndefined()) {
79         jsStyle = paramObject->GetProperty("style");
80     }
81 
82     auto progressStyle = ProgressStyle::Linear;
83     if (jsStyle->IsNumber()) {
84         progressStyle = static_cast<ProgressStyle>(jsStyle->ToNumber<int32_t>());
85     }
86     if (progressStyle == ProgressStyle::Eclipse) {
87         g_progressType = ProgressType::MOON;
88     } else if (progressStyle == ProgressStyle::Ring) {
89         g_progressType = ProgressType::RING;
90     } else if (progressStyle == ProgressStyle::ScaleRing) {
91         g_progressType = ProgressType::SCALE;
92     } else if (progressStyle == ProgressStyle::Capsule) {
93         g_progressType = ProgressType::CAPSULE;
94     } else {
95         g_progressType = ProgressType::LINEAR;
96     }
97 
98     ProgressModel::GetInstance()->Create(0.0, value, 0.0, total, static_cast<NG::ProgressType>(g_progressType));
99 }
100 
JSBind(BindingTarget globalObj)101 void JSProgress::JSBind(BindingTarget globalObj)
102 {
103     JSClass<JSProgress>::Declare("Progress");
104     MethodOptions opt = MethodOptions::NONE;
105 
106     JSClass<JSProgress>::StaticMethod("create", &JSProgress::Create, opt);
107     JSClass<JSProgress>::StaticMethod("value", &JSProgress::SetValue, opt);
108     JSClass<JSProgress>::StaticMethod("color", &JSProgress::SetColor, opt);
109     JSClass<JSProgress>::StaticMethod("style", &JSProgress::SetCircularStyle, opt);
110     JSClass<JSProgress>::StaticMethod("backgroundColor", &JSProgress::JsBackgroundColor, opt);
111     JSClass<JSProgress>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
112     JSClass<JSProgress>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
113     JSClass<JSProgress>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
114     JSClass<JSProgress>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
115     JSClass<JSProgress>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
116     JSClass<JSProgress>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
117     JSClass<JSProgress>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
118     JSClass<JSProgress>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
119     JSClass<JSProgress>::StaticMethod("borderColor", &JSProgress::JsBorderColor, opt);
120     JSClass<JSProgress>::InheritAndBind<JSViewAbstract>(globalObj);
121 }
122 
SetValue(double value)123 void JSProgress::SetValue(double value)
124 {
125     if (std::isnan(value)) {
126         return;
127     }
128     if (value < 0) {
129         value = 0;
130     }
131     ProgressModel::GetInstance()->SetValue(value);
132 }
133 
SetColor(const JSCallbackInfo & info)134 void JSProgress::SetColor(const JSCallbackInfo& info)
135 {
136     Color colorVal;
137     NG::Gradient gradient;
138     bool gradientColorByUser = true;
139     RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
140     if (ConvertGradientColor(info[0], gradient)) {
141         ProgressModel::GetInstance()->SetGradientColor(gradient);
142     } else {
143         RefPtr<ResourceObject> resObj;
144         Color endColor;
145         Color beginColor;
146         if (info[0]->IsNull() || info[0]->IsUndefined() || !ParseJsColor(info[0], colorVal, resObj)) {
147             endColor = theme->GetRingProgressEndSideColor();
148             beginColor = theme->GetRingProgressBeginSideColor();
149             colorVal = (g_progressType == ProgressType::CAPSULE) ? theme->GetCapsuleParseFailedSelectColor()
150                                                                  : theme->GetTrackParseFailedSelectedColor();
151             gradientColorByUser = false;
152         } else {
153             endColor = colorVal;
154             beginColor = colorVal;
155         }
156         if (SystemProperties::ConfigChangePerform()) {
157             ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::COLOR, resObj);
158         }
159         NG::GradientColor endSideColor;
160         NG::GradientColor beginSideColor;
161         endSideColor.SetLinearColor(LinearColor(endColor));
162         endSideColor.SetDimension(Dimension(0.0f));
163         beginSideColor.SetLinearColor(LinearColor(beginColor));
164         beginSideColor.SetDimension(Dimension(1.0f));
165         gradient.AddColor(endSideColor);
166         gradient.AddColor(beginSideColor);
167         ProgressModel::GetInstance()->SetGradientColor(gradient);
168         ProgressModel::GetInstance()->SetColor(colorVal);
169     }
170     if (SystemProperties::ConfigChangePerform()) {
171         ProgressModel::GetInstance()->SetGradientColorByUser(gradientColorByUser);
172     }
173 }
174 
SetCircularStyle(const JSCallbackInfo & info)175 void JSProgress::SetCircularStyle(const JSCallbackInfo& info)
176 {
177     if (!info[0]->IsObject()) {
178         return;
179     }
180 
181     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
182         JsSetProgressStyleOptions(info);
183         return;
184     }
185 
186     JsSetCommonOptions(info);
187 
188     switch (g_progressType) {
189         case ProgressType::LINEAR:
190             JsSetLinearStyleOptions(info);
191             break;
192         case ProgressType::RING:
193             JsSetRingStyleOptions(info);
194             break;
195         case ProgressType::CAPSULE:
196             JsSetCapsuleStyle(info);
197             break;
198         default:
199             JsSetProgressStyleOptions(info);
200             break;
201     }
202 }
203 
JsSetProgressStyleOptions(const JSCallbackInfo & info)204 void JSProgress::JsSetProgressStyleOptions(const JSCallbackInfo& info)
205 {
206     static const char attrsProgressStrokeWidth[] = "strokeWidth";
207     static const char attrsProgressScaleWidth[] = "scaleWidth";
208     auto paramObject = JSRef<JSObject>::Cast(info[0]);
209     RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
210     CHECK_NULL_VOID(theme);
211 
212     CalcDimension strokeWidthDimension;
213     RefPtr<ResourceObject> strokeWidthResObj;
214     auto jsStrokeWidth = paramObject->GetProperty(attrsProgressStrokeWidth);
215     if (!CheckLength(
216         jsStrokeWidth, strokeWidthDimension, V2::PROGRESS_ETS_TAG, attrsProgressStrokeWidth, strokeWidthResObj)) {
217         strokeWidthDimension = theme->GetTrackThickness();
218     }
219 
220     if (strokeWidthDimension.Value() <= 0.0 || strokeWidthDimension.Unit() == DimensionUnit::PERCENT) {
221         strokeWidthDimension = theme->GetTrackThickness();
222     }
223 
224     if (SystemProperties::ConfigChangePerform()) {
225         ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::PSStrokeWidth, strokeWidthResObj);
226     }
227     ProgressModel::GetInstance()->SetStrokeWidth(strokeWidthDimension);
228 
229     auto jsScaleCount = paramObject->GetProperty("scaleCount");
230     auto scaleCount = jsScaleCount->IsNumber() ? jsScaleCount->ToNumber<int32_t>() : theme->GetScaleNumber();
231     if (scaleCount > 1.0) {
232         ProgressModel::GetInstance()->SetScaleCount(scaleCount);
233     } else {
234         ProgressModel::GetInstance()->SetScaleCount(theme->GetScaleNumber());
235     }
236 
237     CalcDimension scaleWidthDimension;
238     RefPtr<ResourceObject> scaleWidthResObj;
239     auto jsScaleWidth = paramObject->GetProperty(attrsProgressScaleWidth);
240     if (!CheckLength(
241         jsScaleWidth, scaleWidthDimension, V2::PROGRESS_ETS_TAG, attrsProgressScaleWidth, scaleWidthResObj)) {
242         scaleWidthDimension = theme->GetScaleWidth();
243     }
244 
245     if ((scaleWidthDimension.Value() <= 0.0) || (scaleWidthDimension.Value() > strokeWidthDimension.Value()) ||
246         scaleWidthDimension.Unit() == DimensionUnit::PERCENT) {
247         scaleWidthDimension = theme->GetScaleWidth();
248     }
249     if (SystemProperties::ConfigChangePerform()) {
250         ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::PSScaleWidth, scaleWidthResObj);
251     }
252     ProgressModel::GetInstance()->SetScaleWidth(scaleWidthDimension);
253 }
254 
ConvertStrToProgressStatus(const std::string & value)255 NG::ProgressStatus JSProgress::ConvertStrToProgressStatus(const std::string& value)
256 {
257     if (value.compare("LOADING") == 0) {
258         return NG::ProgressStatus::LOADING;
259     } else {
260         return NG::ProgressStatus::PROGRESSING;
261     }
262 }
263 
JsSetRingStyleOptions(const JSCallbackInfo & info)264 void JSProgress::JsSetRingStyleOptions(const JSCallbackInfo& info)
265 {
266     auto paramObject = JSRef<JSObject>::Cast(info[0]);
267     ProcessRingStrokeWidth(paramObject);
268     // Parse stroke width
269     bool state = false;
270 
271     // Parse shadow
272     bool paintShadow = false;
273     RefPtr<ResourceObject> shadowResObj;
274     auto shadow = paramObject->GetProperty("shadow");
275 
276     if (shadow->IsUndefined() || shadow->IsNull()) {
277         paintShadow = false;
278     }
279     state = ParseJsBool(shadow, paintShadow, shadowResObj);
280     if (!state) {
281         paintShadow = false;
282     }
283 
284     if (SystemProperties::ConfigChangePerform()) {
285         ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::RingShadow, shadowResObj);
286     }
287     ProgressModel::GetInstance()->SetPaintShadow(paintShadow);
288 
289     // Parse progress status
290     std::string statusStr;
291     NG::ProgressStatus progressStatus;
292     auto status = paramObject->GetProperty("status");
293     RefPtr<ResourceObject> statusResObj;
294     if (status->IsUndefined() || status->IsNull()) {
295         progressStatus = NG::ProgressStatus::PROGRESSING;
296     }
297     if (!ParseJsString(status, statusStr, statusResObj)) {
298         progressStatus = NG::ProgressStatus::PROGRESSING;
299     }
300     if (SystemProperties::ConfigChangePerform()) {
301         ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::RingStatus, statusResObj);
302     }
303     progressStatus = ConvertStrToProgressStatus(statusStr);
304     ProgressModel::GetInstance()->SetProgressStatus(static_cast<NG::ProgressStatus>(progressStatus));
305 
306     auto jsSweepingEffect = paramObject->GetProperty("enableScanEffect");
307     bool sweepingEffect = false;
308     RefPtr<ResourceObject> sweepingEffectResObj;
309     state = ParseJsBool(jsSweepingEffect, sweepingEffect, sweepingEffectResObj);
310     if (!state) {
311         sweepingEffect = false;
312     }
313     if (SystemProperties::ConfigChangePerform()) {
314         ProgressModel::GetInstance()->CreateWithResourceObj(
315             JsProgressResourceType::RingSweepingEffect, sweepingEffectResObj);
316     }
317     ProgressModel::GetInstance()->SetRingSweepingEffect(sweepingEffect);
318 }
319 
JsBackgroundColor(const JSCallbackInfo & info)320 void JSProgress::JsBackgroundColor(const JSCallbackInfo& info)
321 {
322     Color colorVal;
323     RefPtr<ResourceObject> bgColorResObj;
324     bool state = CheckColor(info[0], colorVal, V2::PROGRESS_ETS_TAG, V2::ATTRS_COMMON_BACKGROUND_COLOR, bgColorResObj);
325     if (SystemProperties::ConfigChangePerform()) {
326         ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::BackgroundColor, bgColorResObj);
327     }
328     if (!state) {
329         RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
330         CHECK_NULL_VOID(theme);
331         colorVal = (g_progressType == ProgressType::CAPSULE) ? theme->GetCapsuleParseFailedBgColor()
332                    : (g_progressType == ProgressType::RING)  ? theme->GetRingProgressParseFailedBgColor()
333                                                              : theme->GetTrackParseFailedBgColor();
334     }
335 
336     ProgressModel::GetInstance()->SetBackgroundColor(colorVal);
337 }
338 
JsBorderColor(const JSCallbackInfo & info)339 void JSProgress::JsBorderColor(const JSCallbackInfo& info)
340 {
341     JSViewAbstract::JsBorderColor(info);
342 }
343 
JsSetCapsuleStyle(const JSCallbackInfo & info)344 void JSProgress::JsSetCapsuleStyle(const JSCallbackInfo& info)
345 {
346     if (!info[0]->IsObject()) {
347         return;
348     }
349     if (SystemProperties::ConfigChangePerform()) {
350         ProgressModel::GetInstance()->SetCapsuleStyle(true);
351     }
352     auto paramObject = JSRef<JSObject>::Cast(info[0]);
353 
354     ProcessCapsuleBorderWidth(paramObject);
355     ProcessCapsuleBorderColor(paramObject);
356 
357     auto jsSweepingEffect = paramObject->GetProperty("enableScanEffect");
358     bool sweepingEffect = false;
359     RefPtr<ResourceObject> sweepingEffectResObj;
360     bool state = ParseJsBool(jsSweepingEffect, sweepingEffect, sweepingEffectResObj);
361     if (SystemProperties::ConfigChangePerform()) {
362         ProgressModel::GetInstance()->CreateWithResourceObj(
363             JsProgressResourceType::CapsuleSweepingEffect, sweepingEffectResObj);
364     }
365     if (!state) {
366         sweepingEffect = false;
367     }
368     ProgressModel::GetInstance()->SetSweepingEffect(sweepingEffect);
369 
370     auto jsShowDefaultPercentage = paramObject->GetProperty("showDefaultPercentage");
371     bool showDefaultPercentage = false;
372     RefPtr<ResourceObject> showDefaultPercentageObj;
373     state = ParseJsBool(jsShowDefaultPercentage, showDefaultPercentage, showDefaultPercentageObj);
374     if (SystemProperties::ConfigChangePerform()) {
375         ProgressModel::GetInstance()->CreateWithResourceObj(
376             JsProgressResourceType::ShowDefaultPercentage, showDefaultPercentageObj);
377     }
378     if (!state) {
379         showDefaultPercentage = false;
380     }
381     ProgressModel::GetInstance()->SetShowText(showDefaultPercentage);
382 
383     ProcessCapsuleContent(paramObject);
384     JsSetFontStyle(info);
385     JsSetBorderRadius(paramObject);
386 }
387 
JsSetCommonOptions(const JSCallbackInfo & info)388 void JSProgress::JsSetCommonOptions(const JSCallbackInfo& info)
389 {
390     auto paramObject = JSRef<JSObject>::Cast(info[0]);
391 
392     // Parse smooth effect
393     auto jsSmoothEffect = paramObject->GetProperty("enableSmoothEffect");
394     RefPtr<ResourceObject> smoothEffectResObj;
395     bool enable = true;
396     if (!ParseJsBool(jsSmoothEffect, enable, smoothEffectResObj)) {
397         enable = true;
398     }
399     if (SystemProperties::ConfigChangePerform()) {
400         ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::SmoothEffect, smoothEffectResObj);
401     }
402     ProgressModel::GetInstance()->SetSmoothEffect(enable);
403 }
404 
JsSetFontStyle(const JSCallbackInfo & info)405 void JSProgress::JsSetFontStyle(const JSCallbackInfo& info)
406 {
407     auto paramObject = JSRef<JSObject>::Cast(info[0]);
408     auto jsFontColor = paramObject->GetProperty("fontColor");
409     Color fontColorVal;
410     RefPtr<ResourceObject> fontColorResObj;
411     bool state = ParseJsColor(jsFontColor, fontColorVal, fontColorResObj);
412     if (SystemProperties::ConfigChangePerform()) {
413         ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::FontColor, fontColorResObj);
414     }
415     if (!state) {
416         ProgressModel::GetInstance()->ResetFontColor();
417     } else {
418         ProgressModel::GetInstance()->SetFontColor(fontColorVal);
419     }
420     if (SystemProperties::ConfigChangePerform()) {
421         ProgressModel::GetInstance()->SetCapsuleStyleFontColor(state);
422     }
423     auto textStyle = paramObject->GetProperty("font");
424     if (!textStyle->IsObject()) {
425         JsSetFontDefault();
426     } else {
427         auto textObject = JSRef<JSObject>::Cast(textStyle);
428         JsSetFont(textObject);
429     }
430 }
431 
JsSetFontDefault()432 void JSProgress::JsSetFontDefault()
433 {
434     RefPtr<TextTheme> textTheme = GetTheme<TextTheme>();
435     RefPtr<ProgressTheme> progressTheme = GetTheme<ProgressTheme>();
436     ProgressModel::GetInstance()->SetFontSize(progressTheme->GetTextSize());
437     ProgressModel::GetInstance()->SetFontFamily(textTheme->GetTextStyle().GetFontFamilies());
438     ProgressModel::GetInstance()->SetFontWeight(textTheme->GetTextStyle().GetFontWeight());
439     ProgressModel::GetInstance()->SetItalicFontStyle(textTheme->GetTextStyle().GetFontStyle());
440 }
441 
JsSetFont(const JSRef<JSObject> & textObject)442 void JSProgress::JsSetFont(const JSRef<JSObject>& textObject)
443 {
444     RefPtr<TextTheme> textTheme = GetTheme<TextTheme>();
445     CHECK_NULL_VOID(textTheme);
446     ProcessFontSizeOption(textObject);
447     auto fontWeight = textObject->GetProperty("weight");
448     RefPtr<ResourceObject> weightResObj;
449     bool weightState = false;
450     if (!fontWeight->IsNull()) {
451         std::string weight;
452         if (fontWeight->IsNumber()) {
453             weight = std::to_string(fontWeight->ToNumber<int32_t>());
454         } else {
455             weightState = ParseJsString(fontWeight, weight, weightResObj);
456         }
457         if (SystemProperties::ConfigChangePerform()) {
458             ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::FontWeight, weightResObj);
459         }
460         auto fontWeightVal = ConvertStrToFontWeight(weight);
461         ProgressModel::GetInstance()->SetFontWeight(fontWeightVal);
462     } else {
463         ProgressModel::GetInstance()->SetFontWeight(textTheme->GetTextStyle().GetFontWeight());
464     }
465     auto family = textObject->GetProperty("family");
466     if (!family->IsNull() && family->IsString()) {
467         auto familyVal = family->ToString();
468         ProgressModel::GetInstance()->SetFontFamily(ConvertStrToFontFamilies(familyVal));
469     } else {
470         ProgressModel::GetInstance()->SetFontFamily(textTheme->GetTextStyle().GetFontFamilies());
471     }
472     auto style = textObject->GetProperty("style");
473     if (!style->IsNull() && style->IsNumber()) {
474         auto styleVal = static_cast<FontStyle>(style->ToNumber<int32_t>());
475         ProgressModel::GetInstance()->SetItalicFontStyle(styleVal);
476     } else {
477         ProgressModel::GetInstance()->SetItalicFontStyle(textTheme->GetTextStyle().GetFontStyle());
478     }
479 }
480 
ConvertGradientColor(const JsiRef<JsiValue> & param,NG::Gradient & gradient)481 bool JSProgress::ConvertGradientColor(const JsiRef<JsiValue>& param, NG::Gradient& gradient)
482 {
483     if (param->IsNull() || param->IsUndefined() || !param->IsObject()) {
484         return false;
485     }
486 
487     JSLinearGradient* jsLinearGradient = JSRef<JSObject>::Cast(param)->Unwrap<JSLinearGradient>();
488     auto proxy = param->GetLocalHandle();
489     auto vm = param->GetEcmaVM();
490     if (proxy->IsProxy(vm)) {
491         panda::Local<panda::ProxyRef> thisProxiedObj =
492             static_cast<panda::Local<panda::ProxyRef>>(proxy);
493         jsLinearGradient = static_cast<JSLinearGradient *>(
494             panda::Local<panda::ObjectRef>(thisProxiedObj->GetTarget(vm))
495                 ->GetNativePointerField(vm, 0));
496     }
497 
498     if (!jsLinearGradient || jsLinearGradient->GetGradient().empty()) {
499         return false;
500     }
501 
502     size_t size = jsLinearGradient->GetGradient().size();
503     if (size == 1) {
504         // If there is only one color, then this color is used for both the begin and end side.
505         NG::GradientColor gradientColor;
506         gradientColor.SetLinearColor(LinearColor(jsLinearGradient->GetGradient().front().first));
507         gradientColor.SetDimension(jsLinearGradient->GetGradient().front().second);
508         gradient.AddColor(gradientColor);
509         gradient.AddColor(gradientColor);
510         return true;
511     }
512 
513     for (size_t colorIndex = 0; colorIndex < size; colorIndex++) {
514         NG::GradientColor gradientColor;
515         gradientColor.SetLinearColor(LinearColor(jsLinearGradient->GetGradient().at(colorIndex).first));
516         gradientColor.SetDimension(jsLinearGradient->GetGradient().at(colorIndex).second);
517         gradient.AddColor(gradientColor);
518     }
519     return true;
520 }
521 
JsSetLinearStyleOptions(const JSCallbackInfo & info)522 void JSProgress::JsSetLinearStyleOptions(const JSCallbackInfo& info)
523 {
524     auto paramObject = JSRef<JSObject>::Cast(info[0]);
525     ProcessLinearStrokeWidth(paramObject);
526     // Parse stroke width
527     bool state = false;
528     RefPtr<ResourceObject> sweepingEffectResObj;
529     RefPtr<ResourceObject> strokeRadiusResObj;
530 
531     auto jsSweepingEffect = paramObject->GetProperty("enableScanEffect");
532     bool sweepingEffect = false;
533     state = ParseJsBool(jsSweepingEffect, sweepingEffect, sweepingEffectResObj);
534     if (!state) {
535         sweepingEffect = false;
536     }
537     if (SystemProperties::ConfigChangePerform()) {
538         ProgressModel::GetInstance()->CreateWithResourceObj(
539             JsProgressResourceType::LSSweepingEffect, sweepingEffectResObj);
540     }
541     ProgressModel::GetInstance()->SetLinearSweepingEffect(sweepingEffect);
542 
543     CalcDimension strokeRadiusDimension;
544     auto strokeRadius = paramObject->GetProperty("strokeRadius");
545     if (strokeRadius->IsUndefined() || strokeRadius->IsNull()) {
546         ProgressModel::GetInstance()->ResetStrokeRadius();
547         return;
548     }
549     bool radiusState = ParseJsDimensionVpNG(strokeRadius, strokeRadiusDimension, strokeRadiusResObj);
550     if (SystemProperties::ConfigChangePerform()) {
551         ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::LSStrokeRadius, strokeRadiusResObj);
552     }
553     if (!radiusState) {
554         ProgressModel::GetInstance()->ResetStrokeRadius();
555         return;
556     }
557 
558     if (LessNotEqual(strokeRadiusDimension.Value(), 0.0f) || strokeRadiusDimension.Unit() == DimensionUnit::PERCENT) {
559         ProgressModel::GetInstance()->ResetStrokeRadius();
560         return;
561     }
562     ProgressModel::GetInstance()->SetStrokeRadius(strokeRadiusDimension);
563 }
564 
JsSetBorderRadius(const JSRef<JSObject> & paramObject)565 void JSProgress::JsSetBorderRadius(const JSRef<JSObject>& paramObject)
566 {
567     CalcDimension radiusDimension;
568     auto borderRadius = paramObject->GetProperty("borderRadius");
569     if (!borderRadius->IsObject() || !ParseJsLengthMetricsVp(JSRef<JSObject>::Cast(borderRadius), radiusDimension)) {
570         ProgressModel::GetInstance()->ResetBorderRadius();
571         return;
572     }
573     if (LessNotEqual(radiusDimension.Value(), 0.0f) || radiusDimension.Unit() == DimensionUnit::PERCENT) {
574         ProgressModel::GetInstance()->ResetBorderRadius();
575         return;
576     }
577     ProgressModel::GetInstance()->SetBorderRadius(radiusDimension);
578 }
579 
ProcessLinearStrokeWidth(const JSRef<JSObject> & paramObject)580 void JSProgress::ProcessLinearStrokeWidth(const JSRef<JSObject>& paramObject)
581 {
582     RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
583     CHECK_NULL_VOID(theme);
584     auto jsStrokeWidth = paramObject->GetProperty("strokeWidth");
585     CalcDimension strokeWidthDimension;
586     RefPtr<ResourceObject> strokeWidthResObj;
587     bool state = false;
588     if (jsStrokeWidth->IsUndefined() || jsStrokeWidth->IsNull()) {
589         strokeWidthDimension = theme->GetTrackThickness();
590     } else if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
591         state = ParseJsDimensionVpNG(jsStrokeWidth, strokeWidthDimension, strokeWidthResObj);
592     } else {
593         state = ParseJsDimensionVp(jsStrokeWidth, strokeWidthDimension, strokeWidthResObj);
594     }
595     if (!state) {
596         strokeWidthDimension = theme->GetTrackThickness();
597     }
598     if (LessOrEqual(strokeWidthDimension.Value(), 0.0f) || strokeWidthDimension.Unit() == DimensionUnit::PERCENT) {
599         strokeWidthDimension = theme->GetTrackThickness();
600     }
601     if (SystemProperties::ConfigChangePerform()) {
602         ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::LSStrokeWidth, strokeWidthResObj);
603     }
604     ProgressModel::GetInstance()->SetStrokeWidth(strokeWidthDimension);
605 }
606 
ProcessFontSizeOption(const JSRef<JSObject> & textObject)607 void JSProgress::ProcessFontSizeOption(const JSRef<JSObject>& textObject)
608 {
609     RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
610     CHECK_NULL_VOID(theme);
611     auto jsSize = textObject->GetProperty("size");
612     CalcDimension fontSize;
613     RefPtr<ResourceObject> fontSizeResObj;
614     bool sizeState = ParseJsDimensionNG(jsSize, fontSize, DimensionUnit::FP, fontSizeResObj);
615     if (SystemProperties::ConfigChangePerform()) {
616         ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::FontSize, fontSizeResObj);
617     }
618     if (!sizeState || LessNotEqual(fontSize.Value(), 0.0f) || fontSize.Unit() == DimensionUnit::PERCENT) {
619         fontSize = theme->GetTextSize();
620     }
621     ProgressModel::GetInstance()->SetFontSize(fontSize);
622 }
623 
ProcessRingStrokeWidth(const JSRef<JSObject> & paramObject)624 void JSProgress::ProcessRingStrokeWidth(const JSRef<JSObject>& paramObject)
625 {
626     RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
627     CHECK_NULL_VOID(theme);
628     auto jsStrokeWidth = paramObject->GetProperty("strokeWidth");
629     CalcDimension strokeWidthDimension;
630     RefPtr<ResourceObject> strokeWidthResObj;
631     bool state = false;
632     if (jsStrokeWidth->IsUndefined() || jsStrokeWidth->IsNull()) {
633         strokeWidthDimension = theme->GetTrackThickness();
634     } else if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
635         state = ParseJsDimensionVpNG(jsStrokeWidth, strokeWidthDimension, strokeWidthResObj);
636     } else {
637         state = ParseJsDimensionVp(jsStrokeWidth, strokeWidthDimension, strokeWidthResObj);
638     }
639     if (!state) {
640         strokeWidthDimension = theme->GetTrackThickness();
641     }
642     if (LessOrEqual(strokeWidthDimension.Value(), 0.0f) || strokeWidthDimension.Unit() == DimensionUnit::PERCENT) {
643         strokeWidthDimension = theme->GetTrackThickness();
644     }
645     if (SystemProperties::ConfigChangePerform()) {
646         ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::RingStrokeWidth, strokeWidthResObj);
647     }
648     ProgressModel::GetInstance()->SetStrokeWidth(strokeWidthDimension);
649 }
650 
ProcessCapsuleBorderWidth(const JSRef<JSObject> & paramObject)651 void JSProgress::ProcessCapsuleBorderWidth(const JSRef<JSObject>& paramObject)
652 {
653     RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
654     CHECK_NULL_VOID(theme);
655     auto jsBorderWidth = paramObject->GetProperty("borderWidth");
656     CalcDimension borderWidth;
657     RefPtr<ResourceObject> borderWidthResObj;
658     bool state = ParseJsDimensionVpNG(jsBorderWidth, borderWidth, borderWidthResObj);
659     if (SystemProperties::ConfigChangePerform()) {
660         ProgressModel::GetInstance()->CreateWithResourceObj(
661             JsProgressResourceType::CapsuleBorderWidth, borderWidthResObj);
662     }
663     if (!state) {
664         borderWidth = theme->GetBorderWidth();
665     }
666     if (LessNotEqual(borderWidth.Value(), 0.0) || borderWidth.Unit() == DimensionUnit::PERCENT) {
667         borderWidth = theme->GetBorderWidth();
668     }
669     ProgressModel::GetInstance()->SetBorderWidth(borderWidth);
670 }
671 
ProcessCapsuleBorderColor(const JSRef<JSObject> & paramObject)672 void JSProgress::ProcessCapsuleBorderColor(const JSRef<JSObject>& paramObject)
673 {
674     RefPtr<ProgressTheme> theme = GetTheme<ProgressTheme>();
675     CHECK_NULL_VOID(theme);
676     auto jsBorderColor = paramObject->GetProperty("borderColor");
677     Color colorVal;
678     RefPtr<ResourceObject> borderColorResObj;
679     bool state = ParseJsColor(jsBorderColor, colorVal, borderColorResObj);
680     if (SystemProperties::ConfigChangePerform()) {
681         ProgressModel::GetInstance()->CreateWithResourceObj(
682             JsProgressResourceType::CapsuleBorderColor, borderColorResObj);
683     }
684     if (state) {
685         ProgressModel::GetInstance()->SetBorderColor(colorVal);
686     } else {
687         ProgressModel::GetInstance()->ResetBorderColor();
688     }
689 }
690 
ProcessCapsuleContent(const JSRef<JSObject> & paramObject)691 void JSProgress::ProcessCapsuleContent(const JSRef<JSObject>& paramObject)
692 {
693     auto jsContext = paramObject->GetProperty("content");
694     RefPtr<ResourceObject> textResObj;
695     std::string text;
696     if (jsContext->IsUndefined() || jsContext->IsNull()) {
697         ProgressModel::GetInstance()->SetText(std::nullopt);
698     } else {
699         bool parseOk = ParseJsString(jsContext, text, textResObj);
700         if (SystemProperties::ConfigChangePerform() && jsContext->IsObject()) {
701             ProgressModel::GetInstance()->CreateWithResourceObj(JsProgressResourceType::Text, textResObj);
702         }
703         if (parseOk) {
704             ProgressModel::GetInstance()->SetText(text);
705         } else {
706             ProgressModel::GetInstance()->SetText(std::nullopt);
707         }
708     }
709 }
710 } // namespace OHOS::Ace::Framework
711