1 
2 
3 /*
4  * Copyright (c) 2023 Huawei Device Co., Ltd.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_progress_bridge.h"
18 
19 #include "base/utils/utils.h"
20 #include "bridge/declarative_frontend/jsview/js_progress.h"
21 #include "core/components_ng/base/frame_node.h"
22 #include "core/components/progress/progress_theme.h"
23 #include "core/components_ng/pattern/progress/progress_date.h"
24 #include "core/components_ng/pattern/progress/progress_layout_property.h"
25 #include "core/components_ng/pattern/progress/progress_model_ng.h"
26 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
27 #include "bridge/declarative_frontend/jsview/js_linear_gradient.h"
28 
29 namespace OHOS::Ace::NG {
30 constexpr int32_t ARG_NUM_NATIVE_NODE = 0;
31 constexpr int32_t ARG_NUM_VALUE = 1;
32 constexpr int32_t ARG_COLOR_INDEX_VALUE = 1;
33 constexpr int32_t ARG_NUM_STYLE_STROKE_WIDTH = 1;
34 constexpr int32_t ARG_NUM_STYLE_BORDER_WIDTH = 6;
35 constexpr int32_t ARG_NUM_STYLE_PROGRESS_STATUS = 16;
36 constexpr int32_t ARG_NUM_STYLE_FONT_STYLE = 11;
37 constexpr int32_t ARG_NUM_STYLE_SCALE_COUNT = 2;
38 constexpr int32_t ARG_NUM_STYLE_SCALE_WIDTH = 3;
39 constexpr int32_t ARG_NUM_STYLE_FONT_SIZE = 8;
40 constexpr int32_t ARG_NUM_STYLE_ENABLE_SMOOTH_EFFECT = 4;
41 constexpr int32_t ARG_NUM_STYLE_BORDER_COLOR = 5;
42 constexpr int32_t ARG_NUM_STYLE_CONTENT = 7;
43 constexpr int32_t ARG_NUM_STYLE_FONT_WEIGHT = 9;
44 constexpr int32_t ARG_NUM_STYLE_FONT_COLOR = 12;
45 constexpr int32_t ARG_NUM_STYLE_ENABLE_SCAN_EFFECT = 13;
46 constexpr int32_t ARG_NUM_STYLE_SHADOW = 15;
47 constexpr int32_t ARG_NUM_STYLE_SHOW_DEFAULT_PERCENTAGE = 14;
48 constexpr int32_t ARG_NUM_STYLE_FONT_FAMILY = 10;
49 constexpr int32_t ARG_NUM_STYLE_STROKE_RADIUS = 17;
50 constexpr int32_t ARG_SECOND = 2;
51 const char* PROGRESS_NODEPTR_OF_UINODE = "nodePtr_";
52 constexpr double DEFAULT_PROGRESS_VALUE = 0;
53 constexpr double DEFAULT_STROKE_WIDTH = 4;
54 constexpr double DEFAULT_BORDER_WIDTH = 1;
55 constexpr double DEFAULT_SCALE_WIDTH = 2;
56 constexpr double DEFAULT_STROKE_RADIUS = 0;
57 constexpr int32_t DEFAULT_SCALE_COUNT = 120;
58 constexpr Color DEFAULT_BORDER_COLOR = Color(0x33006cde);
59 constexpr Color DEFAULT_FONT_COLOR = Color(0xff182431);
60 constexpr double DEFAULT_CAPSULE_FONT_SIZE = 12;
61 constexpr NG::ProgressStatus DEFAULT_PROGRESS_STATUS = NG::ProgressStatus::PROGRESSING;
62 constexpr DimensionUnit DEFAULT_CAPSULE_FONT_UNIT = DimensionUnit::FP;
63 const std::vector<Ace::FontStyle> FONT_STYLES = { Ace::FontStyle::NORMAL, Ace::FontStyle::ITALIC };
64 const std::vector<NG::ProgressStatus> STATUS_STYLES = { NG::ProgressStatus::PROGRESSING, NG::ProgressStatus::LOADING };
65 
66 namespace {
ConvertProgressRResourceColor(const EcmaVM * vm,const Local<JSValueRef> & item,OHOS::Ace::NG::Gradient & gradient)67 bool ConvertProgressRResourceColor(const EcmaVM* vm, const Local<JSValueRef>& item, OHOS::Ace::NG::Gradient& gradient)
68 {
69     Color color;
70     if (!ArkTSUtils::ParseJsColor(vm, item, color)) {
71         return false;
72     }
73     OHOS::Ace::NG::GradientColor gradientColorStart;
74     gradientColorStart.SetLinearColor(LinearColor(color));
75     gradientColorStart.SetDimension(Dimension(0.0));
76     gradient.AddColor(gradientColorStart);
77     OHOS::Ace::NG::GradientColor gradientColorEnd;
78     gradientColorEnd.SetLinearColor(LinearColor(color));
79     gradientColorEnd.SetDimension(Dimension(1.0));
80     gradient.AddColor(gradientColorEnd);
81     return true;
82 }
83 
ConvertProgressResourceColor(const EcmaVM * vm,const Local<JSValueRef> & itemParam,OHOS::Ace::NG::Gradient & gradient)84 bool ConvertProgressResourceColor(
85     const EcmaVM* vm, const Local<JSValueRef>& itemParam, OHOS::Ace::NG::Gradient& gradient)
86 {
87     if (!itemParam->IsObject(vm)) {
88         return ConvertProgressRResourceColor(vm, itemParam, gradient);
89     }
90     Framework::JSLinearGradient* jsLinearGradient =
91         static_cast<Framework::JSLinearGradient*>(itemParam->ToObject(vm)->GetNativePointerField(vm, 0));
92     if (!jsLinearGradient) {
93         return ConvertProgressRResourceColor(vm, itemParam, gradient);
94     }
95 
96     size_t colorLength = jsLinearGradient->GetGradient().size();
97     if (colorLength == 0) {
98         return false;
99     }
100     for (size_t colorIndex = 0; colorIndex < colorLength; ++colorIndex) {
101         OHOS::Ace::NG::GradientColor gradientColor;
102         gradientColor.SetLinearColor(LinearColor(jsLinearGradient->GetGradient().at(colorIndex).first));
103         gradientColor.SetDimension(jsLinearGradient->GetGradient().at(colorIndex).second);
104         gradient.AddColor(gradientColor);
105     }
106     return true;
107 }
108 } // namespace
109 
ResetProgressValue(ArkUIRuntimeCallInfo * runtimeCallInfo)110 ArkUINativeModuleValue ProgressBridge::ResetProgressValue(ArkUIRuntimeCallInfo* runtimeCallInfo)
111 {
112     EcmaVM* vm = runtimeCallInfo->GetVM();
113     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
114     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(ARG_NUM_NATIVE_NODE);
115     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
116     GetArkUINodeModifiers()->getProgressModifier()->resetProgressValue(nativeNode);
117     return panda::JSValueRef::Undefined(vm);
118 }
119 
SetProgressValue(ArkUIRuntimeCallInfo * runtimeCallInfo)120 ArkUINativeModuleValue ProgressBridge::SetProgressValue(ArkUIRuntimeCallInfo* runtimeCallInfo)
121 {
122     EcmaVM* vm = runtimeCallInfo->GetVM();
123     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
124     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(ARG_NUM_NATIVE_NODE);
125     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(ARG_NUM_VALUE);
126     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
127     if (secondArg->IsNumber()) {
128         ArkUI_Float32 value = secondArg->ToNumber(vm)->Value();
129         if (value < DEFAULT_PROGRESS_VALUE) {
130             value = DEFAULT_PROGRESS_VALUE;
131         }
132         GetArkUINodeModifiers()->getProgressModifier()->setProgressValue(nativeNode, value);
133     } else {
134         GetArkUINodeModifiers()->getProgressModifier()->resetProgressValue(nativeNode);
135     }
136     return panda::JSValueRef::Undefined(vm);
137 }
138 
ResetProgressColor(ArkUIRuntimeCallInfo * runtimeCallInfo)139 ArkUINativeModuleValue ProgressBridge::ResetProgressColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
140 {
141     EcmaVM* vm = runtimeCallInfo->GetVM();
142     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
143     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(ARG_NUM_NATIVE_NODE);
144     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
145     GetArkUINodeModifiers()->getProgressModifier()->resetProgressColor(nativeNode);
146     return panda::JSValueRef::Undefined(vm);
147 }
148 
SetProgressColor(ArkUIRuntimeCallInfo * runtimeCallInfo)149 ArkUINativeModuleValue ProgressBridge::SetProgressColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
150 {
151     EcmaVM* vm = runtimeCallInfo->GetVM();
152     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
153     Local<JSValueRef> nativeArg = runtimeCallInfo->GetCallArgRef(ARG_NUM_NATIVE_NODE);
154     Local<JSValueRef> colorArg = runtimeCallInfo->GetCallArgRef(ARG_COLOR_INDEX_VALUE);
155     auto nativeNode = nodePtr(nativeArg->ToNativePointer(vm)->Value());
156     Color color;
157     OHOS::Ace::NG::Gradient gradient;
158     if (ArkTSUtils::ParseJsColorAlpha(vm, colorArg, color)) {
159         GetArkUINodeModifiers()->getProgressModifier()->setProgressColor(nativeNode, color.GetValue());
160     } else if (ConvertProgressResourceColor(vm, colorArg, gradient)) {
161         ArkUIGradientType gradientObj;
162         auto colorlength = gradient.GetColors().size();
163         std::vector<uint32_t> colorValues;
164         std::vector<ArkUILengthType> offsetValues;
165         if (colorlength <= 0) {
166             GetArkUINodeModifiers()->getProgressModifier()->resetProgressColor(nativeNode);
167             return panda::JSValueRef::Undefined(vm);
168         }
169 
170         for (int32_t i = 0; i < static_cast<int32_t>(colorlength); i++) {
171             colorValues.push_back(gradient.GetColors()[i].GetLinearColor().GetValue());
172             offsetValues.push_back(ArkUILengthType { .number = gradient.GetColors()[i].GetDimension().Value(),
173                 .unit = static_cast<int8_t>(gradient.GetColors()[i].GetDimension().Unit()) });
174         }
175 
176         gradientObj.color = &(*colorValues.begin());
177         gradientObj.offset = &(*offsetValues.begin());
178         GetArkUINodeModifiers()->getProgressModifier()->setProgressGradientColor(
179             nativeNode, &gradientObj, colorlength);
180     } else {
181         GetArkUINodeModifiers()->getProgressModifier()->resetProgressColor(nativeNode);
182     }
183 
184     return panda::JSValueRef::Undefined(vm);
185 }
186 
ResetProgressStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)187 ArkUINativeModuleValue ProgressBridge::ResetProgressStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
188 {
189     EcmaVM* vm = runtimeCallInfo->GetVM();
190     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
191     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(ARG_NUM_NATIVE_NODE);
192     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
193     GetArkUINodeModifiers()->getProgressModifier()->resetProgressStyle(nativeNode);
194     return panda::JSValueRef::Undefined(vm);
195 }
196 
ParseStrokeWidth(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)197 void ParseStrokeWidth(
198     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
199 {
200     Local<JSValueRef> strokeWidthArg = runtimeCallInfo->GetCallArgRef(index);
201     CalcDimension strokeWidth = CalcDimension(DEFAULT_STROKE_WIDTH, DimensionUnit::VP);
202     auto theme = ArkTSUtils::GetTheme<ProgressTheme>();
203 
204     if (strokeWidthArg->IsString(vm)) {
205         const std::string& value = strokeWidthArg->ToString(vm)->ToString(vm);
206         strokeWidth = StringUtils::StringToDimensionWithUnit(value, DimensionUnit::VP, DEFAULT_STROKE_WIDTH);
207     } else {
208         ArkTSUtils::ParseJsDimension(vm, strokeWidthArg, strokeWidth, DimensionUnit::VP, false);
209     }
210 
211     if ((LessOrEqual(strokeWidth.Value(), 0.0f) || strokeWidth.Unit() == DimensionUnit::PERCENT) && theme) {
212         strokeWidth = theme->GetTrackThickness();
213     }
214     if (strokeWidth.IsNegative()) {
215         progressStyle.strokeWidthValue = DEFAULT_STROKE_WIDTH;
216         progressStyle.strokeWidthUnit = static_cast<uint8_t>(DimensionUnit::VP);
217     } else {
218         progressStyle.strokeWidthValue = strokeWidth.Value();
219         progressStyle.strokeWidthUnit = static_cast<uint8_t>(strokeWidth.Unit());
220     }
221 }
222 
ParseBorderWidth(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)223 void ParseBorderWidth(
224     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
225 {
226     Local<JSValueRef> borderWidthArg = runtimeCallInfo->GetCallArgRef(index);
227     CalcDimension borderWidth = CalcDimension(DEFAULT_BORDER_WIDTH, DimensionUnit::VP);
228 
229     if (borderWidthArg->IsString(vm)) {
230         const std::string& value = borderWidthArg->ToString(vm)->ToString(vm);
231         borderWidth = StringUtils::StringToDimensionWithUnit(value, DimensionUnit::VP, DEFAULT_BORDER_WIDTH);
232     } else {
233         ArkTSUtils::ParseJsDimension(vm, borderWidthArg, borderWidth, DimensionUnit::VP, false);
234     }
235     if (borderWidth.IsNegative()) {
236         progressStyle.borderWidthValue = DEFAULT_BORDER_WIDTH;
237         progressStyle.borderWidthUnit = static_cast<uint8_t>(DimensionUnit::VP);
238     } else {
239         progressStyle.borderWidthValue = borderWidth.Value();
240         progressStyle.borderWidthUnit = static_cast<uint8_t>(borderWidth.Unit());
241     }
242 }
243 
ParseScaleCount(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)244 void ParseScaleCount(
245     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
246 {
247     Local<JSValueRef> scaleCountArg = runtimeCallInfo->GetCallArgRef(index);
248     int32_t scaleCount = DEFAULT_SCALE_COUNT;
249     auto theme = ArkTSUtils::GetTheme<ProgressTheme>();
250     if (theme) {
251         scaleCount = theme->GetScaleNumber();
252     }
253 
254     if (scaleCountArg->IsNull() || !ArkTSUtils::ParseJsInteger(vm, scaleCountArg, scaleCount)) {
255         scaleCount = DEFAULT_SCALE_COUNT;
256     }
257     if (scaleCount > 1) {
258         progressStyle.scaleCount = scaleCount;
259     } else if (theme) {
260         progressStyle.scaleCount = theme->GetScaleNumber();
261     }
262 }
263 
ParseProgressStatus(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)264 void ParseProgressStatus(
265     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
266 {
267     Local<JSValueRef> ProgressStatusArg = runtimeCallInfo->GetCallArgRef(index);
268     NG::ProgressStatus progressStatus = DEFAULT_PROGRESS_STATUS;
269     std::string statusStr;
270     if (ProgressStatusArg->IsUndefined() || ProgressStatusArg->IsNull() ||
271         !ArkTSUtils::ParseJsString(vm, ProgressStatusArg, statusStr)) {
272         progressStatus = DEFAULT_PROGRESS_STATUS;
273     } else {
274         if (statusStr.compare("LOADING") == 0) {
275             progressStatus = NG::ProgressStatus::LOADING;
276         } else {
277             progressStatus = NG::ProgressStatus::PROGRESSING;
278         }
279     }
280     progressStyle.status = static_cast<int8_t>(progressStatus);
281 }
282 
ParseScaleWidth(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)283 void ParseScaleWidth(
284     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
285 {
286     Local<JSValueRef> scaleWidthArg = runtimeCallInfo->GetCallArgRef(index);
287     CalcDimension scaleWidth = CalcDimension(DEFAULT_SCALE_WIDTH, DimensionUnit::VP);
288 
289     if (scaleWidthArg->IsString(vm)) {
290         const std::string& value = scaleWidthArg->ToString(vm)->ToString(vm);
291         scaleWidth = StringUtils::StringToDimensionWithUnit(value, DimensionUnit::VP, DEFAULT_SCALE_WIDTH);
292     } else {
293         ArkTSUtils::ParseJsDimension(vm, scaleWidthArg, scaleWidth, DimensionUnit::VP, false);
294     }
295     if (scaleWidth.IsNegative()) {
296         scaleWidth = CalcDimension(DEFAULT_SCALE_WIDTH, DimensionUnit::VP);
297     }
298 
299     progressStyle.scaleWidthValue = scaleWidth.Value();
300     progressStyle.scaleWidthUnit = static_cast<uint8_t>(scaleWidth.Unit());
301 }
302 
ParseStrokeRadius(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)303 void ParseStrokeRadius(
304     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
305 {
306     Local<JSValueRef> strokeRadiusArg = runtimeCallInfo->GetCallArgRef(index);
307     CalcDimension strokeRadius = CalcDimension(DEFAULT_STROKE_RADIUS, DimensionUnit::PERCENT);
308     if (strokeRadiusArg->IsNull() ||
309         !ArkTSUtils::ParseJsDimension(vm, strokeRadiusArg, strokeRadius, DimensionUnit::VP, true)) {
310         strokeRadius.SetUnit(DimensionUnit::PERCENT);
311     }
312 
313     progressStyle.strokeRadiusValue = strokeRadius.Value();
314     progressStyle.strokeRadiusUnit = static_cast<uint8_t>(strokeRadius.Unit());
315 }
316 
ParseBorderColor(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)317 void ParseBorderColor(
318     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
319 {
320     Local<JSValueRef> borderColorArg = runtimeCallInfo->GetCallArgRef(index);
321     Color borderColor = DEFAULT_BORDER_COLOR;
322 
323     if (borderColorArg->IsNull() || !ArkTSUtils::ParseJsColorAlpha(vm, borderColorArg, borderColor)) {
324         borderColor = DEFAULT_BORDER_COLOR;
325     }
326 
327     progressStyle.borderColor = borderColor.GetValue();
328 }
329 
ParseFontColor(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)330 void ParseFontColor(
331     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
332 {
333     Local<JSValueRef> fontColorArg = runtimeCallInfo->GetCallArgRef(index);
334     Color fontColor = DEFAULT_FONT_COLOR;
335 
336     if (fontColorArg->IsNull() || !ArkTSUtils::ParseJsColorAlpha(vm, fontColorArg, fontColor)) {
337         fontColor = DEFAULT_FONT_COLOR;
338     }
339 
340     progressStyle.fontColor = fontColor.GetValue();
341 }
342 
ParseEnableSmoothEffect(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)343 void ParseEnableSmoothEffect(
344     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
345 {
346     Local<JSValueRef> enableSmoothEffectArg = runtimeCallInfo->GetCallArgRef(index);
347     progressStyle.enableSmoothEffect =
348         (enableSmoothEffectArg->IsBoolean()) ? enableSmoothEffectArg->ToBoolean(vm)->Value() : true;
349 }
350 
ParseContent(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)351 void ParseContent(
352     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
353 {
354     Local<JSValueRef> contentArg = runtimeCallInfo->GetCallArgRef(index);
355     std::string content = contentArg->ToString(vm)->ToString(vm);
356     progressStyle.content = (contentArg->IsString(vm)) ? content.c_str() : nullptr;
357 }
358 
ParseEnableScanEffect(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)359 void ParseEnableScanEffect(
360     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
361 {
362     Local<JSValueRef> enableScanEffectArg = runtimeCallInfo->GetCallArgRef(index);
363     progressStyle.enableScanEffect =
364         (enableScanEffectArg->IsBoolean()) ? enableScanEffectArg->ToBoolean(vm)->Value() : false;
365 }
366 
ParseShadow(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)367 void ParseShadow(
368     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
369 {
370     Local<JSValueRef> shadowArg = runtimeCallInfo->GetCallArgRef(index);
371     progressStyle.shadow = (shadowArg->IsBoolean()) ? shadowArg->ToBoolean(vm)->Value() : false;
372 }
373 
ParseShowDefaultPercentage(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)374 void ParseShowDefaultPercentage(
375     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
376 {
377     Local<JSValueRef> showDefaultPercentageArg = runtimeCallInfo->GetCallArgRef(index);
378     progressStyle.showDefaultPercentage =
379         (showDefaultPercentageArg->IsBoolean()) ? showDefaultPercentageArg->ToBoolean(vm)->Value() : false;
380 }
381 
ParseCapsuleFontSize(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)382 void ParseCapsuleFontSize(
383     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
384 {
385     Local<JSValueRef> sizeArg = runtimeCallInfo->GetCallArgRef(index);
386 
387     CalcDimension fontSize;
388     if (sizeArg->IsNull() || !ArkTSUtils::ParseJsDimensionFp(vm, sizeArg, fontSize) || fontSize.IsNegative() ||
389         fontSize.Unit() == DimensionUnit::PERCENT) {
390         progressStyle.fontInfo.fontSizeNumber = DEFAULT_CAPSULE_FONT_SIZE;
391         progressStyle.fontInfo.fontSizeUnit = static_cast<int8_t>(DEFAULT_CAPSULE_FONT_UNIT);
392     } else {
393         progressStyle.fontInfo.fontSizeNumber = fontSize.Value();
394         progressStyle.fontInfo.fontSizeUnit = static_cast<int8_t>(fontSize.Unit());
395     }
396 }
397 
ParseCapsuleFontWeight(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)398 void ParseCapsuleFontWeight(
399     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
400 {
401     Local<JSValueRef> weightArg = runtimeCallInfo->GetCallArgRef(index);
402     auto pipelineContext = PipelineContext::GetCurrentContext();
403     CHECK_NULL_VOID(pipelineContext);
404     auto theme = pipelineContext->GetTheme<TextTheme>();
405 
406     std::string weight;
407     if (!weightArg->IsNull()) {
408         if (weightArg->IsNumber()) {
409             weight = std::to_string(weightArg->Int32Value(vm));
410         } else if (weightArg->IsString(vm)) {
411             weight = weightArg->ToString(vm)->ToString(vm);
412         }
413         progressStyle.fontInfo.fontWeight = static_cast<uint8_t>(Framework::ConvertStrToFontWeight(weight));
414     } else {
415         progressStyle.fontInfo.fontWeight = static_cast<uint8_t>(theme->GetTextStyle().GetFontWeight());
416     }
417 }
418 
ParseCapsuleFontStyle(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)419 void ParseCapsuleFontStyle(
420     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
421 {
422     Local<JSValueRef> styleArg = runtimeCallInfo->GetCallArgRef(index);
423     auto pipelineContext = PipelineContext::GetCurrentContext();
424     CHECK_NULL_VOID(pipelineContext);
425     auto theme = pipelineContext->GetTheme<TextTheme>();
426 
427     uint8_t style = static_cast<uint8_t>(theme->GetTextStyle().GetFontStyle());
428     if (!styleArg->IsNull() && styleArg->IsInt()) {
429         style = static_cast<uint8_t>(styleArg->Int32Value(vm));
430         if (style <= 0 || style > static_cast<uint8_t>(FONT_STYLES.size())) {
431             style = static_cast<uint8_t>(theme->GetTextStyle().GetFontStyle());
432         }
433     }
434 
435     progressStyle.fontInfo.fontStyle = style;
436 }
437 
ParseCapsuleFontFamily(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle,int32_t index)438 void ParseCapsuleFontFamily(
439     const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle, int32_t index)
440 {
441     Local<JSValueRef> familyArg = runtimeCallInfo->GetCallArgRef(index);
442     auto pipelineContext = PipelineContext::GetCurrentContext();
443     CHECK_NULL_VOID(pipelineContext);
444     auto theme = pipelineContext->GetTheme<TextTheme>();
445 
446     std::vector<std::string> fontFamilies;
447     if (familyArg->IsNull() || !ArkTSUtils::ParseJsFontFamilies(vm, familyArg, fontFamilies)) {
448         fontFamilies = theme->GetTextStyle().GetFontFamilies();
449     }
450 
451     auto families = std::make_unique<const char* []>(fontFamilies.size());
452     for (uint32_t i = 0; i < fontFamilies.size(); i++) {
453         families[i] = fontFamilies[i].c_str();
454     }
455 
456     progressStyle.fontInfo.fontFamilies = families.get();
457     progressStyle.fontInfo.familyLength = fontFamilies.size();
458 }
459 
ParseLinearStyle(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle)460 void ParseLinearStyle(const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle)
461 {
462     ParseStrokeWidth(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_STROKE_WIDTH);
463     ParseStrokeRadius(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_STROKE_RADIUS);
464     ParseEnableScanEffect(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_ENABLE_SCAN_EFFECT);
465     ParseEnableSmoothEffect(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_ENABLE_SMOOTH_EFFECT);
466 }
467 
ParseRingStyle(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle)468 void ParseRingStyle(const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle)
469 {
470     ParseStrokeWidth(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_STROKE_WIDTH);
471     ParseShadow(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_SHADOW);
472     ParseProgressStatus(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_PROGRESS_STATUS);
473     ParseEnableScanEffect(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_ENABLE_SCAN_EFFECT);
474     ParseEnableSmoothEffect(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_ENABLE_SMOOTH_EFFECT);
475 }
476 
ParseCapsuleStyle(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle)477 void ParseCapsuleStyle(const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle)
478 {
479     ParseBorderColor(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_BORDER_COLOR);
480     ParseBorderWidth(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_BORDER_WIDTH);
481     ParseContent(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_CONTENT);
482     ParseFontColor(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_FONT_COLOR);
483     ParseCapsuleFontSize(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_FONT_SIZE);
484     ParseCapsuleFontWeight(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_FONT_WEIGHT);
485     ParseCapsuleFontStyle(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_FONT_STYLE);
486     ParseCapsuleFontFamily(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_FONT_FAMILY);
487     ParseEnableScanEffect(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_ENABLE_SCAN_EFFECT);
488     ParseShowDefaultPercentage(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_SHOW_DEFAULT_PERCENTAGE);
489     ParseEnableSmoothEffect(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_ENABLE_SMOOTH_EFFECT);
490 }
491 
ParseProgressStyle(const EcmaVM * vm,ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIProgressStyle & progressStyle)492 void ParseProgressStyle(const EcmaVM* vm, ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIProgressStyle& progressStyle)
493 {
494     auto progressTheme = ArkTSUtils::GetTheme<ProgressTheme>();
495     CHECK_NULL_VOID(progressTheme);
496     ParseStrokeWidth(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_STROKE_WIDTH);
497     ParseScaleCount(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_SCALE_COUNT);
498     ParseScaleWidth(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_SCALE_WIDTH);
499     if ((progressStyle.scaleWidthValue <= 0.0) || (progressStyle.scaleWidthValue > progressStyle.strokeWidthValue) ||
500         progressStyle.scaleWidthUnit == static_cast<int8_t>(DimensionUnit::PERCENT)) {
501         progressStyle.scaleWidthValue = progressTheme->GetScaleWidth().Value();
502         progressStyle.scaleWidthUnit = static_cast<int8_t>(progressTheme->GetScaleWidth().Unit());
503     }
504     ParseEnableSmoothEffect(vm, runtimeCallInfo, progressStyle, ARG_NUM_STYLE_ENABLE_SMOOTH_EFFECT);
505 }
506 
SetProgressStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)507 ArkUINativeModuleValue ProgressBridge::SetProgressStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
508 {
509     EcmaVM* vm = runtimeCallInfo->GetVM();
510     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
511     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(ARG_NUM_NATIVE_NODE);
512     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
513     auto pipelineContext = PipelineContext::GetCurrentContext();
514     CHECK_NULL_RETURN(pipelineContext, panda::JSValueRef::Undefined(vm));
515     auto theme = pipelineContext->GetTheme<TextTheme>();
516 
517     auto fontFamilies = theme->GetTextStyle().GetFontFamilies();
518     auto families = std::make_unique<const char* []>(fontFamilies.size());
519     for (uint32_t i = 0; i < fontFamilies.size(); i++) {
520         families[i] = fontFamilies[i].c_str();
521     }
522 
523     ArkUIProgressStyle progressStyle = { DEFAULT_STROKE_WIDTH, static_cast<int8_t>(DimensionUnit::VP),
524         DEFAULT_BORDER_WIDTH, static_cast<int8_t>(DimensionUnit::VP), DEFAULT_SCALE_COUNT,
525         static_cast<uint8_t>(DEFAULT_PROGRESS_STATUS), DEFAULT_SCALE_WIDTH, static_cast<int8_t>(DimensionUnit::VP),
526         DEFAULT_STROKE_RADIUS, static_cast<int8_t>(DimensionUnit::PERCENT), true,
527         static_cast<double>(DEFAULT_BORDER_COLOR.GetValue()), nullptr,
528         static_cast<double>(DEFAULT_FONT_COLOR.GetValue()), false, false, false,
529         { DEFAULT_CAPSULE_FONT_SIZE, static_cast<int8_t>(DEFAULT_CAPSULE_FONT_UNIT),
530             static_cast<uint8_t>(theme->GetTextStyle().GetFontWeight()),
531             static_cast<uint8_t>(theme->GetTextStyle().GetFontStyle()), families.get(), fontFamilies.size() } };
532 
533     auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
534     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
535     auto progressLayoutProperty = frameNode->GetLayoutProperty<ProgressLayoutProperty>();
536     CHECK_NULL_RETURN(progressLayoutProperty, panda::JSValueRef::Undefined(vm));
537     auto progresstype = progressLayoutProperty->GetType();
538     if (progresstype == ProgressType::LINEAR) {
539         ParseLinearStyle(vm, runtimeCallInfo, progressStyle);
540     } else if (progresstype == ProgressType::RING) {
541         ParseRingStyle(vm, runtimeCallInfo, progressStyle);
542     } else if (progresstype == ProgressType::CAPSULE) {
543         ParseCapsuleStyle(vm, runtimeCallInfo, progressStyle);
544     } else {
545         ParseProgressStyle(vm, runtimeCallInfo, progressStyle);
546     }
547     GetArkUINodeModifiers()->getProgressModifier()->setProgressStyle(nativeNode, &progressStyle);
548     return panda::JSValueRef::Undefined(vm);
549 }
550 
SetProgressBackgroundColor(ArkUIRuntimeCallInfo * runtimeCallInfo)551 ArkUINativeModuleValue ProgressBridge::SetProgressBackgroundColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
552 {
553     EcmaVM *vm = runtimeCallInfo->GetVM();
554     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
555     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
556     Local<JSValueRef> colorArg = runtimeCallInfo->GetCallArgRef(1);
557     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
558     Color color;
559     if (!ArkTSUtils::ParseJsColorAlpha(vm, colorArg, color)) {
560         GetArkUINodeModifiers()->getProgressModifier()->resetProgressBackgroundColor(nativeNode);
561     } else {
562         GetArkUINodeModifiers()->getProgressModifier()->setProgressBackgroundColor(nativeNode, color.GetValue());
563     }
564 
565     return panda::JSValueRef::Undefined(vm);
566 }
567 
ResetProgressBackgroundColor(ArkUIRuntimeCallInfo * runtimeCallInfo)568 ArkUINativeModuleValue ProgressBridge::ResetProgressBackgroundColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
569 {
570     EcmaVM* vm = runtimeCallInfo->GetVM();
571     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
572     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
573     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
574     GetArkUINodeModifiers()->getProgressModifier()->resetProgressBackgroundColor(nativeNode);
575     return panda::JSValueRef::Undefined(vm);
576 }
577 
SetContentModifierBuilder(ArkUIRuntimeCallInfo * runtimeCallInfo)578 ArkUINativeModuleValue ProgressBridge::SetContentModifierBuilder(ArkUIRuntimeCallInfo* runtimeCallInfo)
579 {
580     EcmaVM* vm = runtimeCallInfo->GetVM();
581     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
582     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
583     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
584     auto* frameNode = reinterpret_cast<FrameNode*>(firstArg->ToNativePointer(vm)->Value());
585     if (!secondArg->IsObject(vm)) {
586         ProgressModelNG::SetBuilderFunc(frameNode, nullptr);
587         return panda::JSValueRef::Undefined(vm);
588     }
589     panda::CopyableGlobal<panda::ObjectRef> obj(vm, secondArg);
590     ProgressModelNG::SetBuilderFunc(frameNode, [vm, frameNode, obj = std::move(obj),
591         containerId = Container::CurrentId()](ProgressConfiguration config) -> RefPtr<FrameNode> {
592         ContainerScope scope(containerId);
593         auto context = ArkTSUtils::GetContext(vm);
594         CHECK_EQUAL_RETURN(context->IsUndefined(), true, nullptr);
595         const char* keysOfProgress[] = { "value", "total", "enabled"};
596         Local<JSValueRef> valuesOfProgress[] = { panda::NumberRef::New(vm, config.value_),
597             panda::NumberRef::New(vm, config.total_), panda::BooleanRef::New(vm, config.enabled_)};
598         auto progress = panda::ObjectRef::NewWithNamedProperties(vm,
599             ArraySize(keysOfProgress), keysOfProgress, valuesOfProgress);
600         progress->SetNativePointerFieldCount(vm, 1);
601         progress->SetNativePointerField(vm, 0, static_cast<void*>(frameNode));
602         panda::Local<panda::JSValueRef> params[ARG_SECOND] = { context, progress };
603         LocalScope pandaScope(vm);
604         panda::TryCatch trycatch(vm);
605         auto jsObject = obj.ToLocal();
606         auto makeFunc = jsObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "makeContentModifierNode"));
607         CHECK_NULL_RETURN(makeFunc->IsFunction(vm), nullptr);
608         panda::Local<panda::FunctionRef> func = makeFunc;
609         auto result = func->Call(vm, jsObject, params, 2);
610         JSNApi::ExecutePendingJob(vm);
611         if (result.IsEmpty() || trycatch.HasCaught() || !result->IsObject(vm)) {
612             return nullptr;
613         }
614         auto resultObj = result->ToObject(vm);
615         panda::Local<panda::JSValueRef> nodeptr = resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm,
616             PROGRESS_NODEPTR_OF_UINODE));
617         if (nodeptr.IsEmpty() || nodeptr->IsUndefined() || nodeptr->IsNull()) {
618             return nullptr;
619         }
620         auto* frameNode = reinterpret_cast<FrameNode*>(nodeptr->ToNativePointer(vm)->Value());
621         CHECK_NULL_RETURN(frameNode, nullptr);
622         return AceType::Claim(frameNode);
623     });
624     return panda::JSValueRef::Undefined(vm);
625 }
626 
ResetProgressInitialize(ArkUIRuntimeCallInfo * runtimeCallInfo)627 ArkUINativeModuleValue ProgressBridge::ResetProgressInitialize(ArkUIRuntimeCallInfo* runtimeCallInfo)
628 {
629     EcmaVM* vm = runtimeCallInfo->GetVM();
630     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
631     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
632     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
633     GetArkUINodeModifiers()->getProgressModifier()->resetProgressInitialize(nativeNode);
634     return panda::JSValueRef::Undefined(vm);
635 }
636 
SetProgressInitialize(ArkUIRuntimeCallInfo * runtimeCallInfo)637 ArkUINativeModuleValue ProgressBridge::SetProgressInitialize(ArkUIRuntimeCallInfo* runtimeCallInfo)
638 {
639     EcmaVM* vm = runtimeCallInfo->GetVM();
640     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
641     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
642     Local<JSValueRef> valueArg = runtimeCallInfo->GetCallArgRef(1);
643     Local<JSValueRef> totalArg = runtimeCallInfo->GetCallArgRef(2);
644     Local<JSValueRef> styleArg = runtimeCallInfo->GetCallArgRef(3);
645     Local<JSValueRef> typeArg = runtimeCallInfo->GetCallArgRef(4);
646     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
647     auto value = 0;
648     if (valueArg->IsNumber()) {
649         value = valueArg->ToNumber(vm)->Value();
650     }
651     auto total = 100;
652     if (totalArg->IsNumber() && totalArg->ToNumber(vm)->Value() > 0) {
653         total = totalArg->Int32Value(vm);
654     }
655     if (value > total) {
656         value = total;
657     } else if (value < 0) {
658         value = 0;
659     }
660     auto type = 0;
661     if (styleArg->IsNull() || styleArg->IsUndefined()) {
662         if (typeArg->IsNumber()) {
663             type = typeArg->Int32Value(vm);
664         }
665     } else if (styleArg->IsNumber()) {
666         type = styleArg->Int32Value(vm);
667     }
668     auto progressStyle = static_cast<Framework::ProgressStyle>(type);
669     ProgressType g_progressType = NG::ProgressType::LINEAR;
670     if (progressStyle == Framework::ProgressStyle::Eclipse) {
671         g_progressType = NG::ProgressType::MOON;
672     } else if (progressStyle == Framework::ProgressStyle::Ring) {
673         g_progressType = NG::ProgressType::RING;
674     } else if (progressStyle == Framework::ProgressStyle::ScaleRing) {
675         g_progressType = NG::ProgressType::SCALE;
676     } else if (progressStyle == Framework::ProgressStyle::Capsule) {
677         g_progressType = NG::ProgressType::CAPSULE;
678     }
679     GetArkUINodeModifiers()->getProgressModifier()->setProgressInitialize(
680         nativeNode, value, total, static_cast<int>(g_progressType));
681     return panda::JSValueRef::Undefined(vm);
682 }
683 } // namespace OHOS::Ace::NG
684