1 /*
2  * Copyright (c) 2023-2024 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_PATTERNS_WATERFLOW_WATER_FLOW_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_WATERFLOW_WATER_FLOW_PATTERN_H
18 
19 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
20 #include "core/components_ng/pattern/waterflow/layout/water_flow_layout_algorithm_base.h"
21 #include "core/components_ng/pattern/waterflow/layout/water_flow_layout_info_base.h"
22 #include "core/components_ng/pattern/waterflow/water_flow_accessibility_property.h"
23 #include "core/components_ng/pattern/waterflow/water_flow_content_modifier.h"
24 #include "core/components_ng/pattern/waterflow/water_flow_event_hub.h"
25 #include "core/components_ng/pattern/waterflow/water_flow_layout_property.h"
26 #include "core/components_ng/pattern/waterflow/water_flow_sections.h"
27 
28 namespace OHOS::Ace::NG {
29 class ACE_EXPORT WaterFlowPattern : public ScrollablePattern {
30     DECLARE_ACE_TYPE(WaterFlowPattern, ScrollablePattern);
31 
32 public:
33     bool UpdateCurrentOffset(float delta, int32_t source) override;
34     bool IsScrollable() const override;
35     bool IsAtTop() const override;
36     bool IsAtBottom() const override;
37     bool IsReverse() const override;
38     bool IsVerticalReverse() const;
hasFooter()39     bool hasFooter()
40     {
41         return footer_.Upgrade() != nullptr;
42     };
43     OverScrollOffset GetOverScrollOffset(double delta) const override;
44     void UpdateScrollBarOffset() override;
45 
46     using LayoutMode = WaterFlowLayoutMode;
47     void SetLayoutMode(LayoutMode mode);
GetLayoutMode()48     LayoutMode GetLayoutMode() const
49     {
50         return layoutInfo_->Mode();
51     }
52 
53     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override;
54 
CreateLayoutProperty()55     RefPtr<LayoutProperty> CreateLayoutProperty() override
56     {
57         return MakeRefPtr<WaterFlowLayoutProperty>();
58     }
59 
CreateEventHub()60     RefPtr<EventHub> CreateEventHub() override
61     {
62         return MakeRefPtr<WaterFlowEventHub>();
63     }
64 
CreateAccessibilityProperty()65     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
66     {
67         return MakeRefPtr<WaterFlowAccessibilityProperty>();
68     }
69 
GetPositionController()70     RefPtr<ScrollableController> GetPositionController() const
71     {
72         return positionController_;
73     }
74 
75     void TriggerModifyDone();
76 
77     RefPtr<NodePaintMethod> CreateNodePaintMethod() override;
78 
79     bool UpdateStartIndex(int32_t index);
80 
81     void AddFooter(const RefPtr<NG::UINode>& footer);
82 
83     void ResetLayoutInfo();
84 
GetBeginIndex()85     int32_t GetBeginIndex() const
86     {
87         return layoutInfo_->startIndex_;
88     }
89 
GetEndIndex()90     int32_t GetEndIndex() const
91     {
92         return layoutInfo_->endIndex_;
93     }
94 
95     int32_t GetChildrenCount() const;
96 
GetTotalOffset()97     float GetTotalOffset() const override
98     {
99         return -layoutInfo_->Offset();
100     }
101 
102     int32_t GetRows() const;
103 
104     int32_t GetColumns() const;
105 
106     void OnAnimateStop() override;
107     /**
108      * @brief LayoutMode::SLIDING_WINDOW doesn't support scrollTo and animateTo
109      */
110     void ScrollTo(float position) override;
111     /**
112      * @brief LayoutMode::SLIDING_WINDOW doesn't support animateTo
113      */
114     void AnimateTo(float position, float duration, const RefPtr<Curve>& curve, bool smooth, bool canOverScroll,
115         bool useTotalOffset = true) override;
116 
117     void ScrollPage(bool reverse, bool smooth = false,
118         AccessibilityScrollType scrollType = AccessibilityScrollType::SCROLL_FULL) override;
119 
120     void ScrollToIndex(int32_t index, bool smooth = false, ScrollAlign align = ScrollAlign::START,
121         std::optional<float> extraOffset = std::nullopt) override;
122 
GetStoredOffset()123     double GetStoredOffset() const
124     {
125         return layoutInfo_->storedOffset_;
126     }
127 
SetRestoreOffset(double restoreOffset)128     void SetRestoreOffset(double restoreOffset)
129     {
130         layoutInfo_->restoreOffset_ = restoreOffset;
131     }
132 
SetScrollAlign(ScrollAlign align)133     void SetScrollAlign(ScrollAlign align)
134     {
135         layoutInfo_->align_ = align;
136     }
137 
138     std::string ProvideRestoreInfo() override;
139     void OnRestoreInfo(const std::string& restoreInfo) override;
140     Rect GetItemRect(int32_t index) const override;
141     int32_t GetItemIndex(double x, double y) const override;
142 
143     RefPtr<WaterFlowSections> GetSections() const;
144     RefPtr<WaterFlowSections> GetOrCreateWaterFlowSections();
145     void ResetSections();
146 
147     /**
148      * @brief Callback function when Sections data has changed.
149      *
150      * @param start the index of the first modified section.
151      */
152     void OnSectionChanged(int32_t start);
153 
154     void DumpAdvanceInfo() override;
155 
SetPreloadList(std::list<int32_t> && preload)156     void SetPreloadList(std::list<int32_t>&& preload)
157     {
158         preloadItems_ = std::move(preload);
159     }
PreloadListEmpty()160     bool PreloadListEmpty() const
161     {
162         return preloadItems_.empty();
163     }
MovePreloadList()164     std::list<int32_t>&& MovePreloadList()
165     {
166         return std::move(preloadItems_);
167     }
SetCacheLayoutAlgo(const RefPtr<WaterFlowLayoutBase> & algo)168     void SetCacheLayoutAlgo(const RefPtr<WaterFlowLayoutBase>& algo)
169     {
170         cacheLayout_ = algo;
171     }
GetCacheLayoutAlgo()172     const RefPtr<WaterFlowLayoutBase>& GetCacheLayoutAlgo() const
173     {
174         return cacheLayout_;
175     }
176 
177     void NotifyDataChange(int32_t index, int32_t count) override;
178 
179     // ------------------------ Focus adapter --------------------------------
GetFocusPattern()180     FocusPattern GetFocusPattern() const override
181     {
182         return { FocusType::SCOPE, true };
183     }
184     ScopeFocusAlgorithm GetScopeFocusAlgorithm() override;
185     std::function<bool(int32_t)> GetScrollIndexAbility() override;
186     // ------------------------ Focus ^^^ --------------------------------
187     void BeforeCreateLayoutWrapper() override;
188 
AddSectionChangeStartPos(int32_t start)189     void AddSectionChangeStartPos(int32_t start)
190     {
191         sectionChangeStartPos_.emplace_back(start);
192         MarkDirtyNodeSelf();
193     }
194 
GetPrevOffset()195     float GetPrevOffset() const
196     {
197         return prevOffset_;
198     }
199 
GetDefaultCachedCount()200     int32_t GetDefaultCachedCount() const
201     {
202         return layoutInfo_->defCachedCount_;
203     }
204 
205     SizeF GetChildrenExpandedSize() override;
206 
207 private:
GetDefaultScrollBarDisplayMode()208     DisplayMode GetDefaultScrollBarDisplayMode() const override
209     {
210         return DisplayMode::OFF;
211     }
212     void OnModifyDone() override;
213     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
214     void CheckScrollable();
215     bool IsOutOfBoundary(bool useCurrentDelta = true) override;
216 
217     void TriggerPostLayoutEvents();
218 
219     void SetEdgeEffectCallback(const RefPtr<ScrollEdgeEffect>& scrollEffect) override;
220     SizeF GetContentSize() const;
221     void MarkDirtyNodeSelf();
222     void OnScrollEndCallback() override;
223     bool ScrollToTargetIndex(int32_t index);
224     bool NeedRender();
225     void FireOnReachStart(const OnReachEvent& onReachStart) override;
226     void FireOnReachEnd(const OnReachEvent& onReachEnd) override;
227     void FireOnScrollIndex(bool indexChanged, const ScrollIndexFunc& onScrollIndex);
228 
229     /**
230      * @param step FocusStep
231      * @param currentFocusNode the currently focused FlowItem.
232      * @return WeakPtr<FocusHub> of the next FlowItem to focus on.
233      */
234     WeakPtr<FocusHub> GetNextFocusNode(FocusStep step, const WeakPtr<FocusHub>& currentFocusNode);
235 
236     std::optional<int32_t> targetIndex_;
237     RefPtr<WaterFlowLayoutInfoBase> layoutInfo_ = WaterFlowLayoutInfoBase::Create(LayoutMode::TOP_DOWN);
238     RefPtr<WaterFlowSections> sections_;
239 
240     float prevOffset_ = 0.0f;
241     SizeF lastSize_;
242     std::pair<int32_t, int32_t> itemRange_ = { -1, -1 };
243     WeakPtr<UINode> footer_;
244     // for keepVisiableContentPosition mode temporarily.
245     bool keepContentPosition_ = true;
246 
247     // clip padding of WaterFlow
248     RefPtr<WaterFlowContentModifier> contentModifier_;
249 
250     std::list<int32_t> preloadItems_;
251     RefPtr<WaterFlowLayoutBase> cacheLayout_;
252 
253     std::vector<int32_t> sectionChangeStartPos_;
254 };
255 } // namespace OHOS::Ace::NG
256 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_WATERFLOW_WATER_FLOW_PATTERN_H
257