• 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_SCROLL_SCROLL_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_PATTERN_H
18 
19 #include "base/geometry/axis.h"
20 #include "core/components/common/layout/constants.h"
21 #include "core/components_ng/event/event_hub.h"
22 #include "core/components_ng/pattern/pattern.h"
23 #include "core/components_ng/pattern/scroll/scroll_accessibility_property.h"
24 #include "core/components_ng/pattern/scroll/scroll_edge_effect.h"
25 #include "core/components_ng/pattern/scroll/scroll_event_hub.h"
26 #include "core/components_ng/pattern/scroll/scroll_layout_algorithm.h"
27 #include "core/components_ng/pattern/scroll/scroll_layout_property.h"
28 #include "core/components_ng/pattern/scroll/scroll_paint_property.h"
29 #include "core/components_ng/pattern/scroll/scroll_paint_method.h"
30 #include "core/components_ng/pattern/scroll/scroll_position_controller.h"
31 #include "core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.h"
32 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
33 #include "core/components_ng/pattern/scrollable/scrollable_properties.h"
34 
35 namespace OHOS::Ace::NG {
36 
37 class ScrollPattern : public ScrollablePattern {
38     DECLARE_ACE_TYPE(ScrollPattern, ScrollablePattern);
39 
40 public:
41     ScrollPattern() = default;
~ScrollPattern()42     ~ScrollPattern() override
43     {
44         positionController_ = nullptr;
45     }
46 
IsAtomicNode()47     bool IsAtomicNode() const override
48     {
49         return false;
50     }
51 
UsResRegion()52     bool UsResRegion() override
53     {
54         return false;
55     }
56 
CreateLayoutProperty()57     RefPtr<LayoutProperty> CreateLayoutProperty() override
58     {
59         return MakeRefPtr<ScrollLayoutProperty>();
60     }
61 
CreatePaintProperty()62     RefPtr<PaintProperty> CreatePaintProperty() override
63     {
64         return MakeRefPtr<ScrollPaintProperty>();
65     }
66 
CreateAccessibilityProperty()67     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
68     {
69         return MakeRefPtr<ScrollAccessibilityProperty>();
70     }
71 
CreateLayoutAlgorithm()72     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
73     {
74         auto layoutAlgorithm = MakeRefPtr<ScrollLayoutAlgorithm>(currentOffset_);
75         return layoutAlgorithm;
76     }
77 
CreateNodePaintMethod()78     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
79     {
80         auto paint = MakeRefPtr<ScrollPaintMethod>();
81         paint->SetScrollBar(GetScrollBar());
82         CreateScrollBarOverlayModifier();
83         paint->SetScrollBarOverlayModifier(GetScrollBarOverlayModifier());
84         auto scrollEffect = GetScrollEdgeEffect();
85         if (scrollEffect && scrollEffect->IsFadeEffect()) {
86             paint->SetEdgeEffect(scrollEffect);
87         }
88         return paint;
89     }
90 
CreateEventHub()91     RefPtr<EventHub> CreateEventHub() override
92     {
93         return MakeRefPtr<ScrollEventHub>();
94     }
95 
ReachMaxCount()96     virtual bool ReachMaxCount() const
97     {
98         return true;
99     }
100 
IsScrollable()101     bool IsScrollable() const override
102     {
103         return GetAxis() != Axis::NONE;
104     }
105 
106     bool OnScrollCallback(float offset, int32_t source) override;
107     void OnScrollEndCallback() override;
108 
GetCurrentPosition()109     double GetCurrentPosition() const
110     {
111         return currentOffset_;
112     }
113 
GetTotalOffset()114     float GetTotalOffset() const override
115     {
116         return -currentOffset_;
117     }
118 
119     void ResetPosition();
120 
GetCurrentOffset()121     Offset GetCurrentOffset() const
122     {
123         if (GetAxis() == Axis::HORIZONTAL) {
124             return Offset{currentOffset_, 0};
125         }
126         return Offset{0, currentOffset_};
127     }
128 
GetScrollableDistance()129     float GetScrollableDistance() const
130     {
131         return scrollableDistance_;
132     }
133 
IsRowReverse()134     bool IsRowReverse() const
135     {
136         // TODO: not consider rightToLeft
137         return direction_ == FlexDirection::ROW_REVERSE;
138     }
139 
IsColReverse()140     bool IsColReverse() const
141     {
142         return  direction_ == FlexDirection::COLUMN_REVERSE;
143     }
144 
GetScrollPositionController()145     RefPtr<ScrollPositionController> GetScrollPositionController() const
146     {
147         return positionController_;
148     }
149 
SetScrollPositionController(const RefPtr<ScrollPositionController> & positionController)150     void SetScrollPositionController(const RefPtr<ScrollPositionController>& positionController)
151     {
152         positionController_ = positionController;
153     }
154 
SetDirection(FlexDirection direction)155     void SetDirection(FlexDirection direction)
156     {
157         direction_ = direction;
158     }
159 
GetFocusPattern()160     FocusPattern GetFocusPattern() const override
161     {
162         return { FocusType::SCOPE, true };
163     }
164 
165     bool ScrollToNode(const RefPtr<FrameNode>& focusFrameNode) override;
166 
167     bool IsAtTop() const override;
168     bool IsAtBottom() const override;
169     bool IsOutOfBoundary() const;
170     OverScrollOffset GetOverScrollOffset(double delta) const override;
171 
172     void OnAnimateStop() override;
173     bool UpdateCurrentOffset(float offset, int32_t source) override;
174     void AnimateTo(float position, float duration, const RefPtr<Curve>& curve, bool smooth) override;
175     void ScrollToEdge(ScrollEdgeType scrollEdgeType, bool smooth);
176     void ScrollBy(float pixelX, float pixelY, bool smooth, const std::function<void()>& onFinish = nullptr);
177     bool ScrollPage(bool reverse, bool smooth, const std::function<void()>& onFinish = nullptr);
178     void ScrollTo(float position) override;
179     void JumpToPosition(float position, int32_t source = SCROLL_FROM_JUMP);
180     bool ScrollPageCheck(float delta, int32_t source);
181     void AdjustOffset(float& delta, int32_t source);
182     void ToJsonValue(std::unique_ptr<JsonValue>& json) const override;
183 
184     // scrollSnap
185     std::optional<float> CalePredictSnapOffset(float delta) override;
186     bool NeedScrollSnapToSide(float delta) override;
187     void CaleSnapOffsets();
188     void CaleSnapOffsetsByInterval(ScrollSnapAlign scrollSnapAlign);
189     void CaleSnapOffsetsByPaginations();
190 
IsSnapToInterval()191     bool IsSnapToInterval() const
192     {
193         return snapPaginations_.empty();
194     }
195 
GetSnapOffsets()196     std::vector<float> GetSnapOffsets() const
197     {
198         return snapOffsets_;
199     }
200 
SetSnapOffsets(const std::vector<float> & snapOffset)201     void SetSnapOffsets(const std::vector<float>& snapOffset)
202     {
203         snapOffsets_ = snapOffset;
204     }
205 
SetIntervalSize(const Dimension & intervalSize)206     void SetIntervalSize(const Dimension& intervalSize)
207     {
208         if (intervalSize_ != intervalSize) {
209             intervalSize_ = intervalSize;
210             scrollSnapUpdate_ = true;
211         }
212     }
213 
GetIntervalSize()214     Dimension GetIntervalSize() const
215     {
216         return intervalSize_;
217     }
218 
SetSnapPaginations(const std::vector<Dimension> & snapPaginations)219     void SetSnapPaginations(const std::vector<Dimension>& snapPaginations)
220     {
221         if (snapPaginations_ != snapPaginations) {
222             snapPaginations_ = snapPaginations;
223             scrollSnapUpdate_ = true;
224         }
225     }
226 
GetSnapPaginations()227     std::vector<Dimension> GetSnapPaginations() const
228     {
229         return snapPaginations_;
230     }
231 
SetEnableSnapToSide(const std::pair<bool,bool> & enableSnapToSide)232     void SetEnableSnapToSide(const std::pair<bool, bool>& enableSnapToSide)
233     {
234         enableSnapToSide_ = enableSnapToSide;
235     }
236 
GetEnableSnapToSide()237     std::pair<bool, bool> GetEnableSnapToSide() const
238     {
239         return enableSnapToSide_;
240     }
241 
SetScrollSnapUpdate(bool scrollSnapUpdate)242     void SetScrollSnapUpdate(bool scrollSnapUpdate)
243     {
244         scrollSnapUpdate_ = scrollSnapUpdate;
245     }
246 
GetScrollSnapUpdate()247     bool GetScrollSnapUpdate() const
248     {
249         return scrollSnapUpdate_;
250     }
251 
GetScrollSnapAlign()252     ScrollSnapAlign GetScrollSnapAlign() const
253     {
254         auto host = GetHost();
255         CHECK_NULL_RETURN_NOLOG(host, ScrollSnapAlign::NONE);
256         auto scrollLayoutProperty = host->GetLayoutProperty<ScrollLayoutProperty>();
257         CHECK_NULL_RETURN_NOLOG(scrollLayoutProperty, ScrollSnapAlign::NONE);
258         return scrollLayoutProperty->GetScrollSnapAlign().value_or(ScrollSnapAlign::NONE);
259     }
260 
261 protected:
262     void DoJump(float position, int32_t source = SCROLL_FROM_JUMP);
263 
264 private:
265     void OnModifyDone() override;
266     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
267 
268     bool IsCrashTop() const;
269     bool IsCrashBottom() const;
270     bool IsScrollOutOnEdge(float delta) const;
271     void HandleCrashTop() const;
272     void HandleCrashBottom() const;
273 
274     void RegisterScrollEventTask();
275     void RegisterScrollBarEventTask();
276     void HandleScrollEffect();
277     void ValidateOffset(int32_t source);
278     void HandleScrollPosition(float scroll, int32_t scrollState);
279     void SetEdgeEffectCallback(const RefPtr<ScrollEdgeEffect>& scrollEffect) override;
280     void AddScrollEdgeEffect(RefPtr<ScrollEdgeEffect> scrollEffect);
281     void UpdateScrollBarOffset() override;
282     void FireOnScrollStart();
283     void FireOnScrollStop();
284     void SetAccessibilityAction();
285     void CheckScrollable();
286     OffsetF GetOffsetToScroll(const RefPtr<FrameNode>& childFrame) const;
287 
288     RefPtr<ScrollPositionController> positionController_;
289     float currentOffset_ = 0.0f;
290     float lastOffset_ = 0.0f;
291     float scrollableDistance_ = 0.0f;
292     float viewPortLength_ = 0.0f;
293     SizeF viewPort_;
294     SizeF viewSize_;
295     SizeF viewPortExtent_;
296     FlexDirection direction_ { FlexDirection::COLUMN };
297     bool scrollStop_ = false;
298 
299     // scrollSnap
300     std::vector<float> snapOffsets_;
301     std::vector<Dimension> snapPaginations_;
302     std::pair<bool, bool> enableSnapToSide_ = { true, true };
303     Dimension intervalSize_;
304     bool scrollSnapUpdate_ = false;
305 };
306 
307 } // namespace OHOS::Ace::NG
308 
309 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_PATTERN_H
310