• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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/navigation/navigation_layout_util.h"
17 
18 #include "core/components/common/layout/grid_system_manager.h"
19 #include "core/components_ng/pattern/navigation/navdestination_node_base.h"
20 #include "core/components_ng/pattern/navigation/navdestination_pattern_base.h"
21 #include "core/components_ng/pattern/navigation/nav_bar_pattern.h"
22 #include "core/components_ng/pattern/navigation/title_bar_pattern.h"
23 #include "core/components_ng/pattern/navigation/tool_bar_node.h"
24 #include "core/components_ng/pattern/navigation/navigation_title_util.h"
25 
26 namespace OHOS::Ace::NG {
27 namespace {
GetRootWidth(const RefPtr<NavDestinationNodeBase> & nodeBase)28 double GetRootWidth(const RefPtr<NavDestinationNodeBase>& nodeBase)
29 {
30     double fallbackWidth = ScreenSystemManager::GetInstance().GetScreenWidth();
31     CHECK_NULL_RETURN(nodeBase, fallbackWidth);
32     auto context = nodeBase->GetContextRefPtr();
33     CHECK_NULL_RETURN(context, fallbackWidth);
34     auto rotateAngle = nodeBase->GetPageRotateAngle();
35     auto config = nodeBase->GetPageViewportConfig();
36     if (!config || !rotateAngle.has_value() ||
37         rotateAngle.value() == ROTATION_0 || rotateAngle.value() == ROTATION_180) {
38         return GridSystemManager::GetInstance().GetScreenWidth(context);
39     }
40     return config->GetWidth();
41 }
42 }
43 
CheckWhetherNeedToHideToolbar(const RefPtr<NavDestinationNodeBase> & nodeBase,const SizeF & navigationSize)44 bool NavigationLayoutUtil::CheckWhetherNeedToHideToolbar(
45     const RefPtr<NavDestinationNodeBase>& nodeBase, const SizeF& navigationSize)
46 {
47     // if current menu or toolBar is custom, no need to hide.
48     if (nodeBase->GetPrevMenuIsCustomValue(false) || nodeBase->GetPrevToolBarIsCustom().value_or(false)) {
49         return false;
50     }
51 
52     auto toolbarNode = AceType::DynamicCast<NavToolbarNode>(nodeBase->GetToolBarNode());
53     CHECK_NULL_RETURN(toolbarNode, false);
54 
55     if (!EnableToolBarAdaptation(nodeBase)) {
56         TAG_LOGI(AceLogTag::ACE_NAVIGATION, "The toolbar adaptation has been closed");
57         return false;
58     }
59 
60     if (!toolbarNode->HasValidContent()) {
61         return true;
62     }
63 
64     auto theme = NavigationGetTheme();
65     CHECK_NULL_RETURN(theme, false);
66     auto rotationLimitCount = theme->GetToolbarRotationLimitGridCount();
67 
68     RefPtr<GridColumnInfo> columnInfo;
69     columnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::NAVIGATION_TOOLBAR);
70     CHECK_NULL_RETURN(columnInfo, false);
71     auto columnInfoParent = columnInfo->GetParent();
72     CHECK_NULL_RETURN(columnInfoParent, false);
73     columnInfoParent->BuildColumnWidth(GetRootWidth(nodeBase));
74 
75     auto currentColumns = columnInfoParent->GetColumns();
76     float gridWidth = static_cast<float>(columnInfo->GetWidth(rotationLimitCount));
77     float gutterWidth = columnInfoParent->GetGutterWidth().ConvertToPx();
78     float hideLimitWidth = gridWidth + gutterWidth * 2;
79     if (SystemProperties::GetDeviceType() == DeviceType::PHONE) {
80         if (currentColumns >= static_cast<int32_t>(rotationLimitCount) &&
81             GreatOrEqual(navigationSize.Width(), gridWidth)) {
82             return true;
83         }
84     } else if (SystemProperties::GetDeviceType() == DeviceType::TABLET) {
85         if (currentColumns > static_cast<int32_t>(rotationLimitCount) &&
86             GreatNotEqual(navigationSize.Width(), hideLimitWidth)) {
87             return true;
88         }
89     }
90     return false;
91 }
92 
EnableToolBarAdaptation(const RefPtr<NavDestinationNodeBase> & nodeBase)93 bool NavigationLayoutUtil::EnableToolBarAdaptation(const RefPtr<NavDestinationNodeBase>& nodeBase)
94 {
95     auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(nodeBase->GetNavigationNode());
96     if (navigationNode) {
97         auto navigatonLayoutProperty = navigationNode->GetLayoutProperty<NavigationLayoutProperty>();
98         if (navigatonLayoutProperty) {
99             return navigatonLayoutProperty->GetEnableToolBarAdaptationValue(true);
100         }
101     }
102     return true;
103 }
104 
UpdateTitleBarMenuNode(const RefPtr<NavDestinationNodeBase> & nodeBase,const SizeF & navigationSize)105 void NavigationLayoutUtil::UpdateTitleBarMenuNode(
106     const RefPtr<NavDestinationNodeBase>& nodeBase, const SizeF& navigationSize)
107 {
108     auto pattern = nodeBase->GetPattern<NavDestinationPatternBase>();
109     CHECK_NULL_VOID(pattern);
110     if (nodeBase->GetPrevMenuIsCustomValue(false)) {
111         return;
112     }
113 
114     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(nodeBase->GetTitleBarNode());
115     CHECK_NULL_VOID(titleBarNode);
116     auto toolBarNode = AceType::DynamicCast<FrameNode>(nodeBase->GetToolBarNode());
117     CHECK_NULL_VOID(toolBarNode);
118     auto toolBarLayoutProperty = toolBarNode->GetLayoutProperty<LayoutProperty>();
119     CHECK_NULL_VOID(toolBarLayoutProperty);
120     auto toolBarDivider = AceType::DynamicCast<FrameNode>(nodeBase->GetToolBarDividerNode());
121     RefPtr<LayoutProperty> toolBarDividerProperty = nullptr;
122     if (toolBarDivider) {
123         toolBarDividerProperty = toolBarDivider->GetLayoutProperty();
124     }
125     auto isHideToolbar = pattern->GetToolbarHideStatus();
126     auto preMenuNode = titleBarNode->GetMenu();
127     bool needHide = CheckWhetherNeedToHideToolbar(nodeBase, navigationSize);
128     bool isNeedLandscapeMenu = needHide && !isHideToolbar;
129     pattern->SetIsNeedHideToolBarForNavWidth(needHide);
130     if (isNeedLandscapeMenu) {
131         toolBarLayoutProperty->UpdateVisibility(VisibleType::GONE);
132         if (toolBarDividerProperty) {
133             toolBarDividerProperty->UpdateVisibility(VisibleType::GONE);
134         }
135     } else if (!isHideToolbar) {
136         toolBarLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
137         if (toolBarDividerProperty) {
138             toolBarDividerProperty->UpdateVisibility(VisibleType::VISIBLE);
139         }
140     }
141     RefPtr<UINode> newMenuNode = isNeedLandscapeMenu ? nodeBase->GetLandscapeMenu() : nodeBase->GetMenu();
142     if (preMenuNode == newMenuNode) {
143         return;
144     }
145     auto nodeBasePattern = nodeBase->GetPattern<NavDestinationPatternBase>();
146     CHECK_NULL_VOID(nodeBasePattern);
147     // Mark need update safeAreaPadding when need hide safe-area-padding-mode-toolBar by landscape menu
148     if (nodeBasePattern->GetToolBarStyle().value_or(BarStyle::STANDARD) == BarStyle::SAFE_AREA_PADDING) {
149         nodeBasePattern->UpdateSafeAreaPaddingChanged(true);
150     }
151     titleBarNode->RemoveChild(preMenuNode);
152     titleBarNode->SetMenu(newMenuNode);
153     titleBarNode->AddChild(newMenuNode);
154 }
155 
MeasureToolBar(LayoutWrapper * layoutWrapper,const RefPtr<NavDestinationNodeBase> & nodeBase,const RefPtr<NavDestinationLayoutPropertyBase> & layoutPropertyBase,const SizeF & navigationSize)156 float NavigationLayoutUtil::MeasureToolBar(LayoutWrapper* layoutWrapper, const RefPtr<NavDestinationNodeBase>& nodeBase,
157     const RefPtr<NavDestinationLayoutPropertyBase>& layoutPropertyBase, const SizeF& navigationSize)
158 {
159     auto navDestinationPatternBase = nodeBase->GetPattern<NavDestinationPatternBase>();
160     CHECK_NULL_RETURN(navDestinationPatternBase, 0.0f);
161     auto toolBarNode = nodeBase->GetToolBarNode();
162     CHECK_NULL_RETURN(toolBarNode, 0.0f);
163     auto index = nodeBase->GetChildIndexById(toolBarNode->GetId());
164     auto toolBarWrapper = layoutWrapper->GetOrCreateChildByIndex(index);
165     CHECK_NULL_RETURN(toolBarWrapper, 0.0f);
166     auto constraint = layoutPropertyBase->CreateChildConstraint();
167 
168     /**
169      * In the follow scenarios, we need to set the toolBar size to zero.
170      * 1. ToolBar has no child.
171      * 2. ToolBar is hidden and no toolBar animation is running.
172      * 3. ToolBar should be moved to the menu position in the Title.
173      */
174     auto translateState = layoutPropertyBase->GetToolBarTranslateStateValue(BarTranslateState::NONE);
175     if ((translateState == BarTranslateState::NONE &&
176         layoutPropertyBase->GetHideToolBar().value_or(false)) || toolBarNode->GetChildren().empty() ||
177         CheckWhetherNeedToHideToolbar(nodeBase, navigationSize)) {
178         constraint.selfIdealSize = OptionalSizeF(0.0f, 0.0f);
179         toolBarWrapper->Measure(constraint);
180         return 0.0f;
181     }
182 
183     auto theme = NavigationGetTheme();
184     CHECK_NULL_RETURN(theme, 0.0f);
185     auto toolbarHeight = theme->GetToolbarHeigth();
186     constraint.selfIdealSize = OptionalSizeF(navigationSize.Width(), static_cast<float>(toolbarHeight.ConvertToPx()));
187     toolBarWrapper->Measure(constraint);
188     auto toolbarHeightAfterMeasure = toolBarWrapper->GetGeometryNode()->GetFrameSize().Height();
189     return static_cast<float>(toolbarHeightAfterMeasure);
190 }
191 
MeasureToolBarDivider(LayoutWrapper * layoutWrapper,const RefPtr<NavDestinationNodeBase> & nodeBase,const RefPtr<NavDestinationLayoutPropertyBase> & layoutPropertyBase,const SizeF & navigationSize,float toolBarHeight)192 float NavigationLayoutUtil::MeasureToolBarDivider(
193     LayoutWrapper* layoutWrapper, const RefPtr<NavDestinationNodeBase>& nodeBase,
194     const RefPtr<NavDestinationLayoutPropertyBase>& layoutPropertyBase,
195     const SizeF& navigationSize, float toolBarHeight)
196 {
197     if (nodeBase->GetPrevToolBarIsCustom().value_or(false) || !nodeBase->IsUseToolbarConfiguration()) {
198         return 0.0f;
199     }
200 
201     auto navDestinationPatternBase = nodeBase->GetPattern<NavDestinationPatternBase>();
202     CHECK_NULL_RETURN(navDestinationPatternBase, 0.0f);
203     auto toolBarDividerNode = AceType::DynamicCast<FrameNode>(nodeBase->GetToolBarDividerNode());
204     CHECK_NULL_RETURN(toolBarDividerNode, 0.0f);
205     auto dividerIndex = nodeBase->GetChildIndexById(toolBarDividerNode->GetId());
206     auto dividerWrapper = layoutWrapper->GetOrCreateChildByIndex(dividerIndex);
207     CHECK_NULL_RETURN(dividerWrapper, 0.0f);
208     auto constraint = layoutPropertyBase->CreateChildConstraint();
209 
210     /**
211      * In the follow scenarios, we need to set the toolBarDivider size to zero.
212      * 1. ToolBar has zero size.
213      * 2. ToolBar is hidden and no toolBar animation is running.
214      */
215     auto translateState = layoutPropertyBase->GetToolBarTranslateStateValue(BarTranslateState::NONE);
216     if ((translateState == BarTranslateState::NONE &&
217         layoutPropertyBase->GetHideToolBar().value_or(false)) || NearEqual(toolBarHeight, 0.0f)) {
218         constraint.selfIdealSize = OptionalSizeF(0.0f, 0.0f);
219         dividerWrapper->Measure(constraint);
220         return 0.0f;
221     }
222     auto theme = NavigationGetTheme();
223     CHECK_NULL_RETURN(theme, 0.0f);
224     constraint.selfIdealSize =
225         OptionalSizeF(navigationSize.Width(), static_cast<float>(theme->GetToolBarDividerWidth().ConvertToPx()));
226     dividerWrapper->Measure(constraint);
227     return static_cast<float>(theme->GetToolBarDividerWidth().ConvertToPx());
228 }
229 
LayoutToolBar(LayoutWrapper * layoutWrapper,const RefPtr<NavDestinationNodeBase> & nodeBase,const RefPtr<NavDestinationLayoutPropertyBase> & layoutPropertyBase,bool isNeedToCreatePaddingAndBorder)230 float NavigationLayoutUtil::LayoutToolBar(LayoutWrapper* layoutWrapper, const RefPtr<NavDestinationNodeBase>& nodeBase,
231     const RefPtr<NavDestinationLayoutPropertyBase>& layoutPropertyBase, bool isNeedToCreatePaddingAndBorder)
232 {
233     /**
234      * When all the following conditions are met, we consider the boolBar height to be 0:
235      * 1. ToolBar should hide.
236      * 2. No toolBar animation is running or toolBar was translate out of navigation area.
237      */
238     auto translateState = layoutPropertyBase->GetToolBarTranslateStateValue(BarTranslateState::NONE);
239     if (translateState != BarTranslateState::TRANSLATE_ZERO && layoutPropertyBase->GetHideToolBar().value_or(false)) {
240         return 0.0f;
241     }
242     auto toolBarNode = nodeBase->GetToolBarNode();
243     CHECK_NULL_RETURN(toolBarNode, 0.0f);
244     auto index = nodeBase->GetChildIndexById(toolBarNode->GetId());
245     auto toolBarWrapper = layoutWrapper->GetOrCreateChildByIndex(index);
246     CHECK_NULL_RETURN(toolBarWrapper, 0.0f);
247     auto geometryNode = toolBarWrapper->GetGeometryNode();
248     float toolbarHeight = geometryNode->GetFrameSize().Height();
249     if (NearZero(toolbarHeight)) {
250         return 0.0f;
251     }
252     auto toolBarOffsetX = geometryNode->GetFrameOffset().GetX();
253     auto toolBarOffsetY = layoutWrapper->GetGeometryNode()->GetFrameSize().Height() - toolbarHeight;
254     if (isNeedToCreatePaddingAndBorder) {
255         const auto& padding = layoutPropertyBase->CreatePaddingAndBorder();
256         toolBarOffsetX = padding.left.value_or(0.0f);
257         toolBarOffsetY -= padding.bottom.value_or(0.0f);
258     }
259     auto toolBarOffset = OffsetF(static_cast<float>(toolBarOffsetX), static_cast<float>(toolBarOffsetY));
260     geometryNode->SetMarginFrameOffset(toolBarOffset);
261     toolBarWrapper->Layout();
262     return toolbarHeight;
263 }
264 
LayoutToolBarDivider(LayoutWrapper * layoutWrapper,const RefPtr<NavDestinationNodeBase> & nodeBase,const RefPtr<NavDestinationLayoutPropertyBase> & layoutPropertyBase,float toolbarHeight,bool isNeedToCreatePaddingAndBorder)265 void NavigationLayoutUtil::LayoutToolBarDivider(
266     LayoutWrapper* layoutWrapper, const RefPtr<NavDestinationNodeBase>& nodeBase,
267     const RefPtr<NavDestinationLayoutPropertyBase>& layoutPropertyBase, float toolbarHeight,
268     bool isNeedToCreatePaddingAndBorder)
269 {
270     /**
271      * In the follow scenarios, we should not layout the toolBarDivider:
272      * 1. ToolBar has zero size.
273      * 2. Developer use the deprecated `toolBar` attr.
274      * 3. Custom toolbar was used.
275      * 4. Hide toolbar, no toolBar animation is running or toolBar was translate out of navigation area.
276      */
277     auto translateState = layoutPropertyBase->GetToolBarTranslateStateValue(BarTranslateState::NONE);
278     if ((translateState != BarTranslateState::TRANSLATE_ZERO && layoutPropertyBase->GetHideToolBar().value_or(false)) ||
279         nodeBase->GetPrevToolBarIsCustom().value_or(false) ||
280         !nodeBase->IsUseToolbarConfiguration() || NearZero(toolbarHeight)) {
281         return;
282     }
283     auto dividerNode = nodeBase->GetToolBarDividerNode();
284     CHECK_NULL_VOID(dividerNode);
285     auto dividerIndex = nodeBase->GetChildIndexById(dividerNode->GetId());
286     auto dividerWrapper = layoutWrapper->GetOrCreateChildByIndex(dividerIndex);
287     CHECK_NULL_VOID(dividerWrapper);
288     auto dividerGeometryNode = dividerWrapper->GetGeometryNode();
289 
290     auto theme = NavigationGetTheme();
291     CHECK_NULL_VOID(theme);
292     auto dividerOffsetX = dividerGeometryNode->GetFrameOffset().GetX();
293     auto dividerOffsetY = layoutWrapper->GetGeometryNode()->GetFrameSize().Height() - toolbarHeight -
294                           theme->GetToolBarDividerWidth().ConvertToPx();
295     if (isNeedToCreatePaddingAndBorder) {
296         const auto& padding = layoutPropertyBase->CreatePaddingAndBorder();
297         dividerOffsetX = padding.left.value_or(0.0f);
298         dividerOffsetY -= padding.bottom.value_or(0.0f);
299     }
300     auto toolBarDividerOffset = OffsetF(static_cast<float>(dividerOffsetX), static_cast<float>(dividerOffsetY));
301     dividerGeometryNode->SetFrameOffset(toolBarDividerOffset);
302     dividerWrapper->Layout();
303 }
304 
UpdateContentSafeAreaPadding(const RefPtr<NavDestinationNodeBase> & nodeBase,float titleBarHeight)305 void NavigationLayoutUtil::UpdateContentSafeAreaPadding(
306     const RefPtr<NavDestinationNodeBase>& nodeBase, float titleBarHeight)
307 {
308     CHECK_NULL_VOID(nodeBase);
309     auto patternBase = nodeBase->GetPattern<NavDestinationPatternBase>();
310     CHECK_NULL_VOID(patternBase);
311     if (!patternBase->IsSafeAreaPaddingChanged()) {
312         return;
313     }
314     patternBase->UpdateSafeAreaPaddingChanged(false);
315     auto contentNode = AceType::DynamicCast<FrameNode>(nodeBase->GetContentNode());
316     CHECK_NULL_VOID(contentNode);
317     auto contentLayoutProperty = contentNode->GetLayoutProperty();
318     CHECK_NULL_VOID(contentLayoutProperty);
319 
320     Dimension paddingTop = 0.0_vp;
321     if (patternBase->GetTitleBarStyle().value_or(BarStyle::STANDARD) == BarStyle::SAFE_AREA_PADDING &&
322         !NavigationTitleUtil::IsTitleBarHasOffsetY(AceType::DynamicCast<FrameNode>(nodeBase->GetTitleBarNode()))) {
323         paddingTop = Dimension(titleBarHeight);
324     }
325     Dimension paddingBottom = 0.0_vp;
326     auto toolBarNode = AceType::DynamicCast<FrameNode>(nodeBase->GetToolBarNode());
327     if (patternBase->GetToolBarStyle().value_or(BarStyle::STANDARD) == BarStyle::SAFE_AREA_PADDING &&
328         toolBarNode && toolBarNode->IsVisible()) {
329         auto theme = NavigationGetTheme();
330         if (theme) {
331             paddingBottom = theme->GetToolbarHeigth();
332         }
333     }
334     PaddingProperty paddingProperty;
335     paddingProperty.left = CalcLength(0.0_vp);
336     paddingProperty.right = CalcLength(0.0_vp);
337     paddingProperty.top = CalcLength(paddingTop);
338     paddingProperty.bottom = CalcLength(paddingBottom);
339 
340     contentLayoutProperty->UpdateSafeAreaPadding(paddingProperty);
341 }
342 
UpdateConstraintWhenFixOrWrap(const RefPtr<LayoutProperty> & layoutProperty,LayoutConstraintF & constraint,SizeF size)343 void NavigationLayoutUtil::UpdateConstraintWhenFixOrWrap(
344     const RefPtr<LayoutProperty>& layoutProperty, LayoutConstraintF& constraint, SizeF size)
345 {
346     auto layoutPolicy = layoutProperty->GetLayoutPolicyProperty();
347     bool isWidthWrapOrFix =
348         layoutPolicy.has_value() ? layoutPolicy->IsWidthWrap() || layoutPolicy->IsWidthFix() : false;
349     bool isHeightWrapOrFix =
350         layoutPolicy.has_value() ? layoutPolicy->IsHeightWrap() || layoutPolicy->IsHeightFix() : false;
351     constraint.selfIdealSize = OptionalSizeF();
352     bool isAutoHeight = NavigationLayoutAlgorithm::IsAutoHeight(layoutProperty);
353     if (!isWidthWrapOrFix) {
354         constraint.selfIdealSize.SetWidth(size.Width());
355     }
356 
357     if (!isHeightWrapOrFix && !isAutoHeight) {
358         constraint.selfIdealSize.SetHeight(size.Height());
359     }
360 }
CheckVerticalExtend(const RefPtr<NavDestinationLayoutPropertyBase> & layoutProperty,const RefPtr<NavDestinationNodeBase> & hostNode,const NG::IgnoreLayoutSafeAreaOpts & opts)361 std::pair<bool, bool> NavigationLayoutUtil::CheckVerticalExtend(
362     const RefPtr<NavDestinationLayoutPropertyBase>& layoutProperty, const RefPtr<NavDestinationNodeBase>& hostNode,
363     const NG::IgnoreLayoutSafeAreaOpts& opts)
364 {
365     auto defaultValue = std::make_pair(false, false);
366     if (!layoutProperty || !hostNode) {
367         return defaultValue;
368     }
369     const auto& padding = layoutProperty->CreatePaddingAndBorder();
370     float topPadding = padding.top.value_or(0.0f);
371     if (!NearEqual(topPadding, 0.0f)) {
372         return defaultValue;
373     }
374 
375     bool isCanTopExtend = true;
376     isCanTopExtend &= ((opts.edges & LAYOUT_SAFE_AREA_EDGE_TOP) && (opts.type & LAYOUT_SAFE_AREA_TYPE_SYSTEM));
377     auto navBasePattern = hostNode->GetPattern<NavDestinationPatternBase>();
378     CHECK_NULL_RETURN(navBasePattern, defaultValue);
379     auto barStyle = navBasePattern->GetTitleBarStyle().value_or(BarStyle::STANDARD);
380     if (!(layoutProperty->GetHideTitleBar().value_or(false) || barStyle == BarStyle::STACK ||
381             (barStyle == BarStyle::SAFE_AREA_PADDING && !NearZero(navBasePattern->GetTitleBarOffsetY())))) {
382         isCanTopExtend = false;
383     }
384 
385     bool isCanBottomExtend = true;
386     isCanBottomExtend &= ((opts.edges & LAYOUT_SAFE_AREA_EDGE_BOTTOM) && (opts.type & LAYOUT_SAFE_AREA_TYPE_SYSTEM));
387     auto toolBarStyle = navBasePattern->GetToolBarStyle().value_or(BarStyle::STANDARD);
388     if (hostNode->IsToolBarVisible() && toolBarStyle != BarStyle::STACK) {
389         isCanBottomExtend = false;
390     }
391     return std::make_pair(isCanTopExtend, isCanBottomExtend);
392 }
393 } // namespace OHOS::Ace::NG
394