• 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/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