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_BAR_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TABS_TAB_BAR_PATTERN_H 18 19 #include <optional> 20 #include <unordered_map> 21 22 #include "base/geometry/axis.h" 23 #include "base/memory/referenced.h" 24 #include "core/components/common/layout/constants.h" 25 #include "core/components/swiper/swiper_controller.h" 26 #include "core/components/tab_bar/tab_theme.h" 27 #include "core/components_ng/event/event_hub.h" 28 #include "core/components_ng/pattern/pattern.h" 29 #include "core/components_ng/pattern/swiper/swiper_model.h" 30 #include "core/components_ng/pattern/tabs/tab_bar_accessibility_property.h" 31 #include "core/components_ng/pattern/tabs/tab_bar_layout_algorithm.h" 32 #include "core/components_ng/pattern/tabs/tab_bar_layout_property.h" 33 #include "core/components_ng/pattern/tabs/tab_bar_paint_method.h" 34 #include "core/components_ng/pattern/tabs/tab_bar_paint_property.h" 35 #include "core/event/mouse_event.h" 36 #include "core/components_ng/pattern/tabs/tab_content_transition_proxy.h" 37 #include "frameworks/core/components/focus_animation/focus_animation_theme.h" 38 #include "frameworks/core/components_ng/event/focus_hub.h" 39 40 namespace OHOS::Ace::NG { 41 42 const auto TabBarPhysicalCurve = AceType::MakeRefPtr<InterpolatingSpring>(-1.0f, 1.0f, 228.0f, 30.f); 43 44 using TabBarBuilderFunc = std::function<void()>; 45 class TabBarParam : public virtual Referenced { 46 public: TabBarParam(const std::string & textParam,const std::string & iconParam,TabBarBuilderFunc && builderParam)47 TabBarParam(const std::string& textParam, const std::string& iconParam, TabBarBuilderFunc&& builderParam) 48 : text_(textParam), icon_(iconParam), builder_(std::move(builderParam)) {}; 49 GetIcon()50 const std::string& GetIcon() const 51 { 52 return icon_; 53 } 54 SetIcon(const std::string & icon)55 void SetIcon(const std::string& icon) 56 { 57 icon_ = icon; 58 } 59 GetText()60 const std::string& GetText() const 61 { 62 return text_; 63 } 64 SetText(const std::string & text)65 void SetText(const std::string& text) 66 { 67 text_ = text; 68 } 69 HasBuilder()70 bool HasBuilder() const 71 { 72 return builder_ != nullptr; 73 } 74 SetBuilder(TabBarBuilderFunc && builderParam)75 void SetBuilder(TabBarBuilderFunc&& builderParam) 76 { 77 builder_ = std::move(builderParam); 78 } 79 ExecuteBuilder()80 void ExecuteBuilder() const 81 { 82 if (builder_ != nullptr) { 83 builder_(); 84 } 85 } 86 SetTabBarStyle(TabBarStyle tabBarStyle)87 void SetTabBarStyle(TabBarStyle tabBarStyle) 88 { 89 tabBarStyle_ = tabBarStyle; 90 } 91 GetTabBarStyle()92 TabBarStyle GetTabBarStyle() const 93 { 94 return tabBarStyle_; 95 } 96 97 private: 98 std::string text_; 99 std::string icon_; 100 TabBarBuilderFunc builder_; 101 TabBarStyle tabBarStyle_; 102 }; 103 104 enum class AnimationType { 105 PRESS = 0, 106 HOVER, 107 HOVERTOPRESS, 108 }; 109 110 class TabBarPattern : public Pattern { 111 DECLARE_ACE_TYPE(TabBarPattern, Pattern); 112 113 public: TabBarPattern(const RefPtr<SwiperController> & swiperController)114 explicit TabBarPattern(const RefPtr<SwiperController>& swiperController) : swiperController_(swiperController) {}; 115 ~TabBarPattern() override = default; 116 IsAtomicNode()117 bool IsAtomicNode() const override 118 { 119 return false; 120 } 121 CreateLayoutProperty()122 RefPtr<LayoutProperty> CreateLayoutProperty() override 123 { 124 return MakeRefPtr<TabBarLayoutProperty>(); 125 } 126 CreateLayoutAlgorithm()127 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 128 { 129 auto layoutAlgorithm = MakeRefPtr<TabBarLayoutAlgorithm>(); 130 layoutAlgorithm->SetChildrenMainSize(childrenMainSize_); 131 layoutAlgorithm->SetCurrentOffset(currentOffset_); 132 layoutAlgorithm->SetIndicator(indicator_); 133 layoutAlgorithm->SetIsBuilder(IsContainsBuilder()); 134 layoutAlgorithm->SetTabBarStyle(tabBarStyle_); 135 if (needSetCentered_) { 136 layoutAlgorithm->SetNeedSetCentered(); 137 needSetCentered_ = false; 138 } 139 layoutAlgorithm->SetScrollMargin(scrollMargin_); 140 return layoutAlgorithm; 141 } 142 CreatePaintProperty()143 RefPtr<PaintProperty> CreatePaintProperty() override 144 { 145 return MakeRefPtr<TabBarPaintProperty>(); 146 } 147 148 RefPtr<NodePaintMethod> CreateNodePaintMethod() override; 149 CreateAccessibilityProperty()150 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 151 { 152 return MakeRefPtr<TabBarAccessibilityProperty>(); 153 } 154 GetFocusPattern()155 FocusPattern GetFocusPattern() const override 156 { 157 FocusPaintParam focusPaintParams; 158 auto pipeline = PipelineBase::GetCurrentContext(); 159 CHECK_NULL_RETURN(pipeline, FocusPattern()); 160 auto focusTheme = pipeline->GetTheme<FocusAnimationTheme>(); 161 CHECK_NULL_RETURN(focusTheme, FocusPattern()); 162 auto tabTheme = pipeline->GetTheme<TabTheme>(); 163 CHECK_NULL_RETURN(tabTheme, FocusPattern()); 164 focusPaintParams.SetPaintWidth(tabTheme->GetActiveIndicatorWidth()); 165 focusPaintParams.SetPaintColor(focusTheme->GetColor()); 166 return { FocusType::NODE, true, FocusStyleType::CUSTOM_REGION, focusPaintParams }; 167 } 168 SetChildrenMainSize(float childrenMainSize)169 void SetChildrenMainSize(float childrenMainSize) 170 { 171 childrenMainSize_ = childrenMainSize; 172 } 173 SetIndicator(int32_t indicator)174 void SetIndicator(int32_t indicator) 175 { 176 indicator_ = indicator; 177 } 178 179 void UpdateCurrentOffset(float offset); 180 181 void UpdateIndicator(int32_t indicator); 182 183 void UpdateTextColorAndFontWeight(int32_t indicator); 184 185 void UpdateImageColor(int32_t indicator); 186 187 void UpdateSubTabBoard(); 188 189 SelectedMode GetSelectedMode() const; 190 AddTabBarItemType(int32_t tabContentId,bool isBuilder)191 void AddTabBarItemType(int32_t tabContentId, bool isBuilder) 192 { 193 tabBarType_.emplace(std::make_pair(tabContentId, isBuilder)); 194 } 195 196 bool IsContainsBuilder(); 197 SetAnimationDuration(int32_t animationDuration)198 void SetAnimationDuration(int32_t animationDuration) 199 { 200 animationDuration_ = animationDuration; 201 } 202 SetTouching(bool isTouching)203 void SetTouching(bool isTouching) 204 { 205 touching_ = isTouching; 206 } 207 IsTouching()208 bool IsTouching() const 209 { 210 return touching_; 211 } 212 SetTabBarStyle(TabBarStyle tabBarStyle)213 void SetTabBarStyle(TabBarStyle tabBarStyle) 214 { 215 tabBarStyle_ = tabBarStyle; 216 } 217 GetTabBarStyle()218 TabBarStyle GetTabBarStyle() const 219 { 220 return tabBarStyle_; 221 } 222 223 void PlayTabBarTranslateAnimation(int32_t targetIndex); 224 void StopTabBarTranslateAnimation(); 225 void HandleBottomTabBarChange(int32_t index); 226 GetChangeByClick()227 bool GetChangeByClick() const 228 { 229 return changeByClick_; 230 } 231 SetChangeByClick(bool changeByClick)232 void SetChangeByClick(bool changeByClick) 233 { 234 changeByClick_ = changeByClick; 235 } SetSelectedMode(SelectedMode selectedMode,uint32_t position)236 void SetSelectedMode(SelectedMode selectedMode, uint32_t position) 237 { 238 if (selectedModes_.size() == position) { 239 selectedModes_.emplace_back(selectedMode); 240 } else { 241 selectedModes_[position] = selectedMode; 242 } 243 } 244 SetIndicatorStyle(const IndicatorStyle & indicatorStyle,uint32_t position)245 void SetIndicatorStyle(const IndicatorStyle& indicatorStyle, uint32_t position) 246 { 247 if (indicatorStyles_.size() == position) { 248 indicatorStyles_.emplace_back(indicatorStyle); 249 } else { 250 indicatorStyles_[position] = indicatorStyle; 251 } 252 } 253 SetTabBarStyle(TabBarStyle tabBarStyle,uint32_t position)254 void SetTabBarStyle(TabBarStyle tabBarStyle, uint32_t position) 255 { 256 if (tabBarStyles_.size() == position) { 257 tabBarStyles_.emplace_back(tabBarStyle); 258 } else { 259 tabBarStyles_[position] = tabBarStyle; 260 } 261 } 262 SetBottomTabBarStyle(const BottomTabBarStyle & bottomTabBarStyle,uint32_t position)263 void SetBottomTabBarStyle(const BottomTabBarStyle& bottomTabBarStyle, uint32_t position) 264 { 265 if (bottomTabBarStyles_.size() == position) { 266 bottomTabBarStyles_.emplace_back(bottomTabBarStyle); 267 } else { 268 bottomTabBarStyles_[position] = bottomTabBarStyle; 269 } 270 } 271 SetLabelStyle(const LabelStyle & labelStyle,uint32_t position)272 void SetLabelStyle(const LabelStyle& labelStyle, uint32_t position) 273 { 274 if (labelStyles_.size() == position) { 275 labelStyles_.emplace_back(labelStyle); 276 } else { 277 labelStyles_[position] = labelStyle; 278 } 279 } 280 IsMaskAnimationByCreate()281 bool IsMaskAnimationByCreate() 282 { 283 return isMaskAnimationByCreate_; 284 } 285 SetMaskAnimationByCreate(bool isMaskAnimationByCreate)286 void SetMaskAnimationByCreate(bool isMaskAnimationByCreate) 287 { 288 isMaskAnimationByCreate_ = isMaskAnimationByCreate; 289 } 290 IsMaskAnimationExecuted()291 bool IsMaskAnimationExecuted() 292 { 293 return isMaskAnimationExecuted_; 294 } 295 SetMaskAnimationExecuted(bool isMaskAnimationExecuted)296 void SetMaskAnimationExecuted(bool isMaskAnimationExecuted) 297 { 298 isMaskAnimationExecuted_ = isMaskAnimationExecuted; 299 } 300 SetImageColorOnIndex(int32_t index)301 void SetImageColorOnIndex(int32_t index) 302 { 303 imageColorOnIndex_ = index; 304 } 305 GetImageColorOnIndex()306 std::optional<int32_t> GetImageColorOnIndex() 307 { 308 return imageColorOnIndex_; 309 } 310 GetIndicator()311 int32_t GetIndicator() 312 { 313 return indicator_; 314 } 315 316 bool IsAtTop() const; 317 318 bool IsAtBottom() const; 319 std::string ProvideRestoreInfo() override; 320 void OnRestoreInfo(const std::string& restoreInfo) override; 321 322 void ToJsonValue(std::unique_ptr<JsonValue>& json) const override; 323 void FromJson(const std::unique_ptr<JsonValue>& json) override; 324 SetFirstFocus(bool isFirstFocus)325 void SetFirstFocus(bool isFirstFocus) 326 { 327 isFirstFocus_ = isFirstFocus; 328 } 329 ResetIndicatorAnimationState()330 void ResetIndicatorAnimationState() 331 { 332 isAnimating_ = false; 333 animationTargetIndex_.reset(); 334 } 335 GetTouchingSwiper()336 bool GetTouchingSwiper() const 337 { 338 return isTouchingSwiper_; 339 } 340 GetTabBarStyle(uint32_t position)341 TabBarStyle GetTabBarStyle(uint32_t position) const 342 { 343 if (position < 0 || position >= tabBarStyles_.size()) { 344 return TabBarStyle::NOSTYLE; 345 } 346 return tabBarStyles_[position]; 347 } 348 GetBottomTabBarStyle(uint32_t position)349 const BottomTabBarStyle& GetBottomTabBarStyle(uint32_t position) const 350 { 351 if (position < 0 || position >= bottomTabBarStyles_.size()) { 352 return bottomTabBarStyle_; 353 } 354 return bottomTabBarStyles_[position]; 355 } 356 357 void DumpAdvanceInfo() override; 358 359 std::optional<int32_t> GetAnimationDuration(); 360 HasSurfaceChangedCallback()361 bool HasSurfaceChangedCallback() 362 { 363 return surfaceChangedCallbackId_.has_value(); 364 } 365 UpdateSurfaceChangedCallbackId(int32_t id)366 void UpdateSurfaceChangedCallbackId(int32_t id) 367 { 368 surfaceChangedCallbackId_ = id; 369 } 370 371 bool ContentWillChange(int32_t comingIndex); 372 bool ContentWillChange(int32_t currentIndex, int32_t comingIndex); 373 374 private: 375 void OnModifyDone() override; 376 void OnAttachToFrameNode() override; 377 void InitSurfaceChangedCallback(); 378 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 379 380 void InitClick(const RefPtr<GestureEventHub>& gestureHub); 381 void InitScrollable(const RefPtr<GestureEventHub>& gestureHub); 382 void InitTouch(const RefPtr<GestureEventHub>& gestureHub); 383 void InitHoverEvent(); 384 void InitMouseEvent(); 385 386 void HandleMouseEvent(const MouseInfo& info); 387 void HandleHoverEvent(bool isHover); 388 void HandleHoverOnEvent(int32_t index); 389 void HandleMoveAway(int32_t index); 390 void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub); 391 bool OnKeyEvent(const KeyEvent& event); 392 bool OnKeyEventWithoutClick(const KeyEvent& event); 393 bool OnKeyEventWithoutClick(const RefPtr<FrameNode>& host, const KeyEvent& event); 394 void HandleClick(const GestureEvent& info); 395 void ClickTo(const RefPtr<FrameNode>& host, int32_t index); 396 void HandleTouchEvent(const TouchLocationInfo& info); 397 void HandleSubTabBarClick(const RefPtr<TabBarLayoutProperty>& layoutProperty, int32_t index); 398 void HandleBottomTabBarClick(int32_t selectedIndex, int32_t unselectedIndex); 399 void ChangeMask(int32_t index, float imageSize, const OffsetF& originalMaskOffset, float opacity, 400 float radiusRatio, bool isSelected); 401 void PlayMaskAnimation(float selectedImageSize, const OffsetF& originalSelectedMaskOffset, int32_t selectedIndex, 402 float unselectedImageSize, const OffsetF& originalUnselectedMaskOffset, int32_t unselectedIndex); 403 static void MaskAnimationFinish(const RefPtr<FrameNode>& host, int32_t selectedIndex, bool isSelected); 404 void GetBottomTabBarImageSizeAndOffset(const std::vector<int32_t>& selectedIndexes, 405 int32_t maskIndex, float& selectedImageSize, float& unselectedImageSize, OffsetF& originalSelectedMaskOffset, 406 OffsetF& originalUnselectedMaskOffset); 407 bool CheckSvg(int32_t index) const; 408 409 void HandleTouchDown(int32_t index); 410 void HandleTouchUp(int32_t index); 411 int32_t CalculateSelectedIndex(const Offset& info); 412 413 void PlayPressAnimation(int32_t index, const Color& pressColor, AnimationType animationType); 414 void PlayTranslateAnimation(float startPos, float endPos, float targetCurrentOffset); 415 void StopTranslateAnimation(); 416 void UpdateIndicatorCurrentOffset(float offset); 417 418 void GetInnerFocusPaintRect(RoundRect& paintRect); 419 void PaintFocusState(bool needMarkDirty = true); 420 void FocusIndexChange(int32_t index); 421 void UpdateGradientRegions(bool needMarkDirty = true); 422 423 float GetSpace(int32_t indicator); 424 float CalculateFrontChildrenMainSize(int32_t indicator); 425 float CalculateBackChildrenMainSize(int32_t indicator); 426 void SetEdgeEffect(const RefPtr<GestureEventHub>& gestureHub); 427 void SetEdgeEffectCallback(const RefPtr<ScrollEdgeEffect>& scrollEffect); 428 bool IsOutOfBoundary(); 429 void SetAccessibilityAction(); 430 void AdjustFocusPosition(); 431 void TabBarClickEvent(int32_t index) const; 432 void OnCustomContentTransition(int32_t fromIndex, int32_t toIndex); 433 void ApplyTurnPageRateToIndicator(float turnPageRate); 434 bool CheckSwiperDisable() const; 435 void SetSwiperCurve(const RefPtr<Curve>& curve) const; 436 void AdjustOffset(double& offset) const; 437 void InitTurnPageRateEvent(); 438 void GetIndicatorStyle(IndicatorStyle& indicatorStyle); 439 float GetLeftPadding() const; 440 void HandleBottomTabBarAnimation(int32_t index); 441 void TriggerTranslateAnimation( 442 const RefPtr<TabBarLayoutProperty>& layoutProperty, int32_t index, int32_t indicator); 443 void UpdatePaintIndicator(int32_t indicator, bool needMarkDirty); 444 bool IsNeedUpdateFontWeight(int32_t index); 445 446 RefPtr<ClickEvent> clickEvent_; 447 RefPtr<TouchEventImpl> touchEvent_; 448 RefPtr<ScrollableEvent> scrollableEvent_; 449 RefPtr<InputEvent> mouseEvent_; 450 RefPtr<InputEvent> hoverEvent_; 451 RefPtr<SwiperController> swiperController_; 452 RefPtr<ScrollEdgeEffect> scrollEffect_; 453 AnimationStartEventPtr animationStartEvent_; 454 AnimationEndEventPtr animationEndEvent_; 455 456 float currentOffset_ = 0.0f; 457 float childrenMainSize_ = 0.0f; 458 int32_t indicator_ = 0; 459 int32_t focusIndicator_ = 0; 460 Axis axis_ = Axis::HORIZONTAL; 461 std::vector<OffsetF> tabItemOffsets_; 462 std::unordered_map<int32_t, bool> tabBarType_; 463 std::optional<int32_t> animationDuration_; 464 465 std::shared_ptr<AnimationUtils::Animation> tabbarIndicatorAnimation_; 466 std::shared_ptr<AnimationUtils::Animation> translateAnimation_; 467 std::shared_ptr<AnimationUtils::Animation> tabBarTranslateAnimation_; 468 469 bool indicatorAnimationIsRunning_ = false; 470 bool translateAnimationIsRunning_ = false; 471 bool tabBarTranslateAnimationIsRunning_ = false; 472 473 bool isRTL_ = false; // TODO Adapt RTL. 474 475 bool touching_ = false; // whether the item is in touching 476 bool isHover_ = false; 477 bool isMaskAnimationByCreate_ = false; 478 bool isMaskAnimationExecuted_ = false; 479 std::optional<int32_t> imageColorOnIndex_; 480 std::optional<int32_t> touchingIndex_; 481 std::optional<int32_t> hoverIndex_; 482 TabBarStyle tabBarStyle_; 483 float currentIndicatorOffset_ = 0.0f; 484 std::vector<SelectedMode> selectedModes_; 485 std::vector<IndicatorStyle> indicatorStyles_; 486 std::vector<TabBarStyle> tabBarStyles_; 487 std::vector<LabelStyle> labelStyles_; 488 bool isFirstFocus_ = true; 489 bool isTouchingSwiper_ = false; 490 float indicatorStartPos_ = 0.0f; 491 float indicatorEndPos_ = 0.0f; 492 float turnPageRate_ = 0.0f; 493 int32_t swiperStartIndex_ = 0; 494 std::vector<BottomTabBarStyle> bottomTabBarStyles_; 495 BottomTabBarStyle bottomTabBarStyle_; 496 497 RefPtr<TabBarModifier> tabBarModifier_; 498 std::vector<bool> gradientRegions_ = {false, false, false, false}; 499 bool isAnimating_ = false; 500 bool changeByClick_ = false; 501 bool needSetCentered_ = false; 502 float scrollMargin_ = 0.0f; 503 bool isFirstLayout_ = true; 504 std::optional<int32_t> animationTargetIndex_; 505 std::optional<int32_t> surfaceChangedCallbackId_; 506 std::optional<WindowSizeChangeReason> windowSizeChangeReason_; 507 ACE_DISALLOW_COPY_AND_MOVE(TabBarPattern); 508 }; 509 } // namespace OHOS::Ace::NG 510 511 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TABS_TAB_BAR_PATTERN_H 512