• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_SWIPER_SWIPER_LAYOUT_ALGORITHM_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SWIPER_SWIPER_LAYOUT_ALGORITHM_H
18 
19 #include <cstdint>
20 #include <optional>
21 
22 #include "base/geometry/axis.h"
23 #include "base/geometry/ng/offset_t.h"
24 #include "base/memory/referenced.h"
25 #include "core/components_ng/layout/layout_algorithm.h"
26 #include "core/components_ng/layout/layout_wrapper.h"
27 #include "core/components_ng/pattern/swiper/swiper_layout_property.h"
28 
29 namespace OHOS::Ace::NG {
30 
31 struct SwiperItemInfo {
32     float startPos = 0.0f;
33     float endPos = 0.0f;
34     RefPtr<FrameNode> node;
35     OffsetF finalOffset;
36     CancelableCallback<void()> task;
37     bool isFinishAnimation = false;
38 };
39 
40 class ACE_EXPORT SwiperLayoutAlgorithm : public LayoutAlgorithm {
41     DECLARE_ACE_TYPE(SwiperLayoutAlgorithm, LayoutAlgorithm);
42 
43 public:
44     using PositionMap = std::map<int32_t, SwiperItemInfo>;
45 
46     SwiperLayoutAlgorithm() = default;
~SwiperLayoutAlgorithm()47     ~SwiperLayoutAlgorithm() override
48     {
49         std::lock_guard<std::mutex> lock(swiperMutex_);
50     }
51 
OnReset()52     void OnReset() override {}
53     void Measure(LayoutWrapper* layoutWrapper) override;
54     void Layout(LayoutWrapper* layoutWrapper) override;
55 
56     void LayoutForward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, Axis axis,
57         int32_t startIndex, float startPos, bool cachedLayout = false);
58     void LayoutBackward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, Axis axis,
59         int32_t endIndex, float endPos, bool cachedLayout = false);
60     bool LayoutForwardItem(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, Axis axis,
61         int32_t& currentIndex, float startPos, float& endPos);
62     bool LayoutBackwardItem(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, Axis axis,
63         int32_t& currentIndex, float endPos, float& startPos);
64     float GetChildMaxSize(LayoutWrapper* layoutWrapper, Axis axis, bool isMainAxis) const;
65     int32_t GetLoopIndex(int32_t originalIndex) const;
66 
SetItemsPosition(const PositionMap & itemPosition)67     void SetItemsPosition(const PositionMap& itemPosition)
68     {
69         itemPosition_ = itemPosition;
70     }
71 
GetItemPosition()72     PositionMap&& GetItemPosition()
73     {
74         return std::move(itemPosition_);
75     }
76 
SetJumpIndex(int32_t index)77     void SetJumpIndex(int32_t index)
78     {
79         jumpIndex_ = index;
80     }
81 
SetCurrentDelta(float offset)82     void SetCurrentDelta(float offset)
83     {
84         currentDelta_ = offset;
85         currentOffset_ = offset;
86     }
87 
SetOverScrollFeature()88     void SetOverScrollFeature()
89     {
90         overScrollFeature_ = true;
91     }
92 
SetCanOverScroll(bool canOverScroll)93     void SetCanOverScroll(bool canOverScroll)
94     {
95         canOverScroll_ = canOverScroll;
96     }
97 
SetTotalItemCount(int32_t totalItemCount)98     void SetTotalItemCount(int32_t totalItemCount)
99     {
100         totalItemCount_ = totalItemCount;
101     }
102 
GetContentMainSize()103     float GetContentMainSize() const
104     {
105         return contentMainSize_;
106     }
107 
SetContentMainSize(float contentMainSize)108     void SetContentMainSize(float contentMainSize)
109     {
110         contentMainSize_ = contentMainSize;
111         oldContentMainSize_ = contentMainSize;
112     }
113 
GetContentCrossSize()114     float GetContentCrossSize() const
115     {
116         return contentCrossSize_;
117     }
118 
SetContentCrossSize(float contentCrossSize)119     void SetContentCrossSize(float contentCrossSize)
120     {
121         contentCrossSize_ = contentCrossSize;
122     }
123 
SetCurrentOffset(float offset)124     void SetCurrentOffset(float offset)
125     {
126         currentOffset_ = offset;
127     }
128 
GetCurrentOffset()129     float GetCurrentOffset() const
130     {
131         return currentOffset_;
132     }
133 
SetTargetIndex(std::optional<int32_t> targetIndex)134     void SetTargetIndex(std::optional<int32_t> targetIndex)
135     {
136         targetIndex_ = targetIndex;
137     }
138 
SetIsLoop(bool isLoop)139     void SetIsLoop(bool isLoop)
140     {
141         isLoop_ = isLoop;
142     }
143 
GetStartIndex()144     int32_t GetStartIndex() const
145     {
146         return itemPosition_.empty() ? 0 : itemPosition_.begin()->first;
147     }
148 
GetEndIndex()149     int32_t GetEndIndex() const
150     {
151         return itemPosition_.empty() ? 0 : itemPosition_.rbegin()->first;
152     }
153 
GetStartPosition()154     float GetStartPosition() const
155     {
156         if (itemPosition_.empty()) {
157             return 0.0f;
158         }
159         if (GetStartIndex() == 0 && !isLoop_) {
160             return itemPosition_.begin()->second.startPos;
161         }
162         return itemPosition_.begin()->second.startPos - spaceWidth_;
163     }
164 
GetEndPosition()165     float GetEndPosition() const
166     {
167         if (itemPosition_.empty()) {
168             return 0.0f;
169         }
170         if (GetEndIndex() == totalItemCount_ - 1 && !isLoop_) {
171             return itemPosition_.rbegin()->second.endPos;
172         }
173         return itemPosition_.rbegin()->second.endPos + spaceWidth_;
174     }
175 
SetMainSizeIsMeasured(bool mainSizeIsMeasured)176     void SetMainSizeIsMeasured(bool mainSizeIsMeasured)
177     {
178         mainSizeIsMeasured_ = mainSizeIsMeasured;
179     }
180 
GetMainSizeIsMeasured()181     bool GetMainSizeIsMeasured() const
182     {
183         return mainSizeIsMeasured_;
184     }
185 
SetCurrentIndex(int32_t currentIndex)186     void SetCurrentIndex(int32_t currentIndex)
187     {
188         currentIndex_ = currentIndex;
189     }
190 
GetCurrentIndex()191     int32_t GetCurrentIndex() const
192     {
193         return currentIndex_;
194     }
195 
IsCrossMatchChild()196     bool IsCrossMatchChild() const
197     {
198         return crossMatchChild_;
199     }
200 
SetUseCustomAnimation(bool useCustomAnimation)201     void SetUseCustomAnimation(bool useCustomAnimation)
202     {
203         useCustomAnimation_ = useCustomAnimation;
204     }
205 
SetCustomAnimationToIndex(std::optional<int32_t> customAnimationToIndex)206     void SetCustomAnimationToIndex(std::optional<int32_t> customAnimationToIndex)
207     {
208         customAnimationToIndex_ = customAnimationToIndex;
209     }
210 
SetRemoveFromRSTreeIndex(std::optional<int32_t> removeFromRSTreeIndex)211     void SetRemoveFromRSTreeIndex(std::optional<int32_t> removeFromRSTreeIndex)
212     {
213         removeFromRSTreeIndex_ = removeFromRSTreeIndex;
214     }
215 
SetIndexsInAnimation(const std::set<int32_t> & indexsInAnimation)216     void SetIndexsInAnimation(const std::set<int32_t>& indexsInAnimation)
217     {
218         indexsInAnimation_ = indexsInAnimation;
219     }
220 
SetNeedUnmountIndexs(const std::set<int32_t> & needUnmountIndexs)221     void SetNeedUnmountIndexs(const std::set<int32_t>& needUnmountIndexs)
222     {
223         needUnmountIndexs_ = needUnmountIndexs;
224     }
225 
GetNeedUnmountIndexs()226     std::set<int32_t> GetNeedUnmountIndexs() const
227     {
228         return needUnmountIndexs_;
229     }
230 
SetSwipeByGroup(bool swipeByGroup)231     void SetSwipeByGroup(bool swipeByGroup)
232     {
233         swipeByGroup_ = swipeByGroup;
234     }
235 
SetRealTotalCount(int32_t realTotalCount)236     void SetRealTotalCount(int32_t realTotalCount)
237     {
238         realTotalCount_ = realTotalCount;
239     }
240 
SetPlaceItemWidth(std::optional<float> placeItemWidth)241     void SetPlaceItemWidth(std::optional<float> placeItemWidth)
242     {
243         placeItemWidth_ = placeItemWidth;
244     }
245 
SetHasCachedCapture(bool hasCachedCapture)246     void SetHasCachedCapture(bool hasCachedCapture)
247     {
248         hasCachedCapture_ = hasCachedCapture;
249     }
250 
SetIsCaptureReverse(bool isCaptureReverse)251     void SetIsCaptureReverse(bool isCaptureReverse)
252     {
253         isCaptureReverse_ = isCaptureReverse;
254     }
255 
GetIsCaptureReverse()256     bool GetIsCaptureReverse() const
257     {
258         return isCaptureReverse_;
259     }
260 
GetIsNeedUpdateCapture()261     bool GetIsNeedUpdateCapture() const
262     {
263         return isNeedUpdateCapture_;
264     }
265 
SetItemsPositionInAnimation(const PositionMap & itemPositionInAnimation)266     void SetItemsPositionInAnimation(const PositionMap& itemPositionInAnimation)
267     {
268         itemPositionInAnimation_ = itemPositionInAnimation;
269     }
270 
GetItemsPositionInAnimation()271     PositionMap&& GetItemsPositionInAnimation()
272     {
273         return std::move(itemPositionInAnimation_);
274     }
275 
SetIsMeasureOneMoreItem(bool isMeasureOneMoreItem)276     void SetIsMeasureOneMoreItem(bool isMeasureOneMoreItem)
277     {
278         isMeasureOneMoreItem_ = isMeasureOneMoreItem;
279     }
280 
SetIsFrameAnimation(bool isFrameAnimation)281     void SetIsFrameAnimation(bool isFrameAnimation)
282     {
283         isFrameAnimation_ = isFrameAnimation;
284     }
285 
GetTargetStartPos()286     float GetTargetStartPos() const
287     {
288         return targetStartPos_;
289     }
290 
SetCachedCount(int32_t cachedCount)291     void SetCachedCount(int32_t cachedCount)
292     {
293         cachedCount_ = cachedCount > realTotalCount_ ? realTotalCount_ : cachedCount;
294     }
295 
GetCachedItems()296     const std::set<int32_t>& GetCachedItems() const
297     {
298         return cachedItems_;
299     }
300 
GetLayoutConstraint()301     const LayoutConstraintF& GetLayoutConstraint() const
302     {
303         return childLayoutConstraint_;
304     }
305 
GetIgnoreBlankOffset()306     float GetIgnoreBlankOffset() const
307     {
308         return ignoreBlankOffset_;
309     }
310 
SetIgnoreBlankOffset(float ignoreBlankOffset)311     void SetIgnoreBlankOffset(float ignoreBlankOffset)
312     {
313         ignoreBlankOffset_ = ignoreBlankOffset;
314     }
315 
SetDuringInteraction(bool duringInteraction)316     void SetDuringInteraction(bool duringInteraction)
317     {
318         duringInteraction_ = duringInteraction;
319     }
320 
SetCachedShow(bool cachedShow)321     void SetCachedShow(bool cachedShow)
322     {
323         cachedShow_ = cachedShow;
324     }
325 
326 private:
327     void LayoutSwiperIndicator(
328         LayoutWrapper* layoutWrapper, const RefPtr<SwiperLayoutProperty>& swiperLayoutProperty,
329         const PaddingPropertyF& padding);
330     void MeasureSwiper(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, Axis axis);
331     void MeasureTabsCustomAnimation(LayoutWrapper* layoutWrapper);
332     void MeasureSwiperCustomAnimation(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint);
333     void LayoutCustomAnimation(LayoutWrapper* layoutWrapper) const;
334     void LayoutItem(LayoutWrapper* layoutWrapper, Axis axis, OffsetF offset, std::pair<int32_t, SwiperItemInfo> pos);
335     void SetInactive(
336         LayoutWrapper* layoutWrapper, float startMainPos, float endMainPos, std::optional<int32_t> targetIndex);
337 
338     void PlaceDigitChild(const RefPtr<LayoutWrapper>& indicatorWrapper, const RefPtr<LayoutProperty>& layoutProperty);
339     RefPtr<LayoutWrapper> GetNodeLayoutWrapperByTag(LayoutWrapper* layoutWrapper, const std::string& tagName) const;
340     void MeasureArrow(const RefPtr<LayoutWrapper>& arrowWrapper, const RefPtr<LayoutProperty>& layoutProperty) const;
341     void ArrowLayout(
342         LayoutWrapper* layoutWrapper, const RefPtr<LayoutWrapper>& arrowWrapper, const PaddingPropertyF padding) const;
343     void ResetOffscreenItemPosition(LayoutWrapper* layoutWrapper, int32_t index, bool isForward, Axis axis) const;
344     int32_t GetDisplayCount(LayoutWrapper* layoutWrapper) const;
345     void SetInactiveOnForward(LayoutWrapper* layoutWrapper, Axis axis);
346     void SetInactiveOnBackward(LayoutWrapper* layoutWrapper, Axis axis);
347     void AdjustStartInfoOnSwipeByGroup(
348         int32_t startIndex, const PositionMap& itemPosition, int32_t& startIndexInVisibleWindow, float& startPos);
349     bool HasCustomIndicatorOffset(const RefPtr<LayoutWrapper>& indicatorWrapper);
350     const OffsetF CalculateCustomOffset(
351         const RefPtr<LayoutWrapper>& indicatorWrapper, const OffsetF& currentOffset);
352     void CaptureMeasure(LayoutWrapper* layoutWrapper, LayoutConstraintF& childLayoutConstraint);
353     void CaptureLayout(LayoutWrapper* layoutWrapper);
354     bool IsNormalItem(const RefPtr<LayoutWrapper>& wrapper) const;
355     bool CheckIsSingleCase(const RefPtr<SwiperLayoutProperty>& property);
356     void UpdateLayoutInfoBeforeMeasureSwiper(const RefPtr<SwiperLayoutProperty>& property);
357     void IndicatorAndArrowMeasure(LayoutWrapper* layoutWrapper, const OptionalSizeF& parentIdealSize);
358     float GetChildMainAxisSize(
359         const RefPtr<LayoutWrapper>& childWrapper, const RefPtr<SwiperLayoutProperty>& swiperProperty, Axis axis);
360 
361     void CheckCachedItem(int32_t startIndex, int32_t endIndex, LayoutWrapper* layoutWrapper);
362     bool NeedMeasureForward(int32_t currentIndex, float currentEndPos, float forwardEndPos, bool cachedLayout) const;
363     bool NeedMeasureBackward(
364         int32_t currentIndex, float currentStartPos, float backwardStartPos, bool isStretch, bool cachedLayout) const;
365     void CalcCachedItemIndex(LayoutWrapper* layoutWrapper);
366     int32_t GetCurrentFirstIndexInWindow(LayoutWrapper* layoutWrapper) const;
367     int32_t GetCurrentLastIndexInWindow(LayoutWrapper* layoutWrapper) const;
368     void LayoutCachedItem(LayoutWrapper* layoutWrapper, const LayoutConstraintF& constraint, Axis axis);
369     int32_t GetUserSetCachedCount(LayoutWrapper* layoutWrapper) const;
370     void AdjustItemPositionOnCachedShow();
371     void AdjustOffsetOnForward(float currentEndPos);
372     void AdjustOffsetOnBackward(float currentStartPos);
373 
374     bool isLoop_ = true;
375     float prevMargin_ = 0.0f;
376     float nextMargin_ = 0.0f;
377 
378     PositionMap itemPosition_;
379     PositionMap prevItemPosition_;
380     PositionMap itemPositionInAnimation_;
381     float currentOffset_ = 0.0f;
382     float currentDelta_ = 0.0f;
383     float startMainPos_ = 0.0f;
384     float endMainPos_ = 0.0f;
385 
386     float paddingBeforeContent_ = 0.0f;
387     float paddingAfterContent_ = 0.0f;
388     float contentMainSize_ = 0.0f;
389     float oldContentMainSize_ = 0.0f;
390     float contentCrossSize_ = 0.0f;
391     int32_t totalItemCount_ = 0;
392     bool mainSizeIsDefined_ = false;
393 
394     float spaceWidth_ = 0.0f;
395     bool overScrollFeature_ = false;
396     bool canOverScroll_ = false;
397 
398     bool mainSizeIsMeasured_ = false;
399     bool crossMatchChild_ = false;
400     bool measured_ = false; // to distinguish first and second measure in flex layout
401     bool duringInteraction_ = false; // user interacting, include touching and translating animation.
402 
403     std::optional<int32_t> jumpIndex_;
404     std::optional<int32_t> targetIndex_;
405     std::optional<int32_t> currentJumpIndex_;
406     std::optional<int32_t> currentTargetIndex_;
407     std::optional<int32_t> customAnimationToIndex_;
408     std::optional<int32_t> removeFromRSTreeIndex_;
409     int32_t currentIndex_ = 0;
410     bool targetIsSameWithStartFlag_ = false;
411     bool useCustomAnimation_ = false;
412     std::set<int32_t> indexsInAnimation_;
413     std::set<int32_t> needUnmountIndexs_;
414     bool swipeByGroup_ = false;
415     int32_t realTotalCount_ = 0;
416     std::optional<float> placeItemWidth_;
417     bool useCustomIndicatorOffset = false;
418     bool hasCachedCapture_ = false;
419     bool isCaptureReverse_ = false;
420     bool isNeedUpdateCapture_ = false;
421     bool isMeasureOneMoreItem_ = false;
422     bool isFrameAnimation_ = false;
423     float ignoreBlankOffset_ = 0.0f;
424     float currentIgnoreBlankOffset_ = 0.0f;
425     std::set<int32_t> measuredItems_;
426     std::set<int32_t> activeItems_;
427     std::set<int32_t> cachedItems_;
428     // only be used in AutoLinear mode
429     float targetStartPos_ = 0.0f;
430     int32_t cachedCount_ = 0;
431     bool cachedShow_ = false;
432     int32_t cachedStartIndex_ = 0;
433     int32_t cachedEndIndex_ = 0;
434     LayoutConstraintF childLayoutConstraint_;
435 
436     std::mutex swiperMutex_;
437 };
438 
439 } // namespace OHOS::Ace::NG
440 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SWIPER_SWIPER_LAYOUT_ALGORITHM_H
441