• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "bridge/declarative_frontend/jsview/models/tab_content_model_impl.h"
17 
18 #include "bridge/declarative_frontend/jsview/js_container_base.h"
19 #include "bridge/declarative_frontend/view_stack_processor.h"
20 
21 namespace OHOS::Ace::Framework {
22 namespace {
23 
24 constexpr char DEFAULT_TAB_BAR_NAME[] = "TabBar";
25 
26 } // namespace
27 
Create()28 void TabContentModelImpl::Create()
29 {
30     std::list<RefPtr<Component>> components;
31     auto tabContentItemComponent = AceType::MakeRefPtr<V2::TabContentItemComponent>(components);
32     tabContentItemComponent->SetCrossAxisSize(CrossAxisSize::MAX);
33     ViewStackProcessor::GetInstance()->ClaimElementId(tabContentItemComponent);
34 
35     RefPtr<V2::TabsComponent> tabsComponent = nullptr;
36     tabsComponent = AceType::DynamicCast<V2::TabsComponent>(ViewStackProcessor::GetInstance()->GetTopTabs());
37     CHECK_NULL_VOID(tabsComponent);
38     // GetTabsComponent used only by JSTabContent::SetTabBar
39     // To Find TabBarComponent eventually
40     tabContentItemComponent->SetTabsComponent(AceType::WeakClaim(AceType::RawPtr(tabsComponent)));
41 
42     auto tabBar = tabsComponent->GetTabBarChild();
43     tabBar->AppendChild(CreateTabBarLabelComponent(tabContentItemComponent, std::string(DEFAULT_TAB_BAR_NAME)));
44 
45     ViewStackProcessor::GetInstance()->Push(tabContentItemComponent);
46     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
47     CHECK_NULL_VOID(box);
48     box->SetBoxClipFlag(true);
49 }
50 
Create(std::function<void ()> && deepRenderFunc)51 void TabContentModelImpl::Create(std::function<void()>&& deepRenderFunc)
52 {
53     std::list<RefPtr<Component>> components;
54     auto tabContentItemComponent = AceType::MakeRefPtr<V2::TabContentItemComponent>(components);
55     tabContentItemComponent->SetCrossAxisSize(CrossAxisSize::MAX);
56     ViewStackProcessor::GetInstance()->ClaimElementId(tabContentItemComponent);
57 
58     RefPtr<V2::TabsComponent> tabsComponent = nullptr;
59     ViewStackProcessor::GetInstance()->Push(tabContentItemComponent);
60     auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
61     if (box) {
62         box->SetBoxClipFlag(true);
63     }
64 
65     auto jsWrapperFunc = [builder = std::move(deepRenderFunc)]() -> RefPtr<Component> {
66         CHECK_NULL_RETURN(builder, nullptr);
67         builder();
68         return ViewStackProcessor::GetInstance()->Finish();
69     };
70     tabContentItemComponent->SetBuilder(std::move(jsWrapperFunc));
71 }
72 
Pop()73 void TabContentModelImpl::Pop()
74 {
75     JSContainerBase::Pop();
76 }
77 
SetTabBar(const std::optional<std::string> & text,const std::optional<std::string> & icon,const std::optional<TabBarSymbol> & tabBarSymbol,std::function<void ()> && builder,bool useContentOnly)78 void TabContentModelImpl::SetTabBar(const std::optional<std::string>& text, const std::optional<std::string>& icon,
79     const std::optional<TabBarSymbol>& tabBarSymbol, std::function<void()>&& builder, bool useContentOnly)
80 {
81     auto tabContentItemComponent =
82         AceType::DynamicCast<V2::TabContentItemComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
83     CHECK_NULL_VOID(tabContentItemComponent);
84 
85     auto weakTabs = tabContentItemComponent->GetTabsComponent();
86     // Full update: tabs and tabBar always exist
87     // Partial update: tabs and tabBar exist for initial render and nullptr for rerender
88     auto tabs = weakTabs.Upgrade();
89     auto tabBar = tabs ? tabs->GetTabBarChild() : nullptr;
90 
91     if (!Container::IsCurrentUsePartialUpdate()) {
92         CHECK_NULL_VOID(tabs);
93         CHECK_NULL_VOID(tabBar);
94     }
95 
96     RefPtr<Component> tabBarChild = nullptr;
97     if (useContentOnly) {
98         auto textVal = text.value_or(DEFAULT_TAB_BAR_NAME);
99         if (!Container::IsCurrentUsePartialUpdate()) {
100             tabBarChild = CreateTabBarLabelComponent(tabContentItemComponent, textVal);
101         } else {
102             tabContentItemComponent->SetBarText(textVal);
103         }
104     } else {
105         // For Partial Update ProcessTabBarXXX methods
106         // do not create any components for the tab bar items
107         // and return nullptr.
108         // Tab bar items created and added later by
109         // TabContentItemElementProxy class.
110         if (builder) {
111             tabBarChild = ProcessTabBarBuilderFunction(tabContentItemComponent, std::move(builder));
112             // Update tabBar always for full update and for initial render only for partial update
113             if (tabBar) {
114                 tabBar->ResetIndicator();
115                 tabBar->SetAlignment(Alignment::TOP_LEFT);
116             }
117         } else if (text.has_value() && icon.has_value()) {
118             tabBarChild = ProcessTabBarTextIconPair(tabContentItemComponent, text, icon);
119         } else if (text.has_value() && !icon.has_value()) {
120             tabBarChild = ProcessTabBarLabel(tabContentItemComponent, text);
121         }
122     }
123 
124     if (!Container::IsCurrentUsePartialUpdate()) {
125         auto defaultTabChild = tabBar->GetChildren().back();
126         tabBar->RemoveChildDirectly(defaultTabChild);
127         tabBar->AppendChild(tabBarChild);
128         return;
129     }
130 
131     // Partial Update only
132     if (tabContentItemComponent->GetBarElementId() == ElementRegister::UndefinedElementId) {
133         const auto id = ElementRegister::GetInstance()->MakeUniqueId();
134         tabContentItemComponent->SetBarElementId(id);
135     }
136 }
137 
ProcessTabBarBuilderFunction(RefPtr<V2::TabContentItemComponent> & tabContent,std::function<void ()> && builderFunc)138 RefPtr<Component> TabContentModelImpl::ProcessTabBarBuilderFunction(
139     RefPtr<V2::TabContentItemComponent>& tabContent, std::function<void()>&& builderFunc)
140 {
141     CHECK_NULL_RETURN(builderFunc, nullptr);
142     tabContent->SetBarText("custom");
143     if (Container::IsCurrentUsePartialUpdate()) {
144         auto jsWrapperFunc = [builder = std::move(builderFunc)]() -> RefPtr<Component> {
145             builder();
146             return ViewStackProcessor::GetInstance()->Finish();
147         };
148         tabContent->SetBarBuilder(jsWrapperFunc);
149         return nullptr;
150     }
151 
152     ScopedViewStackProcessor builderViewStackProcessor;
153     builderFunc();
154     RefPtr<Component> builderGeneratedRootComponent = ViewStackProcessor::GetInstance()->Finish();
155     return builderGeneratedRootComponent;
156 }
157 
CreateTabBarLabelComponent(RefPtr<V2::TabContentItemComponent> & tabContent,const std::string & labelStr)158 RefPtr<Component> TabContentModelImpl::CreateTabBarLabelComponent(
159     RefPtr<V2::TabContentItemComponent>& tabContent, const std::string& labelStr)
160 {
161     tabContent->SetBarText(labelStr);
162     return TabBarItemComponent::BuildWithTextIcon(labelStr, std::string());
163 }
164 
ProcessTabBarLabel(RefPtr<V2::TabContentItemComponent> & tabContent,const std::optional<std::string> & textVal)165 RefPtr<Component> TabContentModelImpl::ProcessTabBarLabel(
166     RefPtr<V2::TabContentItemComponent>& tabContent, const std::optional<std::string>& textVal)
167 {
168     std::string textStr = textVal.value_or(DEFAULT_TAB_BAR_NAME);
169     tabContent->SetBarText(textStr);
170 
171     if (!Container::IsCurrentUsePartialUpdate()) {
172         return CreateTabBarLabelComponent(tabContent, textStr);
173     }
174     return nullptr;
175 }
176 
ProcessTabBarTextIconPair(RefPtr<V2::TabContentItemComponent> & tabContent,const std::optional<std::string> & textVal,const std::optional<std::string> & iconVal)177 RefPtr<Component> TabContentModelImpl::ProcessTabBarTextIconPair(RefPtr<V2::TabContentItemComponent>& tabContent,
178     const std::optional<std::string>& textVal, const std::optional<std::string>& iconVal)
179 {
180     if (!iconVal.has_value()) {
181         return ProcessTabBarLabel(tabContent, textVal);
182     }
183 
184     auto textStr = textVal.value_or(DEFAULT_TAB_BAR_NAME);
185     tabContent->SetBarText(textStr);
186     tabContent->SetBarIcon(iconVal.value());
187 
188     if (!Container::IsCurrentUsePartialUpdate()) {
189         return TabBarItemComponent::BuildWithTextIcon(textStr, iconVal.value());
190     }
191     return nullptr;
192 }
193 
194 } // namespace OHOS::Ace::Framework
195