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