• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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