1 /* 2 * Copyright (c) 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_NG_PATTERN_WATERFLOW_WATER_FLOW_SW_LAYOUT_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_SW_LAYOUT_H 18 19 #include "core/components/scroll/scroll_controller_base.h" 20 #include "core/components_ng/layout/layout_wrapper.h" 21 #include "core/components_ng/pattern/waterflow/layout/sliding_window/water_flow_layout_info_sw.h" 22 #include "core/components_ng/pattern/waterflow/layout/top_down/water_flow_segmented_layout.h" 23 24 namespace OHOS::Ace::NG { 25 26 class ACE_EXPORT WaterFlowLayoutSW : public WaterFlowSegmentLayoutBase { 27 DECLARE_ACE_TYPE(WaterFlowLayoutSW, WaterFlowSegmentLayoutBase); 28 29 public: WaterFlowLayoutSW(const RefPtr<WaterFlowLayoutInfoSW> & info)30 explicit WaterFlowLayoutSW(const RefPtr<WaterFlowLayoutInfoSW>& info) : info_(info) {} 31 void Measure(LayoutWrapper* wrapper) override; 32 void Layout(LayoutWrapper* wrapper) override; 33 SetCanOverScroll(bool value)34 void SetCanOverScroll(bool value) override 35 { 36 overScroll_ = value; 37 } 38 39 void StartCacheLayout() override; 40 bool PreloadItem(LayoutWrapper* host, int32_t itemIdx, int64_t deadline) override; 41 void EndCacheLayout() override; 42 43 private: 44 void Init(const SizeF& frameSize); 45 /* init WaterFlow without Sections */ 46 void SingleInit(const SizeF& frameSize); 47 void CheckReset(); 48 49 void MeasureOnOffset(float delta); 50 51 void ApplyDelta(float delta); 52 53 void MeasureBeforeAnimation(int32_t targetIdx); 54 55 void MeasureToTarget(int32_t targetIdx); 56 57 /** 58 * @brief When the item is within or close to viewport, layout is preserved and we merely apply an offset. 59 * When jumping to an item further away, the current layout would be reset for better layout performance. 60 * 61 * @param jumpIdx 62 * @param align ScrollAlign 63 * @param mainSize of the viewport 64 */ 65 void MeasureOnJump(int32_t jumpIdx, ScrollAlign align); 66 67 /** 68 * @brief Helper to perform jumping to an item. 69 * 70 * @param noSkip true if we can directly apply offset to reach the target. 71 */ 72 void Jump(int32_t jumpIdx, ScrollAlign align, bool noSkip); 73 74 /** 75 * @brief convert Auto align to other Align types. 76 * 77 * @param inView true if item is between startIndex and endIndex. 78 * @return converted ScrollAlign type. 79 */ 80 ScrollAlign ParseAutoAlign(int32_t jumpIdx, bool inView); 81 82 /** 83 * @brief fills the viewport backward until [viewportBound] is reached / idx < minChildIdx. 84 * 85 * @param viewportBound boundary to fill towards. 86 * @param idx first item index to fill with. 87 * @param minChildIdx smallest item index to fill before stopping. 88 */ 89 void FillFront(float viewportBound, int32_t idx, int32_t minChildIdx); 90 /** 91 * @brief fills backward with one section. 92 * 93 * @return true if fillFront should end. False implies section is completely filled or idx < minChildIdx. 94 */ 95 bool FillFrontSection(float viewportBound, int32_t& idx, int32_t minChildIdx); 96 /** 97 * @brief fills the viewport backward with cached idx -> lane mapping. 98 */ 99 void RecoverFront(float viewportBound, int32_t& idx, int32_t minChildIdx); 100 /** 101 * @brief Append Item in the front of a lane. 102 * @return endPos of next item in the filled lane. 103 */ 104 float FillFrontHelper(float itemLen, int32_t idx, size_t laneIdx); 105 /** 106 * @brief Clear items above the viewport. 107 * Iterate by index to keep item range continuous. 108 */ 109 void ClearFront(); 110 111 /** 112 * @brief fills the viewport forward until [viewportBound] is reached / idx > maxChildIdx. 113 * 114 * @param viewportBound boundary to fill towards. 115 * @param idx first item index to fill with. 116 * @param maxChildIdx greatest item index to fill before stopping. 117 */ 118 void FillBack(float viewportBound, int32_t idx, int32_t maxChildIdx); 119 /** 120 * @brief fills forward with one section. 121 * 122 * @return true if fillBack should end. False implies section is completely filled or idx > maxChildIdx. 123 */ 124 bool FillBackSection(float viewportBound, int32_t& idx, int32_t maxChildIdx); 125 /** 126 * @brief fills the viewport forward with cached idx -> lane mapping. 127 */ 128 void RecoverBack(float viewportBound, int32_t& idx, int32_t maxChildIdx); 129 /** 130 * @brief Append Item to a lane. 131 * @return startPos of next item in the filled lane. 132 */ 133 float FillBackHelper(float itemLen, int32_t idx, size_t laneIdx); 134 /** 135 * @brief Clear items below the viewport. 136 * 137 * @param bound of the viewport 138 */ 139 void ClearBack(float bound); 140 141 void AdjustOverScroll(); 142 143 /** 144 * @brief If need to match children size, adjust self size after measuring children. 145 */ 146 void PostMeasureSelf(float selfCrossLen); 147 148 float MeasureChild(const RefPtr<WaterFlowLayoutProperty>& props, int32_t idx, size_t lane) const; 149 150 /** 151 * @brief Fill cache items back to lanes_ to prepare for Layout phase. 152 * (These items were removed during ClearFront / ClearBack) 153 */ 154 void RecoverCacheItems(int32_t cacheCount); 155 /** 156 * @param itemIdx to recover. 157 * @param front true if recovering an item before startIndex_. 158 * @return true if item is successfully recovered. 159 */ 160 bool RecoverCachedHelper(int32_t itemIdx, bool front); 161 162 /** 163 * @brief Measure all items in view to check if any item's height changed. 164 */ 165 bool ItemHeightChanged() const; 166 167 /** 168 * @brief Data validity check 169 */ 170 bool CheckData() const; 171 172 /** 173 * @brief Layout a single section of items 174 * 175 * @param idx section index. 176 * @param paddingOffset WaterFlow padding, need to add to the child offset. 177 * @param selfCrossLen cross length of WaterFlow. 178 * @param reverse true if reverse layout 179 * @param rtl true if layout right to left 180 */ 181 void LayoutSection(size_t idx, const OffsetF& paddingOffset, float selfCrossLen, bool reverse, bool rtl); 182 void LayoutFooter(const OffsetF& paddingOffset, bool reverse); 183 184 void SyncPreloadItem(LayoutWrapper* host, int32_t itemIdx) override; 185 /** 186 * @brief shared implementation to preload a cache item. 187 * @return true if the item is successfully preloaded. 188 */ 189 bool PreloadItemImpl(int32_t itemIdx); 190 191 // convert FlowItem's index to children node index. 192 inline int32_t nodeIdx(int32_t idx) const; 193 194 RefPtr<WaterFlowLayoutInfoSW> info_; 195 RefPtr<WaterFlowSections> sections_; 196 197 int32_t itemCnt_ = 0; // total number of FlowItems (excluding footer) 198 float mainLen_ = 0.0f; 199 std::optional<int64_t> cacheDeadline_; // cache layout deadline 200 201 bool overScroll_ = true; 202 }; 203 } // namespace OHOS::Ace::NG 204 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_SW_LAYOUT_H 205