1 /* 2 * Copyright (c) 2023-2025 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_GRID_GRID_IRREGULAR_LAYOUT_ALGORITHM_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_IRREGULAR_LAYOUT_ALGORITHM_H 18 19 #include "base/utils/noncopyable.h" 20 #include "core/components_ng/layout/layout_wrapper.h" 21 #include "core/components_ng/pattern/grid/grid_layout_base_algorithm.h" 22 #include "core/components_ng/pattern/grid/grid_layout_info.h" 23 24 /** 25 * @brief GridIrregularLayout class supports irregular grid items that take multiple rows and multiple columns. 26 * 27 * INVARIANT: gridMatrix_ is always filled from the first row up to endIndex_ at the beginning of each layout. 28 * INVARIANT: startMainLineIndex_ always corresponds to where Item [startIndex_] is placed. 29 * But endMainLineIndex_ corresponds to the last line in viewport. 30 */ 31 namespace OHOS::Ace::NG { 32 class GridIrregularLayoutAlgorithm : public GridLayoutBaseAlgorithm { 33 DECLARE_ACE_TYPE(GridIrregularLayoutAlgorithm, GridLayoutBaseAlgorithm); 34 35 public: 36 explicit GridIrregularLayoutAlgorithm( 37 GridLayoutInfo info, bool canOverScrollStart = false, bool canOverScrollEnd = false) GridLayoutBaseAlgorithm(std::move (info))38 : GridLayoutBaseAlgorithm(std::move(info)), canOverScrollStart_(canOverScrollStart), 39 canOverScrollEnd_(canOverScrollEnd) {}; 40 41 ~GridIrregularLayoutAlgorithm() override = default; 42 43 void Measure(LayoutWrapper* layoutWrapper) override; 44 45 void Layout(LayoutWrapper* layoutWrapper) override; 46 SetEnableSkip(bool value)47 void SetEnableSkip(bool value) 48 { 49 enableSkip_ = value; 50 } 51 52 private: 53 /** 54 * @brief Measures the size of Grid based on the given GridLayoutProperty. 55 * @param props The GridLayoutProperty object containing the layout properties. 56 * @return The main-axis length of Grid contentRect. 57 */ 58 float MeasureSelf(const RefPtr<GridLayoutProperty>& props); 59 60 /** 61 * @brief Initializes member variables based on the given GridLayoutProperty. 62 * @param props The GridLayoutProperty object containing the layout properties. 63 */ 64 void Init(const RefPtr<GridLayoutProperty>& props); 65 66 void MeasureOnOffset(float mainSize); 67 void MeasureForward(float mainSize); 68 void MeasureBackward(float mainSize, bool toAdjust = false); 69 70 /** 71 * @brief Check if offset is larger than the entire viewport. If so, skip measuring intermediate items and jump 72 * directly to the estimated destination. 73 * 74 * @param mainSize main-axis length of the viewport. 75 * @return true if a skip is performed. 76 */ 77 bool TrySkipping(float mainSize); 78 79 /** 80 * @brief Measure all items until targetIndex_ is reached. For performing scrollTo with animation. 81 * 82 */ 83 void MeasureToTarget(); 84 85 /** 86 * @brief Check if layout states (matrix, height map) need to be reset during Init. 87 */ 88 void CheckForReset(); 89 90 /** 91 * @brief Performs the layout of the children based on the main offset. 92 * @param mainOffset The main offset of the layout. 93 * @param cacheLine number of lines of cache items to layout 94 * @return number of cached items laid out in front and back 95 */ 96 std::pair<int32_t, int32_t> LayoutChildren(float mainOffset, int32_t cacheLine); 97 98 /** 99 * @brief Update variables in GridLayoutInfo at the end of Layout. 100 */ 101 void UpdateLayoutInfo(); 102 103 /** 104 * @brief Calculates the cross positions based on the padding. 105 * @param padding The padding property of the layout. 106 * @return A vector containing the cross positions. 107 */ 108 std::vector<float> CalculateCrossPositions(const PaddingPropertyF& padding); 109 110 // ========================================== MeasureOnJump functions ===================================== 111 112 void MeasureOnJump(float mainSize); 113 void Jump(float mainSize); 114 115 /** 116 * @brief Find the line the jumpIdx item resides in. If not in matrix, fill the matrix up to [jumpIdx]. 117 * 118 * @param jumpIdx The GridItem index to jump to. 119 * @return The line index of the item in GridMatrix. 120 */ 121 int32_t FindJumpLineIdx(int32_t jumpIdx); 122 123 /** 124 * @brief Prepares GridLayoutInfo::lineHeightMap_ using GridIrregularFiller. 125 * 126 * If the algorithm identifies that mainSize can't be filled with the current scrollAlign_ and jumpLineIdx, these 127 * params will be adjusted. For instance, jumping to the last line with ScrollAlign::START isn't possible. 128 * 129 * @param mainSize The main-axis length of the grid. 130 * @param jumpLineIdx The line index to jump to, can be adjusted during the function call. 131 */ 132 void PrepareLineHeight(float mainSize, int32_t& jumpLineIdx); 133 // ========================================== MeasureOnJump ends =========================================== 134 135 /** 136 * @brief Skip forward by currentOffset_ and fill the matrix along the way. 137 * 138 * @return item index to jump to after skipping. 139 */ 140 int32_t SkipLinesForward(); 141 142 /** 143 * @brief Skip backward by currentOffset_. Can assume that the matrix is already filled up to startIdx_ 144 * 145 * @return item index to jump to after skipping. 146 */ 147 int32_t SkipLinesBackward() const; 148 149 bool IsIrregularLine(int32_t lineIndex) const override; 150 151 /** 152 * @brief post delayed task to preload GridItems in cache range. 153 */ 154 void PreloadItems(int32_t cacheCnt); 155 /** 156 * @brief immediately create & measure GridItems in cache range. 157 */ 158 void SyncPreloadItems(int32_t cacheCnt); 159 160 void AdaptToChildMainSize(RefPtr<GridLayoutProperty>& gridLayoutProperty, float mainSize, SizeF idealSize); 161 162 LayoutWrapper* wrapper_ = nullptr; 163 164 std::vector<float> crossLens_; /**< The column widths of the GridItems. */ 165 float crossGap_ = 0.0f; /**< The cross-axis gap between GridItems. */ 166 float mainGap_ = 0.0f; /**< The main-axis gap between GridItems. */ 167 168 float postJumpOffset_ = 0.0f; /**< The offset to be applied after performing a jump. */ 169 float overscrollOffsetBeforeJump_ = 0.0f; 170 171 bool enableSkip_ = true; 172 bool canOverScrollStart_ = false; 173 bool canOverScrollEnd_ = false; 174 175 SizeF frameSize_; 176 177 ACE_DISALLOW_COPY_AND_MOVE(GridIrregularLayoutAlgorithm); 178 }; 179 180 } // namespace OHOS::Ace::NG 181 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_IRREGULAR_LAYOUT_ALGORITHM_H 182