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