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(false); 74 CHECK_NULL_VOID(parentNode); 75 auto grandParentNode = parentNode->GetAncestorNodeOfFrame(false); 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 } 89 CheckTabAnimateMode()90 void CheckTabAnimateMode() 91 { 92 if (!shallowBuilder_ || !firstTimeLayout_) { 93 return; 94 } 95 96 // Check whether current tabcontent belongs to tab component. 97 auto tabContentNode = GetHost(); 98 CHECK_NULL_VOID(tabContentNode); 99 auto parentNode = tabContentNode->GetAncestorNodeOfFrame(false); 100 CHECK_NULL_VOID(parentNode); 101 if (parentNode->GetTag() != V2::SWIPER_ETS_TAG) { 102 return; 103 } 104 auto grandParentNode = parentNode->GetAncestorNodeOfFrame(false); 105 CHECK_NULL_VOID(grandParentNode); 106 if (grandParentNode->GetTag() != V2::TABS_ETS_TAG) { 107 return; 108 } 109 110 auto tabsPattern = grandParentNode->GetPattern<TabsPattern>(); 111 CHECK_NULL_VOID(tabsPattern); 112 auto tabsLayoutProperty = grandParentNode->GetLayoutProperty<TabsLayoutProperty>(); 113 CHECK_NULL_VOID(tabsLayoutProperty); 114 TabAnimateMode mode = tabsPattern->GetAnimateMode(); 115 if ((mode == TabAnimateMode::ACTION_FIRST || mode == TabAnimateMode::ACTION_FIRST_WITH_JUMP) 116 && !tabsLayoutProperty->GetHeightAutoValue(false) 117 && !tabsLayoutProperty->GetWidthAutoValue(false)) { 118 ACE_SCOPED_TRACE("TabContentMarkRenderDone"); 119 /* 120 * Set render done only when tab's height&weight is not set to 'auto' and its animateMode 121 * is set to AnimateMode::ACTION_FIRST. 122 * Set render done before first layout, so to measure tabcontent and its children 123 * in two seperate frame. 124 */ 125 shallowBuilder_->MarkIsExecuteDeepRenderDone(true); 126 } 127 } 128 CleanChildren()129 void CleanChildren() 130 { 131 auto host = GetHost(); 132 CHECK_NULL_VOID(host); 133 if (host->GetChildren().empty()) { 134 return; 135 } 136 host->Clean(); 137 firstTimeLayout_ = true; 138 CHECK_NULL_VOID(shallowBuilder_); 139 shallowBuilder_->MarkIsExecuteDeepRenderDone(false); 140 } 141 BeforeCreateLayoutWrapper()142 void BeforeCreateLayoutWrapper() override 143 { 144 if (firstTimeLayout_) { 145 CheckTabAnimateMode(); 146 } 147 148 if (shallowBuilder_ && !shallowBuilder_->IsExecuteDeepRenderDone()) { 149 shallowBuilder_->ExecuteDeepRender(); 150 auto host = GetHost(); 151 CHECK_NULL_VOID(host); 152 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); 153 } else if (firstTimeLayout_ && shallowBuilder_ && shallowBuilder_->IsExecuteDeepRenderDone()) { 154 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck(); 155 if (!pipeline) { 156 shallowBuilder_->MarkIsExecuteDeepRenderDone(false); 157 return; 158 } 159 160 pipeline->AddAfterRenderTask([weak = WeakClaim(this), shallowBuilder = shallowBuilder_]() { 161 CHECK_NULL_VOID(shallowBuilder); 162 shallowBuilder->MarkIsExecuteDeepRenderDone(false); 163 auto pattern = weak.Upgrade(); 164 CHECK_NULL_VOID(pattern); 165 auto host = pattern->GetHost(); 166 CHECK_NULL_VOID(host); 167 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); 168 }); 169 } 170 firstTimeLayout_ = false; 171 } 172 CreateLayoutProperty()173 RefPtr<LayoutProperty> CreateLayoutProperty() override 174 { 175 return MakeRefPtr<TabContentLayoutProperty>(); 176 } 177 SetTabBar(const std::string & text,const std::string & icon,const std::optional<TabBarSymbol> & tabBarSymbol,TabBarBuilderFunc && builder)178 void SetTabBar(const std::string& text, const std::string& icon, 179 const std::optional<TabBarSymbol>& tabBarSymbol, TabBarBuilderFunc&& builder) 180 { 181 tabBarParam_.SetText(text); 182 tabBarParam_.SetIcon(icon); 183 tabBarParam_.SetSymbol(tabBarSymbol); 184 if (tabBarSymbol.has_value()) { 185 symbol_ = tabBarSymbol.value(); 186 } 187 tabBarParam_.SetBuilder(move(builder)); 188 } 189 SetTabBarWithContent(const RefPtr<NG::UINode> & content)190 void SetTabBarWithContent(const RefPtr<NG::UINode>& content) 191 { 192 tabBarParam_.SetContent(content); 193 } 194 GetSymbol()195 const TabBarSymbol& GetSymbol() 196 { 197 return symbol_; 198 } 199 GetTabBarParam()200 const TabBarParam& GetTabBarParam() const 201 { 202 return tabBarParam_; 203 } 204 SetCustomTabBar(FrameNode * node)205 void SetCustomTabBar(FrameNode* node) 206 { 207 tabBarParam_.SetCustomNode(node); 208 } 209 SetTabBarStyle(TabBarStyle tabBarStyle)210 void SetTabBarStyle(TabBarStyle tabBarStyle) 211 { 212 tabBarParam_.SetTabBarStyle(tabBarStyle); 213 } 214 GetTabBarStyle()215 TabBarStyle GetTabBarStyle() const 216 { 217 return tabBarParam_.GetTabBarStyle(); 218 } 219 SetIndicatorStyle(const IndicatorStyle & indicatorStyle)220 void SetIndicatorStyle(const IndicatorStyle& indicatorStyle) 221 { 222 indicatorStyle_ = indicatorStyle; 223 } 224 GetIndicatorStyle()225 const IndicatorStyle& GetIndicatorStyle() const 226 { 227 return indicatorStyle_; 228 } 229 SetSelectedMode(SelectedMode selectedMode)230 void SetSelectedMode(SelectedMode selectedMode) 231 { 232 selectedMode_ = selectedMode; 233 } 234 GetSelectedMode()235 SelectedMode GetSelectedMode() const 236 { 237 return selectedMode_; 238 } 239 SetBoardStyle(const BoardStyle & boardStyle)240 void SetBoardStyle(const BoardStyle& boardStyle) 241 { 242 boardStyle_ = boardStyle; 243 } 244 GetBoardStyle()245 const BoardStyle& GetBoardStyle() const 246 { 247 return boardStyle_; 248 } 249 SetLabelStyle(const LabelStyle & labelStyle)250 void SetLabelStyle(const LabelStyle& labelStyle) 251 { 252 labelStyle_ = labelStyle; 253 } 254 GetLabelStyle()255 const LabelStyle& GetLabelStyle() const 256 { 257 return labelStyle_; 258 } 259 SetIconStyle(const IconStyle & iconStyle)260 void SetIconStyle(const IconStyle& iconStyle) 261 { 262 iconStyle_ = iconStyle; 263 } 264 GetIconStyle()265 const IconStyle& GetIconStyle() const 266 { 267 return iconStyle_; 268 } 269 SetPadding(const PaddingProperty & padding)270 void SetPadding(const PaddingProperty& padding) 271 { 272 padding_ = padding; 273 } 274 GetPadding()275 const PaddingProperty& GetPadding() const 276 { 277 return padding_; 278 } 279 SetUseLocalizedPadding(bool useLocalizedPadding)280 void SetUseLocalizedPadding(bool useLocalizedPadding) 281 { 282 useLocalizedPadding_ = useLocalizedPadding; 283 } 284 GetUseLocalizedPadding()285 bool GetUseLocalizedPadding() 286 { 287 return useLocalizedPadding_; 288 } 289 SetSymmetricExtensible(bool isExtensible)290 void SetSymmetricExtensible(bool isExtensible) 291 { 292 bottomTabBarStyle_.symmetricExtensible = isExtensible; 293 } 294 SetLayoutMode(LayoutMode layoutMode)295 void SetLayoutMode(LayoutMode layoutMode) 296 { 297 bottomTabBarStyle_.layoutMode = layoutMode; 298 } 299 SetVerticalAlign(FlexAlign verticalAlign)300 void SetVerticalAlign(FlexAlign verticalAlign) 301 { 302 bottomTabBarStyle_.verticalAlign = verticalAlign; 303 } 304 SetId(const std::string & id)305 void SetId(const std::string& id) 306 { 307 tabBarInspectorId_ = id; 308 } 309 GetId()310 const std::string& GetId() const 311 { 312 return tabBarInspectorId_; 313 } 314 GetBottomTabBarStyle()315 const BottomTabBarStyle& GetBottomTabBarStyle() const 316 { 317 return bottomTabBarStyle_; 318 } 319 DumpAdvanceInfo()320 void DumpAdvanceInfo() override 321 { 322 switch (selectedMode_) { 323 case SelectedMode::INDICATOR: { 324 DumpLog::GetInstance().AddDesc("SelectedMode:INDICATOR"); 325 break; 326 } 327 case SelectedMode::BOARD: { 328 DumpLog::GetInstance().AddDesc("SelectedMode:BOARD"); 329 break; 330 } 331 default: { 332 break; 333 } 334 } 335 } 336 CreateEventHub()337 RefPtr<EventHub> CreateEventHub() override 338 { 339 return MakeRefPtr<TabContentEventHub>(); 340 } 341 FireWillShowEvent()342 void FireWillShowEvent() 343 { 344 auto tabContentEventHub = GetEventHub<TabContentEventHub>(); 345 CHECK_NULL_VOID(tabContentEventHub); 346 tabContentEventHub->FireWillShowEvent(); 347 } 348 FireWillHideEvent()349 void FireWillHideEvent() 350 { 351 auto tabContentEventHub = GetEventHub<TabContentEventHub>(); 352 CHECK_NULL_VOID(tabContentEventHub); 353 tabContentEventHub->FireWillHideEvent(); 354 } 355 HasSubTabBarStyleNode()356 bool HasSubTabBarStyleNode() const 357 { 358 return customStyleNode_ != nullptr; 359 } 360 SetCustomStyleNode(const RefPtr<FrameNode> & customStyleNode)361 void SetCustomStyleNode(const RefPtr<FrameNode>& customStyleNode) 362 { 363 customStyleNode_ = customStyleNode; 364 } 365 FireCustomStyleNode()366 const RefPtr<FrameNode>& FireCustomStyleNode() const 367 { 368 return customStyleNode_; 369 } 370 DumpAdvanceInfo(std::unique_ptr<JsonValue> & json)371 void DumpAdvanceInfo(std::unique_ptr<JsonValue>& json) override 372 { 373 switch (selectedMode_) { 374 case SelectedMode::INDICATOR: { 375 json->Put("SelectedMode", "INDICATOR"); 376 break; 377 } 378 case SelectedMode::BOARD: { 379 json->Put("SelectedMode", "BOARD"); 380 break; 381 } 382 default: { 383 break; 384 } 385 } 386 } 387 388 private: 389 RefPtr<ShallowBuilder> shallowBuilder_; 390 TabBarParam tabBarParam_; 391 IndicatorStyle indicatorStyle_; 392 SelectedMode selectedMode_ = SelectedMode::INDICATOR; 393 BoardStyle boardStyle_; 394 LabelStyle labelStyle_; 395 IconStyle iconStyle_; 396 PaddingProperty padding_; 397 std::string tabBarInspectorId_; 398 BottomTabBarStyle bottomTabBarStyle_; 399 RefPtr<FrameNode> customStyleNode_ = nullptr; 400 TabBarSymbol symbol_; 401 402 bool firstTimeLayout_ = true; 403 bool useLocalizedPadding_ = false; 404 405 ACE_DISALLOW_COPY_AND_MOVE(TabContentPattern); 406 }; 407 408 } // namespace OHOS::Ace::NG 409 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TABS_TAB_CONTENT_PATTERN_H 410