• 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_PATTERNS_LIST_LIST_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_LIST_LIST_PATTERN_H
18 
19 #include "core/animation/chain_animation.h"
20 #include "core/components_ng/pattern/list/list_accessibility_property.h"
21 #include "core/components_ng/pattern/list/list_content_modifier.h"
22 #include "core/components_ng/pattern/list/list_event_hub.h"
23 #include "core/components_ng/pattern/list/list_item_pattern.h"
24 #include "core/components_ng/pattern/list/list_layout_algorithm.h"
25 #include "core/components_ng/pattern/list/list_layout_property.h"
26 #include "core/components_ng/pattern/list/list_paint_method.h"
27 #include "core/components_ng/pattern/scroll/inner/scroll_bar.h"
28 #include "core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.h"
29 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
30 #include "core/components_ng/render/render_context.h"
31 #include "core/pipeline_ng/pipeline_context.h"
32 
33 namespace OHOS::Ace::NG {
34 struct ListItemGroupPara {
35     int32_t lanes = -1;
36     int32_t itemEndIndex = -1;
37     int32_t displayStartIndex = -1;
38     int32_t displayEndIndex = -1;
39 };
40 
41 class ListPattern : public ScrollablePattern {
42     DECLARE_ACE_TYPE(ListPattern, ScrollablePattern);
43 
44 public:
ListPattern()45     ListPattern() : ScrollablePattern(EdgeEffect::SPRING, false) {}
46     ~ListPattern() override = default;
47 
48     RefPtr<NodePaintMethod> CreateNodePaintMethod() override;
49 
CreateLayoutProperty()50     RefPtr<LayoutProperty> CreateLayoutProperty() override
51     {
52         return MakeRefPtr<ListLayoutProperty>();
53     }
54 
CreateEventHub()55     RefPtr<EventHub> CreateEventHub() override
56     {
57         return MakeRefPtr<ListEventHub>();
58     }
59 
CreateAccessibilityProperty()60     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
61     {
62         return MakeRefPtr<ListAccessibilityProperty>();
63     }
64 
UsResRegion()65     bool UsResRegion() override
66     {
67         return false;
68     }
69 
70     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override;
71 
72     void ToJsonValue(std::unique_ptr<JsonValue>& json) const override;
73 
74     void FromJson(const std::unique_ptr<JsonValue>& json) override;
75 
76     bool UpdateCurrentOffset(float offset, int32_t source) override;
77 
78     DisplayMode GetDefaultScrollBarDisplayMode() const override;
79 
GetStartIndex()80     int32_t GetStartIndex() const
81     {
82         return startIndex_;
83     }
84 
GetEndIndex()85     int32_t GetEndIndex() const
86     {
87         return endIndex_;
88     }
89 
GetMaxListItemIndex()90     int32_t GetMaxListItemIndex() const
91     {
92         return maxListItemIndex_;
93     }
94 
IsScrollable()95     bool IsScrollable() const override
96     {
97         return scrollable_;
98     }
99 
100     bool IsAtTop() const override;
101     bool IsAtBottom() const override;
102     bool OutBoundaryCallback() override;
103     OverScrollOffset GetOverScrollOffset(double delta) const override;
104     float GetOffsetWithLimit(float offset) const override;
105     void HandleScrollBarOutBoundary();
106 
GetFocusPattern()107     FocusPattern GetFocusPattern() const override
108     {
109         return { FocusType::SCOPE, true };
110     }
111 
GetScopeFocusAlgorithm()112     ScopeFocusAlgorithm GetScopeFocusAlgorithm() override
113     {
114         auto property = GetLayoutProperty<ListLayoutProperty>();
115         if (!property) {
116             return {};
117         }
118         return ScopeFocusAlgorithm(property->GetListDirection().value_or(Axis::VERTICAL) == Axis::VERTICAL, true,
119             ScopeType::OTHERS,
120             [wp = WeakClaim(this)](
121                 FocusStep step, const WeakPtr<FocusHub>& currFocusNode, WeakPtr<FocusHub>& nextFocusNode) {
122                 auto list = wp.Upgrade();
123                 if (list) {
124                     nextFocusNode = list->GetNextFocusNode(step, currFocusNode);
125                 }
126             });
127     }
128 
129     bool ScrollToNode(const RefPtr<FrameNode>& focusFrameNode) override;
130 
GetItemPosition()131     const ListLayoutAlgorithm::PositionMap& GetItemPosition() const
132     {
133         return itemPosition_;
134     }
135 
GetTotalOffset()136     float GetTotalOffset() const override
137     {
138         return currentOffset_;
139     }
140 
141     float GetTotalHeight() const override;
142 
143     // scroller
144     void ScrollTo(float position) override;
145     void ScrollToIndex(int32_t index, bool smooth = false, ScrollAlign align = ScrollAlign::START) override;
146     void ScrollToItemInGroup(int32_t index, int32_t indexInGroup, bool smooth = false,
147         ScrollAlign align = ScrollAlign::START);
148     bool CheckTargetValid(int32_t index, int32_t indexInGroup);
149     bool ScrollPage(bool reverse);
150     void ScrollBy(float offset);
151     bool AnimateToTarget(int32_t index, std::optional<int32_t> indexInGroup, ScrollAlign align);
152     Offset GetCurrentOffset() const;
153     Rect GetItemRect(int32_t index) const override;
154     Rect GetItemRectInGroup(int32_t index, int32_t indexInGroup) const;
155     void OnAnimateStop() override;
GetMainContentSize()156     float GetMainContentSize() const override
157     {
158         return contentMainSize_;
159     };
160 
161     void UpdateScrollBarOffset() override;
162     // chain animation
163     void SetChainAnimation();
164     void SetChainAnimationOptions(const ChainAnimationOptions& options);
165     float FlushChainAnimation(float dragOffset);
166     void ProcessDragStart(float startPosition);
167     void ProcessDragUpdate(float dragOffset, int32_t source);
168     float GetChainDelta(int32_t index) const;
169 
170     // multiSelectable
SetMultiSelectable(bool multiSelectable)171     void SetMultiSelectable(bool multiSelectable)
172     {
173         multiSelectable_ = multiSelectable;
174     }
175 
176     void SetSwiperItem(WeakPtr<ListItemPattern> swiperItem);
SetSwiperItemEnd(WeakPtr<ListItemPattern> swiperItem)177     void SetSwiperItemEnd(WeakPtr<ListItemPattern> swiperItem)
178     {
179         if (swiperItem == swiperItem_) {
180             canReplaceSwiperItem_ = true;
181         }
182     }
IsCurrentSwiperItem(WeakPtr<ListItemPattern> swiperItem)183     bool IsCurrentSwiperItem(WeakPtr<ListItemPattern> swiperItem)
184     {
185         if (!swiperItem_.Upgrade()) {
186             return true;
187         }
188         return swiperItem == swiperItem_;
189     }
CanReplaceSwiperItem()190     bool CanReplaceSwiperItem()
191     {
192         if (!swiperItem_.Upgrade()) {
193             canReplaceSwiperItem_ = true;
194         }
195         return canReplaceSwiperItem_;
196     }
197 
SetPredictSnapOffset(float predictSnapOffset)198     void SetPredictSnapOffset(float predictSnapOffset)
199     {
200         predictSnapOffset_ = predictSnapOffset;
201     }
202     bool OnScrollSnapCallback(double targetOffset, double velocity) override;
203 
204     int32_t GetItemIndexByPosition(float xOffset, float yOffset);
205 
SetPredictLayoutParam(std::optional<ListPredictLayoutParam> param)206     void SetPredictLayoutParam(std::optional<ListPredictLayoutParam> param)
207     {
208         predictLayoutParam_ = param;
209     }
GetPredictLayoutParam()210     std::optional<ListPredictLayoutParam> GetPredictLayoutParam() const
211     {
212         return predictLayoutParam_;
213     }
214 
215     void CloseAllSwipeActions(OnFinishFunc&&);
216 
217     std::string ProvideRestoreInfo() override;
218     void OnRestoreInfo(const std::string& restoreInfo) override;
219     void DumpAdvanceInfo() override;
220 
SetNeedToUpdateListDirectionInCardStyle(bool isNeedToUpdateListDirection)221     void SetNeedToUpdateListDirectionInCardStyle(bool isNeedToUpdateListDirection)
222     {
223         isNeedToUpdateListDirection_ = isNeedToUpdateListDirection;
224     }
225 
IsNeedToUpdateListDirectionInCardStyle()226     bool IsNeedToUpdateListDirectionInCardStyle() const
227     {
228         return isNeedToUpdateListDirection_;
229     }
230 
231 private:
IsNeedInitClickEventRecorder()232     bool IsNeedInitClickEventRecorder() const override
233     {
234         return true;
235     }
236 
237     void OnScrollEndCallback() override;
238 
239     void OnModifyDone() override;
240     void ChangeAxis(RefPtr<UINode> node);
241     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
242     float CalculateTargetPos(float startPos, float endPos);
243 
244     void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub);
245     bool OnKeyEvent(const KeyEvent& event);
246     bool HandleDirectionKey(const KeyEvent& event);
247     WeakPtr<FocusHub> GetNextFocusNode(FocusStep step, const WeakPtr<FocusHub>& currentFocusNode);
248     WeakPtr<FocusHub> GetChildFocusNodeByIndex(int32_t tarMainIndex, int32_t tarGroupIndex);
249     WeakPtr<FocusHub> ScrollAndFindFocusNode(int32_t nextIndex, int32_t curIndex, int32_t& nextIndexInGroup,
250         int32_t curIndexInGroup, int32_t moveStep, FocusStep step);
251     bool ScrollListForFocus(int32_t nextIndex, int32_t curIndex, int32_t nextIndexInGroup);
252     bool ScrollListItemGroupForFocus(int32_t nextIndex, int32_t& nextIndexInGroup, int32_t curIndexInGroup,
253         int32_t moveStep, FocusStep step, bool isScrollIndex);
254 
255     void MarkDirtyNodeSelf();
256     SizeF GetContentSize() const;
257     void ProcessEvent(bool indexChanged, float finalOffset, bool isJump, float prevStartOffset, float prevEndOffset);
258     void CheckScrollable();
259     bool IsOutOfBoundary(bool useCurrentDelta = true) override;
260     bool OnScrollCallback(float offset, int32_t source) override;
261     void InitScrollableEvent();
262     void SetEdgeEffectCallback(const RefPtr<ScrollEdgeEffect>& scrollEffect) override;
263     void HandleScrollEffect(float offset);
264     void CheckRestartSpring(bool sizeDiminished);
265     void StartDefaultOrCustomSpringMotion(float start, float end, const RefPtr<InterpolatingSpring>& curve);
266     void UpdateScrollSnap();
267     bool IsScrollSnapAlignCenter() const;
268     void SetChainAnimationLayoutAlgorithm(
269         RefPtr<ListLayoutAlgorithm> listLayoutAlgorithm, RefPtr<ListLayoutProperty> listLayoutProperty);
270     bool NeedScrollSnapAlignEffect() const;
271     ScrollAlign GetScrollAlignByScrollSnapAlign() const;
272     bool GetListItemAnimatePos(float startPos, float endPos, ScrollAlign align, float& targetPos);
273     bool GetListItemGroupAnimatePosWithoutIndexInGroup(int32_t index, float startPos, float endPos,
274         ScrollAlign align, float& targetPos);
275     bool GetListItemGroupAnimatePosWithIndexInGroup(int32_t index, int32_t indexInGroup, float startPos,
276         ScrollAlign align, float& targetPos);
277 
278     // multiSelectable
279     void ClearMultiSelect() override;
280     bool IsItemSelected(const GestureEvent& info) override;
281     void MultiSelectWithoutKeyboard(const RectF& selectedZone) override;
282     void HandleCardModeSelectedEvent(
283         const RectF& selectedZone, const RefPtr<FrameNode>& itemGroupNode, float itemGroupTop);
284 
285     void DrivenRender(const RefPtr<LayoutWrapper>& layoutWrapper);
286     void SetAccessibilityAction();
287     ListItemGroupPara GetListItemGroupParameter(const RefPtr<FrameNode>& node);
288     bool IsListItemGroup(int32_t listIndex, RefPtr<FrameNode>& node);
289     void GetListItemGroupEdge(bool& groupAtStart, bool& groupAtEnd) const;
290     void RefreshLanesItemRange();
291     void UpdateListDirectionInCardStyle();
292     RefPtr<ListContentModifier> listContentModifier_;
293 
294     int32_t maxListItemIndex_ = 0;
295     int32_t startIndex_ = -1;
296     int32_t endIndex_ = -1;
297     int32_t centerIndex_ = -1;
298     float startMainPos_ = 0.0f;
299     float endMainPos_ = 0.0f;
300     float currentOffset_ = 0.0f;
301     float spaceWidth_ = 0.0f;
302     float contentMainSize_ = 0.0f;
303     float contentStartOffset_ = 0.0f;
304     float contentEndOffset_ = 0.0f;
305 
306     float currentDelta_ = 0.0f;
307     bool crossMatchChild_ = false;
308     bool smooth_ = false;
309     float scrollSnapVelocity_ = 0.0f;
310 
311     std::optional<int32_t> jumpIndex_;
312     std::optional<int32_t> jumpIndexInGroup_;
313     std::optional<int32_t> targetIndex_;
314     std::optional<int32_t> targetIndexInGroup_;
315     std::optional<float> predictSnapOffset_;
316     std::optional<float> predictSnapEndPos_;
317     ScrollAlign scrollAlign_ = ScrollAlign::START;
318     bool scrollable_ = true;
319     bool paintStateFlag_ = false;
320     bool isFramePaintStateValid_ = false;
321     bool isNeedCheckOffset_ = false;
322 
323     ListLayoutAlgorithm::PositionMap itemPosition_;
324 
325     std::map<int32_t, int32_t> lanesItemRange_;
326     int32_t lanes_ = 1;
327     float laneGutter_ = 0.0f;
328     // chain animation
329     RefPtr<ChainAnimation> chainAnimation_;
330     bool dragFromSpring_ = false;
331     RefPtr<SpringProperty> springProperty_;
332     std::optional<ChainAnimationOptions> chainAnimationOptions_;
333 
334     bool isOritationListenerRegisted_ = false;
335 
336     // ListItem swiperAction
337     WeakPtr<ListItemPattern> swiperItem_;
338     bool canReplaceSwiperItem_ = true;
339 
340     RefPtr<SpringMotion> scrollToIndexMotion_;
341     RefPtr<SpringMotion> scrollSnapMotion_;
342     RefPtr<Scrollable> scrollableTouchEvent_;
343 
344     bool isScrollEnd_ = false;
345     std::optional<ListPredictLayoutParam> predictLayoutParam_;
346 
347     bool isNeedToUpdateListDirection_ = false;
348 
349     bool endIndexChanged_ = false;
350 };
351 } // namespace OHOS::Ace::NG
352 
353 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_LIST_LIST_PATTERN_H
354