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_data_panel_bridge.h"
16
17 #include "base/geometry/dimension.h"
18 #include "core/interfaces/native/node/api.h"
19 #include "bridge/declarative_frontend/jsview/js_linear_gradient.h"
20 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
21 #include "core/components/common/properties/color.h"
22 #include "core/components/data_panel/data_panel_theme.h"
23 #include "core/components/divider/divider_theme.h"
24 #include "core/components_ng/pattern/gauge/gauge_paint_property.h"
25 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
26
27 namespace OHOS::Ace::NG {
28 namespace {
29 constexpr int NUM_0 = 0;
30 constexpr int NUM_1 = 1;
31
ConvertThemeColor(std::vector<OHOS::Ace::NG::Gradient> & colors)32 void ConvertThemeColor(std::vector<OHOS::Ace::NG::Gradient>& colors)
33 {
34 RefPtr<DataPanelTheme> theme = ArkTSUtils::GetTheme<DataPanelTheme>();
35 auto themeColors = theme->GetColorsArray();
36 for (const auto& item : themeColors) {
37 OHOS::Ace::NG::Gradient gradient;
38 OHOS::Ace::NG::GradientColor gradientColorStart;
39 gradientColorStart.SetLinearColor(LinearColor(item.first));
40 gradientColorStart.SetDimension(Dimension(0.0));
41 gradient.AddColor(gradientColorStart);
42 OHOS::Ace::NG::GradientColor gradientColorEnd;
43 gradientColorEnd.SetLinearColor(LinearColor(item.second));
44 gradientColorEnd.SetDimension(Dimension(1.0));
45 gradient.AddColor(gradientColorEnd);
46 colors.emplace_back(gradient);
47 }
48 }
49
ConvertResourceColor(const EcmaVM * vm,const Local<JSValueRef> & item,OHOS::Ace::NG::Gradient & gradient)50 bool ConvertResourceColor(const EcmaVM* vm, const Local<JSValueRef>& item, OHOS::Ace::NG::Gradient& gradient)
51 {
52 Color color;
53 if (!ArkTSUtils::ParseJsColorAlpha(vm, item, color)) {
54 return false;
55 }
56 OHOS::Ace::NG::GradientColor gradientColorStart;
57 gradientColorStart.SetLinearColor(LinearColor(color));
58 gradientColorStart.SetDimension(Dimension(0.0));
59 gradient.AddColor(gradientColorStart);
60 OHOS::Ace::NG::GradientColor gradientColorEnd;
61 gradientColorEnd.SetLinearColor(LinearColor(color));
62 gradientColorEnd.SetDimension(Dimension(1.0));
63 gradient.AddColor(gradientColorEnd);
64 return true;
65 }
66
ConvertGradientColor(const EcmaVM * vm,const Local<JSValueRef> & itemParam,OHOS::Ace::NG::Gradient & gradient)67 bool ConvertGradientColor(const EcmaVM* vm, const Local<JSValueRef>& itemParam, OHOS::Ace::NG::Gradient& gradient)
68 {
69 if (!itemParam->IsObject()) {
70 return ConvertResourceColor(vm, itemParam, gradient);
71 }
72 Framework::JSLinearGradient* jsLinearGradient =
73 static_cast<Framework::JSLinearGradient*>(itemParam->ToObject(vm)->GetNativePointerField(0));
74 if (!jsLinearGradient) {
75 return ConvertResourceColor(vm, itemParam, gradient);
76 }
77
78 size_t colorLength = jsLinearGradient->GetGradient().size();
79 if (colorLength == 0) {
80 return false;
81 }
82 for (size_t colorIndex = 0; colorIndex < colorLength; ++colorIndex) {
83 OHOS::Ace::NG::GradientColor gradientColor;
84 gradientColor.SetLinearColor(LinearColor(jsLinearGradient->GetGradient().at(colorIndex).first));
85 gradientColor.SetDimension(jsLinearGradient->GetGradient().at(colorIndex).second);
86 gradient.AddColor(gradientColor);
87 }
88 return true;
89 }
90
SetTrackShadownObject(void * nativeNode,std::vector<OHOS::Ace::NG::Gradient> & shadowColors,double radius,double offsetX,double offsetY)91 void SetTrackShadownObject(
92 void* nativeNode, std::vector<OHOS::Ace::NG::Gradient>& shadowColors, double radius, double offsetX, double offsetY)
93 {
94 ArkUIGradientType gradient;
95 gradient.length = shadowColors.size();
96 auto linearLength = std::make_unique<uint32_t[]>(shadowColors.size());
97 std::vector<uint32_t> allColor;
98 std::vector<ArkUILengthType> allOffset;
99 for (uint32_t i = 0; i < shadowColors.size(); i++) {
100 linearLength[i] = shadowColors[i].GetColors().size();
101 for (uint32_t j = 0; j < linearLength[i]; j++) {
102 allColor.emplace_back(shadowColors[i].GetColors()[j].GetLinearColor().GetValue());
103 allOffset.emplace_back(ArkUILengthType { .number = shadowColors[i].GetColors()[j].GetDimension().Value(),
104 .unit = static_cast<int8_t>(shadowColors[i].GetColors()[j].GetDimension().Unit()) });
105 }
106 }
107 gradient.color = &(*allColor.begin());
108 gradient.offset = &(*allOffset.begin());
109 gradient.gradientLength = linearLength.get();
110 GetArkUIInternalNodeAPI()->GetDataPanelModifier().SetTrackShadow(nativeNode, &gradient, radius, offsetX, offsetY);
111 }
112 } // namespace
113
SetValueColors(ArkUIRuntimeCallInfo * runtimeCallInfo)114 ArkUINativeModuleValue DataPanelBridge::SetValueColors(ArkUIRuntimeCallInfo* runtimeCallInfo)
115 {
116 EcmaVM* vm = runtimeCallInfo->GetVM();
117 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
118 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
119 Local<JSValueRef> colors = runtimeCallInfo->GetCallArgRef(NUM_1);
120 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
121
122 std::vector<OHOS::Ace::NG::Gradient> shadowColors;
123 if (!colors.IsEmpty() && colors->IsArray(vm)) {
124 auto colorsArray = panda::CopyableGlobal<panda::ArrayRef>(vm, colors);
125 for (size_t i = 0; i < colorsArray->Length(vm); ++i) {
126 auto item = colorsArray->GetValueAt(vm, colors, i);
127 OHOS::Ace::NG::Gradient gradient;
128 if (!ConvertGradientColor(vm, item, gradient)) {
129 shadowColors.clear();
130 ConvertThemeColor(shadowColors);
131 break;
132 }
133 shadowColors.emplace_back(gradient);
134 }
135 }
136 ArkUIGradientType gradient;
137 gradient.length = shadowColors.size();
138 auto linearLength = std::make_unique<uint32_t[]>(shadowColors.size());
139 std::vector<uint32_t> allColor;
140 std::vector<ArkUILengthType> allOffset;
141 for (uint32_t i = 0; i < shadowColors.size(); i++) {
142 linearLength[i] = shadowColors[i].GetColors().size();
143 for (uint32_t j = 0; j < linearLength[i]; j++) {
144 allColor.emplace_back(shadowColors[i].GetColors()[j].GetLinearColor().GetValue());
145 allOffset.emplace_back(ArkUILengthType { .number = shadowColors[i].GetColors()[j].GetDimension().Value(),
146 .unit = static_cast<int8_t>(shadowColors[i].GetColors()[j].GetDimension().Unit()) });
147 }
148 }
149 gradient.color = &(*allColor.begin());
150 gradient.offset = &(*allOffset.begin());
151 gradient.gradientLength = linearLength.get();
152 GetArkUIInternalNodeAPI()->GetDataPanelModifier().SetValueColors(nativeNode, &gradient);
153 return panda::JSValueRef::Undefined(vm);
154 }
155
ResetValueColors(ArkUIRuntimeCallInfo * runtimeCallInfo)156 ArkUINativeModuleValue DataPanelBridge::ResetValueColors(ArkUIRuntimeCallInfo* runtimeCallInfo)
157 {
158 EcmaVM* vm = runtimeCallInfo->GetVM();
159 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
160 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
161 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
162 GetArkUIInternalNodeAPI()->GetDataPanelModifier().ResetValueColors(nativeNode);
163 return panda::JSValueRef::Undefined(vm);
164 }
165
SetTrackShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)166 ArkUINativeModuleValue DataPanelBridge::SetTrackShadow(ArkUIRuntimeCallInfo* runtimeCallInfo)
167 {
168 EcmaVM* vm = runtimeCallInfo->GetVM();
169 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
170 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
171 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
172 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
173 if (secondArg->IsNull()) {
174 GetArkUIInternalNodeAPI()->GetDataPanelModifier().SetNullTrackShadow(nativeNode);
175 return panda::JSValueRef::Undefined(vm);
176 }
177 if (!secondArg->IsObject()) {
178 GetArkUIInternalNodeAPI()->GetDataPanelModifier().ResetTrackShadow(nativeNode);
179 return panda::JSValueRef::Undefined(vm);
180 }
181 auto obj = secondArg->ToObject(vm);
182 auto jsRadius = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "radius"));
183 auto jsOffsetX = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "offsetX"));
184 auto jsOffsetY = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "offsetY"));
185 RefPtr<DataPanelTheme> theme = ArkTSUtils::GetTheme<DataPanelTheme>();
186 double radius = 0.0;
187 if (!ArkTSUtils::ParseJsDouble(vm, jsRadius, radius)) {
188 radius = theme->GetTrackShadowRadius().ConvertToVp();
189 }
190
191 if (NonPositive(radius)) {
192 radius = theme->GetTrackShadowRadius().ConvertToVp();
193 }
194
195 double offsetX = 0.0;
196 if (!ArkTSUtils::ParseJsDouble(vm, jsOffsetX, offsetX)) {
197 offsetX = theme->GetTrackShadowOffsetX().ConvertToVp();
198 }
199
200 double offsetY = 0.0;
201 if (!ArkTSUtils::ParseJsDouble(vm, jsOffsetY, offsetY)) {
202 offsetY = theme->GetTrackShadowOffsetY().ConvertToVp();
203 }
204
205 auto colors = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "colors"));
206 std::vector<OHOS::Ace::NG::Gradient> shadowColors;
207 if (!colors.IsEmpty() && colors->IsArray(vm)) {
208 auto colorsArray = panda::CopyableGlobal<panda::ArrayRef>(vm, colors);
209 for (size_t i = 0; i < colorsArray->Length(vm); ++i) {
210 auto item = colorsArray->GetValueAt(vm, colors, i);
211 OHOS::Ace::NG::Gradient gradient;
212 if (!ConvertGradientColor(vm, item, gradient)) {
213 shadowColors.clear();
214 ConvertThemeColor(shadowColors);
215 break;
216 }
217 shadowColors.emplace_back(gradient);
218 }
219 }
220 SetTrackShadownObject(nativeNode, shadowColors, radius, offsetX, offsetY);
221 return panda::JSValueRef::Undefined(vm);
222 }
223
ResetTrackShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)224 ArkUINativeModuleValue DataPanelBridge::ResetTrackShadow(ArkUIRuntimeCallInfo* runtimeCallInfo)
225 {
226 EcmaVM* vm = runtimeCallInfo->GetVM();
227 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
228 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
229 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
230 GetArkUIInternalNodeAPI()->GetDataPanelModifier().ResetTrackShadow(nativeNode);
231 return panda::JSValueRef::Undefined(vm);
232 }
SetCloseEffect(ArkUIRuntimeCallInfo * runtimeCallInfo)233 ArkUINativeModuleValue DataPanelBridge::SetCloseEffect(ArkUIRuntimeCallInfo* runtimeCallInfo)
234 {
235 EcmaVM* vm = runtimeCallInfo->GetVM();
236 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
237 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
238 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
239 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
240 bool boolValue = secondArg->ToBoolean(vm)->Value();
241 GetArkUIInternalNodeAPI()->GetDataPanelModifier().SetCloseEffect(nativeNode, boolValue);
242 return panda::JSValueRef::Undefined(vm);
243 }
244
ResetCloseEffect(ArkUIRuntimeCallInfo * runtimeCallInfo)245 ArkUINativeModuleValue DataPanelBridge::ResetCloseEffect(ArkUIRuntimeCallInfo* runtimeCallInfo)
246 {
247 EcmaVM* vm = runtimeCallInfo->GetVM();
248 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
249 Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
250 void* nativeNode = nativeNodeArg->ToNativePointer(vm)->Value();
251 GetArkUIInternalNodeAPI()->GetDataPanelModifier().ResetCloseEffect(nativeNode);
252 return panda::JSValueRef::Undefined(vm);
253 }
254
SetDataPanelTrackBackgroundColor(ArkUIRuntimeCallInfo * runtimeCallInfo)255 ArkUINativeModuleValue DataPanelBridge::SetDataPanelTrackBackgroundColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
256 {
257 EcmaVM* vm = runtimeCallInfo->GetVM();
258 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
259 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
260 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
261 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
262
263 Color color;
264 if (!ArkTSUtils::ParseJsColorAlpha(vm, secondArg, color)) {
265 RefPtr<DataPanelTheme> theme = ArkTSUtils::GetTheme<DataPanelTheme>();
266 color = theme->GetBackgroundColor();
267 }
268 GetArkUIInternalNodeAPI()->GetDataPanelModifier().SetDataPanelTrackBackgroundColor(nativeNode, color.GetValue());
269 return panda::JSValueRef::Undefined(vm);
270 }
271
ResetDataPanelTrackBackgroundColor(ArkUIRuntimeCallInfo * runtimeCallInfo)272 ArkUINativeModuleValue DataPanelBridge::ResetDataPanelTrackBackgroundColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
273 {
274 EcmaVM* vm = runtimeCallInfo->GetVM();
275 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
276 Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
277 void* nativeNode = nativeNodeArg->ToNativePointer(vm)->Value();
278 GetArkUIInternalNodeAPI()->GetDataPanelModifier().ResetDataPanelTrackBackgroundColor(nativeNode);
279 return panda::JSValueRef::Undefined(vm);
280 }
281
SetDataPanelStrokeWidth(ArkUIRuntimeCallInfo * runtimeCallInfo)282 ArkUINativeModuleValue DataPanelBridge::SetDataPanelStrokeWidth(ArkUIRuntimeCallInfo* runtimeCallInfo)
283 {
284 EcmaVM* vm = runtimeCallInfo->GetVM();
285 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
286 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
287 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
288 Local<JSValueRef> jsValue = runtimeCallInfo->GetCallArgRef(1);
289
290 RefPtr<DataPanelTheme> theme = ArkTSUtils::GetTheme<DataPanelTheme>();
291
292 CalcDimension strokeWidth;
293
294 if (!ArkTSUtils::ParseJsDimensionVp(vm, jsValue, strokeWidth)) {
295 strokeWidth = theme->GetThickness();
296 }
297
298 if (jsValue->IsString() && jsValue->ToString(vm)->ToString().empty()) {
299 strokeWidth = theme->GetThickness();
300 }
301
302 if (strokeWidth.IsNegative() || strokeWidth.Unit() == DimensionUnit::PERCENT) {
303 strokeWidth = theme->GetThickness();
304 }
305
306 GetArkUIInternalNodeAPI()->GetDataPanelModifier().SetDataPanelStrokeWidth(
307 nativeNode, strokeWidth.Value(), static_cast<int>(strokeWidth.Unit()));
308 return panda::JSValueRef::Undefined(vm);
309 }
310
ResetDataPanelStrokeWidth(ArkUIRuntimeCallInfo * runtimeCallInfo)311 ArkUINativeModuleValue DataPanelBridge::ResetDataPanelStrokeWidth(ArkUIRuntimeCallInfo* runtimeCallInfo)
312 {
313 EcmaVM* vm = runtimeCallInfo->GetVM();
314 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
315 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
316 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
317 GetArkUIInternalNodeAPI()->GetDataPanelModifier().ResetDataPanelStrokeWidth(nativeNode);
318 return panda::JSValueRef::Undefined(vm);
319 }
320 } // namespace OHOS::Ace::NG
321