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/nav_bar_node.h"
17
18 #include "core/components_ng/pattern/navigation/nav_bar_layout_property.h"
19 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
20 #include "core/components_ng/pattern/navigation/navigation_title_util.h"
21
22 namespace OHOS::Ace::NG {
23 constexpr float TITLE_OFFSET_PERCENT = 0.02f;
24
GetOrCreateNavBarNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)25 RefPtr<NavBarNode> NavBarNode::GetOrCreateNavBarNode(
26 const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
27 {
28 auto frameNode = GetFrameNode(tag, nodeId);
29 CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<NavBarNode>(frameNode));
30 auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
31 auto navBarNode = AceType::MakeRefPtr<NavBarNode>(tag, nodeId, pattern);
32 navBarNode->InitializePatternAndContext();
33 ElementRegister::GetInstance()->AddUINode(navBarNode);
34 return navBarNode;
35 }
36
AddChildToGroup(const RefPtr<UINode> & child,int32_t slot)37 void NavBarNode::AddChildToGroup(const RefPtr<UINode>& child, int32_t slot)
38 {
39 auto pattern = AceType::DynamicCast<NavigationPattern>(GetPattern());
40 CHECK_NULL_VOID(pattern);
41 auto contentNode = GetContentNode();
42 if (!contentNode) {
43 auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
44 contentNode = FrameNode::GetOrCreateFrameNode(
45 V2::NAVBAR_CONTENT_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
46 SetContentNode(contentNode);
47 AddChild(contentNode);
48
49 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
50 auto navBarContentNode = AceType::DynamicCast<FrameNode>(contentNode);
51 SafeAreaExpandOpts opts = { .type = SAFE_AREA_TYPE_SYSTEM | SAFE_AREA_TYPE_CUTOUT,
52 .edges = SAFE_AREA_EDGE_ALL };
53 navBarContentNode->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
54 }
55 }
56 contentNode->AddChild(child);
57 }
58
SystemTransitionPushStart(bool transitionIn)59 void NavBarNode::SystemTransitionPushStart(bool transitionIn)
60 {
61 if (transitionIn) {
62 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "can't push navBar");
63 return;
64 }
65
66 SetTransitionType(PageTransitionType::EXIT_PUSH);
67 GetRenderContext()->UpdateTranslateInXY({ 0.0f, 0.0f });
68 auto titleNode = AceType::DynamicCast<FrameNode>(GetTitleBarNode());
69 CHECK_NULL_VOID(titleNode);
70 titleNode->GetRenderContext()->UpdateTranslateInXY({ 0.0f, 0.0f });
71 }
72
InitSoftTransitionPop()73 void NavBarNode::InitSoftTransitionPop()
74 {
75 SetTransitionType(PageTransitionType::ENTER_POP);
76 auto renderContext = GetRenderContext();
77 CHECK_NULL_VOID(renderContext);
78 auto geometryNode = GetGeometryNode();
79 CHECK_NULL_VOID(geometryNode);
80 auto frameSize = geometryNode->GetFrameSize();
81 auto translate = CalcTranslateForTransitionPopStart(frameSize, true);
82 renderContext->UpdateTranslateInXY(translate);
83 }
84
SoftTransitionPushAction(bool isStart)85 void NavBarNode::SoftTransitionPushAction(bool isStart)
86 {
87 if (isStart) {
88 SetTransitionType(PageTransitionType::EXIT_PUSH);
89 }
90 GetRenderContext()->UpdateTranslateInXY({0.0f, 0.0f});
91 }
92
StartSoftTransitionPush()93 void NavBarNode::StartSoftTransitionPush()
94 {
95 auto geometryNode = GetGeometryNode();
96 CHECK_NULL_VOID(geometryNode);
97 auto frameSize = geometryNode->GetFrameSize();
98 auto renderContext = GetRenderContext();
99 CHECK_NULL_VOID(renderContext);
100 auto translate = CalcTranslateForTransitionPushEnd(frameSize, false);
101 renderContext->UpdateTranslateInXY(translate);
102 }
103
StartSoftTransitionPop()104 void NavBarNode::StartSoftTransitionPop()
105 {
106 GetRenderContext()->UpdateTranslateInXY({0.0f, 0.0f});
107 }
108
SystemTransitionPushEnd(bool transitionIn)109 void NavBarNode::SystemTransitionPushEnd(bool transitionIn)
110 {
111 if (transitionIn) {
112 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "can't push navBar");
113 return;
114 }
115
116 // start EXIT_PUSH transition animation
117 float isRTL = GetLanguageDirection();
118 auto geometryNode = GetGeometryNode();
119 CHECK_NULL_VOID(geometryNode);
120 auto frameSize = geometryNode->GetFrameSize();
121 auto renderContext = GetRenderContext();
122 CHECK_NULL_VOID(renderContext);
123 auto translate = CalcTranslateForTransitionPushEnd(frameSize, false);
124 renderContext->UpdateTranslateInXY(translate);
125
126 auto titleNode = AceType::DynamicCast<FrameNode>(GetTitleBarNode());
127 CHECK_NULL_VOID(titleNode);
128 titleNode->GetRenderContext()->UpdateTranslateInXY(
129 { frameSize.Width() * TITLE_OFFSET_PERCENT * isRTL, 0.0f });
130 }
131
SystemTransitionPushFinish(bool transitionIn,int32_t animationId)132 void NavBarNode::SystemTransitionPushFinish(bool transitionIn, int32_t animationId)
133 {
134 if (transitionIn) {
135 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "can't push navBar");
136 return;
137 }
138
139 GetRenderContext()->SetActualForegroundColor(Color::TRANSPARENT);
140 GetRenderContext()->UpdateTranslateInXY({ 0.0f, 0.0f });
141 auto titleNode = AceType::DynamicCast<FrameNode>(GetTitleBarNode());
142 CHECK_NULL_VOID(titleNode);
143 titleNode->GetRenderContext()->UpdateTranslateInXY({ 0.0f, 0.0f });
144 }
145
SystemTransitionPopStart(bool transitionIn)146 void NavBarNode::SystemTransitionPopStart(bool transitionIn)
147 {
148 if (!transitionIn) {
149 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "can't pop navBar");
150 return;
151 }
152
153 // navabr do enter pop initialization
154 float isRTL = GetLanguageDirection();
155 SetTransitionType(PageTransitionType::ENTER_POP);
156 auto renderContext = GetRenderContext();
157 CHECK_NULL_VOID(renderContext);
158 auto geometryNode = GetGeometryNode();
159 CHECK_NULL_VOID(geometryNode);
160 auto frameSize = geometryNode->GetFrameSize();
161 renderContext->RemoveClipWithRRect();
162 auto translate = CalcTranslateForTransitionPopStart(frameSize, true);
163 renderContext->UpdateTranslateInXY(translate);
164 auto curTitleBarNode = AceType::DynamicCast<FrameNode>(GetTitleBarNode());
165 CHECK_NULL_VOID(curTitleBarNode);
166 curTitleBarNode->GetRenderContext()->UpdateTranslateInXY(
167 { frameSize.Width() * TITLE_OFFSET_PERCENT * isRTL, 0.0f });
168 }
169
SystemTransitionPopEnd(bool transitionIn)170 void NavBarNode::SystemTransitionPopEnd(bool transitionIn)
171 {
172 if (!transitionIn) {
173 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "can't pop navBar");
174 return;
175 }
176
177 // navabr start to do ENTER_POP animation
178 GetRenderContext()->UpdateTranslateInXY({ 0.0f, 0.0f });
179 auto titleBarNode = AceType::DynamicCast<FrameNode>(GetTitleBarNode());
180 CHECK_NULL_VOID(titleBarNode);
181 titleBarNode->GetRenderContext()->UpdateTranslateInXY({ 0.0f, 0.0f });
182 }
183
IsNodeInvisible(const RefPtr<FrameNode> & node)184 bool NavBarNode::IsNodeInvisible(const RefPtr<FrameNode>& node)
185 {
186 auto navigation = DynamicCast<NavigationGroupNode>(node);
187 CHECK_NULL_RETURN(navigation, false);
188 auto lastStandardIndex = navigation->GetLastStandardIndex();
189 bool isInvisible = navigation->GetNavigationMode() == NavigationMode::STACK && lastStandardIndex >= 0;
190 return isInvisible;
191 }
192
GetNavigationNode()193 RefPtr<UINode> NavBarNode::GetNavigationNode()
194 {
195 return GetParentFrameNode();
196 }
197
ToDumpString()198 std::string NavBarNode::ToDumpString()
199 {
200 std::string dumpString;
201 dumpString.append("| [/]{ NavBar ");
202 dumpString.append("Visible? \"");
203 dumpString.append(IsVisible() ? "Yes" : "No");
204 int32_t count = 0;
205 int32_t depth = 0;
206 GetPageNodeCountAndDepth(&count, &depth);
207 dumpString.append("\", Count: " + std::to_string(count));
208 dumpString.append(", Depth: " + std::to_string(depth) + " }");
209 return dumpString;
210 }
211 } // namespace OHOS::Ace::NG
212