• 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 class ListPositionMap;
28 class ListChildrenMainSize;
29 struct ListItemGroupLayoutInfo;
30 struct LayoutedItemInfo {
31     int32_t startIndex = 0;
32     float startPos = 0.0f;
33     int32_t endIndex = 0;
34     float endPos = 0.0f;
35 };
36 
37 struct ListItemGroupInfo {
38     int32_t id = -1;
39     float startPos = 0.0f;
40     float endPos = 0.0f;
41     bool isPressed = false;
42 };
43 
44 struct ListItemGroupCacheParam {
45     bool forward = true;
46     int32_t cacheCount = 0;
47     int32_t forwardCachedIndex = -1;
48     int32_t backwardCachedIndex = INT_MAX;
49     int64_t deadline = 0;
50 };
51 
52 // TextLayoutAlgorithm acts as the underlying text layout.
53 class ACE_EXPORT ListItemGroupLayoutAlgorithm : public LayoutAlgorithm {
54     DECLARE_ACE_TYPE(ListItemGroupLayoutAlgorithm, LayoutAlgorithm);
55 public:
56     using PositionMap = std::map<int32_t, ListItemGroupInfo>;
57 
58     static const int32_t LAST_ITEM = -1;
59 
ListItemGroupLayoutAlgorithm(int32_t headerIndex,int32_t footerIndex,int32_t itemStartIndex)60     ListItemGroupLayoutAlgorithm(int32_t headerIndex, int32_t footerIndex, int32_t itemStartIndex)
61         :headerIndex_(headerIndex), footerIndex_(footerIndex), itemStartIndex_(itemStartIndex) {}
62 
63     void Measure(LayoutWrapper* layoutWrapper) override;
64 
65     void Layout(LayoutWrapper* layoutWrapper) override;
66 
GetItemPosition()67     const PositionMap& GetItemPosition() const
68     {
69         return itemPosition_;
70     }
71 
SetItemsPosition(const PositionMap & itemPosition)72     void SetItemsPosition(const PositionMap& itemPosition)
73     {
74         itemPosition_ = itemPosition;
75     }
76 
77     void ClearItemPosition();
78 
GetSpaceWidth()79     float GetSpaceWidth() const
80     {
81         return spaceWidth_;
82     }
83 
GetAxis()84     Axis GetAxis() const
85     {
86         return axis_;
87     }
88 
GetLayoutDirection()89     TextDirection GetLayoutDirection() const
90     {
91         return layoutDirection_;
92     }
93 
GetMainSize()94     float GetMainSize() const
95     {
96         return totalMainSize_;
97     }
98 
GetLanes()99     int32_t GetLanes() const
100     {
101         return lanes_;
102     }
103 
GetLaneGutter()104     float GetLaneGutter() const
105     {
106         return laneGutter_;
107     }
108 
GetLanesFloor(int32_t index)109     int32_t GetLanesFloor(int32_t index) const
110     {
111         if (lanes_ <= 1) {
112             return index;
113         }
114         return index - index % lanes_;
115     }
116 
GetLanesCeil(int32_t index)117     int32_t GetLanesCeil(int32_t index) const
118     {
119         int32_t tmpIndex = (lanes_ <= 1) ? index : (index - index % lanes_ + lanes_ - 1);
120         tmpIndex = tmpIndex >= totalItemCount_ ? totalItemCount_ - 1 : tmpIndex;
121         return tmpIndex;
122     }
123 
SetListMainSize(float startPos,float endPos,float referencePos,float prevContentSize,bool forwardLayout)124     void SetListMainSize(float startPos, float endPos, float referencePos, float prevContentSize, bool forwardLayout)
125     {
126         startPos_ = startPos;
127         endPos_ = endPos;
128         referencePos_ = referencePos;
129         forwardLayout_ = forwardLayout;
130         refPos_ = referencePos;
131         prevContentMainSize_ = prevContentSize;
132     }
133 
134     void ModifyReferencePos(int32_t index, float pos);
135 
SetNeedAdjustRefPos(bool needAdjust)136     void SetNeedAdjustRefPos(bool needAdjust)
137     {
138         needAdjustRefPos_ = needAdjust;
139     }
140 
SetNeedCheckOffset(bool needCheckOffset)141     void SetNeedCheckOffset(bool needCheckOffset)
142     {
143         isNeedCheckOffset_ = needCheckOffset;
144     }
145 
GetRefPos()146     float GetRefPos() const
147     {
148         return refPos_;
149     }
150 
SetContentOffset(float contentStartOffset,float contentEndOffset)151     void SetContentOffset(float contentStartOffset, float contentEndOffset)
152     {
153         contentStartOffset_ = contentStartOffset;
154         contentEndOffset_ = contentEndOffset;
155     }
156 
SetListLayoutProperty(RefPtr<ListLayoutProperty> layoutProperty)157     void SetListLayoutProperty(RefPtr<ListLayoutProperty> layoutProperty)
158     {
159         listLayoutProperty_ = std::move(layoutProperty);
160     }
161 
SetJumpIndex(int32_t index)162     void SetJumpIndex(int32_t index)
163     {
164         jumpIndex_ = index;
165     }
166 
SetTargetIndex(int32_t index)167     void SetTargetIndex(int32_t index)
168     {
169         targetIndex_ = index;
170     }
171 
GetStartIndex()172     int32_t GetStartIndex() const
173     {
174         return itemPosition_.empty() ? 0 : itemPosition_.begin()->first;
175     }
176 
GetEndIndex()177     int32_t GetEndIndex() const
178     {
179         return itemPosition_.empty() ? 0 : itemPosition_.rbegin()->first;
180     }
181 
GetStartPosition()182     float GetStartPosition() const
183     {
184         if (itemPosition_.empty()) {
185             return 0.0f;
186         }
187         if (GetStartIndex() == 0) {
188             return itemPosition_.begin()->second.startPos;
189         }
190         return itemPosition_.begin()->second.startPos - spaceWidth_;
191     }
192 
GetEndPosition()193     float GetEndPosition() const
194     {
195         if (itemPosition_.empty()) {
196             return 0.0f;
197         }
198         if (GetEndIndex() == totalItemCount_ - 1) {
199             return itemPosition_.rbegin()->second.endPos;
200         }
201         return itemPosition_.rbegin()->second.endPos + spaceWidth_;
202     }
203 
GetTotalItemCount()204     int32_t GetTotalItemCount() const
205     {
206         return totalItemCount_;
207     }
208 
209     float GetChildMaxCrossSize(LayoutWrapper* layoutWrapper, Axis axis);
210 
211     void CheckRecycle(const RefPtr<LayoutWrapper>& layoutWrapper, float startPos, float endPos, float referencePos,
212         bool forwardLayout);
213 
SetNeedAllLayout()214     void SetNeedAllLayout()
215     {
216         needAllLayout_ = true;
217     }
218 
219     void CheckNeedAllLayout(const RefPtr<LayoutWrapper>& layoutWrapper, bool forwardLayout);
220 
SetScrollAlign(ScrollAlign align)221     void SetScrollAlign(ScrollAlign align)
222     {
223         scrollAlign_ = align;
224     }
225 
226     std::pair<float, float> GetItemGroupPosition(int32_t index);
227 
GetHeaderMainSize()228     float GetHeaderMainSize() const
229     {
230         return headerMainSize_;
231     }
232 
GetFooterMainSize()233     float GetFooterMainSize() const
234     {
235         return footerMainSize_;
236     }
237 
238     float GetItemHeight(int32_t index);
239 
GetItemStartIndex()240     int32_t GetItemStartIndex()
241     {
242         return itemStartIndex_;
243     }
244 
SetLayoutedItemInfo(const std::optional<LayoutedItemInfo> & itemInfo)245     void SetLayoutedItemInfo(const std::optional<LayoutedItemInfo>& itemInfo)
246     {
247         layoutedItemInfo_ = itemInfo;
248     }
249 
GetLayoutedItemInfo()250     std::optional<LayoutedItemInfo> GetLayoutedItemInfo() const
251     {
252         return layoutedItemInfo_;
253     }
254 
SetListChildrenMainSize(const RefPtr<ListChildrenMainSize> & childrenMainSize)255     void SetListChildrenMainSize(const RefPtr<ListChildrenMainSize>& childrenMainSize)
256     {
257         childrenSize_ = childrenMainSize;
258     }
259 
SetListPositionMap(const RefPtr<ListPositionMap> & posMap)260     void SetListPositionMap(const RefPtr<ListPositionMap>& posMap)
261     {
262         posMap_ = posMap;
263     }
264 
265     void AdjustByPosMap();
266 
267     static void SyncGeometry(RefPtr<LayoutWrapper>& wrapper);
268 
GetStartHeaderPos()269     float GetStartHeaderPos() const
270     {
271         return startHeaderPos_;
272     }
273 
GetEndFooterPos()274     float GetEndFooterPos() const
275     {
276         return endFooterPos_;
277     }
278 
SetCacheParam(std::optional<ListItemGroupCacheParam> param)279     void SetCacheParam(std::optional<ListItemGroupCacheParam> param)
280     {
281         cacheParam_ = param;
282     }
283 
GetCacheParam()284     std::optional<ListItemGroupCacheParam> GetCacheParam() const
285     {
286         return cacheParam_;
287     }
288 
SetNeedMeasureFormLastItem(bool needMeasureFormLastItem)289     void SetNeedMeasureFormLastItem(bool needMeasureFormLastItem)
290     {
291         isNeedMeasureFormLastItem_ = needMeasureFormLastItem;
292     }
293 
294     ListItemGroupLayoutInfo GetLayoutInfo() const;
295 
GetAdjustReferenceDelta()296     float GetAdjustReferenceDelta() const
297     {
298         return adjustReferenceDelta_;
299     }
300 
GetListItemCount()301     int32_t GetListItemCount() const
302     {
303         return static_cast<int32_t>(itemPosition_.size());
304     }
305 
306 private:
307     float CalculateLaneCrossOffset(float crossSize, float childCrossSize);
308     void UpdateListItemConstraint(const OptionalSizeF& selfIdealSize, LayoutConstraintF& contentConstraint);
309     void LayoutListItem(LayoutWrapper* layoutWrapper, const OffsetF& paddingOffset, float crossSize);
310     void LayoutListItemAll(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, float startPos);
311     void LayoutHeaderFooterRTL(LayoutWrapper* layoutWrapper, const OffsetF& paddingOffset, float crossSize);
312     void LayoutHeaderFooterLTR(LayoutWrapper* layoutWrapper, const OffsetF& paddingOffset, float crossSize);
313     void UpdateZIndex(const RefPtr<LayoutWrapper>& layoutWrapper);
314     void LayoutIndex(const RefPtr<LayoutWrapper>& wrapper, const OffsetF& paddingOffset,
315         float crossSize, float startPos);
GetListItem(LayoutWrapper * layoutWrapper,int32_t index)316     inline RefPtr<LayoutWrapper> GetListItem(LayoutWrapper* layoutWrapper, int32_t index) const
317     {
318         return layoutWrapper->GetOrCreateChildByIndex(index + itemStartIndex_);
319     }
320     void CalculateLanes(const RefPtr<ListLayoutProperty>& layoutProperty,
321         const LayoutConstraintF& layoutConstraint, std::optional<float> crossSizeOptional, Axis axis);
322 
323     void MeasureListItem(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint);
324     int32_t MeasureALineForward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
325         int32_t& currentIndex, float startPos, float& endPos);
326     int32_t MeasureALineBackward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
327         int32_t& currentIndex, float endPos, float& startPos);
328     int32_t MeasureALineCenter(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
329         int32_t currentIndex);
330     int32_t MeasureALineAuto(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
331         int32_t currentIndex);
332     void CheckJumpForwardForBigOffset(int32_t& startIndex, float& startPos);
333     void CheckJumpBackwardForBigOffset(int32_t& endIndex, float& endPos);
334     void MeasureForward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
335         int32_t startIndex, float startPos);
336     void MeasureBackward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint,
337         int32_t endIndex, float endPos);
338     void MeasureJumpToItemForward(LayoutWrapper* layoutWrapper,
339         const LayoutConstraintF& layoutConstraint, int32_t startIndex, float startPos);
340     void MeasureJumpToItemBackward(LayoutWrapper* layoutWrapper,
341         const LayoutConstraintF& layoutConstraint, int32_t endIndex, float endPos);
342     void MeasureCenter(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex);
343     void MeasureStart(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex);
344     void MeasureEnd(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex);
345     void MeasureAuto(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex);
346     void MeasureHeaderFooter(LayoutWrapper* layoutWrapper);
347     void SetActiveChildRange(LayoutWrapper* layoutWrapper, int32_t cacheCount);
348     float UpdateReferencePos(RefPtr<LayoutProperty> layoutProperty, bool forwardLayout, float referencePos);
349     bool NeedMeasureItem(LayoutWrapper* layoutWrapper);
350     static void SetListItemIndex(const LayoutWrapper* groupLayoutWrapper,
351         const RefPtr<LayoutWrapper>& itemLayoutWrapper, int32_t indexInGroup);
352     bool IsCardStyleForListItemGroup(const LayoutWrapper* groupLayoutWrapper);
353     float GetListItemGroupMaxWidth(const OptionalSizeF& parentIdealSize, RefPtr<LayoutProperty> layoutProperty);
354     void AdjustItemPosition();
355     bool CheckNeedMeasure(const RefPtr<LayoutWrapper>& layoutWrapper) const;
356     void MeasureCacheItem(LayoutWrapper* layoutWrapper);
357     void LayoutCacheItem(LayoutWrapper* layoutWrapper);
358 
359     bool isCardStyle_ = false;
360     int32_t headerIndex_;
361     int32_t footerIndex_;
362     int32_t itemStartIndex_;
363     RefPtr<ListLayoutProperty> listLayoutProperty_;
364     float paddingBeforeContent_ = 0.0f;
365     float paddingAfterContent_ = 0.0f;
366 
367     PositionMap itemPosition_;
368     RefPtr<ListChildrenMainSize> childrenSize_;
369     RefPtr<ListPositionMap> posMap_;
370     Axis axis_ = Axis::VERTICAL;
371     int32_t lanes_ = 1;
372     float laneGutter_ = 0.0f;
373     std::optional<float> minLaneLength_;
374     std::optional<float> maxLaneLength_;
375     V2::ListItemAlign itemAlign_ = V2::ListItemAlign::START;
376     float spaceWidth_ = 0.0f;
377 
378     std::optional<int32_t> jumpIndex_;
379     std::optional<int32_t> targetIndex_;
380     ScrollAlign scrollAlign_ = ScrollAlign::NONE;
381     int32_t totalItemCount_ = 0;
382     float totalMainSize_ = 0.0f;
383     float headerMainSize_ = 0.0f;
384     float footerMainSize_ = 0.0f;
385     float startPos_ = 0.0f;
386     float startHeaderPos_ = 0.0f;
387     float endFooterPos_ = 0.0f;
388     float prevStartPos_ = 0.0f;
389     float prevEndPos_ = 0.0f;
390     float endPos_ = 0.0f;
391     float referencePos_ = 0.0f;
392     float adjustReferenceDelta_ = 0.0f;
393     float refPos_ = 0.0f;
394     float prevContentMainSize_ = 0.0f;
395     float contentStartOffset_ = 0.0f;
396     float contentEndOffset_ = 0.0f;
397     bool forwardLayout_ = true;
398     bool needAllLayout_ = false;
399     bool needAdjustRefPos_ = false;
400     bool isNeedCheckOffset_ = false;
401     bool isNeedMeasureFormLastItem_ = false;
402 
403     std::optional<LayoutedItemInfo> layoutedItemInfo_;
404     LayoutConstraintF childLayoutConstraint_;
405     TextDirection layoutDirection_ = TextDirection::LTR;
406 
407     std::optional<ListItemGroupCacheParam> cacheParam_;
408     std::list<int32_t> cachedItem_;
409 };
410 } // namespace OHOS::Ace::NG
411 
412 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H
413