• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "frameworks/bridge/common/dom/dom_tab_bar.h"
17 
18 #include "core/components/tab_bar/tab_theme.h"
19 #include "core/components/theme/theme_manager.h"
20 #include "frameworks/bridge/common/dom/dom_type.h"
21 #include "frameworks/bridge/common/utils/utils.h"
22 
23 namespace OHOS::Ace::Framework {
24 
DOMTabBar(NodeId nodeId,const std::string & nodeName)25 DOMTabBar::DOMTabBar(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
26 {
27     std::list<RefPtr<Component>> tabBars;
28     RefPtr<TabController> controller;
29     tabBarIndicator_ = AceType::MakeRefPtr<TabBarIndicatorComponent>();
30     tabBarChild_ = AceType::MakeRefPtr<TabBarComponent>(tabBars, controller, tabBarIndicator_);
31 }
32 
InitializeStyle()33 void DOMTabBar::InitializeStyle()
34 {
35     RefPtr<TabTheme> theme = GetTheme<TabTheme>();
36     if (!theme) {
37         return;
38     }
39     if (boxComponent_) {
40         boxComponent_->SetColor(theme->GetBackgroundColor());
41         boxComponent_->SetHasBackgroundColor(true);
42     }
43     auto paddingDimension = theme->GetPadding();
44     padding_ = Edge(paddingDimension.Value(), 0.0, paddingDimension.Value(), 0.0, paddingDimension.Unit());
45 }
46 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)47 bool DOMTabBar::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
48 {
49     if (attr.first == DOM_TAB_BAR_MODE) {
50         tabBarMode_ = ConvertStrToTabBarMode(attr.second);
51         return true;
52     }
53     return false;
54 }
55 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)56 bool DOMTabBar::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
57 {
58     static const std::unordered_map<std::string, void (*)(const std::string&, DOMTabBar&)> styleOperators = {
59         { DOM_PADDING,
60             [](const std::string& val, DOMTabBar& node) {
61                 node.padding_ = node.ParseEdge(val);
62             } },
63         { DOM_PADDING_END,
64             [](const std::string& val, DOMTabBar& node) {
65                 if (node.IsRightToLeft()) {
66                     node.padding_.SetLeft(node.ParseDimension(val));
67                 } else {
68                     node.padding_.SetRight(node.ParseDimension(val));
69                 }
70             } },
71         { DOM_PADDING_LEFT,
72             [](const std::string& val, DOMTabBar& node) {
73                 node.padding_.SetLeft(node.ParseDimension(val));
74             } },
75         { DOM_PADDING_RIGHT,
76             [](const std::string& val, DOMTabBar& node) {
77                 node.padding_.SetRight(node.ParseDimension(val));
78             } },
79         { DOM_PADDING_START,
80             [](const std::string& val, DOMTabBar& node) {
81                 if (node.IsRightToLeft()) {
82                     node.padding_.SetRight(node.ParseDimension(val));
83                 } else {
84                     node.padding_.SetLeft(node.ParseDimension(val));
85                 }
86             } },
87         { DOM_INDICATOR_COLOR,
88             [](const std::string& val, DOMTabBar& node) {
89                node.indicatorColor_= node.ParseColor(val);
90             }},
91     };
92     auto operatorIter = styleOperators.find(style.first);
93     if (operatorIter != styleOperators.end()) {
94         operatorIter->second(style.second, *this);
95         return true;
96     }
97     return false;
98 }
99 
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)100 void DOMTabBar::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
101 {
102     if (!child) {
103         LOGE("Child is nullptr, add node failed, slot:%{public}d.", slot);
104         return;
105     }
106     if (tabBarChild_) {
107         LOGD("DOMTabBar Add Child in slot(=%{public}d)", slot);
108         tabBarChild_->InsertChild(slot, child->GetRootComponent());
109     }
110 }
111 
UpdateIndex(uint32_t currentIndex)112 void DOMTabBar::UpdateIndex(uint32_t currentIndex)
113 {
114     uint32_t index = 0;
115     for (const auto& childNode : GetChildList()) {
116         if (index == currentIndex) {
117             OnChildActive(childNode, true);
118         } else if (index == lastIndex_) {
119             OnChildActive(childNode, false);
120         }
121         index++;
122     }
123     lastIndex_ = currentIndex;
124 }
125 
OnMounted(const RefPtr<DOMNode> & parentNode)126 void DOMTabBar::OnMounted(const RefPtr<DOMNode>& parentNode)
127 {
128     if (!parentNode) {
129         LOGE("parentNode is nullptr, mount node failed");
130         return;
131     }
132     if (parentNode->GetTag() == DOM_NODE_TAG_TABS) {
133         const auto& parentNodeTmp = AceType::DynamicCast<DOMTabs>(parentNode);
134         if (!parentNodeTmp) {
135             LOGE("DynamicCast DOMTabs failed");
136             return;
137         }
138         lastIndex_ = parentNodeTmp->GetTabIndex();
139         controllerId_ = parentNodeTmp->GetTabControllerId();
140         const auto& controller = parentNodeTmp->GetTabController();
141         controller->SetIndexWithoutChangeContent(static_cast<int32_t>(lastIndex_));
142         tabBarChild_->SetController(controller);
143         PrepareChangeListener();
144     }
145 }
146 
OnChildNodeRemoved(const RefPtr<DOMNode> & child)147 void DOMTabBar::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
148 {
149     if (!child) {
150         LOGE("Child is nullptr, remove node failed.");
151         return;
152     }
153     if (tabBarChild_) {
154         LOGD("DOMTabBar remove child");
155         tabBarChild_->RemoveChild(child->GetRootComponent());
156     }
157 }
158 
ResetInitializedStyle()159 void DOMTabBar::ResetInitializedStyle()
160 {
161     if (!boxComponent_) {
162         LOGE("BoxComponent is null, reset style failed.");
163         return;
164     }
165     RefPtr<TabTheme> theme = GetTheme<TabTheme>();
166     if (theme) {
167         if(indicatorColor_.has_value()){
168            tabBarChild_->SetIndicatorColor(indicatorColor_.value());
169         }
170         tabBarChild_->InitStyle(theme);
171         if (vertical_) {
172             if (LessOrEqual(GetWidth().Value(), 0.0)) {
173                 boxComponent_->SetWidth(theme->GetDefaultWidth().Value(), theme->GetDefaultWidth().Unit());
174             }
175         } else {
176             if (LessOrEqual(GetHeight().Value(), 0.0)) {
177                 boxComponent_->SetHeight(theme->GetDefaultHeight().Value(), theme->GetDefaultHeight().Unit());
178             }
179         }
180     }
181 }
182 
PrepareSpecializedComponent()183 void DOMTabBar::PrepareSpecializedComponent()
184 {
185     tabBarChild_->SetTextDirection(IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
186     tabBarChild_->SetMode(tabBarMode_);
187     const auto& parentNodeTmp = AceType::DynamicCast<DOMTabs>(parentNode_.Upgrade());
188     if (parentNodeTmp) {
189         vertical_ = parentNodeTmp->IsVertical();
190     }
191     tabBarChild_->SetVertical(vertical_);
192     ResetInitializedStyle();
193     tabBarChild_->SetPadding(padding_);
194 }
195 
PrepareChangeListener()196 void DOMTabBar::PrepareChangeListener()
197 {
198     // used for initalized the active tabBarItem
199     auto weak = AceType::WeakClaim(this);
200     auto changeCallback = [weak](uint32_t currentIndex) {
201         auto tabBarNode = weak.Upgrade();
202         if (!tabBarNode) {
203             LOGE("get dom node failed!");
204             return;
205         }
206         tabBarNode->UpdateIndex(currentIndex);
207     };
208     auto changeMarker = BackEndEventManager<void(uint32_t)>::GetInstance().GetAvailableMarker();
209     BackEndEventManager<void(uint32_t)>::GetInstance().BindBackendEvent(changeMarker, changeCallback);
210     tabBarChild_->SetDomChangeEventId(changeMarker);
211 }
212 
OnChildActive(const RefPtr<DOMNode> & node,bool active)213 void DOMTabBar::OnChildActive(const RefPtr<DOMNode>& node, bool active)
214 {
215     node->OnActive(active);
216     for (const auto& childNode : node->GetChildList()) {
217         childNode->OnActive(active);
218     }
219 }
220 
ParseEdge(const std::string & value) const221 Edge DOMTabBar::ParseEdge(const std::string& value) const
222 {
223     Edge edge;
224     std::vector<std::string> offsets;
225     StringUtils::StringSplitter(value, ' ', offsets);
226     switch (offsets.size()) {
227         case 1:
228             edge.SetLeft(ParseDimension(offsets[0]));
229             edge.SetRight(ParseDimension(offsets[0]));
230             edge.SetTop(ParseDimension(offsets[0]));
231             edge.SetBottom(ParseDimension(offsets[0]));
232             break;
233         case 2:
234             edge.SetLeft(ParseDimension(offsets[0]));
235             edge.SetRight(ParseDimension(offsets[1]));
236             edge.SetTop(ParseDimension(offsets[0]));
237             edge.SetBottom(ParseDimension(offsets[0]));
238             break;
239         case 3:
240             edge.SetLeft(ParseDimension(offsets[1]));
241             edge.SetRight(ParseDimension(offsets[1]));
242             edge.SetTop(ParseDimension(offsets[0]));
243             edge.SetBottom(ParseDimension(offsets[2]));
244             break;
245         case 4:
246             edge.SetLeft(ParseDimension(offsets[3]));
247             edge.SetRight(ParseDimension(offsets[1]));
248             edge.SetTop(ParseDimension(offsets[0]));
249             edge.SetBottom(ParseDimension(offsets[2]));
250             break;
251         default:
252             break;
253     }
254     return edge;
255 }
256 
257 } // namespace OHOS::Ace::Framework
258