1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Quick Controls module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qquickwheelarea_p.h"
41
42QT_BEGIN_NAMESPACE
43
44// On Mac OS X, the scrolling speed in Safari is roughly 2.5 times faster
45// than in TextEdit (the native app). The former is using high-resolution
46// pixel-based delta values as they are, which is fine for a typical web
47// content, whereas the latter evidently makes scrolling slower to make it
48// feel natural and more precise for typical document type of content.
49// => we'll compromise between the two for now, and pick an arbitrary value
50// to make the pixel-based scrolling speed something between the two
51static const qreal pixelDeltaAdjustment = 0.5;
52
53// The default scroll speed for typical angle-based mouse wheels. The value
54// comes originally from QTextEdit, which sets 20px steps by default.
55static const qreal defaultScrollSpeed = 20.0;
56
57QQuickWheelArea1::QQuickWheelArea1(QQuickItem *parent)
58 : QQuickItem(parent),
59 m_horizontalMinimumValue(0),
60 m_horizontalMaximumValue(0),
61 m_verticalMinimumValue(0),
62 m_verticalMaximumValue(0),
63 m_horizontalValue(0),
64 m_verticalValue(0),
65 m_verticalDelta(0),
66 m_horizontalDelta(0),
67 m_scrollSpeed(defaultScrollSpeed),
68 m_active(false)
69{
70
71}
72
73QQuickWheelArea1::~QQuickWheelArea1()
74{
75
76}
77
78bool QQuickWheelArea1::isAtXEnd() const
79{
80 return qFuzzyCompare(p1: m_horizontalMaximumValue, p2: m_horizontalValue);
81}
82
83bool QQuickWheelArea1::isAtXBeginning() const
84{
85 return qFuzzyCompare(p1: m_horizontalMinimumValue, p2: m_horizontalValue);
86}
87
88bool QQuickWheelArea1::isAtYEnd() const
89{
90 return qFuzzyCompare(p1: m_verticalMaximumValue, p2: m_verticalValue);
91}
92
93bool QQuickWheelArea1::isAtYBeginning() const
94{
95 return qFuzzyCompare(p1: m_verticalMinimumValue, p2: m_verticalValue);
96}
97
98bool QQuickWheelArea1::isInverted() const
99{
100 return m_inverted;
101}
102
103#ifndef QT_NO_WHEELEVENT
104void QQuickWheelArea1::wheelEvent(QWheelEvent *we)
105{
106 if (we->phase() == Qt::ScrollBegin)
107 setActive(true);
108 else if (we->phase() == Qt::ScrollEnd)
109 setActive(false);
110
111 QPoint numPixels = we->pixelDelta();
112 QPoint numDegrees = we->angleDelta() / 8;
113
114 m_inverted = we->inverted();
115
116 if (!numPixels.isNull()) {
117 setHorizontalDelta(numPixels.x() * pixelDeltaAdjustment);
118 setVerticalDelta(numPixels.y() * pixelDeltaAdjustment);
119 } else if (!numDegrees.isNull()) {
120 setHorizontalDelta(numDegrees.x() / 15.0 * m_scrollSpeed);
121 setVerticalDelta(numDegrees.y() / 15.0 * m_scrollSpeed);
122 }
123
124 // This allows other parent WheelArea's to handle scrolling
125 // For example this allows for ScrollView inside of another ScrollView to work correctly
126 // Once this scrollbar can't scroll anymore, ie it reaches the limits,
127 // it will ignore the scroll event so the parent WheelArea can start scrolling
128 if ((numPixels.x() != 0 || numDegrees.x() != 0) &&
129 m_horizontalMinimumValue <= m_horizontalMaximumValue &&
130 (isAtXBeginning() || isAtXEnd())) {
131 we->ignore();
132 } else if ((numPixels.y() != 0 || numDegrees.y() != 0) &&
133 m_verticalMinimumValue <= m_verticalMaximumValue &&
134 (isAtYBeginning() || isAtYEnd())) {
135 we->ignore();
136 } else {
137 we->accept();
138 }
139}
140#endif
141
142void QQuickWheelArea1::setHorizontalMinimumValue(qreal value)
143{
144 if (value == m_horizontalMinimumValue)
145 return;
146
147 m_horizontalMinimumValue = value;
148 emit horizontalMinimumValueChanged();
149}
150
151qreal QQuickWheelArea1::horizontalMinimumValue() const
152{
153 return m_horizontalMinimumValue;
154}
155
156void QQuickWheelArea1::setHorizontalMaximumValue(qreal value)
157{
158 if (value == m_horizontalMaximumValue)
159 return;
160
161 m_horizontalMaximumValue = value;
162 emit horizontalMaximumValueChanged();
163}
164
165qreal QQuickWheelArea1::horizontalMaximumValue() const
166{
167 return m_horizontalMaximumValue;
168}
169
170void QQuickWheelArea1::setVerticalMinimumValue(qreal value)
171{
172 if (value == m_verticalMinimumValue)
173 return;
174
175 m_verticalMinimumValue = value;
176 emit verticalMinimumValueChanged();
177}
178
179qreal QQuickWheelArea1::verticalMinimumValue() const
180{
181 return m_verticalMinimumValue;
182}
183
184void QQuickWheelArea1::setVerticalMaximumValue(qreal value)
185{
186 if (value == m_verticalMaximumValue)
187 return;
188
189 m_verticalMaximumValue = value;
190 emit verticalMaximumValueChanged();
191}
192
193qreal QQuickWheelArea1::verticalMaximumValue() const
194{
195 return m_verticalMaximumValue;
196}
197
198void QQuickWheelArea1::setHorizontalValue(qreal value)
199{
200 value = qBound<qreal>(min: m_horizontalMinimumValue, val: value, max: m_horizontalMaximumValue);
201
202 if (value != m_horizontalValue) {
203 m_horizontalValue = value;
204 emit horizontalValueChanged();
205 }
206}
207
208qreal QQuickWheelArea1::horizontalValue() const
209{
210 return m_horizontalValue;
211}
212
213void QQuickWheelArea1::setVerticalValue(qreal value)
214{
215 value = qBound<qreal>(min: m_verticalMinimumValue, val: value, max: m_verticalMaximumValue);
216
217 if (value != m_verticalValue) {
218 m_verticalValue = value;
219 emit verticalValueChanged();
220 }
221}
222
223qreal QQuickWheelArea1::verticalValue() const
224{
225 return m_verticalValue;
226}
227
228void QQuickWheelArea1::setVerticalDelta(qreal value)
229{
230 m_verticalDelta = value;
231 setVerticalValue(m_verticalValue - m_verticalDelta);
232
233 emit verticalWheelMoved();
234}
235
236qreal QQuickWheelArea1::verticalDelta() const
237{
238 return m_verticalDelta;
239}
240
241void QQuickWheelArea1::setHorizontalDelta(qreal value)
242{
243 m_horizontalDelta = value;
244 setHorizontalValue(m_horizontalValue - m_horizontalDelta);
245
246 emit horizontalWheelMoved();
247}
248
249qreal QQuickWheelArea1::horizontalDelta() const
250{
251 return m_horizontalDelta;
252}
253
254void QQuickWheelArea1::setScrollSpeed(qreal value)
255{
256 if (value != m_scrollSpeed) {
257 m_scrollSpeed = value;
258 emit scrollSpeedChanged();
259 }
260}
261
262qreal QQuickWheelArea1::scrollSpeed() const
263{
264 return m_scrollSpeed;
265}
266
267bool QQuickWheelArea1::isActive() const
268{
269 return m_active;
270}
271
272void QQuickWheelArea1::setActive(bool active)
273{
274 if (active != m_active) {
275 m_active = active;
276 emit activeChanged();
277 }
278}
279
280QT_END_NAMESPACE
281

source code of qtquickcontrols/src/controls/Private/qquickwheelarea.cpp