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