1 /*
2  * Copyright (c) 2021 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_item_component.h"
17 
18 #include "core/components/flex/flex_component.h"
19 #include "core/components/padding/padding_component.h"
20 #include "core/components/tab_bar/tab_bar_item_element.h"
21 
22 namespace OHOS::Ace {
23 
24 constexpr Dimension DEFAULT_SINGLE_TEXT_FONT_SIZE = 16.0_fp;
25 constexpr Dimension DEFAULT_SMALL_TEXT_FONT_SIZE = 10.0_fp;
26 constexpr Dimension DEFAULT_SMALL_IMAGE_WIDTH = 24.0_vp;
27 constexpr Dimension DEFAULT_SMALL_IMAGE_HEIGHT = 26.0_vp;
28 
TabBarItemComponent(const RefPtr<Component> & child)29 TabBarItemComponent::TabBarItemComponent(const RefPtr<Component>& child)
30 {
31     SetChild(child);
32 }
33 
TabBarItemComponent(const std::string & text,const RefPtr<Component> & imageComponent)34 TabBarItemComponent::TabBarItemComponent(const std::string& text, const RefPtr<Component>& imageComponent)
35 {
36     std::list<RefPtr<Component>> children;
37     RefPtr<ImageComponent> icon = AceType::DynamicCast<ImageComponent>(imageComponent);
38     if (icon) {
39         icon_ = icon;
40         children.push_back(icon_);
41     }
42     if (!text.empty()) {
43         text_ = AceType::MakeRefPtr<TextComponent>(text);
44         TextStyle textStyle;
45         textStyle.SetTextAlign(TextAlign::CENTER);
46         textStyle.SetMaxLines(1);
47         textStyle.SetTextOverflow(TextOverflow::CLIP);
48         text_->SetTextStyle(textStyle);
49         children.push_back(text_);
50     }
51     if (!children.empty()) {
52         auto flex = AceType::MakeRefPtr<ColumnComponent>(FlexAlign::CENTER, FlexAlign::CENTER, children);
53         SetChild(flex);
54     } else {
55         LOGE("Create Tab err: text == null && icon == null");
56     }
57 }
58 
CreateElement()59 RefPtr<Element> TabBarItemComponent::CreateElement()
60 {
61     return AceType::MakeRefPtr<TabBarItemElement>();
62 }
63 
CreateRenderNode()64 RefPtr<RenderNode> TabBarItemComponent::CreateRenderNode()
65 {
66     return RenderTabBarItem::Create();
67 }
68 
FindChildren(const RefPtr<Component> & component,std::stack<RefPtr<Component>> & allChildren)69 void FindChildren(const RefPtr<Component>& component, std::stack<RefPtr<Component>>& allChildren)
70 {
71     auto singleChildGroup = AceType::DynamicCast<SingleChild>(component);
72     if (singleChildGroup) {
73         allChildren.push(singleChildGroup->GetChild());
74     }
75 
76     auto multiChildGroup = AceType::DynamicCast<ComponentGroup>(component);
77     if (multiChildGroup) {
78         for (const auto& item : multiChildGroup->GetChildren()) {
79             allChildren.push(item);
80         }
81     }
82 }
83 
UpdateStyle(const TextStyle & textStyle,const Color & color)84 void TabBarItemComponent::UpdateStyle(const TextStyle& textStyle, const Color& color)
85 {
86     std::stack<RefPtr<Component>> allChildren;
87     allChildren.push(GetChild());
88 
89     while (!allChildren.empty()) {
90         auto component = allChildren.top();
91         allChildren.pop();
92         auto text = AceType::DynamicCast<TextComponent>(component);
93         auto image = AceType::DynamicCast<ImageComponent>(component);
94         if (text) {
95             text->SetTextStyle(textStyle);
96         } else if (image) {
97             image->SetImageFill(color);
98         } else {
99             FindChildren(component, allChildren);
100         }
101     }
102 }
103 
BuildWithTextIcon(const std::string & textStr,const std::string & iconUri)104 RefPtr<Component> TabBarItemComponent::BuildWithTextIcon(const std::string& textStr, const std::string& iconUri)
105 {
106     if (!textStr.empty() && !iconUri.empty()) {
107         auto imageComponent = AceType::MakeRefPtr<ImageComponent>(iconUri);
108         auto box = AceType::MakeRefPtr<BoxComponent>();
109         auto padding = AceType::MakeRefPtr<PaddingComponent>();
110         padding->SetPadding(Edge(0, 0, 0, 2, DimensionUnit::VP));
111         padding->SetChild(imageComponent);
112         box->SetChild(padding);
113         box->SetWidth(DEFAULT_SMALL_IMAGE_WIDTH);
114         box->SetHeight(DEFAULT_SMALL_IMAGE_HEIGHT);
115         auto textComponent = AceType::MakeRefPtr<TextComponent>(textStr);
116         auto textStyle = textComponent->GetTextStyle();
117         textStyle.SetFontSize(DEFAULT_SMALL_TEXT_FONT_SIZE);
118         textStyle.SetMaxLines(1);
119         textStyle.SetTextOverflow(TextOverflow::ELLIPSIS);
120         textComponent->SetTextStyle(textStyle);
121         std::list<RefPtr<Component>> children;
122         children.emplace_back(box);
123         children.emplace_back(textComponent);
124         auto columnComponent = AceType::MakeRefPtr<ColumnComponent>(FlexAlign::FLEX_START, FlexAlign::CENTER, children);
125         columnComponent->SetMainAxisSize(MainAxisSize::MIN);
126         return columnComponent;
127     }
128 
129     if (!textStr.empty()) {
130         auto text = AceType::MakeRefPtr<TextComponent>(textStr);
131         auto textStyle = text->GetTextStyle();
132         textStyle.SetFontSize(DEFAULT_SINGLE_TEXT_FONT_SIZE);
133         textStyle.SetMaxLines(1);
134         textStyle.SetTextOverflow(TextOverflow::ELLIPSIS);
135         text->SetTextStyle(textStyle);
136         text->SetAutoMaxLines(false);
137         return text;
138     }
139 
140     return nullptr;
141 }
142 
143 } // namespace OHOS::Ace
144