1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_NAVIGATION_TITLE_BAR_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_NAVIGATION_TITLE_BAR_PATTERN_H
18 
19 #include "base/memory/referenced.h"
20 #include "core/components_ng/base/ui_node.h"
21 #include "core/components_ng/pattern/navigation/navigation_options.h"
22 #include "core/components_ng/pattern/navigation/title_bar_accessibility_property.h"
23 #include "core/components_ng/pattern/navigation/title_bar_layout_algorithm.h"
24 #include "core/components_ng/pattern/navigation/title_bar_layout_property.h"
25 #include "core/components_ng/pattern/pattern.h"
26 
27 namespace OHOS::Ace::NG {
28 
29 class TitleBarPattern : public Pattern {
30     DECLARE_ACE_TYPE(TitleBarPattern, Pattern);
31 
32 public:
33     TitleBarPattern() = default;
34     ~TitleBarPattern() override = default;
35 
CreateLayoutProperty()36     RefPtr<LayoutProperty> CreateLayoutProperty() override
37     {
38         return MakeRefPtr<TitleBarLayoutProperty>();
39     }
40 
CreateAccessibilityProperty()41     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
42     {
43         return MakeRefPtr<TitleBarAccessibilityProperty>();
44     }
45 
CreateLayoutAlgorithm()46     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
47     {
48         auto titleBarLayoutAlgorithm = MakeRefPtr<TitleBarLayoutAlgorithm>();
49         titleBarLayoutAlgorithm->SetInitialTitleOffsetY(initialTitleOffsetY_);
50         titleBarLayoutAlgorithm->MarkIsInitialTitle(isInitialTitle_);
51         titleBarLayoutAlgorithm->SetInitialSubtitleOffsetY(initialSubtitleOffsetY_);
52         titleBarLayoutAlgorithm->MarkIsInitialSubtitle(isInitialSubtitle_);
53         titleBarLayoutAlgorithm->SetMinTitleHeight(minTitleHeight_);
54         return titleBarLayoutAlgorithm;
55     }
56 
IsAtomicNode()57     bool IsAtomicNode() const override
58     {
59         return false;
60     }
61 
62     void OnModifyDone() override;
63 
GetTempTitleBarHeight()64     float GetTempTitleBarHeight() const
65     {
66         return static_cast<float>(tempTitleBarHeight_.ConvertToPx());
67     }
68 
SetTempTitleBarHeightVp(float value)69     void SetTempTitleBarHeightVp(float value)
70     {
71         tempTitleBarHeight_.SetValue(Dimension(value).ConvertToVp());
72     }
73 
GetDefaultTitleBarHeight()74     float GetDefaultTitleBarHeight() const
75     {
76         return defaultTitleBarHeight_;
77     }
78 
GetTempTitleOffsetY()79     float GetTempTitleOffsetY() const
80     {
81         return tempTitleOffsetY_;
82     }
83 
GetTempSubTitleOffsetY()84     float GetTempSubTitleOffsetY() const
85     {
86         return tempSubTitleOffsetY_;
87     }
88 
GetMaxTitleBarHeight()89     float GetMaxTitleBarHeight() const
90     {
91         return maxTitleBarHeight_;
92     }
93 
94     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
95 
96     void InitTitleParam();
97 
98     bool IsHidden();
99 
IsInitialTitle()100     bool IsInitialTitle() const
101     {
102         return isInitialTitle_;
103     }
104 
MarkIsInitialTitle(bool isInitialTitle)105     void MarkIsInitialTitle(bool isInitialTitle)
106     {
107         isInitialTitle_ = isInitialTitle;
108     }
109 
IsInitialSubtitle()110     bool IsInitialSubtitle() const
111     {
112         return isInitialSubtitle_;
113     }
114 
MarkIsInitialSubtitle(bool isInitialSubtitle)115     void MarkIsInitialSubtitle(bool isInitialSubtitle)
116     {
117         isInitialSubtitle_ = isInitialSubtitle;
118     }
119 
120     void ProcessTitleDragUpdate(float offset);
121 
122     void OnColorConfigurationUpdate() override;
123 
GetCurrentOffset()124     float GetCurrentOffset()
125     {
126         return GetTempTitleBarHeight() - defaultTitleBarHeight_;
127     }
128 
SetOverDragOffset(float overDragOffset)129     void SetOverDragOffset(float overDragOffset)
130     {
131         overDragOffset_ = overDragOffset;
132     }
133 
GetOverDragOffset()134     float GetOverDragOffset() const
135     {
136         return overDragOffset_;
137     }
138 
IsTitleDraggedDown()139     bool IsTitleDraggedDown() const
140     {
141         if (NearZero(tempTitleBarHeight_.Value())) {
142             return true;
143         }
144         return GreatNotEqual(GetTempTitleBarHeight(), static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx()));
145     }
146 
IsTitleFullStatus()147     bool IsTitleFullStatus() const
148     {
149         if (NearZero(tempTitleBarHeight_.Value())) {
150             return true;
151         }
152         GetMaxTitleBarHeight();
153         return GreatOrEqual(GetTempTitleBarHeight(), maxTitleBarHeight_);
154     }
155 
IsMinTitle()156     bool IsMinTitle() const
157     {
158         if (NearZero(tempTitleBarHeight_.Value())) {
159             return true;
160         }
161         GetMaxTitleBarHeight();
162         return LessOrEqual(GetTempTitleBarHeight(), maxTitleBarHeight_);
163     }
164 
IsCurrentMinTitle()165     bool IsCurrentMinTitle() const
166     {
167         if (NearZero(tempTitleBarHeight_.Value())) {
168             return true;
169         }
170         return LessOrEqual(GetTempTitleBarHeight(), static_cast<float>(SINGLE_LINE_TITLEBAR_HEIGHT.ConvertToPx()));
171     }
172 
IsCurrentMaxTitle()173     bool IsCurrentMaxTitle() const
174     {
175         if (NearZero(tempTitleBarHeight_.Value())) {
176             return false;
177         }
178         GetMaxTitleBarHeight();
179         return GreatOrEqual(GetTempTitleBarHeight(), maxTitleBarHeight_);
180     }
181 
IsFreeTitleUpdated()182     bool IsFreeTitleUpdated() const
183     {
184         return isFreeTitleUpdated_;
185     }
186 
GetNavigationTitleMode()187     NavigationTitleMode GetNavigationTitleMode() const
188     {
189         return titleMode_;
190     }
191 
SetCanOverDrag(bool CanOverDrag)192     void SetCanOverDrag(bool CanOverDrag)
193     {
194         CanOverDrag_ = CanOverDrag;
195     }
196 
SetTitleScaleChange(bool isTitleScaleChange)197     void SetTitleScaleChange(bool isTitleScaleChange)
198     {
199         isTitleScaleChange_ = isTitleScaleChange;
200     }
201 
SetCurrentTitleOffsetY(float currentTitleOffsetY)202     void SetCurrentTitleOffsetY(float currentTitleOffsetY)
203     {
204         currentTitleOffsetY_ = currentTitleOffsetY;
205     }
206 
SetCurrentTitleBarHeight(float currentTitleBarHeight)207     void SetCurrentTitleBarHeight(float currentTitleBarHeight)
208     {
209         currentTitleBarHeight_ = currentTitleBarHeight;
210     }
211 
SetIsTitleChanged(bool isTitleChanged)212     void SetIsTitleChanged(bool isTitleChanged)
213     {
214         isTitleChanged_ = isTitleChanged;
215     }
216 
217     void OnCoordScrollStart();
218     float OnCoordScrollUpdate(float offset);
219     void OnCoordScrollEnd();
220 
221     void SetTitlebarOptions(NavigationTitlebarOptions&& opt);
222 
GetTitleBarOptions()223     NavigationTitlebarOptions GetTitleBarOptions() const
224     {
225         return options_;
226     }
227 
GetLargeFontPopUpDialogNode()228     RefPtr<FrameNode> GetLargeFontPopUpDialogNode() const
229     {
230         return largeFontPopUpDialogNode_.Upgrade();
231     }
232 
SetLargeFontPopUpDialogNode(const WeakPtr<FrameNode> & dialogNode)233     void SetLargeFontPopUpDialogNode(const WeakPtr<FrameNode>& dialogNode)
234     {
235         largeFontPopUpDialogNode_ = dialogNode;
236     }
237 
GetMoveIndex()238     std::optional<int32_t> GetMoveIndex() const
239     {
240         return moveIndex_;
241     }
242 
SetMoveIndex(int32_t index)243     void SetMoveIndex(int32_t index)
244     {
245         moveIndex_ = index;
246     }
247 
248     void UpdateNavBarTitleProperty(const RefPtr<TitleBarNode>& hostNode);
249     void UpdateNavDesTitleProperty(const RefPtr<TitleBarNode>& hostNode);
250 
IsFontSizeSettedByDeveloper()251     bool IsFontSizeSettedByDeveloper() const
252     {
253         return isFontSizeSettedByDeveloper_;
254     }
255 
SetNeedResetMainTitleProperty(bool reset)256     void SetNeedResetMainTitleProperty(bool reset)
257     {
258         shouldResetMainTitleProperty_ = reset;
259     }
SetNeedResetSubTitleProperty(bool reset)260     void SetNeedResetSubTitleProperty(bool reset)
261     {
262         shouldResetSubTitleProperty_ = reset;
263     }
264 
265     float GetTitleBarHeightLessThanMaxBarHeight() const;
UpdateHalfFoldHoverChangedCallbackId(std::optional<int32_t> id)266     void UpdateHalfFoldHoverChangedCallbackId(std::optional<int32_t> id)
267     {
268         halfFoldHoverChangedCallbackId_ = id;
269     }
270 
HasHalfFoldHoverChangedCallbackId()271     bool HasHalfFoldHoverChangedCallbackId()
272     {
273         return halfFoldHoverChangedCallbackId_.has_value();
274     }
275 
276     void InitFoldCreaseRegion();
277 
GetFoldCreaseRects()278     std::vector<Rect> GetFoldCreaseRects()
279     {
280         return currentFoldCreaseRegion_;
281     }
282 
OnAttachToMainTree()283     void OnAttachToMainTree() override
284     {
285         auto host = GetHost();
286         CHECK_NULL_VOID(host);
287         InitFoldCreaseRegion();
288     }
289 
290     void InitBackButtonLongPressEvent(const RefPtr<FrameNode>& backButtonNode);
291 
GetBackButtonDialogNode()292     RefPtr<FrameNode> GetBackButtonDialogNode() const
293     {
294         return dialogNode_;
295     }
296 
297 private:
298     void TransformScale(float overDragOffset, const RefPtr<FrameNode>& frameNode);
299 
300     void ClearDragState();
301     float GetSubtitleOpacity();
302     Dimension GetFontSize(float offset);
303     float GetMappedOffset(float offset);
304     void SpringAnimation(float startPos, float endPos);
305     void UpdateScaleByDragOverDragOffset(float overDragOffset);
306     void AnimateTo(float offset, bool isFullTitleMode = false);
307 
308     void OnAttachToFrameNode() override;
309     void OnDetachFromFrameNode(FrameNode* frameNode) override;
310 
311     void HandleDragStart(const GestureEvent& info);
312     void HandleDragUpdate(const GestureEvent& info);
313     void HandleDragEnd(double dragVelocity);
314 
315     void SetMaxTitleBarHeight();
316     void SetTempTitleBarHeight(float offsetY);
317     void SetTempTitleOffsetY();
318     void SetTempSubTitleOffsetY();
319     void SetDefaultTitleFontSize();
320     void SetDefaultSubtitleOpacity();
321 
322     float GetTitleHeight();
323     float GetSubTitleOffsetY();
324     void UpdateTitleFontSize(const Dimension& tempTitleFontSize);
325     void UpdateSubTitleOpacity(const double &value);
326     void UpdateTitleModeChange();
327     void MountTitle(const RefPtr<TitleBarNode>& hostNode);
328 
329     void UpdateTitleBarByCoordScroll(float offset);
330     void SetTitleStyleByCoordScrollOffset(float offset);
331     float CalculateHandledOffsetMinTitle(float offset, float lastCordScrollOffset);
332     float CalculateHandledOffsetMaxTitle(float offset, float lastCordScrollOffset);
333     float CalculateHandledOffsetBetweenMinAndMaxTitle(float offset, float lastCordScrollOffset);
CleanSpringAnimation()334     void CleanSpringAnimation()
335     {
336         springAnimation_.reset();
337     }
CleanAnimation()338     void CleanAnimation()
339     {
340         animation_.reset();
341     }
342     void UpdateBackgroundStyle(RefPtr<FrameNode>& host);
343     void MountSubTitle(const RefPtr<TitleBarNode>& hostNode);
344     void ResetMainTitleProperty(const RefPtr<FrameNode>& textNode,
345         const RefPtr<TitleBarLayoutProperty>& titleBarLayoutProperty,
346         NavigationTitleMode titleMode, bool hasSubTitle, bool parentIsNavDest);
347     void ResetSubTitleProperty(const RefPtr<FrameNode>& textNode,
348         NavigationTitleMode titleMode, bool parentIsNavDest);
349     void ApplyTitleModifierIfNeeded(const RefPtr<TitleBarNode>& hostNode);
350     void ApplyTitleModifier(const RefPtr<FrameNode>& textNode,
351         const TextStyleApplyFunc& applyFunc, bool needCheckFontSizeIsSetted);
352     void DumpInfo() override;
353 
354     void HandleLongPress(const RefPtr<FrameNode>& backButtonNode);
355     void HandleLongPressActionEnd();
356     void OnFontScaleConfigurationUpdate() override;
357 
358     RefPtr<PanEvent> panEvent_;
359     std::shared_ptr<AnimationUtils::Animation> springAnimation_;
360     std::shared_ptr<AnimationUtils::Animation> animation_;
361     std::optional<Dimension> fontSize_ = 0.0_fp;
362     std::optional<float> opacity_;
363 
364     float overDragOffset_ = 0.0f;
365     float maxTitleBarHeight_ = 0.0f;
366     float defaultTitleBarHeight_ = 0.0f;
367     Dimension titleSpaceVertical_;
368     Dimension tempTitleBarHeight_ = 0.0_vp;
369     float minTitleOffsetY_ = 0.0f;
370     float maxTitleOffsetY_ = 0.0f;
371     // ratio of titleOffsetY difference and titleBarHeight difference
372     float moveRatio_ = 0.0f;
373     float titleMoveDistance_ = 0.0f;
374     float defaultTitleOffsetY_ = 0.0f;
375     float defaultSubtitleOffsetY_ = 0.0f;
376     float tempTitleOffsetY_ = 0.0f;
377     float tempSubTitleOffsetY_ = 0.0f;
378 
379     Dimension defaultTitleFontSize_;
380     // ratio of fontSize difference and titleBarHeight difference
381     double fontSizeRatio_ = 0.0f;
382 
383     float defaultSubtitleOpacity_;
384     // ratio of opacity difference and titleBarHeight difference
385     double opacityRatio_ = 0.0f;
386 
387     float initialTitleOffsetY_ = 0.0f;
388     bool isInitialTitle_ = true;
389     float initialSubtitleOffsetY_ = 0.0f;
390     bool isInitialSubtitle_ = true;
391     float minTitleHeight_ = 0.0f;
392     bool CanOverDrag_ = true;
393     bool isTitleScaleChange_ = true;
394     bool isTitleChanged_ = false; // navigation Non-custom title changed
395     NavigationTitleMode titleMode_ = NavigationTitleMode::FREE;
396 
397     bool isFreeTitleUpdated_ = false;
398 
399     float coordScrollOffset_ = 0.0f;
400     float coordScrollFinalOffset_ = 0.0f;
401 
402     // the value before title bar expand safe area
403     float currentTitleOffsetY_ = 0.0f;
404     float currentTitleBarHeight_ = 0.0f;
405 
406     NavigationTitlebarOptions options_;
407 
408     WeakPtr<FrameNode> largeFontPopUpDialogNode_;
409     std::optional<int32_t> moveIndex_;
410 
411     bool isFontSizeSettedByDeveloper_ = false;
412     bool shouldResetMainTitleProperty_ = true;
413     bool shouldResetSubTitleProperty_ = true;
414 
415     RefPtr<LongPressEvent> longPressEvent_;
416     RefPtr<FrameNode> dialogNode_;
417 
418     std::optional<int32_t> halfFoldHoverChangedCallbackId_;
419     std::vector<Rect> currentFoldCreaseRegion_;
420 };
421 
422 } // namespace OHOS::Ace::NG
423 
424 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_NAVIGATION_TITLE_BAR_PATTERN_H
425