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 "base/memory/ace_type.h"
19 #include "core/common/container.h"
20 #include "base/memory/referenced.h"
21 #include "core/components_ng/base/inspector_filter.h"
22 #include "core/components_ng/base/view_stack_processor.h"
23 #include "core/components_ng/pattern/image/image_layout_property.h"
24 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
25 #include "core/components_ng/pattern/navigation/bar_item_node.h"
26 #include "core/components_ng/pattern/navigation/nav_bar_layout_property.h"
27 #include "core/components_ng/pattern/navigation/navigation_declaration.h"
28 #include "core/components_ng/pattern/navigation/navigation_pattern.h"
29 #include "core/components_ng/pattern/navigation/navigation_title_util.h"
30 #include "core/components_ng/pattern/text/text_layout_property.h"
31 #include "core/components_v2/inspector/inspector_constants.h"
32 #include "core/pipeline_ng/ui_task_scheduler.h"
33
34 namespace OHOS::Ace::NG {
35 constexpr float CONTENT_OFFSET_PERCENT = 0.2f;
36 constexpr float TITLE_OFFSET_PERCENT = 0.02f;
37
GetOrCreateNavBarNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)38 RefPtr<NavBarNode> NavBarNode::GetOrCreateNavBarNode(
39 const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
40 {
41 auto frameNode = GetFrameNode(tag, nodeId);
42 CHECK_NULL_RETURN(!frameNode, AceType::DynamicCast<NavBarNode>(frameNode));
43 auto pattern = patternCreator ? patternCreator() : MakeRefPtr<Pattern>();
44 auto navBarNode = AceType::MakeRefPtr<NavBarNode>(tag, nodeId, pattern);
45 navBarNode->InitializePatternAndContext();
46 ElementRegister::GetInstance()->AddUINode(navBarNode);
47 return navBarNode;
48 }
49
AddChildToGroup(const RefPtr<UINode> & child,int32_t slot)50 void NavBarNode::AddChildToGroup(const RefPtr<UINode>& child, int32_t slot)
51 {
52 auto pattern = AceType::DynamicCast<NavigationPattern>(GetPattern());
53 CHECK_NULL_VOID(pattern);
54 auto contentNode = GetContentNode();
55 if (!contentNode) {
56 auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
57 contentNode = FrameNode::GetOrCreateFrameNode(
58 V2::NAVBAR_CONTENT_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
59 SetContentNode(contentNode);
60 AddChild(contentNode);
61
62 if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
63 auto navBarContentNode = AceType::DynamicCast<FrameNode>(contentNode);
64 SafeAreaExpandOpts opts = { .type = SAFE_AREA_TYPE_SYSTEM | SAFE_AREA_TYPE_CUTOUT,
65 .edges = SAFE_AREA_EDGE_ALL };
66 navBarContentNode->GetLayoutProperty()->UpdateSafeAreaExpandOpts(opts);
67 }
68 }
69 contentNode->AddChild(child);
70 }
71
InitSystemTransitionPop()72 void NavBarNode::InitSystemTransitionPop()
73 {
74 // navabr do enter pop initialization
75 float isRTL = GetLanguageDirection();
76 SetTransitionType(PageTransitionType::ENTER_POP);
77 auto curFrameSize = GetGeometryNode()->GetFrameSize();
78 GetRenderContext()->RemoveClipWithRRect();
79 GetRenderContext()->UpdateTranslateInXY({ -curFrameSize.Width() * CONTENT_OFFSET_PERCENT * isRTL, 0.0f });
80 auto curTitleBarNode = AceType::DynamicCast<FrameNode>(GetTitleBarNode());
81 CHECK_NULL_VOID(curTitleBarNode);
82 curTitleBarNode->GetRenderContext()->UpdateTranslateInXY(
83 { curFrameSize.Width() * TITLE_OFFSET_PERCENT * isRTL, 0.0f });
84 }
85
SystemTransitionPushAction(bool isStart)86 void NavBarNode::SystemTransitionPushAction(bool isStart)
87 {
88 // initialization or finish callBack
89 if (isStart) {
90 SetTransitionType(PageTransitionType::EXIT_PUSH);
91 } else {
92 GetRenderContext()->SetActualForegroundColor(Color::TRANSPARENT);
93 }
94 GetRenderContext()->UpdateTranslateInXY({ 0.0f, 0.0f });
95 auto titleNode = AceType::DynamicCast<FrameNode>(GetTitleBarNode());
96 CHECK_NULL_VOID(titleNode);
97 titleNode->GetRenderContext()->UpdateTranslateInXY({ 0.0f, 0.0f });
98 }
99
StartSystemTransitionPush()100 void NavBarNode::StartSystemTransitionPush()
101 {
102 // start EXIT_PUSH transition animation
103 float isRTL = GetLanguageDirection();
104 auto frameSize = GetGeometryNode()->GetFrameSize();
105 GetRenderContext()->UpdateTranslateInXY(
106 { -frameSize.Width() * CONTENT_OFFSET_PERCENT * isRTL, 0.0f });
107 auto titleNode = AceType::DynamicCast<FrameNode>(GetTitleBarNode());
108 CHECK_NULL_VOID(titleNode);
109 titleNode->GetRenderContext()->UpdateTranslateInXY(
110 { frameSize.Width() * TITLE_OFFSET_PERCENT * isRTL, 0.0f });
111 }
112
StartSystemTransitionPop()113 void NavBarNode::StartSystemTransitionPop()
114 {
115 // navabr start to do ENTER_POP animation
116 GetRenderContext()->UpdateTranslateInXY({ 0.0f, 0.0f });
117 auto titleBarNode = AceType::DynamicCast<FrameNode>(GetTitleBarNode());
118 CHECK_NULL_VOID(titleBarNode);
119 titleBarNode->GetRenderContext()->UpdateTranslateInXY({ 0.0f, 0.0f });
120 }
121
IsNodeInvisible(const RefPtr<FrameNode> & node)122 bool NavBarNode::IsNodeInvisible(const RefPtr<FrameNode>& node)
123 {
124 auto navigation = DynamicCast<NavigationGroupNode>(node);
125 CHECK_NULL_RETURN(navigation, false);
126 auto lastStandardIndex = navigation->GetLastStandardIndex();
127 bool isInvisible = navigation->GetNavigationMode() == NavigationMode::STACK && lastStandardIndex >= 0;
128 return isInvisible;
129 }
130 } // namespace OHOS::Ace::NG
131