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