1 /* 2 * Copyright (c) 2022-2023 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TABS_TAB_CONTENT_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TABS_TAB_CONTENT_PATTERN_H 18 19 #include "base/log/dump_log.h" 20 #include "base/memory/referenced.h" 21 #include "base/utils/noncopyable.h" 22 #include "core/components_ng/event/event_hub.h" 23 #include "core/components_ng/pattern/pattern.h" 24 #include "core/components_ng/pattern/tabs/tabs_pattern.h" 25 #include "core/components_ng/pattern/tabs/tab_bar_pattern.h" 26 #include "core/components_ng/pattern/tabs/tab_content_event_hub.h" 27 #include "core/components_ng/pattern/tabs/tab_content_layout_property.h" 28 #include "core/components_ng/syntax/shallow_builder.h" 29 30 namespace OHOS::Ace::NG { 31 32 class ACE_EXPORT TabContentPattern : public Pattern { 33 DECLARE_ACE_TYPE(TabContentPattern, Pattern); 34 35 public: TabContentPattern(const RefPtr<ShallowBuilder> & shallowBuilder)36 explicit TabContentPattern(const RefPtr<ShallowBuilder>& shallowBuilder) 37 : shallowBuilder_(shallowBuilder), tabBarParam_(std::string(""), std::string(""), nullptr) 38 {} 39 ~TabContentPattern() override = default; 40 OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)41 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override 42 { 43 if (shallowBuilder_ && !shallowBuilder_->IsExecuteDeepRenderDone()) { 44 auto host = GetHost(); 45 CHECK_NULL_RETURN(host, false); 46 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); 47 return true; 48 } 49 return false; 50 } 51 IsAtomicNode()52 bool IsAtomicNode() const override 53 { 54 return false; 55 } 56 IsMeasureBoundary()57 bool IsMeasureBoundary() const override 58 { 59 return false; 60 } 61 UsResRegion()62 bool UsResRegion() override 63 { 64 return false; 65 } 66 OnAttachToFrameNode()67 void OnAttachToFrameNode() override 68 { 69 auto host = GetHost(); 70 CHECK_NULL_VOID(host); 71 host->GetRenderContext()->UpdateClipEdge(true); 72 FireWillShowEvent(); 73 auto parentNode = host->GetAncestorNodeOfFrame(); 74 CHECK_NULL_VOID(parentNode); 75 auto grandParentNode = parentNode->GetAncestorNodeOfFrame(); 76 CHECK_NULL_VOID(grandParentNode); 77 if (grandParentNode->GetTag() == V2::TABS_ETS_TAG) { 78 auto tabLayoutProperty = AceType::DynamicCast<TabsLayoutProperty>( 79 grandParentNode->GetLayoutProperty()); 80 CHECK_NULL_VOID(tabLayoutProperty); 81 if (tabLayoutProperty->GetSafeAreaPaddingProperty()) { 82 host->GetLayoutProperty()->UpdateSafeAreaExpandOpts({ 83 .type = SAFE_AREA_TYPE_SYSTEM, 84 .edges = SAFE_AREA_EDGE_TOP + SAFE_AREA_EDGE_BOTTOM }); 85 } 86 } 87 } 88 CheckTabAnimateMode()89 void CheckTabAnimateMode() 90 { 91 if (!shallowBuilder_ || !firstTimeLayout_) { 92 return; 93 } 94 95 // Check whether current tabcontent belongs to tab component. 96 auto tabContentNode = GetHost(); 97 CHECK_NULL_VOID(tabContentNode); 98 auto parentNode = tabContentNode->GetAncestorNodeOfFrame(); 99 CHECK_NULL_VOID(parentNode); 100 if (parentNode->GetTag() != V2::SWIPER_ETS_TAG) { 101 return; 102 } 103 auto grandParentNode = parentNode->GetAncestorNodeOfFrame(); 104 CHECK_NULL_VOID(grandParentNode); 105 if (grandParentNode->GetTag() != V2::TABS_ETS_TAG) { 106 return; 107 } 108 109 auto tabsPattern = grandParentNode->GetPattern<TabsPattern>(); 110 CHECK_NULL_VOID(tabsPattern); 111 auto tabsLayoutProperty = grandParentNode->GetLayoutProperty<TabsLayoutProperty>(); 112 CHECK_NULL_VOID(tabsLayoutProperty); 113 TabAnimateMode mode = tabsPattern->GetAnimateMode(); 114 if (mode == TabAnimateMode::ACTION_FIRST 115 && !tabsLayoutProperty->GetHeightAutoValue(false) 116 && !tabsLayoutProperty->GetWidthAutoValue(false)) { 117 ACE_SCOPED_TRACE("TabContentMarkRenderDone"); 118 /* 119 * Set render done only when tab's height&weight is not set to 'auto' and its animateMode 120 * is set to AnimateMode::ACTION_FIRST. 121 * Set render done before first layout, so to measure tabcontent and its children 122 * in two seperate frame. 123 */ 124 shallowBuilder_->MarkIsExecuteDeepRenderDone(true); 125 } 126 } 127 BeforeCreateLayoutWrapper()128 void BeforeCreateLayoutWrapper() override 129 { 130 if (firstTimeLayout_) { 131 CheckTabAnimateMode(); 132 firstTimeLayout_ = false; 133 } 134 135 if (shallowBuilder_ && !shallowBuilder_->IsExecuteDeepRenderDone()) { 136 shallowBuilder_->ExecuteDeepRender(); 137 shallowBuilder_.Reset(); 138 } else if (shallowBuilder_ && shallowBuilder_->IsExecuteDeepRenderDone()) { 139 auto pipeline = PipelineContext::GetCurrentContextSafely(); 140 if (!pipeline) { 141 shallowBuilder_->MarkIsExecuteDeepRenderDone(false); 142 return; 143 } 144 145 pipeline->AddAfterRenderTask([weak = WeakClaim(this), shallowBuilder = shallowBuilder_]() { 146 CHECK_NULL_VOID(shallowBuilder); 147 shallowBuilder->MarkIsExecuteDeepRenderDone(false); 148 auto pattern = weak.Upgrade(); 149 CHECK_NULL_VOID(pattern); 150 auto host = pattern->GetHost(); 151 CHECK_NULL_VOID(host); 152 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); 153 }); 154 } 155 } 156 CreateLayoutProperty()157 RefPtr<LayoutProperty> CreateLayoutProperty() override 158 { 159 return MakeRefPtr<TabContentLayoutProperty>(); 160 } 161 SetTabBar(const std::string & text,const std::string & icon,const std::optional<TabBarSymbol> & tabBarSymbol,TabBarBuilderFunc && builder)162 void SetTabBar(const std::string& text, const std::string& icon, 163 const std::optional<TabBarSymbol>& tabBarSymbol, TabBarBuilderFunc&& builder) 164 { 165 tabBarParam_.SetText(text); 166 tabBarParam_.SetIcon(icon); 167 tabBarParam_.SetSymbol(tabBarSymbol); 168 if (tabBarSymbol.has_value()) { 169 symbol_ = tabBarSymbol.value(); 170 } 171 tabBarParam_.SetBuilder(move(builder)); 172 } 173 GetSymbol()174 const TabBarSymbol& GetSymbol() 175 { 176 return symbol_; 177 } 178 GetTabBarParam()179 const TabBarParam& GetTabBarParam() const 180 { 181 return tabBarParam_; 182 } 183 SetCustomTabBar(FrameNode * node)184 void SetCustomTabBar(FrameNode* node) 185 { 186 tabBarParam_.SetCustomNode(node); 187 } 188 SetTabBarStyle(TabBarStyle tabBarStyle)189 void SetTabBarStyle(TabBarStyle tabBarStyle) 190 { 191 tabBarParam_.SetTabBarStyle(tabBarStyle); 192 } 193 GetTabBarStyle()194 TabBarStyle GetTabBarStyle() const 195 { 196 return tabBarParam_.GetTabBarStyle(); 197 } 198 SetIndicatorStyle(const IndicatorStyle & indicatorStyle)199 void SetIndicatorStyle(const IndicatorStyle& indicatorStyle) 200 { 201 indicatorStyle_ = indicatorStyle; 202 } 203 GetIndicatorStyle()204 const IndicatorStyle& GetIndicatorStyle() const 205 { 206 return indicatorStyle_; 207 } 208 SetSelectedMode(SelectedMode selectedMode)209 void SetSelectedMode(SelectedMode selectedMode) 210 { 211 selectedMode_ = selectedMode; 212 } 213 GetSelectedMode()214 SelectedMode GetSelectedMode() const 215 { 216 return selectedMode_; 217 } 218 SetBoardStyle(const BoardStyle & boardStyle)219 void SetBoardStyle(const BoardStyle& boardStyle) 220 { 221 boardStyle_ = boardStyle; 222 } 223 GetBoardStyle()224 const BoardStyle& GetBoardStyle() const 225 { 226 return boardStyle_; 227 } 228 SetLabelStyle(const LabelStyle & labelStyle)229 void SetLabelStyle(const LabelStyle& labelStyle) 230 { 231 labelStyle_ = labelStyle; 232 } 233 GetLabelStyle()234 const LabelStyle& GetLabelStyle() const 235 { 236 return labelStyle_; 237 } 238 SetIconStyle(const IconStyle & iconStyle)239 void SetIconStyle(const IconStyle& iconStyle) 240 { 241 iconStyle_ = iconStyle; 242 } 243 GetIconStyle()244 const IconStyle& GetIconStyle() const 245 { 246 return iconStyle_; 247 } 248 SetPadding(const PaddingProperty & padding)249 void SetPadding(const PaddingProperty& padding) 250 { 251 padding_ = padding; 252 } 253 GetPadding()254 const PaddingProperty& GetPadding() const 255 { 256 return padding_; 257 } 258 SetUseLocalizedPadding(bool useLocalizedPadding)259 void SetUseLocalizedPadding(bool useLocalizedPadding) 260 { 261 useLocalizedPadding_ = useLocalizedPadding; 262 } 263 GetUseLocalizedPadding()264 bool GetUseLocalizedPadding() 265 { 266 return useLocalizedPadding_; 267 } 268 SetSymmetricExtensible(bool isExtensible)269 void SetSymmetricExtensible(bool isExtensible) 270 { 271 bottomTabBarStyle_.symmetricExtensible = isExtensible; 272 } 273 SetLayoutMode(LayoutMode layoutMode)274 void SetLayoutMode(LayoutMode layoutMode) 275 { 276 bottomTabBarStyle_.layoutMode = layoutMode; 277 } 278 SetVerticalAlign(FlexAlign verticalAlign)279 void SetVerticalAlign(FlexAlign verticalAlign) 280 { 281 bottomTabBarStyle_.verticalAlign = verticalAlign; 282 } 283 SetId(const std::string & id)284 void SetId(const std::string& id) 285 { 286 tabBarInspectorId_ = id; 287 } 288 GetId()289 const std::string& GetId() const 290 { 291 return tabBarInspectorId_; 292 } 293 GetBottomTabBarStyle()294 const BottomTabBarStyle& GetBottomTabBarStyle() const 295 { 296 return bottomTabBarStyle_; 297 } 298 DumpAdvanceInfo()299 void DumpAdvanceInfo() override 300 { 301 switch (selectedMode_) { 302 case SelectedMode::INDICATOR: { 303 DumpLog::GetInstance().AddDesc("SelectedMode:INDICATOR"); 304 break; 305 } 306 case SelectedMode::BOARD: { 307 DumpLog::GetInstance().AddDesc("SelectedMode:BOARD"); 308 break; 309 } 310 default: { 311 break; 312 } 313 } 314 } 315 CreateEventHub()316 RefPtr<EventHub> CreateEventHub() override 317 { 318 return MakeRefPtr<TabContentEventHub>(); 319 } 320 FireWillShowEvent()321 void FireWillShowEvent() 322 { 323 auto tabContentEventHub = GetEventHub<TabContentEventHub>(); 324 CHECK_NULL_VOID(tabContentEventHub); 325 tabContentEventHub->FireWillShowEvent(); 326 } 327 FireWillHideEvent()328 void FireWillHideEvent() 329 { 330 auto tabContentEventHub = GetEventHub<TabContentEventHub>(); 331 CHECK_NULL_VOID(tabContentEventHub); 332 tabContentEventHub->FireWillHideEvent(); 333 } 334 HasSubTabBarStyleNode()335 bool HasSubTabBarStyleNode() const 336 { 337 return customStyleNode_ != nullptr; 338 } 339 SetCustomStyleNode(const RefPtr<FrameNode> & customStyleNode)340 void SetCustomStyleNode(const RefPtr<FrameNode>& customStyleNode) 341 { 342 customStyleNode_ = customStyleNode; 343 } 344 FireCustomStyleNode()345 const RefPtr<FrameNode>& FireCustomStyleNode() const 346 { 347 return customStyleNode_; 348 } 349 350 private: 351 RefPtr<ShallowBuilder> shallowBuilder_; 352 TabBarParam tabBarParam_; 353 IndicatorStyle indicatorStyle_; 354 SelectedMode selectedMode_ = SelectedMode::INDICATOR; 355 BoardStyle boardStyle_; 356 LabelStyle labelStyle_; 357 IconStyle iconStyle_; 358 PaddingProperty padding_; 359 std::string tabBarInspectorId_; 360 BottomTabBarStyle bottomTabBarStyle_; 361 RefPtr<FrameNode> customStyleNode_ = nullptr; 362 TabBarSymbol symbol_; 363 364 bool firstTimeLayout_ = true; 365 bool useLocalizedPadding_ = false; 366 367 ACE_DISALLOW_COPY_AND_MOVE(TabContentPattern); 368 }; 369 370 } // namespace OHOS::Ace::NG 371 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TABS_TAB_CONTENT_PATTERN_H 372