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