• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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