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/tab_bar/tab_bar_component.h"
17
18 #include "core/components/tab_bar/render_tab_bar.h"
19 #include "core/components/tab_bar/tab_bar_element.h"
20
21 namespace OHOS::Ace {
22 namespace {
23
24 constexpr int32_t ACTIVE_TEXT_SIZE = 24;
25 constexpr int32_t INACTIVE_TEXT_SIZE = 18;
26 constexpr double ACTIVE_TEXT_OPACITY = 0.9;
27 constexpr double INACTIVE_TEXT_OPACITY = 0.6;
28 constexpr Dimension BOTTOM_PADING(12, DimensionUnit::VP);
29
30 constexpr int32_t BOTTOM_TAB_TEXT_SIZE = 10;
31 constexpr double BOTTOM_TAB_INACTIVE_TEXT_OPACITY = 0.4;
32
33 } // namespace
34
TabBarComponent(const std::list<RefPtr<Component>> & tabItems,const RefPtr<TabController> & controller,const RefPtr<BoxComponent> & indicator)35 TabBarComponent::TabBarComponent(const std::list<RefPtr<Component>>& tabItems, const RefPtr<TabController>& controller,
36 const RefPtr<BoxComponent>& indicator)
37 : ComponentGroup(tabItems)
38 {
39 controller_ = controller;
40 indicator_ = indicator;
41 focusIndicator_ = indicator;
42 }
43
CreateElement()44 RefPtr<Element> TabBarComponent::CreateElement()
45 {
46 return AceType::MakeRefPtr<TabBarElement>();
47 }
48
CreateRenderNode()49 RefPtr<RenderNode> TabBarComponent::CreateRenderNode()
50 {
51 return RenderTabBar::Create();
52 }
53
InitStyle(const RefPtr<TabTheme> & theme)54 void TabBarComponent::InitStyle(const RefPtr<TabTheme>& theme)
55 {
56 if (!theme) {
57 return;
58 }
59
60 focusRadiusDimension_ = theme->GetFocusIndicatorRadius();
61 focusAnimationColor_ = theme->GetFocusIndicatorColor();
62 gradientWidth_ = theme->GetGradientWidth();
63 activeIndicatorMinWidth_ = theme->GetActiveIndicatorMinWidth();
64
65 Dimension labelPaddingDimension = theme->GetLabelPadding();
66 SetLabelPadding(
67 Edge(labelPaddingDimension.Value(), 0.0, labelPaddingDimension.Value(), 0.0, labelPaddingDimension.Unit()));
68
69 auto paddingDimension = theme->GetPadding();
70 SetPadding(Edge(paddingDimension.Value(), 0.0, paddingDimension.Value(), 0.0, paddingDimension.Unit()));
71
72 auto indicatorPadding = Edge(0.0, theme->GetActiveIndicatorPadding().Value(), 0.0,
73 theme->GetActiveIndicatorPadding().Value(), theme->GetActiveIndicatorPadding().Unit());
74 Color activeIndicatorColor = HasIndicatorColor() ? GetIndicatorColor() : theme->GetActiveIndicatorColor();
75 indicator_ = AceType::MakeRefPtr<TabBarIndicatorComponent>(
76 indicatorPadding, activeIndicatorColor, theme->GetActiveIndicatorWidth());
77 indicator_->SetPadding(indicatorPadding);
78
79 auto deviceType = SystemProperties::GetDeviceType();
80 if (deviceType == DeviceType::TV) {
81 RefPtr<Decoration> backDecoration = AceType::MakeRefPtr<Decoration>();
82 Border border;
83 border.SetBorderRadius(Radius(theme->GetFocusIndicatorRadius()));
84 backDecoration->SetBorder(border);
85 backDecoration->SetBackgroundColor(theme->GetFocusIndicatorColor());
86
87 focusIndicator_ = AceType::MakeRefPtr<TabBarIndicatorComponent>(backDecoration);
88 auto focusIndicatorPadding = Edge(theme->GetFocusIndicatorHorizontalPadding().Value(),
89 theme->GetFocusIndicatorVerticalPadding().Value(), theme->GetFocusIndicatorHorizontalPadding().Value(),
90 theme->GetFocusIndicatorVerticalPadding().Value(), theme->GetFocusIndicatorVerticalPadding().Unit());
91 focusIndicator_->SetPadding(focusIndicatorPadding);
92 } else if (deviceType == DeviceType::PHONE) {
93 focusIndicator_->SetPadding(indicatorPadding);
94 }
95 }
96
InitNavigationBarStyle()97 void TabBarComponent::InitNavigationBarStyle()
98 {
99 usingDefaultStyle_ = true;
100 indicator_ = nullptr;
101 activeTextStyle_.SetTextColor(Color::FromRGBO(0, 0, 0, ACTIVE_TEXT_OPACITY));
102 activeTextStyle_.SetFontSize(Dimension(ACTIVE_TEXT_SIZE, DimensionUnit::VP));
103 activeTextStyle_.SetMaxLines(1);
104 activeTextStyle_.SetTextOverflow(TextOverflow::CLIP);
105
106 inactiveTextStyle_.SetTextColor(Color::FromRGBO(0, 0, 0, BOTTOM_TAB_INACTIVE_TEXT_OPACITY));
107 inactiveTextStyle_.SetFontSize(Dimension(INACTIVE_TEXT_SIZE, DimensionUnit::VP));
108 inactiveTextStyle_.SetMaxLines(1);
109 inactiveTextStyle_.SetTextOverflow(TextOverflow::CLIP);
110 labelPadding_.SetBottom(BOTTOM_PADING);
111 itemAlignment_ = Alignment::BOTTOM_CENTER;
112 mode_ = TabBarMode::FIXED_START;
113 }
114
InitBottomTabStyle(const RefPtr<TabTheme> & theme)115 void TabBarComponent::InitBottomTabStyle(const RefPtr<TabTheme>& theme)
116 {
117 usingDefaultStyle_ = true;
118 indicator_ = nullptr;
119 activeColor_ = theme->GetActiveIndicatorColor();
120 activeTextStyle_.SetTextColor(activeColor_);
121 activeTextStyle_.SetFontSize(Dimension(BOTTOM_TAB_TEXT_SIZE, DimensionUnit::VP));
122 activeTextStyle_.SetMaxLines(1);
123 activeTextStyle_.SetTextOverflow(TextOverflow::CLIP);
124
125 inactiveColor_ = Color::FromRGBO(0, 0, 0, INACTIVE_TEXT_OPACITY);
126 inactiveTextStyle_.SetTextColor(inactiveColor_);
127 inactiveTextStyle_.SetFontSize(Dimension(BOTTOM_TAB_TEXT_SIZE, DimensionUnit::VP));
128 inactiveTextStyle_.SetMaxLines(1);
129 inactiveTextStyle_.SetTextOverflow(TextOverflow::CLIP);
130 }
131
BuildItems(std::list<RefPtr<TabBarItemComponent>> & items)132 void TabBarComponent::BuildItems(std::list<RefPtr<TabBarItemComponent>>& items)
133 {
134 int32_t currentIndex = 0;
135 int32_t activeIndex = controller_ ? controller_->GetIndex() : 0;
136 for (const auto& pos : GetChildren()) {
137 RefPtr<TabBarItemComponent> box = AceType::DynamicCast<TabBarItemComponent>(pos);
138 if (!box) {
139 box = AceType::MakeRefPtr<TabBarItemComponent>(pos);
140 }
141 if (usingDefaultStyle_) {
142 if (currentIndex++ == activeIndex) {
143 box->UpdateStyle(activeTextStyle_, activeColor_);
144 } else {
145 box->UpdateStyle(inactiveTextStyle_, inactiveColor_);
146 }
147 }
148 box->SetEnableDebugBoundary(true);
149 box->SetPadding(labelPadding_);
150 if (mode_ == TabBarMode::FIXED) {
151 box->SetFlex(BoxFlex::FLEX_XY);
152 } else {
153 if (vertical_) {
154 box->SetFlex(BoxFlex::FLEX_X);
155 } else {
156 box->SetFlex(BoxFlex::FLEX_Y);
157 }
158 }
159 box->SetDeliverMinToChild(false);
160 box->SetAlignment(itemAlignment_);
161 items.push_back(box);
162 }
163 }
164
UpdateItemStyle(const RefPtr<TabBarItemComponent> & item)165 void TabBarComponent::UpdateItemStyle(const RefPtr<TabBarItemComponent>& item)
166 {
167 RefPtr<TabBarItemComponent> box = item;
168 if (usingDefaultStyle_) {
169 box->UpdateStyle(inactiveTextStyle_, inactiveColor_);
170 }
171 box->SetPadding(labelPadding_);
172 if (mode_ == TabBarMode::FIXED) {
173 box->SetFlex(BoxFlex::FLEX_XY);
174 } else {
175 if (vertical_) {
176 box->SetFlex(BoxFlex::FLEX_X);
177 } else {
178 box->SetFlex(BoxFlex::FLEX_Y);
179 }
180 }
181 box->SetDeliverMinToChild(false);
182 box->SetAlignment(itemAlignment_);
183 }
184
185 } // namespace OHOS::Ace