Use "= default" to denote default constructor or destructor
[WebKit-https.git] / Source / WebCore / platform / cocoa / ScrollController.h
1 /*
2  * Copyright (C) 2011, 2014-2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef ScrollController_h
27 #define ScrollController_h
28
29 #if ENABLE(RUBBER_BANDING) || ENABLE(CSS_SCROLL_SNAP)
30
31 #include "FloatPoint.h"
32 #include "FloatSize.h"
33 #include "ScrollTypes.h"
34 #include "WheelEventTestTrigger.h"
35 #include <wtf/Noncopyable.h>
36 #include <wtf/RunLoop.h>
37
38 #if ENABLE(CSS_SCROLL_SNAP)
39 #include "ScrollSnapAnimatorState.h"
40 #include "ScrollSnapOffsetsInfo.h"
41 #endif
42
43 namespace WebCore {
44
45 class LayoutSize;
46 class PlatformWheelEvent;
47 class ScrollableArea;
48 class WheelEventTestTrigger;
49
50 class ScrollControllerClient {
51 protected:
52     virtual ~ScrollControllerClient() = default;
53
54 public:
55 #if ENABLE(RUBBER_BANDING)
56     virtual bool allowsHorizontalStretching(const PlatformWheelEvent&) = 0;
57     virtual bool allowsVerticalStretching(const PlatformWheelEvent&) = 0;
58     virtual IntSize stretchAmount() = 0;
59     virtual bool pinnedInDirection(const FloatSize&) = 0;
60     virtual bool canScrollHorizontally() = 0;
61     virtual bool canScrollVertically() = 0;
62     virtual bool shouldRubberBandInDirection(ScrollDirection) = 0;
63
64     virtual void immediateScrollBy(const FloatSize&) = 0;
65     virtual void immediateScrollByWithoutContentEdgeConstraints(const FloatSize&) = 0;
66     virtual void startSnapRubberbandTimer()
67     {
68         // Override to perform client-specific snap start logic
69     }
70
71     virtual void stopSnapRubberbandTimer()
72     {
73         // Override to perform client-specific snap end logic
74     }
75     
76     // If the current scroll position is within the overhang area, this function will cause
77     // the page to scroll to the nearest boundary point.
78     virtual void adjustScrollPositionToBoundsIfNecessary() = 0;
79 #endif
80
81     virtual void deferTestsForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const { /* Do nothing */ }
82     virtual void removeTestDeferralForReason(WheelEventTestTrigger::ScrollableAreaIdentifier, WheelEventTestTrigger::DeferTestTriggerReason) const { /* Do nothing */ }
83
84 #if ENABLE(CSS_SCROLL_SNAP)
85     virtual FloatPoint scrollOffset() const = 0;
86     virtual void immediateScrollOnAxis(ScrollEventAxis, float delta) = 0;
87     virtual void startScrollSnapTimer()
88     {
89         // Override to perform client-specific scroll snap point start logic
90     }
91
92     virtual void stopScrollSnapTimer()
93     {
94         // Override to perform client-specific scroll snap point end logic
95     }
96
97     virtual float pageScaleFactor() const
98     {
99         return 1.0f;
100     }
101
102     virtual unsigned activeScrollOffsetIndex(ScrollEventAxis) const
103     {
104         return 0;
105     }
106
107     virtual LayoutSize scrollExtent() const = 0;
108     virtual FloatSize viewportSize() const = 0;
109 #endif
110 };
111
112 enum class WheelEventStatus {
113     UserScrollBegin,
114     UserScrolling,
115     UserScrollEnd,
116     InertialScrollBegin,
117     InertialScrolling,
118     InertialScrollEnd,
119     StatelessScrollEvent,
120     Unknown
121 };
122
123 class ScrollController {
124     WTF_MAKE_NONCOPYABLE(ScrollController);
125
126 public:
127     explicit ScrollController(ScrollControllerClient&);
128
129 #if PLATFORM(MAC)
130     bool handleWheelEvent(const PlatformWheelEvent&);
131 #endif
132
133     bool isRubberBandInProgress() const;
134     bool isScrollSnapInProgress() const;
135
136 #if ENABLE(CSS_SCROLL_SNAP)
137     void updateScrollSnapPoints(ScrollEventAxis, const Vector<LayoutUnit>&, const Vector<ScrollOffsetRange<LayoutUnit>>&);
138     void setActiveScrollSnapIndexForAxis(ScrollEventAxis, unsigned);
139     void setActiveScrollSnapIndicesForOffset(int x, int y);
140     bool activeScrollSnapIndexDidChange() const { return m_activeScrollSnapIndexDidChange; }
141     void setScrollSnapIndexDidChange(bool state) { m_activeScrollSnapIndexDidChange = state; }
142     unsigned activeScrollSnapIndexForAxis(ScrollEventAxis) const;
143     void updateScrollSnapState(const ScrollableArea&);
144 #if PLATFORM(MAC)
145     bool processWheelEventForScrollSnap(const PlatformWheelEvent&);
146 #endif
147 #endif
148
149 private:
150 #if ENABLE(RUBBER_BANDING)
151     void startSnapRubberbandTimer();
152     void stopSnapRubberbandTimer();
153     void snapRubberBand();
154     void snapRubberBandTimerFired();
155
156     bool shouldRubberBandInHorizontalDirection(const PlatformWheelEvent&);
157 #endif
158
159 #if ENABLE(CSS_SCROLL_SNAP)
160     void setNearestScrollSnapIndexForAxisAndOffset(ScrollEventAxis, int);
161 #if PLATFORM(MAC)
162     void scrollSnapTimerFired();
163     void startScrollSnapTimer();
164     void stopScrollSnapTimer();
165
166     bool shouldOverrideInertialScrolling() const;
167     void statelessSnapTransitionTimerFired();
168     void startDeferringTestsDueToScrollSnapping();
169     void stopDeferringTestsDueToScrollSnapping();
170     void scheduleStatelessScrollSnap();
171 #endif
172 #endif
173
174     ScrollControllerClient& m_client;
175
176 #if PLATFORM(MAC)
177     CFTimeInterval m_lastMomentumScrollTimestamp { 0 };
178 #endif
179     FloatSize m_overflowScrollDelta;
180     FloatSize m_stretchScrollForce;
181     FloatSize m_momentumVelocity;
182
183 #if ENABLE(RUBBER_BANDING)
184     // Rubber band state.
185     CFTimeInterval m_startTime { 0 };
186     FloatSize m_startStretch;
187     FloatSize m_origVelocity;
188     RunLoop::Timer<ScrollController> m_snapRubberbandTimer;
189 #endif
190
191 #if ENABLE(CSS_SCROLL_SNAP)
192     std::unique_ptr<ScrollSnapAnimatorState> m_scrollSnapState;
193 #if PLATFORM(MAC)
194     FloatSize m_dragEndedScrollingVelocity;
195     RunLoop::Timer<ScrollController> m_statelessSnapTransitionTimer;
196     RunLoop::Timer<ScrollController> m_scrollSnapTimer;
197 #endif
198 #endif
199
200 #if PLATFORM(MAC)
201     bool m_inScrollGesture { false };
202     bool m_momentumScrollInProgress { false };
203     bool m_ignoreMomentumScrolls { false };
204     bool m_snapRubberbandTimerIsActive { false };
205 #endif
206
207     bool m_activeScrollSnapIndexDidChange { false };
208 };
209     
210 } // namespace WebCore
211
212 #endif // ENABLE(RUBBER_BANDING)
213
214 #endif // ScrollController_h