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