1 /* 2 * Copyright (c) 2021 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_V2_GRID_RENDER_GRID_SCROLL_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_GRID_RENDER_GRID_SCROLL_H 18 19 #include <list> 20 #include <map> 21 #include <set> 22 #include <unordered_map> 23 #include <utility> 24 25 #include "core/components/common/layout/constants.h" 26 #include "core/components/common/properties/scroll_bar.h" 27 #include "core/components/grid_layout/grid_layout_component.h" 28 #include "core/components/grid_layout/render_grid_layout.h" 29 #include "core/components/scroll/scroll_bar_theme.h" 30 #include "core/components/scroll/scrollable.h" 31 #include "core/pipeline/base/render_node.h" 32 33 namespace OHOS::Ace::V2 { 34 35 class GridEventInfo : public BaseEventInfo, public EventToJSONStringAdapter { 36 DECLARE_RELATIONSHIP_OF_CLASSES(GridEventInfo, BaseEventInfo, EventToJSONStringAdapter); 37 38 public: GridEventInfo(int32_t scrollIndex)39 GridEventInfo(int32_t scrollIndex) : BaseEventInfo("grid"), scrollIndex_(scrollIndex) {} 40 41 ~GridEventInfo() = default; 42 43 std::string ToJSONString() const override; 44 GetScrollIndex()45 int32_t GetScrollIndex() const 46 { 47 return scrollIndex_; 48 } 49 50 private: 51 int32_t scrollIndex_ = 0; 52 }; 53 54 class RenderGridScroll : public RenderGridLayout { 55 DECLARE_ACE_TYPE(RenderGridScroll, RenderGridLayout); 56 57 public: 58 using BuildChildByIndex = std::function<bool(int32_t)>; 59 using GetChildSpanByIndex = std::function<bool(int32_t, bool, int32_t&, int32_t&, int32_t&, int32_t&)>; 60 using DeleteChildByIndex = std::function<void(int32_t)>; 61 using OnScrolledFunc = std::function<void(std::shared_ptr<GridEventInfo>&)>; 62 63 RenderGridScroll() = default; 64 ~RenderGridScroll() override; 65 66 static RefPtr<RenderNode> Create(); 67 68 void Update(const RefPtr<Component>& component) override; 69 void PerformLayout() override; 70 void OnPredictLayout(int64_t deadline) override; 71 GetChildren()72 const std::list<RefPtr<RenderNode>>& GetChildren() const override 73 { 74 return childrenInRect_; 75 } 76 SetBuildChildByIndex(BuildChildByIndex func)77 void SetBuildChildByIndex(BuildChildByIndex func) 78 { 79 buildChildByIndex_ = std::move(func); 80 } 81 SetDeleteChildByIndex(DeleteChildByIndex func)82 void SetDeleteChildByIndex(DeleteChildByIndex func) 83 { 84 deleteChildByIndex_ = std::move(func); 85 } 86 SetGetChildSpanByIndex(GetChildSpanByIndex func)87 void SetGetChildSpanByIndex(GetChildSpanByIndex func) 88 { 89 getChildSpanByIndex_ = std::move(func); 90 } 91 92 void AddChildByIndex(int32_t index, const RefPtr<RenderNode>& renderNode); RemoveChildByIndex(int32_t index)93 void RemoveChildByIndex(int32_t index) 94 { 95 auto item = items_.find(index); 96 if (item != items_.end()) { 97 RemoveChild(item->second); 98 items_.erase(item); 99 } 100 } 101 void ClearLayout(bool needReservedPlace = false); 102 void ClearItems(); 103 void OnDataSourceUpdated(int32_t index); 104 SetTotalCount(int32_t totalCount)105 void SetTotalCount(int32_t totalCount) 106 { 107 if (totalCount_ == totalCount) { 108 return; 109 } 110 totalCount_ = totalCount; 111 totalCountFlag_ = true; 112 } 113 114 double GetEstimatedHeight(); 115 // Used in GridPositionController 116 void ScrollToIndex(int32_t index, int32_t source); 117 bool AnimateTo(const Dimension& position, float duration, const RefPtr<Curve>& curve); 118 Offset CurrentOffset(); 119 void ScrollToEdge(ScrollEdgeType edgeType, bool smooth); 120 void ScrollPage(bool reverse, bool smooth); GetAxis()121 Axis GetAxis() const 122 { 123 return useScrollable_ == SCROLLABLE::VERTICAL ? Axis::VERTICAL : Axis::HORIZONTAL; 124 } 125 126 void OnPaintFinish() override; 127 128 bool IsChildrenTouchEnable() override; 129 GetCachedSize()130 size_t GetCachedSize() const 131 { 132 return endShowItemIndex_ - startShowItemIndex_; 133 } 134 GetLastOffset()135 Offset GetLastOffset() const 136 { 137 return useScrollable_ == SCROLLABLE::VERTICAL ? Offset(0, lastOffset_) : Offset(lastOffset_, 0); 138 } 139 140 void HandleAxisEvent(const AxisEvent& event) override; 141 142 bool IsAxisScrollable(AxisDirection direction) override; 143 144 WeakPtr<RenderNode> CheckAxisNode() override; 145 146 protected: 147 int32_t GetItemMainIndex(const RefPtr<RenderNode>& child, bool isMain) const; 148 void SetMainSize(Size& dst, const Size& src); 149 double GetSize(const Size& src, bool isMain = true) const; 150 void GetNextGrid(int32_t& curMain, int32_t& curCross) const override; 151 void GetPreviousGrid(int32_t& curMain, int32_t& curCross); 152 LayoutParam MakeInnerLayoutParam(int32_t row, int32_t col, int32_t rowSpan, int32_t colSpan) const override; 153 bool CheckGridPlaced(int32_t index, int32_t row, int32_t col, int32_t& rowSpan, int32_t& colSpan) override; 154 155 // Sets child position, the mainAxis does not contain the offset. 156 void SetChildPosition( 157 const RefPtr<RenderNode>& child, int32_t row, int32_t col, int32_t rowSpan, int32_t colSpan) override; 158 159 void CreateScrollable(); 160 void LayoutChild(const RefPtr<RenderNode>& child, int32_t row, int32_t col, int32_t rowSpan, int32_t colSpan, 161 bool needPosition = true); 162 void OnTouchTestHit( 163 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override; 164 bool UpdateScrollPosition(double offset, int32_t source); 165 void RecordLocation(); 166 167 void InitialGridProp() override; 168 void CaculateViewPort(); 169 double BuildLazyGridLayout(int32_t index, double sizeNeed); 170 bool GetGridSize(); 171 void BuildGrid(std::vector<double>& rows, std::vector<double>& cols); 172 double CalculateBlankOfEnd(); 173 double SupplyItems(int32_t mainIndex, int32_t itemIndex = -1, bool needPosition = true); 174 bool Rank(int32_t mainIndex, int32_t itemIndex = -1); 175 bool GetItemPropsByIndex( 176 int32_t index, int32_t& itemMain, int32_t& itemCross, int32_t& itemMainSpan, int32_t& itemCrossSpan); 177 178 void DealCache(int32_t start, int32_t end); 179 void DeleteItems(int32_t index, bool isTail); 180 181 void GetMinAndMaxIndex(int32_t& min, int32_t& max); 182 int32_t GetItemMainIndex(int32_t index); 183 184 bool NeedUpdate(const RefPtr<Component>& component); 185 186 void CalculateWholeSize(double drawLength); 187 188 void InitScrollBar(const RefPtr<Component>& component); 189 void InitScrollBarProxy(); 190 191 void DoJump(double position, int32_t source); 192 193 int32_t GetStartingItem(int32_t first); 194 void LoadForward(); 195 GetCurrentOffset()196 double GetCurrentOffset() const 197 { 198 return startMainPos_ + currentOffset_ - firstItemOffset_; 199 } 200 201 void SetScrollBarCallback(); 202 203 int32_t GetIndexByPosition(double position) const; 204 205 void OnScrolled(int32_t scrolled) const; 206 207 enum class SCROLLABLE : uint32_t { 208 NO_SCROLL = 0, 209 VERTICAL, 210 HORIZONTAL, 211 }; 212 213 SCROLLABLE useScrollable_ = SCROLLABLE::NO_SCROLL; 214 215 std::map<int32_t, Size> metaData_; 216 std::unordered_map<int32_t, RefPtr<RenderNode>> items_; 217 std::set<int32_t> showItem_; 218 std::set<int32_t> inCache_; 219 std::list<RefPtr<RenderNode>> childrenInRect_; 220 221 RefPtr<Scrollable> scrollable_; 222 bool reachHead_ = false; 223 bool reachTail_ = false; 224 std::optional<bool> firstLineToBottom_; 225 bool needCalculateViewPort_ = false; 226 double startMainPos_ = 0.0; 227 double currentOffset_ = 0.0; 228 double animateDelta_ = 0.0; 229 double lastOffset_ = 0.0; 230 double firstItemOffset_ = 0.0; 231 int32_t startIndex_ = 0; 232 int32_t endIndex_ = -1; 233 234 int32_t startShowItemIndex_ = 0; 235 int32_t endShowItemIndex_ = -1; 236 237 int32_t startRankItemIndex_ = 0; 238 int32_t currentItemIndex_ = 0; 239 240 double* mainSize_ = &rowSize_; 241 double* crossSize_ = &colSize_; 242 int32_t* mainCount_ = &rowCount_; 243 int32_t* crossCount_ = &colCount_; 244 int32_t totalCount_ = 0; 245 double* crossGap_ = &colGap_; 246 double* mainGap_ = &rowGap_; 247 248 // used for scrollbar 249 double scrollBarExtent_ = 0.0; 250 double mainScrollExtent_ = 0.0; 251 int32_t scrollBarOpacity_ = 0; 252 double estimateHeight_ = 0.0; 253 bool totalCountFlag_ = false; 254 bool animatorJumpFlag_ = false; 255 Color scrollBarColor_; 256 257 RefPtr<ScrollBarProxy> scrollBarProxy_; 258 RefPtr<ScrollBar> scrollBar_; 259 RefPtr<Animator> animator_; 260 RefPtr<GridLayoutComponent> component_; 261 BuildChildByIndex buildChildByIndex_; 262 DeleteChildByIndex deleteChildByIndex_; 263 GetChildSpanByIndex getChildSpanByIndex_; 264 OnScrolledFunc scrolledEventFun_; 265 266 int32_t lastFirstIndex_ = -1; 267 int32_t loadingIndex_ = -1; 268 int32_t cacheCount_ = 1; 269 }; 270 271 } // namespace OHOS::Ace::V2 272 273 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_GRID_RENDER_GRID_SCROLL_H