1 /*
2 * Copyright (c) 2022-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/navrouter/navdestination_pattern.h"
17
18 #include <atomic>
19
20 #include "base/log/dump_log.h"
21 #include "core/common/agingadapation/aging_adapation_dialog_theme.h"
22 #include "core/common/agingadapation/aging_adapation_dialog_util.h"
23 #include "core/common/container.h"
24 #include "core/components/theme/app_theme.h"
25 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
26 #include "core/components_ng/pattern/navigation/title_bar_layout_property.h"
27 #include "core/components_ng/pattern/navigation/title_bar_node.h"
28 #include "core/components_ng/pattern/navigation/navigation_title_util.h"
29 #include "core/components_ng/pattern/navigation/navigation_toolbar_util.h"
30 #include "core/components_ng/pattern/navigation/title_bar_pattern.h"
31 #include "core/components_ng/pattern/text/text_layout_property.h"
32
33 namespace OHOS::Ace::NG {
34 namespace {
35 std::atomic<uint64_t> g_navDestinationPatternNextAutoGenId = 0;
36 // titlebar ZINDEX
37 constexpr static int32_t DEFAULT_TITLEBAR_ZINDEX = 2;
38
BuildMenu(const RefPtr<NavDestinationGroupNode> & navDestinationGroupNode,const RefPtr<TitleBarNode> & titleBarNode)39 void BuildMenu(const RefPtr<NavDestinationGroupNode>& navDestinationGroupNode, const RefPtr<TitleBarNode>& titleBarNode)
40 {
41 if (navDestinationGroupNode->GetMenuNodeOperationValue(ChildNodeOperation::NONE) == ChildNodeOperation::REPLACE) {
42 titleBarNode->RemoveChild(titleBarNode->GetMenu());
43 titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
44 }
45 if (navDestinationGroupNode->GetPrevMenuIsCustomValue(false)) {
46 if (navDestinationGroupNode->GetMenuNodeOperationValue(ChildNodeOperation::NONE) == ChildNodeOperation::NONE) {
47 return;
48 }
49 titleBarNode->SetMenu(navDestinationGroupNode->GetMenu());
50 titleBarNode->AddChild(titleBarNode->GetMenu());
51 titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
52 navDestinationGroupNode->UpdateMenuNodeOperation(ChildNodeOperation::NONE);
53 } else {
54 navDestinationGroupNode->UpdateMenuNodeOperation(ChildNodeOperation::NONE);
55 auto navDestinationPattern = navDestinationGroupNode->GetPattern<NavDestinationPattern>();
56 CHECK_NULL_VOID(navDestinationPattern);
57 auto titleBarMenuItems = navDestinationPattern->GetTitleBarMenuItems();
58 auto toolBarMenuItems = navDestinationPattern->GetToolBarMenuItems();
59
60 bool isButtonEnabled = false;
61 auto hub = navDestinationGroupNode->GetEventHub<EventHub>();
62 if (hub) {
63 isButtonEnabled = hub->IsEnabled();
64 }
65 if (navDestinationPattern->HasMenuNodeId()) {
66 auto menuNode = NavigationTitleUtil::CreateMenuItems(navDestinationPattern->GetMenuNodeId(),
67 titleBarMenuItems, navDestinationGroupNode, isButtonEnabled, DES_FIELD,
68 titleBarNode->GetInnerParentId(), false);
69 CHECK_NULL_VOID(menuNode);
70 navDestinationGroupNode->SetMenu(menuNode);
71 }
72
73 titleBarMenuItems.insert(titleBarMenuItems.end(), toolBarMenuItems.begin(), toolBarMenuItems.end());
74 auto landscapeMenuNode = NavigationTitleUtil::CreateMenuItems(navDestinationPattern->GetLandscapeMenuNodeId(),
75 titleBarMenuItems, navDestinationGroupNode, isButtonEnabled, DES_FIELD, titleBarNode->GetInnerParentId(),
76 true);
77 CHECK_NULL_VOID(landscapeMenuNode);
78 navDestinationGroupNode->SetLandscapeMenu(landscapeMenuNode);
79 }
80 }
81 }
82
NavDestinationPattern(const RefPtr<ShallowBuilder> & shallowBuilder)83 NavDestinationPattern::NavDestinationPattern(const RefPtr<ShallowBuilder>& shallowBuilder)
84 : shallowBuilder_(shallowBuilder)
85 {
86 navDestinationId_ = g_navDestinationPatternNextAutoGenId.fetch_add(1);
87 }
88
NavDestinationPattern()89 NavDestinationPattern::NavDestinationPattern()
90 {
91 navDestinationId_ = g_navDestinationPatternNextAutoGenId.fetch_add(1);
92 }
93
~NavDestinationPattern()94 NavDestinationPattern::~NavDestinationPattern()
95 {
96 customNode_ = nullptr;
97 }
98
OnActive()99 void NavDestinationPattern::OnActive()
100 {
101 Pattern::OnActive();
102 auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
103 CHECK_NULL_VOID(hostNode);
104 auto navDestinationContext = hostNode->GetRenderContext();
105 CHECK_NULL_VOID(navDestinationContext);
106 auto navDestinationLayoutProperty = hostNode->GetLayoutProperty<NavDestinationLayoutProperty>();
107 CHECK_NULL_VOID(navDestinationLayoutProperty);
108 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
109 CHECK_NULL_VOID(titleBarNode);
110 auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
111 CHECK_NULL_VOID(titleBarLayoutProperty);
112 if (navDestinationLayoutProperty->GetHideTitleBar().value_or(false)) {
113 titleBarLayoutProperty->UpdateVisibility(VisibleType::GONE);
114 } else {
115 titleBarLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
116 }
117 titleBarNode->MarkModifyDone();
118 }
119
OnModifyDone()120 void NavDestinationPattern::OnModifyDone()
121 {
122 Pattern::OnModifyDone();
123 auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
124 CHECK_NULL_VOID(hostNode);
125 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
126 CHECK_NULL_VOID(titleBarNode);
127 auto titleBarRenderContext = titleBarNode->GetRenderContext();
128 CHECK_NULL_VOID(titleBarRenderContext);
129 titleBarNode->SetInnerParentId(hostNode->GetInspectorId().value_or(""));
130 // set the titlebar to float on the top
131 titleBarRenderContext->UpdateZIndex(DEFAULT_TITLEBAR_ZINDEX);
132 auto navDestinationLayoutProperty = hostNode->GetLayoutProperty<NavDestinationLayoutProperty>();
133 CHECK_NULL_VOID(navDestinationLayoutProperty);
134 isHideToolbar_ = navDestinationLayoutProperty->GetHideToolBarValue(false);
135 isHideTitlebar_ = navDestinationLayoutProperty->GetHideTitleBar().value_or(false);
136 auto&& opts = hostNode->GetLayoutProperty()->GetSafeAreaExpandOpts();
137 auto navDestinationContentNode = AceType::DynamicCast<FrameNode>(hostNode->GetContentNode());
138 if (opts && navDestinationContentNode) {
139 TAG_LOGI(AceLogTag::ACE_NAVIGATION, "Navdestination SafArea expand as %{public}s", opts->ToString().c_str());
140 navDestinationContentNode->GetLayoutProperty()->UpdateSafeAreaExpandOpts(*opts);
141 navDestinationContentNode->MarkModifyDone();
142 }
143
144 UpdateNameIfNeeded(hostNode);
145 UpdateBackgroundColorIfNeeded(hostNode);
146 bool needRunTitleBarAnimation = false;
147 MountTitleBar(hostNode, needRunTitleBarAnimation);
148 bool needRunToolBarAnimation = false;
149 NavigationToolbarUtil::MountToolBar(hostNode, needRunToolBarAnimation);
150 HandleTitleBarAndToolBarAnimation(hostNode, needRunTitleBarAnimation, needRunToolBarAnimation);
151 auto pipeline = hostNode->GetContext();
152 CHECK_NULL_VOID(pipeline);
153 if (GreatOrEqual(pipeline->GetFontScale(), AgingAdapationDialogUtil::GetDialogBigFontSizeScale())) {
154 auto titleBarPattern = titleBarNode->GetPattern<TitleBarPattern>();
155 CHECK_NULL_VOID(titleBarPattern);
156 auto backButtonNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetBackButton());
157 CHECK_NULL_VOID(backButtonNode);
158 titleBarPattern->InitBackButtonLongPressEvent(backButtonNode);
159 }
160 }
161
OnLanguageConfigurationUpdate()162 void NavDestinationPattern::OnLanguageConfigurationUpdate()
163 {
164 if (isRightToLeft_ == AceApplicationInfo::GetInstance().IsRightToLeft()) {
165 return;
166 }
167 isRightToLeft_ = AceApplicationInfo::GetInstance().IsRightToLeft();
168 auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
169 CHECK_NULL_VOID(hostNode);
170 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
171 CHECK_NULL_VOID(titleBarNode);
172 titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
173 }
174
UpdateNameIfNeeded(RefPtr<NavDestinationGroupNode> & hostNode)175 void NavDestinationPattern::UpdateNameIfNeeded(RefPtr<NavDestinationGroupNode>& hostNode)
176 {
177 if (!name_.empty()) {
178 return;
179 }
180
181 if (hostNode->GetInspectorId().has_value()) {
182 name_ = hostNode->GetInspectorIdValue();
183 } else {
184 name_ = std::to_string(GetHost()->GetId());
185 }
186 auto pathInfo = GetNavPathInfo();
187 if (pathInfo) {
188 pathInfo->SetName(name_);
189 }
190 }
191
UpdateBackgroundColorIfNeeded(RefPtr<NavDestinationGroupNode> & hostNode)192 void NavDestinationPattern::UpdateBackgroundColorIfNeeded(RefPtr<NavDestinationGroupNode>& hostNode)
193 {
194 auto renderContext = hostNode->GetRenderContext();
195 CHECK_NULL_VOID(renderContext);
196 if (IsUserDefinedBgColor()) {
197 TAG_LOGI(AceLogTag::ACE_NAVIGATION, "User defined Background color: %{public}s",
198 renderContext->GetBackgroundColor()->ColorToString().c_str());
199 return;
200 }
201 if (hostNode->GetNavDestinationMode() == NavDestinationMode::DIALOG) {
202 renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
203 TAG_LOGI(AceLogTag::ACE_NAVIGATION, "Set dialog background color: %{public}s",
204 renderContext->GetBackgroundColor()->ColorToString().c_str());
205 return;
206 }
207 auto pipelineContext = PipelineContext::GetCurrentContext();
208 if (!pipelineContext) {
209 return;
210 }
211 auto theme = pipelineContext->GetTheme<AppTheme>();
212 if (!theme) {
213 return;
214 }
215 renderContext->UpdateBackgroundColor(theme->GetBackgroundColor());
216 TAG_LOGI(AceLogTag::ACE_NAVIGATION, "Default background color: %{public}s",
217 renderContext->GetBackgroundColor()->ColorToString().c_str());
218 }
219
MountTitleBar(RefPtr<NavDestinationGroupNode> & hostNode,bool & needRunTitleBarAnimation)220 void NavDestinationPattern::MountTitleBar(
221 RefPtr<NavDestinationGroupNode>& hostNode, bool& needRunTitleBarAnimation)
222 {
223 needRunTitleBarAnimation = false;
224 auto navDestinationLayoutProperty = hostNode->GetLayoutProperty<NavDestinationLayoutProperty>();
225 CHECK_NULL_VOID(navDestinationLayoutProperty);
226 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
227 CHECK_NULL_VOID(titleBarNode);
228 auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
229 CHECK_NULL_VOID(titleBarLayoutProperty);
230
231 if (navDestinationLayoutProperty->HasNoPixMap()) {
232 if (navDestinationLayoutProperty->HasImageSource()) {
233 titleBarLayoutProperty->UpdateImageSource(navDestinationLayoutProperty->GetImageSourceValue());
234 }
235 if (navDestinationLayoutProperty->HasPixelMap()) {
236 titleBarLayoutProperty->UpdatePixelMap(navDestinationLayoutProperty->GetPixelMapValue());
237 }
238 titleBarLayoutProperty->UpdateNoPixMap(navDestinationLayoutProperty->GetNoPixMapValue());
239 }
240 bool hideTitleBar = navDestinationLayoutProperty->GetHideTitleBarValue(false);
241 BuildMenu(hostNode, titleBarNode);
242
243 auto navDesIndex = hostNode->GetIndex();
244 if (navDesIndex == 0) {
245 navDestinationLayoutProperty->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
246 titleBarLayoutProperty->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
247 }
248
249 // At the initial state, animation is not required.
250 if (!currHideTitleBar_.has_value() || !navDestinationLayoutProperty->GetIsAnimatedTitleBarValue(false)) {
251 currHideTitleBar_ = hideTitleBar;
252 HideOrShowTitleBarImmediately(hostNode, hideTitleBar);
253 return;
254 }
255
256 titleBarNode->MarkModifyDone();
257 titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
258
259 // Animation is needed only when the status changed.
260 needRunTitleBarAnimation = currHideTitleBar_.value() != hideTitleBar;
261 currHideTitleBar_ = hideTitleBar;
262 }
263
GetBackButtonState()264 bool NavDestinationPattern::GetBackButtonState()
265 {
266 auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
267 CHECK_NULL_RETURN(hostNode, false);
268 auto navDestinationLayoutProperty = hostNode->GetLayoutProperty<NavDestinationLayoutProperty>();
269 CHECK_NULL_RETURN(navDestinationLayoutProperty, false);
270
271 auto translateState = navDestinationLayoutProperty->GetTitleBarTranslateStateValue(BarTranslateState::NONE);
272 if (navDestinationLayoutProperty->GetHideTitleBarValue(false) && translateState == BarTranslateState::NONE) {
273 return false;
274 }
275 // get navigation node
276 auto parent = AceType::DynamicCast<FrameNode>(hostNode->GetParent());
277 RefPtr<NavigationGroupNode> navigationNode;
278 while (parent && !parent->IsRootNode()) {
279 navigationNode = AceType::DynamicCast<NavigationGroupNode>(parent);
280 if (navigationNode) {
281 break;
282 }
283 parent = AceType::DynamicCast<FrameNode>(parent->GetParent());
284 }
285 if (!navigationNode) {
286 TAG_LOGW(AceLogTag::ACE_NAVIGATION, "can't find navigation node");
287 return false;
288 }
289 auto navigationLayoutProperty = navigationNode->GetLayoutProperty<NavigationLayoutProperty>();
290 CHECK_NULL_RETURN(navigationLayoutProperty, false);
291 auto pattern = navigationNode->GetPattern<NavigationPattern>();
292 auto stack = pattern->GetNavigationStack();
293 auto index = stack->FindIndex(name_, customNode_, true);
294 bool showBackButton = true;
295 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
296 if (index == 0 && (pattern->GetNavigationMode() == NavigationMode::SPLIT ||
297 navigationLayoutProperty->GetHideNavBarValue(false))) {
298 showBackButton = false;
299 }
300 auto isCustomTitle = hostNode->GetPrevTitleIsCustomValue(false);
301 if (isCustomTitle) {
302 return showBackButton;
303 }
304 auto titleBarPattern = titleBarNode->GetPattern<TitleBarPattern>();
305 CHECK_NULL_RETURN(titleBarPattern, showBackButton);
306 if (titleBarPattern->IsFontSizeSettedByDeveloper()) {
307 return showBackButton;
308 }
309 auto titleNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetTitle());
310 CHECK_NULL_RETURN(titleNode, showBackButton);
311 auto theme = NavigationGetTheme();
312 CHECK_NULL_RETURN(theme, showBackButton);
313 auto textLayoutProperty = titleNode->GetLayoutProperty<TextLayoutProperty>();
314 auto currentFontSize = textLayoutProperty->GetAdaptMaxFontSizeValue(Dimension(0.0, DimensionUnit::FP));
315 auto targetFontSize = showBackButton ? theme->GetTitleFontSizeMin() : theme->GetTitleFontSize();
316 if (targetFontSize == currentFontSize) {
317 return showBackButton;
318 }
319 textLayoutProperty->UpdateAdaptMaxFontSize(targetFontSize);
320 textLayoutProperty->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
321 return showBackButton;
322 }
323
OnAttachToFrameNode()324 void NavDestinationPattern::OnAttachToFrameNode()
325 {
326 auto host = GetHost();
327 CHECK_NULL_VOID(host);
328 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
329 SafeAreaExpandOpts opts = { .type = SAFE_AREA_TYPE_SYSTEM | SAFE_AREA_TYPE_CUTOUT,
330 .edges = SAFE_AREA_EDGE_ALL };
331 host->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
332 }
333 isRightToLeft_ = AceApplicationInfo::GetInstance().IsRightToLeft();
334 auto id = host->GetId();
335 auto pipeline = host->GetContext();
336 CHECK_NULL_VOID(pipeline);
337 pipeline->AddWindowStateChangedCallback(id);
338 pipeline->AddWindowSizeChangeCallback(id);
339 }
340
OnDetachFromFrameNode(FrameNode * frameNode)341 void NavDestinationPattern::OnDetachFromFrameNode(FrameNode* frameNode)
342 {
343 CHECK_NULL_VOID(frameNode);
344 auto id = frameNode->GetId();
345 auto pipeline = frameNode->GetContext();
346 CHECK_NULL_VOID(pipeline);
347 pipeline->RemoveWindowStateChangedCallback(id);
348 pipeline->RemoveWindowSizeChangeCallback(id);
349 }
350
DumpInfo()351 void NavDestinationPattern::DumpInfo()
352 {
353 DumpLog::GetInstance().AddDesc(std::string("name: ").append(name_));
354 }
355
OverlayOnBackPressed()356 bool NavDestinationPattern::OverlayOnBackPressed()
357 {
358 CHECK_NULL_RETURN(overlayManager_, false);
359 CHECK_EQUAL_RETURN(overlayManager_->IsModalEmpty(), true, false);
360 return overlayManager_->RemoveOverlay(true);
361 }
362
NeedIgnoreKeyboard()363 bool NavDestinationPattern::NeedIgnoreKeyboard()
364 {
365 auto layoutProperty = GetLayoutProperty<NavDestinationLayoutProperty>();
366 CHECK_NULL_RETURN(layoutProperty, false);
367 auto& opts = layoutProperty->GetSafeAreaExpandOpts();
368 if (opts && (opts->type & SAFE_AREA_TYPE_KEYBOARD) && (opts->edges & SAFE_AREA_EDGE_BOTTOM)) {
369 return true;
370 }
371 return false;
372 }
373
OnFontScaleConfigurationUpdate()374 void NavDestinationPattern::OnFontScaleConfigurationUpdate()
375 {
376 auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
377 CHECK_NULL_VOID(hostNode);
378 auto pipeline = hostNode->GetContext();
379 CHECK_NULL_VOID(pipeline);
380 auto titleBarUINode = hostNode->GetTitleBarNode();
381 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(titleBarUINode);
382 CHECK_NULL_VOID(titleBarNode);
383 auto backButtonNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetBackButton());
384 CHECK_NULL_VOID(backButtonNode);
385 if (LessNotEqual(pipeline->GetFontScale(), AgingAdapationDialogUtil::GetDialogBigFontSizeScale())) {
386 auto gestureHub = backButtonNode->GetOrCreateGestureEventHub();
387 CHECK_NULL_VOID(gestureHub);
388 gestureHub->SetLongPressEvent(nullptr);
389 auto longPressRecognizer = gestureHub->GetLongPressRecognizer();
390 CHECK_NULL_VOID(longPressRecognizer);
391 longPressRecognizer->SetOnActionEnd(nullptr);
392 return;
393 }
394 auto titleBarPattern = titleBarNode->GetPattern<TitleBarPattern>();
395 CHECK_NULL_VOID(titleBarPattern);
396 titleBarPattern->InitBackButtonLongPressEvent(backButtonNode);
397 }
398
SetSystemBarStyle(const RefPtr<SystemBarStyle> & style)399 void NavDestinationPattern::SetSystemBarStyle(const RefPtr<SystemBarStyle>& style)
400 {
401 auto host = GetHost();
402 CHECK_NULL_VOID(host);
403 auto pipeline = host->GetContext();
404 CHECK_NULL_VOID(pipeline);
405 auto windowManager = pipeline->GetWindowManager();
406 CHECK_NULL_VOID(windowManager);
407 if (!backupStyle_.has_value()) {
408 backupStyle_ = windowManager->GetSystemBarStyle();
409 }
410 currStyle_ = style;
411 auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(navigationNode_.Upgrade());
412 CHECK_NULL_VOID(navigationNode);
413 auto navigationPattern = navigationNode->GetPattern<NavigationPattern>();
414 if (navigationPattern->IsFullPageNavigation() && navigationPattern->IsTopNavDestination(host)) {
415 if (currStyle_.value() != nullptr) {
416 windowManager->SetSystemBarStyle(currStyle_.value());
417 } else {
418 navigationPattern->TryRestoreSystemBarStyle(windowManager);
419 }
420 }
421 }
422
GetTitlebarZIndex() const423 int32_t NavDestinationPattern::GetTitlebarZIndex() const
424 {
425 return DEFAULT_TITLEBAR_ZINDEX;
426 }
427
OnWindowHide()428 void NavDestinationPattern::OnWindowHide()
429 {
430 CHECK_NULL_VOID(navDestinationContext_);
431 auto navPathInfo = navDestinationContext_->GetNavPathInfo();
432 CHECK_NULL_VOID(navPathInfo);
433 if (!navPathInfo->GetIsEntry()) {
434 return;
435 }
436 TAG_LOGI(AceLogTag::ACE_NAVIGATION, "window lifecycle change to hide, clear navDestination entry tag");
437 navPathInfo->SetIsEntry(false);
438 auto stack = GetNavigationStack().Upgrade();
439 CHECK_NULL_VOID(stack);
440 auto index = navDestinationContext_->GetIndex();
441 stack->SetIsEntryByIndex(index, false);
442 }
443
OnWindowSizeChanged(int32_t width,int32_t height,WindowSizeChangeReason type)444 void NavDestinationPattern::OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type)
445 {
446 auto navDestinationGroupNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
447 CHECK_NULL_VOID(navDestinationGroupNode);
448 if (preWidth_.has_value() && preWidth_.value() != width) {
449 AbortBarAnimation();
450 }
451 preWidth_ = width;
452 // change menu num in landscape and orientation
453 do {
454 if (navDestinationGroupNode->GetPrevMenuIsCustomValue(false)) {
455 break;
456 }
457 auto targetNum = SystemProperties::GetDeviceOrientation() == DeviceOrientation::LANDSCAPE ? MAX_MENU_NUM_LARGE
458 : MAX_MENU_NUM_SMALL;
459 if (targetNum == maxMenuNums_) {
460 break;
461 }
462 maxMenuNums_ = targetNum;
463 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navDestinationGroupNode->GetTitleBarNode());
464 CHECK_NULL_VOID(titleBarNode);
465 BuildMenu(navDestinationGroupNode, titleBarNode);
466 titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
467 } while (0);
468 }
469 } // namespace OHOS::Ace::NG
470