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/multi_menu_layout_algorithm.h"
17
18 #include "core/components/common/layout/grid_system_manager.h"
19 #include "core/components_ng/pattern/menu/menu_theme.h"
20 #include "core/components_ng/pattern/menu/menu_pattern.h"
21 #include "core/components_ng/pattern/menu/menu_item/menu_item_layout_property.h"
22 #include "core/components_ng/pattern/select_overlay/select_overlay_node.h"
23 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
24
25 namespace OHOS::Ace::NG {
26 namespace {
27 struct SelectOverlayRightClickMenuLayoutHelper {
AdjustLayoutConstraintsOHOS::Ace::NG::__anon8ebb139c0111::SelectOverlayRightClickMenuLayoutHelper28 static void AdjustLayoutConstraints(
29 LayoutConstraintF& constrainMinWidth, const RefPtr<LayoutWrapper>& child, LayoutWrapper* layoutWrapper)
30 {
31 auto host = layoutWrapper->GetHostNode();
32 CHECK_NULL_VOID(host);
33 auto scrollNode = host->GetParentFrameNode();
34 CHECK_NULL_VOID(scrollNode);
35 auto outterMenuNode = scrollNode->GetParentFrameNode();
36 CHECK_NULL_VOID(outterMenuNode);
37 auto outterMenuPattern = outterMenuNode->GetPattern<MenuPattern>();
38 CHECK_NULL_VOID(outterMenuPattern);
39 auto menuWrapperNode = outterMenuNode->GetParentFrameNode();
40 CHECK_NULL_VOID(menuWrapperNode);
41 auto childLayoutProperty = child->GetLayoutProperty();
42 CHECK_NULL_VOID(childLayoutProperty);
43 if (menuWrapperNode->GetInspectorIdValue("") != SelectOverlayRrightClickMenuWrapper ||
44 !outterMenuPattern->IsSelectOverlayRightClickMenu() ||
45 child->GetHostTag() != V2::RELATIVE_CONTAINER_ETS_TAG) {
46 return;
47 }
48 childLayoutProperty->UpdateUserDefinedIdealSize(
49 { CalcLength(1.0, DimensionUnit::PERCENT), CalcLength(0.0, DimensionUnit::AUTO) });
50 constrainMinWidth.percentReference.SetWidth(constrainMinWidth.selfIdealSize.Width().value());
51 auto row = child->GetChildByIndex(0);
52 CHECK_NULL_VOID(row);
53 auto layoutProperty = row->GetLayoutProperty();
54 CHECK_NULL_VOID(layoutProperty);
55 layoutProperty->UpdateUserDefinedIdealSize(
56 { CalcLength(1.0, DimensionUnit::PERCENT), CalcLength(1.0, DimensionUnit::AUTO) });
57 auto pasteButtonRow = child->GetChildByIndex(1);
58 CHECK_NULL_VOID(pasteButtonRow);
59 auto pasteButton = pasteButtonRow->GetChildByIndex(0);
60 CHECK_NULL_VOID(pasteButton);
61 auto pasteButtonLayoutProperty = pasteButton->GetLayoutProperty();
62 CHECK_NULL_VOID(pasteButtonLayoutProperty);
63 pasteButtonLayoutProperty->UpdateUserDefinedIdealSize(
64 { CalcLength(1.0, DimensionUnit::PERCENT), CalcLength(1.0, DimensionUnit::PERCENT) });
65 }
66
AdjustLayoutConstraintsAutoWidthOHOS::Ace::NG::__anon8ebb139c0111::SelectOverlayRightClickMenuLayoutHelper67 static void AdjustLayoutConstraintsAutoWidth(const RefPtr<LayoutWrapper>& child, LayoutWrapper* layoutWrapper)
68 {
69 auto host = layoutWrapper->GetHostNode();
70 CHECK_NULL_VOID(host);
71 auto scrollNode = host->GetParentFrameNode();
72 CHECK_NULL_VOID(scrollNode);
73 auto outterMenuNode = scrollNode->GetParentFrameNode();
74 CHECK_NULL_VOID(outterMenuNode);
75 auto outterMenuPattern = outterMenuNode->GetPattern<MenuPattern>();
76 CHECK_NULL_VOID(outterMenuPattern);
77 auto menuWrapperNode = outterMenuNode->GetParentFrameNode();
78 CHECK_NULL_VOID(menuWrapperNode);
79 auto childLayoutProperty = child->GetLayoutProperty();
80 CHECK_NULL_VOID(childLayoutProperty);
81 if (menuWrapperNode->GetInspectorIdValue("") != SelectOverlayRrightClickMenuWrapper ||
82 !outterMenuPattern->IsSelectOverlayRightClickMenu() ||
83 child->GetHostTag() != V2::RELATIVE_CONTAINER_ETS_TAG) {
84 return;
85 }
86 childLayoutProperty->UpdateUserDefinedIdealSize(
87 { CalcLength(0.0, DimensionUnit::AUTO), CalcLength(0.0, DimensionUnit::AUTO) });
88 auto row = child->GetChildByIndex(0);
89 CHECK_NULL_VOID(row);
90 auto layoutProperty = row->GetLayoutProperty();
91 CHECK_NULL_VOID(layoutProperty);
92 layoutProperty->UpdateUserDefinedIdealSize(
93 { CalcLength(0.0, DimensionUnit::AUTO), CalcLength(0.0, DimensionUnit::AUTO) });
94 auto pasteButtonRow = child->GetChildByIndex(1);
95 CHECK_NULL_VOID(pasteButtonRow);
96 auto pasteButton = pasteButtonRow->GetChildByIndex(0);
97 CHECK_NULL_VOID(pasteButton);
98 auto pasteButtonLayoutProperty = pasteButton->GetLayoutProperty();
99 CHECK_NULL_VOID(pasteButtonLayoutProperty);
100 pasteButtonLayoutProperty->UpdateUserDefinedIdealSize(
101 { CalcLength(0.0, DimensionUnit::AUTO), CalcLength(0.0, DimensionUnit::AUTO) });
102 }
103 };
104 } // namespace
105
UpdateColumnWidth(const RefPtr<FrameNode> & frameNode,const RefPtr<GridColumnInfo> & columnInfo)106 bool UpdateColumnWidth(const RefPtr<FrameNode>& frameNode, const RefPtr<GridColumnInfo>& columnInfo)
107 {
108 CHECK_NULL_RETURN(frameNode && columnInfo, false);
109 auto pipeline = frameNode->GetContext();
110 CHECK_NULL_RETURN(pipeline, false);
111 if (Positive(pipeline->GetRootWidth())) {
112 return false;
113 }
114
115 auto currentId = Container::CurrentId();
116 CHECK_NULL_RETURN(currentId >= MIN_SUBCONTAINER_ID, false);
117 auto subwindowManager = SubwindowManager::GetInstance();
118 CHECK_NULL_RETURN(subwindowManager, false);
119 auto subwindow = subwindowManager->GetSubwindowByType(pipeline->GetInstanceId(), SubwindowType::TYPE_MENU);
120 CHECK_NULL_RETURN(subwindow, false);
121 auto width = subwindow->GetRect().Width();
122 CHECK_NULL_RETURN(Positive(width), false);
123 auto parent = columnInfo->GetParent();
124 CHECK_NULL_RETURN(parent, false);
125 parent->BuildColumnWidth(width);
126 return true;
127 }
128
Measure(LayoutWrapper * layoutWrapper)129 void MultiMenuLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
130 {
131 CHECK_NULL_VOID(layoutWrapper);
132 auto layoutProperty = layoutWrapper->GetLayoutProperty();
133 CHECK_NULL_VOID(layoutProperty);
134 auto layoutConstraint = layoutProperty->GetLayoutConstraint();
135 CHECK_NULL_VOID(layoutConstraint);
136 auto childConstraint = layoutProperty->CreateChildConstraint();
137 childConstraint.maxSize.SetWidth(layoutConstraint->maxSize.Width());
138 // constraint max size minus padding
139 const auto& padding = layoutProperty->CreatePaddingAndBorder();
140 auto node = layoutWrapper->GetHostNode();
141 CHECK_NULL_VOID(node);
142 auto pattern = node->GetPattern<MenuPattern>();
143 CHECK_NULL_VOID(pattern);
144 if (!pattern->IsEmbedded()) {
145 MinusPaddingToSize(padding, childConstraint.maxSize);
146 } else {
147 UpdateEmbeddedPercentReference(layoutWrapper, childConstraint, layoutConstraint);
148 }
149 if (layoutConstraint->selfIdealSize.Width().has_value()) {
150 // when Menu is set self ideal width, make children node adaptively fill up.
151 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
152 if (LessNotEqual(layoutConstraint->selfIdealSize.Width().value(), MIN_MENU_WIDTH.ConvertToPx())) {
153 RefPtr<GridColumnInfo> columnInfo;
154 columnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::MENU);
155 CHECK_NULL_VOID(columnInfo);
156 auto columnParent = columnInfo->GetParent();
157 CHECK_NULL_VOID(columnParent);
158 columnParent->BuildColumnWidth();
159 auto minWidth = static_cast<float>(columnInfo->GetWidth(MENU_MIN_GRID_COUNTS));
160 layoutConstraint->selfIdealSize.SetWidth(minWidth);
161
162 UpdateMenuDefaultConstraintByDevice(pattern, childConstraint, padding.Width(), layoutConstraint, true);
163 }
164 }
165 auto idealWidth =
166 std::max(layoutConstraint->minSize.Width(),
167 std::min(layoutConstraint->maxSize.Width(), layoutConstraint->selfIdealSize.Width().value())) -
168 padding.Width();
169 childConstraint.selfIdealSize.SetWidth(idealWidth);
170 } else {
171 // constraint min width base on grid column
172 auto columnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::MENU);
173 CHECK_NULL_VOID(columnInfo);
174 auto columnParent = columnInfo->GetParent();
175 CHECK_NULL_VOID(columnParent);
176 if (!UpdateSelectOverlayMenuMinWidth(pattern, columnInfo) && !UpdateColumnWidth(node, columnInfo)) {
177 columnParent->BuildColumnWidth();
178 }
179 auto minWidth = static_cast<float>(columnInfo->GetWidth()) - padding.Width();
180 childConstraint.minSize.SetWidth(minWidth);
181
182 UpdateMenuDefaultConstraintByDevice(pattern, childConstraint, padding.Width(), layoutConstraint, false);
183 }
184 // Calculate max width of menu items
185 UpdateConstraintBaseOnMenuItems(layoutWrapper, childConstraint);
186 UpdateSelfSize(layoutWrapper, childConstraint, layoutConstraint);
187 }
188
UpdateMenuDefaultConstraintByDevice(const RefPtr<MenuPattern> & pattern,LayoutConstraintF & childConstraint,float paddingWidth,std::optional<LayoutConstraintF> & layoutConstraint,bool idealSizeHasVal)189 void MultiMenuLayoutAlgorithm::UpdateMenuDefaultConstraintByDevice(const RefPtr<MenuPattern>& pattern,
190 LayoutConstraintF& childConstraint, float paddingWidth, std::optional<LayoutConstraintF>& layoutConstraint,
191 bool idealSizeHasVal)
192 {
193 CHECK_NULL_VOID(pattern);
194
195 // only 2in1 device has restrictions on the menu width in API13
196 CHECK_NULL_VOID(Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_THIRTEEN));
197 auto pipeline = PipelineBase::GetCurrentContext();
198 CHECK_NULL_VOID(pipeline);
199 auto theme = pipeline->GetTheme<SelectTheme>();
200 CHECK_NULL_VOID(theme);
201 auto expandDisplay = theme->GetExpandDisplay();
202 CHECK_NULL_VOID(expandDisplay);
203
204 auto mainMenuPattern = pattern->GetMainMenuPattern();
205 CHECK_NULL_VOID(mainMenuPattern);
206 if (!mainMenuPattern->IsContextMenu() && !mainMenuPattern->IsMenu() &&
207 !mainMenuPattern->IsSelectOverlayRightClickMenu()) {
208 return;
209 }
210
211 if (idealSizeHasVal) {
212 layoutConstraint->selfIdealSize.SetWidth(theme->GetMenuDefaultWidth().ConvertToPx());
213 } else {
214 childConstraint.minSize.SetWidth(theme->GetMenuDefaultWidth().ConvertToPx() - paddingWidth);
215 }
216 }
217
Layout(LayoutWrapper * layoutWrapper)218 void MultiMenuLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper)
219 {
220 CHECK_NULL_VOID(layoutWrapper);
221 BoxLayoutAlgorithm::PerformLayout(layoutWrapper);
222
223 auto pipeline = PipelineBase::GetCurrentContext();
224 CHECK_NULL_VOID(pipeline);
225 auto theme = pipeline->GetTheme<SelectTheme>();
226 CHECK_NULL_VOID(theme);
227 auto layoutProperty = layoutWrapper->GetLayoutProperty();
228 CHECK_NULL_VOID(layoutProperty);
229 auto node = layoutWrapper->GetHostNode();
230 CHECK_NULL_VOID(node);
231 auto pattern = node->GetPattern<MenuPattern>();
232 CHECK_NULL_VOID(pattern);
233 OffsetF translate(0.0f, 0.0f);
234 const auto& padding = layoutProperty->CreatePaddingAndBorder();
235 auto outPadding = static_cast<float>(theme->GetMenuPadding().ConvertToPx());
236 if (!pattern->IsEmbedded()) {
237 translate.AddX(padding.left.value_or(outPadding));
238 translate.AddY(padding.top.value_or(outPadding));
239 }
240 // translate each option by the height of previous options
241 for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) {
242 child->GetGeometryNode()->SetMarginFrameOffset(translate);
243 child->Layout();
244 translate.AddY(child->GetGeometryNode()->GetMarginFrameSize().Height());
245 }
246 }
247
UpdateEmbeddedPercentReference(LayoutWrapper * layoutWrapper,LayoutConstraintF & childConstraint,std::optional<LayoutConstraintF> & layoutConstraint)248 void MultiMenuLayoutAlgorithm::UpdateEmbeddedPercentReference(LayoutWrapper* layoutWrapper,
249 LayoutConstraintF& childConstraint, std::optional<LayoutConstraintF>& layoutConstraint)
250 {
251 // Set percent reference for embedded menu the same as for parent menu item
252 auto node = layoutWrapper->GetHostNode();
253 CHECK_NULL_VOID(node);
254 auto parentNode = AceType::DynamicCast<FrameNode>(node->GetParent());
255 CHECK_NULL_VOID(parentNode);
256 auto parentProperty = parentNode->GetLayoutProperty<MenuItemLayoutProperty>();
257 CHECK_NULL_VOID(parentProperty);
258 auto parentConstraint = parentProperty->GetLayoutConstraint();
259 CHECK_NULL_VOID(parentConstraint);
260 auto parentPercentReference = parentConstraint->percentReference.Height();
261 layoutConstraint->percentReference.SetHeight(parentPercentReference);
262
263 auto props = layoutWrapper->GetLayoutProperty();
264 CHECK_NULL_VOID(props);
265 const auto& calcConstraint = props->GetCalcLayoutConstraint();
266 if (calcConstraint && calcConstraint->selfIdealSize.has_value() &&
267 calcConstraint->selfIdealSize.value().Height().has_value()) {
268 ScaleProperty scaleProperty;
269 if (layoutWrapper->GetGeometryNode() && layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint()) {
270 scaleProperty = layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint()->scaleProperty;
271 } else {
272 scaleProperty = layoutConstraint->scaleProperty;
273 }
274 userHeight_ = ConvertToPx(calcConstraint->selfIdealSize.value().Height()->GetDimension(),
275 scaleProperty, layoutConstraint->percentReference.Height()).value_or(0.0f);
276 }
277
278 // Update embedded menu items percent reference dependent of the submenu constraint
279 if (GreatNotEqual(userHeight_, 0.0f)) {
280 childConstraint.percentReference.SetHeight(userHeight_);
281 } else {
282 childConstraint.percentReference.SetHeight(parentPercentReference);
283 }
284 }
285
UpdateSelfSize(LayoutWrapper * layoutWrapper,LayoutConstraintF & childConstraint,std::optional<LayoutConstraintF> & layoutConstraint)286 void MultiMenuLayoutAlgorithm::UpdateSelfSize(LayoutWrapper* layoutWrapper,
287 LayoutConstraintF& childConstraint, std::optional<LayoutConstraintF>& layoutConstraint)
288 {
289 auto node = layoutWrapper->GetHostNode();
290 CHECK_NULL_VOID(node);
291 auto pattern = node->GetPattern<MenuPattern>();
292 CHECK_NULL_VOID(pattern);
293
294 float contentHeight = 0.0f;
295 float contentWidth = childConstraint.selfIdealSize.Width().value();
296 for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) {
297 if (!child) {
298 TAG_LOGW(AceLogTag::ACE_MENU, "child is null in MultiMenu");
299 continue;
300 }
301 auto resetLayoutConstraint = ResetLayoutConstraintMinWidth(child, childConstraint);
302 SelectOverlayRightClickMenuLayoutHelper::AdjustLayoutConstraints(
303 resetLayoutConstraint, child, layoutWrapper);
304 if (pattern->IsEmbedded() && (resetLayoutConstraint.minSize.Width() > resetLayoutConstraint.maxSize.Width())) {
305 resetLayoutConstraint.minSize.SetWidth(resetLayoutConstraint.maxSize.Width());
306 }
307 child->Measure(resetLayoutConstraint);
308 auto childGeometryNode = child->GetGeometryNode();
309 CHECK_NULL_VOID(childGeometryNode);
310 auto childHeight = std::max(childGeometryNode->GetMarginFrameSize().Height(),
311 childGeometryNode->GetContentSize().Height());
312 contentHeight += childHeight;
313 }
314 layoutWrapper->GetGeometryNode()->SetContentSize(SizeF(contentWidth, contentHeight));
315 BoxLayoutAlgorithm::PerformMeasureSelf(layoutWrapper);
316
317 // Stack or Embedded submenu must follow parent width
318 if (pattern->IsStackSubmenu() || pattern->IsEmbedded()) {
319 auto idealSize = layoutWrapper->GetGeometryNode()->GetFrameSize();
320 auto width = layoutConstraint->maxSize.Width();
321 idealSize.SetWidth(width);
322 if (pattern->IsEmbedded()) {
323 auto idealHeight = GreatNotEqual(userHeight_, 0.0f) ? userHeight_ : contentHeight;
324 idealSize.SetHeight(idealHeight);
325 }
326 layoutWrapper->GetGeometryNode()->SetFrameSize(idealSize);
327 } else if (layoutConstraint->selfIdealSize.Width().has_value()) {
328 auto idealWidth = std::max(layoutConstraint->minSize.Width(),
329 std::min(layoutConstraint->maxSize.Width(), layoutConstraint->selfIdealSize.Width().value()));
330 auto idealSize = layoutWrapper->GetGeometryNode()->GetFrameSize();
331 idealSize.SetWidth(idealWidth);
332 layoutWrapper->GetGeometryNode()->SetFrameSize(idealSize);
333 }
334 }
335
UpdateConstraintBaseOnMenuItems(LayoutWrapper * layoutWrapper,LayoutConstraintF & constraint)336 void MultiMenuLayoutAlgorithm::UpdateConstraintBaseOnMenuItems(
337 LayoutWrapper* layoutWrapper, LayoutConstraintF& constraint)
338 {
339 // multiMenu children are menuItem or menuItemGroup, constrain width is same as the menu
340 auto maxChildrenWidth = GetChildrenMaxWidth(layoutWrapper, constraint);
341 constraint.selfIdealSize.SetWidth(maxChildrenWidth);
342 }
343
GetChildrenMaxWidth(LayoutWrapper * layoutWrapper,const LayoutConstraintF & layoutConstraint)344 float MultiMenuLayoutAlgorithm::GetChildrenMaxWidth(
345 LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint)
346 {
347 float maxWidth = 0.0f;
348 auto node = layoutWrapper->GetHostNode();
349 CHECK_NULL_RETURN(node, maxWidth);
350 auto pattern = node->GetPattern<MenuPattern>();
351 CHECK_NULL_RETURN(pattern, maxWidth);
352 for (const auto& child : layoutWrapper->GetAllChildrenWithBuild()) {
353 auto childConstraint = ResetLayoutConstraintMinWidth(child, layoutConstraint);
354 if (pattern->IsEmbedded() && (childConstraint.minSize.Width() > childConstraint.maxSize.Width())) {
355 childConstraint.minSize.SetWidth(childConstraint.maxSize.Width());
356 }
357 SelectOverlayRightClickMenuLayoutHelper::AdjustLayoutConstraintsAutoWidth(child, layoutWrapper);
358 child->Measure(childConstraint);
359 auto childSize = child->GetGeometryNode()->GetMarginFrameSize();
360 maxWidth = std::max(maxWidth, childSize.Width());
361 }
362 return maxWidth;
363 }
364
ResetLayoutConstraintMinWidth(const RefPtr<LayoutWrapper> & child,const LayoutConstraintF & layoutConstraint)365 LayoutConstraintF MultiMenuLayoutAlgorithm::ResetLayoutConstraintMinWidth(
366 const RefPtr<LayoutWrapper>& child, const LayoutConstraintF& layoutConstraint)
367 {
368 auto childLayoutProps = child->GetLayoutProperty();
369 CHECK_NULL_RETURN(childLayoutProps, layoutConstraint);
370 auto childConstraint = layoutConstraint;
371 const auto& calcConstraint = childLayoutProps->GetCalcLayoutConstraint();
372 if (calcConstraint && calcConstraint->selfIdealSize.has_value() &&
373 calcConstraint->selfIdealSize.value().Width().has_value()) {
374 childConstraint.minSize.Reset();
375 }
376 return childConstraint;
377 }
378
UpdateSelectOverlayMenuMinWidth(const RefPtr<MenuPattern> & pattern,const RefPtr<GridColumnInfo> & columnInfo)379 bool MultiMenuLayoutAlgorithm::UpdateSelectOverlayMenuMinWidth(
380 const RefPtr<MenuPattern>& pattern, const RefPtr<GridColumnInfo>& columnInfo)
381 {
382 CHECK_NULL_RETURN(pattern, false);
383 auto mainMenuPattern = pattern->GetMainMenuPattern();
384 CHECK_NULL_RETURN(mainMenuPattern, false);
385 CHECK_NULL_RETURN(mainMenuPattern->IsSelectOverlayRightClickMenu(), false);
386 auto menuWrapper = pattern->GetMenuWrapper();
387 CHECK_NULL_RETURN(menuWrapper, false);
388 auto menuWrapperPattern = menuWrapper->GetPattern<MenuWrapperPattern>();
389 CHECK_NULL_RETURN(menuWrapperPattern, false);
390 CHECK_NULL_RETURN(menuWrapperPattern->GetIsSelectOverlaySubWindowWrapper(), false);
391 auto mainWindowContainerId = menuWrapperPattern->GetContainerId();
392 auto container = Container::GetContainer(mainWindowContainerId);
393 CHECK_NULL_RETURN(container, false);
394 auto pipelineContext = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext());
395 CHECK_NULL_RETURN(pipelineContext, false);
396 auto displayWindowRect = pipelineContext->GetDisplayWindowRectInfo();
397 auto mainWindowWidth = displayWindowRect.Width();
398 if (Positive(mainWindowWidth)) {
399 auto parent = columnInfo->GetParent();
400 CHECK_NULL_RETURN(parent, false);
401 parent->BuildColumnWidth(mainWindowWidth);
402 TAG_LOGD(
403 AceLogTag::ACE_MENU, "Update select overlay right click menu min width with main window width constraint.");
404 return true;
405 }
406 return false;
407 }
408 } // namespace OHOS::Ace::NG
409