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
16 #include "core/components_ng/pattern/menu/menu_item/menu_item_model_ng.h"
17
18 #include "base/geometry/dimension.h"
19 #include "base/utils/utils.h"
20 #include "core/components/select/select_theme.h"
21 #include "core/components_ng/base/view_stack_processor.h"
22 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
23 #include "core/components_ng/pattern/menu/menu_item/menu_item_layout_property.h"
24 #include "core/components_ng/pattern/menu/menu_item/menu_item_pattern.h"
25 #include "core/components_v2/inspector/inspector_constants.h"
26 #include "core/pipeline/pipeline_base.h"
27
28 namespace OHOS::Ace::NG {
Create(const RefPtr<UINode> & customNode)29 void MenuItemModelNG::Create(const RefPtr<UINode>& customNode)
30 {
31 auto* stack = ViewStackProcessor::GetInstance();
32 int32_t nodeId = stack->ClaimNodeId();
33 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::MENU_ITEM_ETS_TAG, nodeId);
34 auto menuItem = FrameNode::GetOrCreateFrameNode(
35 V2::MENU_ITEM_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<CustomMenuItemPattern>(); });
36 CHECK_NULL_VOID(menuItem);
37 stack->Push(menuItem);
38
39 auto layoutProps = menuItem->GetLayoutProperty();
40 CHECK_NULL_VOID(layoutProps);
41 layoutProps->UpdateAlignment(Alignment::CENTER_LEFT);
42 // set border radius
43 auto renderContext = menuItem->GetRenderContext();
44 CHECK_NULL_VOID(renderContext);
45 auto pipeline = PipelineBase::GetCurrentContext();
46 CHECK_NULL_VOID(pipeline);
47 auto theme = pipeline->GetTheme<SelectTheme>();
48 CHECK_NULL_VOID(theme);
49 BorderRadiusProperty border;
50 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
51 border.SetRadius(theme->GetMenuDefaultInnerRadius());
52 } else {
53 border.SetRadius(theme->GetInnerBorderRadius());
54 }
55 renderContext->UpdateBorderRadius(border);
56
57 CHECK_NULL_VOID(customNode);
58 menuItem->AddChild(customNode);
59 }
60
61 /*
62 * The structure of menu item is designed as follows :
63 * |--menu_item
64 * |--left_row
65 * |--icon
66 * |--content
67 * |--right_row
68 * |--label
69 * |--end_icon
70 */
Create(const MenuItemProperties & menuItemProps)71 void MenuItemModelNG::Create(const MenuItemProperties& menuItemProps)
72 {
73 auto* stack = ViewStackProcessor::GetInstance();
74 int32_t nodeId = stack->ClaimNodeId();
75 auto menuItem = FrameNode::GetOrCreateFrameNode(
76 V2::MENU_ITEM_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<MenuItemPattern>(); });
77 CHECK_NULL_VOID(menuItem);
78 stack->Push(menuItem);
79
80 // set border radius
81 auto renderContext = menuItem->GetRenderContext();
82 CHECK_NULL_VOID(renderContext);
83 auto pipeline = PipelineBase::GetCurrentContext();
84 CHECK_NULL_VOID(pipeline);
85 auto theme = pipeline->GetTheme<SelectTheme>();
86 CHECK_NULL_VOID(theme);
87 BorderRadiusProperty border;
88 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
89 border.SetRadius(theme->GetMenuDefaultInnerRadius());
90 } else {
91 border.SetRadius(theme->GetInnerBorderRadius());
92 }
93 renderContext->UpdateBorderRadius(border);
94
95 auto leftRow = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
96 AceType::MakeRefPtr<LinearLayoutPattern>(false));
97 CHECK_NULL_VOID(leftRow);
98 auto leftRowLayoutProps = leftRow->GetLayoutProperty<LinearLayoutProperty>();
99 CHECK_NULL_VOID(leftRowLayoutProps);
100 leftRowLayoutProps->UpdateMainAxisAlign(FlexAlign::FLEX_START);
101 leftRowLayoutProps->UpdateCrossAxisAlign(FlexAlign::CENTER);
102 leftRowLayoutProps->UpdateSpace(theme->GetIconContentPadding());
103
104 leftRow->MountToParent(menuItem);
105 auto rightRow = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
106 AceType::MakeRefPtr<LinearLayoutPattern>(false));
107 CHECK_NULL_VOID(rightRow);
108 auto rightRowLayoutProps = rightRow->GetLayoutProperty<LinearLayoutProperty>();
109 CHECK_NULL_VOID(rightRowLayoutProps);
110 rightRowLayoutProps->UpdateMainAxisAlign(FlexAlign::CENTER);
111 rightRowLayoutProps->UpdateCrossAxisAlign(FlexAlign::CENTER);
112 rightRowLayoutProps->UpdateSpace(theme->GetIconContentPadding());
113
114 rightRow->MountToParent(menuItem);
115 auto buildFunc = menuItemProps.buildFunc;
116 auto pattern = menuItem->GetPattern<MenuItemPattern>();
117 CHECK_NULL_VOID(pattern);
118 if (buildFunc.has_value()) {
119 pattern->SetSubBuilder(buildFunc.value_or(nullptr));
120 }
121 UpdateMenuProperty(menuItem, menuItemProps);
122 }
123
UpdateMenuProperty(const RefPtr<NG::FrameNode> & menuItem,const MenuItemProperties & menuItemProps)124 void MenuItemModelNG::UpdateMenuProperty(const RefPtr<NG::FrameNode>& menuItem, const MenuItemProperties& menuItemProps)
125 {
126 auto menuProperty = menuItem->GetLayoutProperty<MenuItemLayoutProperty>();
127 CHECK_NULL_VOID(menuProperty);
128
129 menuProperty->UpdateStartIcon(menuItemProps.startIcon.value_or(ImageSourceInfo("")));
130 menuProperty->UpdateContent(menuItemProps.content);
131 menuProperty->UpdateEndIcon(menuItemProps.endIcon.value_or(ImageSourceInfo("")));
132 menuProperty->UpdateLabel(menuItemProps.labelInfo.value_or(""));
133 menuProperty->SetStartSymbol(menuItemProps.startApply);
134 menuProperty->SetEndSymbol(menuItemProps.endApply);
135 }
136
SetSelected(bool isSelected)137 void MenuItemModelNG::SetSelected(bool isSelected)
138 {
139 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
140 CHECK_NULL_VOID(frameNode);
141 auto pattern = frameNode->GetPattern<MenuItemPattern>();
142 CHECK_NULL_VOID(pattern);
143 pattern->SetSelected(isSelected);
144 auto eventHub = frameNode->GetEventHub<MenuItemEventHub>();
145 CHECK_NULL_VOID(eventHub);
146 eventHub->SetCurrentUIState(UI_STATE_SELECTED, isSelected);
147 }
148
SetSelectIcon(bool isShow)149 void MenuItemModelNG::SetSelectIcon(bool isShow)
150 {
151 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, SelectIcon, isShow);
152 }
153
SetSelectIconSrc(const std::string & src)154 void MenuItemModelNG::SetSelectIconSrc(const std::string& src)
155 {
156 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, SelectIconSrc, src);
157 }
158
SetSelectIconSymbol(std::function<void (WeakPtr<NG::FrameNode>)> && symbolApply)159 void MenuItemModelNG::SetSelectIconSymbol(std::function<void(WeakPtr<NG::FrameNode>)>&& symbolApply)
160 {
161 if (symbolApply != nullptr) {
162 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
163 CHECK_NULL_VOID(frameNode);
164 auto menuProperty = frameNode->GetLayoutProperty<MenuItemLayoutProperty>();
165 menuProperty->SetSelectSymbol(symbolApply);
166 }
167 }
168
SetOnChange(std::function<void (bool)> && onChange)169 void MenuItemModelNG::SetOnChange(std::function<void(bool)>&& onChange)
170 {
171 auto eventHub = ViewStackProcessor::GetInstance()->GetMainFrameNodeEventHub<MenuItemEventHub>();
172 CHECK_NULL_VOID(eventHub);
173 eventHub->SetOnChange(onChange);
174 }
175
SetFontSize(const Dimension & fontSize)176 void MenuItemModelNG::SetFontSize(const Dimension& fontSize)
177 {
178 if (fontSize.IsValid()) {
179 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontSize, fontSize);
180 } else {
181 ACE_RESET_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontSize);
182 }
183 }
184
SetFontWeight(FontWeight weight)185 void MenuItemModelNG::SetFontWeight(FontWeight weight)
186 {
187 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontWeight, weight);
188 }
189
SetFontStyle(Ace::FontStyle style)190 void MenuItemModelNG::SetFontStyle(Ace::FontStyle style)
191 {
192 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, ItalicFontStyle, style);
193 }
194
SetFontColor(const std::optional<Color> & color)195 void MenuItemModelNG::SetFontColor(const std::optional<Color>& color)
196 {
197 if (color.has_value()) {
198 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontColor, color.value());
199 } else {
200 ACE_RESET_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontColor);
201 }
202 }
203
SetFontFamily(const std::vector<std::string> & families)204 void MenuItemModelNG::SetFontFamily(const std::vector<std::string> &families)
205 {
206 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontFamily, families);
207 }
208
SetLabelFontSize(const Dimension & fontSize)209 void MenuItemModelNG::SetLabelFontSize(const Dimension& fontSize)
210 {
211 if (fontSize.IsValid()) {
212 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontSize, fontSize);
213 } else {
214 ACE_RESET_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontSize);
215 }
216 }
217
SetLabelFontWeight(FontWeight weight)218 void MenuItemModelNG::SetLabelFontWeight(FontWeight weight)
219 {
220 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontWeight, weight);
221 }
222
SetLabelFontStyle(Ace::FontStyle style)223 void MenuItemModelNG::SetLabelFontStyle(Ace::FontStyle style)
224 {
225 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelItalicFontStyle, style);
226 }
227
SetLabelFontColor(const std::optional<Color> & color)228 void MenuItemModelNG::SetLabelFontColor(const std::optional<Color>& color)
229 {
230 if (color.has_value()) {
231 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontColor, color.value());
232 } else {
233 ACE_RESET_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontColor);
234 }
235 }
236
SetLabelFontFamily(const std::vector<std::string> & families)237 void MenuItemModelNG::SetLabelFontFamily(const std::vector<std::string> &families)
238 {
239 ACE_UPDATE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontFamily, families);
240 }
241
SetSelectedChangeEvent(std::function<void (bool)> && selectedChangeEvent)242 void MenuItemModelNG::SetSelectedChangeEvent(std::function<void(bool)>&& selectedChangeEvent)
243 {
244 auto eventHub = ViewStackProcessor::GetInstance()->GetMainFrameNodeEventHub<MenuItemEventHub>();
245 CHECK_NULL_VOID(eventHub);
246 eventHub->SetSelectedChangeEvent(selectedChangeEvent);
247 }
248
SetSelected(FrameNode * frameNode,bool isSelected)249 void MenuItemModelNG::SetSelected(FrameNode* frameNode, bool isSelected)
250 {
251 CHECK_NULL_VOID(frameNode);
252 auto pattern = frameNode->GetPattern<MenuItemPattern>();
253 CHECK_NULL_VOID(pattern);
254 pattern->SetSelected(isSelected);
255 auto eventHub = frameNode->GetEventHub<MenuItemEventHub>();
256 CHECK_NULL_VOID(eventHub);
257 eventHub->SetCurrentUIState(UI_STATE_SELECTED, isSelected);
258 }
259
SetLabelFontColor(FrameNode * frameNode,const std::optional<Color> & color)260 void MenuItemModelNG::SetLabelFontColor(FrameNode* frameNode, const std::optional<Color>& color)
261 {
262 if (color.has_value()) {
263 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontColor, color.value(), frameNode);
264 } else {
265 ACE_RESET_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontColor, frameNode);
266 }
267 }
268
SetFontColor(FrameNode * frameNode,const std::optional<Color> & color)269 void MenuItemModelNG::SetFontColor(FrameNode* frameNode, const std::optional<Color>& color)
270 {
271 if (color.has_value()) {
272 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontColor, color.value(), frameNode);
273 } else {
274 ACE_RESET_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontColor, frameNode);
275 }
276 }
277
SetLabelFontSize(FrameNode * frameNode,const Dimension & fontSize)278 void MenuItemModelNG::SetLabelFontSize(FrameNode* frameNode, const Dimension& fontSize)
279 {
280 if (fontSize.IsValid()) {
281 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontSize, fontSize, frameNode);
282 } else {
283 ACE_RESET_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontSize, frameNode);
284 }
285 }
286
SetLabelFontWeight(FrameNode * frameNode,FontWeight weight)287 void MenuItemModelNG::SetLabelFontWeight(FrameNode* frameNode, FontWeight weight)
288 {
289 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontWeight, weight, frameNode);
290 }
291
SetLabelFontFamily(FrameNode * frameNode,const std::vector<std::string> & families)292 void MenuItemModelNG::SetLabelFontFamily(FrameNode* frameNode, const std::vector<std::string> &families)
293 {
294 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelFontFamily, families, frameNode);
295 }
296
SetLabelFontStyle(FrameNode * frameNode,Ace::FontStyle style)297 void MenuItemModelNG::SetLabelFontStyle(FrameNode* frameNode, Ace::FontStyle style)
298 {
299 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, LabelItalicFontStyle, style, frameNode);
300 }
301
SetFontSize(FrameNode * frameNode,const Dimension & fontSize)302 void MenuItemModelNG::SetFontSize(FrameNode* frameNode, const Dimension& fontSize)
303 {
304 if (fontSize.IsValid()) {
305 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontSize, fontSize, frameNode);
306 } else {
307 ACE_RESET_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontSize, frameNode);
308 }
309 }
310
SetFontWeight(FrameNode * frameNode,FontWeight weight)311 void MenuItemModelNG::SetFontWeight(FrameNode* frameNode, FontWeight weight)
312 {
313 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontWeight, weight, frameNode);
314 }
315
SetFontFamily(FrameNode * frameNode,const std::vector<std::string> & families)316 void MenuItemModelNG::SetFontFamily(FrameNode* frameNode, const std::vector<std::string> &families)
317 {
318 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, FontFamily, families, frameNode);
319 }
320
SetFontStyle(FrameNode * frameNode,Ace::FontStyle style)321 void MenuItemModelNG::SetFontStyle(FrameNode* frameNode, Ace::FontStyle style)
322 {
323 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, ItalicFontStyle, style, frameNode);
324 }
325
SetSelectIcon(FrameNode * frameNode,bool isShow)326 void MenuItemModelNG::SetSelectIcon(FrameNode* frameNode, bool isShow)
327 {
328 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, SelectIcon, isShow, frameNode);
329 }
330
SetSelectIconSrc(FrameNode * frameNode,const std::string & src)331 void MenuItemModelNG::SetSelectIconSrc(FrameNode* frameNode, const std::string& src)
332 {
333 ACE_UPDATE_NODE_LAYOUT_PROPERTY(MenuItemLayoutProperty, SelectIconSrc, src, frameNode);
334 }
335
SetSelectIconSymbol(FrameNode * frameNode,std::function<void (WeakPtr<NG::FrameNode>)> && symbolApply)336 void MenuItemModelNG::SetSelectIconSymbol(FrameNode* frameNode,
337 std::function<void(WeakPtr<NG::FrameNode>)>&& symbolApply)
338 {
339 if (symbolApply != nullptr) {
340 auto menuProperty = frameNode->GetLayoutProperty<MenuItemLayoutProperty>();
341 CHECK_NULL_VOID(menuProperty);
342 menuProperty->SetSelectSymbol(symbolApply);
343 }
344 }
345 } // namespace OHOS::Ace::NG
346