1 /*
2 * Copyright (c) 2022 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/title_bar_pattern.h"
17
18 #include <sstream>
19
20 #include "base/i18n/localization.h"
21 #include "core/common/agingadapation/aging_adapation_dialog_theme.h"
22 #include "core/common/agingadapation/aging_adapation_dialog_util.h"
23 #include "core/components/button/button_theme.h"
24 #include "core/components_ng/pattern/navigation/nav_bar_node.h"
25 #include "core/components_ng/pattern/navigation/navigation_declaration.h"
26 #include "core/components_ng/pattern/navigation/navigation_group_node.h"
27 #include "core/components_ng/pattern/navigation/navigation_layout_util.h"
28 #include "core/components_ng/pattern/navigation/navigation_title_util.h"
29 #include "core/components_ng/pattern/navigation/title_bar_layout_property.h"
30 #include "core/components_ng/pattern/navigation/title_bar_node.h"
31 #include "core/components_ng/pattern/text/text_layout_property.h"
32 #include "core/components_ng/pattern/text/text_pattern.h"
33 #include "core/components_v2/inspector/utils.h"
34
35 namespace OHOS::Ace::NG {
36 namespace {
37 constexpr int32_t DEFAULT_ANIMATION_DURATION = 200;
38 constexpr int32_t TITLE_RATIO = 2;
39
TextLayoutPropertyToString(const RefPtr<TextLayoutProperty> & property)40 std::string TextLayoutPropertyToString(const RefPtr<TextLayoutProperty>& property)
41 {
42 CHECK_NULL_RETURN(property, "");
43 std::stringstream ss;
44 auto fontSize = property->GetFontSize();
45 ss << "FontSize: " << (fontSize.has_value() ? fontSize.value().ToString() : "NA") << ", ";
46
47 auto adaptMinFontSize = property->GetAdaptMinFontSize();
48 ss << "AdaptMinFontSize: " << (adaptMinFontSize.has_value() ? adaptMinFontSize.value().ToString() : "NA") << ", ";
49
50 auto adaptMaxFontSize = property->GetAdaptMaxFontSize();
51 ss << "AdaptMaxFontSize: " << (adaptMaxFontSize.has_value() ? adaptMaxFontSize.value().ToString() : "NA") << ", ";
52
53 auto heightAdaptivePolicy = property->GetHeightAdaptivePolicy();
54 ss << "TextHeightAdaptivePolicy: " << (heightAdaptivePolicy.has_value() ?
55 V2::ConvertWrapTextHeightAdaptivePolicyToString(heightAdaptivePolicy.value()) : "NA") << ", ";
56
57 auto textColor = property->GetTextColor();
58 ss << "TextColor: " << (textColor.has_value() ? textColor.value().ToString() : "NA") << ", ";
59
60 auto fontWeight = property->GetFontWeight();
61 ss << "fontWeight: " << (fontWeight.has_value() ?
62 V2::ConvertWrapFontWeightToStirng(fontWeight.value()) :"NA") << ", ";
63
64 auto textShadow = property->GetTextShadow();
65 ss << "TextShadow: " << (textShadow.has_value() ? "hasValue" : "NA") << ", ";
66
67 auto maxLines = property->GetMaxLines();
68 ss << "MaxLines: " << (maxLines.has_value() ? std::to_string(maxLines.value()) : "NA");
69
70 return ss.str();
71 }
72
DumpTitleProperty(const RefPtr<TextLayoutProperty> & property,bool isMainTitle)73 void DumpTitleProperty(const RefPtr<TextLayoutProperty>& property, bool isMainTitle)
74 {
75 std::string info;
76 if (isMainTitle) {
77 info.append("MainTitle: ");
78 } else {
79 info.append("SubTitle: ");
80 }
81 info.append(TextLayoutPropertyToString(property));
82 DumpLog::GetInstance().AddDesc(info);
83 }
84
SetTextColor(const RefPtr<FrameNode> & textNode,const Color & color)85 void SetTextColor(const RefPtr<FrameNode>& textNode, const Color& color)
86 {
87 CHECK_NULL_VOID(textNode);
88 auto textPattern = textNode->GetPattern<TextPattern>();
89 CHECK_NULL_VOID(textPattern);
90 auto property = textNode->GetLayoutPropertyPtr<TextLayoutProperty>();
91 CHECK_NULL_VOID(property);
92 property->UpdateTextColor(color);
93 ACE_UPDATE_NODE_RENDER_CONTEXT(ForegroundColor, color, textNode);
94 ACE_RESET_NODE_RENDER_CONTEXT(RenderContext, ForegroundColorStrategy, textNode);
95 ACE_UPDATE_NODE_RENDER_CONTEXT(ForegroundColorFlag, true, textNode);
96 }
97
SetImageSourceInfoFillColor(ImageSourceInfo & imageSourceInfo)98 void SetImageSourceInfoFillColor(ImageSourceInfo& imageSourceInfo)
99 {
100 auto theme = NavigationGetTheme();
101 if (theme) {
102 imageSourceInfo.SetFillColor(theme->GetIconColor());
103 }
104 }
105
SetBackButtonImgAboveVersionTen(const RefPtr<FrameNode> & backButtonNode,const RefPtr<TitleBarLayoutProperty> & titleBarLayoutProperty,RefPtr<ImageLayoutProperty> & backButtonImageLayoutProperty)106 void SetBackButtonImgAboveVersionTen(const RefPtr<FrameNode>& backButtonNode,
107 const RefPtr<TitleBarLayoutProperty>& titleBarLayoutProperty,
108 RefPtr<ImageLayoutProperty>& backButtonImageLayoutProperty)
109 {
110 // API >= 10
111 if (!backButtonNode || !titleBarLayoutProperty || !backButtonImageLayoutProperty) {
112 return;
113 }
114 if (titleBarLayoutProperty->HasPixelMap() && titleBarLayoutProperty->GetPixelMapValue() != nullptr) {
115 auto pixelMap = titleBarLayoutProperty->GetPixelMapValue();
116 ImageSourceInfo imageSourceInfo = ImageSourceInfo(pixelMap);
117 SetImageSourceInfoFillColor(imageSourceInfo);
118 backButtonImageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
119 backButtonNode->MarkModifyDone();
120 return;
121 }
122
123 ImageSourceInfo imageSourceInfo = titleBarLayoutProperty->GetImageSourceValue();
124 SetImageSourceInfoFillColor(imageSourceInfo);
125 backButtonImageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
126 backButtonNode->MarkModifyDone();
127 }
128
SetBackButtonImgBelowVersionTen(const RefPtr<FrameNode> & backButtonNode,const RefPtr<TitleBarLayoutProperty> & titleBarLayoutProperty,RefPtr<ImageLayoutProperty> & backButtonImageLayoutProperty)129 void SetBackButtonImgBelowVersionTen(const RefPtr<FrameNode>& backButtonNode,
130 const RefPtr<TitleBarLayoutProperty>& titleBarLayoutProperty,
131 RefPtr<ImageLayoutProperty>& backButtonImageLayoutProperty)
132 {
133 // API < 10
134 if (!backButtonNode || !titleBarLayoutProperty || !backButtonImageLayoutProperty) {
135 return;
136 }
137 ImageSourceInfo imageSourceInfo = titleBarLayoutProperty->GetImageSourceValue();
138 SetImageSourceInfoFillColor(imageSourceInfo);
139 backButtonImageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
140 backButtonNode->MarkModifyDone();
141 }
142
HandleDefaultIconForNavDestination(const RefPtr<TitleBarNode> & hostNode,const RefPtr<FrameNode> & backButtonImageNode)143 void HandleDefaultIconForNavDestination(
144 const RefPtr<TitleBarNode>& hostNode, const RefPtr<FrameNode>& backButtonImageNode)
145 {
146 auto navDestinationNode = AceType::DynamicCast<FrameNode>(hostNode->GetParent());
147 CHECK_NULL_VOID(navDestinationNode);
148 auto theme = NavigationGetTheme();
149 CHECK_NULL_VOID(theme);
150 auto navDestinationEventHub = navDestinationNode->GetOrCreateEventHub<EventHub>();
151 CHECK_NULL_VOID(navDestinationEventHub);
152 auto paintProperty = backButtonImageNode->GetPaintProperty<ImageRenderProperty>();
153 CHECK_NULL_VOID(paintProperty);
154 // If use defalut icon, need to set fill-color
155 if (!navDestinationEventHub->IsEnabled()) {
156 paintProperty->UpdateSvgFillColor(theme->GetBackButtonIconColor().BlendOpacity(theme->GetAlphaDisabled()));
157 } else {
158 paintProperty->UpdateSvgFillColor(theme->GetBackButtonIconColor());
159 }
160 backButtonImageNode->MarkModifyDone();
161 }
162
IsImageBackIcon(const RefPtr<TitleBarLayoutProperty> & titleBarLayoutProperty)163 bool IsImageBackIcon(const RefPtr<TitleBarLayoutProperty>& titleBarLayoutProperty)
164 {
165 CHECK_NULL_RETURN(titleBarLayoutProperty, false);
166 if (titleBarLayoutProperty->HasIsValidImage() && titleBarLayoutProperty->GetIsValidImageValue()) {
167 return true;
168 }
169
170 return false;
171 }
172
ApplyImageSourceInfo(const RefPtr<FrameNode> & backButtonNode,const RefPtr<TitleBarLayoutProperty> & titleBarLayoutProperty,RefPtr<ImageLayoutProperty> & backButtonImageLayoutProperty)173 void ApplyImageSourceInfo(const RefPtr<FrameNode>& backButtonNode,
174 const RefPtr<TitleBarLayoutProperty>& titleBarLayoutProperty,
175 RefPtr<ImageLayoutProperty>& backButtonImageLayoutProperty)
176 {
177 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
178 SetBackButtonImgBelowVersionTen(backButtonNode, titleBarLayoutProperty, backButtonImageLayoutProperty);
179 } else {
180 SetBackButtonImgAboveVersionTen(backButtonNode, titleBarLayoutProperty, backButtonImageLayoutProperty);
181 }
182 }
183
ApplyThemeIconSize(RefPtr<TextLayoutProperty> & symbolProperty)184 void ApplyThemeIconSize(RefPtr<TextLayoutProperty>& symbolProperty)
185 {
186 CHECK_NULL_VOID(symbolProperty);
187 auto theme = NavigationGetTheme();
188 if (theme) {
189 symbolProperty->UpdateFontSize(theme->GetIconWidth());
190 }
191 }
192
UpdateSymbolEffect(RefPtr<TextLayoutProperty> symbolProperty,bool isActive)193 void UpdateSymbolEffect(RefPtr<TextLayoutProperty> symbolProperty, bool isActive)
194 {
195 CHECK_NULL_VOID(symbolProperty);
196 auto symbolEffectOptions = SymbolEffectOptions(SymbolEffectType::BOUNCE);
197 symbolEffectOptions.SetIsTxtActive(isActive);
198 symbolEffectOptions.SetIsTxtActiveSource(0);
199 symbolProperty->UpdateSymbolEffectOptions(symbolEffectOptions);
200 }
201
UpdateSymbolBackButton(const RefPtr<TitleBarNode> & hostNode,const RefPtr<FrameNode> & backButtonNode,const RefPtr<FrameNode> & backButtonIconNode,const RefPtr<TitleBarLayoutProperty> & titleBarLayoutProperty)202 void UpdateSymbolBackButton(const RefPtr<TitleBarNode>& hostNode, const RefPtr<FrameNode>& backButtonNode,
203 const RefPtr<FrameNode>& backButtonIconNode, const RefPtr<TitleBarLayoutProperty>& titleBarLayoutProperty)
204 {
205 CHECK_NULL_VOID(hostNode);
206 auto theme = NavigationGetTheme(hostNode->GetThemeScopeId());
207 auto backIconSymbol = titleBarLayoutProperty->GetBackIconSymbol();
208 if (backIconSymbol != nullptr) {
209 // symbol -> symbol
210 auto symbolProperty = backButtonIconNode->GetLayoutProperty<TextLayoutProperty>();
211 CHECK_NULL_VOID(symbolProperty);
212 symbolProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
213 if (theme) {
214 symbolProperty->UpdateSymbolColorList({ theme->GetIconColor() });
215 }
216 // User-defined color overrides the default color of the theme
217 backIconSymbol(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(backButtonIconNode)));
218 ApplyThemeIconSize(symbolProperty);
219 UpdateSymbolEffect(symbolProperty, false);
220 backButtonIconNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
221 } else if (IsImageBackIcon(titleBarLayoutProperty)) {
222 // symbol -> image
223 auto backButtonImageNode = FrameNode::CreateFrameNode(V2::BACK_BUTTON_IMAGE_ETS_TAG,
224 ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
225 CHECK_NULL_VOID(backButtonImageNode);
226
227 auto backButtonImageLayoutProperty = backButtonImageNode->GetLayoutProperty<ImageLayoutProperty>();
228 CHECK_NULL_VOID(backButtonImageLayoutProperty);
229 backButtonImageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
230 ApplyImageSourceInfo(backButtonNode, titleBarLayoutProperty, backButtonImageLayoutProperty);
231 backButtonImageNode->MountToParent(backButtonNode);
232 backButtonNode->RemoveChild(backButtonIconNode);
233 backButtonImageNode->MarkModifyDone();
234 } else {
235 auto symbolProperty = backButtonIconNode->GetLayoutProperty<TextLayoutProperty>();
236 CHECK_NULL_VOID(symbolProperty);
237 if (theme) {
238 symbolProperty->UpdateSymbolSourceInfo(SymbolSourceInfo(theme->GetBackSymbolId()));
239 symbolProperty->UpdateSymbolColorList({ theme->GetBackButtonIconColor() });
240 symbolProperty->UpdateFontSize(theme->GetIconWidth());
241 }
242 backButtonIconNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
243 }
244 }
245
CreateDefaultBackButton(const RefPtr<FrameNode> & backButtonNode,const RefPtr<FrameNode> & backButtonIconNode)246 void CreateDefaultBackButton(const RefPtr<FrameNode>& backButtonNode, const RefPtr<FrameNode>& backButtonIconNode)
247 {
248 auto theme = NavigationGetTheme();
249 CHECK_NULL_VOID(theme);
250 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
251 SystemProperties::IsNeedSymbol()) {
252 backButtonNode->RemoveChild(backButtonIconNode);
253 auto symbolNode = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
254 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
255 CHECK_NULL_VOID(symbolNode);
256 auto symbolProperty = symbolNode->GetLayoutProperty<TextLayoutProperty>();
257 CHECK_NULL_VOID(symbolProperty);
258 symbolProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
259 auto iconColor = theme->GetIconColor();
260 symbolProperty->UpdateSymbolColorList({ iconColor });
261 symbolProperty->UpdateSymbolSourceInfo(SymbolSourceInfo(theme->GetBackSymbolId()));
262 symbolProperty->UpdateFontSize(theme->GetIconWidth());
263 symbolNode->MountToParent(backButtonNode);
264 symbolNode->MarkDirtyNode();
265 symbolNode->MarkModifyDone();
266 } else {
267 auto backButtonImageLayoutProperty = backButtonIconNode->GetLayoutProperty<ImageLayoutProperty>();
268 CHECK_NULL_VOID(backButtonImageLayoutProperty);
269
270 ImageSourceInfo imageSourceInfo;
271 imageSourceInfo.SetResourceId(theme->GetBackResourceId());
272 imageSourceInfo.SetFillColor(theme->GetBackButtonIconColor());
273 backButtonImageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
274 backButtonImageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
275 backButtonIconNode->MarkModifyDone();
276 }
277 }
278
UpdateImageBackButton(const RefPtr<FrameNode> & backButtonNode,const RefPtr<FrameNode> & backButtonIconNode,const RefPtr<TitleBarLayoutProperty> & titleBarLayoutProperty)279 void UpdateImageBackButton(const RefPtr<FrameNode>& backButtonNode, const RefPtr<FrameNode>& backButtonIconNode,
280 const RefPtr<TitleBarLayoutProperty>& titleBarLayoutProperty)
281 {
282 auto backIconSymbol = titleBarLayoutProperty->GetBackIconSymbol();
283 auto theme = NavigationGetTheme();
284 if (backIconSymbol != nullptr) {
285 // image -> symbol
286 backButtonNode->RemoveChild(backButtonIconNode);
287 auto symbolNode = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
288 ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
289 CHECK_NULL_VOID(symbolNode);
290 auto symbolProperty = symbolNode->GetLayoutProperty<TextLayoutProperty>();
291 CHECK_NULL_VOID(symbolProperty);
292 symbolProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
293 if (theme) {
294 symbolProperty->UpdateSymbolColorList({ theme->GetIconColor() });
295 }
296 backIconSymbol(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(symbolNode)));
297 ApplyThemeIconSize(symbolProperty);
298 UpdateSymbolEffect(symbolProperty, false);
299 symbolNode->MountToParent(backButtonNode);
300 symbolNode->MarkDirtyNode();
301 symbolNode->MarkModifyDone();
302 } else if (IsImageBackIcon(titleBarLayoutProperty)) {
303 // image -> image
304 auto backButtonImageNode = FrameNode::CreateFrameNode(V2::BACK_BUTTON_IMAGE_ETS_TAG,
305 ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
306 CHECK_NULL_VOID(backButtonImageNode);
307 ImageSourceInfo imageSourceInfo = titleBarLayoutProperty->GetImageSourceValue();
308 auto backButtonImageLayoutProperty = backButtonImageNode->GetLayoutProperty<ImageLayoutProperty>();
309 CHECK_NULL_VOID(backButtonImageLayoutProperty);
310 backButtonImageLayoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
311 ApplyImageSourceInfo(backButtonNode, titleBarLayoutProperty, backButtonImageLayoutProperty);
312 backButtonImageNode->MountToParent(backButtonNode);
313 backButtonNode->RemoveChild(backButtonIconNode);
314 backButtonImageNode->MarkModifyDone();
315 } else {
316 CreateDefaultBackButton(backButtonNode, backButtonIconNode);
317 }
318 }
319
MountBackButton(const RefPtr<TitleBarNode> & hostNode)320 void MountBackButton(const RefPtr<TitleBarNode>& hostNode)
321 {
322 auto theme = NavigationGetTheme();
323 CHECK_NULL_VOID(theme);
324 auto titleBarLayoutProperty = hostNode->GetLayoutProperty<TitleBarLayoutProperty>();
325 CHECK_NULL_VOID(titleBarLayoutProperty);
326 auto backButtonNode = AceType::DynamicCast<FrameNode>(hostNode->GetBackButton());
327 CHECK_NULL_VOID(backButtonNode);
328 auto backButtonIconNode = AceType::DynamicCast<FrameNode>(backButtonNode->GetChildren().front());
329 CHECK_NULL_VOID(backButtonIconNode);
330 auto parentType = titleBarLayoutProperty->GetTitleBarParentTypeValue(TitleBarParentType::NAVBAR);
331 if (backButtonIconNode->GetTag() == V2::SYMBOL_ETS_TAG) {
332 UpdateSymbolBackButton(hostNode, backButtonNode, backButtonIconNode, titleBarLayoutProperty);
333 } else {
334 UpdateImageBackButton(backButtonNode, backButtonIconNode, titleBarLayoutProperty);
335 }
336 std::string parentId = hostNode->GetInnerParentId();
337 if (parentType == TitleBarParentType::NAVBAR) {
338 auto navBarNode = AceType::DynamicCast<FrameNode>(hostNode->GetParent());
339 CHECK_NULL_VOID(navBarNode);
340 auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
341 CHECK_NULL_VOID(navBarLayoutProperty);
342 auto hideBackButton = navBarLayoutProperty->GetHideBackButtonValue(false);
343 auto backButtonLayoutProperty = AceType::DynamicCast<FrameNode>(backButtonNode)->GetLayoutProperty();
344 CHECK_NULL_VOID(backButtonLayoutProperty);
345 backButtonLayoutProperty->UpdateVisibility(hideBackButton ? VisibleType::GONE : VisibleType::VISIBLE);
346 backButtonNode->SetJSViewActive(hideBackButton ? false : true);
347
348 // set navigation titleBar backButton inspectorId
349 NavigationTitleUtil::SetInnerChildId(backButtonNode, NG::NAV_FIELD,
350 backButtonNode->GetTag(), "Back", parentId);
351 backButtonNode->MarkModifyDone();
352 return;
353 }
354
355 // set navdestination titleBar backButton inspectorId
356 NavigationTitleUtil::SetInnerChildId(backButtonNode, NG::DES_FIELD,
357 backButtonNode->GetTag(), "Back", parentId);
358 if (!titleBarLayoutProperty->HasNoPixMap()) {
359 if (parentType == TitleBarParentType::NAV_DESTINATION) {
360 HandleDefaultIconForNavDestination(hostNode, backButtonIconNode);
361 }
362 backButtonNode->MarkModifyDone();
363 return;
364 }
365 }
366
SetBackgroundBlurStyle(RefPtr<FrameNode> & host,const BlurStyleOption & bgBlurStyle)367 void SetBackgroundBlurStyle(RefPtr<FrameNode>& host, const BlurStyleOption& bgBlurStyle)
368 {
369 CHECK_NULL_VOID(host);
370 auto pipeline = host->GetContext();
371 CHECK_NULL_VOID(pipeline);
372 if (bgBlurStyle.policy == BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) {
373 pipeline->AddWindowFocusChangedCallback(host->GetId());
374 } else {
375 pipeline->RemoveWindowFocusChangedCallback(host->GetId());
376 }
377 auto renderContext = host->GetRenderContext();
378 if (renderContext) {
379 if (renderContext->GetBackgroundEffect().has_value()) {
380 renderContext->UpdateBackgroundEffect(std::nullopt);
381 }
382 renderContext->UpdateBackBlurStyle(bgBlurStyle);
383 if (renderContext->GetBackBlurRadius().has_value()) {
384 renderContext->UpdateBackBlurRadius(Dimension());
385 }
386 }
387 }
388
SetBackgroundEffect(RefPtr<FrameNode> & host,const EffectOption & effectOption)389 void SetBackgroundEffect(RefPtr<FrameNode>& host, const EffectOption &effectOption)
390 {
391 CHECK_NULL_VOID(host);
392 auto pipeline = host->GetContext();
393 CHECK_NULL_VOID(pipeline);
394 if (effectOption.policy == BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) {
395 pipeline->AddWindowFocusChangedCallback(host->GetId());
396 } else {
397 pipeline->RemoveWindowFocusChangedCallback(host->GetId());
398 }
399 auto renderContext = host->GetRenderContext();
400 if (renderContext) {
401 if (renderContext->GetBackBlurRadius().has_value()) {
402 renderContext->UpdateBackBlurRadius(Dimension());
403 }
404 if (renderContext->GetBackBlurStyle().has_value()) {
405 renderContext->UpdateBackBlurStyle(std::nullopt);
406 }
407 renderContext->UpdateBackgroundEffect(effectOption);
408 }
409 }
410 } // namespace
411
MountSubTitle(const RefPtr<TitleBarNode> & hostNode)412 void TitleBarPattern::MountSubTitle(const RefPtr<TitleBarNode>& hostNode)
413 {
414 CHECK_NULL_VOID(hostNode);
415 auto titleBarLayoutProperty = hostNode->GetLayoutProperty<TitleBarLayoutProperty>();
416 CHECK_NULL_VOID(titleBarLayoutProperty);
417 auto subtitleNode = AceType::DynamicCast<FrameNode>(hostNode->GetSubtitle());
418 CHECK_NULL_VOID(subtitleNode);
419
420 // set titleBar subTitle inspectorId
421 auto parentType = titleBarLayoutProperty->GetTitleBarParentTypeValue(TitleBarParentType::NAVBAR);
422 std::string field = NG::NAV_FIELD;
423 if (parentType == TitleBarParentType::NAV_DESTINATION) {
424 field = NG::DES_FIELD;
425 }
426 NavigationTitleUtil::SetInnerChildId(subtitleNode, field, subtitleNode->GetTag(),
427 "SubTitle", hostNode->GetInnerParentId());
428
429 if (options_.textOptions.subTitleApplyFunc || shouldResetSubTitleProperty_) {
430 auto titleMode = titleBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE);
431 ResetSubTitleProperty(subtitleNode, titleMode, parentType == TitleBarParentType::NAV_DESTINATION);
432 shouldResetSubTitleProperty_ = false;
433 }
434
435 subtitleNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
436 subtitleNode->MarkModifyDone();
437 }
438
InitTitleParam()439 void TitleBarPattern::InitTitleParam()
440 {
441 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
442 CHECK_NULL_VOID(titleBarNode);
443 if (titleBarNode->GetSubtitle()) {
444 tempTitleBarHeight_.SetValue(FULL_DOUBLE_LINE_TITLEBAR_HEIGHT.Value());
445 } else {
446 tempTitleBarHeight_.SetValue(FULL_SINGLE_LINE_TITLEBAR_HEIGHT.Value());
447 }
448 overDragOffset_ = 0.0f;
449 tempTitleOffsetY_ = 0.0f;
450 fontSize_.reset();
451 opacity_.reset();
452 isFreeTitleUpdated_ = false;
453 auto theme = NavigationGetTheme();
454 CHECK_NULL_VOID(theme);
455 titleSpaceVertical_ = theme->GetTitleSpaceVertical();
456 }
457
IsHidden()458 bool TitleBarPattern::IsHidden()
459 {
460 auto host = GetHost();
461 CHECK_NULL_RETURN(host, false);
462 auto navBarNode = AceType::DynamicCast<NavBarNode>(host->GetParent());
463 CHECK_NULL_RETURN(navBarNode, false);
464 auto navBarLayoutProperty = navBarNode->GetLayoutProperty<NavBarLayoutProperty>();
465 CHECK_NULL_RETURN(navBarLayoutProperty, false);
466 return navBarLayoutProperty->GetHideTitleBar().value_or(false);
467 }
468
UpdateNavBarTitleProperty(const RefPtr<TitleBarNode> & hostNode)469 void TitleBarPattern::UpdateNavBarTitleProperty(const RefPtr<TitleBarNode>& hostNode)
470 {
471 auto titleNode = AceType::DynamicCast<FrameNode>(hostNode->GetTitle());
472 CHECK_NULL_VOID(titleNode);
473 auto navBarNode = AceType::DynamicCast<NavBarNode>(hostNode->GetParent());
474 CHECK_NULL_VOID(navBarNode);
475 auto titleBarLayoutProperty = hostNode->GetLayoutProperty<TitleBarLayoutProperty>();
476 CHECK_NULL_VOID(titleBarLayoutProperty);
477
478 // if title node is custom node markModifyDone and return
479 if (navBarNode->GetPrevTitleIsCustomValue(false)) {
480 titleNode->MarkModifyDone();
481 return;
482 }
483
484 // set navbar titleBar main title inspectorId
485 NavigationTitleUtil::SetInnerChildId(titleNode, NG::NAV_FIELD, titleNode->GetTag(),
486 "MainTitle", hostNode->GetInnerParentId());
487
488 // update main title layout property
489 if (options_.textOptions.mainTitleApplyFunc || shouldResetMainTitleProperty_) {
490 auto titleMode = titleBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE);
491 ResetMainTitleProperty(titleNode, titleBarLayoutProperty, titleMode, hostNode->GetSubtitle() != nullptr, false);
492 shouldResetMainTitleProperty_ = false;
493 }
494
495 titleNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
496 titleNode->MarkModifyDone();
497 }
498
UpdateNavDesTitleProperty(const RefPtr<TitleBarNode> & hostNode)499 void TitleBarPattern::UpdateNavDesTitleProperty(const RefPtr<TitleBarNode>& hostNode)
500 {
501 auto titleBarLayoutProperty = hostNode->GetLayoutProperty<TitleBarLayoutProperty>();
502 CHECK_NULL_VOID(titleBarLayoutProperty);
503 auto navDestinationGroupNode = AceType::DynamicCast<NavDestinationGroupNode>(hostNode->GetParent());
504 CHECK_NULL_VOID(navDestinationGroupNode);
505 auto titleNode = AceType::DynamicCast<FrameNode>(hostNode->GetTitle());
506 CHECK_NULL_VOID(titleNode);
507
508 // if navdestination titleBar main title is custom, just return
509 if (navDestinationGroupNode->GetPrevTitleIsCustomValue(false)) {
510 titleNode->MarkModifyDone();
511 return;
512 }
513 // if navdestination titleBar main title is not custom, set inspectorId
514 std::string parentId = hostNode->GetInnerParentId();
515 NavigationTitleUtil::SetInnerChildId(titleNode, NG::DES_FIELD, titleNode->GetTag(),
516 "MainTitle", parentId);
517
518 if (options_.textOptions.mainTitleApplyFunc || shouldResetMainTitleProperty_) {
519 auto titleMode = titleBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE);
520 ResetMainTitleProperty(titleNode, titleBarLayoutProperty, titleMode, hostNode->GetSubtitle() != nullptr, true);
521 shouldResetMainTitleProperty_ = false;
522 }
523
524 titleNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
525 titleNode->MarkModifyDone();
526 }
527
ResetMainTitleProperty(const RefPtr<FrameNode> & textNode,const RefPtr<TitleBarLayoutProperty> & titleBarLayoutProperty,NavigationTitleMode titleMode,bool hasSubTitle,bool parentIsNavDest)528 void TitleBarPattern::ResetMainTitleProperty(const RefPtr<FrameNode>& textNode,
529 const RefPtr<TitleBarLayoutProperty>& titleBarLayoutProperty,
530 NavigationTitleMode titleMode, bool hasSubTitle, bool parentIsNavDest)
531 {
532 // update main title layout property
533 auto titleLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
534 CHECK_NULL_VOID(titleLayoutProperty);
535
536 auto host = GetHost();
537 CHECK_NULL_VOID(host);
538
539 std::u16string contentStr;
540 if (titleLayoutProperty->HasContent()) {
541 contentStr = titleLayoutProperty->GetContentValue(std::u16string());
542 }
543 titleLayoutProperty->Reset();
544 titleLayoutProperty->UpdateContent(contentStr);
545
546 auto theme = NavigationGetTheme(host->GetThemeScopeId());
547 CHECK_NULL_VOID(theme);
548 auto titleFontSize = theme->GetTitleFontSizeBig();
549 auto maxFontSize = theme->GetTitleFontSizeBig();
550 auto miniTitleFontSize = theme->GetTitleFontSize();
551 auto miniTitleFontSizeMin = theme->GetTitleFontSizeMin();
552 auto textHeightAdaptivePolicy = TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST;
553 Color color = theme->GetTitleColor();
554 FontWeight mainTitleWeight = FontWeight::MEDIUM;
555 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
556 titleFontSize = theme->GetMainTitleFontSizeL();
557 maxFontSize = theme->GetMainTitleFontSizeL();
558 miniTitleFontSize = theme->GetMainTitleFontSizeM();
559 miniTitleFontSizeMin = theme->GetMainTitleFontSizeS();
560 textHeightAdaptivePolicy = hasSubTitle ? TextHeightAdaptivePolicy::MAX_LINES_FIRST :
561 TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST;
562 color = theme->GetMainTitleFontColor();
563 mainTitleWeight = FontWeight::BOLD;
564 }
565 SetTextColor(textNode, color);
566 titleLayoutProperty->UpdateFontWeight(mainTitleWeight);
567 titleLayoutProperty->UpdateMaxFontScale(STANDARD_FONT_SCALE);
568 titleLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
569 auto maxLines = hasSubTitle ? 1 : TITLEBAR_MAX_LINES;
570 titleLayoutProperty->UpdateMaxLines(maxLines);
571 titleLayoutProperty->UpdateAdaptMinFontSize(MIN_ADAPT_TITLE_FONT_SIZE);
572
573 if (!parentIsNavDest) {
574 titleLayoutProperty->UpdateHeightAdaptivePolicy(textHeightAdaptivePolicy);
575 }
576
577 if (parentIsNavDest) {
578 titleLayoutProperty->ResetFontSize();
579 titleLayoutProperty->UpdateAdaptMaxFontSize(miniTitleFontSizeMin);
580 titleLayoutProperty->UpdateHeightAdaptivePolicy(hasSubTitle ? TextHeightAdaptivePolicy::MAX_LINES_FIRST :
581 TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST);
582 } else if (titleMode == NavigationTitleMode::MINI) {
583 auto hideBackButtonValid = titleBarLayoutProperty->HasHideBackButton() &&
584 titleBarLayoutProperty->GetHideBackButtonValue();
585 titleLayoutProperty->UpdateFontSize(hideBackButtonValid ? miniTitleFontSize : miniTitleFontSizeMin);
586 titleLayoutProperty->UpdateAdaptMaxFontSize(hideBackButtonValid ? miniTitleFontSize : miniTitleFontSizeMin);
587 UpdateSubTitleOpacity(1.0);
588 } else if (titleMode == NavigationTitleMode::FULL) {
589 titleLayoutProperty->UpdateFontSize(titleFontSize);
590 titleLayoutProperty->UpdateAdaptMaxFontSize(maxFontSize);
591 UpdateSubTitleOpacity(1.0);
592 } else {
593 titleLayoutProperty->UpdateFontSize(fontSize_.has_value() ? fontSize_.value() : titleFontSize);
594 titleLayoutProperty->UpdateAdaptMaxFontSize(fontSize_.has_value() ? fontSize_.value() : maxFontSize);
595 UpdateSubTitleOpacity(opacity_.has_value() ? opacity_.value() : 1.0);
596 }
597 }
598
ResetSubTitleProperty(const RefPtr<FrameNode> & textNode,NavigationTitleMode titleMode,bool parentIsNavDest)599 void TitleBarPattern::ResetSubTitleProperty(const RefPtr<FrameNode>& textNode,
600 NavigationTitleMode titleMode, bool parentIsNavDest)
601 {
602 CHECK_NULL_VOID(textNode);
603 auto titleLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
604 CHECK_NULL_VOID(titleLayoutProperty);
605 auto host = GetHost();
606 CHECK_NULL_VOID(host);
607 std::u16string contentStr;
608 if (titleLayoutProperty->HasContent()) {
609 contentStr = titleLayoutProperty->GetContentValue(std::u16string());
610 }
611 titleLayoutProperty->Reset();
612 titleLayoutProperty->UpdateContent(contentStr);
613
614 auto theme = NavigationGetTheme(host->GetThemeScopeId());
615 CHECK_NULL_VOID(theme);
616 auto subTitleSize = theme->GetSubTitleFontSize();
617 Color color = theme->GetSubTitleColor();
618 auto textHeightAdaptivePolicy = TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST;
619 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
620 subTitleSize = theme->GetSubTitleFontSizeS();
621 color = theme->GetSubTitleFontColor();
622 textHeightAdaptivePolicy = TextHeightAdaptivePolicy::MAX_LINES_FIRST;
623 }
624 if (parentIsNavDest) {
625 titleLayoutProperty->UpdateHeightAdaptivePolicy(TextHeightAdaptivePolicy::MAX_LINES_FIRST);
626 } else if (titleMode == NavigationTitleMode::MINI) {
627 titleLayoutProperty->UpdateHeightAdaptivePolicy(textHeightAdaptivePolicy);
628 } else if (titleMode == NavigationTitleMode::FREE) {
629 UpdateSubTitleOpacity(opacity_.value_or(1.0f));
630 } else {
631 UpdateSubTitleOpacity(1.0);
632 }
633 titleLayoutProperty->UpdateAdaptMinFontSize(MIN_ADAPT_SUBTITLE_FONT_SIZE);
634 titleLayoutProperty->UpdateAdaptMaxFontSize(subTitleSize);
635 titleLayoutProperty->UpdateMaxFontScale(STANDARD_FONT_SCALE);
636 titleLayoutProperty->UpdateMaxLines(1);
637 titleLayoutProperty->UpdateFontWeight(FontWeight::REGULAR); // ohos_id_text_font_family_regular
638 titleLayoutProperty->UpdateFontSize(subTitleSize);
639 titleLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
640 SetTextColor(textNode, color);
641 }
642
MountTitle(const RefPtr<TitleBarNode> & hostNode)643 void TitleBarPattern::MountTitle(const RefPtr<TitleBarNode>& hostNode)
644 {
645 CHECK_NULL_VOID(hostNode);
646 UpdateNavDesTitleProperty(hostNode);
647 UpdateNavBarTitleProperty(hostNode);
648 }
649
CreateLayoutAlgorithm()650 RefPtr<LayoutAlgorithm> TitleBarPattern::CreateLayoutAlgorithm()
651 {
652 auto titleBarLayoutAlgorithm = MakeRefPtr<TitleBarLayoutAlgorithm>();
653 titleBarLayoutAlgorithm->SetInitialTitleOffsetY(initialTitleOffsetY_);
654 titleBarLayoutAlgorithm->MarkIsInitialTitle(isInitialTitle_);
655 titleBarLayoutAlgorithm->SetInitialSubtitleOffsetY(initialSubtitleOffsetY_);
656 titleBarLayoutAlgorithm->MarkIsInitialSubtitle(isInitialSubtitle_);
657 titleBarLayoutAlgorithm->SetMinTitleHeight(minTitleHeight_);
658 return titleBarLayoutAlgorithm;
659 }
660
OnModifyDone()661 void TitleBarPattern::OnModifyDone()
662 {
663 Pattern::OnModifyDone();
664 if (isInitialTitle_) {
665 InitTitleParam();
666 }
667 auto hostNode = AceType::DynamicCast<TitleBarNode>(GetHost());
668 CHECK_NULL_VOID(hostNode);
669 MountBackButton(hostNode);
670 MountTitle(hostNode);
671 MountSubTitle(hostNode);
672 ApplyTitleModifierIfNeeded(hostNode);
673 auto pipeline = hostNode->GetContext();
674 CHECK_NULL_VOID(pipeline);
675 if (GreatOrEqual(pipeline->GetFontScale(), AgingAdapationDialogUtil::GetDialogBigFontSizeScale())) {
676 auto backButtonNode = AceType::DynamicCast<FrameNode>(hostNode->GetBackButton());
677 CHECK_NULL_VOID(backButtonNode);
678 InitBackButtonLongPressEvent(backButtonNode);
679 }
680 if (options_.enableHoverMode && currentFoldCreaseRegion_.empty()) {
681 InitFoldCreaseRegion();
682 }
683 auto titleBarLayoutProperty = hostNode->GetLayoutProperty<TitleBarLayoutProperty>();
684 CHECK_NULL_VOID(titleBarLayoutProperty);
685 if (titleBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE) != NavigationTitleMode::FREE ||
686 isInitialTitle_ || !isTitleChanged_) {
687 return;
688 }
689 isTitleChanged_ = false;
690 if (NearEqual(GetTempTitleBarHeight(), static_cast<float>(FULL_DOUBLE_LINE_TITLEBAR_HEIGHT.ConvertToPx())) ||
691 NearEqual(GetTempTitleBarHeight(), static_cast<float>(FULL_SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx()))) {
692 tempTitleBarHeight_.SetValue(hostNode->GetSubtitle() ? FULL_DOUBLE_LINE_TITLEBAR_HEIGHT.Value()
693 : FULL_SINGLE_LINE_TITLEBAR_HEIGHT.Value());
694 }
695 }
696
ApplyTitleModifierIfNeeded(const RefPtr<TitleBarNode> & hostNode)697 void TitleBarPattern::ApplyTitleModifierIfNeeded(const RefPtr<TitleBarNode>& hostNode)
698 {
699 isFontSizeSettedByDeveloper_ = false;
700 CHECK_NULL_VOID(hostNode);
701 auto titleNode = AceType::DynamicCast<FrameNode>(hostNode->GetTitle());
702 if (options_.textOptions.mainTitleApplyFunc && titleNode) {
703 ApplyTitleModifier(titleNode, options_.textOptions.mainTitleApplyFunc, true);
704 }
705 auto subtitleNode = AceType::DynamicCast<FrameNode>(hostNode->GetSubtitle());
706 if (options_.textOptions.subTitleApplyFunc && subtitleNode) {
707 ApplyTitleModifier(subtitleNode, options_.textOptions.subTitleApplyFunc, false);
708 }
709 }
710
ApplyTitleModifier(const RefPtr<FrameNode> & textNode,const TextStyleApplyFunc & applyFunc,bool needCheckFontSizeIsSetted)711 void TitleBarPattern::ApplyTitleModifier(const RefPtr<FrameNode>& textNode,
712 const TextStyleApplyFunc& applyFunc, bool needCheckFontSizeIsSetted)
713 {
714 CHECK_NULL_VOID(textNode);
715 CHECK_NULL_VOID(applyFunc);
716 auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
717 CHECK_NULL_VOID(textLayoutProperty);
718
719 std::optional<Dimension> backupFontSize;
720 std::optional<Dimension> backupMaxFontSize;
721 std::optional<Dimension> backupMinFontSize;
722 if (textLayoutProperty->HasFontSize()) {
723 backupFontSize = textLayoutProperty->GetFontSizeValue(Dimension());
724 }
725 if (textLayoutProperty->HasAdaptMaxFontSize()) {
726 backupMaxFontSize = textLayoutProperty->GetAdaptMaxFontSizeValue(Dimension());
727 }
728 if (textLayoutProperty->HasAdaptMinFontSize()) {
729 backupMinFontSize = textLayoutProperty->GetAdaptMinFontSizeValue(Dimension());
730 }
731 textLayoutProperty->ResetFontSize();
732 textLayoutProperty->ResetAdaptMaxFontSize();
733 textLayoutProperty->ResetAdaptMinFontSize();
734 applyFunc(AceType::WeakClaim(AceType::RawPtr(textNode)));
735
736 if (!textLayoutProperty->HasFontSize() &&
737 !textLayoutProperty->HasAdaptMinFontSize() &&
738 !textLayoutProperty->HasAdaptMaxFontSize()) {
739 // restore
740 if (backupFontSize.has_value()) {
741 textLayoutProperty->UpdateFontSize(backupFontSize.value());
742 }
743 if (backupMaxFontSize.has_value()) {
744 textLayoutProperty->UpdateAdaptMaxFontSize(backupMaxFontSize.value());
745 }
746 if (backupMinFontSize.has_value()) {
747 textLayoutProperty->UpdateAdaptMinFontSize(backupMinFontSize.value());
748 }
749 } else {
750 TAG_LOGD(AceLogTag::ACE_NAVIGATION, "modifier set %{public}s, %{public}s, %{public}s",
751 textLayoutProperty->HasFontSize() ? "FontSize" : "",
752 textLayoutProperty->HasAdaptMinFontSize() ? "AdaptMinFontSize" : "",
753 textLayoutProperty->HasAdaptMaxFontSize() ? "AdaptMaxFontSize" : "");
754 if (needCheckFontSizeIsSetted) {
755 isFontSizeSettedByDeveloper_ = true;
756 }
757 }
758
759 textNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
760 textNode->MarkModifyDone();
761 }
762
ProcessTitleDragUpdate(float offset)763 void TitleBarPattern::ProcessTitleDragUpdate(float offset)
764 {
765 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
766 CHECK_NULL_VOID(titleBarNode);
767 auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
768 CHECK_NULL_VOID(titleBarLayoutProperty);
769 if (titleBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE) != NavigationTitleMode::FREE ||
770 IsHidden()) {
771 return;
772 }
773 SetTempTitleBarHeight(offset);
774 titleMoveDistance_ = (GetTempTitleBarHeight() - defaultTitleBarHeight_) * moveRatio_;
775 SetTempTitleOffsetY();
776 SetTempSubTitleOffsetY();
777 titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
778
779 // title font size
780 auto mappedOffset = GetMappedOffset(offset);
781 fontSize_ = GetFontSize(mappedOffset);
782 UpdateTitleFontSize(fontSize_.value());
783
784 // subTitle Opacity
785 opacity_ = GetSubtitleOpacity();
786 UpdateSubTitleOpacity(opacity_.value());
787 }
788
GetSubtitleOpacity()789 float TitleBarPattern::GetSubtitleOpacity()
790 {
791 auto titleBarHeightDiff = maxTitleBarHeight_ - static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
792 opacityRatio_ = 1.0f / titleBarHeightDiff;
793 auto tempOpacity = static_cast<float>((GetTempTitleBarHeight() -
794 static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx())) * opacityRatio_ + 0.0f);
795 return tempOpacity;
796 }
797
GetFontSize(float offset)798 Dimension TitleBarPattern::GetFontSize(float offset)
799 {
800 auto titleBarHeight = defaultTitleBarHeight_ + offset;
801 auto theme = NavigationGetTheme();
802 CHECK_NULL_RETURN(theme, Dimension(0.0f, DimensionUnit::FP));
803 Dimension titleL = theme->GetTitleFontSizeBig();
804 Dimension titleM = theme->GetTitleFontSize();
805 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
806 titleL = theme->GetMainTitleFontSizeL();
807 titleM = theme->GetMainTitleFontSizeM();
808 }
809 auto titleFontSizeDiff = titleL - titleM;
810 auto titleBarHeightDiff = maxTitleBarHeight_ - static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
811 if (!NearZero(titleBarHeightDiff)) {
812 fontSizeRatio_ = titleFontSizeDiff.Value() / titleBarHeightDiff;
813 }
814 auto tempFontSize = titleM.Value() +
815 (titleBarHeight - static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx())) * fontSizeRatio_;
816 if (GreatNotEqual(tempFontSize, titleL.Value())) {
817 tempFontSize = titleL.Value();
818 }
819 if (LessNotEqual(tempFontSize, titleM.Value())) {
820 tempFontSize = titleM.Value();
821 }
822 return Dimension(tempFontSize, DimensionUnit::FP);
823 }
824
GetMappedOffset(float offset)825 float TitleBarPattern::GetMappedOffset(float offset)
826 {
827 auto titleOffset = offset + defaultTitleBarHeight_ - static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
828 auto heightDiff = maxTitleBarHeight_ - static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
829 float moveRatio = Curves::SHARP->MoveInternal(std::clamp(titleOffset / heightDiff, 0.0f, 1.0f));
830 auto mappedTitleOffset = moveRatio * heightDiff;
831 auto mappedOffset =
832 mappedTitleOffset - defaultTitleBarHeight_ + static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
833 return mappedOffset;
834 }
835
SpringAnimation(float startPos,float endPos)836 void TitleBarPattern::SpringAnimation(float startPos, float endPos)
837 {
838 auto host = GetHost();
839 CHECK_NULL_VOID(host);
840 SetOverDragOffset(overDragOffset_);
841 SetTempTitleBarHeightVp(maxTitleBarHeight_ + overDragOffset_ / 6.0f);
842 UpdateScaleByDragOverDragOffset(overDragOffset_);
843 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
844 auto pipeline = PipelineContext::GetCurrentContext();
845 if (pipeline) {
846 pipeline->FlushUITasks();
847 }
848
849 constexpr float velocity = 0.0f;
850 constexpr float mass = 1.0f; // The move animation spring curve mass is 1.0f
851 constexpr float stiffness = 228.0f; // The move animation spring curve stiffness is 228.0f
852 constexpr float damping = 30.0f; // The move animation spring curve damping is 30.0f
853 auto springCurve = AceType::MakeRefPtr<InterpolatingSpring>(velocity, mass, stiffness, damping);
854 AnimationOption option;
855 option.SetCurve(springCurve);
856
857 springAnimation_ = AnimationUtils::StartAnimation(
858 option,
859 [weakPattern = AceType::WeakClaim(this)]() {
860 auto pattern = weakPattern.Upgrade();
861 CHECK_NULL_VOID(pattern);
862 auto host = pattern->GetHost();
863 CHECK_NULL_VOID(host);
864 pattern->SetOverDragOffset(0.0f);
865 pattern->SetTempTitleBarHeightVp(pattern->GetMaxTitleBarHeight());
866 pattern->UpdateScaleByDragOverDragOffset(0.0f);
867 pattern->tempTitleOffsetY_ = 0.0f;
868 pattern->isFreeTitleUpdated_ = false;
869 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
870 auto pipeline = PipelineContext::GetCurrentContext();
871 if (pipeline) {
872 pipeline->FlushUITasks();
873 }
874 }, [weakPattern = AceType::WeakClaim(this)]() {
875 auto pattern = weakPattern.Upgrade();
876 CHECK_NULL_VOID(pattern);
877 pattern->CleanSpringAnimation();
878 }, nullptr /* repeatCallback */, host->GetContextRefPtr());
879 }
880
ClearDragState()881 void TitleBarPattern::ClearDragState()
882 {
883 overDragOffset_ = 0.0f;
884 }
885
UpdateScaleByDragOverDragOffset(float overDragOffset)886 void TitleBarPattern::UpdateScaleByDragOverDragOffset(float overDragOffset)
887 {
888 if (Negative(overDragOffset)) {
889 return;
890 }
891 auto host = GetHost();
892 CHECK_NULL_VOID(host);
893 auto navBarNode = AceType::DynamicCast<NavBarNode>(host->GetParent());
894 CHECK_NULL_VOID(navBarNode);
895 if (navBarNode->GetPrevTitleIsCustomValue(true)) {
896 return;
897 }
898 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
899 CHECK_NULL_VOID(titleBarNode);
900 auto titleNode = titleBarNode->GetTitle();
901 CHECK_NULL_VOID(titleNode);
902 auto title = AceType::DynamicCast<FrameNode>(titleNode);
903 TransformScale(overDragOffset, title);
904 auto subtitleNode = titleBarNode->GetSubtitle();
905 if (subtitleNode) {
906 auto subtitle = AceType::DynamicCast<FrameNode>(subtitleNode);
907 TransformScale(overDragOffset, subtitle);
908 }
909
910 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
911 }
912
TransformScale(float overDragOffset,const RefPtr<FrameNode> & frameNode)913 void TitleBarPattern::TransformScale(float overDragOffset, const RefPtr<FrameNode>& frameNode)
914 {
915 CHECK_NULL_VOID(frameNode);
916 auto renderCtx = frameNode->GetRenderContext();
917 CHECK_NULL_VOID(renderCtx);
918 auto offset = std::clamp(overDragOffset, 0.0f, static_cast<float>(MAX_OVER_DRAG_OFFSET.ConvertToPx()));
919 auto scaleRatio = offset / static_cast<float>(MAX_OVER_DRAG_OFFSET.ConvertToPx());
920 VectorF scaleValue = VectorF(scaleRatio * 0.1f + 1.0f, scaleRatio * 0.1f + 1.0f);
921 renderCtx->UpdateTransformScale(scaleValue);
922 }
923
AnimateTo(float offset,bool isFullTitleMode)924 void TitleBarPattern::AnimateTo(float offset, bool isFullTitleMode)
925 {
926 auto host = GetHost();
927 CHECK_NULL_VOID(host);
928 AnimationOption option;
929 option.SetCurve(Curves::FAST_OUT_SLOW_IN);
930 option.SetDuration(DEFAULT_ANIMATION_DURATION);
931
932 animation_ = AnimationUtils::StartAnimation(
933 option,
934 [weakPattern = AceType::WeakClaim(this), offset, isFullTitleMode]() {
935 auto pattern = weakPattern.Upgrade();
936 CHECK_NULL_VOID(pattern);
937 auto host = pattern->GetHost();
938 CHECK_NULL_VOID(host);
939 pattern->ProcessTitleDragUpdate(offset);
940 if (isFullTitleMode) {
941 pattern->tempTitleOffsetY_ = 0.0f;
942 pattern->isFreeTitleUpdated_ = false;
943 }
944 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
945 auto pipeline = PipelineContext::GetCurrentContext();
946 if (pipeline) {
947 pipeline->FlushUITasks();
948 }
949 }, [weakPattern = AceType::WeakClaim(this)]() {
950 auto pattern = weakPattern.Upgrade();
951 CHECK_NULL_VOID(pattern);
952 pattern->CleanAnimation();
953 }, nullptr /* repeatCallback */, host->GetContextRefPtr());
954 }
955
SetMaxTitleBarHeight()956 void TitleBarPattern::SetMaxTitleBarHeight()
957 {
958 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
959 CHECK_NULL_VOID(titleBarNode);
960 if (titleBarNode->GetSubtitle()) {
961 maxTitleBarHeight_ = static_cast<float>(FULL_DOUBLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
962 } else {
963 maxTitleBarHeight_ = static_cast<float>(FULL_SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
964 }
965 }
966
SetTempTitleBarHeight(float offsetY)967 void TitleBarPattern::SetTempTitleBarHeight(float offsetY)
968 {
969 auto tmepTitleBarHeight = defaultTitleBarHeight_ + offsetY;
970 if (tmepTitleBarHeight < static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx())) {
971 tmepTitleBarHeight = static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
972 }
973 if (tmepTitleBarHeight > maxTitleBarHeight_) {
974 tmepTitleBarHeight = maxTitleBarHeight_;
975 }
976 SetTempTitleBarHeightVp(tmepTitleBarHeight);
977 }
978
SetTempTitleOffsetY()979 void TitleBarPattern::SetTempTitleOffsetY()
980 {
981 tempTitleOffsetY_ = defaultTitleOffsetY_ + titleMoveDistance_;
982 if (tempTitleOffsetY_ < minTitleOffsetY_) {
983 tempTitleOffsetY_ = minTitleOffsetY_;
984 }
985 if (tempTitleOffsetY_ > maxTitleOffsetY_) {
986 tempTitleOffsetY_ = maxTitleOffsetY_;
987 }
988 }
989
SetTempSubTitleOffsetY()990 void TitleBarPattern::SetTempSubTitleOffsetY()
991 {
992 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
993 tempSubTitleOffsetY_ = tempTitleOffsetY_ + GetTitleHeight() +
994 static_cast<float>(titleSpaceVertical_.ConvertToPx());
995 } else {
996 tempSubTitleOffsetY_ = tempTitleOffsetY_ + GetTitleHeight();
997 }
998 if (tempTitleOffsetY_ < minTitleOffsetY_) {
999 tempSubTitleOffsetY_ = minTitleOffsetY_;
1000 }
1001 if (tempTitleOffsetY_ > maxTitleOffsetY_) {
1002 tempSubTitleOffsetY_ = maxTitleOffsetY_;
1003 }
1004 }
1005
SetDefaultTitleFontSize()1006 void TitleBarPattern::SetDefaultTitleFontSize()
1007 {
1008 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1009 CHECK_NULL_VOID(titleBarNode);
1010 CHECK_NULL_VOID(titleBarNode->GetTitle());
1011 auto titleNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetTitle());
1012 CHECK_NULL_VOID(titleNode);
1013 auto textLayoutProperty = titleNode->GetLayoutProperty<TextLayoutProperty>();
1014 CHECK_NULL_VOID(textLayoutProperty);
1015 auto theme = NavigationGetTheme();
1016 CHECK_NULL_VOID(theme);
1017 defaultTitleFontSize_ = theme->GetTitleFontSize();
1018 }
1019
SetDefaultSubtitleOpacity()1020 void TitleBarPattern::SetDefaultSubtitleOpacity()
1021 {
1022 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1023 CHECK_NULL_VOID(titleBarNode);
1024 CHECK_NULL_VOID(titleBarNode->GetSubtitle());
1025 auto subtitleNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetSubtitle());
1026 CHECK_NULL_VOID(subtitleNode);
1027 auto context = subtitleNode->GetRenderContext();
1028 CHECK_NULL_VOID(context);
1029 if (defaultTitleBarHeight_ == maxTitleBarHeight_) {
1030 defaultSubtitleOpacity_ = context->GetOpacityValue(1.0f);
1031 } else {
1032 defaultSubtitleOpacity_ = context->GetOpacityValue(0.0f);
1033 }
1034 }
1035
GetTitleHeight()1036 float TitleBarPattern::GetTitleHeight()
1037 {
1038 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1039 CHECK_NULL_RETURN(titleBarNode, 0.0f);
1040 auto titleNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetTitle());
1041 CHECK_NULL_RETURN(titleNode, 0.0f);
1042 auto geometryNode = titleNode->GetGeometryNode();
1043 CHECK_NULL_RETURN(geometryNode, 0.0f);
1044 return geometryNode->GetFrameSize().Height();
1045 }
1046
GetSubTitleOffsetY()1047 float TitleBarPattern::GetSubTitleOffsetY()
1048 {
1049 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1050 CHECK_NULL_RETURN(titleBarNode, 0.0f);
1051 auto subTitleNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetSubtitle());
1052 CHECK_NULL_RETURN(subTitleNode, 0.0f);
1053 auto geometryNode = subTitleNode->GetGeometryNode();
1054 CHECK_NULL_RETURN(geometryNode, 0.0f);
1055 return geometryNode->GetMarginFrameOffset().GetY();
1056 }
1057
UpdateTitleFontSize(const Dimension & tempTitleFontSize)1058 void TitleBarPattern::UpdateTitleFontSize(const Dimension& tempTitleFontSize)
1059 {
1060 if (isFontSizeSettedByDeveloper_) {
1061 return;
1062 }
1063 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1064 CHECK_NULL_VOID(titleBarNode);
1065 auto titleNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetTitle());
1066 CHECK_NULL_VOID(titleNode);
1067 auto textLayoutProperty = titleNode->GetLayoutProperty<TextLayoutProperty>();
1068 CHECK_NULL_VOID(textLayoutProperty);
1069 textLayoutProperty->UpdateFontSize(tempTitleFontSize);
1070 textLayoutProperty->UpdateAdaptMaxFontSize(tempTitleFontSize);
1071 titleNode->MarkModifyDone();
1072 }
1073
UpdateSubTitleOpacity(const double & value)1074 void TitleBarPattern::UpdateSubTitleOpacity(const double& value)
1075 {
1076 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1077 CHECK_NULL_VOID(titleBarNode);
1078 auto subTitleNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetSubtitle());
1079 CHECK_NULL_VOID(subTitleNode);
1080 auto context = subTitleNode->GetRenderContext();
1081 CHECK_NULL_VOID(context);
1082 context->UpdateOpacity(value);
1083 }
1084
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)1085 bool TitleBarPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
1086 {
1087 if (config.skipMeasure && config.skipLayout) {
1088 return false;
1089 }
1090 auto layoutAlgorithmWrapper = DynamicCast<LayoutAlgorithmWrapper>(dirty->GetLayoutAlgorithm());
1091 CHECK_NULL_RETURN(layoutAlgorithmWrapper, false);
1092 auto titleBarLayoutAlgorithm = DynamicCast<TitleBarLayoutAlgorithm>(layoutAlgorithmWrapper->GetLayoutAlgorithm());
1093 CHECK_NULL_RETURN(titleBarLayoutAlgorithm, false);
1094 UpdateTitleModeChange();
1095
1096 initialTitleOffsetY_ = titleBarLayoutAlgorithm->GetInitialTitleOffsetY();
1097 isInitialTitle_ = titleBarLayoutAlgorithm->IsInitialTitle();
1098 initialSubtitleOffsetY_ = titleBarLayoutAlgorithm->GetInitialSubtitleOffsetY();
1099 isInitialSubtitle_ = titleBarLayoutAlgorithm->IsInitialSubtitle();
1100 minTitleHeight_ = titleBarLayoutAlgorithm->GetMinTitleHeight();
1101 return true;
1102 }
1103
UpdateTitleModeChange()1104 void TitleBarPattern::UpdateTitleModeChange()
1105 {
1106 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1107 CHECK_NULL_VOID(titleBarNode);
1108 auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
1109 CHECK_NULL_VOID(titleBarLayoutProperty);
1110 auto geometryNode = titleBarNode->GetGeometryNode();
1111 CHECK_NULL_VOID(geometryNode);
1112
1113 auto titleBarHeight = geometryNode->GetFrameSize().Height();
1114 if ((titleBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE) == NavigationTitleMode::FREE) &&
1115 !NearZero(maxTitleBarHeight_)) {
1116 if (titleBarHeight >= maxTitleBarHeight_) {
1117 titleMode_ = NavigationTitleMode::FULL;
1118 } else if (NearEqual(titleBarHeight, static_cast<float>(TITLEBAR_HEIGHT_MINI.ConvertToPx()))) {
1119 titleMode_ = NavigationTitleMode::MINI;
1120 }
1121 }
1122 }
1123
OnAttachToFrameNode()1124 void TitleBarPattern::OnAttachToFrameNode()
1125 {
1126 auto host = GetHost();
1127 CHECK_NULL_VOID(host);
1128 host->GetRenderContext()->SetClipToFrame(true);
1129 host->GetRenderContext()->UpdateClipEdge(true);
1130
1131 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1132 SafeAreaExpandOpts opts = { .type = SAFE_AREA_TYPE_SYSTEM | SAFE_AREA_TYPE_CUTOUT,
1133 .edges = SAFE_AREA_EDGE_TOP };
1134 host->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
1135 }
1136 auto pipelineContext = PipelineContext::GetCurrentContext();
1137 CHECK_NULL_VOID(pipelineContext);
1138
1139 auto halfFoldHoverCallbackId = pipelineContext->RegisterHalfFoldHoverChangedCallback(
1140 [weakHost = WeakPtr<FrameNode>(host)](bool isHalfFoldHover) {
1141 auto host = weakHost.Upgrade();
1142 CHECK_NULL_VOID(host);
1143 NavigationTitleUtil::FoldStatusChangedAnimation(host);
1144 });
1145 UpdateHalfFoldHoverChangedCallbackId(halfFoldHoverCallbackId);
1146 }
1147
InitFoldCreaseRegion()1148 void TitleBarPattern::InitFoldCreaseRegion()
1149 {
1150 auto container = Container::Current();
1151 CHECK_NULL_VOID(container);
1152 auto displayInfo = container->GetDisplayInfo();
1153 CHECK_NULL_VOID(displayInfo);
1154 currentFoldCreaseRegion_ = displayInfo->GetCurrentFoldCreaseRegion();
1155 }
1156
OnCoordScrollStart()1157 void TitleBarPattern::OnCoordScrollStart()
1158 {
1159 coordScrollOffset_ = 0.0f;
1160 coordScrollFinalOffset_ = 0.0f;
1161 isFreeTitleUpdated_ = true;
1162
1163 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1164 CHECK_NULL_VOID(titleBarNode);
1165 auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
1166 CHECK_NULL_VOID(titleBarLayoutProperty);
1167 if (titleBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE) != NavigationTitleMode::FREE) {
1168 return;
1169 }
1170 if (springAnimation_) {
1171 AnimationUtils::StopAnimation(springAnimation_);
1172 springAnimation_.reset();
1173 }
1174 if (animation_) {
1175 AnimationUtils::StopAnimation(animation_);
1176 animation_.reset();
1177 }
1178
1179 defaultTitleBarHeight_ = currentTitleBarHeight_;
1180 defaultTitleOffsetY_ = currentTitleOffsetY_;
1181 SetMaxTitleBarHeight();
1182 SetTempTitleBarHeight(0);
1183 minTitleOffsetY_ = (static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx()) - minTitleHeight_) / 2.0f;
1184 maxTitleOffsetY_ = initialTitleOffsetY_;
1185 moveRatio_ = (maxTitleOffsetY_ - minTitleOffsetY_) /
1186 (maxTitleBarHeight_ - static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx()));
1187 titleMoveDistance_ = (GetTempTitleBarHeight() - defaultTitleBarHeight_) * moveRatio_;
1188 }
1189
OnCoordScrollUpdate(float offset)1190 float TitleBarPattern::OnCoordScrollUpdate(float offset)
1191 {
1192 float lastOffset = coordScrollOffset_;
1193 coordScrollOffset_ += offset;
1194
1195 float offsetHandled = 0.0f;
1196 float minHeight = static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
1197 float titleBarOffset = coordScrollOffset_;
1198 if (LessNotEqual(defaultTitleBarHeight_ + titleBarOffset, minHeight)) {
1199 // The target height is smaller than the minHeight, so the titleBarOffset is adjusted to modify the height to
1200 // the minHeight.
1201 titleBarOffset = minHeight - defaultTitleBarHeight_;
1202 overDragOffset_ = 0.0f;
1203 offsetHandled = CalculateHandledOffsetMinTitle(offset, lastOffset);
1204 } else if (GreatNotEqual(defaultTitleBarHeight_ + titleBarOffset, maxTitleBarHeight_)) {
1205 // The target height is greater than the maxTitleBarHeight_, so overDragOffset_ needs to be updated.
1206 overDragOffset_ = defaultTitleBarHeight_ + titleBarOffset - maxTitleBarHeight_;
1207 offsetHandled = CalculateHandledOffsetMaxTitle(offset, lastOffset);
1208 } else {
1209 // The target height is between the minHeight and the maxTitleBarHeight_.
1210 overDragOffset_ = 0.0f;
1211 offsetHandled = CalculateHandledOffsetBetweenMinAndMaxTitle(offset, lastOffset);
1212 }
1213 UpdateTitleBarByCoordScroll(titleBarOffset);
1214 coordScrollFinalOffset_ = titleBarOffset;
1215 auto barStyle = options_.brOptions.barStyle.value_or(BarStyle::STANDARD);
1216 if (barStyle == BarStyle::STACK) {
1217 offsetHandled = 0.0f;
1218 }
1219
1220 return offsetHandled;
1221 }
1222
OnCoordScrollEnd()1223 void TitleBarPattern::OnCoordScrollEnd()
1224 {
1225 if (NearZero(coordScrollOffset_)) {
1226 return;
1227 }
1228 float minHeight = static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
1229 float middleHeight =
1230 (static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx()) + maxTitleBarHeight_) / TITLE_RATIO;
1231 float finalHeight = defaultTitleBarHeight_ + coordScrollFinalOffset_;
1232 if (GreatNotEqual(finalHeight, minHeight) && LessOrEqual(finalHeight, middleHeight)) {
1233 // The finalHeight is between the minHeight and the middleHeight, so animate to min title.
1234 AnimateTo(static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx()) - defaultTitleBarHeight_);
1235 return;
1236 }
1237 if (GreatNotEqual(finalHeight, middleHeight) && LessNotEqual(finalHeight, maxTitleBarHeight_)) {
1238 // The finalHeight is between the middleHeight and the maxTitleBarHeight_, so animate to max title.
1239 AnimateTo(maxTitleBarHeight_ - defaultTitleBarHeight_, true);
1240 return;
1241 }
1242 if (GreatNotEqual(finalHeight, maxTitleBarHeight_)) {
1243 // The finalHeight is bigger than the maxTitleBarHeight_, so animate to max title.
1244 SpringAnimation(finalHeight - maxTitleBarHeight_, 0);
1245 }
1246 }
1247
UpdateTitleBarByCoordScroll(float offset)1248 void TitleBarPattern::UpdateTitleBarByCoordScroll(float offset)
1249 {
1250 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1251 CHECK_NULL_VOID(titleBarNode);
1252 auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
1253 CHECK_NULL_VOID(titleBarLayoutProperty);
1254 if (titleBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE) != NavigationTitleMode::FREE) {
1255 return;
1256 }
1257 SetTitleStyleByCoordScrollOffset(offset);
1258 UpdateScaleByDragOverDragOffset(overDragOffset_);
1259 }
1260
SetTitleStyleByCoordScrollOffset(float offset)1261 void TitleBarPattern::SetTitleStyleByCoordScrollOffset(float offset)
1262 {
1263 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1264 CHECK_NULL_VOID(titleBarNode);
1265 auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
1266 CHECK_NULL_VOID(titleBarLayoutProperty);
1267 if (titleBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE) != NavigationTitleMode::FREE) {
1268 return;
1269 }
1270 if (Positive(overDragOffset_)) {
1271 SetTempTitleBarHeightVp(maxTitleBarHeight_ + overDragOffset_ / 6.0f);
1272 titleMoveDistance_ = (maxTitleBarHeight_ - defaultTitleBarHeight_) * moveRatio_ + overDragOffset_ / 6.0f;
1273 } else {
1274 SetTempTitleBarHeight(offset);
1275 titleMoveDistance_ = (GetTempTitleBarHeight() - defaultTitleBarHeight_) * moveRatio_;
1276 }
1277
1278 SetTempTitleOffsetY();
1279 SetTempSubTitleOffsetY();
1280 titleBarNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
1281
1282 // title font size
1283 auto mappedOffset = GetMappedOffset(offset);
1284 fontSize_ = GetFontSize(mappedOffset);
1285 UpdateTitleFontSize(fontSize_.value());
1286
1287 // subTitle Opacity
1288 opacity_ = GetSubtitleOpacity();
1289 UpdateSubTitleOpacity(opacity_.value());
1290 }
1291
OnColorConfigurationUpdate()1292 void TitleBarPattern::OnColorConfigurationUpdate()
1293 {
1294 auto host = GetHost();
1295 CHECK_NULL_VOID(host);
1296 UpdateBackgroundStyle(host);
1297 SetNeedResetMainTitleProperty(true);
1298 SetNeedResetSubTitleProperty(true);
1299
1300 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(host);
1301 CHECK_NULL_VOID(titleBarNode);
1302 auto backButton = AceType::DynamicCast<FrameNode>(titleBarNode->GetBackButton());
1303 CHECK_NULL_VOID(backButton);
1304 if (backButton->GetTag() == "Navigator") {
1305 backButton = AceType::DynamicCast<FrameNode>(backButton->GetChildren().front());
1306 CHECK_NULL_VOID(backButton);
1307 }
1308 auto theme = NavigationGetTheme();
1309 CHECK_NULL_VOID(theme);
1310 auto iconColor = theme->GetBackButtonIconColor();
1311 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1312 iconColor = theme->GetIconColor();
1313 auto backButtonColor = theme->GetCompBackgroundColor();
1314 auto renderContext = backButton->GetRenderContext();
1315 auto backButtonPattern = backButton->GetPattern<ButtonPattern>();
1316 backButtonPattern->setComponentButtonType(ComponentButtonType::NAVIGATION);
1317 backButtonPattern->SetBlendColor(theme->GetBackgroundPressedColor(), theme->GetBackgroundHoverColor());
1318 backButtonPattern->SetFocusBorderColor(theme->GetBackgroundFocusOutlineColor());
1319 backButtonPattern->SetFocusBorderWidth(theme->GetBackgroundFocusOutlineWeight());
1320 renderContext->UpdateBackgroundColor(backButtonColor);
1321 backButton->MarkModifyDone();
1322 }
1323 auto backButtonImgNode = AceType::DynamicCast<FrameNode>(backButton->GetChildren().front());
1324 CHECK_NULL_VOID(backButtonImgNode);
1325 if (backButtonImgNode->GetTag() == V2::IMAGE_ETS_TAG) {
1326 auto backButtonImgRender = backButtonImgNode->GetPaintProperty<ImageRenderProperty>();
1327 CHECK_NULL_VOID(backButtonImgRender);
1328 backButtonImgRender->UpdateSvgFillColor(iconColor);
1329 }
1330 backButtonImgNode->MarkModifyDone();
1331 }
1332
OnThemeScopeUpdate(int32_t themeScopeId)1333 bool TitleBarPattern::OnThemeScopeUpdate(int32_t themeScopeId)
1334 {
1335 auto host = AceType::DynamicCast<TitleBarNode>(GetHost());
1336 CHECK_NULL_RETURN(host, false);
1337 shouldResetMainTitleProperty_ = true;
1338 shouldResetSubTitleProperty_ = true;
1339 host->MarkModifyDone();
1340 return false;
1341 }
1342
CalculateHandledOffsetMinTitle(float offset,float lastCordScrollOffset)1343 float TitleBarPattern::CalculateHandledOffsetMinTitle(float offset, float lastCordScrollOffset)
1344 {
1345 float offsetHandled = 0.0f;
1346 float minHeight = static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
1347 if (LessOrEqual(defaultTitleBarHeight_ + lastCordScrollOffset, minHeight)) {
1348 // The starting height of this update is smaller than the minHeight, so the navigation component does
1349 // not handle the offset.
1350 offsetHandled = 0.0f;
1351 } else if (GreatOrEqual(defaultTitleBarHeight_ + lastCordScrollOffset, maxTitleBarHeight_)) {
1352 // The starting position height of this update is greater than the maxTitleBarHeight_, so the navigation
1353 // component only handles offsets from maxTitleBarHeight_ to minHeight.
1354 offsetHandled = minHeight - maxTitleBarHeight_;
1355 } else {
1356 // The starting position height of this update is between the minHeight and the maxTitleBarHeight_, so the
1357 // navigation component only handles offsets from defaultTitleBarHeight_ to minHeight.
1358 offsetHandled = offset - (coordScrollOffset_ - (minHeight - defaultTitleBarHeight_));
1359 }
1360 return offsetHandled;
1361 }
1362
CalculateHandledOffsetMaxTitle(float offset,float lastCordScrollOffset)1363 float TitleBarPattern::CalculateHandledOffsetMaxTitle(float offset, float lastCordScrollOffset)
1364 {
1365 float minHeight = static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
1366 if (GreatOrEqual(defaultTitleBarHeight_ + lastCordScrollOffset, maxTitleBarHeight_)) {
1367 // The starting height of this update is greater than the maxTitleBarHeight_, so the navigation component
1368 // does not handle the offset.
1369 return 0.0f;
1370 }
1371 if (LessOrEqual(defaultTitleBarHeight_ + lastCordScrollOffset, minHeight)) {
1372 // The starting position height of this update is smaller than the minHeight, so the navigation component
1373 // only handles offsets from minHeight to maxTitleBarHeight_.
1374 return maxTitleBarHeight_ - minHeight;
1375 }
1376 // The starting position height of this update is between the minHeight and the maxTitleBarHeight_, so the
1377 // navigation component only handles offsets from defaultTitleBarHeight_ to maxTitleBarHeight_.
1378 return offset - (coordScrollOffset_ - (maxTitleBarHeight_ - defaultTitleBarHeight_));
1379 }
1380
CalculateHandledOffsetBetweenMinAndMaxTitle(float offset,float lastCordScrollOffset)1381 float TitleBarPattern::CalculateHandledOffsetBetweenMinAndMaxTitle(float offset, float lastCordScrollOffset)
1382 {
1383 float minHeight = static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx());
1384 if (LessOrEqual(defaultTitleBarHeight_ + lastCordScrollOffset, minHeight)) {
1385 // The starting height of this update is smaller than the minHeight, so the navigation component only
1386 // handles offsets from minHeight to target height.
1387 return defaultTitleBarHeight_ + coordScrollOffset_ - minHeight;
1388 }
1389 if (GreatOrEqual(defaultTitleBarHeight_ + lastCordScrollOffset, maxTitleBarHeight_)) {
1390 // The starting position height of this update is greater than the maxTitleBarHeight_, so the navigation
1391 // component only handles offsets from maxTitleBarHeight_ to target height.
1392 return coordScrollOffset_ - (maxTitleBarHeight_ - defaultTitleBarHeight_);
1393 }
1394 // The starting position height of this update is between the minHeight and the maxTitleBarHeight_, so the
1395 // navigation component handles all of the offset.
1396 return offset;
1397 }
1398
SetTitlebarOptions(NavigationTitlebarOptions & opt)1399 void TitleBarPattern::SetTitlebarOptions(NavigationTitlebarOptions& opt)
1400 {
1401 bool needUpdateBgOptions = options_.bgOptions != opt.bgOptions;
1402 if (options_.textOptions.mainTitleApplyFunc && !opt.textOptions.mainTitleApplyFunc) {
1403 shouldResetMainTitleProperty_ = true;
1404 }
1405 if (options_.textOptions.subTitleApplyFunc && !opt.textOptions.subTitleApplyFunc) {
1406 shouldResetSubTitleProperty_ = true;
1407 }
1408 if (options_.bgOptions.blurStyleOption->blurOption != opt.bgOptions.blurStyleOption->blurOption) {
1409 needUpdateBgOptions = true;
1410 }
1411 options_ = opt;
1412 if (!needUpdateBgOptions) {
1413 return;
1414 }
1415
1416 auto host = GetHost();
1417 CHECK_NULL_VOID(host);
1418 UpdateBackgroundStyle(host);
1419 }
1420
UpdateBackgroundStyle(RefPtr<FrameNode> & host)1421 void TitleBarPattern::UpdateBackgroundStyle(RefPtr<FrameNode>& host)
1422 {
1423 auto renderContext = host->GetRenderContext();
1424 CHECK_NULL_VOID(renderContext);
1425 if (options_.bgOptions.color.has_value()) {
1426 renderContext->UpdateBackgroundColor(options_.bgOptions.color.value());
1427 } else {
1428 renderContext->ResetBackgroundColor();
1429 }
1430 if (options_.bgOptions.blurStyleOption.has_value()) {
1431 BlurStyleOption styleOption = options_.bgOptions.blurStyleOption.value();
1432 SetBackgroundBlurStyle(host, styleOption);
1433 } else {
1434 renderContext->ResetBackBlurStyle();
1435 }
1436 if (options_.bgOptions.effectOption.has_value()) {
1437 EffectOption effectOption = options_.bgOptions.effectOption.value();
1438 SetBackgroundEffect(host, effectOption);
1439 }
1440 }
1441
OnDetachFromFrameNode(FrameNode * frameNode)1442 void TitleBarPattern::OnDetachFromFrameNode(FrameNode* frameNode)
1443 {
1444 CHECK_NULL_VOID(frameNode);
1445 auto pipeline = PipelineContext::GetCurrentContext();
1446 CHECK_NULL_VOID(pipeline);
1447
1448 if (HasHalfFoldHoverChangedCallbackId()) {
1449 pipeline->UnRegisterHalfFoldHoverChangedCallback(halfFoldHoverChangedCallbackId_.value());
1450 }
1451 }
1452
DumpInfo()1453 void TitleBarPattern::DumpInfo()
1454 {
1455 auto hostNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1456 CHECK_NULL_VOID(hostNode);
1457 auto mainTitle = AceType::DynamicCast<FrameNode>(hostNode->GetTitle());
1458 if (mainTitle) {
1459 auto property = mainTitle->GetLayoutProperty<TextLayoutProperty>();
1460 if (property) {
1461 DumpTitleProperty(property, true);
1462 }
1463 }
1464
1465 auto subTitle = AceType::DynamicCast<FrameNode>(hostNode->GetSubtitle());
1466 if (subTitle) {
1467 auto property = subTitle->GetLayoutProperty<TextLayoutProperty>();
1468 if (property) {
1469 DumpTitleProperty(property, false);
1470 }
1471 }
1472 }
1473
OnLanguageConfigurationUpdate()1474 void TitleBarPattern::OnLanguageConfigurationUpdate()
1475 {
1476 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1477 CHECK_NULL_VOID(titleBarNode);
1478 auto backButtonNode = AceType::DynamicCast<FrameNode>(titleBarNode->GetBackButton());
1479 CHECK_NULL_VOID(backButtonNode);
1480 auto theme = NavigationGetTheme();
1481 std::string message = theme ? theme->GetNavigationBack() : "";
1482 NavigationTitleUtil::SetAccessibility(backButtonNode, message);
1483 }
1484
GetTitleBarHeightLessThanMaxBarHeight() const1485 float TitleBarPattern::GetTitleBarHeightLessThanMaxBarHeight() const
1486 {
1487 auto titleBarNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1488 CHECK_NULL_RETURN(titleBarNode, 0.f);
1489 auto titleBarLayoutProperty = titleBarNode->GetLayoutProperty<TitleBarLayoutProperty>();
1490 CHECK_NULL_RETURN(titleBarLayoutProperty, 0.f);
1491 auto titleMode = titleBarLayoutProperty->GetTitleModeValue(NavigationTitleMode::FREE);
1492 if (titleMode != NavigationTitleMode::FREE) {
1493 return 0.f;
1494 }
1495 auto barStyle = options_.brOptions.barStyle.value_or(BarStyle::STANDARD);
1496 if (barStyle != BarStyle::STACK) {
1497 return 0.f;
1498 }
1499 return maxTitleBarHeight_ - currentTitleBarHeight_;
1500 }
1501
HandleLongPress(const RefPtr<FrameNode> & backButtonNode)1502 void TitleBarPattern::HandleLongPress(const RefPtr<FrameNode>& backButtonNode)
1503 {
1504 auto host = GetHost();
1505 CHECK_NULL_VOID(host);
1506 auto accessibilityProperty = backButtonNode->GetAccessibilityProperty<AccessibilityProperty>();
1507 CHECK_NULL_VOID(accessibilityProperty);
1508 auto message = accessibilityProperty->GetAccessibilityText();
1509 if (dialogNode_ != nullptr) {
1510 HandleLongPressActionEnd();
1511 }
1512
1513 auto backButtonIconNode = AceType::DynamicCast<FrameNode>(backButtonNode->GetFirstChild());
1514 CHECK_NULL_VOID(backButtonIconNode);
1515 if (backButtonIconNode->GetTag() == V2::SYMBOL_ETS_TAG) {
1516 dialogNode_ =
1517 AgingAdapationDialogUtil::ShowLongPressDialog(message, backButtonIconNode);
1518 return;
1519 }
1520 auto imageProperty = backButtonIconNode->GetLayoutProperty<ImageLayoutProperty>();
1521 CHECK_NULL_VOID(imageProperty);
1522 ImageSourceInfo imageSourceInfo = imageProperty->GetImageSourceInfoValue();
1523 dialogNode_ = AgingAdapationDialogUtil::ShowLongPressDialog(message, imageSourceInfo, host->GetThemeScopeId());
1524 }
1525
HandleLongPressActionEnd()1526 void TitleBarPattern::HandleLongPressActionEnd()
1527 {
1528 CHECK_NULL_VOID(dialogNode_);
1529 auto hostNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1530 CHECK_NULL_VOID(hostNode);
1531 auto pipeline = hostNode->GetContext();
1532 CHECK_NULL_VOID(pipeline);
1533 auto overlayManager = pipeline->GetOverlayManager();
1534 CHECK_NULL_VOID(overlayManager);
1535 overlayManager->CloseDialog(dialogNode_);
1536 dialogNode_ = nullptr;
1537 }
1538
InitBackButtonLongPressEvent(const RefPtr<FrameNode> & backButtonNode)1539 void TitleBarPattern::InitBackButtonLongPressEvent(const RefPtr<FrameNode>& backButtonNode)
1540 {
1541 auto gestureHub = backButtonNode->GetOrCreateGestureEventHub();
1542 CHECK_NULL_VOID(gestureHub);
1543
1544 auto longPressCallback = [weak = WeakClaim(this), weakNode = WeakClaim(RawPtr(backButtonNode))](
1545 GestureEvent& info) {
1546 auto pattern = weak.Upgrade();
1547 CHECK_NULL_VOID(pattern);
1548 auto backButtonNode = weakNode.Upgrade();
1549 CHECK_NULL_VOID(backButtonNode);
1550 pattern->HandleLongPress(backButtonNode);
1551 };
1552 longPressEvent_ = MakeRefPtr<LongPressEvent>(std::move(longPressCallback));
1553 gestureHub->SetLongPressEvent(longPressEvent_);
1554
1555 auto longPressRecognizer = gestureHub->GetLongPressRecognizer();
1556 CHECK_NULL_VOID(longPressRecognizer);
1557
1558 auto longPressEndCallback = [weak = WeakClaim(this)](GestureEvent& info) {
1559 auto pattern = weak.Upgrade();
1560 CHECK_NULL_VOID(pattern);
1561 pattern->HandleLongPressActionEnd();
1562 };
1563 longPressRecognizer->SetOnActionEnd(longPressEndCallback);
1564 }
1565
OnFontScaleConfigurationUpdate()1566 void TitleBarPattern::OnFontScaleConfigurationUpdate()
1567 {
1568 auto hostNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1569 CHECK_NULL_VOID(hostNode);
1570 auto pipeline = hostNode->GetContext();
1571 CHECK_NULL_VOID(pipeline);
1572 auto backButtonNode = AceType::DynamicCast<FrameNode>(hostNode->GetBackButton());
1573 CHECK_NULL_VOID(backButtonNode);
1574 if (LessNotEqual(pipeline->GetFontScale(), AgingAdapationDialogUtil::GetDialogBigFontSizeScale())) {
1575 auto gestureHub = backButtonNode->GetOrCreateGestureEventHub();
1576 CHECK_NULL_VOID(gestureHub);
1577 gestureHub->SetLongPressEvent(nullptr);
1578 auto longPressRecognizer = gestureHub->GetLongPressRecognizer();
1579 CHECK_NULL_VOID(longPressRecognizer);
1580 longPressRecognizer->SetOnActionEnd(nullptr);
1581 return;
1582 }
1583 InitBackButtonLongPressEvent(backButtonNode);
1584 }
1585
InitMenuDragAndLongPressEvent(const RefPtr<FrameNode> & menuNode,const std::vector<NG::BarItem> & menuItems)1586 void TitleBarPattern::InitMenuDragAndLongPressEvent(
1587 const RefPtr<FrameNode>& menuNode, const std::vector<NG::BarItem>& menuItems)
1588 {
1589 CHECK_NULL_VOID(menuNode);
1590 auto hostNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1591 CHECK_NULL_VOID(hostNode);
1592 auto pipeline = hostNode->GetContext();
1593 CHECK_NULL_VOID(pipeline);
1594 if (LessNotEqual(pipeline->GetFontScale(), AgingAdapationDialogUtil::GetDialogBigFontSizeScale())) {
1595 return;
1596 }
1597
1598 auto gestureHub = menuNode->GetOrCreateGestureEventHub();
1599 CHECK_NULL_VOID(gestureHub);
1600 InitMenuDragEvent(gestureHub, menuNode, menuItems);
1601 InitMenuLongPressEvent(gestureHub, menuNode, menuItems);
1602 auto accessibilityProperty = menuNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1603 CHECK_NULL_VOID(accessibilityProperty);
1604 accessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::NO_STR);
1605 }
1606
InitMenuDragEvent(const RefPtr<GestureEventHub> & gestureHub,const RefPtr<FrameNode> & menuNode,const std::vector<NG::BarItem> & menuItems)1607 void TitleBarPattern::InitMenuDragEvent(const RefPtr<GestureEventHub>& gestureHub, const RefPtr<FrameNode>& menuNode,
1608 const std::vector<NG::BarItem>& menuItems)
1609 {
1610 auto actionUpdateTask = [weakMenuNode = WeakPtr<FrameNode>(menuNode), menuItems, weak = WeakClaim(this)](
1611 const GestureEvent& info) {
1612 auto menuNode = weakMenuNode.Upgrade();
1613 CHECK_NULL_VOID(menuNode);
1614 auto pattern = weak.Upgrade();
1615 CHECK_NULL_VOID(pattern);
1616 auto host = pattern->GetHost();
1617 CHECK_NULL_VOID(host);
1618 auto menuItemNode =
1619 menuNode->FindChildByPosition(info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
1620 CHECK_NULL_VOID(menuItemNode);
1621 auto index = menuNode->GetChildIndex(menuItemNode);
1622 auto totalCount = menuNode->TotalChildCount();
1623 auto dialogNode = pattern->GetLargeFontPopUpDialogNode();
1624 if (dialogNode && index >= 0 && index < totalCount) {
1625 auto pipeline = menuNode->GetContextWithCheck();
1626 CHECK_NULL_VOID(pipeline);
1627 auto buttonTheme = pipeline->GetTheme<ButtonTheme>();
1628 CHECK_NULL_VOID(buttonTheme);
1629 auto buttonPattern = menuItemNode->GetPattern<ButtonPattern>();
1630 CHECK_NULL_VOID(buttonPattern);
1631 buttonPattern->SetClickedColor(buttonTheme->GetClickedColor());
1632 if (!pattern->GetMoveIndex().has_value()) {
1633 pattern->SetMoveIndex(index);
1634 }
1635 if (pattern->GetMoveIndex().value() != index) {
1636 auto renderContext = menuItemNode->GetRenderContext();
1637 CHECK_NULL_VOID(renderContext);
1638 renderContext->UpdateBackgroundColor(buttonTheme->GetClickedColor());
1639 pattern->HandleMenuLongPressActionEnd();
1640 pattern->SetMoveIndex(index);
1641 pattern->SetLargeFontPopUpDialogNode(NavigationTitleUtil::CreatePopupDialogNode(
1642 menuItemNode, menuItems, index, host->GetThemeScopeId()));
1643 }
1644 }
1645 };
1646
1647 auto dragEvent = AceType::MakeRefPtr<DragEvent>(nullptr, std::move(actionUpdateTask), nullptr, nullptr);
1648 PanDirection panDirection = { .type = PanDirection::ALL };
1649 gestureHub->SetDragEvent(dragEvent, panDirection, DEFAULT_PAN_FINGER, DEFAULT_PAN_DISTANCE);
1650 }
1651
InitMenuLongPressEvent(const RefPtr<GestureEventHub> & gestureHub,const RefPtr<FrameNode> & menuNode,const std::vector<NG::BarItem> & menuItems)1652 void TitleBarPattern::InitMenuLongPressEvent(const RefPtr<GestureEventHub>& gestureHub,
1653 const RefPtr<FrameNode>& menuNode, const std::vector<NG::BarItem>& menuItems)
1654 {
1655 auto longPressCallback = [weakTargetNode = WeakPtr<FrameNode>(menuNode), menuItems, weak = WeakClaim(this)](
1656 GestureEvent& info) {
1657 auto menuNode = weakTargetNode.Upgrade();
1658 CHECK_NULL_VOID(menuNode);
1659 auto pattern = weak.Upgrade();
1660 CHECK_NULL_VOID(pattern);
1661 pattern->HandleMenuLongPress(info, menuNode, menuItems);
1662 };
1663 auto longPressEvent = AceType::MakeRefPtr<LongPressEvent>(std::move(longPressCallback));
1664 gestureHub->SetLongPressEvent(longPressEvent);
1665
1666 auto longPressRecognizer = gestureHub->GetLongPressRecognizer();
1667 CHECK_NULL_VOID(longPressRecognizer);
1668
1669 auto longPressEndCallback = [weak = WeakClaim(this)](GestureEvent& info) {
1670 auto pattern = weak.Upgrade();
1671 CHECK_NULL_VOID(pattern);
1672 pattern->HandleMenuLongPressActionEnd();
1673 };
1674 longPressRecognizer->SetOnActionEnd(longPressEndCallback);
1675 }
1676
HandleMenuLongPress(const GestureEvent & info,const RefPtr<FrameNode> & menuNode,const std::vector<NG::BarItem> & menuItems)1677 void TitleBarPattern::HandleMenuLongPress(
1678 const GestureEvent& info, const RefPtr<FrameNode>& menuNode, const std::vector<NG::BarItem>& menuItems)
1679 {
1680 CHECK_NULL_VOID(menuNode);
1681 auto hostNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1682 CHECK_NULL_VOID(hostNode);
1683 auto pipeline = hostNode->GetContext();
1684 CHECK_NULL_VOID(pipeline);
1685 auto dialogTheme = pipeline->GetTheme<AgingAdapationDialogTheme>();
1686 CHECK_NULL_VOID(dialogTheme);
1687 float scale = pipeline->GetFontScale();
1688 if (LessNotEqual(scale, dialogTheme->GetBigFontSizeScale())) {
1689 TAG_LOGI(AceLogTag::ACE_NAVIGATION,
1690 "The current system font scale is %{public}f; dialogTheme font scale is %{public}f", scale,
1691 dialogTheme->GetBigFontSizeScale());
1692 return;
1693 }
1694 auto menuItemNode = menuNode->FindChildByPosition(info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
1695 CHECK_NULL_VOID(menuItemNode);
1696 auto index = menuNode->GetChildIndex(menuItemNode);
1697 auto dialogNode =
1698 NavigationTitleUtil::CreatePopupDialogNode(menuItemNode, menuItems, index, hostNode->GetThemeScopeId());
1699 CHECK_NULL_VOID(dialogNode);
1700 if (GetLargeFontPopUpDialogNode()) {
1701 HandleMenuLongPressActionEnd();
1702 }
1703 SetLargeFontPopUpDialogNode(dialogNode);
1704 }
1705
HandleMenuLongPressActionEnd()1706 void TitleBarPattern::HandleMenuLongPressActionEnd()
1707 {
1708 auto dialogNode = GetLargeFontPopUpDialogNode();
1709 CHECK_NULL_VOID(dialogNode);
1710 auto hostNode = AceType::DynamicCast<TitleBarNode>(GetHost());
1711 CHECK_NULL_VOID(hostNode);
1712 auto pipeline = hostNode->GetContext();
1713 CHECK_NULL_VOID(pipeline);
1714 auto menuNode = AceType::DynamicCast<FrameNode>(hostNode->GetMenu());
1715 CHECK_NULL_VOID(menuNode);
1716 if (moveIndex_.has_value()) {
1717 auto menuItemNode = AceType::DynamicCast<FrameNode>(menuNode->GetChildAtIndex(moveIndex_.value()));
1718 CHECK_NULL_VOID(menuItemNode);
1719 auto renderContext = menuItemNode->GetRenderContext();
1720 CHECK_NULL_VOID(renderContext);
1721 auto theme = NavigationGetTheme();
1722 CHECK_NULL_VOID(theme);
1723 renderContext->UpdateBackgroundColor(theme->GetCompBackgroundColor());
1724 renderContext->ResetBlendBgColor();
1725 moveIndex_.reset();
1726 }
1727 auto overlayManager = pipeline->GetOverlayManager();
1728 CHECK_NULL_VOID(overlayManager);
1729 overlayManager->CloseDialog(dialogNode);
1730 SetLargeFontPopUpDialogNode(nullptr);
1731 }
1732
CustomizeExpandSafeArea()1733 bool TitleBarPattern::CustomizeExpandSafeArea()
1734 {
1735 auto host = GetHost();
1736 CHECK_NULL_RETURN(host, false);
1737 return RunCustomizeExpandIfNeeded(host);
1738 }
1739 } // namespace OHOS::Ace::NG
1740