1 /* 2 * Copyright (c) 2022-2024 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_WATER_FLOW_RENDER_WATER_FLOW_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_WATER_FLOW_RENDER_WATER_FLOW_H 18 19 #include <map> 20 #include <set> 21 #include <unordered_map> 22 #include <vector> 23 24 #include "core/components/common/layout/constants.h" 25 #include "core/components/common/properties/scroll_bar.h" 26 #include "core/components/positioned/positioned_component.h" 27 #include "core/components/scroll/scroll_bar_theme.h" 28 #include "core/components/scroll/scrollable.h" 29 #include "core/components_v2/water_flow/render_water_flow_item.h" 30 #include "core/components_v2/water_flow/water_flow_component.h" 31 #include "core/components_v2/water_flow/water_flow_item_generator.h" 32 #include "core/pipeline/base/render_node.h" 33 34 namespace OHOS::Ace::V2 { 35 enum class SCROLLABLE : uint32_t { 36 NO_SCROLL = 0, 37 VERTICAL, 38 HORIZONTAL, 39 }; 40 41 enum class WaterFlowEvents : uint32_t { 42 NONE = 0, 43 REACH_START, 44 REACH_END, 45 }; 46 47 using FlowStyle = struct { 48 double mainPos = 0.0; // position of main side 49 double crossPos = 0.0; // position of cross side 50 double mainSize = 0.0; // size of main side 51 double crossSize = 0.0; // size of corss side 52 }; 53 54 using ItemConstraintSize = struct { 55 double minCrossSize = 0.0; // min cross Size 56 double maxCrossSize = 0.0; // max cross Size 57 double minMainSize = 0.0; // min main Size 58 double maxMainSize = 0.0; // max cross Size 59 }; 60 61 class RenderWaterFlow : public RenderNode { 62 DECLARE_ACE_TYPE(RenderWaterFlow, RenderNode); 63 64 public: 65 using BuildChildByIndex = std::function<bool(size_t)>; 66 using DeleteChildByIndex = std::function<void(size_t)>; 67 using UpdateTotalCount = std::function<size_t()>; 68 69 RenderWaterFlow() = default; 70 ~RenderWaterFlow() override; 71 72 static RefPtr<RenderNode> Create(); 73 74 void Update(const RefPtr<Component>& component) override; 75 void PerformLayout() override; 76 void OnPredictLayout(int64_t deadline) override; 77 SetBuildChildByIndex(BuildChildByIndex func)78 inline void SetBuildChildByIndex(BuildChildByIndex func) 79 { 80 buildChildByIndex_ = std::move(func); 81 } 82 SetDeleteChildByIndex(DeleteChildByIndex func)83 inline void SetDeleteChildByIndex(DeleteChildByIndex func) 84 { 85 deleteChildByIndex_ = std::move(func); 86 } 87 SetGetTotalCount(UpdateTotalCount func)88 inline void SetGetTotalCount(UpdateTotalCount func) 89 { 90 getTotalCount_ = std::move(func); 91 } 92 93 void AddChildByIndex(size_t index, const RefPtr<RenderNode>& renderNode); RemoveChildByIndex(size_t index)94 inline void RemoveChildByIndex(size_t index) 95 { 96 auto item = items_.find(index); 97 if (item != items_.end()) { 98 RemoveChild(item->second); 99 items_.erase(item); 100 } 101 } 102 void ClearLayout(size_t index, bool clearAll = false); 103 void ClearItems(size_t index = 0); 104 void OnDataSourceUpdated(size_t index); 105 SetTotalCount(size_t totalCount)106 inline void SetTotalCount(size_t totalCount) 107 { 108 if (totalCount_ != totalCount) { 109 totalCount_ = totalCount; 110 } 111 } 112 113 double GetEstimatedHeight(); 114 void ScrollToIndex(int32_t index); 115 GetAxis()116 inline Axis GetAxis() const 117 { 118 return useScrollable_ == SCROLLABLE::VERTICAL ? Axis::VERTICAL : Axis::HORIZONTAL; 119 } 120 121 bool IsChildrenTouchEnable() override; GetLastOffset()122 inline Offset GetLastOffset() const 123 { 124 return useScrollable_ == SCROLLABLE::VERTICAL ? Offset(0.0, lastOffset_) : Offset(lastOffset_, 0.0); 125 } 126 127 void HandleAxisEvent(const AxisEvent& event) override; 128 bool IsAxisScrollable(AxisDirection direction) override; 129 WeakPtr<RenderNode> CheckAxisNode() override; 130 void OnChildAdded(const RefPtr<RenderNode>& renderNode) override; 131 bool IsUseOnly() override; 132 void RequestWaterFlowFooter(); RegisterItemGenerator(WeakPtr<WaterFlowItemGenerator> && waterFlowItemGenerator)133 inline void RegisterItemGenerator(WeakPtr<WaterFlowItemGenerator>&& waterFlowItemGenerator) 134 { 135 itemGenerator_ = std::move(waterFlowItemGenerator); 136 } 137 GetColumnsArgs()138 const std::string& GetColumnsArgs() const 139 { 140 return colsArgs_; 141 } 142 GetRowsArgs()143 const std::string& GetRowsArgs() const 144 { 145 return rowsArgs_; 146 } 147 GetColumnsGap()148 const Dimension& GetColumnsGap() const 149 { 150 return userColGap_; 151 } 152 GetRowsGap()153 const Dimension& GetRowsGap() const 154 { 155 return userRowGap_; 156 } 157 GetlayoutDirection()158 FlexDirection GetlayoutDirection() const 159 { 160 return direction_; 161 } 162 GetItemConstraintSize()163 ItemConstraintSize GetItemConstraintSize() const 164 { 165 return itemConstraintSize_; 166 } 167 168 protected: 169 RefPtr<ScrollBarProxy> scrollBarProxy_; 170 RefPtr<ScrollBar> scrollBar_; 171 int32_t scrollBarOpacity_ = 0; 172 SCROLLABLE useScrollable_ = SCROLLABLE::NO_SCROLL; 173 double lastOffset_ = 0.0; 174 175 private: 176 void HandleScrollEvent(); 177 LayoutParam MakeInnerLayoutParam(size_t itemIndex); 178 179 // Sets child position, the mainAxis does not contain the offset. 180 void SetChildPosition(const RefPtr<RenderNode>& child, size_t itemIndex); 181 void CreateScrollable(); 182 void OnTouchTestHit( 183 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override; 184 bool UpdateScrollPosition(double offset, int32_t source); 185 void CallGap(); 186 void CallItemConstraintSize(); 187 void InitialFlowProp(); 188 void GetFlowSize(); 189 void SupplyItems(size_t startIndex, double targetPos); 190 void LayoutItems(std::set<size_t>& items); 191 void GetFooterSize(double mainSize, double crossSize); 192 void LayoutFooter(); 193 void SetFooterPosition(); 194 void UpdateCacheItems(); 195 std::set<size_t> GetShowItems(); 196 size_t GetLastSupplyedIndex(); 197 size_t GetNextSupplyedIndex(); 198 double GetLastSupplyedMainSize(); 199 Offset GetLastMainBlankPos(); 200 size_t GetLastMainBlankCross(); 201 Offset GetLastMainPos(); 202 void ClearFlowMatrix(size_t index, bool clearAll = false); 203 void ClearItemsByCrossIndex(size_t index, bool clearAll = false); 204 void InitMainSideEndPos(); 205 void UpdateMainSideEndPos(); 206 double GetCrossEndPos(size_t crossIndex); 207 FlowStyle ConstraintItemSize(FlowStyle item, size_t crossIndex); 208 static RefPtr<RenderWaterFlowItem> GetFlowItemByChild(const RefPtr<RenderNode>& child); 209 double GetMainSize(const RefPtr<RenderNode>& item) const; 210 double GetCrossSize(const RefPtr<RenderNode>& item) const; 211 bool CheckReachHead(); 212 bool CheckReachTail(); 213 void AdjustViewPort(); 214 double GetTailPos(); 215 double GetTargetPos(); 216 double GetCacheTargetPos() const; 217 void SetTargetPos(double targetPos); 218 void DealCache(); 219 void DeleteItems(size_t index); 220 bool GetItemMainCrossIndex(int32_t index, int32_t& mainIndex, int32_t& crossIndex); 221 void InitScrollBar(); 222 void InitScrollBarProxy(); 223 void DoJump(double position, int32_t source); 224 void SetScrollBarCallback(); 225 void AnimateToPos(const double& position, int32_t duration, const RefPtr<Curve>& curve); 226 void OutputMatrix(); 227 void RemoveAllChild(); 228 bool NeedPredictLayout(); 229 static std::string PreParseArgs(const std::string& args); 230 231 std::unordered_map<size_t, RefPtr<RenderNode>> items_; 232 std::set<size_t> cacheItems_; 233 234 RefPtr<Scrollable> scrollable_; 235 bool reachHead_ = false; 236 bool reachTail_ = false; 237 int32_t targetIndex_ = -1; // target item index of supply items (for scrollToIndex) 238 double viewportStartPos_ = 0.0; 239 bool lastReachHead_ = false; 240 bool lastReachTail_ = false; 241 double mainSize_ = 0.0; // size ot main side 242 double crossSize_ = 0.0; // size of cross side 243 double crossGap_ = 0.0; // gap of cross side 244 double mainGap_ = 0.0; // gap of main side 245 size_t crossCount_ = 0; // splits count of cross side 246 size_t totalCount_ = 0; // ElementProxyHost::TotalCount() 247 size_t totalCountBack_ = 0; 248 249 // used for scrollbar 250 double scrollBarExtent_ = 0.0; 251 double mainScrollExtent_ = 0.0; 252 double estimateHeight_ = 0.0; 253 254 RefPtr<Animator> animator_; 255 RefPtr<V2::WaterFlowComponent> component_; 256 WeakPtr<WaterFlowItemGenerator> itemGenerator_; 257 BuildChildByIndex buildChildByIndex_; 258 DeleteChildByIndex deleteChildByIndex_; 259 UpdateTotalCount getTotalCount_; 260 261 double cacheSize_ = 0.0; 262 bool updateFlag_ = false; 263 FlexDirection direction_ = FlexDirection::COLUMN; 264 ItemConstraintSize itemConstraintSize_ = { 0.0, 0.0, 0.0, 0.0 }; 265 double mainMaxConstraintSize_ = 0.0; 266 double dVPStartPosBackup_ = -1; 267 std::string colsArgs_; 268 std::string rowsArgs_; 269 270 Dimension userColGap_ = 0.0_px; 271 Dimension userRowGap_ = 0.0_px; 272 DisplayMode displayMode_ = DisplayMode::OFF; 273 // Map structure: [Index - FlowStyle] 274 std::map<size_t, FlowStyle> flowMatrix_; 275 // Map structure: [crossIndex, main side endPos of per splits] 276 std::vector<double> mainSideEndPos_; 277 // Map structure: [crossIndex, cross side size of per splits] 278 std::vector<double> crossSideSize_; 279 // Map structure: [crossIndex, item index] 280 std::vector<std::vector<size_t>> itemsByCrossIndex_; 281 282 std::map<WaterFlowEvents, bool> waterflowEventFlags_; 283 RefPtr<RenderNode> footer_; 284 Size footerMaxSize_; 285 286 ACE_DISALLOW_COPY_AND_MOVE(RenderWaterFlow); 287 }; 288 } // namespace OHOS::Ace::V2 289 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_V2_WATER_FLOW_RENDER_WATER_FLOW_H 290