• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "base/log/dump_log.h"
19 #include "core/common/agingadapation/aging_adapation_dialog_theme.h"
20 #include "core/common/agingadapation/aging_adapation_dialog_util.h"
21 #include "core/components/theme/app_theme.h"
22 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
23 #include "core/components_ng/pattern/navigation/navigation_title_util.h"
24 #include "core/components_ng/pattern/navigation/navigation_toolbar_util.h"
25 #include "core/components_ng/pattern/navigation/title_bar_pattern.h"
26 
27 namespace OHOS::Ace::NG {
28 namespace {
29 std::atomic<uint64_t> g_navDestinationPatternNextAutoGenId = 0;
30 // titlebar ZINDEX
31 constexpr static int32_t DEFAULT_TITLEBAR_ZINDEX = 2;
32 constexpr float TRANSLATE_THRESHOLD = 26.0f;
33 const auto TRANSLATE_CURVE = AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 228.0f, 30.0f);
34 
BuildMenu(const RefPtr<NavDestinationGroupNode> & navDestinationGroupNode,const RefPtr<TitleBarNode> & titleBarNode)35 void BuildMenu(const RefPtr<NavDestinationGroupNode>& navDestinationGroupNode, const RefPtr<TitleBarNode>& titleBarNode)
36 {
37     if (navDestinationGroupNode->GetMenuNodeOperationValue(ChildNodeOperation::NONE) == ChildNodeOperation::REPLACE) {
38         titleBarNode->RemoveChild(titleBarNode->GetMenu());
39         titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
40     }
41     if (navDestinationGroupNode->GetPrevMenuIsCustomValue(false)) {
42         if (navDestinationGroupNode->GetMenuNodeOperationValue(ChildNodeOperation::NONE) == ChildNodeOperation::NONE) {
43             return;
44         }
45         titleBarNode->SetMenu(navDestinationGroupNode->GetMenu());
46         titleBarNode->AddChild(titleBarNode->GetMenu());
47         titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
48         navDestinationGroupNode->UpdateMenuNodeOperation(ChildNodeOperation::NONE);
49     } else {
50         navDestinationGroupNode->UpdateMenuNodeOperation(ChildNodeOperation::NONE);
51         auto navDestinationPattern = navDestinationGroupNode->GetPattern<NavDestinationPattern>();
52         CHECK_NULL_VOID(navDestinationPattern);
53         auto titleBarMenuItems = navDestinationPattern->GetTitleBarMenuItems();
54         auto toolBarMenuItems = navDestinationPattern->GetToolBarMenuItems();
55 
56         bool isButtonEnabled = false;
57         auto hub = navDestinationGroupNode->GetOrCreateEventHub<EventHub>();
58         if (hub) {
59             isButtonEnabled = hub->IsEnabled();
60         }
61         if (navDestinationPattern->HasMenuNodeId()) {
62             auto menuNode = NavigationTitleUtil::CreateMenuItems(navDestinationPattern->GetMenuNodeId(),
63                 titleBarMenuItems, navDestinationGroupNode, isButtonEnabled, DES_FIELD,
64                 titleBarNode->GetInnerParentId(), false);
65             CHECK_NULL_VOID(menuNode);
66             navDestinationGroupNode->SetMenu(menuNode);
67         }
68 
69         titleBarMenuItems.insert(titleBarMenuItems.end(), toolBarMenuItems.begin(), toolBarMenuItems.end());
70         auto landscapeMenuNode = NavigationTitleUtil::CreateMenuItems(navDestinationPattern->GetLandscapeMenuNodeId(),
71             titleBarMenuItems, navDestinationGroupNode, isButtonEnabled, DES_FIELD, titleBarNode->GetInnerParentId(),
72             true);
73         CHECK_NULL_VOID(landscapeMenuNode);
74         navDestinationGroupNode->SetLandscapeMenu(landscapeMenuNode);
75     }
76 }
77 
GetTitleOrToolBarTranslateAndHeight(const RefPtr<FrameNode> & barNode,float & translate,float & height)78 bool GetTitleOrToolBarTranslateAndHeight(const RefPtr<FrameNode>& barNode, float& translate, float& height)
79 {
80     CHECK_NULL_RETURN(barNode, false);
81     auto renderContext = barNode->GetRenderContext();
82     CHECK_NULL_RETURN(renderContext, false);
83     auto options = renderContext->GetTransformTranslateValue(TranslateOptions(0.0f, 0.0f, 0.0f));
84     translate = options.y.ConvertToPx();
85     height = renderContext->GetPaintRectWithoutTransform().Height();
86     return true;
87 }
88 }
89 
NavDestinationPattern(const RefPtr<ShallowBuilder> & shallowBuilder)90 NavDestinationPattern::NavDestinationPattern(const RefPtr<ShallowBuilder>& shallowBuilder)
91     : shallowBuilder_(shallowBuilder)
92 {
93     navDestinationId_ = g_navDestinationPatternNextAutoGenId.fetch_add(1);
94 }
95 
NavDestinationPattern()96 NavDestinationPattern::NavDestinationPattern()
97 {
98     navDestinationId_ = g_navDestinationPatternNextAutoGenId.fetch_add(1);
99 }
100 
~NavDestinationPattern()101 NavDestinationPattern::~NavDestinationPattern()
102 {
103     customNode_ = nullptr;
104     if (scrollableProcessor_) {
105         scrollableProcessor_->UnbindAllScrollers();
106     }
107 }
108 
OnActive()109 void NavDestinationPattern::OnActive()
110 {
111     Pattern::OnActive();
112     auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
113     CHECK_NULL_VOID(hostNode);
114     auto navDestinationContext = hostNode->GetRenderContext();
115     CHECK_NULL_VOID(navDestinationContext);
116     auto navDestinationLayoutProperty = hostNode->GetLayoutProperty<NavDestinationLayoutProperty>();
117     CHECK_NULL_VOID(navDestinationLayoutProperty);
118     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
119     CHECK_NULL_VOID(titleBarNode);
120     auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
121     CHECK_NULL_VOID(titleBarLayoutProperty);
122     if (navDestinationLayoutProperty->GetHideTitleBar().value_or(false)) {
123         titleBarLayoutProperty->UpdateVisibility(VisibleType::GONE);
124     } else {
125         titleBarLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
126     }
127     titleBarNode->MarkModifyDone();
128 }
129 
OnModifyDone()130 void NavDestinationPattern::OnModifyDone()
131 {
132     Pattern::OnModifyDone();
133     auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
134     CHECK_NULL_VOID(hostNode);
135     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
136     CHECK_NULL_VOID(titleBarNode);
137     auto titleBarRenderContext = titleBarNode->GetRenderContext();
138     CHECK_NULL_VOID(titleBarRenderContext);
139     titleBarNode->SetInnerParentId(hostNode->GetInspectorId().value_or(""));
140     // set the titlebar to float on the top
141     titleBarRenderContext->UpdateZIndex(DEFAULT_TITLEBAR_ZINDEX);
142     auto navDestinationLayoutProperty = hostNode->GetLayoutProperty<NavDestinationLayoutProperty>();
143     CHECK_NULL_VOID(navDestinationLayoutProperty);
144     auto contentNode = AceType::DynamicCast<FrameNode>(hostNode->GetContentNode());
145     auto layoutPolicy = navDestinationLayoutProperty->GetLayoutPolicyProperty();
146     if (layoutPolicy.has_value()) {
147         contentNode->GetLayoutProperty()->UpdateLayoutPolicyProperty(
148             layoutPolicy.value().widthLayoutPolicy_.value_or(LayoutCalPolicy::NO_MATCH), true);
149         contentNode->GetLayoutProperty()->UpdateLayoutPolicyProperty(
150             layoutPolicy.value().heightLayoutPolicy_.value_or(LayoutCalPolicy::NO_MATCH), false);
151     }
152 
153     UpdateHideBarProperty();
154     ExpandContentSafeAreaIfNeeded();
155     UpdateNameIfNeeded(hostNode);
156     UpdateBackgroundColorIfNeeded(hostNode);
157     bool needRunTitleBarAnimation = false;
158     MountTitleBar(hostNode, needRunTitleBarAnimation);
159     bool needRunToolBarAnimation = false;
160     NavigationToolbarUtil::MountToolBar(hostNode, needRunToolBarAnimation);
161     HandleTitleBarAndToolBarAnimation(hostNode, needRunTitleBarAnimation, needRunToolBarAnimation);
162     auto pipeline = hostNode->GetContext();
163     CHECK_NULL_VOID(pipeline);
164     if (GreatOrEqual(pipeline->GetFontScale(), AgingAdapationDialogUtil::GetDialogBigFontSizeScale())) {
165         auto titleBarPattern = titleBarNode->GetPattern<TitleBarPattern>();
166         CHECK_NULL_VOID(titleBarPattern);
167         auto backButtonNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetBackButton());
168         CHECK_NULL_VOID(backButtonNode);
169         titleBarPattern->InitBackButtonLongPressEvent(backButtonNode);
170     }
171     if (scrollableProcessor_) {
172         scrollableProcessor_->UpdateBindingRelation();
173     }
174     auto renderContext = hostNode->GetRenderContext();
175     CHECK_NULL_VOID(renderContext);
176     hostNode->UpdateUserSetOpacity(renderContext->GetOpacity().value_or(1.0f));
177 
178     CheckIfOrientationChanged();
179     CheckIfStatusBarConfigChanged();
180     CheckIfNavigationIndicatorConfigChagned();
181 }
182 
OnLanguageConfigurationUpdate()183 void NavDestinationPattern::OnLanguageConfigurationUpdate()
184 {
185     if (isRightToLeft_ == AceApplicationInfo::GetInstance().IsRightToLeft()) {
186         return;
187     }
188     isRightToLeft_ = AceApplicationInfo::GetInstance().IsRightToLeft();
189     auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
190     CHECK_NULL_VOID(hostNode);
191     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
192     CHECK_NULL_VOID(titleBarNode);
193     titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
194     auto backButtonUINode = titleBarNode->GetBackButton();
195     auto backButtonNode = AceType::DynamicCast<FrameNode>(backButtonUINode);
196     CHECK_NULL_VOID(backButtonNode);
197     auto imageNode = backButtonNode->GetFirstChild();
198     CHECK_NULL_VOID(imageNode);
199     imageNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
200 }
201 
UpdateNameIfNeeded(RefPtr<NavDestinationGroupNode> & hostNode)202 void NavDestinationPattern::UpdateNameIfNeeded(RefPtr<NavDestinationGroupNode>& hostNode)
203 {
204     if (!name_.empty()) {
205         return;
206     }
207     CHECK_NULL_VOID(hostNode);
208     if (hostNode->GetInspectorId().has_value()) {
209         name_ = hostNode->GetInspectorIdValue();
210     } else {
211         name_ = std::to_string(hostNode->GetId());
212     }
213     auto pathInfo = GetNavPathInfo();
214     if (pathInfo) {
215         pathInfo->SetName(name_);
216     }
217 }
218 
UpdateBackgroundColor()219 void NavDestinationPattern::UpdateBackgroundColor()
220 {
221     auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
222     CHECK_NULL_VOID(hostNode);
223     if (hostNode->GetRerenderable()) {
224         ContainerScope scope(hostNode->GetInstanceId());
225         UpdateBackgroundColorIfNeeded(hostNode);
226     }
227 }
228 
UpdateBackgroundColorIfNeeded(RefPtr<NavDestinationGroupNode> & hostNode)229 void NavDestinationPattern::UpdateBackgroundColorIfNeeded(RefPtr<NavDestinationGroupNode>& hostNode)
230 {
231     auto renderContext = hostNode->GetRenderContext();
232     CHECK_NULL_VOID(renderContext);
233     if (IsUserDefinedBgColor()) {
234         TAG_LOGI(AceLogTag::ACE_NAVIGATION, "User defined Background color: %{public}s",
235             renderContext->GetBackgroundColor()->ColorToString().c_str());
236         return;
237     }
238     if (hostNode->GetNavDestinationMode() == NavDestinationMode::DIALOG) {
239         renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
240         return;
241     }
242     auto pipelineContext = PipelineContext::GetCurrentContext();
243     if (!pipelineContext) {
244         return;
245     }
246     auto theme = pipelineContext->GetTheme<AppTheme>();
247     if (!theme) {
248         return;
249     }
250     renderContext->UpdateBackgroundColor(theme->GetBackgroundColor());
251 }
252 
MountTitleBar(RefPtr<NavDestinationGroupNode> & hostNode,bool & needRunTitleBarAnimation)253 void NavDestinationPattern::MountTitleBar(
254     RefPtr<NavDestinationGroupNode>& hostNode, bool& needRunTitleBarAnimation)
255 {
256     needRunTitleBarAnimation = false;
257     auto navDestinationLayoutProperty = hostNode->GetLayoutProperty<NavDestinationLayoutProperty>();
258     CHECK_NULL_VOID(navDestinationLayoutProperty);
259     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
260     CHECK_NULL_VOID(titleBarNode);
261     auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
262     CHECK_NULL_VOID(titleBarLayoutProperty);
263 
264     auto backButtonNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetBackButton());
265     if (backButtonNode) {
266         auto backButtonLayoutProperty = backButtonNode->GetLayoutProperty();
267         CHECK_NULL_VOID(backButtonLayoutProperty);
268         backButtonLayoutProperty->UpdateVisibility(
269             navDestinationLayoutProperty->GetHideBackButtonValue(false) ? VisibleType::GONE : VisibleType::VISIBLE);
270     }
271     if (navDestinationLayoutProperty->HasNoPixMap()) {
272         if (navDestinationLayoutProperty->HasImageSource()) {
273             titleBarLayoutProperty->UpdateImageSource(navDestinationLayoutProperty->GetImageSourceValue());
274         }
275         if (navDestinationLayoutProperty->HasPixelMap()) {
276             titleBarLayoutProperty->UpdatePixelMap(navDestinationLayoutProperty->GetPixelMapValue());
277         }
278         titleBarLayoutProperty->UpdateNoPixMap(navDestinationLayoutProperty->GetNoPixMapValue());
279     }
280     bool hideTitleBar = navDestinationLayoutProperty->GetHideTitleBarValue(false);
281     BuildMenu(hostNode, titleBarNode);
282 
283     auto navDesIndex = hostNode->GetIndex();
284     if (navDesIndex == 0) {
285         navDestinationLayoutProperty->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
286         titleBarLayoutProperty->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
287     }
288 
289     if (currHideTitleBar_.has_value() && currHideTitleBar_.value() != hideTitleBar && hideTitleBar) {
290         /**
291          * we need reset translate&opacity of titleBar when state change from show to hide. @sa EnableTitleBarSwipe
292          */
293         NavigationTitleUtil::UpdateTitleOrToolBarTranslateYAndOpacity(hostNode, titleBarNode, 0.0f, true);
294     }
295     // At the initial state, animation is not required.
296     if (!currHideTitleBar_.has_value() || !navDestinationLayoutProperty->GetIsAnimatedTitleBarValue(false)) {
297         currHideTitleBar_ = hideTitleBar;
298         HideOrShowTitleBarImmediately(hostNode, hideTitleBar);
299         return;
300     }
301 
302     titleBarNode->MarkModifyDone();
303     titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
304 
305     // Animation is needed only when the status changed.
306     needRunTitleBarAnimation = currHideTitleBar_.value() != hideTitleBar;
307     currHideTitleBar_ = hideTitleBar;
308 }
309 
GetBackButtonState()310 bool NavDestinationPattern::GetBackButtonState()
311 {
312     auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
313     CHECK_NULL_RETURN(hostNode, false);
314     auto navDestinationLayoutProperty = hostNode->GetLayoutProperty<NavDestinationLayoutProperty>();
315     CHECK_NULL_RETURN(navDestinationLayoutProperty, false);
316 
317     auto translateState = navDestinationLayoutProperty->GetTitleBarTranslateStateValue(BarTranslateState::NONE);
318     if (navDestinationLayoutProperty->GetHideTitleBarValue(false) && translateState == BarTranslateState::NONE) {
319         return false;
320     }
321     // get navigation node
322     auto parent = AceType::DynamicCast<FrameNode>(hostNode->GetParent());
323     RefPtr<NavigationGroupNode> navigationNode;
324     while (parent && !parent->IsRootNode()) {
325         navigationNode = AceType::DynamicCast<NavigationGroupNode>(parent);
326         if (navigationNode) {
327             break;
328         }
329         parent = AceType::DynamicCast<FrameNode>(parent->GetParent());
330     }
331     if (!navigationNode) {
332         TAG_LOGW(AceLogTag::ACE_NAVIGATION, "can't find navigation node");
333         return false;
334     }
335     auto navigationLayoutProperty = navigationNode->GetLayoutProperty<NavigationLayoutProperty>();
336     CHECK_NULL_RETURN(navigationLayoutProperty, false);
337     auto pattern = navigationNode->GetPattern<NavigationPattern>();
338     auto stack = pattern->GetNavigationStack();
339     auto index = stack->FindIndex(name_, customNode_, true);
340     bool showBackButton = true;
341     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
342     CHECK_NULL_RETURN(titleBarNode, false);
343     if (navDestinationLayoutProperty->GetHideBackButtonValue(false)) {
344         showBackButton = false;
345     }
346     if (index == 0 && (pattern->GetNavigationMode() == NavigationMode::SPLIT ||
347         navigationLayoutProperty->GetHideNavBarValue(false))) {
348         showBackButton = false;
349     }
350     /**
351      * When using navBar as home in forceSplit scenario, the first NavDestination on
352      * the right side need to hide it's backButton.
353      */
354     if (pattern->IsForceSplitSuccess() && pattern->IsForceSplitUseNavBar() && index == 0) {
355         showBackButton = false;
356     }
357     auto isCustomTitle = hostNode->GetPrevTitleIsCustomValue(false);
358     if (isCustomTitle) {
359         return showBackButton;
360     }
361     auto titleBarPattern = titleBarNode->GetPattern<TitleBarPattern>();
362     CHECK_NULL_RETURN(titleBarPattern, showBackButton);
363     if (titleBarPattern->IsFontSizeSettedByDeveloper()) {
364         return showBackButton;
365     }
366     auto titleNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetTitle());
367     CHECK_NULL_RETURN(titleNode, showBackButton);
368     auto theme = NavigationGetTheme();
369     CHECK_NULL_RETURN(theme, showBackButton);
370     auto textLayoutProperty = titleNode->GetLayoutProperty<TextLayoutProperty>();
371     auto currentFontSize = textLayoutProperty->GetAdaptMaxFontSizeValue(Dimension(0.0, DimensionUnit::FP));
372     auto targetFontSize = showBackButton ? theme->GetTitleFontSizeMin() : theme->GetTitleFontSize();
373     if (targetFontSize == currentFontSize) {
374         return showBackButton;
375     }
376     textLayoutProperty->UpdateAdaptMaxFontSize(targetFontSize);
377     textLayoutProperty->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
378     return showBackButton;
379 }
380 
OnAttachToFrameNode()381 void NavDestinationPattern::OnAttachToFrameNode()
382 {
383     auto host = GetHost();
384     CHECK_NULL_VOID(host);
385     NavDestinationPatternBase::InitOnTouchEvent(host);
386     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
387         SafeAreaExpandOpts opts = { .type = SAFE_AREA_TYPE_SYSTEM | SAFE_AREA_TYPE_CUTOUT,
388             .edges = SAFE_AREA_EDGE_ALL };
389         host->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
390     }
391     isRightToLeft_ = AceApplicationInfo::GetInstance().IsRightToLeft();
392     auto id = host->GetId();
393     auto pipeline = host->GetContext();
394     CHECK_NULL_VOID(pipeline);
395 
396     pipeline->AddWindowStateChangedCallback(id);
397     pipeline->AddWindowSizeChangeCallback(id);
398     pipeline->GetMemoryManager()->AddRecyclePageNode(host);
399 }
400 
OnDetachFromFrameNode(FrameNode * frameNode)401 void NavDestinationPattern::OnDetachFromFrameNode(FrameNode* frameNode)
402 {
403     CHECK_NULL_VOID(frameNode);
404     auto id = frameNode->GetId();
405     auto pipeline = frameNode->GetContext();
406     CHECK_NULL_VOID(pipeline);
407     pipeline->RemoveWindowStateChangedCallback(id);
408     pipeline->RemoveWindowSizeChangeCallback(id);
409     pipeline->GetMemoryManager()->RemoveRecyclePageNode(id);
410     NavDestinationPatternBase::RemoveOnTouchEvent(frameNode);
411 }
412 
DumpInfo()413 void NavDestinationPattern::DumpInfo()
414 {
415     DumpLog::GetInstance().AddDesc(std::string("name: ").append(name_));
416 }
417 
OverlayOnBackPressed()418 bool NavDestinationPattern::OverlayOnBackPressed()
419 {
420     CHECK_NULL_RETURN(overlayManager_, false);
421     if (overlayManager_->IsCurrentNodeProcessRemoveOverlay(GetHost(), false)) {
422         return overlayManager_->RemoveOverlay(true);
423     }
424     return false;
425 }
426 
NeedIgnoreKeyboard()427 bool NavDestinationPattern::NeedIgnoreKeyboard()
428 {
429     auto layoutProperty = GetLayoutProperty<NavDestinationLayoutProperty>();
430     CHECK_NULL_RETURN(layoutProperty, false);
431     auto& opts = layoutProperty->GetSafeAreaExpandOpts();
432     if (opts && (opts->type & SAFE_AREA_TYPE_KEYBOARD) && (opts->edges & SAFE_AREA_EDGE_BOTTOM)) {
433         return true;
434     }
435     return false;
436 }
437 
OnFontScaleConfigurationUpdate()438 void NavDestinationPattern::OnFontScaleConfigurationUpdate()
439 {
440     auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
441     CHECK_NULL_VOID(hostNode);
442     auto pipeline = hostNode->GetContext();
443     CHECK_NULL_VOID(pipeline);
444     auto titleBarUINode = hostNode->GetTitleBarNode();
445     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(titleBarUINode);
446     CHECK_NULL_VOID(titleBarNode);
447     auto backButtonNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetBackButton());
448     CHECK_NULL_VOID(backButtonNode);
449     if (LessNotEqual(pipeline->GetFontScale(), AgingAdapationDialogUtil::GetDialogBigFontSizeScale())) {
450         auto gestureHub = backButtonNode->GetOrCreateGestureEventHub();
451         CHECK_NULL_VOID(gestureHub);
452         gestureHub->SetLongPressEvent(nullptr);
453         auto longPressRecognizer = gestureHub->GetLongPressRecognizer();
454         CHECK_NULL_VOID(longPressRecognizer);
455         longPressRecognizer->SetOnActionEnd(nullptr);
456         return;
457     }
458     auto titleBarPattern = titleBarNode->GetPattern<TitleBarPattern>();
459     CHECK_NULL_VOID(titleBarPattern);
460     titleBarPattern->InitBackButtonLongPressEvent(backButtonNode);
461 }
462 
SetSystemBarStyle(const RefPtr<SystemBarStyle> & style)463 void NavDestinationPattern::SetSystemBarStyle(const RefPtr<SystemBarStyle>& style)
464 {
465     auto host = GetHost();
466     CHECK_NULL_VOID(host);
467     auto pipeline = host->GetContext();
468     CHECK_NULL_VOID(pipeline);
469     auto windowManager = pipeline->GetWindowManager();
470     CHECK_NULL_VOID(windowManager);
471     if (!backupStyle_.has_value()) {
472         backupStyle_ = windowManager->GetSystemBarStyle();
473     }
474     currStyle_ = style;
475     auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(navigationNode_.Upgrade());
476     CHECK_NULL_VOID(navigationNode);
477     auto navigationPattern = navigationNode->GetPattern<NavigationPattern>();
478     if (navigationPattern->IsFullPageNavigation() && navigationPattern->IsTopNavDestination(host)) {
479         if (currStyle_.value() != nullptr) {
480             windowManager->SetSystemBarStyle(currStyle_.value());
481         } else {
482             navigationPattern->TryRestoreSystemBarStyle(windowManager);
483         }
484     }
485 }
486 
GetTitlebarZIndex() const487 int32_t NavDestinationPattern::GetTitlebarZIndex() const
488 {
489     return DEFAULT_TITLEBAR_ZINDEX;
490 }
491 
OnWindowHide()492 void NavDestinationPattern::OnWindowHide()
493 {
494     CHECK_NULL_VOID(navDestinationContext_);
495     auto navPathInfo = navDestinationContext_->GetNavPathInfo();
496     CHECK_NULL_VOID(navPathInfo);
497     if (!navPathInfo->GetIsEntry()) {
498         return;
499     }
500     TAG_LOGI(AceLogTag::ACE_NAVIGATION, "window lifecycle change to hide, clear navDestination entry tag");
501     navPathInfo->SetIsEntry(false);
502     auto stack = GetNavigationStack().Upgrade();
503     CHECK_NULL_VOID(stack);
504     auto index = navDestinationContext_->GetIndex();
505     stack->SetIsEntryByIndex(index, false);
506 }
507 
OnDetachFromMainTree()508 void NavDestinationPattern::OnDetachFromMainTree()
509 {
510     backupStyle_.reset();
511     currStyle_.reset();
512     auto host = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
513     CHECK_NULL_VOID(host);
514     if (!host->IsHomeDestination()) {
515         return;
516     }
517     auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(navigationNode_.Upgrade());
518     CHECK_NULL_VOID(navigationNode);
519     auto navigationPattern = navigationNode->GetPattern<NavigationPattern>();
520     CHECK_NULL_VOID(navigationPattern);
521     navigationPattern->NotifyDestinationLifecycle(host, NavDestinationLifecycle::ON_WILL_DISAPPEAR);
522 }
523 
DumpInfo(std::unique_ptr<JsonValue> & json)524 void NavDestinationPattern::DumpInfo(std::unique_ptr<JsonValue>& json)
525 {
526     json->Put("name", name_.c_str());
527 }
528 
OnWindowSizeChanged(int32_t width,int32_t height,WindowSizeChangeReason type)529 void NavDestinationPattern::OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type)
530 {
531     auto navDestinationGroupNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
532     CHECK_NULL_VOID(navDestinationGroupNode);
533     if (preWidth_.has_value() && preWidth_.value() != width) {
534         AbortBarAnimation();
535     }
536     preWidth_ = width;
537     // change menu num in landscape and orientation
538     do {
539         if (navDestinationGroupNode->GetPrevMenuIsCustomValue(false)) {
540             break;
541         }
542         auto targetNum = SystemProperties::GetDeviceOrientation() == DeviceOrientation::LANDSCAPE ? MAX_MENU_NUM_LARGE
543                                                                                                   : MAX_MENU_NUM_SMALL;
544         if (targetNum == maxMenuNums_) {
545             break;
546         }
547         maxMenuNums_ = targetNum;
548         auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navDestinationGroupNode->GetTitleBarNode());
549         CHECK_NULL_VOID(titleBarNode);
550         BuildMenu(navDestinationGroupNode, titleBarNode);
551         titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
552     } while (0);
553     if (type == WindowSizeChangeReason::ROTATION) {
554         CloseLongPressDialog();
555     }
556 }
557 
CloseLongPressDialog()558 void NavDestinationPattern::CloseLongPressDialog()
559 {
560     auto navDestinationGroupNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
561     CHECK_NULL_VOID(navDestinationGroupNode);
562     auto pipeline = navDestinationGroupNode->GetContext();
563     CHECK_NULL_VOID(pipeline);
564     auto overlayManager = pipeline->GetOverlayManager();
565     CHECK_NULL_VOID(overlayManager);
566 
567     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(navDestinationGroupNode->GetTitleBarNode());
568     CHECK_NULL_VOID(titleBarNode);
569     auto titleBarPattern = titleBarNode->GetPattern<TitleBarPattern>();
570     CHECK_NULL_VOID(titleBarPattern);
571     auto backButtonDialogNode = titleBarPattern->GetBackButtonDialogNode();
572     if (backButtonDialogNode) {
573         overlayManager->CloseDialog(backButtonDialogNode);
574         titleBarPattern->SetBackButtonDialogNode(nullptr);
575     }
576     auto menuItemDialogNode = titleBarPattern->GetLargeFontPopUpDialogNode();
577     if (menuItemDialogNode) {
578         overlayManager->CloseDialog(menuItemDialogNode);
579         titleBarPattern->SetLargeFontPopUpDialogNode(nullptr);
580     }
581 }
582 
UpdateTitleAndToolBarHiddenOffset(float offset)583 void NavDestinationPattern::UpdateTitleAndToolBarHiddenOffset(float offset)
584 {
585     CancelShowTitleAndToolBarTask();
586     auto nodeBase = AceType::DynamicCast<NavDestinationNodeBase>(GetHost());
587     CHECK_NULL_VOID(nodeBase);
588     if (EnableTitleBarSwipe(nodeBase)) {
589         auto titleBarNode = AceType::DynamicCast<TitleBarNode>(nodeBase->GetTitleBarNode());
590         UpdateBarHiddenOffset(nodeBase, titleBarNode, offset, true);
591     }
592     if (EnableToolBarSwipe(nodeBase)) {
593         auto toolBarNode = AceType::DynamicCast<NavToolbarNode>(nodeBase->GetToolBarNode());
594         UpdateBarHiddenOffset(nodeBase, toolBarNode, offset, false);
595     }
596 }
597 
CancelShowTitleAndToolBarTask()598 void NavDestinationPattern::CancelShowTitleAndToolBarTask()
599 {
600     if (titleBarSwipeContext_.showBarTask) {
601         titleBarSwipeContext_.showBarTask.Cancel();
602         titleBarSwipeContext_.showBarTask.Reset(nullptr);
603     }
604     if (toolBarSwipeContext_.showBarTask) {
605         toolBarSwipeContext_.showBarTask.Cancel();
606         toolBarSwipeContext_.showBarTask.Reset(nullptr);
607     }
608 }
609 
ResetTitleAndToolBarState()610 void NavDestinationPattern::ResetTitleAndToolBarState()
611 {
612     auto nodeBase = AceType::DynamicCast<NavDestinationNodeBase>(GetHost());
613     CHECK_NULL_VOID(nodeBase);
614     if (EnableTitleBarSwipe(nodeBase)) {
615         auto titleBarNode = AceType::DynamicCast<TitleBarNode>(nodeBase->GetTitleBarNode());
616         ResetBarState(nodeBase, titleBarNode, true);
617     }
618     if (EnableToolBarSwipe(nodeBase)) {
619         auto toolBarNode = AceType::DynamicCast<NavToolbarNode>(nodeBase->GetToolBarNode());
620         ResetBarState(nodeBase, toolBarNode, false);
621     }
622 }
623 
ResetBarState(const RefPtr<NavDestinationNodeBase> & nodeBase,const RefPtr<FrameNode> & barNode,bool isTitle)624 void NavDestinationPattern::ResetBarState(const RefPtr<NavDestinationNodeBase>& nodeBase,
625     const RefPtr<FrameNode>& barNode, bool isTitle)
626 {
627     CHECK_NULL_VOID(nodeBase);
628     CHECK_NULL_VOID(barNode);
629     auto& ctx = GetSwipeContext(isTitle);
630     if (ctx.isBarHiding || ctx.isBarShowing) {
631         return;
632     }
633 
634     float translate = 0.0f;
635     float barHeight = 0.0f;
636     if (!GetTitleOrToolBarTranslateAndHeight(barNode, translate, barHeight) || NearZero(barHeight)) {
637         return;
638     }
639 
640     auto threshold = Dimension(TRANSLATE_THRESHOLD, DimensionUnit::VP).ConvertToPx();
641     float halfBarHeight = barHeight / 2.0f;
642     if (GreatOrEqual(threshold, halfBarHeight)) {
643         threshold = halfBarHeight;
644     }
645     float showAreaHeight = barHeight - std::abs(translate);
646     if (GreatNotEqual(showAreaHeight, 0.0f) && LessNotEqual(showAreaHeight, threshold)) {
647         /**
648          * Scroll to show a small portion of the titleBar&toolBar,
649          * but the height of shownArea is less than the threshold,
650          * it needs to be restored to the hidden state.
651          */
652         StartHideOrShowBarInner(nodeBase, barHeight, translate, isTitle, true);
653     } else if (GreatOrEqual(showAreaHeight, barHeight - threshold) && LessNotEqual(showAreaHeight, barHeight)) {
654         /**
655          * Scroll to hide a small portion of the titleBar&toolBar,
656          * but the height of hiddenArea is less than the threshold,
657          * it needs to be restored to the shown state.
658          */
659         StartHideOrShowBarInner(nodeBase, barHeight, translate, isTitle, false);
660     }
661 }
662 
EnableTitleBarSwipe(const RefPtr<NavDestinationNodeBase> & nodeBase)663 bool NavDestinationPattern::EnableTitleBarSwipe(const RefPtr<NavDestinationNodeBase>& nodeBase)
664 {
665     CHECK_NULL_RETURN(nodeBase, false);
666     auto property = nodeBase->GetLayoutProperty<NavDestinationLayoutPropertyBase>();
667     CHECK_NULL_RETURN(property, false);
668     return !property->GetHideTitleBarValue(false);
669 }
670 
EnableToolBarSwipe(const RefPtr<NavDestinationNodeBase> & nodeBase)671 bool NavDestinationPattern::EnableToolBarSwipe(const RefPtr<NavDestinationNodeBase>& nodeBase)
672 {
673     CHECK_NULL_RETURN(nodeBase, false);
674     auto property = nodeBase->GetLayoutProperty<NavDestinationLayoutPropertyBase>();
675     CHECK_NULL_RETURN(property, false);
676     return !property->GetHideToolBarValue(false);
677 }
678 
UpdateBarHiddenOffset(const RefPtr<NavDestinationNodeBase> & nodeBase,const RefPtr<FrameNode> & barNode,float offset,bool isTitle)679 void NavDestinationPattern::UpdateBarHiddenOffset(
680     const RefPtr<NavDestinationNodeBase>& nodeBase, const RefPtr<FrameNode>& barNode, float offset, bool isTitle)
681 {
682     CHECK_NULL_VOID(nodeBase);
683     CHECK_NULL_VOID(barNode);
684     auto& ctx = GetSwipeContext(isTitle);
685     if (ctx.isBarShowing || ctx.isBarHiding) {
686         return;
687     }
688 
689     float preTranslate = 0.0f;
690     float barHeight = 0.0f;
691     if (!GetTitleOrToolBarTranslateAndHeight(barNode, preTranslate, barHeight) || NearZero(barHeight)) {
692         return;
693     }
694 
695     float newTranslate = 0.0f;
696     if (isTitle) {
697         newTranslate = std::clamp(preTranslate - offset, -barHeight, 0.0f);
698     } else {
699         newTranslate = std::clamp(preTranslate + offset, 0.0f, barHeight);
700     }
701     NavigationTitleUtil::UpdateTitleOrToolBarTranslateYAndOpacity(nodeBase, barNode, newTranslate, isTitle);
702 
703     auto threshold = Dimension(TRANSLATE_THRESHOLD, DimensionUnit::VP).ConvertToPx();
704     float halfBarHeight = barHeight / 2.0f;
705     if (GreatOrEqual(threshold, halfBarHeight)) {
706         threshold = halfBarHeight;
707     }
708     if (Positive(offset) && LessNotEqual(std::abs(preTranslate), threshold) &&
709         GreatOrEqual(std::abs(newTranslate), threshold)) {
710         // When the scrolling up distance exceeds the threshold, it is necessary to start the hide animation.
711         StartHideOrShowBarInner(nodeBase, barHeight, newTranslate, isTitle, true);
712     } else if (Negative(offset) && LessNotEqual(barHeight - std::abs(preTranslate), threshold) &&
713         GreatOrEqual(barHeight - std::abs(newTranslate), threshold)) {
714         // When the scrolling down distance exceeds the threshold, it is necessary to start the show animation.
715         StartHideOrShowBarInner(nodeBase, barHeight, newTranslate, isTitle, false);
716     }
717 }
718 
ShowTitleAndToolBar()719 void NavDestinationPattern::ShowTitleAndToolBar()
720 {
721     auto nodeBase = AceType::DynamicCast<NavDestinationNodeBase>(GetHost());
722     CHECK_NULL_VOID(nodeBase);
723     if (EnableTitleBarSwipe(nodeBase)) {
724         auto titleBarNode = AceType::DynamicCast<TitleBarNode>(nodeBase->GetTitleBarNode());
725         float translate = 0.0f;
726         float barHeight = 0.0f;
727         if (GetTitleOrToolBarTranslateAndHeight(titleBarNode, translate, barHeight)) {
728             if (titleBarSwipeContext_.showBarTask) {
729                 titleBarSwipeContext_.showBarTask.Cancel();
730                 titleBarSwipeContext_.showBarTask.Reset(nullptr);
731             }
732             StopHideBarIfNeeded(translate, true);
733             StartHideOrShowBarInner(nodeBase, barHeight, translate, true, false);
734         }
735     }
736     if (EnableToolBarSwipe(nodeBase)) {
737         auto toolBarNode = AceType::DynamicCast<NavToolbarNode>(nodeBase->GetToolBarNode());
738         float translate = 0.0f;
739         float barHeight = 0.0f;
740         if (GetTitleOrToolBarTranslateAndHeight(toolBarNode, translate, barHeight)) {
741             if (toolBarSwipeContext_.showBarTask) {
742                 toolBarSwipeContext_.showBarTask.Cancel();
743                 toolBarSwipeContext_.showBarTask.Reset(nullptr);
744             }
745             StopHideBarIfNeeded(translate, false);
746             StartHideOrShowBarInner(nodeBase, barHeight, translate, false, false);
747         }
748     }
749 }
750 
StartHideOrShowBarInner(const RefPtr<NavDestinationNodeBase> & nodeBase,float barHeight,float curTranslate,bool isTitle,bool isHide)751 void NavDestinationPattern::StartHideOrShowBarInner(
752     const RefPtr<NavDestinationNodeBase>& nodeBase, float barHeight, float curTranslate, bool isTitle, bool isHide)
753 {
754     CHECK_NULL_VOID(nodeBase);
755     auto barNode = GetBarNode(nodeBase, isTitle);
756     CHECK_NULL_VOID(barNode);
757 
758     auto propertyCallback = [weak = WeakClaim(this), barHeight, isTitle, isHide]() {
759         auto pattern = weak.Upgrade();
760         CHECK_NULL_VOID(pattern);
761         auto nodeBase = AceType::DynamicCast<NavDestinationNodeBase>(pattern->GetHost());
762         CHECK_NULL_VOID(nodeBase);
763         auto barNode = pattern->GetBarNode(nodeBase, isTitle);
764         CHECK_NULL_VOID(barNode);
765         float translate = isHide ? (isTitle ? -barHeight : barHeight) : 0.0f;
766         NavigationTitleUtil::UpdateTitleOrToolBarTranslateYAndOpacity(nodeBase, barNode, translate, isTitle);
767     };
768     auto finishCallback = [weak = WeakClaim(this), isTitle, isHide]() {
769         auto pattern = weak.Upgrade();
770         CHECK_NULL_VOID(pattern);
771         auto nodeBase = AceType::DynamicCast<NavDestinationNodeBase>(pattern->GetHost());
772         CHECK_NULL_VOID(nodeBase);
773         auto barNode = pattern->GetBarNode(nodeBase, isTitle);
774         CHECK_NULL_VOID(barNode);
775         auto& ctx = pattern->GetSwipeContext(isTitle);
776         if (isHide) {
777             ctx.isBarHiding = false;
778         } else {
779             ctx.isBarShowing = false;
780         }
781     };
782     AnimationOption option;
783     option.SetCurve(TRANSLATE_CURVE);
784     auto& ctx = GetSwipeContext(isTitle);
785     if (isHide) {
786         ctx.isBarHiding = true;
787     } else {
788         ctx.isBarShowing = true;
789     }
790     NavigationTitleUtil::UpdateTitleOrToolBarTranslateYAndOpacity(nodeBase, barNode, curTranslate, isTitle);
791     AnimationUtils::Animate(
792         option, propertyCallback, finishCallback, nullptr /* repeatCallback */, nodeBase->GetContextRefPtr());
793 }
794 
StopHideBarIfNeeded(float curTranslate,bool isTitle)795 void NavDestinationPattern::StopHideBarIfNeeded(float curTranslate, bool isTitle)
796 {
797     auto& ctx = GetSwipeContext(isTitle);
798     if (!ctx.isBarHiding) {
799         return;
800     }
801 
802     auto propertyCallback = [weak = WeakClaim(this), isTitle, curTranslate]() {
803         auto pattern = weak.Upgrade();
804         CHECK_NULL_VOID(pattern);
805         auto nodeBase = AceType::DynamicCast<NavDestinationNodeBase>(pattern->GetHost());
806         CHECK_NULL_VOID(nodeBase);
807         auto barNode = pattern->GetBarNode(nodeBase, isTitle);
808         CHECK_NULL_VOID(barNode);
809         NavigationTitleUtil::UpdateTitleOrToolBarTranslateYAndOpacity(nodeBase, barNode, curTranslate, isTitle);
810     };
811     AnimationOption option;
812     option.SetDuration(0);
813     option.SetCurve(Curves::LINEAR);
814     auto host = GetHost();
815     CHECK_NULL_VOID(host);
816     AnimationUtils::Animate(
817         option, propertyCallback, nullptr /* finishCallback */, nullptr /* repeatCallback */, host->GetContextRefPtr());
818     ctx.isBarHiding = false;
819 }
820 
GetBarNode(const RefPtr<NavDestinationNodeBase> & nodeBase,bool isTitle)821 RefPtr<FrameNode> NavDestinationPattern::GetBarNode(const RefPtr<NavDestinationNodeBase>& nodeBase, bool isTitle)
822 {
823     CHECK_NULL_RETURN(nodeBase, nullptr);
824     return isTitle ? AceType::DynamicCast<FrameNode>(nodeBase->GetTitleBarNode())
825                    : AceType::DynamicCast<FrameNode>(nodeBase->GetToolBarNode());
826 }
827 
OnCoordScrollStart()828 void NavDestinationPattern::OnCoordScrollStart()
829 {
830     auto navDestinationGroupNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
831     CHECK_NULL_VOID(navDestinationGroupNode);
832     auto navDestinationEventHub = navDestinationGroupNode->GetOrCreateEventHub<NavDestinationEventHub>();
833     CHECK_NULL_VOID(navDestinationEventHub);
834     navDestinationEventHub->FireOnCoordScrollStartAction();
835 }
836 
OnCoordScrollUpdate(float offset,float currentOffset)837 float NavDestinationPattern::OnCoordScrollUpdate(float offset, float currentOffset)
838 {
839     auto navDestinationGroupNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
840     CHECK_NULL_RETURN(navDestinationGroupNode, 0.0f);
841     auto navDestinationEventHub = navDestinationGroupNode->GetOrCreateEventHub<NavDestinationEventHub>();
842     CHECK_NULL_RETURN(navDestinationEventHub, 0.0f);
843     navDestinationEventHub->FireOnCoordScrollUpdateAction(currentOffset);
844     return 0.0f;
845 }
846 
OnCoordScrollEnd()847 void NavDestinationPattern::OnCoordScrollEnd()
848 {
849     auto navDestinationGroupNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
850     CHECK_NULL_VOID(navDestinationGroupNode);
851     auto navDestinationEventHub = navDestinationGroupNode->GetOrCreateEventHub<NavDestinationEventHub>();
852     CHECK_NULL_VOID(navDestinationEventHub);
853     navDestinationEventHub->FireOnCoordScrollEndAction();
854 }
855 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)856 bool NavDestinationPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
857 {
858     auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
859     CHECK_NULL_RETURN(hostNode, false);
860     hostNode->AdjustRenderContextIfNeeded();
861     return false;
862 }
863 
CheckIfOrientationChanged()864 void NavDestinationPattern::CheckIfOrientationChanged()
865 {
866     auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
867     CHECK_NULL_VOID(hostNode);
868     if (hostNode->GetNavDestinationMode() == NavDestinationMode::DIALOG) {
869         TAG_LOGI(AceLogTag::ACE_NAVIGATION, "Setting Orientation is not supported in dialog mode");
870         return;
871     }
872 
873     std::optional<Orientation> curOri = hostNode->GetOrientation();
874     std::optional<Orientation> preOri = hostNode->GetPreOrientation();
875     if (isFirstTimeCheckOrientation_) {
876         isFirstTimeCheckOrientation_ = false;
877         hostNode->SetPreOrientation(curOri);
878         return;
879     }
880     if (curOri == preOri) {
881         return;
882     }
883     hostNode->SetPreOrientation(curOri);
884 
885     auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(navigationNode_.Upgrade());
886     CHECK_NULL_VOID(navigationNode);
887     auto navigationPattern = navigationNode->GetPattern<NavigationPattern>();
888     CHECK_NULL_VOID(navigationPattern);
889     if (!navigationPattern->IsPageLevelConfigEnabled() || !navigationPattern->IsFullPageNavigation()) {
890         TAG_LOGI(AceLogTag::ACE_NAVIGATION, "conditions are not met, orientation won't change");
891         return;
892     }
893 
894     if (hostNode->IsOnAnimation()) {
895         StopAnimation();
896     } else {
897         auto context = hostNode->GetContext();
898         CHECK_NULL_VOID(context);
899         auto windowMgr = context->GetWindowManager();
900         CHECK_NULL_VOID(windowMgr);
901         windowMgr->SetRequestedOrientation(curOri, true);
902     }
903 }
904 
StopAnimation()905 void NavDestinationPattern::StopAnimation()
906 {
907     auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(navigationNode_.Upgrade());
908     CHECK_NULL_VOID(navigationNode);
909     auto navigationPattern = navigationNode->GetPattern<NavigationPattern>();
910     CHECK_NULL_VOID(navigationPattern);
911     navigationPattern->AbortAnimation(navigationNode);
912 }
913 
CheckIfStatusBarConfigChanged()914 void NavDestinationPattern::CheckIfStatusBarConfigChanged()
915 {
916     auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
917     CHECK_NULL_VOID(hostNode);
918     if (hostNode->GetNavDestinationMode() == NavDestinationMode::DIALOG) {
919         TAG_LOGI(AceLogTag::ACE_NAVIGATION, "enable/disable statusBar is not supported in dialog mode");
920         return;
921     }
922 
923     auto curConfig = hostNode->GetStatusBarConfig();
924     auto preConfig = hostNode->GetPreStatusBarConfig();
925     if (isFirstTimeCheckStatusBarConfig_) {
926         isFirstTimeCheckStatusBarConfig_ = false;
927         hostNode->SetPreStatusBarConfig(curConfig);
928         return;
929     }
930     if (curConfig == preConfig) {
931         return;
932     }
933     hostNode->SetPreStatusBarConfig(curConfig);
934 
935     auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(navigationNode_.Upgrade());
936     CHECK_NULL_VOID(navigationNode);
937     auto navigationPattern = navigationNode->GetPattern<NavigationPattern>();
938     CHECK_NULL_VOID(navigationPattern);
939     if (!navigationPattern->IsPageLevelConfigEnabled() || !navigationPattern->IsFullPageNavigation()) {
940         TAG_LOGI(AceLogTag::ACE_NAVIGATION, "conditions are not met, status won't change");
941         return;
942     }
943 
944     auto context = hostNode->GetContext();
945     CHECK_NULL_VOID(context);
946     auto mgr = context->GetWindowManager();
947     CHECK_NULL_VOID(mgr);
948     std::optional<bool> enable;
949     std::optional<bool> animated;
950     if (curConfig.has_value()) {
951         enable = curConfig.value().first;
952         animated = curConfig.value().second;
953     }
954     mgr->SetWindowSystemBarEnabled(SystemBarType::STATUS, enable, animated);
955 }
956 
CheckIfNavigationIndicatorConfigChagned()957 void NavDestinationPattern::CheckIfNavigationIndicatorConfigChagned()
958 {
959     auto hostNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
960     CHECK_NULL_VOID(hostNode);
961     if (hostNode->GetNavDestinationMode() == NavDestinationMode::DIALOG) {
962         TAG_LOGI(AceLogTag::ACE_NAVIGATION, "enable/disable navIndicator is not supported in dialog mode");
963         return;
964     }
965 
966     auto curConfig = hostNode->GetNavigationIndicatorConfig();
967     auto preConfig = hostNode->GetPreNavigationIndicatorConfig();
968     if (isFirstTimeCheckNavigationIndicatorConfig_) {
969         isFirstTimeCheckNavigationIndicatorConfig_ = false;
970         hostNode->SetPreNavigationIndicatorConfig(curConfig);
971         return;
972     }
973     if (curConfig == preConfig) {
974         return;
975     }
976     hostNode->SetPreNavigationIndicatorConfig(curConfig);
977 
978     auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(navigationNode_.Upgrade());
979     CHECK_NULL_VOID(navigationNode);
980     auto navigationPattern = navigationNode->GetPattern<NavigationPattern>();
981     CHECK_NULL_VOID(navigationPattern);
982     if (!navigationPattern->IsPageLevelConfigEnabled() || !navigationPattern->IsFullPageNavigation()) {
983         TAG_LOGI(AceLogTag::ACE_NAVIGATION, "conditions are not met, navigationIndicator won't change");
984         return;
985     }
986 
987     auto context = hostNode->GetContext();
988     CHECK_NULL_VOID(context);
989     auto mgr = context->GetWindowManager();
990     CHECK_NULL_VOID(mgr);
991     std::optional<bool> enable;
992     if (curConfig.has_value()) {
993         enable = curConfig.value();
994     }
995     mgr->SetWindowSystemBarEnabled(SystemBarType::NAVIGATION_INDICATOR, enable, std::nullopt);
996 }
997 
BeforeCreateLayoutWrapper()998 void NavDestinationPattern::BeforeCreateLayoutWrapper()
999 {
1000     auto navDestinationGroupNode = AceType::DynamicCast<NavDestinationGroupNode>(GetHost());
1001     CHECK_NULL_VOID(navDestinationGroupNode);
1002     auto navDestinationEventHub = navDestinationGroupNode->GetOrCreateEventHub<NavDestinationEventHub>();
1003     CHECK_NULL_VOID(navDestinationEventHub);
1004     navDestinationEventHub->FireBeforeCreateLayoutWrapperCallBack();
1005 }
1006 } // namespace OHOS::Ace::NG
1007