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