229ab216c35d4807c610435ba77ca41c9ab29b02
[WebKit-https.git] / Source / WebCore / page / WheelEventDeltaFilter.cpp
1 /*
2  * Copyright (C) 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 #include "config.h"
27 #include "WheelEventDeltaFilter.h"
28
29 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
30 #include "WheelEventDeltaFilterMac.h"
31 #endif
32
33 #include "FloatSize.h"
34 #include "Logging.h"
35 #include "TextStream.h"
36
37 namespace WebCore {
38     
39 WheelEventDeltaFilter::WheelEventDeltaFilter()
40 {
41 }
42
43 WheelEventDeltaFilter::~WheelEventDeltaFilter()
44 {
45 }
46
47 std::unique_ptr<WheelEventDeltaFilter> WheelEventDeltaFilter::create()
48 {
49 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
50     return std::make_unique<WheelEventDeltaFilterMac>();
51 #else
52     return std::make_unique<BasicWheelEventDeltaFilter>();
53 #endif
54 }
55
56 bool WheelEventDeltaFilter::isFilteringDeltas() const
57 {
58     return m_isFilteringDeltas;
59 }
60
61 FloatSize WheelEventDeltaFilter::filteredDelta() const
62 {
63     LOG_WITH_STREAM(Scrolling, stream << "BasicWheelEventDeltaFilter::filteredDelta returning " << m_currentFilteredDelta);
64     return m_currentFilteredDelta;
65 }
66
67 BasicWheelEventDeltaFilter::BasicWheelEventDeltaFilter()
68     : WheelEventDeltaFilter()
69 {
70 }
71
72 const size_t basicWheelEventDeltaFilterWindowSize = 3;
73
74 void BasicWheelEventDeltaFilter::updateFromDelta(const FloatSize& delta)
75 {
76     m_currentFilteredDelta = delta;
77     if (!m_isFilteringDeltas)
78         return;
79     
80     m_recentWheelEventDeltas.append(delta);
81     if (m_recentWheelEventDeltas.size() > basicWheelEventDeltaFilterWindowSize)
82         m_recentWheelEventDeltas.removeFirst();
83     
84     DominantScrollGestureDirection scrollDirection = dominantScrollGestureDirection();
85     if (scrollDirection == DominantScrollGestureDirection::Vertical)
86         m_currentFilteredDelta.setWidth(0);
87     else if (scrollDirection == DominantScrollGestureDirection::Horizontal)
88         m_currentFilteredDelta.setHeight(0);
89 }
90
91 void BasicWheelEventDeltaFilter::beginFilteringDeltas()
92 {
93     m_recentWheelEventDeltas.clear();
94     m_isFilteringDeltas = true;
95 }
96
97 void BasicWheelEventDeltaFilter::endFilteringDeltas()
98 {
99     m_currentFilteredDelta = FloatSize(0, 0);
100     m_isFilteringDeltas = false;
101 }
102
103 static inline bool deltaIsPredominantlyVertical(const FloatSize& delta)
104 {
105     return fabs(delta.height()) > fabs(delta.width());
106 }
107
108 DominantScrollGestureDirection BasicWheelEventDeltaFilter::dominantScrollGestureDirection() const
109 {
110     bool allVertical = m_recentWheelEventDeltas.size();
111     bool allHorizontal = m_recentWheelEventDeltas.size();
112     
113     for (const auto& delta : m_recentWheelEventDeltas) {
114         bool isVertical = deltaIsPredominantlyVertical(delta);
115         allVertical &= isVertical;
116         allHorizontal &= !isVertical;
117     }
118     
119     if (allVertical)
120         return DominantScrollGestureDirection::Vertical;
121     
122     if (allHorizontal)
123         return DominantScrollGestureDirection::Horizontal;
124     
125     return DominantScrollGestureDirection::None;
126 }
127
128 };