• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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_LIST_LIST_ITEM_GROUP_LAYOUT_ALGORITHM_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_ITEM_GROUP_LAYOUT_ALGORITHM_H
18 
19 #include <optional>
20 #include "base/geometry/axis.h"
21 #include "core/components_ng/layout/layout_algorithm.h"
22 #include "core/components_ng/layout/layout_wrapper.h"
23 #include "core/components_ng/pattern/list/list_layout_property.h"
24 #include "core/components_v2/list/list_properties.h"
25 
26 namespace OHOS::Ace::NG {
27 struct LayoutedItemInfo {
28     int32_t startIndex = 0;
29     float startPos = 0.0f;
30     int32_t endIndex = 0;
31     float endPos = 0.0f;
32 };
33 
34 // TextLayoutAlgorithm acts as the underlying text layout.
35 class ACE_EXPORT ListItemGroupLayoutAlgorithm : public LayoutAlgorithm {
36     DECLARE_ACE_TYPE(ListItemGroupLayoutAlgorithm, LayoutAlgorithm);
37 public:
38     using PositionMap = std::map<int32_t, std::pair<float, float>>;
39 
40     static const int32_t LAST_ITEM = -1;
41 
ListItemGroupLayoutAlgorithm(int32_t headerIndex,int32_t footerIndex,int32_t itemStartIndex)42     ListItemGroupLayoutAlgorithm(int32_t headerIndex, int32_t footerIndex, int32_t itemStartIndex)
43         :headerIndex_(headerIndex), footerIndex_(footerIndex), itemStartIndex_(itemStartIndex) {}
44 
45     void Measure(LayoutWrapper* layoutWrapper) override;
46 
47     void Layout(LayoutWrapper* layoutWrapper) override;
48 
GetItemPosition()49     const PositionMap& GetItemPosition() const
50     {
51         return itemPosition_;
52     }
53 
SetItemsPosition(const PositionMap & itemPosition)54     void SetItemsPosition(const PositionMap& itemPosition)
55     {
56         itemPosition_ = itemPosition;
57     }
58 
59     void ClearItemPosition(LayoutWrapper* layoutWrapper);
60 
GetSpaceWidth()61     float GetSpaceWidth() const
62     {
63         return spaceWidth_;
64     }
65 
GetAxis()66     Axis GetAxis() const
67     {
68         return axis_;
69     }
70 
GetLanes()71     int32_t GetLanes() const
72     {
73         return lanes_;
74     }
75 
GetLaneGutter()76     float GetLaneGutter() const
77     {
78         return laneGutter_;
79     }
80 
GetLanesFloor(int32_t index)81     int32_t GetLanesFloor(int32_t index) const
82     {
83         if (lanes_ <= 1) {
84             return index;
85         }
86         return index - index % lanes_;
87     }
88 
GetLanesCeil(int32_t index)89     int32_t GetLanesCeil(int32_t index) const
90     {
91         int32_t tmpIndex = (lanes_ <= 1) ? index : (index - index % lanes_ + lanes_ - 1);
92         tmpIndex = tmpIndex >= totalItemCount_ ? totalItemCount_ - 1 : tmpIndex;
93         return tmpIndex;
94     }
95 
SetListMainSize(float startPos,float endPos,float referencePos,bool forwardLayout)96     void SetListMainSize(float startPos, float endPos, float referencePos, bool forwardLayout)
97     {
98         startPos_ = startPos;
99         endPos_ = endPos;
100         referencePos_ = referencePos;
101         forwardLayout_ = forwardLayout;
102     }
103 
SetContentOffset(float contentStartOffset,float contentEndOffset)104     void SetContentOffset(float contentStartOffset, float contentEndOffset)
105     {
106         contentStartOffset_ = contentStartOffset;
107         contentEndOffset_ = contentEndOffset;
108     }
109 
SetListLayoutProperty(RefPtr<ListLayoutProperty> layoutProperty)110     void SetListLayoutProperty(RefPtr<ListLayoutProperty> layoutProperty)
111     {
112         listLayoutProperty_ = std::move(layoutProperty);
113     }
114 
SetJumpIndex(int32_t index)115     void SetJumpIndex(int32_t index)
116     {
117         jumpIndex_ = index;
118     }
119 
SetTargetIndex(int32_t index)120     void SetTargetIndex(int32_t index)
121     {
122         targetIndex_ = index;
123     }
124 
GetStartIndex()125     int32_t GetStartIndex() const
126     {
127         return itemPosition_.empty() ? 0 : itemPosition_.begin()->first;
128     }
129 
GetEndIndex()130     int32_t GetEndIndex() const
131     {
132         return itemPosition_.empty() ? 0 : itemPosition_.rbegin()->first;
133     }
134 
GetStartPosition()135     float GetStartPosition() const
136     {
137         if (itemPosition_.empty()) {
138             return 0.0f;
139         }
140         if (GetStartIndex() == 0) {
141             return itemPosition_.begin()->second.first;
142         }
143         return itemPosition_.begin()->second.first - spaceWidth_;
144     }
145 
GetEndPosition()146     float GetEndPosition() const
147     {
148         if (itemPosition_.empty()) {
149             return 0.0f;
150         }
151         if (GetEndIndex() == totalItemCount_ - 1) {
152             return itemPosition_.rbegin()->second.second;
153         }
154         return itemPosition_.rbegin()->second.second + spaceWidth_;
155     }
156 
GetTotalItemCount()157     int32_t GetTotalItemCount() const
158     {
159         return totalItemCount_;
160     }
161 
162     float GetChildMaxCrossSize(LayoutWrapper* layoutWrapper, Axis axis);
163 
164     void CheckRecycle(const RefPtr<LayoutWrapper>& layoutWrapper, float startPos, float endPos, float referencePos,
165         bool forwardLayout);
166 
SetNeedAllLayout()167     void SetNeedAllLayout()
168     {
169         needAllLayout_ = true;
170     }
171 
SetScrollAlign(ScrollAlign align)172     void SetScrollAlign(ScrollAlign align)
173     {
174         scrollAlign_ = align;
175     }
176 
177     std::pair<float, float> GetItemGroupPosition(int32_t index);
178 
GetHeaderMainSize()179     float GetHeaderMainSize() const
180     {
181         return headerMainSize_;
182     }
183 
GetFooterMainSize()184     float GetFooterMainSize() const
185     {
186         return footerMainSize_;
187     }
188 
189     float GetItemHeight(int32_t index);
190 
GetItemStartIndex()191     int32_t GetItemStartIndex()
192     {
193         return itemStartIndex_;
194     }
195 
SetLayoutedItemInfo(const std::optional<LayoutedItemInfo> & itemInfo)196     void SetLayoutedItemInfo(const std::optional<LayoutedItemInfo>& itemInfo)
197     {
198         layoutedItemInfo_ = itemInfo;
199     }
200 
GetLayoutedItemInfo()201     std::optional<LayoutedItemInfo> GetLayoutedItemInfo() const
202     {
203         return layoutedItemInfo_;
204     }
205 
206 private:
207     float CalculateLaneCrossOffset(float crossSize, float childCrossSize);
208     void UpdateListItemConstraint(const OptionalSizeF& selfIdealSize, LayoutConstraintF& contentConstraint);
209     void LayoutListItem(LayoutWrapper* layoutWrapper, const OffsetF& paddingOffset, float crossSize);
210     void LayoutListItemAll(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, float startPos);
211     void LayoutHeaderFooter(LayoutWrapper* layoutWrapper, const OffsetF& paddingOffset, float crossSize);
212     void LayoutIndex(const RefPtr<LayoutWrapper>& wrapper, const OffsetF& paddingOffset,
213         float crossSize, float startPos);
GetListItem(LayoutWrapper * layoutWrapper,int32_t index)214     inline RefPtr<LayoutWrapper> GetListItem(LayoutWrapper* layoutWrapper, int32_t index) const
215     {
216         return layoutWrapper->GetOrCreateChildByIndex(index + itemStartIndex_);
217     }
RecycleListItem(const RefPtr<LayoutWrapper> & layoutWrapper,int32_t index)218     inline void RecycleListItem(const RefPtr<LayoutWrapper>& layoutWrapper, int32_t index) const
219     {
220         layoutWrapper->RemoveChildInRenderTree(index + itemStartIndex_);
221     }
222     void CalculateLanes(const RefPtr<ListLayoutProperty>& layoutProperty,
223         const LayoutConstraintF& layoutConstraint, std::optional<float> crossSizeOptional, Axis axis);
224 
225     void MeasureListItem(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint);
226     int32_t MeasureALineForward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
227         int32_t& currentIndex, float startPos, float& endPos);
228     int32_t MeasureALineBackward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
229         int32_t& currentIndex, float endPos, float& startPos);
230     int32_t MeasureALineCenter(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
231         int32_t currentIndex);
232     int32_t MeasureALineAuto(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
233         int32_t currentIndex);
234     void MeasureForward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
235         int32_t startIndex, float startPos);
236     void MeasureBackward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
237         int32_t endIndex, float endPos);
238     void MeasureJumpToItemForward(LayoutWrapper* layoutWrapper,
239         const LayoutConstraintF& layoutConstraint, int32_t startIndex, float startPos);
240     void MeasureJumpToItemBackward(LayoutWrapper* layoutWrapper,
241         const LayoutConstraintF& layoutConstraint, int32_t endIndex, float endPos);
242     void MeasureCenter(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex);
243     void MeasureStart(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex);
244     void MeasureEnd(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex);
245     void MeasureAuto(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex);
246     float UpdateReferencePos(RefPtr<LayoutProperty> layoutProperty, bool forwardLayout, float referencePos);
247     bool NeedMeasureItem() const;
248     static void SetListItemIndex(const LayoutWrapper* groupLayoutWrapper,
249         const RefPtr<LayoutWrapper>& itemLayoutWrapper, int32_t indexInGroup);
250     bool IsCardStyleForListItemGroup(const LayoutWrapper* groupLayoutWrapper);
251     float GetListItemGroupMaxWidth(const OptionalSizeF& parentIdealSize, RefPtr<LayoutProperty> layoutProperty);
252     void AdjustItemPosition();
253 
254     bool isCardStyle_ = false;
255     int32_t headerIndex_;
256     int32_t footerIndex_;
257     int32_t itemStartIndex_;
258     RefPtr<ListLayoutProperty> listLayoutProperty_;
259     float paddingBeforeContent_ = 0.0f;
260     float paddingAfterContent_ = 0.0f;
261 
262     PositionMap itemPosition_;
263     Axis axis_ = Axis::VERTICAL;
264     int32_t lanes_ = 1;
265     float laneGutter_ = 0.0f;
266     std::optional<float> minLaneLength_;
267     std::optional<float> maxLaneLength_;
268     V2::ListItemAlign itemAlign_ = V2::ListItemAlign::START;
269     float spaceWidth_ = 0.0f;
270 
271     std::optional<int32_t> jumpIndex_;
272     std::optional<int32_t> targetIndex_;
273     ScrollAlign scrollAlign_ = ScrollAlign::NONE;
274     int32_t totalItemCount_ = 0;
275     float totalMainSize_ = 0.0f;
276     float headerMainSize_ = 0.0f;
277     float footerMainSize_ = 0.0f;
278     float startPos_ = 0.0f;
279     float prevStartPos_ = 0.0f;
280     float prevEndPos_ = 0.0f;
281     float endPos_ = 0.0f;
282     float referencePos_ = 0.0f;
283     float contentStartOffset_ = 0.0f;
284     float contentEndOffset_ = 0.0f;
285     bool forwardLayout_ = true;
286     bool needAllLayout_ = false;
287 
288     std::optional<LayoutedItemInfo> layoutedItemInfo_;
289 };
290 } // namespace OHOS::Ace::NG
291 
292 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H
293