1 /*
2 * Copyright (c) 2024 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_badge_bridge.h"
16
17 #include "base/geometry/dimension.h"
18 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_theme_utils.h"
19 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
20 #include "core/components/badge/badge_theme.h"
21 #include "core/components/common/properties/text_style.h"
22
23 namespace OHOS::Ace::NG {
24 namespace {
25 constexpr int32_t DEFAULT_BADGE_POSITION = 0;
26 constexpr Dimension UNDEFINED_DIMENSION(-1.0, DimensionUnit::VP);
27 const uint32_t DEFAULT_TEXT_COLOR = Color::WHITE.GetValue();
28 const uint32_t DEFAULT_BADGE_COLOR = Color::RED.GetValue();
InitBadgeParam(const RefPtr<BadgeTheme> & badgeTheme,ArkUIBadgeParam & param)29 bool InitBadgeParam(const RefPtr<BadgeTheme>& badgeTheme, ArkUIBadgeParam& param)
30 {
31 CHECK_NULL_RETURN(badgeTheme, false);
32 auto positionX = badgeTheme->GetBadgePositionX();
33 auto positionY = badgeTheme->GetBadgePositionY();
34 auto fontSize = badgeTheme->GetBadgeFontSize();
35 auto circleSize = badgeTheme->GetBadgeCircleSize();
36 auto borderWidth = badgeTheme->GetBadgeBorderWidth();
37 auto themeColors = Framework::JSThemeUtils::GetThemeColors();
38 param.position = DEFAULT_BADGE_POSITION;
39 param.isPositionXy = false;
40 param.positionX.value = positionX.Value();
41 param.positionX.units = static_cast<int32_t>(positionX.Unit());
42 param.positionY.value = positionY.Value();
43 param.positionY.units = static_cast<int32_t>(positionY.Unit());
44 if (themeColors.has_value()) {
45 param.textColor = themeColors->FontOnPrimary().GetValue();
46 param.badgeColor = themeColors->Warning().GetValue();
47 } else {
48 param.textColor = DEFAULT_TEXT_COLOR;
49 param.badgeColor = DEFAULT_BADGE_COLOR;
50 }
51 param.fontSize.value = fontSize.Value();
52 param.fontSize.units = static_cast<int32_t>(fontSize.Unit());
53 param.badgeSize.value = circleSize.Value();
54 param.badgeSize.units = static_cast<int32_t>(fontSize.Unit());
55 param.borderColor = themeColors ? themeColors->Warning().GetValue() : badgeTheme->GetBadgeBorderColor().GetValue();
56 param.borderWidth.value = borderWidth.Value();
57 param.borderWidth.units = static_cast<int32_t>(borderWidth.Unit());
58 param.fontWeight = static_cast<int32_t>(FontWeight::NORMAL);
59 param.isDefaultFontSize = true;
60 param.isDefaultBadgeSize = true;
61 return true;
62 }
63
ParsePosition(const EcmaVM * vm,const ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIBadgeParam & param)64 void ParsePosition(const EcmaVM* vm, const ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIBadgeParam& param)
65 {
66 CHECK_NULL_VOID(vm);
67 CHECK_NULL_VOID(runtimeCallInfo);
68 Local<JSValueRef> position = runtimeCallInfo->GetCallArgRef(1);
69 Local<JSValueRef> positionX = runtimeCallInfo->GetCallArgRef(2); // 2: parameter index
70 Local<JSValueRef> positionY = runtimeCallInfo->GetCallArgRef(3); // 3: parameter index
71 Local<JSValueRef> positionObj = runtimeCallInfo->GetCallArgRef(11); // 11: parameter index
72 if (!position->IsNull() && position->IsNumber()) {
73 param.isPositionXy = false;
74 param.position = position->Int32Value(vm);
75 } else if (!positionX->IsUndefined() || !positionY->IsUndefined() ||
76 (positionObj->IsBoolean() && positionObj->ToBoolean(vm)->Value())) {
77 param.isPositionXy = true;
78 CalcDimension dimenX;
79 CalcDimension dimenY;
80 bool xResult = ArkTSUtils::ParseJsDimensionVp(vm, positionX, dimenX);
81 bool yResult = ArkTSUtils::ParseJsDimensionVp(vm, positionY, dimenY);
82 if (xResult || yResult) {
83 param.positionX.value = dimenX.Value();
84 param.positionX.units = static_cast<int32_t>(dimenX.Unit());
85 param.positionY.value = dimenY.Value();
86 param.positionY.units = static_cast<int32_t>(dimenY.Unit());
87 }
88 }
89 }
90
ParseFontSize(const EcmaVM * vm,const ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIBadgeParam & param)91 void ParseFontSize(const EcmaVM* vm, const ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIBadgeParam& param)
92 {
93 CHECK_NULL_VOID(vm);
94 CHECK_NULL_VOID(runtimeCallInfo);
95 Local<JSValueRef> fontSize = runtimeCallInfo->GetCallArgRef(9); // 9: parameter index
96 CalcDimension fontSizeVal;
97 if (ArkTSUtils::ParseJsDimensionNG(vm, fontSize, fontSizeVal, DimensionUnit::FP)) {
98 if (fontSizeVal.IsNonNegative() && fontSizeVal.Unit() != DimensionUnit::PERCENT) {
99 param.fontSize.value = fontSizeVal.Value();
100 param.fontSize.units = static_cast<int32_t>(fontSizeVal.Unit());
101 param.isDefaultFontSize = false;
102 }
103 } else if (fontSize->IsUndefined()) {
104 param.fontSize.value = UNDEFINED_DIMENSION.Value();
105 param.fontSize.units = static_cast<int32_t>(UNDEFINED_DIMENSION.Unit());
106 }
107 }
108
ParseBadgeSize(const EcmaVM * vm,const ArkUIRuntimeCallInfo * runtimeCallInfo,ArkUIBadgeParam & param)109 void ParseBadgeSize(const EcmaVM* vm, const ArkUIRuntimeCallInfo* runtimeCallInfo, ArkUIBadgeParam& param)
110 {
111 CHECK_NULL_VOID(vm);
112 CHECK_NULL_VOID(runtimeCallInfo);
113 Local<JSValueRef> badgeSize = runtimeCallInfo->GetCallArgRef(5); // 5: parameter index
114 CalcDimension badgeSizeVal;
115 if (ArkTSUtils::ParseJsDimensionNG(vm, badgeSize, badgeSizeVal, DimensionUnit::FP)) {
116 if (badgeSizeVal.IsNonNegative() && badgeSizeVal.Unit() != DimensionUnit::PERCENT) {
117 param.badgeSize.value = badgeSizeVal.Value();
118 param.badgeSize.units = static_cast<int32_t>(badgeSizeVal.Unit());
119 param.isDefaultBadgeSize = false;
120 }
121 }
122 }
123
ParseBadgeBaseParam(const EcmaVM * vm,const ArkUIRuntimeCallInfo * runtimeCallInfo,const RefPtr<BadgeTheme> & badgeTheme,ArkUIBadgeParam & param)124 bool ParseBadgeBaseParam(const EcmaVM* vm, const ArkUIRuntimeCallInfo* runtimeCallInfo,
125 const RefPtr<BadgeTheme>& badgeTheme, ArkUIBadgeParam& param)
126 {
127 CHECK_NULL_RETURN(vm, false);
128 CHECK_NULL_RETURN(runtimeCallInfo, false);
129 CHECK_NULL_RETURN(badgeTheme, false);
130 Local<JSValueRef> badgeColor = runtimeCallInfo->GetCallArgRef(4); // 4: parameter index
131 Local<JSValueRef> borderColor = runtimeCallInfo->GetCallArgRef(6); // 6: parameter index
132 Local<JSValueRef> borderWidth = runtimeCallInfo->GetCallArgRef(7); // 7: parameter index
133 Local<JSValueRef> textColor = runtimeCallInfo->GetCallArgRef(8); // 8: parameter index
134 Local<JSValueRef> fontWeight = runtimeCallInfo->GetCallArgRef(10); // 10: parameter index
135 if (!InitBadgeParam(badgeTheme, param)) {
136 return false;
137 }
138 ParsePosition(vm, runtimeCallInfo, param);
139 ParseFontSize(vm, runtimeCallInfo, param);
140 ParseBadgeSize(vm, runtimeCallInfo, param);
141
142 Color badgeColorVal, textColorVal, borderColorVal;
143 if (ArkTSUtils::ParseJsColor(vm, badgeColor, badgeColorVal)) {
144 param.badgeColor = badgeColorVal.GetValue();
145 }
146 if (ArkTSUtils::ParseJsColorAlpha(vm, textColor, textColorVal)) {
147 param.textColor = textColorVal.GetValue();
148 }
149 if (ArkTSUtils::ParseJsColorAlpha(vm, borderColor, borderColorVal)) {
150 param.borderColor = borderColorVal.GetValue();
151 }
152 std::string fontWeightVal;
153 if (fontWeight->IsNumber()) {
154 fontWeightVal = std::to_string(fontWeight->Int32Value(vm));
155 } else {
156 ArkTSUtils::ParseJsString(vm, fontWeight, fontWeightVal);
157 }
158 CalcDimension borderWidthVal;
159 if (ArkTSUtils::ParseJsDimensionVp(vm, borderWidth, borderWidthVal)) {
160 if (borderWidthVal.IsNonNegative() && borderWidthVal.Unit() != DimensionUnit::PERCENT) {
161 param.borderWidth.value = borderWidthVal.Value();
162 param.borderWidth.units = static_cast<int32_t>(borderWidthVal.Unit());
163 }
164 }
165 param.fontWeight = static_cast<ArkUI_Int32>(Framework::ConvertStrToFontWeight(fontWeightVal));
166 return true;
167 }
168 } // namespace
169
SetBadgeParamWithNumber(ArkUIRuntimeCallInfo * runtimeCallInfo)170 ArkUINativeModuleValue BadgeBridge::SetBadgeParamWithNumber(ArkUIRuntimeCallInfo* runtimeCallInfo)
171 {
172 EcmaVM* vm = runtimeCallInfo->GetVM();
173 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
174 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
175 Local<JSValueRef> countArg = runtimeCallInfo->GetCallArgRef(12); // 12: parameter index
176 Local<JSValueRef> maxCountArg = runtimeCallInfo->GetCallArgRef(13); // 13: parameter index
177 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
178
179 ArkUIBadgeParam style;
180 int32_t count = 0;
181 int32_t maxCount = 0;
182 bool hasValue = false;
183 auto badgeTheme = ArkTSUtils::GetTheme<BadgeTheme>();
184 CHECK_NULL_RETURN(badgeTheme, panda::JSValueRef::Undefined(vm));
185 if (!ParseBadgeBaseParam(vm, runtimeCallInfo, badgeTheme, style)) {
186 return panda::JSValueRef::Undefined(vm);
187 }
188 if (!countArg->IsNull() && countArg->IsNumber()) {
189 count = countArg->Int32Value(vm);
190 hasValue = true;
191 }
192 if (!maxCountArg->IsNull() && maxCountArg->IsNumber()) {
193 maxCount = maxCountArg->Int32Value(vm);
194 } else {
195 maxCount = badgeTheme->GetMaxCount();
196 }
197
198 GetArkUINodeModifiers()->getBadgeModifier()->setBadgeParamWithNumber(nativeNode, &style, count, hasValue, maxCount);
199 return panda::JSValueRef::Undefined(vm);
200 }
201
SetBadgeParamWithString(ArkUIRuntimeCallInfo * runtimeCallInfo)202 ArkUINativeModuleValue BadgeBridge::SetBadgeParamWithString(ArkUIRuntimeCallInfo* runtimeCallInfo)
203 {
204 EcmaVM* vm = runtimeCallInfo->GetVM();
205 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
206 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
207 Local<JSValueRef> valueArg = runtimeCallInfo->GetCallArgRef(12); // 12: parameter index
208 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
209
210 ArkUIBadgeParam style;
211 const char* value = nullptr;
212 auto badgeTheme = ArkTSUtils::GetTheme<BadgeTheme>();
213 CHECK_NULL_RETURN(badgeTheme, panda::JSValueRef::Undefined(vm));
214 if (!ParseBadgeBaseParam(vm, runtimeCallInfo, badgeTheme, style)) {
215 return panda::JSValueRef::Undefined(vm);
216 }
217 if (!valueArg->IsNull() && valueArg->IsString(vm)) {
218 value = valueArg->ToString(vm)->ToString(vm).c_str();
219 }
220
221 GetArkUINodeModifiers()->getBadgeModifier()->setBadgeParamWithString(nativeNode, &style, value);
222 return panda::JSValueRef::Undefined(vm);
223 }
224 } // namespace OHOS::Ace::NG
225