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 "core/interfaces/native/node/menu_modifier.h"
16
17 #include "core/components/common/properties/text_style.h"
18 #include "core/components_ng/base/frame_node.h"
19 #include "core/components_ng/pattern/menu/menu_model_ng.h"
20 #include "core/pipeline/base/element_register.h"
21 #include "frameworks/bridge/common/utils/utils.h"
22
23 namespace OHOS::Ace::NG {
24 const char DELIMITER = '|';
25 constexpr int32_t SIZE_OF_FONT_INFO = 3;
26 static const char* ERR_CODE = "-1";
27 constexpr int SUB_MENU_EXPANDING_MODE_SIDE = 0;
28 constexpr int SUB_MENU_EXPANDING_MODE_EMBEDDED = 1;
29 constexpr int SUB_MENU_EXPANDING_MODE_STACK = 2;
30 const std::string DEFAULT_FONT_WEIGHT = "normal";
31 const std::string DEFAULT_FONT_FAMILY = "HarmonyOS Sans";
32 const Ace::FontStyle DEFAULT_FONT_STYLE = Ace::FontStyle::NORMAL;
33 const std::vector<OHOS::Ace::FontStyle> FONT_STYLES = { OHOS::Ace::FontStyle::NORMAL, OHOS::Ace::FontStyle::ITALIC };
34
ParseSubMenuExpandingMode(int32_t subMenuExpandingMode)35 SubMenuExpandingMode ParseSubMenuExpandingMode(int32_t subMenuExpandingMode)
36 {
37 SubMenuExpandingMode mode = SubMenuExpandingMode::SIDE;
38 switch (subMenuExpandingMode) {
39 case SUB_MENU_EXPANDING_MODE_SIDE:
40 mode = SubMenuExpandingMode::SIDE;
41 break;
42 case SUB_MENU_EXPANDING_MODE_EMBEDDED:
43 mode = SubMenuExpandingMode::EMBEDDED;
44 break;
45 case SUB_MENU_EXPANDING_MODE_STACK:
46 mode = SubMenuExpandingMode::STACK;
47 break;
48 default:
49 break;
50 }
51 return mode;
52 }
53
SetMenuDivider(ArkUINodeHandle node,ArkUIMenuDividerOptions * dividerInfo,bool isGroupDivider)54 void SetMenuDivider(ArkUINodeHandle node, ArkUIMenuDividerOptions* dividerInfo, bool isGroupDivider)
55 {
56 auto* frameNode = reinterpret_cast<FrameNode*>(node);
57 CHECK_NULL_VOID(frameNode);
58
59 V2::ItemDivider divider;
60 divider.strokeWidth = Dimension(dividerInfo->strokeWidth.value,
61 static_cast<OHOS::Ace::DimensionUnit>(dividerInfo->strokeWidth.units));
62 divider.color = Color(dividerInfo->color);
63 divider.startMargin = Dimension(dividerInfo->startMargin.value,
64 static_cast<OHOS::Ace::DimensionUnit>(dividerInfo->startMargin.units));;
65 divider.endMargin = Dimension(dividerInfo->endMargin.value,
66 static_cast<OHOS::Ace::DimensionUnit>(dividerInfo->endMargin.units));;
67 if (isGroupDivider) {
68 MenuModelNG::SetItemGroupDivider(frameNode, divider);
69 } else {
70 MenuModelNG::SetItemDivider(frameNode, divider);
71 }
72 }
73
ResetMenuDivider(ArkUINodeHandle node,bool isGroupDivider)74 void ResetMenuDivider(ArkUINodeHandle node, bool isGroupDivider)
75 {
76 auto* frameNode = reinterpret_cast<FrameNode*>(node);
77 CHECK_NULL_VOID(frameNode);
78 V2::ItemDivider divider;
79 divider.strokeWidth = Dimension(0.0);
80 divider.color = Color::TRANSPARENT;
81 divider.startMargin = Dimension(0.0);
82 divider.endMargin = Dimension(0.0);
83 if (isGroupDivider) {
84 MenuModelNG::SetItemGroupDivider(frameNode, divider);
85 } else {
86 MenuModelNG::SetItemDivider(frameNode, divider);
87 }
88 }
89
SetMenuFontColor(ArkUINodeHandle node,uint32_t color)90 void SetMenuFontColor(ArkUINodeHandle node, uint32_t color)
91 {
92 auto* frameNode = reinterpret_cast<FrameNode*>(node);
93 CHECK_NULL_VOID(frameNode);
94 MenuModelNG::SetFontColor(frameNode, Color(color));
95 }
96
ResetMenuFontColor(ArkUINodeHandle node)97 void ResetMenuFontColor(ArkUINodeHandle node)
98 {
99 auto* frameNode = reinterpret_cast<FrameNode*>(node);
100 CHECK_NULL_VOID(frameNode);
101 std::optional<Color> color = std::nullopt;
102 MenuModelNG::SetFontColor(frameNode, color);
103 }
104
SetMenuFont(ArkUINodeHandle node,const char * fontInfo,int32_t styleVal)105 void SetMenuFont(ArkUINodeHandle node, const char* fontInfo, int32_t styleVal)
106 {
107 auto* frameNode = reinterpret_cast<FrameNode*>(node);
108 CHECK_NULL_VOID(frameNode);
109
110 std::vector<std::string> res;
111 std::string fontValues = std::string(fontInfo);
112 StringUtils::StringSplitter(fontValues, DELIMITER, res);
113 if (res.empty() || res.size() != SIZE_OF_FONT_INFO) {
114 return;
115 }
116
117 CalcDimension fontSize;
118 if (res[0] != ERR_CODE) { // 0: index of font size data
119 fontSize = StringUtils::StringToCalcDimension(res[0], false, DimensionUnit::FP);
120 }
121 MenuModelNG::SetFontSize(frameNode, fontSize);
122
123 if (res[1] != ERR_CODE) { // 1: index of font weight data
124 MenuModelNG::SetFontWeight(frameNode, Framework::ConvertStrToFontWeight(res[1]));
125 } else {
126 MenuModelNG::SetFontWeight(frameNode, FontWeight::NORMAL);
127 }
128
129 if (styleVal >= 0 && styleVal < static_cast<int32_t>(FONT_STYLES.size())) {
130 MenuModelNG::SetFontStyle(frameNode, FONT_STYLES[styleVal]);
131 } else {
132 MenuModelNG::SetFontStyle(frameNode, DEFAULT_FONT_STYLE);
133 }
134
135 if (res[2] != ERR_CODE) { // 2: index of font family data
136 MenuModelNG::SetFontFamily(frameNode, Framework::ConvertStrToFontFamilies(res[2]));
137 } else {
138 MenuModelNG::SetFontFamily(frameNode, Framework::ConvertStrToFontFamilies(DEFAULT_FONT_FAMILY));
139 }
140 }
141
ResetMenuFont(ArkUINodeHandle node)142 void ResetMenuFont(ArkUINodeHandle node)
143 {
144 auto* frameNode = reinterpret_cast<FrameNode*>(node);
145 CHECK_NULL_VOID(frameNode);
146 CalcDimension fontSize;
147 FontWeight fontWeight = StringUtils::StringToFontWeight(DEFAULT_FONT_WEIGHT);
148 MenuModelNG::SetFontSize(frameNode, fontSize);
149 MenuModelNG::SetFontWeight(frameNode, fontWeight);
150 MenuModelNG::SetFontStyle(frameNode, DEFAULT_FONT_STYLE);
151 MenuModelNG::SetFontFamily(frameNode, Framework::ConvertStrToFontFamilies(DEFAULT_FONT_FAMILY));
152 }
153
SetRadius(ArkUINodeHandle node,const ArkUI_Float32 * values,const int32_t * units)154 void SetRadius(ArkUINodeHandle node, const ArkUI_Float32* values, const int32_t* units)
155 {
156 auto* frameNode = reinterpret_cast<FrameNode*>(node);
157 CHECK_NULL_VOID(frameNode);
158 auto topLeft =
159 Dimension(values[0], static_cast<OHOS::Ace::DimensionUnit>(units[0])); // 0: index of top left value
160 auto topRight =
161 Dimension(values[1], static_cast<OHOS::Ace::DimensionUnit>(units[1])); // 1: index of top right value
162 auto bottomLeft =
163 Dimension(values[2], static_cast<OHOS::Ace::DimensionUnit>(units[2])); // 2: index of bottom left value
164 auto bottomRight =
165 Dimension(values[3], static_cast<OHOS::Ace::DimensionUnit>(units[3])); // 3: index of bottom right value
166 MenuModelNG::SetBorderRadius(frameNode, topLeft, topRight, bottomLeft, bottomRight);
167 }
168
ResetRadius(ArkUINodeHandle node)169 void ResetRadius(ArkUINodeHandle node)
170 {
171 auto* frameNode = reinterpret_cast<FrameNode*>(node);
172 CHECK_NULL_VOID(frameNode);
173 MenuModelNG::ResetBorderRadius(frameNode);
174 }
175
SetMenuWidth(ArkUINodeHandle node,ArkUI_Float32 value,int32_t unit)176 void SetMenuWidth(ArkUINodeHandle node, ArkUI_Float32 value, int32_t unit)
177 {
178 auto* frameNode = reinterpret_cast<FrameNode*>(node);
179 CHECK_NULL_VOID(frameNode);
180 Dimension width = Dimension(value, static_cast<OHOS::Ace::DimensionUnit>(unit));
181 MenuModelNG::SetWidth(frameNode, width);
182 }
183
ResetMenuWidth(ArkUINodeHandle node)184 void ResetMenuWidth(ArkUINodeHandle node)
185 {
186 auto* frameNode = reinterpret_cast<FrameNode*>(node);
187 CHECK_NULL_VOID(frameNode);
188 OHOS::Ace::CalcDimension reset;
189 MenuModelNG::SetWidth(frameNode, reset);
190 }
191
SetMenuItemDivider(ArkUINodeHandle node,ArkUIMenuDividerOptions * menuItemDividerInfo)192 void SetMenuItemDivider(ArkUINodeHandle node, ArkUIMenuDividerOptions* menuItemDividerInfo)
193 {
194 SetMenuDivider(node, menuItemDividerInfo, false);
195 }
196
ResetMenuItemDivider(ArkUINodeHandle node)197 void ResetMenuItemDivider(ArkUINodeHandle node)
198 {
199 ResetMenuDivider(node, false);
200 }
201
SetMenuItemGroupDivider(ArkUINodeHandle node,ArkUIMenuDividerOptions * menuItemGroupDividerInfo)202 void SetMenuItemGroupDivider(ArkUINodeHandle node, ArkUIMenuDividerOptions* menuItemGroupDividerInfo)
203 {
204 SetMenuDivider(node, menuItemGroupDividerInfo, true);
205 }
206
ResetMenuItemGroupDivider(ArkUINodeHandle node)207 void ResetMenuItemGroupDivider(ArkUINodeHandle node)
208 {
209 ResetMenuDivider(node, true);
210 }
211
SetSubMenuExpandingMode(ArkUINodeHandle node,ArkUI_Int32 modeParam)212 void SetSubMenuExpandingMode(ArkUINodeHandle node, ArkUI_Int32 modeParam)
213 {
214 auto* frameNode = reinterpret_cast<FrameNode*>(node);
215 CHECK_NULL_VOID(frameNode);
216
217 SubMenuExpandingMode subMenuExpandingMode = ParseSubMenuExpandingMode(modeParam);
218 MenuModelNG::SetExpandingMode(frameNode, subMenuExpandingMode);
219 }
220
ResetSubMenuExpandingMode(ArkUINodeHandle node)221 void ResetSubMenuExpandingMode(ArkUINodeHandle node)
222 {
223 auto* frameNode = reinterpret_cast<FrameNode*>(node);
224 CHECK_NULL_VOID(frameNode);
225 MenuModelNG::SetExpandingMode(frameNode, SubMenuExpandingMode::SIDE);
226 }
227
228 namespace NodeModifier {
GetMenuModifier()229 const ArkUIMenuModifier* GetMenuModifier()
230 {
231 static const ArkUIMenuModifier modifier = { SetMenuFontColor, ResetMenuFontColor, SetMenuFont, ResetMenuFont,
232 SetRadius, ResetRadius, SetMenuWidth, ResetMenuWidth, SetMenuItemDivider, ResetMenuItemDivider,
233 SetMenuItemGroupDivider, ResetMenuItemGroupDivider, SetSubMenuExpandingMode, ResetSubMenuExpandingMode };
234
235 return &modifier;
236 }
237
GetCJUIMenuModifier()238 const CJUIMenuModifier* GetCJUIMenuModifier()
239 {
240 static const CJUIMenuModifier modifier = { SetMenuFontColor, ResetMenuFontColor, SetMenuFont, ResetMenuFont,
241 SetRadius, ResetRadius, SetMenuWidth, ResetMenuWidth };
242
243 return &modifier;
244 }
245 }
246 } // namespace OHOS::Ace::NG
247