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