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";
SetMenuItemSelected(ArkUIRuntimeCallInfo * runtimeCallInfo)25 ArkUINativeModuleValue MenuItemBridge::SetMenuItemSelected(ArkUIRuntimeCallInfo* runtimeCallInfo)
26 {
27     EcmaVM* vm = runtimeCallInfo->GetVM();
28     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
29     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
30     Local<JSValueRef> isSelectedArg = runtimeCallInfo->GetCallArgRef(1);
31     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
32     if (isSelectedArg->IsBoolean()) {
33         bool isSelected = isSelectedArg->ToBoolean(vm)->Value();
34         GetArkUINodeModifiers()->getMenuItemModifier()->setMenuItemSelected(nativeNode, isSelected);
35     } else {
36         GetArkUINodeModifiers()->getMenuItemModifier()->resetMenuItemSelected(nativeNode);
37     }
38     return panda::JSValueRef::Undefined(vm);
39 }
40 
ResetMenuItemSelected(ArkUIRuntimeCallInfo * runtimeCallInfo)41 ArkUINativeModuleValue MenuItemBridge::ResetMenuItemSelected(ArkUIRuntimeCallInfo* runtimeCallInfo)
42 {
43     EcmaVM* vm = runtimeCallInfo->GetVM();
44     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
45     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
46     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
47     GetArkUINodeModifiers()->getMenuItemModifier()->resetMenuItemSelected(nativeNode);
48     return panda::JSValueRef::Undefined(vm);
49 }
50 
SetLabelFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)51 ArkUINativeModuleValue MenuItemBridge::SetLabelFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
52 {
53     EcmaVM* vm = runtimeCallInfo->GetVM();
54     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
55     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
56     Local<JSValueRef> colorArg = runtimeCallInfo->GetCallArgRef(1);
57     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
58     Color color;
59     if (!ArkTSUtils::ParseJsColorAlpha(vm, colorArg, color)) {
60         GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFontColor(nativeNode);
61     } else {
62         GetArkUINodeModifiers()->getMenuItemModifier()->setLabelFontColor(nativeNode, color.GetValue());
63     }
64     return panda::JSValueRef::Undefined(vm);
65 }
66 
ResetLabelFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)67 ArkUINativeModuleValue MenuItemBridge::ResetLabelFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
68 {
69     EcmaVM* vm = runtimeCallInfo->GetVM();
70     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
71     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
72     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
73     GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFontColor(nativeNode);
74     return panda::JSValueRef::Undefined(vm);
75 }
76 
SetContentFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)77 ArkUINativeModuleValue MenuItemBridge::SetContentFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
78 {
79     EcmaVM* vm = runtimeCallInfo->GetVM();
80     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
81     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
82     Local<JSValueRef> colorArg = runtimeCallInfo->GetCallArgRef(1);
83     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
84     Color color;
85     if (!ArkTSUtils::ParseJsColorAlpha(vm, colorArg, color)) {
86         GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFontColor(nativeNode);
87     } else {
88         GetArkUINodeModifiers()->getMenuItemModifier()->setContentFontColor(nativeNode, color.GetValue());
89     }
90     return panda::JSValueRef::Undefined(vm);
91 }
92 
ResetContentFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)93 ArkUINativeModuleValue MenuItemBridge::ResetContentFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
94 {
95     EcmaVM* vm = runtimeCallInfo->GetVM();
96     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
97     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
98     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
99     GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFontColor(nativeNode);
100     return panda::JSValueRef::Undefined(vm);
101 }
102 
SetLabelFont(ArkUIRuntimeCallInfo * runtimeCallInfo)103 ArkUINativeModuleValue MenuItemBridge::SetLabelFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
104 {
105     EcmaVM* vm = runtimeCallInfo->GetVM();
106     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
107     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
108     Local<JSValueRef> sizeArg = runtimeCallInfo->GetCallArgRef(1);   // 1: label font size
109     Local<JSValueRef> weightArg = runtimeCallInfo->GetCallArgRef(2); // 2: label font weight
110     Local<JSValueRef> familyArg = runtimeCallInfo->GetCallArgRef(3); // 3: label font family
111     Local<JSValueRef> styleArg = runtimeCallInfo->GetCallArgRef(4);  // 4: label font style
112     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
113     if (sizeArg->IsUndefined() && weightArg->IsUndefined() && familyArg->IsUndefined() && styleArg->IsUndefined()) {
114         GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFont(nativeNode);
115         return panda::JSValueRef::Undefined(vm);
116     }
117 
118     CalcDimension fontSize;
119     if (!ArkTSUtils::ParseJsDimensionFp(vm, sizeArg, fontSize, false)) {
120         fontSize = Dimension(0.0);
121     }
122 
123     std::string weight = DEFAULT_ERR_CODE;
124     if (weightArg->IsNumber()) {
125         weight = std::to_string(weightArg->Int32Value(vm));
126     } else {
127         if (!ArkTSUtils::ParseJsString(vm, weightArg, weight) || weight.empty()) {
128             weight = DEFAULT_ERR_CODE;
129         }
130     }
131 
132     int32_t style = -1;
133     if (styleArg->IsNumber()) {
134         style = styleArg->Int32Value(vm);
135     }
136 
137     std::string family;
138     if (!ArkTSUtils::ParseJsFontFamiliesToString(vm, familyArg, family) || family.empty()) {
139         family = DEFAULT_ERR_CODE;
140     }
141 
142     std::string fontSizeStr = fontSize.ToString();
143     std::string fontInfo =
144         StringUtils::FormatString(FORMAT_FONT.c_str(), fontSizeStr.c_str(), weight.c_str(), family.c_str());
145     GetArkUINodeModifiers()->getMenuItemModifier()->setLabelFont(nativeNode, fontInfo.c_str(), style);
146     return panda::JSValueRef::Undefined(vm);
147 }
148 
ResetLabelFont(ArkUIRuntimeCallInfo * runtimeCallInfo)149 ArkUINativeModuleValue MenuItemBridge::ResetLabelFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
150 {
151     EcmaVM* vm = runtimeCallInfo->GetVM();
152     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
153     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
154     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
155     GetArkUINodeModifiers()->getMenuItemModifier()->resetLabelFont(nativeNode);
156     return panda::JSValueRef::Undefined(vm);
157 }
158 
SetContentFont(ArkUIRuntimeCallInfo * runtimeCallInfo)159 ArkUINativeModuleValue MenuItemBridge::SetContentFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
160 {
161     EcmaVM* vm = runtimeCallInfo->GetVM();
162     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
163     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
164     Local<JSValueRef> sizeArg = runtimeCallInfo->GetCallArgRef(1);   // 1: index of font size
165     Local<JSValueRef> weightArg = runtimeCallInfo->GetCallArgRef(2); // 2: index of font weight
166     Local<JSValueRef> familyArg = runtimeCallInfo->GetCallArgRef(3); // 3: index of font family
167     Local<JSValueRef> styleArg = runtimeCallInfo->GetCallArgRef(4);  // 4: index of font style
168     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
169     if (sizeArg->IsUndefined() && weightArg->IsUndefined() && familyArg->IsUndefined() && styleArg->IsUndefined()) {
170         GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFont(nativeNode);
171         return panda::JSValueRef::Undefined(vm);
172     }
173 
174     CalcDimension fontSize;
175     if (!ArkTSUtils::ParseJsDimensionFp(vm, sizeArg, fontSize, false)) {
176         fontSize = Dimension(0.0);
177     }
178 
179     std::string weight = DEFAULT_ERR_CODE;
180     if (weightArg->IsNumber()) {
181         weight = std::to_string(weightArg->Int32Value(vm));
182     } else {
183         if (!ArkTSUtils::ParseJsString(vm, weightArg, weight) || weight.empty()) {
184             weight = DEFAULT_ERR_CODE;
185         }
186     }
187 
188     int32_t style = -1;
189     if (styleArg->IsNumber()) {
190         style = styleArg->Int32Value(vm);
191     }
192 
193     std::string family;
194     if (!ArkTSUtils::ParseJsFontFamiliesToString(vm, familyArg, family) || family.empty()) {
195         family = DEFAULT_ERR_CODE;
196     }
197 
198     std::string fontSizeStr = fontSize.ToString();
199     std::string fontInfo =
200         StringUtils::FormatString(FORMAT_FONT.c_str(), fontSizeStr.c_str(), weight.c_str(), family.c_str());
201     GetArkUINodeModifiers()->getMenuItemModifier()->setContentFont(nativeNode, fontInfo.c_str(), style);
202     return panda::JSValueRef::Undefined(vm);
203 }
204 
ResetContentFont(ArkUIRuntimeCallInfo * runtimeCallInfo)205 ArkUINativeModuleValue MenuItemBridge::ResetContentFont(ArkUIRuntimeCallInfo* runtimeCallInfo)
206 {
207     EcmaVM* vm = runtimeCallInfo->GetVM();
208     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
209     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
210     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
211     GetArkUINodeModifiers()->getMenuItemModifier()->resetContentFont(nativeNode);
212     return panda::JSValueRef::Undefined(vm);
213 }
214 
SetSelectIcon(ArkUIRuntimeCallInfo * runtimeCallInfo)215 ArkUINativeModuleValue MenuItemBridge::SetSelectIcon(ArkUIRuntimeCallInfo* runtimeCallInfo)
216 {
217     EcmaVM* vm = runtimeCallInfo->GetVM();
218     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
219     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
220     Local<JSValueRef> inputArg = runtimeCallInfo->GetCallArgRef(1);
221     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
222     std::function<void(WeakPtr<NG::FrameNode>)> symbolApply;
223     bool isShow = false;
224     std::string icon;
225     if (inputArg->IsBoolean()) {
226         isShow = inputArg->ToBoolean(vm)->Value();
227     } else if (inputArg->IsString(vm)) {
228         icon = inputArg->ToString(vm)->ToString(vm);
229         isShow = true;
230     } else if (ArkTSUtils::ParseJsMedia(vm, inputArg, icon)) {
231         isShow = true;
232     } else if (inputArg->IsObject(vm)) {
233         isShow = true;
234         Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
235         Framework::JSViewAbstract::SetSymbolOptionApply(runtimeCallInfo, symbolApply, info[1]);
236     }
237     GetArkUINodeModifiers()->getMenuItemModifier()->setSelectIcon(nativeNode, isShow);
238     GetArkUINodeModifiers()->getMenuItemModifier()->setSelectIconSrc(nativeNode, icon.c_str());
239     GetArkUINodeModifiers()->getMenuItemModifier()->setSelectIconSymbol(
240         nativeNode, reinterpret_cast<void*>(&symbolApply));
241     return panda::JSValueRef::Undefined(vm);
242 }
243 
ResetSelectIcon(ArkUIRuntimeCallInfo * runtimeCallInfo)244 ArkUINativeModuleValue MenuItemBridge::ResetSelectIcon(ArkUIRuntimeCallInfo* runtimeCallInfo)
245 {
246     EcmaVM* vm = runtimeCallInfo->GetVM();
247     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
248     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(0);
249     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
250     GetArkUINodeModifiers()->getMenuItemModifier()->resetSelectIcon(nativeNode);
251     GetArkUINodeModifiers()->getMenuItemModifier()->resetSelectIconSrc(nativeNode);
252     GetArkUINodeModifiers()->getMenuItemModifier()->resetSelectIconSymbol(nativeNode);
253     return panda::JSValueRef::Undefined(vm);
254 }
255 } // namespace OHOS::Ace::NG