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 RefPtr<ResourceObject> colorResObj;
63 auto nodeInfo = ArkTSUtils::MakeNativeNodeInfo(nativeNode);
64 if (!ArkTSUtils::ParseJsColorAlpha(vm, colorArg, color, colorResObj, nodeInfo)) {
65 GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFontColor(nativeNode);
66 } else {
67 auto colorRawPtr = AceType::RawPtr(colorResObj);
68 GetArkUINodeModifiers()->getMenuItemModifier()->setLabelFontColor(nativeNode, color.GetValue(), colorRawPtr);
69 }
70 return panda::JSValueRef::Undefined(vm);
71 }
72
ResetLabelFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)73 ArkUINativeModuleValue MenuItemBridge::ResetLabelFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
74 {
75 EcmaVM* vm = runtimeCallInfo->GetVM();
76 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
77 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
78 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
79 GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFontColor(nativeNode);
80 return panda::JSValueRef::Undefined(vm);
81 }
82
SetContentFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)83 ArkUINativeModuleValue MenuItemBridge::SetContentFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
84 {
85 EcmaVM* vm = runtimeCallInfo->GetVM();
86 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
87 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
88 Local<JSValueRef> colorArg = runtimeCallInfo->GetCallArgRef(1);
89 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
90 Color color;
91 RefPtr<ResourceObject> colorResObj;
92 auto nodeInfo = ArkTSUtils::MakeNativeNodeInfo(nativeNode);
93 if (!ArkTSUtils::ParseJsColorAlpha(vm, colorArg, color, colorResObj, nodeInfo)) {
94 GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFontColor(nativeNode);
95 } else {
96 auto colorRawPtr = AceType::RawPtr(colorResObj);
97 GetArkUINodeModifiers()->getMenuItemModifier()->setContentFontColor(nativeNode, color.GetValue(), colorRawPtr);
98 }
99 return panda::JSValueRef::Undefined(vm);
100 }
101
ResetContentFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)102 ArkUINativeModuleValue MenuItemBridge::ResetContentFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
103 {
104 EcmaVM* vm = runtimeCallInfo->GetVM();
105 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
106 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
107 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
108 GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFontColor(nativeNode);
109 return panda::JSValueRef::Undefined(vm);
110 }
111
SetLabelFont(ArkUIRuntimeCallInfo * runtimeCallInfo)112 ArkUINativeModuleValue MenuItemBridge::SetLabelFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
113 {
114 EcmaVM* vm = runtimeCallInfo->GetVM();
115 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
116 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
117 Local<JSValueRef> sizeArg = runtimeCallInfo->GetCallArgRef(1); // 1: label font size
118 Local<JSValueRef> weightArg = runtimeCallInfo->GetCallArgRef(2); // 2: label font weight
119 Local<JSValueRef> familyArg = runtimeCallInfo->GetCallArgRef(3); // 3: label font family
120 Local<JSValueRef> styleArg = runtimeCallInfo->GetCallArgRef(4); // 4: label font style
121 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
122 if (sizeArg->IsUndefined() && weightArg->IsUndefined() && familyArg->IsUndefined() && styleArg->IsUndefined()) {
123 GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFont(nativeNode);
124 return panda::JSValueRef::Undefined(vm);
125 }
126
127 CalcDimension fontSize;
128 RefPtr<ResourceObject> fontSizeResObj;
129 if (!ArkTSUtils::ParseJsDimensionFp(vm, sizeArg, fontSize, fontSizeResObj, false)) {
130 fontSize = Dimension(0.0);
131 }
132
133 std::string weight = DEFAULT_ERR_CODE;
134 if (weightArg->IsNumber()) {
135 weight = std::to_string(weightArg->Int32Value(vm));
136 } else {
137 if (!ArkTSUtils::ParseJsString(vm, weightArg, weight) || weight.empty()) {
138 weight = DEFAULT_ERR_CODE;
139 }
140 }
141
142 int32_t style = -1;
143 if (styleArg->IsNumber()) {
144 style = styleArg->Int32Value(vm);
145 }
146
147 std::string family;
148 RefPtr<ResourceObject> fontFamiliesResObj;
149 if (!ArkTSUtils::ParseJsFontFamiliesToString(vm, familyArg, family, fontFamiliesResObj) || family.empty()) {
150 family = DEFAULT_ERR_CODE;
151 }
152
153 std::string fontSizeStr = fontSize.ToString();
154 std::string fontInfo =
155 StringUtils::FormatString(FORMAT_FONT.c_str(), fontSizeStr.c_str(), weight.c_str(), family.c_str());
156 auto fontFamiliesRawPtr = AceType::RawPtr(fontFamiliesResObj);
157 auto fontSizeRawPtr = AceType::RawPtr(fontSizeResObj);
158 GetArkUINodeModifiers()->getMenuItemModifier()->setLabelFont(
159 nativeNode, fontInfo.c_str(), style, fontFamiliesRawPtr, fontSizeRawPtr);
160 return panda::JSValueRef::Undefined(vm);
161 }
162
ResetLabelFont(ArkUIRuntimeCallInfo * runtimeCallInfo)163 ArkUINativeModuleValue MenuItemBridge::ResetLabelFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
164 {
165 EcmaVM* vm = runtimeCallInfo->GetVM();
166 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
167 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
168 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
169 GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFont(nativeNode);
170 return panda::JSValueRef::Undefined(vm);
171 }
172
SetContentFont(ArkUIRuntimeCallInfo * runtimeCallInfo)173 ArkUINativeModuleValue MenuItemBridge::SetContentFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
174 {
175 EcmaVM* vm = runtimeCallInfo->GetVM();
176 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
177 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
178 Local<JSValueRef> sizeArg = runtimeCallInfo->GetCallArgRef(1); // 1: index of font size
179 Local<JSValueRef> weightArg = runtimeCallInfo->GetCallArgRef(2); // 2: index of font weight
180 Local<JSValueRef> familyArg = runtimeCallInfo->GetCallArgRef(3); // 3: index of font family
181 Local<JSValueRef> styleArg = runtimeCallInfo->GetCallArgRef(4); // 4: index of font style
182 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
183 if (sizeArg->IsUndefined() && weightArg->IsUndefined() && familyArg->IsUndefined() && styleArg->IsUndefined()) {
184 GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFont(nativeNode);
185 return panda::JSValueRef::Undefined(vm);
186 }
187
188 CalcDimension fontSize;
189 RefPtr<ResourceObject> fontSizeResObj;
190 if (!ArkTSUtils::ParseJsDimensionFp(vm, sizeArg, fontSize, fontSizeResObj, false)) {
191 fontSize = Dimension(0.0);
192 }
193
194 std::string weight = DEFAULT_ERR_CODE;
195 if (weightArg->IsNumber()) {
196 weight = std::to_string(weightArg->Int32Value(vm));
197 } else {
198 if (!ArkTSUtils::ParseJsString(vm, weightArg, weight) || weight.empty()) {
199 weight = DEFAULT_ERR_CODE;
200 }
201 }
202
203 int32_t style = -1;
204 if (styleArg->IsNumber()) {
205 style = styleArg->Int32Value(vm);
206 }
207
208 std::string family;
209 RefPtr<ResourceObject> fontFamiliesResObj;
210 if (!ArkTSUtils::ParseJsFontFamiliesToString(vm, familyArg, family, fontFamiliesResObj) || family.empty()) {
211 family = DEFAULT_ERR_CODE;
212 }
213
214 std::string fontSizeStr = fontSize.ToString();
215 std::string fontInfo =
216 StringUtils::FormatString(FORMAT_FONT.c_str(), fontSizeStr.c_str(), weight.c_str(), family.c_str());
217 auto fontFamiliesRawPtr = AceType::RawPtr(fontFamiliesResObj);
218 auto fontSizeRawPtr = AceType::RawPtr(fontSizeResObj);
219 GetArkUINodeModifiers()->getMenuItemModifier()->setContentFont(
220 nativeNode, fontInfo.c_str(), style, fontSizeRawPtr, fontFamiliesRawPtr);
221 return panda::JSValueRef::Undefined(vm);
222 }
223
ResetContentFont(ArkUIRuntimeCallInfo * runtimeCallInfo)224 ArkUINativeModuleValue MenuItemBridge::ResetContentFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
225 {
226 EcmaVM* vm = runtimeCallInfo->GetVM();
227 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
228 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
229 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
230 GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFont(nativeNode);
231 return panda::JSValueRef::Undefined(vm);
232 }
233
SetSelectIcon(ArkUIRuntimeCallInfo * runtimeCallInfo)234 ArkUINativeModuleValue MenuItemBridge::SetSelectIcon(ArkUIRuntimeCallInfo* runtimeCallInfo)
235 {
236 EcmaVM* vm = runtimeCallInfo->GetVM();
237 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
238 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
239 Local<JSValueRef> inputArg = runtimeCallInfo->GetCallArgRef(1);
240 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
241 std::function<void(WeakPtr<NG::FrameNode>)> symbolApply;
242 bool isShow = false;
243 std::string icon;
244 RefPtr<ResourceObject> selectIconResObj;
245 if (inputArg->IsBoolean()) {
246 isShow = inputArg->ToBoolean(vm)->Value();
247 } else if (inputArg->IsString(vm)) {
248 icon = inputArg->ToString(vm)->ToString(vm);
249 isShow = true;
250 } else if (ArkTSUtils::ParseJsMedia(vm, inputArg, icon, selectIconResObj)) {
251 isShow = true;
252 } else if (inputArg->IsObject(vm)) {
253 isShow = true;
254 Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
255 Framework::JSViewAbstract::SetSymbolOptionApply(runtimeCallInfo, symbolApply, info[1]);
256 }
257 auto selectIconRawPtr = AceType::RawPtr(selectIconResObj);
258 GetArkUINodeModifiers()->getMenuItemModifier()->setSelectIcon(nativeNode, isShow);
259 GetArkUINodeModifiers()->getMenuItemModifier()->setSelectIconSrc(nativeNode, icon.c_str(), selectIconRawPtr);
260 GetArkUINodeModifiers()->getMenuItemModifier()->setSelectIconSymbol(
261 nativeNode, reinterpret_cast<void*>(&symbolApply));
262 return panda::JSValueRef::Undefined(vm);
263 }
264
ResetSelectIcon(ArkUIRuntimeCallInfo * runtimeCallInfo)265 ArkUINativeModuleValue MenuItemBridge::ResetSelectIcon(ArkUIRuntimeCallInfo* runtimeCallInfo)
266 {
267 EcmaVM* vm = runtimeCallInfo->GetVM();
268 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
269 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
270 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
271 GetArkUINodeModifiers()->getMenuItemModifier()->resetSelectIcon(nativeNode);
272 GetArkUINodeModifiers()->getMenuItemModifier()->resetSelectIconSrc(nativeNode);
273 GetArkUINodeModifiers()->getMenuItemModifier()->resetSelectIconSymbol(nativeNode);
274 return panda::JSValueRef::Undefined(vm);
275 }
276
SetOnChange(ArkUIRuntimeCallInfo * runtimeCallInfo)277 ArkUINativeModuleValue MenuItemBridge::SetOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
278 {
279 EcmaVM* vm = runtimeCallInfo->GetVM();
280 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
281 uint32_t argsNumber = runtimeCallInfo->GetArgsNumber();
282 if (argsNumber != NUM_2) {
283 return panda::JSValueRef::Undefined(vm);
284 }
285 Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
286 Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
287 auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
288 auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
289 CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
290 if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
291 GetArkUINodeModifiers()->getMenuItemModifier()->resetOnChange(nativeNode);
292 return panda::JSValueRef::Undefined(vm);
293 }
294 panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
295 std::function<void(bool)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)](bool flag) {
296 panda::LocalScope pandaScope(vm);
297 panda::TryCatch trycatch(vm);
298 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
299 panda::Local<panda::JSValueRef> params[1] = { panda::BooleanRef::New(vm, flag) };
300 func->Call(vm, func.ToLocal(), params, 1);
301 };
302 GetArkUINodeModifiers()->getMenuItemModifier()->setOnChange(nativeNode, reinterpret_cast<void*>(&callback));
303 return panda::JSValueRef::Undefined(vm);
304 }
305
ResetOnChange(ArkUIRuntimeCallInfo * runtimeCallInfo)306 ArkUINativeModuleValue MenuItemBridge::ResetOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
307 {
308 EcmaVM* vm = runtimeCallInfo->GetVM();
309 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
310 Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
311 auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
312 GetArkUINodeModifiers()->getMenuItemModifier()->resetOnChange(nativeNode);
313 return panda::JSValueRef::Undefined(vm);
314 }
315
316 } // namespace OHOS::Ace::NG