1 /*
2 * Copyright (c) 2021-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/navigation_bar/navigation_container_component.h"
17
18 #include "core/components/box/box_component.h"
19 #include "core/components/display/display_component.h"
20 #include "core/components/flex/flex_component.h"
21 #include "core/components/flex/flex_item_component.h"
22 #include "core/components/navigation_bar/navigation_bar_component.h"
23 #include "core/components/navigation_bar/navigation_bar_component_v2.h"
24 #include "core/components/navigation_bar/navigation_container_element.h"
25 #include "core/components/navigation_bar/render_navigation_container.h"
26 #include "core/components/padding/padding_component.h"
27 #include "core/components/stage/stage_component.h"
28 #include "core/components/theme/theme_manager_impl.h"
29 namespace OHOS::Ace {
30
31 namespace {
32
33 static uint32_t g_navigationTabControllerId = 0;
34 constexpr int32_t BOTTOM_TAB_ICON_SIZE = 24;
35 constexpr int32_t BOTTOM_TAB_ICON_AND_TEXT_PADDING = 2;
36 constexpr double SECTION_INDEX_PART_WEIGHT = 1.0;
37 constexpr double SECTION_CONTENT_PART_WEIGHT = 2.0;
38
39 } // namespace
40
CreateRenderNode()41 RefPtr<RenderNode> NavigationContainerComponent::CreateRenderNode()
42 {
43 #ifndef WEARABLE_PRODUCT
44 return RenderNavigationContainer::Create();
45 #else
46 return RenderFlex::Create();
47 #endif
48 }
49
CreateElement()50 RefPtr<Element> NavigationContainerComponent::CreateElement()
51 {
52 #ifndef WEARABLE_PRODUCT
53 return AceType::MakeRefPtr<NavigationContainerElement>();
54 #else
55 return AceType::MakeRefPtr<FlexElement>();
56 #endif
57 }
58
GetGlobalTabControllerId()59 uint32_t NavigationContainerComponent::GetGlobalTabControllerId()
60 {
61 return ++g_navigationTabControllerId;
62 }
63
BuildToolBar(const RefPtr<NavigationDeclaration> & declaration,const RefPtr<TabController> & controller)64 RefPtr<ComposedComponent> NavigationContainerComponent::BuildToolBar(
65 const RefPtr<NavigationDeclaration>& declaration, const RefPtr<TabController>& controller)
66 {
67 #ifndef WEARABLE_PRODUCT
68 std::list<RefPtr<Component>> tabBarItems;
69 for (const auto& item : declaration->toolbarItems) {
70 if (!item->icon.empty()) {
71 auto itemContainer = AceType::MakeRefPtr<ColumnComponent>(
72 FlexAlign::CENTER, FlexAlign::CENTER, std::list<RefPtr<OHOS::Ace::Component>>());
73 auto iconBox = AceType::MakeRefPtr<BoxComponent>();
74 iconBox->SetChild(AceType::MakeRefPtr<ImageComponent>(item->icon));
75 iconBox->SetHeight(BOTTOM_TAB_ICON_SIZE, DimensionUnit::VP);
76 iconBox->SetWidth(BOTTOM_TAB_ICON_SIZE, DimensionUnit::VP);
77 itemContainer->AppendChild(iconBox);
78 auto padding = AceType::MakeRefPtr<PaddingComponent>();
79 padding->SetPaddingTop(Dimension(BOTTOM_TAB_ICON_AND_TEXT_PADDING, DimensionUnit::VP));
80 itemContainer->AppendChild(padding);
81 itemContainer->AppendChild(AceType::MakeRefPtr<TextComponent>(item->value));
82 tabBarItems.push_back(AceType::MakeRefPtr<TabBarItemComponent>(itemContainer));
83 } else {
84 tabBarItems.push_back(
85 AceType::MakeRefPtr<TabBarItemComponent>(AceType::MakeRefPtr<TextComponent>(item->value)));
86 }
87 }
88 auto tabBar = AceType::MakeRefPtr<TabBarComponent>(tabBarItems, controller);
89 auto theme = AceType::MakeRefPtr<ThemeManagerImpl>()->GetTheme<TabTheme>();
90 tabBar->InitBottomTabStyle(theme);
91
92 auto component = declaration->toolBarBuilder;
93 auto display = AceType::MakeRefPtr<DisplayComponent>();
94 if (component) {
95 display->SetChild(component);
96 } else {
97 display->SetChild(tabBar);
98 }
99 RefPtr<BoxComponent> tabBarBox = AceType::MakeRefPtr<BoxComponent>();
100 tabBarBox->SetChild(display);
101 tabBarBox->SetDeliverMinToChild(false);
102 tabBarBox->SetEnableDebugBoundary(true);
103 if (!declaration->HasToolBar()) {
104 display->SetOpacity(0.0, declaration->animationOption);
105 tabBarBox->SetHeight(Dimension(0.0, DimensionUnit::VP), declaration->animationOption);
106 } else {
107 display->SetOpacity(1.0, declaration->animationOption);
108 tabBarBox->SetHeight(theme->GetDefaultHeight(), declaration->animationOption);
109 }
110
111 return AceType::MakeRefPtr<ComposedComponent>("navigation", "navigationToolBarComposed", tabBarBox);
112 #else
113 return nullptr;
114 #endif
115 }
116
NeedSection() const117 bool NavigationContainerComponent::NeedSection() const
118 {
119 bool isSupportDeviceType = SystemProperties::GetDeviceType() == DeviceType::TABLET ||
120 SystemProperties::GetDeviceType() == DeviceType::TWO_IN_ONE;
121 bool isWideScreen = SystemProperties::GetDeviceOrientation() == DeviceOrientation::LANDSCAPE;
122 return isSupportDeviceType && isWideScreen;
123 }
124
Build(const WeakPtr<PipelineContext> & context,int32_t menuCount)125 void NavigationContainerComponent::Build(const WeakPtr<PipelineContext>& context, int32_t menuCount)
126 {
127 if (!declaration_) {
128 return;
129 }
130
131 auto content = GetChildren();
132 ClearChildren();
133
134 auto originalContent = AceType::MakeRefPtr<ColumnComponent>(FlexAlign::FLEX_START, FlexAlign::FLEX_START, content);
135 RefPtr<ColumnComponent> fixPart = AceType::MakeRefPtr<ColumnComponent>(
136 FlexAlign::FLEX_START, FlexAlign::FLEX_START, std::list<RefPtr<OHOS::Ace::Component>>());
137 fixPart->AppendChild(NavigationBarBuilder(declaration_, "navigationBar", direction_).Build(context, menuCount));
138 auto originalFlexItem = AceType::MakeRefPtr<FlexItemComponent>(1.0, 1.0, 0.0, originalContent);
139 originalFlexItem->SetFlexWeight(0.0);
140 fixPart->AppendChild(originalFlexItem);
141 tabController_ = TabController::GetController(GetGlobalTabControllerId());
142 fixPart->AppendChild(NavigationContainerComponent::BuildToolBar(declaration_, tabController_));
143
144 if (NeedSection()) {
145 auto rootContainer = AceType::MakeRefPtr<RowComponent>(
146 FlexAlign::FLEX_START, FlexAlign::FLEX_START, std::list<RefPtr<OHOS::Ace::Component>>());
147 fixPart->SetFlexWeight(SECTION_INDEX_PART_WEIGHT);
148 rootContainer->AppendChild(fixPart);
149
150 auto sectionPart = AceType::MakeRefPtr<StageComponent>(std::list<RefPtr<Component>>(), true);
151 sectionPart->SetFlexWeight(SECTION_CONTENT_PART_WEIGHT);
152 rootContainer->AppendChild(sectionPart);
153
154 AppendChild(rootContainer);
155 } else {
156 AppendChild(fixPart);
157 }
158 }
159
160 } // namespace OHOS::Ace
161