• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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