1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_gauge_bridge.h"
16 
17 #include "base/geometry/dimension.h"
18 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
19 #include "bridge/declarative_frontend/jsview/js_linear_gradient.h"
20 #include "core/components/common/properties/color.h"
21 #include "core/components_ng/pattern/gauge/gauge_paint_property.h"
22 #include "core/components_ng/pattern/gauge/gauge_theme.h"
23 #include "core/components_ng/base/frame_node.h"
24 #include "core/components_ng/pattern/gauge/gauge_model_ng.h"
25 
26 namespace OHOS::Ace::NG {
27 namespace {
28 constexpr Color ERROR_COLOR = Color(0xFFE84026);
29 constexpr uint32_t NUM_0 = 0;
30 constexpr uint32_t NUM_1 = 1;
31 constexpr uint32_t NUM_2 = 2;
32 const char* GAUGE_NODEPTR_OF_UINODE = "nodePtr_";
33 
ResetColor(ArkUINodeHandle nativeNode)34 void ResetColor(ArkUINodeHandle nativeNode)
35 {
36     if (!Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
37         GetArkUINodeModifiers()->getGaugeModifier()->resetGradientColors(nativeNode);
38     } else {
39         GetArkUINodeModifiers()->getGaugeModifier()->resetColors(nativeNode);
40     }
41 }
42 }
43 
SortColorStopOffset(std::vector<NG::ColorStopArray> & colors)44 void SortColorStopOffset(std::vector<NG::ColorStopArray>& colors)
45 {
46     for (auto& colorStopArray : colors) {
47         std::sort(colorStopArray.begin(), colorStopArray.end(),
48             [](const std::pair<Color, Dimension>& left, const std::pair<Color, Dimension>& right) {
49                 return left.second.Value() < right.second.Value();
50             });
51 
52         auto iter = std::unique(colorStopArray.begin(), colorStopArray.end(),
53             [](const std::pair<Color, Dimension>& left, const std::pair<Color, Dimension>& right) {
54                 return left.second.Value() == right.second.Value();
55             });
56         colorStopArray.erase(iter, colorStopArray.end());
57     }
58 }
59 
ConvertResourceColor(const EcmaVM * vm,const Local<JSValueRef> & item,std::vector<NG::ColorStopArray> & colors)60 void ConvertResourceColor(const EcmaVM* vm, const Local<JSValueRef>& item, std::vector<NG::ColorStopArray>& colors)
61 {
62     Color color;
63     if (!ArkTSUtils::ParseJsColorAlpha(vm, item, color)) {
64         color = ERROR_COLOR;
65     }
66     NG::ColorStopArray colorStopArray;
67     colorStopArray.emplace_back(std::make_pair(color, Dimension(0.0)));
68     colors.emplace_back(colorStopArray);
69 }
70 
ConvertGradientColor(const EcmaVM * vm,const Local<JSValueRef> & itemParam,std::vector<NG::ColorStopArray> & colors,NG::GaugeType & type)71 void ConvertGradientColor(
72     const EcmaVM* vm, const Local<JSValueRef>& itemParam, std::vector<NG::ColorStopArray>& colors, NG::GaugeType& type)
73 {
74     if (!itemParam->IsObject(vm)) {
75         type = NG::GaugeType::TYPE_CIRCULAR_MONOCHROME;
76         return ConvertResourceColor(vm, itemParam, colors);
77     }
78     Framework::JSLinearGradient* jsLinearGradient =
79         static_cast<Framework::JSLinearGradient*>(itemParam->ToObject(vm)->GetNativePointerField(vm, 0));
80     if (!jsLinearGradient) {
81         type = NG::GaugeType::TYPE_CIRCULAR_MONOCHROME;
82         return ConvertResourceColor(vm, itemParam, colors);
83     }
84 
85     type = NG::GaugeType::TYPE_CIRCULAR_SINGLE_SEGMENT_GRADIENT;
86     if (jsLinearGradient->GetGradient().size() == 0) {
87         NG::ColorStopArray colorStopArray;
88         colorStopArray.emplace_back(std::make_pair(ERROR_COLOR, Dimension(0.0)));
89         colors.emplace_back(colorStopArray);
90     } else {
91         colors.emplace_back(jsLinearGradient->GetGradient());
92     }
93 }
94 
SetGradientColorsObject(const EcmaVM * vm,const Local<JSValueRef> & info,std::vector<NG::ColorStopArray> & colors,std::vector<float> & weights,NG::GaugeType & type,ArkUINodeHandle nativeNode)95 void SetGradientColorsObject(const EcmaVM* vm, const Local<JSValueRef>& info, std::vector<NG::ColorStopArray>& colors,
96     std::vector<float>& weights, NG::GaugeType& type, ArkUINodeHandle nativeNode)
97 {
98     ArkUIGradientType gradient;
99     ConvertGradientColor(vm, info, colors, type);
100     auto colorStruct = std::make_unique<uint32_t[]>(colors[0].size());
101     auto offsetStruct = std::make_unique<ArkUILengthType[]>(colors[0].size());
102     std::vector<uint32_t> linearLengths { colors[0].size() };
103     for (uint32_t i = 0; i < colors[0].size(); i++) {
104         colorStruct[i] = colors[0][i].first.GetValue();
105         offsetStruct[i].number = colors[0][i].second.Value();
106         offsetStruct[i].unit = static_cast<int8_t>(colors[0][i].second.Unit());
107     }
108     gradient.color = colorStruct.get();
109     gradient.offset = offsetStruct.get();
110     gradient.gradientLength = &(*linearLengths.begin());
111     gradient.weight = nullptr;
112     gradient.type = static_cast<uint32_t>(type);
113     gradient.length = 1;
114     GetArkUINodeModifiers()->getGaugeModifier()->setGradientColors(nativeNode, &gradient, 0);
115 }
116 
SetGradientColorsArray(const EcmaVM * vm,const Local<JSValueRef> & info,std::vector<NG::ColorStopArray> & colors,std::vector<float> & weights,NG::GaugeType & type,ArkUINodeHandle nativeNode)117 void SetGradientColorsArray(const EcmaVM* vm, const Local<JSValueRef>& info, std::vector<NG::ColorStopArray>& colors,
118     std::vector<float>& weights, NG::GaugeType& type, ArkUINodeHandle nativeNode)
119 {
120     ArkUIGradientType gradient;
121     uint32_t totalLength = 0;
122     std::vector<uint32_t> linearLengths(colors.size(), 0);
123     for (uint32_t i = 0; i < colors.size(); i++) {
124         linearLengths[i] = colors[i].size();
125         totalLength += colors[i].size();
126     }
127     auto colorStruct = std::make_unique<uint32_t[]>(totalLength);
128     auto offsetStruct = std::make_unique<ArkUILengthType[]>(totalLength);
129     int32_t pos = 0;
130     for (uint32_t i = 0; i < colors.size(); i++) {
131         for (uint32_t j = 0; j < colors[i].size(); j++, pos++) {
132             colorStruct[pos] = colors[i][j].first.GetValue();
133             offsetStruct[pos].number = colors[i][j].second.Value();
134             offsetStruct[pos].unit = static_cast<int8_t>(colors[i][j].second.Unit());
135         }
136     }
137     gradient.color = colorStruct.get();
138     gradient.offset = offsetStruct.get();
139     gradient.gradientLength = &(*linearLengths.begin());
140     gradient.weight = &(*weights.begin());
141     gradient.type = static_cast<uint32_t>(type);
142     gradient.length = colors.size();
143     GetArkUINodeModifiers()->getGaugeModifier()->setGradientColors(nativeNode, &gradient, weights.size());
144 }
145 
SetGradientColors(const EcmaVM * vm,const Local<JSValueRef> & info,ArkUINodeHandle nativeNode)146 void SetGradientColors(const EcmaVM* vm, const Local<JSValueRef>& info, ArkUINodeHandle nativeNode)
147 {
148     if (info->IsNull() || info->IsUndefined()) {
149         GetArkUINodeModifiers()->getGaugeModifier()->resetGradientColors(nativeNode);
150         return;
151     }
152     NG::GaugeType type = NG::GaugeType::TYPE_CIRCULAR_MULTI_SEGMENT_GRADIENT;
153     std::vector<NG::ColorStopArray> colors;
154     std::vector<float> weights;
155     if (!info->IsArray(vm)) {
156         SetGradientColorsObject(vm, info, colors, weights, type, nativeNode);
157         return;
158     }
159     auto jsColorsArray = panda::CopyableGlobal<panda::ArrayRef>(vm, info);
160     if (jsColorsArray.IsEmpty() || jsColorsArray->IsUndefined()
161         || jsColorsArray->IsNull() || jsColorsArray->Length(vm) == 0) {
162         GetArkUINodeModifiers()->getGaugeModifier()->resetGradientColors(nativeNode);
163         return;
164     }
165 
166     for (size_t i = 0; i < jsColorsArray->Length(vm); ++i) {
167         if (static_cast<int32_t>(i) >= NG::COLORS_MAX_COUNT) {
168             break;
169         }
170         auto jsValue = jsColorsArray->GetValueAt(vm, info, i);
171         if (!jsValue->IsArray(vm)) {
172             continue;
173         }
174         auto tempColors = panda::CopyableGlobal<panda::ArrayRef>(vm, jsValue);
175         // Get weight
176         float weight = tempColors->GetValueAt(vm, jsValue, 1)->ToNumber(vm)->Value();
177         if (NonPositive(weight)) {
178             continue;
179         }
180         weights.push_back(weight);
181         // Get color
182         auto jsColorValue = tempColors->GetValueAt(vm, jsValue, 0);
183         ConvertGradientColor(vm, jsColorValue, colors, type);
184     }
185     type = NG::GaugeType::TYPE_CIRCULAR_MULTI_SEGMENT_GRADIENT;
186     SortColorStopOffset(colors);
187     SetGradientColorsArray(vm, info, colors, weights, type, nativeNode);
188 }
189 
SetColors(ArkUIRuntimeCallInfo * runtimeCallInfo)190 ArkUINativeModuleValue GaugeBridge::SetColors(ArkUIRuntimeCallInfo* runtimeCallInfo)
191 {
192     EcmaVM* vm = runtimeCallInfo->GetVM();
193     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
194     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
195     Local<JSValueRef> jsArg = runtimeCallInfo->GetCallArgRef(NUM_1);
196     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
197 
198     if (!Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
199         SetGradientColors(vm, jsArg, nativeNode);
200         return panda::JSValueRef::Undefined(vm);
201     }
202 
203     if (!jsArg->IsArray(vm)) {
204         ResetColor(nativeNode);
205         return panda::JSValueRef::Undefined(vm);
206     }
207     auto jsColor = panda::CopyableGlobal<panda::ArrayRef>(vm, jsArg);
208     size_t length = jsColor->Length(vm);
209     auto colors = std::make_unique<uint32_t[]>(length);
210     auto weights = std::make_unique<float[]>(length);
211 
212     auto theme = ArkTSUtils::GetTheme<ProgressTheme>();
213     for (size_t i = 0; i < length; i++) {
214         auto jsValue = jsColor->GetValueAt(vm, jsArg, i);
215         if (!jsValue->IsArray(vm)) {
216             ResetColor(nativeNode);
217             return panda::JSValueRef::Undefined(vm);
218         }
219         auto handle = panda::CopyableGlobal<panda::ArrayRef>(vm, jsValue);
220         if (handle.IsEmpty() || handle->IsUndefined() || handle->IsNull()) {
221             return panda::JSValueRef::Undefined(vm);
222         }
223         float weight = handle->GetValueAt(vm, jsValue, 1)->ToNumber(vm)->Value();
224         Color selectedColor;
225         if (!ArkTSUtils::ParseJsColorAlpha(vm, handle->GetValueAt(vm, jsValue, 1), selectedColor)) {
226             selectedColor = ERROR_COLOR;
227         }
228         colors[i] = selectedColor.GetValue();
229         if (weight > 0) {
230             weights[i] = weight;
231         } else {
232             weights[i] = 0.0f;
233         }
234     }
235     GetArkUINodeModifiers()->getGaugeModifier()->setColors(nativeNode, colors.get(), weights.get(), length);
236     return panda::JSValueRef::Undefined(vm);
237 }
238 
ResetColors(ArkUIRuntimeCallInfo * runtimeCallInfo)239 ArkUINativeModuleValue GaugeBridge::ResetColors(ArkUIRuntimeCallInfo* runtimeCallInfo)
240 {
241     EcmaVM* vm = runtimeCallInfo->GetVM();
242     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
243     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
244     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
245     ResetColor(nativeNode);
246     return panda::JSValueRef::Undefined(vm);
247 }
248 
SetGaugeValue(ArkUIRuntimeCallInfo * runtimeCallInfo)249 ArkUINativeModuleValue GaugeBridge::SetGaugeValue(ArkUIRuntimeCallInfo* runtimeCallInfo)
250 {
251     EcmaVM* vm = runtimeCallInfo->GetVM();
252     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
253     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
254     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
255     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
256 
257     if (!secondArg->IsNumber()) {
258         GetArkUINodeModifiers()->getGaugeModifier()->resetGaugeValue(nativeNode);
259         return panda::JSValueRef::Undefined(vm);
260     }
261 
262     float value = static_cast<float>(secondArg->ToNumber(vm)->Value());
263     GetArkUINodeModifiers()->getGaugeModifier()->setGaugeValue(nativeNode, value);
264     return panda::JSValueRef::Undefined(vm);
265 }
266 
ResetGaugeValue(ArkUIRuntimeCallInfo * runtimeCallInfo)267 ArkUINativeModuleValue GaugeBridge::ResetGaugeValue(ArkUIRuntimeCallInfo* runtimeCallInfo)
268 {
269     EcmaVM* vm = runtimeCallInfo->GetVM();
270     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
271     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
272     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
273     GetArkUINodeModifiers()->getGaugeModifier()->resetGaugeValue(nativeNode);
274     return panda::JSValueRef::Undefined(vm);
275 }
276 
SetGaugeStartAngle(ArkUIRuntimeCallInfo * runtimeCallInfo)277 ArkUINativeModuleValue GaugeBridge::SetGaugeStartAngle(ArkUIRuntimeCallInfo* runtimeCallInfo)
278 {
279     EcmaVM* vm = runtimeCallInfo->GetVM();
280     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
281     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
282     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
283     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
284 
285     if (!secondArg->IsNumber()) {
286         GetArkUINodeModifiers()->getGaugeModifier()->resetGaugeStartAngle(nativeNode);
287         return panda::JSValueRef::Undefined(vm);
288     }
289 
290     float value = static_cast<float>(secondArg->ToNumber(vm)->Value());
291     GetArkUINodeModifiers()->getGaugeModifier()->setGaugeStartAngle(nativeNode, value);
292     return panda::JSValueRef::Undefined(vm);
293 }
294 
ResetGaugeStartAngle(ArkUIRuntimeCallInfo * runtimeCallInfo)295 ArkUINativeModuleValue GaugeBridge::ResetGaugeStartAngle(ArkUIRuntimeCallInfo* runtimeCallInfo)
296 {
297     EcmaVM* vm = runtimeCallInfo->GetVM();
298     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
299     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
300     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
301     GetArkUINodeModifiers()->getGaugeModifier()->resetGaugeStartAngle(nativeNode);
302     return panda::JSValueRef::Undefined(vm);
303 }
304 
SetGaugeEndAngle(ArkUIRuntimeCallInfo * runtimeCallInfo)305 ArkUINativeModuleValue GaugeBridge::SetGaugeEndAngle(ArkUIRuntimeCallInfo* runtimeCallInfo)
306 {
307     EcmaVM* vm = runtimeCallInfo->GetVM();
308     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
309     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
310     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
311     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
312 
313     if (!secondArg->IsNumber()) {
314         GetArkUINodeModifiers()->getGaugeModifier()->resetGaugeEndAngle(nativeNode);
315         return panda::JSValueRef::Undefined(vm);
316     }
317 
318     float value = static_cast<float>(secondArg->ToNumber(vm)->Value());
319     GetArkUINodeModifiers()->getGaugeModifier()->setGaugeEndAngle(nativeNode, value);
320     return panda::JSValueRef::Undefined(vm);
321 }
322 
ResetGaugeEndAngle(ArkUIRuntimeCallInfo * runtimeCallInfo)323 ArkUINativeModuleValue GaugeBridge::ResetGaugeEndAngle(ArkUIRuntimeCallInfo* runtimeCallInfo)
324 {
325     EcmaVM* vm = runtimeCallInfo->GetVM();
326     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
327     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
328     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
329     GetArkUINodeModifiers()->getGaugeModifier()->resetGaugeEndAngle(nativeNode);
330     return panda::JSValueRef::Undefined(vm);
331 }
332 
SetGaugeStrokeWidth(ArkUIRuntimeCallInfo * runtimeCallInfo)333 ArkUINativeModuleValue GaugeBridge::SetGaugeStrokeWidth(ArkUIRuntimeCallInfo* runtimeCallInfo)
334 {
335     EcmaVM* vm = runtimeCallInfo->GetVM();
336     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
337     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
338     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
339     Local<JSValueRef> jsValue = runtimeCallInfo->GetCallArgRef(1);
340 
341     CalcDimension strokeWidth;
342     if (!ArkTSUtils::ParseJsDimensionVpNG(vm, jsValue, strokeWidth) || strokeWidth.Unit() == DimensionUnit::PERCENT) {
343         strokeWidth = CalcDimension(0);
344     }
345     GetArkUINodeModifiers()->getGaugeModifier()->setGaugeStrokeWidth(
346         nativeNode, strokeWidth.Value(), static_cast<int>(strokeWidth.Unit()));
347     return panda::JSValueRef::Undefined(vm);
348 }
349 
ResetGaugeStrokeWidth(ArkUIRuntimeCallInfo * runtimeCallInfo)350 ArkUINativeModuleValue GaugeBridge::ResetGaugeStrokeWidth(ArkUIRuntimeCallInfo* runtimeCallInfo)
351 {
352     EcmaVM* vm = runtimeCallInfo->GetVM();
353     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
354     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
355     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
356     GetArkUINodeModifiers()->getGaugeModifier()->resetGaugeStrokeWidth(nativeNode);
357     return panda::JSValueRef::Undefined(vm);
358 }
359 
SetGaugeTrackShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)360 ArkUINativeModuleValue GaugeBridge::SetGaugeTrackShadow(ArkUIRuntimeCallInfo* runtimeCallInfo)
361 {
362     EcmaVM* vm = runtimeCallInfo->GetVM();
363     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
364     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
365     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
366     Local<JSValueRef> jsValue = runtimeCallInfo->GetCallArgRef(1);
367     auto radiusArg = runtimeCallInfo->GetCallArgRef(2);
368     auto offsetXArg = runtimeCallInfo->GetCallArgRef(3);
369     auto offsetYArg = runtimeCallInfo->GetCallArgRef(4);
370 
371     if (jsValue->IsNull()) {
372         GetArkUINodeModifiers()->getGaugeModifier()->setShadowOptions(nativeNode, DEFAULT_GAUGE_SHADOW_RADIUS,
373             DEFAULT_GAUGE_SHADOW_OFFSETX, DEFAULT_GAUGE_SHADOW_OFFSETY, false);
374         return panda::JSValueRef::Undefined(vm);
375     }
376 
377     if (!jsValue->IsObject(vm)) {
378         GetArkUINodeModifiers()->getGaugeModifier()->resetShadowOptions(nativeNode);
379         GetArkUINodeModifiers()->getGaugeModifier()->setIsShowIndicator(nativeNode, true);
380         return panda::JSValueRef::Undefined(vm);
381     }
382 
383     double radius = 0.0;
384     if (!ArkTSUtils::ParseJsDouble(vm, radiusArg, radius)) {
385         radius = DEFAULT_GAUGE_SHADOW_RADIUS;
386     }
387 
388     if (NonPositive(radius)) {
389         radius = DEFAULT_GAUGE_SHADOW_RADIUS;
390     }
391 
392     double offsetX = 0.0;
393     if (!ArkTSUtils::ParseJsDouble(vm, offsetXArg, offsetX)) {
394         offsetX = DEFAULT_GAUGE_SHADOW_OFFSETX;
395     }
396 
397     double offsetY = 0.0;
398     if (!ArkTSUtils::ParseJsDouble(vm, offsetYArg, offsetY)) {
399         offsetY = DEFAULT_GAUGE_SHADOW_OFFSETY;
400     }
401 
402     GetArkUINodeModifiers()->getGaugeModifier()->setShadowOptions(nativeNode, radius, offsetX, offsetY, true);
403     return panda::JSValueRef::Undefined(vm);
404 }
405 
ResetGaugeTrackShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)406 ArkUINativeModuleValue GaugeBridge::ResetGaugeTrackShadow(ArkUIRuntimeCallInfo* runtimeCallInfo)
407 {
408     EcmaVM* vm = runtimeCallInfo->GetVM();
409     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
410     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
411     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
412     GetArkUINodeModifiers()->getGaugeModifier()->resetShadowOptions(nativeNode);
413     return panda::JSValueRef::Undefined(vm);
414 }
415 
SetGaugeIndicator(ArkUIRuntimeCallInfo * runtimeCallInfo)416 ArkUINativeModuleValue GaugeBridge::SetGaugeIndicator(ArkUIRuntimeCallInfo* runtimeCallInfo)
417 {
418     EcmaVM* vm = runtimeCallInfo->GetVM();
419     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
420     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
421     auto iconArg = runtimeCallInfo->GetCallArgRef(1);
422     auto spaceArg = runtimeCallInfo->GetCallArgRef(2);
423     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
424     GetArkUINodeModifiers()->getGaugeModifier()->setIsShowIndicator(nativeNode, true);
425     std::string iconPath;
426     if (ArkTSUtils::ParseJsMedia(vm, iconArg, iconPath)) {
427         std::string bundleName;
428         std::string moduleName;
429         ArkTSUtils::GetJsMediaBundleInfo(vm, iconArg, bundleName, moduleName);
430         GetArkUINodeModifiers()->getGaugeModifier()->setIndicatorIconPath(nativeNode,
431             iconPath.c_str(), bundleName.c_str(), moduleName.c_str());
432     } else {
433         GetArkUINodeModifiers()->getGaugeModifier()->resetIndicatorIconPath(nativeNode);
434     }
435     CalcDimension space;
436     if (!ArkTSUtils::ParseJsDimensionVpNG(vm, spaceArg, space, false)) {
437         space = NG::INDICATOR_DISTANCE_TO_TOP;
438     }
439     if (space.IsNegative()) {
440         space = NG::INDICATOR_DISTANCE_TO_TOP;
441     }
442     GetArkUINodeModifiers()->getGaugeModifier()->setIndicatorSpace(nativeNode,
443         space.CalcValue().c_str(), space.Value(), static_cast<int32_t>(space.Unit()));
444     return panda::JSValueRef::Undefined(vm);
445 }
446 
ResetGaugeIndicator(ArkUIRuntimeCallInfo * runtimeCallInfo)447 ArkUINativeModuleValue GaugeBridge::ResetGaugeIndicator(ArkUIRuntimeCallInfo* runtimeCallInfo)
448 {
449     EcmaVM* vm = runtimeCallInfo->GetVM();
450     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
451     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
452     auto valueArg = runtimeCallInfo->GetCallArgRef(1);
453     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
454     if (valueArg->IsNull()) {
455         GetArkUINodeModifiers()->getGaugeModifier()->setIsShowIndicator(nativeNode, false);
456     } else if (valueArg->IsUndefined() || (!valueArg->IsObject(vm))) {
457         GetArkUINodeModifiers()->getGaugeModifier()->resetIndicatorIconPath(nativeNode);
458         GetArkUINodeModifiers()->getGaugeModifier()->resetIndicatorSpace(nativeNode);
459         GetArkUINodeModifiers()->getGaugeModifier()->setIsShowIndicator(nativeNode, true);
460     }
461     return panda::JSValueRef::Undefined(vm);
462 }
463 
SetContentModifierBuilder(ArkUIRuntimeCallInfo * runtimeCallInfo)464 ArkUINativeModuleValue GaugeBridge::SetContentModifierBuilder(ArkUIRuntimeCallInfo* runtimeCallInfo)
465 {
466     EcmaVM* vm = runtimeCallInfo->GetVM();
467     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
468     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
469     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
470     auto* frameNode = reinterpret_cast<FrameNode*>(firstArg->ToNativePointer(vm)->Value());
471     if (!secondArg->IsObject(vm)) {
472         GaugeModelNG::SetBuilderFunc(frameNode, nullptr);
473         return panda::JSValueRef::Undefined(vm);
474     }
475     panda::CopyableGlobal<panda::ObjectRef> obj(vm, secondArg);
476     auto containerId = Container::CurrentId();
477     GaugeModelNG::SetBuilderFunc(frameNode,
478         [vm, frameNode, obj = std::move(obj), containerId](
479             GaugeConfiguration config) -> RefPtr<FrameNode> {
480             ContainerScope scope(containerId);
481             auto context = ArkTSUtils::GetContext(vm);
482             const char* keyOfGauge[] = { "value", "min", "max" };
483             Local<JSValueRef> valuesOfGauge[] = { panda::NumberRef::New(vm, config.value_),
484                 panda::NumberRef::New(vm, config.min_), panda::NumberRef::New(vm, config.max_) };
485             auto gauge = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keyOfGauge),
486                 keyOfGauge, valuesOfGauge);
487             gauge->SetNativePointerFieldCount(vm, 1);
488             gauge->SetNativePointerField(vm, 0, static_cast<void*>(frameNode));
489             panda::Local<panda::JSValueRef> params[NUM_2] = { context, gauge };
490             LocalScope pandaScope(vm);
491             panda::TryCatch trycatch(vm);
492             auto jsObject = obj.ToLocal();
493             auto makeFunc = jsObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "makeContentModifierNode"));
494             CHECK_EQUAL_RETURN(makeFunc->IsFunction(vm), false, nullptr);
495             panda::Local<panda::FunctionRef> func = makeFunc;
496             auto result = func->Call(vm, jsObject, params, NUM_2);
497             JSNApi::ExecutePendingJob(vm);
498             CHECK_EQUAL_RETURN(result.IsEmpty() || trycatch.HasCaught() || !result->IsObject(vm), true, nullptr);
499             auto resultObj = result->ToObject(vm);
500             panda::Local<panda::JSValueRef> nodeptr =
501                 resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, GAUGE_NODEPTR_OF_UINODE));
502             CHECK_EQUAL_RETURN(nodeptr.IsEmpty() || nodeptr->IsUndefined() || nodeptr->IsNull(), true, nullptr);
503             auto* frameNode = reinterpret_cast<FrameNode*>(nodeptr->ToNativePointer(vm)->Value());
504             CHECK_NULL_RETURN(frameNode, nullptr);
505             return AceType::Claim(frameNode);
506         });
507     return panda::JSValueRef::Undefined(vm);
508 }
509 } // namespace OHOS::Ace::NG
510