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_GROUP_NODE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_NAVIGATION_GROUP_NODE_H
18 
19 #include <atomic>
20 #include <cstdint>
21 #include <list>
22 
23 #include "base/memory/referenced.h"
24 #include "core/animation/page_transition_common.h"
25 #include "core/components_ng/base/frame_node.h"
26 #include "core/components_ng/base/group_node.h"
27 #include "core/components_ng/pattern/navigation/bar_item_node.h"
28 #include "core/components_ng/pattern/navigation/navigation_declaration.h"
29 #include "core/components_ng/pattern/navigation/navigation_stack.h"
30 #include "core/components_ng/pattern/navigation/title_bar_node.h"
31 #include "core/components_ng/pattern/navrouter/navdestination_group_node.h"
32 #include "core/components_ng/pattern/navrouter/navrouter_pattern.h"
33 #include "core/components_ng/property/property.h"
34 
35 namespace OHOS::Ace::NG {
36 class InspectorFilter;
37 
38 class ACE_EXPORT NavigationGroupNode : public GroupNode {
DECLARE_ACE_TYPE(NavigationGroupNode,GroupNode)39     DECLARE_ACE_TYPE(NavigationGroupNode, GroupNode)
40 public:
41     NavigationGroupNode(const std::string& tag, int32_t nodeId, const RefPtr<Pattern>& pattern)
42         : GroupNode(tag, nodeId, pattern)
43     {}
44 
45     ~NavigationGroupNode() override;
46 
47     using AnimationFinishCallback = std::function<void()>;
48 
49     void AddChildToGroup(const RefPtr<UINode>& child, int32_t slot = DEFAULT_NODE_SLOT) override;
50 
51     // remain child needs to keep to use pop animation
52     void UpdateNavDestinationNodeWithoutMarkDirty(const RefPtr<UINode>& remainChild, bool modeChange = false);
53     static RefPtr<NavigationGroupNode> GetOrCreateGroupNode(
54         const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator);
55 
IsAtomicNode()56     bool IsAtomicNode() const override
57     {
58         return false;
59     }
60 
SetNavBarNode(const RefPtr<UINode> & navBarNode)61     void SetNavBarNode(const RefPtr<UINode>& navBarNode)
62     {
63         navBarNode_ = navBarNode;
64     }
65 
GetNavBarNode()66     const RefPtr<UINode>& GetNavBarNode() const
67     {
68         return navBarNode_;
69     }
70 
SetContentNode(const RefPtr<UINode> & contentNode)71     void SetContentNode(const RefPtr<UINode>& contentNode)
72     {
73         contentNode_ = contentNode;
74     }
75 
GetContentNode()76     const RefPtr<UINode>& GetContentNode() const
77     {
78         return contentNode_;
79     }
80 
SetDividerNode(const RefPtr<UINode> & dividerNode)81     void SetDividerNode(const RefPtr<UINode>& dividerNode)
82     {
83         dividerNode_ = dividerNode;
84     }
85 
GetDividerNode()86     const RefPtr<UINode>& GetDividerNode() const
87     {
88         return dividerNode_;
89     }
90 
GetCurId()91     const std::string& GetCurId() const
92     {
93         return curId_;
94     }
95 
GetIsModeChange()96     bool GetIsModeChange() const
97     {
98         return isModeChange_;
99     }
100 
SetIsModeChange(bool isModeChange)101     void SetIsModeChange(bool isModeChange)
102     {
103         isModeChange_ = isModeChange;
104     }
105 
GetNeedSetInvisible()106     bool GetNeedSetInvisible() const
107     {
108         return needSetInvisible_;
109     }
110 
SetNeedSetInvisible(bool needSetInvisible)111     void SetNeedSetInvisible(bool needSetInvisible)
112     {
113         needSetInvisible_ = needSetInvisible;
114     }
115 
IsOnModeSwitchAnimation()116     bool IsOnModeSwitchAnimation()
117     {
118         return isOnModeSwitchAnimation_;
119     }
120 
SetDoingModeSwitchAnimationFlag(bool isOnAnimation)121     void SetDoingModeSwitchAnimationFlag(bool isOnAnimation)
122     {
123         isOnModeSwitchAnimation_ = isOnAnimation;
124     }
125 
GetPushAnimations()126     std::list<std::shared_ptr<AnimationUtils::Animation>>& GetPushAnimations()
127     {
128         return pushAnimations_;
129     }
130 
GetPopAnimations()131     std::list<std::shared_ptr<AnimationUtils::Animation>>& GetPopAnimations()
132     {
133         return popAnimations_;
134     }
135 
CleanPushAnimations()136     void CleanPushAnimations()
137     {
138         pushAnimations_.clear();
139     }
140 
CleanPopAnimations()141     void CleanPopAnimations()
142     {
143         popAnimations_.clear();
144     }
145 
146     bool CheckCanHandleBack(bool& isEntry);
147 
148     void OnInspectorIdUpdate(const std::string& id) override;
149 
150     bool HandleBack(const RefPtr<FrameNode>& node, bool isLastChild, bool isOverride);
151 
152     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override;
153     static RefPtr<UINode> GetNavDestinationNode(RefPtr<UINode> uiNode);
154     void SetBackButtonEvent(const RefPtr<NavDestinationGroupNode>& navDestination);
155 
156     void TransitionWithPop(const RefPtr<FrameNode>& preNode, const RefPtr<FrameNode>& curNode, bool isNavBar = false);
157     void TransitionWithPush(const RefPtr<FrameNode>& preNode, const RefPtr<FrameNode>& curNode, bool isNavBar = false);
158     virtual void CreateAnimationWithPop(const RefPtr<FrameNode>& preNode, const RefPtr<FrameNode>& curNode,
159         const AnimationFinishCallback finishCallback, bool isNavBar = false);
160     virtual void CreateAnimationWithPush(const RefPtr<FrameNode>& preNode, const RefPtr<FrameNode>& curNode,
161         const AnimationFinishCallback finishCallback, bool isNavBar = false);
162 
163     std::shared_ptr<AnimationUtils::Animation> BackButtonAnimation(
164         const RefPtr<FrameNode>& backButtonNode, bool isTransitionIn);
165     std::shared_ptr<AnimationUtils::Animation> MaskAnimation(const RefPtr<FrameNode>& curNode, bool isTransitionIn);
166     std::shared_ptr<AnimationUtils::Animation> TitleOpacityAnimation(
167         const RefPtr<FrameNode>& node, bool isTransitionOut);
168     void TransitionWithReplace(const RefPtr<FrameNode>& preNode, const RefPtr<FrameNode>& curNode, bool isNavBar);
169     void DealNavigationExit(const RefPtr<FrameNode>& preNode, bool isNavBar, bool isAnimated = true);
170     void NotifyPageHide();
171     void UpdateLastStandardIndex();
172 
GetPreLastStandardIndex()173     int32_t GetPreLastStandardIndex() const
174     {
175         return preLastStandardIndex_;
176     }
177 
178     void PreNodeFinishCallback(const RefPtr<FrameNode>& preNode);
179     void CreateAnimationWithDialogPop(const AnimationFinishCallback callback,
180     const std::vector<WeakPtr<FrameNode>> prevNavList, const std::vector<WeakPtr<FrameNode>> curNavList);
181     void CreateAnimationWithDialogPush(const AnimationFinishCallback callback,
182     const std::vector<WeakPtr<FrameNode>> prevNavList, const std::vector<WeakPtr<FrameNode>> curNavList);
183     void TransitionWithDialogPush(const RefPtr<FrameNode>& preNode, const RefPtr<FrameNode>& curNode,
184         bool isNavBar = false);
185     void TransitionWithDialogPop(const RefPtr<FrameNode>& preNode, const RefPtr<FrameNode>& curNode,
186         bool isNavBar = false);
187     void StartDialogtransition(const RefPtr<FrameNode>& preNode, const RefPtr<FrameNode>& curNode,
188         bool isTransitionIn);
189 
190     void InitPopPreList(const RefPtr<FrameNode>& preNode, std::vector<WeakPtr<FrameNode>>& preNavList);
191     void InitPopCurList(const RefPtr<FrameNode>& curNode, std::vector<WeakPtr<FrameNode>>& curNavList,
192         bool isNavbarNeedAnimation);
193     void InitPushPreList(const RefPtr<FrameNode>& preNode, std::vector<WeakPtr<FrameNode>>& prevNavList,
194         bool isNavbarNeedAnimation);
195     void InitPushCurList(const RefPtr<FrameNode>& curNode, std::vector<WeakPtr<FrameNode>>& curNavList);
196 
197     std::vector<WeakPtr<NavDestinationGroupNode>> FindNodesPoped(const RefPtr<FrameNode>& preNode,
198         const RefPtr<FrameNode>& curNode);
199     void DialogTransitionPopAnimation(const RefPtr<FrameNode>& preNode, const RefPtr<FrameNode>& curNode,
200         AnimationOption option);
201     void DialogTransitionPushAnimation(const RefPtr<FrameNode>& preNode, const RefPtr<FrameNode>& curNode,
202         AnimationOption option);
203     void InitDialogTransition(const RefPtr<NavDestinationGroupNode>& node, bool isZeroY);
204 
GetLastStandardIndex()205     int32_t GetLastStandardIndex() const
206     {
207         return lastStandardIndex_;
208     }
209     AnimationOption CreateAnimationOption(const RefPtr<Curve>& curve, FillMode mode,
210         int32_t duration, const AnimationFinishCallback& callback);
211     NavigationMode GetNavigationMode();
212 
SetIsOnAnimation(bool isOnAnimation)213     void SetIsOnAnimation(bool isOnAnimation)
214     {
215         isOnAnimation_ = isOnAnimation;
216     }
217     RefPtr<FrameNode> GetTopDestination();
218     void OnDetachFromMainTree(bool recursive, PipelineContext* context = nullptr) override;
219     void OnAttachToMainTree(bool recursive) override;
220 
221     void FireHideNodeChange(NavDestinationLifecycle lifecycle);
222 
ReduceModeSwitchAnimationCnt()223     void ReduceModeSwitchAnimationCnt()
224     {
225         --modeSwitchAnimationCnt_;
226     }
227 
IncreaseModeSwitchAnimationCnt()228     void IncreaseModeSwitchAnimationCnt()
229     {
230         ++modeSwitchAnimationCnt_;
231     }
232 
GetModeSwitchAnimationCnt()233     int32_t GetModeSwitchAnimationCnt()
234     {
235         return modeSwitchAnimationCnt_;
236     }
237 
238     float CheckLanguageDirection();
239 
240     void RemoveDialogDestination(bool isReplace = false);
241     void AddDestinationNode(const RefPtr<UINode>& parent);
GetParentDestinationNode()242     WeakPtr<NavDestinationGroupNode> GetParentDestinationNode() const
243     {
244         return parentDestinationNode_;
245     }
SetNavigationPathInfo(const std::string & moduleName,const std::string & pagePath)246     void SetNavigationPathInfo(const std::string& moduleName, const std::string& pagePath)
247     {
248         navigationPathInfo_ = pagePath;
249         navigationModuleName_ = moduleName;
250     }
251 
GetNavigationPathInfo()252     const std::string& GetNavigationPathInfo() const
253     {
254         return navigationPathInfo_;
255     }
256 
SetDragBarNode(const RefPtr<UINode> & dragNode)257     void SetDragBarNode(const RefPtr<UINode>& dragNode)
258     {
259         dragBarNode_ = dragNode;
260     }
261 
GetDragBarNode()262     const RefPtr<UINode>& GetDragBarNode() const
263     {
264         return dragBarNode_;
265     }
266 
CleanHideNodes()267     void CleanHideNodes()
268     {
269         hideNodes_.clear();
270     }
271 
GetHideNodes()272     std::vector<std::pair<RefPtr<NavDestinationGroupNode>, bool>> GetHideNodes() const
273     {
274         return hideNodes_;
275     }
276 
SetRecoverable(bool recoverable)277     void SetRecoverable(bool recoverable)
278     {
279         recoverable_ = recoverable;
280     }
281 
CanRecovery()282     bool CanRecovery() const
283     {
284         return recoverable_ && !curId_.empty();
285     }
286 
287 protected:
288     std::list<std::shared_ptr<AnimationUtils::Animation>> pushAnimations_;
289     std::list<std::shared_ptr<AnimationUtils::Animation>> popAnimations_;
290 private:
291     bool UpdateNavDestinationVisibility(const RefPtr<NavDestinationGroupNode>& navDestination,
292         const RefPtr<UINode>& remainChild, int32_t index, size_t destinationSize,
293         const RefPtr<UINode>& preLastStandardNode);
294     bool ReorderNavDestination(
295         const std::vector<std::pair<std::string, RefPtr<UINode>>>& navDestinationNodes,
296         RefPtr<FrameNode>& navigationContentNode, int32_t& slot, bool& hasChanged);
297     void RemoveRedundantNavDestination(RefPtr<FrameNode>& navigationContentNode,
298         const RefPtr<UINode>& remainChild, int32_t slot, bool& hasChanged,
299         const RefPtr<NavDestinationGroupNode>& preLastStandardNode);
300     void ReorderAnimatingDestination(RefPtr<FrameNode>& navigationContentNode, RefPtr<UINode>& maxAnimatingDestination,
301         RefPtr<UINode>& remainDestination, RefPtr<UINode>& curTopDestination);
302     bool FindNavigationParent(const std::string& parentName);
303     void DealRemoveDestination(const RefPtr<NavDestinationGroupNode>& destination);
304     RefPtr<FrameNode> TransitionAnimationIsValid(const RefPtr<FrameNode>& node, bool isNavBar);
305 
306     RefPtr<UINode> navBarNode_;
307     RefPtr<UINode> contentNode_;
308     RefPtr<UINode> dividerNode_;
309     RefPtr<UINode> dragBarNode_;
310     WeakPtr<NavDestinationGroupNode> parentDestinationNode_;
311     // dialog hideNodes, if is true, nodes need remove
312     std::vector<std::pair<RefPtr<NavDestinationGroupNode>, bool>> hideNodes_;
313     std::vector<RefPtr<NavDestinationGroupNode>> showNodes_;
314     int32_t lastStandardIndex_ = -1;
315     std::atomic_int32_t modeSwitchAnimationCnt_ = 0;
316     bool isOnAnimation_ { false };
317     bool isModeChange_ { false };
318     bool needSetInvisible_ { false };
319     bool isOnModeSwitchAnimation_ { false };
320     bool recoverable_ { false };
321     std::string curId_;
322     std::string navigationPathInfo_;
323     std::string navigationModuleName_;
324     int32_t preLastStandardIndex_ = -1;
325 };
326 } // namespace OHOS::Ace::NG
327 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_NAVIGATION_GROUP_NODE_H
328