• 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/navrouter/navrouter_group_node.h"
17 
18 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
19 
20 namespace OHOS::Ace::NG {
GetOrCreateGroupNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)21 RefPtr<NavRouterGroupNode> NavRouterGroupNode::GetOrCreateGroupNode(
22     const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
23 {
24     auto frameNode = GetFrameNode(tag, nodeId);
25     CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<NavRouterGroupNode>(frameNode));
26     auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
27     auto navRouterGroupNode = AceType::MakeRefPtr<NavRouterGroupNode>(tag, nodeId, pattern);
28     navRouterGroupNode->InitializePatternAndContext();
29     ElementRegister::GetInstance()->AddUINode(navRouterGroupNode);
30     return navRouterGroupNode;
31 }
32 
AddChildToGroup(const RefPtr<UINode> & child,int32_t slot)33 void NavRouterGroupNode::AddChildToGroup(const RefPtr<UINode>& child, int32_t slot)
34 {
35     auto navDestination = AceType::DynamicCast<NavDestinationGroupNode>(child);
36     if (navDestination) {
37         SetNavDestinationNode(navDestination);
38         auto navDestinationNode = AceType::DynamicCast<FrameNode>(child);
39         CHECK_NULL_VOID(navDestinationNode);
40         auto navDestinationEventHub =
41             AceType::DynamicCast<NavDestinationEventHub>(navDestinationNode->GetOrCreateEventHub<EventHub>());
42         CHECK_NULL_VOID(navDestinationEventHub);
43         auto eventHub = GetOrCreateEventHub<NavRouterEventHub>();
44         CHECK_NULL_VOID(eventHub);
45         navDestinationEventHub->SetOnStateChange(eventHub->GetOnStateChange());
46         return;
47     }
48     UINode::AddChild(child);
49 }
50 
DeleteChildFromGroup(int32_t slot)51 void NavRouterGroupNode::DeleteChildFromGroup(int32_t slot)
52 {
53     UINode::RemoveChildAtIndex(slot);
54 }
55 
OnDetachFromMainTree(bool recursive,PipelineContext * context)56 void NavRouterGroupNode::OnDetachFromMainTree(bool recursive, PipelineContext* context)
57 {
58     // remove node in navigation
59     do {
60         if (!navDestinationNode_) {
61             break;
62         }
63         auto navigationNode = weakNavigation_.Upgrade();
64         if (!navigationNode) {
65             break;
66         }
67         auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
68         auto stack = navigationPattern->GetNavigationStack();
69         if (!stack) {
70             break;
71         }
72         auto navDestinationPattern = AceType::DynamicCast<NavDestinationPattern>(
73             DynamicCast<NavDestinationGroupNode>(navDestinationNode_)->GetPattern());
74         stack->Remove(navDestinationPattern->GetName(), navDestinationNode_);
75     } while (false);
76     FrameNode::OnDetachFromMainTree(recursive, context);
77 }
78 
OnAttachToMainTree(bool recursive)79 void NavRouterGroupNode::OnAttachToMainTree(bool recursive)
80 {
81     if (!UseOffscreenProcess()) {
82         ProcessDestinationChangeEvent();
83     }
84     FrameNode::OnAttachToMainTree(recursive);
85 }
86 
OnOffscreenProcess(bool recursive)87 void NavRouterGroupNode::OnOffscreenProcess(bool recursive)
88 {
89     ProcessDestinationChangeEvent();
90     FrameNode::OnOffscreenProcess(recursive);
91 }
92 
ProcessDestinationChangeEvent()93 void NavRouterGroupNode::ProcessDestinationChangeEvent()
94 {
95     auto parent = GetParent();
96     while (parent) {
97         auto navigationNode = AceType::DynamicCast<NavigationGroupNode>(parent);
98         if (navigationNode) {
99             weakNavigation_ = WeakPtr<NavigationGroupNode>(navigationNode);
100             break;
101         }
102         parent = parent->GetParent();
103     }
104     auto onDestinationChange = [weak = WeakClaim(this)]() {
105         auto navRouter = weak.Upgrade();
106         CHECK_NULL_VOID(navRouter);
107         navRouter->AddNavDestinationToNavigation();
108     };
109     auto eventHub = GetOrCreateEventHub<NavRouterEventHub>();
110     CHECK_NULL_VOID(eventHub);
111     eventHub->SetOnDestinationChange(std::move(onDestinationChange));
112 }
113 
AddNavDestinationToNavigation()114 void NavRouterGroupNode::AddNavDestinationToNavigation()
115 {
116     auto navigationNode = weakNavigation_.Upgrade();
117     CHECK_NULL_VOID(navigationNode);
118     auto navigationPattern = navigationNode->GetPattern<NavigationPattern>();
119     CHECK_NULL_VOID(navigationPattern);
120     // get the navDestination under NavRouter
121     auto navDestination = AceType::DynamicCast<NavDestinationGroupNode>(GetNavDestinationNode());
122     auto currentNavDestination =
123         AceType::DynamicCast<NavDestinationGroupNode>(navigationPattern->GetNavDestinationNode());
124     // do nothing if this navDestination is already at the top
125     if (navDestination && currentNavDestination == navDestination) {
126         return;
127     }
128     // deal with split mode without user provided navigation stack
129     if (navigationPattern->GetNavigationMode() == NavigationMode::SPLIT &&
130         !navigationPattern->GetNavigationStackProvided()) {
131         navigationPattern->CleanStack();
132         navigationPattern->UpdateAnimatedValue(false);
133     } else {
134         navigationPattern->UpdateAnimatedValue(true);
135     }
136 
137     auto navRouterPattern = GetPattern<NavRouterPattern>();
138     CHECK_NULL_VOID(navRouterPattern);
139     auto navigationStack = navigationPattern->GetNavigationStack();
140     auto routeInfo = navRouterPattern->GetRouteInfo();
141     std::string name;
142     auto navRouteMode = navRouterPattern->GetNavRouteMode();
143     if (routeInfo) {
144         // create navDestination with routeInfo
145         name = routeInfo->GetName();
146         RefPtr<UINode> uiNode = navigationStack->GetFromCacheNode(name);
147         if (uiNode == nullptr) {
148             uiNode = navigationStack->CreateNodeByRouteInfo(routeInfo, navigationPattern->GetParentCustomNode());
149         }
150 
151         navigationPattern->AddNavDestinationNode(name, uiNode, navRouteMode, routeInfo);
152         auto navRouterEventHub = GetOrCreateEventHub<NavRouterEventHub>();
153         CHECK_NULL_VOID(navRouterEventHub);
154         if (uiNode) {
155             navigationPattern->AddOnStateChangeItem(uiNode->GetId(), navRouterEventHub->GetOnStateChange());
156         }
157         navDestination = AceType::DynamicCast<NavDestinationGroupNode>(
158             NavigationGroupNode::GetNavDestinationNode(uiNode));
159     } else if (navDestination) {
160         auto navDestinationPattern = navDestination->GetPattern<NavDestinationPattern>();
161         CHECK_NULL_VOID(navDestinationPattern);
162         navDestination->SetFromNavrouterAndNoRouteInfo(true);
163         auto shallowBuilder = navDestinationPattern->GetShallowBuilder();
164         if (shallowBuilder && navRouteMode != NavRouteMode::PUSH) {
165             shallowBuilder->MarkIsExecuteDeepRenderDone(false);
166         }
167         auto destinationContent = navDestination->GetContentNode();
168         if (destinationContent && navRouteMode != NavRouteMode::PUSH) {
169             destinationContent->Clean();
170         }
171         WeakPtr<NavigationStack> stack = navigationPattern->GetNavigationStack();
172         navDestinationPattern->SetNavigationStack(stack);
173         name = navDestinationPattern->GetName();
174         navigationPattern->AddNavDestinationNode(name, navDestination, navRouteMode);
175     }
176     if (navDestination) {
177         navDestination->SetInCurrentStack(true);
178         auto navDestinationPattern = navDestination->GetPattern<NavDestinationPattern>();
179         navDestinationPattern->SetNavigationId(navigationNode->GetInspectorId().value_or(""));
180     }
181 
182     // when js navigationStack is provided, modifyDone will be called by state manager.
183     if (!navigationPattern->GetNavigationStackProvided()) {
184         navigationNode->MarkModifyDone();
185         navigationNode->MarkDirtyNode();
186     }
187 }
188 } // namespace OHOS::Ace::NG
189