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_controller.h"
17 
18 #include "core/common/container.h"
19 #include "core/components/tab_bar/render_tab_bar.h"
20 #include "core/components/tab_bar/tab_bar_element.h"
21 #include "core/components/tab_bar/tab_content_element.h"
22 
23 namespace OHOS::Ace {
24 
GetController(int32_t id)25 RefPtr<TabController> TabController::GetController(int32_t id)
26 {
27     return AceType::MakeRefPtr<TabController>(id);
28 }
29 
TabController(int32_t id)30 TabController::TabController(int32_t id)
31 {
32     id_ = id;
33 }
34 
ValidateIndex(int32_t maxIndex)35 void TabController::ValidateIndex(int32_t maxIndex)
36 {
37     if (pageReady_ && index_ > maxIndex) {
38         index_ = 0;
39         if (barElement_.Upgrade()) {
40             auto tabBar = AceType::DynamicCast<TabBarElement>(barElement_.Upgrade());
41             if (tabBar) {
42                 tabBar->UpdateIndex(0);
43             }
44         }
45     }
46 }
47 
SetPageReady(bool ready)48 void TabController::SetPageReady(bool ready)
49 {
50     pageReady_ = ready;
51 }
52 
SetIndex(int32_t index)53 void TabController::SetIndex(int32_t index)
54 {
55     // There can be different tab at the same index
56     if ((index_ == index && !Container::IsCurrentUsePartialUpdate()) ||  index < 0) {
57         return;
58     }
59     indexDefined_ = true;
60 
61     index_ = index;
62     if (contentElement_.Upgrade()) {
63         auto tabContent = AceType::DynamicCast<TabContentElement>(contentElement_.Upgrade());
64         if (tabContent) {
65             tabContent->ChangeByBar(index);
66         }
67     }
68 }
69 
SetInitialIndex(int32_t index)70 void TabController::SetInitialIndex(int32_t index)
71 {
72     if (initialIndex_ == index || index < 0) {
73         return;
74     }
75     initialIndex_ = index;
76 }
77 
SetIndexWithoutChangeContent(int32_t index)78 void TabController::SetIndexWithoutChangeContent(int32_t index)
79 {
80     if (index_ == index || index < 0) {
81         return;
82     }
83     indexDefined_ = true;
84     index_ = index;
85 }
86 
SetPendingIndex(int32_t index)87 void TabController::SetPendingIndex(int32_t index)
88 {
89     if (pendingIndex_ == index || index < 0) {
90         return;
91     }
92     pendingIndex_ = index;
93     indexDefined_ = false;
94 }
95 
SetIndexByController(int32_t index,bool blockEvent)96 void TabController::SetIndexByController(int32_t index, bool blockEvent)
97 {
98     if (index_ == index || index < 0) {
99         return;
100     }
101     if (index >= totalCount_) {
102         SetPendingIndex(index);
103         return;
104     }
105     indexDefined_ = true;
106     if (barElement_.Upgrade()) {
107         auto tabBar = AceType::DynamicCast<TabBarElement>(barElement_.Upgrade());
108         if (tabBar) {
109             auto renderTabBar = AceType::DynamicCast<RenderTabBar>(tabBar->GetRenderNode());
110             if (renderTabBar && renderTabBar->GetTabsSize() < index) {
111                 LOGW("Input index is not valid.");
112                 return;
113             }
114             tabBar->UpdateIndex(index);
115         }
116     }
117 
118     index_ = index;
119     if (contentElement_.Upgrade()) {
120         auto tabContent = AceType::DynamicCast<TabContentElement>(contentElement_.Upgrade());
121         if (tabContent) {
122             tabContent->ChangeByBar(index, blockEvent);
123         }
124     }
125 }
126 
ChangeDispatch(int32_t index)127 void TabController::ChangeDispatch(int32_t index)
128 {
129     if (contentElement_.Upgrade()) {
130         auto tabContent = AceType::DynamicCast<TabContentElement>(contentElement_.Upgrade());
131         if (tabContent) {
132             tabContent->ChangeDispatch(index);
133         }
134     }
135 }
136 
SetIndicatorByScrollContent(double percent,int32_t newIndex,bool needChange)137 void TabController::SetIndicatorByScrollContent(double percent, int32_t newIndex, bool needChange)
138 {
139     if (barElement_.Upgrade()) {
140         auto tabBar = AceType::DynamicCast<TabBarElement>(barElement_.Upgrade());
141         if (tabBar) {
142             tabBar->UpdateScrollIndicator(percent, newIndex, needChange);
143         }
144     }
145 }
146 
SetIndexByScrollContent(int32_t index)147 void TabController::SetIndexByScrollContent(int32_t index)
148 {
149     if (index_ == index || index < 0) {
150         return;
151     }
152     indexDefined_ = true;
153     index_ = index;
154     if (barElement_.Upgrade()) {
155         auto tabBar = AceType::DynamicCast<TabBarElement>(barElement_.Upgrade());
156         if (tabBar) {
157             tabBar->UpdateIndex(index);
158         }
159     }
160 }
161 
SetContentElement(const RefPtr<Element> & contentElement)162 void TabController::SetContentElement(const RefPtr<Element>& contentElement)
163 {
164     contentElement_ = contentElement;
165 }
166 
SetBarElement(const RefPtr<Element> & barElement)167 void TabController::SetBarElement(const RefPtr<Element>& barElement)
168 {
169     barElement_ = barElement;
170 }
171 
GetId() const172 int32_t TabController::GetId() const
173 {
174     return id_;
175 }
176 
GetIndex() const177 int32_t TabController::GetIndex() const
178 {
179     return index_;
180 }
181 
IsIndexDefined() const182 bool TabController::IsIndexDefined() const
183 {
184     return indexDefined_;
185 }
186 
187 } // namespace OHOS::Ace
188