• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/navigation/navdestination_pattern_base.h"
17 
18 #include "core/components_ng/pattern/navigation/navdestination_node_base.h"
19 #include "core/components_ng/pattern/navigation/navigation_title_util.h"
20 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
21 #include "core/components_ng/pattern/navigation/navigation_group_node.h"
22 #include "core/components_ng/pattern/divider/divider_render_property.h"
23 
24 namespace OHOS::Ace::NG {
25 namespace {
26 constexpr int32_t DEFAULT_ANIMATION_DURATION = 500;
27 } // namespace
28 
SetTitleBarStyle(const std::optional<BarStyle> & barStyle)29 void NavDestinationPatternBase::SetTitleBarStyle(const std::optional<BarStyle>& barStyle)
30 {
31     if (titleBarStyle_ != barStyle) {
32         // Mark need update safeAreaPadding when it is enabled or disabled.
33         if (barStyle.value_or(BarStyle::STANDARD) == BarStyle::SAFE_AREA_PADDING ||
34             titleBarStyle_.value_or(BarStyle::STANDARD) == BarStyle::SAFE_AREA_PADDING) {
35             safeAreaPaddingChanged_ = true;
36         }
37         titleBarStyle_ = barStyle;
38         auto host = GetHost();
39         CHECK_NULL_VOID(host);
40         host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
41     }
42 }
43 
SetToolBarStyle(const std::optional<BarStyle> & barStyle)44 void NavDestinationPatternBase::SetToolBarStyle(const std::optional<BarStyle>& barStyle)
45 {
46     if (toolBarStyle_ != barStyle) {
47         // Mark need update safeAreaPadding when it is enabled or disabled.
48         if (barStyle.value_or(BarStyle::STANDARD) == BarStyle::SAFE_AREA_PADDING ||
49             toolBarStyle_.value_or(BarStyle::STANDARD) == BarStyle::SAFE_AREA_PADDING) {
50             safeAreaPaddingChanged_ = true;
51         }
52         toolBarStyle_ = barStyle;
53         auto host = GetHost();
54         CHECK_NULL_VOID(host);
55         host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
56     }
57 }
58 
UpdateLayoutPropertyBeforeAnimation(const RefPtr<NavDestinationNodeBase> & navNodeBase,bool needRunTitleBarAnimation,bool needRunToolBarAnimation,bool hideTitleBar,bool hideToolBar)59 void NavDestinationPatternBase::UpdateLayoutPropertyBeforeAnimation(const RefPtr<NavDestinationNodeBase>& navNodeBase,
60     bool needRunTitleBarAnimation, bool needRunToolBarAnimation, bool hideTitleBar, bool hideToolBar)
61 {
62     CHECK_NULL_VOID(navNodeBase);
63     auto property = navNodeBase->GetLayoutProperty<NavDestinationLayoutPropertyBase>();
64     CHECK_NULL_VOID(property);
65     if (needRunTitleBarAnimation && titleBarAnimationCount_ == 0) {
66         property->UpdateTitleBarTranslateState(hideTitleBar ?
67             BarTranslateState::TRANSLATE_ZERO : BarTranslateState::TRANSLATE_HEIGHT);
68         if (!hideTitleBar) {
69             UpdateTitleBarProperty(property, false, navNodeBase);
70         }
71     }
72     if (needRunToolBarAnimation && toolBarAnimationCount_ == 0) {
73         property->UpdateToolBarTranslateState(hideToolBar ?
74             BarTranslateState::TRANSLATE_ZERO : BarTranslateState::TRANSLATE_HEIGHT);
75         if (!hideToolBar) {
76             UpdateToolBarAndDividerProperty(property, false, navNodeBase);
77         }
78     }
79 }
80 
HandleTitleBarAndToolBarAnimation(const RefPtr<NavDestinationNodeBase> & navNodeBase,bool needRunTitleBarAnimation,bool needRunToolBarAnimation)81 void NavDestinationPatternBase::HandleTitleBarAndToolBarAnimation(const RefPtr<NavDestinationNodeBase>& navNodeBase,
82     bool needRunTitleBarAnimation, bool needRunToolBarAnimation)
83 {
84     if (!(needRunToolBarAnimation || needRunTitleBarAnimation)) {
85         return;
86     }
87 
88     CHECK_NULL_VOID(navNodeBase);
89     auto pipeline = navNodeBase->GetContext();
90     CHECK_NULL_VOID(pipeline);
91     auto property = navNodeBase->GetLayoutProperty<NavDestinationLayoutPropertyBase>();
92     CHECK_NULL_VOID(property);
93     bool hideTitleBar = property->GetHideTitleBarValue(false);
94     bool hideToolBar = property->GetHideToolBarValue(false);
95     UpdateLayoutPropertyBeforeAnimation(navNodeBase, needRunTitleBarAnimation,
96         needRunToolBarAnimation, hideTitleBar, hideToolBar);
97 
98     auto task = [weakPattern = WeakClaim(this), needRunTitleBarAnimation, needRunToolBarAnimation,
99         hideTitleBar, hideToolBar]() mutable {
100         auto pattern = weakPattern.Upgrade();
101         CHECK_NULL_VOID(pattern);
102         auto node = AceType::DynamicCast<NavDestinationNodeBase>(pattern->GetHost());
103         CHECK_NULL_VOID(node);
104         auto property = node->GetLayoutProperty<NavDestinationLayoutPropertyBase>();
105         CHECK_NULL_VOID(property);
106         if (pattern->IsNeedHideToolBarForNavWidth()) {
107             property->ResetToolBarTranslateState();
108             needRunToolBarAnimation = false;
109         }
110         if (!(needRunToolBarAnimation || needRunTitleBarAnimation)) {
111             return;
112         }
113 
114         auto titleBarNode = AceType::DynamicCast<TitleBarNode>(node->GetTitleBarNode());
115         if (needRunTitleBarAnimation && !hideTitleBar && titleBarNode && pattern->GetTitleBarAnimationCount() == 0) {
116             pattern->UpdateTitleBarTranslateAndOpacity(true, titleBarNode, pattern->GetTitleBarHeight());
117         }
118         auto toolBarNode = AceType::DynamicCast<NavToolbarNode>(node->GetToolBarNode());
119         auto toolBarDividerNode = AceType::DynamicCast<FrameNode>(node->GetToolBarDividerNode());
120         if (needRunToolBarAnimation && !hideToolBar && toolBarNode && pattern->GetToolBarAnimationCount() == 0) {
121             pattern->UpdateToolBarAndDividerTranslateAndOpacity(true, toolBarNode,
122                 pattern->GetToolBarHeight(), toolBarDividerNode, pattern->GetToolBarDividerHeight());
123         }
124 
125         pattern->StartAnimation(needRunTitleBarAnimation, hideTitleBar, needRunToolBarAnimation, hideToolBar);
126     };
127     pipeline->AddAfterLayoutTask(std::move(task));
128 }
129 
UpdateTitleBarProperty(const RefPtr<LayoutProperty> & navBarLayoutProperty,bool hide,const RefPtr<NavDestinationNodeBase> & hostNode)130 void NavDestinationPatternBase::UpdateTitleBarProperty(const RefPtr<LayoutProperty>& navBarLayoutProperty, bool hide,
131     const RefPtr<NavDestinationNodeBase>& hostNode)
132 {
133     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
134     CHECK_NULL_VOID(titleBarNode);
135     auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty();
136     CHECK_NULL_VOID(titleBarLayoutProperty);
137     if (hide) {
138         titleBarLayoutProperty->UpdateVisibility(VisibleType::GONE);
139         titleBarNode->SetJSViewActive(false);
140     } else {
141         titleBarLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
142         titleBarNode->SetJSViewActive(true);
143         auto&& opts = navBarLayoutProperty->GetSafeAreaExpandOpts();
144         if (opts) {
145             titleBarLayoutProperty->UpdateSafeAreaExpandOpts(*opts);
146         }
147     }
148 }
149 
UpdateTitleBarTranslateAndOpacity(bool hide,const RefPtr<TitleBarNode> & titleBarNode,float titleBarHeight)150 void NavDestinationPatternBase::UpdateTitleBarTranslateAndOpacity(
151     bool hide, const RefPtr<TitleBarNode>& titleBarNode, float titleBarHeight)
152 {
153     if (titleBarNode) {
154         auto renderContext = titleBarNode->GetRenderContext();
155         if (renderContext) {
156             auto offset = renderContext->GetTranslateXYProperty();
157             offset.SetY(hide ? -titleBarHeight : 0.0f);
158             renderContext->UpdateTranslateInXY(offset);
159             renderContext->UpdateOpacity(hide ? 0.0f : 1.0f);
160         }
161     }
162 }
163 
UpdateToolBarAndDividerProperty(const RefPtr<LayoutProperty> & navBarLayoutProperty,bool hide,const RefPtr<NavDestinationNodeBase> & hostNode)164 void NavDestinationPatternBase::UpdateToolBarAndDividerProperty(const RefPtr<LayoutProperty>& navBarLayoutProperty,
165     bool hide, const RefPtr<NavDestinationNodeBase>& hostNode)
166 {
167     auto toolBarNode = AceType::DynamicCast<NavToolbarNode>(hostNode->GetToolBarNode());
168     CHECK_NULL_VOID(toolBarNode);
169     auto toolBarLayoutProperty = toolBarNode->GetLayoutProperty();
170     CHECK_NULL_VOID(toolBarLayoutProperty);
171     auto toolBarDividerNode = AceType::DynamicCast<FrameNode>(hostNode->GetToolBarDividerNode());
172     RefPtr<LayoutProperty> toolBarDividerLayoutProperty = nullptr;
173     if (toolBarDividerNode) {
174         toolBarDividerLayoutProperty = toolBarDividerNode->GetLayoutProperty();
175     }
176     if (hide || !toolBarNode->HasValidContent()) {
177         toolBarLayoutProperty->UpdateVisibility(VisibleType::GONE);
178         toolBarNode->SetActive(false);
179         if (toolBarDividerLayoutProperty) {
180             toolBarDividerLayoutProperty->UpdateVisibility(VisibleType::GONE);
181         }
182     } else {
183         toolBarLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
184         toolBarNode->SetActive(true);
185         if (toolBarDividerLayoutProperty) {
186             toolBarDividerLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
187         }
188 
189         auto&& opts = navBarLayoutProperty->GetSafeAreaExpandOpts();
190         if (opts) {
191             toolBarLayoutProperty->UpdateSafeAreaExpandOpts(*opts);
192         }
193     }
194 }
195 
UpdateToolBarAndDividerTranslateAndOpacity(bool hide,const RefPtr<NavToolbarNode> & toolBarNode,float toolBarHeight,const RefPtr<FrameNode> & toolbarDividerNode,float toolBarDividerHeight)196 void NavDestinationPatternBase::UpdateToolBarAndDividerTranslateAndOpacity(bool hide,
197     const RefPtr<NavToolbarNode>& toolBarNode, float toolBarHeight, const RefPtr<FrameNode>& toolbarDividerNode,
198     float toolBarDividerHeight)
199 {
200     float opacity = hide ? 0.0f : 1.0f;
201     float offsetY = hide ? (toolBarHeight + toolBarDividerHeight) : 0;
202     if (toolBarNode) {
203         auto renderContext = toolBarNode->GetRenderContext();
204         if (renderContext) {
205             renderContext->UpdateTranslateInXY({ 0.0f, offsetY });
206             renderContext->UpdateOpacity(opacity);
207         }
208     }
209     if (toolbarDividerNode) {
210         auto dividerContext = toolbarDividerNode->GetRenderContext();
211         if (dividerContext) {
212             dividerContext->UpdateTranslateInXY({ 0.0f, offsetY });
213             dividerContext->UpdateOpacity(opacity);
214         }
215     }
216 }
217 
HideOrShowTitleBarImmediately(const RefPtr<NavDestinationNodeBase> & hostNode,bool hide)218 void NavDestinationPatternBase::HideOrShowTitleBarImmediately(const RefPtr<NavDestinationNodeBase>& hostNode, bool hide)
219 {
220     auto navBarPattern = hostNode->GetPattern<NavDestinationPatternBase>();
221     CHECK_NULL_VOID(navBarPattern);
222     auto navBarLayoutProperty = hostNode->GetLayoutProperty();
223     CHECK_NULL_VOID(navBarLayoutProperty);
224     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
225     CHECK_NULL_VOID(titleBarNode);
226     UpdateTitleBarProperty(navBarLayoutProperty, hide, hostNode);
227     UpdateTitleBarTranslateAndOpacity(hide, titleBarNode, navBarPattern->GetTitleBarHeight());
228     titleBarNode->MarkModifyDone();
229     titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
230 }
231 
HideOrShowToolBarImmediately(const RefPtr<NavDestinationNodeBase> & hostNode,bool hide)232 void NavDestinationPatternBase::HideOrShowToolBarImmediately(const RefPtr<NavDestinationNodeBase>& hostNode, bool hide)
233 {
234     auto navDestinationPatternBase = hostNode->GetPattern<NavDestinationPatternBase>();
235     CHECK_NULL_VOID(navDestinationPatternBase);
236     auto navBarLayoutProperty = hostNode->GetLayoutProperty();
237     CHECK_NULL_VOID(navBarLayoutProperty);
238     auto toolBarNode = AceType::DynamicCast<NavToolbarNode>(hostNode->GetToolBarNode());
239     CHECK_NULL_VOID(toolBarNode);
240     auto toolBarDividerNode = AceType::DynamicCast<FrameNode>(hostNode->GetToolBarDividerNode());
241     UpdateToolBarAndDividerProperty(navBarLayoutProperty, hide, hostNode);
242     UpdateToolBarAndDividerTranslateAndOpacity(hide, toolBarNode, GetToolBarHeight(),
243         toolBarDividerNode, GetToolBarDividerHeight());
244     toolBarNode->MarkModifyDone();
245     toolBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_CHILD);
246 }
247 
BarAnimationPropertyCallback(bool needRunTitleBarAnimation,bool hideTitle,bool needRunToolBarAnimation,bool hideTool)248 void NavDestinationPatternBase::BarAnimationPropertyCallback(
249     bool needRunTitleBarAnimation, bool hideTitle, bool needRunToolBarAnimation, bool hideTool)
250 {
251     auto node = AceType::DynamicCast<NavDestinationNodeBase>(GetHost());
252     CHECK_NULL_VOID(node);
253     auto property = node->GetLayoutProperty<NavDestinationLayoutPropertyBase>();
254     CHECK_NULL_VOID(property);
255     auto context = node->GetContext();
256     CHECK_NULL_VOID(context);
257     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(node->GetTitleBarNode());
258     auto toolBarNode = AceType::DynamicCast<NavToolbarNode>(node->GetToolBarNode());
259     auto toolBarDividerNode = AceType::DynamicCast<FrameNode>(node->GetToolBarDividerNode());
260     if (needRunTitleBarAnimation && titleBarNode) {
261         property->UpdateTitleBarTranslateState(hideTitle ?
262             BarTranslateState::TRANSLATE_HEIGHT : BarTranslateState::TRANSLATE_ZERO);
263     }
264     if (needRunToolBarAnimation && toolBarNode) {
265         property->UpdateToolBarTranslateState(hideTool ?
266             BarTranslateState::TRANSLATE_HEIGHT : BarTranslateState::TRANSLATE_ZERO);
267     }
268     node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
269     context->FlushUITasks();
270     if (needRunTitleBarAnimation && titleBarNode) {
271         UpdateTitleBarTranslateAndOpacity(hideTitle, titleBarNode, GetTitleBarHeight());
272     }
273     if (needRunToolBarAnimation && toolBarNode) {
274         UpdateToolBarAndDividerTranslateAndOpacity(hideTool, toolBarNode, GetToolBarHeight(),
275             toolBarDividerNode, GetToolBarDividerHeight());
276     }
277 }
278 
BarAnimationFinishCallback(bool needRunTitleBarAnimation,bool needRunToolBarAnimation,int32_t animationId)279 void NavDestinationPatternBase::BarAnimationFinishCallback(
280     bool needRunTitleBarAnimation, bool needRunToolBarAnimation, int32_t animationId)
281 {
282     if (needRunTitleBarAnimation) {
283         OnTitleBarAnimationFinish();
284     }
285     if (needRunToolBarAnimation) {
286         OnToolBarAnimationFinish();
287     }
288     RemoveAnimation(animationId);
289 }
290 
StartAnimation(bool needRunTitleBarAnimation,bool hideTitle,bool needRunToolBarAnimation,bool hideTool)291 void NavDestinationPatternBase::StartAnimation(
292     bool needRunTitleBarAnimation, bool hideTitle, bool needRunToolBarAnimation, bool hideTool)
293 {
294     auto propertyCallback = [needRunTitleBarAnimation, hideTitle, needRunToolBarAnimation, hideTool,
295                                 weakPattern = AceType::WeakClaim(this)]() {
296         auto pattern = weakPattern.Upgrade();
297         CHECK_NULL_VOID(pattern);
298         pattern->BarAnimationPropertyCallback(needRunTitleBarAnimation, hideTitle, needRunToolBarAnimation, hideTool);
299     };
300     auto finishCallback = [needRunTitleBarAnimation, needRunToolBarAnimation,
301                               weakPattern = AceType::WeakClaim(this), animationId = nextBarAnimationId_]() {
302         auto pattern = weakPattern.Upgrade();
303         CHECK_NULL_VOID(pattern);
304         pattern->BarAnimationFinishCallback(needRunTitleBarAnimation, needRunToolBarAnimation, animationId);
305     };
306 
307     AnimationOption option;
308     option.SetCurve(Curves::FAST_OUT_SLOW_IN);
309     option.SetDuration(DEFAULT_ANIMATION_DURATION);
310     if (needRunTitleBarAnimation) {
311         OnTitleBarAnimationStart();
312     }
313     if (needRunToolBarAnimation) {
314         OnToolBarAnimationStart();
315     }
316     auto hostNode = GetHost();
317     CHECK_NULL_VOID(hostNode);
318     auto animation = AnimationUtils::StartAnimation(
319         option, propertyCallback, finishCallback, nullptr /* repeatCallback */, hostNode->GetContextRefPtr());
320     barAnimations_.emplace(nextBarAnimationId_, animation);
321     nextBarAnimationId_++;
322 }
323 
OnTitleBarAnimationFinish()324 void NavDestinationPatternBase::OnTitleBarAnimationFinish()
325 {
326     titleBarAnimationCount_--;
327     if (titleBarAnimationCount_ > 0) {
328         return;
329     }
330 
331     auto node = AceType::DynamicCast<NavDestinationNodeBase>(GetHost());
332     CHECK_NULL_VOID(node);
333     auto property = node->GetLayoutProperty<NavDestinationLayoutPropertyBase>();
334     CHECK_NULL_VOID(property);
335     property->ResetTitleBarTranslateState();
336     HideOrShowTitleBarImmediately(node, property->GetHideTitleBarValue(false));
337 }
338 
OnToolBarAnimationFinish()339 void NavDestinationPatternBase::OnToolBarAnimationFinish()
340 {
341     toolBarAnimationCount_--;
342     if (toolBarAnimationCount_ > 0) {
343         return;
344     }
345 
346     auto node = AceType::DynamicCast<NavDestinationNodeBase>(GetHost());
347     CHECK_NULL_VOID(node);
348     auto property = node->GetLayoutProperty<NavDestinationLayoutPropertyBase>();
349     CHECK_NULL_VOID(property);
350     property->ResetToolBarTranslateState();
351     HideOrShowToolBarImmediately(node, property->GetHideToolBarValue(false));
352 }
353 
AbortBarAnimation()354 void NavDestinationPatternBase::AbortBarAnimation()
355 {
356     auto barAnimations = barAnimations_;
357     for (const auto& pair : barAnimations) {
358         if (pair.second) {
359             AnimationUtils::StopAnimation(pair.second);
360         }
361     }
362     barAnimations_.clear();
363 }
364 
RemoveAnimation(int32_t id)365 void NavDestinationPatternBase::RemoveAnimation(int32_t id)
366 {
367     auto it = barAnimations_.find(id);
368     if (it != barAnimations_.end()) {
369         barAnimations_.erase(it);
370     }
371 }
372 
UpdateHideBarProperty()373 void NavDestinationPatternBase::UpdateHideBarProperty()
374 {
375     auto hostNode = GetHost();
376     CHECK_NULL_VOID(hostNode);
377     auto layoutProperty = hostNode->GetLayoutProperty<NavDestinationLayoutPropertyBase>();
378     CHECK_NULL_VOID(layoutProperty);
379     /**
380      *  Mark need update safeAreaPadding when usr-set visibility of safe-area-padding-mode titleBar changed.
381      *  The same goes for toolBar.
382      */
383     if ((titleBarStyle_.value_or(BarStyle::STANDARD) == BarStyle::SAFE_AREA_PADDING &&
384         isHideTitlebar_ != layoutProperty->GetHideTitleBarValue(false)) ||
385         (toolBarStyle_.value_or(BarStyle::STANDARD) == BarStyle::SAFE_AREA_PADDING &&
386         isHideToolbar_ != layoutProperty->GetHideToolBarValue(false))) {
387         safeAreaPaddingChanged_ = true;
388     }
389     isHideToolbar_ = layoutProperty->GetHideToolBarValue(false);
390     isHideTitlebar_ = layoutProperty->GetHideTitleBarValue(false);
391 }
392 
ExpandContentSafeAreaIfNeeded()393 void NavDestinationPatternBase::ExpandContentSafeAreaIfNeeded()
394 {
395     auto hostNode = DynamicCast<NavDestinationNodeBase>(GetHost());
396     CHECK_NULL_VOID(hostNode);
397     auto layoutProperty = hostNode->GetLayoutProperty<NavDestinationLayoutPropertyBase>();
398     CHECK_NULL_VOID(layoutProperty);
399     auto&& opts = layoutProperty->GetSafeAreaExpandOpts();
400     auto contentNode = AceType::DynamicCast<FrameNode>(hostNode->GetContentNode());
401     if (opts && contentNode) {
402         contentNode->GetLayoutProperty()->UpdateSafeAreaExpandOpts(*opts);
403         contentNode->MarkModifyDone();
404     }
405 }
406 
MarkSafeAreaPaddingChangedWithCheckTitleBar(float titleBarHeight)407 void NavDestinationPatternBase::MarkSafeAreaPaddingChangedWithCheckTitleBar(float titleBarHeight)
408 {
409     auto hostNode = DynamicCast<NavDestinationNodeBase>(GetHost());
410     CHECK_NULL_VOID(hostNode);
411     if (titleBarStyle_.value_or(BarStyle::STANDARD) != BarStyle::SAFE_AREA_PADDING) {
412         return;
413     }
414     /**
415      *  Mark need update safeAreaPadding when the height of safe-area-padding-title changed.
416      *  For example, when titleMode of navigation changed or when free-mode-title is dragged.
417      */
418     if (!NearEqual(titleBarHeight, titleBarHeight_)) {
419         safeAreaPaddingChanged_ = true;
420         return;
421     }
422     /**
423      *  Mark need update safeAreaPadding when titleBar onHover mode updated.
424      */
425     auto titleBarNode = AceType::DynamicCast<TitleBarNode>(hostNode->GetTitleBarNode());
426     if (titleBarNode && NavigationTitleUtil::CalculateTitlebarOffset(titleBarNode) != titleBarOffsetY_) {
427         safeAreaPaddingChanged_ = true;
428     }
429 }
430 
CustomizeExpandSafeArea()431 bool NavDestinationPatternBase::CustomizeExpandSafeArea()
432 {
433     auto host = AceType::DynamicCast<NavDestinationNodeBase>(GetHost());
434     CHECK_NULL_RETURN(host, false);
435     return host->CustomizeExpandSafeArea();
436 }
437 
OnColorConfigurationUpdate()438 void NavDestinationPatternBase::OnColorConfigurationUpdate()
439 {
440     auto node = AceType::DynamicCast<NavDestinationNodeBase>(GetHost());
441     CHECK_NULL_VOID(node);
442     auto dividerNode = AceType::DynamicCast<FrameNode>(node->GetToolBarDividerNode());
443     CHECK_NULL_VOID(dividerNode);
444     auto dividerRenderProperty = dividerNode->GetPaintProperty<DividerRenderProperty>();
445     CHECK_NULL_VOID(dividerRenderProperty);
446     auto theme = NavigationGetTheme();
447     CHECK_NULL_VOID(theme);
448     dividerRenderProperty->UpdateDividerColor(theme->GetToolBarDividerColor());
449 }
450 
InitOnTouchEvent(const RefPtr<FrameNode> & host)451 void NavDestinationPatternBase::InitOnTouchEvent(const RefPtr<FrameNode>& host)
452 {
453     CHECK_NULL_VOID(host);
454     auto context = host->GetContext();
455     CHECK_NULL_VOID(context);
456     auto navManager = context->GetNavigationManager();
457     CHECK_NULL_VOID(navManager);
458     if (touchListener_ || !navManager->IsForceSplitSupported()) {
459         return;
460     }
461     auto gesture = host->GetOrCreateGestureEventHub();
462     CHECK_NULL_VOID(gesture);
463     auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo info) {
464         auto pattern = weak.Upgrade();
465         CHECK_NULL_VOID(pattern);
466         auto host = pattern->GetHost();
467         CHECK_NULL_VOID(host);
468         auto navNode = AceType::DynamicCast<NavigationGroupNode>(pattern->GetNavigationNode());
469         CHECK_NULL_VOID(navNode);
470         auto navPattern = navNode->GetPattern<NavigationPattern>();
471         CHECK_NULL_VOID(navPattern);
472         if (!navPattern->IsForceSplitSuccess()) {
473             return;
474         }
475         if (navPattern->IsForceSplitUseNavBar()) {
476             auto navBar = AceType::DynamicCast<NavBarNode>(host);
477             navPattern->SetIsHomeNodeTouched(navBar != nullptr);
478             return;
479         }
480         auto dest = AceType::DynamicCast<NavDestinationGroupNode>(host);
481         navPattern->SetIsHomeNodeTouched(dest && dest->GetNavDestinationType() == NavDestinationType::HOME);
482     };
483     touchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
484     gesture->AddTouchEvent(touchListener_);
485 }
486 
RemoveOnTouchEvent(FrameNode * frameNode)487 void NavDestinationPatternBase::RemoveOnTouchEvent(FrameNode* frameNode)
488 {
489     CHECK_NULL_VOID(frameNode);
490     auto context = frameNode->GetContext();
491     CHECK_NULL_VOID(context);
492     auto navManager = context->GetNavigationManager();
493     CHECK_NULL_VOID(navManager);
494     if (!touchListener_ || !navManager->IsForceSplitSupported()) {
495         return;
496     }
497     auto gesture = frameNode->GetOrCreateGestureEventHub();
498     CHECK_NULL_VOID(gesture);
499     gesture->RemoveTouchEvent(touchListener_);
500     touchListener_ = nullptr;
501 }
502 } // namespace OHOS::Ace::NG