1 /* 2 * Copyright (c) 2021-2022 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_TAB_BAR_RENDER_TAB_BAR_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_RENDER_TAB_BAR_H 18 19 #include <vector> 20 21 #include "base/memory/ace_type.h" 22 #include "core/components/common/properties/edge.h" 23 #include "core/components/scroll/scrollable.h" 24 #include "core/components/tab_bar/tab_bar_component.h" 25 #include "core/components/tab_bar/tab_bar_size_animation.h" 26 #include "core/gestures/click_recognizer.h" 27 #include "core/gestures/raw_recognizer.h" 28 #include "core/pipeline/base/render_node.h" 29 30 namespace OHOS::Ace { 31 32 class RenderTabBar : public RenderNode { 33 DECLARE_ACE_TYPE(RenderTabBar, RenderNode) 34 35 public: 36 ~RenderTabBar() override = default; 37 static RefPtr<RenderNode> Create(); 38 void Update(const RefPtr<Component>& component) override; 39 void PerformLayout() override; 40 41 using UpdateIndexFunc = std::function<void(int32_t index)>; RegisterCallback(const UpdateIndexFunc & callback)42 void RegisterCallback(const UpdateIndexFunc& callback) 43 { 44 callback_ = callback; 45 } 46 IsRightToLeft()47 bool IsRightToLeft() const 48 { 49 return GetTextDirection() == TextDirection::RTL && !isVertical_; 50 } 51 void SetScrollIndicator(double percent, int32_t newIndex, bool needChange); 52 void SetIndex(int32_t index, bool force = false); 53 void UpdateIndicatorStyle(const RefPtr<Component>& component); 54 void HandleFocusEvent(bool focus); 55 56 void OnPaintFinish() override; 57 GetTabsSize()58 int32_t GetTabsSize() const 59 { 60 return tabsSize_; 61 } 62 GetBarMode()63 TabBarMode GetBarMode() const 64 { 65 return mode_; 66 } 67 GetBarPosition()68 BarPosition GetBarPosition() const 69 { 70 return barPosition_; 71 } 72 FirstItemOffset()73 int32_t FirstItemOffset() const 74 { 75 return indicator_ ? 1 : 0; 76 } 77 78 // Update current focused index before removing of the child 79 // We can not use lifecycle callback OnChildRemoved here 80 // Since it is invoked only after RenderNode removed 81 // from list of the children AboutToRemove(const RefPtr<RenderNode> & child)82 void AboutToRemove(const RefPtr<RenderNode>& child) 83 { 84 auto kids = GetChildren(); 85 auto pos = std::find(kids.begin(), kids.end(), child); 86 if (pos != std::end(kids)) { 87 auto idx = std::distance(kids.begin(), pos); 88 if (indicator_) { 89 idx--; 90 } 91 if (idx <= index_ && index_ > 0) { 92 index_--; 93 } 94 } 95 } 96 GetFocusedTabBarItemIndex()97 int32_t GetFocusedTabBarItemIndex() const 98 { 99 return index_; 100 } 101 GetFocusedTabBarItem()102 RefPtr<RenderNode> GetFocusedTabBarItem() const 103 { 104 auto size = static_cast<int32_t>(GetChildren().size()); 105 106 int index = indicator_? index_ + 1 : index_; 107 if (index < 0 || index >= size) { 108 return nullptr; 109 } 110 auto pos = GetChildren().begin(); 111 std::advance(pos, index); 112 return *pos; 113 } 114 GetIndexForTabBarItem(const RefPtr<RenderNode> & child)115 int32_t GetIndexForTabBarItem(const RefPtr<RenderNode>& child) const 116 { 117 auto kids = GetChildren(); 118 auto pos = std::find(kids.begin(), kids.end(), child); 119 if (pos != std::end(kids)) { 120 auto idx = std::distance(kids.begin(), pos); 121 if (indicator_) { 122 idx--; 123 } 124 return idx; 125 } 126 return -1; 127 } 128 129 std::string ProvideRestoreInfo() override; 130 131 protected: 132 RenderTabBar(); 133 void OnTouchTestHit( 134 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override; 135 136 LayoutParam MakeInnerLayoutParam() const; 137 LayoutParam MakeIndicatorLayoutParam(const RefPtr<RenderNode>& item) const; 138 Offset MakeIndicatorOffset(const RefPtr<RenderNode>& item) const; 139 140 double MaxScrollableWidth() const; 141 double MaxScrollableHeight() const; 142 143 Size GetTabItemChildLayoutSize(const RefPtr<RenderNode>& child) const; 144 void ApplyGradientColor(); 145 TabBarIndicatorStyle GetIndicatorStyle(const RefPtr<BoxComponent>& component) const; 146 void InitScrollableOffset(TabBarMode mode); 147 148 TabBarMode mode_ = TabBarMode::FIXED; 149 TabBarIndicatorType indicatorSize_ = TabBarIndicatorType::TAB; 150 int32_t index_ = 0; 151 int32_t tabsSize_ = 0; 152 // mark update offset flag, which caused by index changed 153 bool needUpdateOffset_ = false; 154 std::vector<Offset> tabItemOffsets_; 155 std::vector<double> tabsWidth_; 156 std::vector<double> tabsHeight_; 157 158 Offset scrollableOffset_; 159 double tabBarWidth_ = 0.0; 160 double actualWidth_ = 0.0; 161 double actualHeight_ = 0.0; 162 163 Edge padding_ { 0.0 }; 164 Edge indicatorPadding_ { 0.0 }; 165 166 RefPtr<RenderNode> indicator_; 167 TabBarIndicatorStyle indicatorStyle_ = TabBarIndicatorStyle::DEFAULT; 168 Dimension activeIndicatorMinWidth_; 169 bool initialUpdate_ = true; 170 bool isFirstLayout_ = true; 171 bool onFocused_ = false; 172 Color focusAnimationColor_ = Color::WHITE; 173 Dimension focusRadiusDimension_; 174 Dimension gradientWidth_; 175 176 private: 177 bool isVertical_ = false; 178 179 void Initialize(); 180 void PerformLayoutChildren(const LayoutParam& innerLayoutParam); 181 void LayoutChildren(); 182 void UpdatePosition(); 183 void HandleClickedEvent(const ClickInfo& info); 184 void AccessibilityScroll(const bool isAdd); 185 void AccessibilityClick(); 186 void InitAccessibilityEventListener(); 187 bool HandleScrollablePosition(double); IsScrollable()188 bool IsScrollable() const 189 { 190 return TabBarMode::SCROLLABLE == mode_ || TabBarMode::FIXED_START == mode_; 191 } 192 RefPtr<RenderNode> GetChildByIndex(int32_t index) const; 193 194 void FlushIndex(const RefPtr<TabController>& controller); 195 void ApplyRestoreInfo(const RefPtr<TabController>& controller); 196 197 RefPtr<ClickRecognizer> clickRecognizer_; 198 RefPtr<Scrollable> scrollable_; 199 200 UpdateIndexFunc callback_; 201 RefPtr<TabBarSizeAnimation> tabBarSizeAnimation_; 202 int accessibilityIndex_ = -1; 203 BarPosition barPosition_ = BarPosition::START; 204 double indicatorPlusX_ = 0.0; 205 double indicatorPlusWidth_ = 0.0; 206 }; 207 208 } // namespace OHOS::Ace 209 210 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TAB_BAR_RENDER_TAB_BAR_H 211