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_menu_item_bridge.h"
16
17 #include "core/components_ng/pattern/menu/menu_item/menu_item_model_ng.h"
18 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
19
20 using namespace OHOS::Ace::Framework;
21
22 namespace OHOS::Ace::NG {
23 const std::string FORMAT_FONT = "%s|%s|%s";
24 const std::string DEFAULT_ERR_CODE = "-1";
25 constexpr int NUM_0 = 0;
26 constexpr int NUM_1 = 1;
27 constexpr int NUM_2 = 2;
SetMenuItemSelected(ArkUIRuntimeCallInfo * runtimeCallInfo)28 ArkUINativeModuleValue MenuItemBridge::SetMenuItemSelected(ArkUIRuntimeCallInfo* runtimeCallInfo)
29 {
30 EcmaVM* vm = runtimeCallInfo->GetVM();
31 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
32 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
33 Local<JSValueRef> isSelectedArg = runtimeCallInfo->GetCallArgRef(1);
34 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
35 if (isSelectedArg->IsBoolean()) {
36 bool isSelected = isSelectedArg->ToBoolean(vm)->Value();
37 GetArkUINodeModifiers()->getMenuItemModifier()->setMenuItemSelected(nativeNode, isSelected);
38 } else {
39 GetArkUINodeModifiers()->getMenuItemModifier()->resetMenuItemSelected(nativeNode);
40 }
41 return panda::JSValueRef::Undefined(vm);
42 }
43
ResetMenuItemSelected(ArkUIRuntimeCallInfo * runtimeCallInfo)44 ArkUINativeModuleValue MenuItemBridge::ResetMenuItemSelected(ArkUIRuntimeCallInfo* runtimeCallInfo)
45 {
46 EcmaVM* vm = runtimeCallInfo->GetVM();
47 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
48 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
49 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
50 GetArkUINodeModifiers()->getMenuItemModifier()->resetMenuItemSelected(nativeNode);
51 return panda::JSValueRef::Undefined(vm);
52 }
53
SetLabelFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)54 ArkUINativeModuleValue MenuItemBridge::SetLabelFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
55 {
56 EcmaVM* vm = runtimeCallInfo->GetVM();
57 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
58 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
59 Local<JSValueRef> colorArg = runtimeCallInfo->GetCallArgRef(1);
60 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
61 Color color;
62 if (!ArkTSUtils::ParseJsColorAlpha(vm, colorArg, color)) {
63 GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFontColor(nativeNode);
64 } else {
65 GetArkUINodeModifiers()->getMenuItemModifier()->setLabelFontColor(nativeNode, color.GetValue());
66 }
67 return panda::JSValueRef::Undefined(vm);
68 }
69
ResetLabelFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)70 ArkUINativeModuleValue MenuItemBridge::ResetLabelFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
71 {
72 EcmaVM* vm = runtimeCallInfo->GetVM();
73 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
74 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
75 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
76 GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFontColor(nativeNode);
77 return panda::JSValueRef::Undefined(vm);
78 }
79
SetContentFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)80 ArkUINativeModuleValue MenuItemBridge::SetContentFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
81 {
82 EcmaVM* vm = runtimeCallInfo->GetVM();
83 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
84 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
85 Local<JSValueRef> colorArg = runtimeCallInfo->GetCallArgRef(1);
86 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
87 Color color;
88 if (!ArkTSUtils::ParseJsColorAlpha(vm, colorArg, color)) {
89 GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFontColor(nativeNode);
90 } else {
91 GetArkUINodeModifiers()->getMenuItemModifier()->setContentFontColor(nativeNode, color.GetValue());
92 }
93 return panda::JSValueRef::Undefined(vm);
94 }
95
ResetContentFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)96 ArkUINativeModuleValue MenuItemBridge::ResetContentFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
97 {
98 EcmaVM* vm = runtimeCallInfo->GetVM();
99 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
100 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
101 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
102 GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFontColor(nativeNode);
103 return panda::JSValueRef::Undefined(vm);
104 }
105
SetLabelFont(ArkUIRuntimeCallInfo * runtimeCallInfo)106 ArkUINativeModuleValue MenuItemBridge::SetLabelFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
107 {
108 EcmaVM* vm = runtimeCallInfo->GetVM();
109 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
110 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
111 Local<JSValueRef> sizeArg = runtimeCallInfo->GetCallArgRef(1); // 1: label font size
112 Local<JSValueRef> weightArg = runtimeCallInfo->GetCallArgRef(2); // 2: label font weight
113 Local<JSValueRef> familyArg = runtimeCallInfo->GetCallArgRef(3); // 3: label font family
114 Local<JSValueRef> styleArg = runtimeCallInfo->GetCallArgRef(4); // 4: label font style
115 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
116 if (sizeArg->IsUndefined() && weightArg->IsUndefined() && familyArg->IsUndefined() && styleArg->IsUndefined()) {
117 GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFont(nativeNode);
118 return panda::JSValueRef::Undefined(vm);
119 }
120
121 CalcDimension fontSize;
122 if (!ArkTSUtils::ParseJsDimensionFp(vm, sizeArg, fontSize, false)) {
123 fontSize = Dimension(0.0);
124 }
125
126 std::string weight = DEFAULT_ERR_CODE;
127 if (weightArg->IsNumber()) {
128 weight = std::to_string(weightArg->Int32Value(vm));
129 } else {
130 if (!ArkTSUtils::ParseJsString(vm, weightArg, weight) || weight.empty()) {
131 weight = DEFAULT_ERR_CODE;
132 }
133 }
134
135 int32_t style = -1;
136 if (styleArg->IsNumber()) {
137 style = styleArg->Int32Value(vm);
138 }
139
140 std::string family;
141 if (!ArkTSUtils::ParseJsFontFamiliesToString(vm, familyArg, family) || family.empty()) {
142 family = DEFAULT_ERR_CODE;
143 }
144
145 std::string fontSizeStr = fontSize.ToString();
146 std::string fontInfo =
147 StringUtils::FormatString(FORMAT_FONT.c_str(), fontSizeStr.c_str(), weight.c_str(), family.c_str());
148 GetArkUINodeModifiers()->getMenuItemModifier()->setLabelFont(nativeNode, fontInfo.c_str(), style);
149 return panda::JSValueRef::Undefined(vm);
150 }
151
ResetLabelFont(ArkUIRuntimeCallInfo * runtimeCallInfo)152 ArkUINativeModuleValue MenuItemBridge::ResetLabelFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
153 {
154 EcmaVM* vm = runtimeCallInfo->GetVM();
155 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
156 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
157 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
158 GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFont(nativeNode);
159 return panda::JSValueRef::Undefined(vm);
160 }
161
SetContentFont(ArkUIRuntimeCallInfo * runtimeCallInfo)162 ArkUINativeModuleValue MenuItemBridge::SetContentFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
163 {
164 EcmaVM* vm = runtimeCallInfo->GetVM();
165 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
166 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
167 Local<JSValueRef> sizeArg = runtimeCallInfo->GetCallArgRef(1); // 1: index of font size
168 Local<JSValueRef> weightArg = runtimeCallInfo->GetCallArgRef(2); // 2: index of font weight
169 Local<JSValueRef> familyArg = runtimeCallInfo->GetCallArgRef(3); // 3: index of font family
170 Local<JSValueRef> styleArg = runtimeCallInfo->GetCallArgRef(4); // 4: index of font style
171 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
172 if (sizeArg->IsUndefined() && weightArg->IsUndefined() && familyArg->IsUndefined() && styleArg->IsUndefined()) {
173 GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFont(nativeNode);
174 return panda::JSValueRef::Undefined(vm);
175 }
176
177 CalcDimension fontSize;
178 if (!ArkTSUtils::ParseJsDimensionFp(vm, sizeArg, fontSize, false)) {
179 fontSize = Dimension(0.0);
180 }
181
182 std::string weight = DEFAULT_ERR_CODE;
183 if (weightArg->IsNumber()) {
184 weight = std::to_string(weightArg->Int32Value(vm));
185 } else {
186 if (!ArkTSUtils::ParseJsString(vm, weightArg, weight) || weight.empty()) {
187 weight = DEFAULT_ERR_CODE;
188 }
189 }
190
191 int32_t style = -1;
192 if (styleArg->IsNumber()) {
193 style = styleArg->Int32Value(vm);
194 }
195
196 std::string family;
197 if (!ArkTSUtils::ParseJsFontFamiliesToString(vm, familyArg, family) || family.empty()) {
198 family = DEFAULT_ERR_CODE;
199 }
200
201 std::string fontSizeStr = fontSize.ToString();
202 std::string fontInfo =
203 StringUtils::FormatString(FORMAT_FONT.c_str(), fontSizeStr.c_str(), weight.c_str(), family.c_str());
204 GetArkUINodeModifiers()->getMenuItemModifier()->setContentFont(nativeNode, fontInfo.c_str(), style);
205 return panda::JSValueRef::Undefined(vm);
206 }
207
ResetContentFont(ArkUIRuntimeCallInfo * runtimeCallInfo)208 ArkUINativeModuleValue MenuItemBridge::ResetContentFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
209 {
210 EcmaVM* vm = runtimeCallInfo->GetVM();
211 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
212 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
213 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
214 GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFont(nativeNode);
215 return panda::JSValueRef::Undefined(vm);
216 }
217
SetSelectIcon(ArkUIRuntimeCallInfo * runtimeCallInfo)218 ArkUINativeModuleValue MenuItemBridge::SetSelectIcon(ArkUIRuntimeCallInfo* runtimeCallInfo)
219 {
220 EcmaVM* vm = runtimeCallInfo->GetVM();
221 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
222 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
223 Local<JSValueRef> inputArg = runtimeCallInfo->GetCallArgRef(1);
224 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
225 std::function<void(WeakPtr<NG::FrameNode>)> symbolApply;
226 bool isShow = false;
227 std::string icon;
228 if (inputArg->IsBoolean()) {
229 isShow = inputArg->ToBoolean(vm)->Value();
230 } else if (inputArg->IsString(vm)) {
231 icon = inputArg->ToString(vm)->ToString(vm);
232 isShow = true;
233 } else if (ArkTSUtils::ParseJsMedia(vm, inputArg, icon)) {
234 isShow = true;
235 } else if (inputArg->IsObject(vm)) {
236 isShow = true;
237 Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
238 Framework::JSViewAbstract::SetSymbolOptionApply(runtimeCallInfo, symbolApply, info[1]);
239 }
240 GetArkUINodeModifiers()->getMenuItemModifier()->setSelectIcon(nativeNode, isShow);
241 GetArkUINodeModifiers()->getMenuItemModifier()->setSelectIconSrc(nativeNode, icon.c_str());
242 GetArkUINodeModifiers()->getMenuItemModifier()->setSelectIconSymbol(
243 nativeNode, reinterpret_cast<void*>(&symbolApply));
244 return panda::JSValueRef::Undefined(vm);
245 }
246
ResetSelectIcon(ArkUIRuntimeCallInfo * runtimeCallInfo)247 ArkUINativeModuleValue MenuItemBridge::ResetSelectIcon(ArkUIRuntimeCallInfo* runtimeCallInfo)
248 {
249 EcmaVM* vm = runtimeCallInfo->GetVM();
250 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
251 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
252 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
253 GetArkUINodeModifiers()->getMenuItemModifier()->resetSelectIcon(nativeNode);
254 GetArkUINodeModifiers()->getMenuItemModifier()->resetSelectIconSrc(nativeNode);
255 GetArkUINodeModifiers()->getMenuItemModifier()->resetSelectIconSymbol(nativeNode);
256 return panda::JSValueRef::Undefined(vm);
257 }
258
SetOnChange(ArkUIRuntimeCallInfo * runtimeCallInfo)259 ArkUINativeModuleValue MenuItemBridge::SetOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
260 {
261 EcmaVM* vm = runtimeCallInfo->GetVM();
262 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
263 int32_t argsNumber = runtimeCallInfo->GetArgsNumber();
264 if (argsNumber != NUM_2) {
265 return panda::JSValueRef::Undefined(vm);
266 }
267 Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
268 Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
269 auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
270 auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
271 CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
272 if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
273 GetArkUINodeModifiers()->getMenuItemModifier()->resetOnChange(nativeNode);
274 return panda::JSValueRef::Undefined(vm);
275 }
276 panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
277 std::function<void(bool)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)](bool flag) {
278 panda::LocalScope pandaScope(vm);
279 panda::TryCatch trycatch(vm);
280 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
281 panda::Local<panda::JSValueRef> params[1] = { panda::BooleanRef::New(vm, flag) };
282 func->Call(vm, func.ToLocal(), params, 1);
283 };
284 GetArkUINodeModifiers()->getMenuItemModifier()->setOnChange(nativeNode, reinterpret_cast<void*>(&callback));
285 return panda::JSValueRef::Undefined(vm);
286 }
287
ResetOnChange(ArkUIRuntimeCallInfo * runtimeCallInfo)288 ArkUINativeModuleValue MenuItemBridge::ResetOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
289 {
290 EcmaVM* vm = runtimeCallInfo->GetVM();
291 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
292 Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
293 auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
294 GetArkUINodeModifiers()->getMenuItemModifier()->resetOnChange(nativeNode);
295 return panda::JSValueRef::Undefined(vm);
296 }
297
298 } // namespace OHOS::Ace::NG