1 /*
2  * Copyright (c) 2023 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_LAYOUT_RANGE_SOLVER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_LAYOUT_RANGE_SOLVER_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_info.h"
22 
23 namespace OHOS::Ace::NG {
24 /**
25  * @brief The GridLayoutRangeSolver class is responsible for solving the layout range of a grid with irregular items.
26  *
27  * It calculates the starting row information based on currentOffset and lineHeights.
28  */
29 class GridLayoutRangeSolver {
30 public:
31     GridLayoutRangeSolver(GridLayoutInfo* info, LayoutWrapper* wrapper);
32     ~GridLayoutRangeSolver() = default;
33 
34     /**
35      * @brief Structure to store the information of the starting row.
36      */
37     struct StartingRowInfo {
38         int32_t row; /**< Row index of the starting row. */
39         int32_t idx; /**< Index of the starting GridItem in the starting row. */
40         float pos;   /**< Main position of the starting row in ViewBox. The new currentOffset_ */
41     };
42     /**
43      * @brief Finds the starting row based on GridLayoutInfo::currentOffset_.
44      *
45      * @param mainGap The main-axis gap between GridItems.
46      * @return The StartingRowInfo object containing the starting row information.
47      */
48     StartingRowInfo FindStartingRow(float mainGap);
49 
50     struct RangeInfo {
51         int32_t startRow = 0; /**< Row index of the starting row. */
52         int32_t startIdx = 0; /**< Index of the starting GridItem in layout range. */
53         float pos = 0.0f;     /**< Main position of the starting row in ViewBox. The new currentOffset_ */
54         int32_t endRow = 0;   /**< Row index of the last row in layout range. */
55         int32_t endIdx = -1;  /**< index of the last GridItem in layout range. */
56     };
57     /**
58      * @brief Finds the layout range when jumping to a new index.
59      *
60      * @param jumpIdx The item index.
61      * @param jumpLineIdx The index of the jump line.
62      * @param mainGap The main gap between rows.
63      * @return The layout range info after jumping to the target line.
64      */
65     RangeInfo FindRangeOnJump(int32_t jumpIdx, int32_t jumpLineIdx, float mainGap);
66 
67     /**
68      * @brief Solves the forward end index for a given target length and starting line index.
69      *
70      * @param mainGap The main gap between grid items.
71      * @param targetLen The target length for the forward traversal.
72      * @param line The starting line index.
73      * @return { ending line index, ending GridItem index }
74      */
75     std::pair<int32_t, int32_t> SolveForwardForEndIdx(float mainGap, float targetLen, int32_t line);
76 
77 private:
78     /**
79      * @brief Find the starting row after offsetting by [targetLen] going forward (scrolling down).
80      *
81      * @param mainGap The gap length between rows.
82      * @param targetLen The target length to offset.
83      * @param idx The index of the current starting row
84      */
85     StartingRowInfo SolveForward(float mainGap, float targetLen, int32_t idx);
86 
87     /**
88      * @brief Find the new starting row after offsetting by [targetLen] going backward (scrolling up).
89      *
90      * @param mainGap The gap length between rows.
91      * @param targetLen The target length to offset.
92      * @param idx The index of the current starting row
93      */
94     StartingRowInfo SolveBackward(float mainGap, float targetLen, int32_t idx);
95 
96     /**
97      * @brief Looks for multi-row items in the row.
98      *
99      * @param idx The current row index.
100      * @return [first row occupied by items in the current row, the corresponding item index].
101      */
102     std::pair<int32_t, int32_t> CheckMultiRow(int32_t idx);
103 
104     const GridLayoutInfo* info_;
105     const LayoutWrapper* wrapper_;
106     const GridLayoutOptions* opts_;
107 
108     ACE_DISALLOW_COPY_AND_MOVE(GridLayoutRangeSolver);
109 };
110 } // namespace OHOS::Ace::NG
111 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_LAYOUT_RANGE_SOLVER_H
112