• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_FREE_GESTURE_CONTROLLER_H
16 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_FREE_GESTURE_CONTROLLER_H
17 
18 #include "core/components_ng/base/modifier.h"
19 #include "core/components_ng/gestures/recognizers/pan_recognizer.h"
20 #include "core/components_ng/pattern/scrollable/scrollable_properties.h"
21 
22 namespace OHOS::Ace::NG {
23 class ScrollPattern;
24 class AxisAnimator;
25 enum class ScrollEdge;
26 
27 /**
28  * @brief Controller for free scrolling behavior. It manages related gestures and animations.
29  *
30  */
31 class FreeScrollController final : public AceType {
32     DECLARE_ACE_TYPE(FreeScrollController, AceType);
33     ACE_DISALLOW_COPY_AND_MOVE(FreeScrollController);
34 
35 public:
36     explicit FreeScrollController(ScrollPattern& pattern);
37     ~FreeScrollController() final;
38 
GetFreePanGesture()39     RefPtr<PanRecognizer> GetFreePanGesture() const
40     {
41         freePanGesture_->SetEnabled(enableScroll_); // workaround gesture's internal reset
42         return freePanGesture_;
43     }
44 
45     /**
46      * @brief Allow other modules to modify offset. Calling this function automatically stops scroll animations.
47      */
48     void SetOffset(OffsetF newPos, bool allowOverScroll = false);
UpdateOffset(const OffsetF & delta)49     inline void UpdateOffset(const OffsetF& delta)
50     {
51         SetOffset(offset_->Get() + delta);
52     }
53 
54     void OnLayoutFinished(const OffsetF& adjustedOffset, const SizeF& scrollableArea);
55 
56     OffsetF GetOffset() const;
GetLayoutOffset()57     const OffsetF& GetLayoutOffset() const
58     {
59         return actualOffset_;
60     }
61 
62     /**
63      * @brief Start a scroll animation to the final position.
64      */
65     void ScrollTo(OffsetF finalPos, const std::optional<float>& velocity,
66         std::optional<int32_t> duration = std::nullopt, RefPtr<Curve> curve = nullptr, bool allowOverScroll = false);
67 
68 private:
69     void InitializePanRecognizer();
70     void InitializeTouchEvent();
71 
72     void HandlePanStart(const GestureEvent& event);
73     void HandlePanUpdate(const GestureEvent& event);
74     void HandlePanEndOrCancel(const GestureEvent& event);
75 
76     void HandleTouchDown();
77     void HandleTouchUpOrCancel();
78 
79     /**
80      * @brief update callback of AnimatableProperty @c offset_.
81      */
82     void HandleOffsetUpdate(const OffsetF& currentValue);
83 
84     /**
85      * @brief Start the scroll animation if possible with the given velocity and offset_.
86      */
87     void Fling(const OffsetF& velocity);
88     void StopScrollAnimation();
89     void HandleAnimationEnd();
90 
91     /**
92      * @brief clamp position to be within the scrollable area.
93      */
94     OffsetF ClampPosition(const OffsetF& finalPos) const;
95 
96     /**
97      * @brief Check if the new offset would reach any edges. If so, fire corresponding user callbacks.
98      * @return true if any edge is reached, false otherwise.
99      */
100     bool CheckCrashEdge(const OffsetF& newOffset, const SizeF& scrollableArea) const;
101 
102     /**
103      * @brief triggers onWillScroll user callback
104      * @return user-modified delta
105      */
106     OffsetF FireOnWillScroll(const OffsetF& delta, ScrollState state, ScrollSource source) const;
107     void FireOnDidScroll(const OffsetF& delta, ScrollState state) const;
108     void FireOnScrollStart() const;
109     void FireOnScrollEnd() const;
110     void FireOnScrollEdge(const std::vector<ScrollEdge>& edges) const;
111 
112     void AnimateOnMouseScroll(const OffsetF& delta);
113     void HandleAxisAnimationFrame(float newOffset);
114 
115     ScrollPattern& pattern_;
116     RefPtr<NodeAnimatablePropertyOffsetF> offset_;
117     OffsetF actualOffset_; // actual displayed offset, adjusted by LayoutAlgorithm
118     RefPtr<PanRecognizer> freePanGesture_;
119     RefPtr<TouchEventImpl> freeTouch_;
120     RefPtr<AxisAnimator> axisAnimator_; // to smooth out mouse wheel scrolls
121 
122 public:
123     enum class State {
124         IDLE,
125         DRAG,
126         FLING,
127         EXTERNAL_FLING, // used for external animations like scroller animation
128         BOUNCE,         // used for bounce animation transitioned from FLING when reaching edge
129     };
130 
131 private:
132     State state_ = State::IDLE;
133     bool enableScroll_ = true;
134     bool mouseWheelScrollIsVertical_ = true;
135 };
136 
137 } // namespace OHOS::Ace::NG
138 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_FREE_GESTURE_CONTROLLER_H
139