1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QPointer>
5#include <QObject>
6#include <QtCore/qmath.h>
7
8#include "qscrollerproperties.h"
9#include "private/qscrollerproperties_p.h"
10
11QT_BEGIN_NAMESPACE
12
13QT_IMPL_METATYPE_EXTERN_TAGGED(QScrollerProperties::OvershootPolicy,
14 QScrollerProperties__OvershootPolicy)
15QT_IMPL_METATYPE_EXTERN_TAGGED(QScrollerProperties::FrameRates,
16 QScrollerProperties__FrameRates)
17
18static QScrollerPropertiesPrivate *userDefaults = nullptr;
19static QScrollerPropertiesPrivate *systemDefaults = nullptr;
20
21QScrollerPropertiesPrivate *QScrollerPropertiesPrivate::defaults()
22{
23 if (!systemDefaults) {
24 QScrollerPropertiesPrivate spp;
25 spp.mousePressEventDelay = qreal(0.25);
26 spp.dragStartDistance = qreal(5.0 / 1000);
27 spp.dragVelocitySmoothingFactor = qreal(0.8);
28 spp.axisLockThreshold = qreal(0);
29 spp.scrollingCurve.setType(QEasingCurve::OutQuad);
30 spp.decelerationFactor = qreal(0.125);
31 spp.minimumVelocity = qreal(50.0 / 1000);
32 spp.maximumVelocity = qreal(500.0 / 1000);
33 spp.maximumClickThroughVelocity = qreal(66.5 / 1000);
34 spp.acceleratingFlickMaximumTime = qreal(1.25);
35 spp.acceleratingFlickSpeedupFactor = qreal(3.0);
36 spp.snapPositionRatio = qreal(0.5);
37 spp.snapTime = qreal(0.3);
38 spp.overshootDragResistanceFactor = qreal(0.5);
39 spp.overshootDragDistanceFactor = qreal(1);
40 spp.overshootScrollDistanceFactor = qreal(0.5);
41 spp.overshootScrollTime = qreal(0.7);
42 spp.hOvershootPolicy = QScrollerProperties::OvershootWhenScrollable;
43 spp.vOvershootPolicy = QScrollerProperties::OvershootWhenScrollable;
44 spp.frameRate = QScrollerProperties::Standard;
45
46 systemDefaults = new QScrollerPropertiesPrivate(spp);
47 }
48 return new QScrollerPropertiesPrivate(userDefaults ? *userDefaults : *systemDefaults);
49}
50
51/*!
52 \class QScrollerProperties
53 \brief The QScrollerProperties class stores the settings for a QScroller.
54 \since 4.8
55
56 \inmodule QtWidgets
57
58 The QScrollerProperties class stores the parameters used by QScroller.
59
60 The default settings are platform dependent so that Qt emulates the
61 platform behaviour for kinetic scrolling.
62
63 As a convention the QScrollerProperties are in physical units (meter,
64 seconds) and are converted by QScroller using the current DPI.
65
66 \sa QScroller
67*/
68
69/*!
70 Constructs new scroller properties.
71*/
72QScrollerProperties::QScrollerProperties()
73 : d(QScrollerPropertiesPrivate::defaults())
74{
75}
76
77/*!
78 Constructs a copy of \a sp.
79*/
80QScrollerProperties::QScrollerProperties(const QScrollerProperties &sp)
81 : d(new QScrollerPropertiesPrivate(*sp.d))
82{
83}
84
85/*!
86 Assigns \a sp to these scroller properties and returns a reference to these scroller properties.
87*/
88QScrollerProperties &QScrollerProperties::operator=(const QScrollerProperties &sp)
89{
90 *d.data() = *sp.d.data();
91 return *this;
92}
93
94/*!
95 Destroys the scroller properties.
96*/
97QScrollerProperties::~QScrollerProperties()
98{
99}
100
101/*!
102 Returns \c true if these scroller properties are equal to \a sp; otherwise returns \c false.
103*/
104bool QScrollerProperties::operator==(const QScrollerProperties &sp) const
105{
106 return *d.data() == *sp.d.data();
107}
108
109/*!
110 Returns \c true if these scroller properties are different from \a sp; otherwise returns \c false.
111*/
112bool QScrollerProperties::operator!=(const QScrollerProperties &sp) const
113{
114 return !(*d.data() == *sp.d.data());
115}
116
117bool QScrollerPropertiesPrivate::operator==(const QScrollerPropertiesPrivate &p) const
118{
119 bool same = true;
120 same &= (mousePressEventDelay == p.mousePressEventDelay);
121 same &= (dragStartDistance == p.dragStartDistance);
122 same &= (dragVelocitySmoothingFactor == p.dragVelocitySmoothingFactor);
123 same &= (axisLockThreshold == p.axisLockThreshold);
124 same &= (scrollingCurve == p.scrollingCurve);
125 same &= (decelerationFactor == p.decelerationFactor);
126 same &= (minimumVelocity == p.minimumVelocity);
127 same &= (maximumVelocity == p.maximumVelocity);
128 same &= (maximumClickThroughVelocity == p.maximumClickThroughVelocity);
129 same &= (acceleratingFlickMaximumTime == p.acceleratingFlickMaximumTime);
130 same &= (acceleratingFlickSpeedupFactor == p.acceleratingFlickSpeedupFactor);
131 same &= (snapPositionRatio == p.snapPositionRatio);
132 same &= (snapTime == p.snapTime);
133 same &= (overshootDragResistanceFactor == p.overshootDragResistanceFactor);
134 same &= (overshootDragDistanceFactor == p.overshootDragDistanceFactor);
135 same &= (overshootScrollDistanceFactor == p.overshootScrollDistanceFactor);
136 same &= (overshootScrollTime == p.overshootScrollTime);
137 same &= (hOvershootPolicy == p.hOvershootPolicy);
138 same &= (vOvershootPolicy == p.vOvershootPolicy);
139 same &= (frameRate == p.frameRate);
140 return same;
141}
142
143/*!
144 Sets the scroller properties for all new QScrollerProperties objects to \a sp.
145
146 Use this function to override the platform default properties returned by the default
147 constructor. If you only want to change the scroller properties of a single scroller, use
148 QScroller::setScrollerProperties()
149
150 \note Calling this function will not change the content of already existing
151 QScrollerProperties objects.
152
153 \sa unsetDefaultScrollerProperties()
154*/
155void QScrollerProperties::setDefaultScrollerProperties(const QScrollerProperties &sp)
156{
157 if (!userDefaults)
158 userDefaults = new QScrollerPropertiesPrivate(*sp.d);
159 else
160 *userDefaults = *sp.d;
161}
162
163/*!
164 Sets the scroller properties returned by the default constructor back to the platform default
165 properties.
166
167 \sa setDefaultScrollerProperties()
168*/
169void QScrollerProperties::unsetDefaultScrollerProperties()
170{
171 delete userDefaults;
172 userDefaults = nullptr;
173}
174
175/*!
176 Query the \a metric value of the scroller properties.
177
178 \sa setScrollMetric(), ScrollMetric
179*/
180QVariant QScrollerProperties::scrollMetric(ScrollMetric metric) const
181{
182 switch (metric) {
183 case MousePressEventDelay: return d->mousePressEventDelay;
184 case DragStartDistance: return d->dragStartDistance;
185 case DragVelocitySmoothingFactor: return d->dragVelocitySmoothingFactor;
186 case AxisLockThreshold: return d->axisLockThreshold;
187 case ScrollingCurve: return d->scrollingCurve;
188 case DecelerationFactor: return d->decelerationFactor;
189 case MinimumVelocity: return d->minimumVelocity;
190 case MaximumVelocity: return d->maximumVelocity;
191 case MaximumClickThroughVelocity: return d->maximumClickThroughVelocity;
192 case AcceleratingFlickMaximumTime: return d->acceleratingFlickMaximumTime;
193 case AcceleratingFlickSpeedupFactor:return d->acceleratingFlickSpeedupFactor;
194 case SnapPositionRatio: return d->snapPositionRatio;
195 case SnapTime: return d->snapTime;
196 case OvershootDragResistanceFactor: return d->overshootDragResistanceFactor;
197 case OvershootDragDistanceFactor: return d->overshootDragDistanceFactor;
198 case OvershootScrollDistanceFactor: return d->overshootScrollDistanceFactor;
199 case OvershootScrollTime: return d->overshootScrollTime;
200 case HorizontalOvershootPolicy: return QVariant::fromValue(value: d->hOvershootPolicy);
201 case VerticalOvershootPolicy: return QVariant::fromValue(value: d->vOvershootPolicy);
202 case FrameRate: return QVariant::fromValue(value: d->frameRate);
203 case ScrollMetricCount: break;
204 }
205 return QVariant();
206}
207
208/*!
209 Set a specific value of the \a metric ScrollerMetric to \a value.
210
211 \sa scrollMetric(), ScrollMetric
212*/
213void QScrollerProperties::setScrollMetric(ScrollMetric metric, const QVariant &value)
214{
215 switch (metric) {
216 case MousePressEventDelay: d->mousePressEventDelay = value.toReal(); break;
217 case DragStartDistance: d->dragStartDistance = value.toReal(); break;
218 case DragVelocitySmoothingFactor: d->dragVelocitySmoothingFactor = qBound(min: qreal(0), val: value.toReal(), max: qreal(1)); break;
219 case AxisLockThreshold: d->axisLockThreshold = qBound(min: qreal(0), val: value.toReal(), max: qreal(1)); break;
220 case ScrollingCurve: d->scrollingCurve = value.toEasingCurve(); break;
221 case DecelerationFactor: d->decelerationFactor = value.toReal(); break;
222 case MinimumVelocity: d->minimumVelocity = value.toReal(); break;
223 case MaximumVelocity: d->maximumVelocity = value.toReal(); break;
224 case MaximumClickThroughVelocity: d->maximumClickThroughVelocity = value.toReal(); break;
225 case AcceleratingFlickMaximumTime: d->acceleratingFlickMaximumTime = value.toReal(); break;
226 case AcceleratingFlickSpeedupFactor:d->acceleratingFlickSpeedupFactor = value.toReal(); break;
227 case SnapPositionRatio: d->snapPositionRatio = qBound(min: qreal(0), val: value.toReal(), max: qreal(1)); break;
228 case SnapTime: d->snapTime = value.toReal(); break;
229 case OvershootDragResistanceFactor: d->overshootDragResistanceFactor = value.toReal(); break;
230 case OvershootDragDistanceFactor: d->overshootDragDistanceFactor = qBound(min: qreal(0), val: value.toReal(), max: qreal(1)); break;
231 case OvershootScrollDistanceFactor: d->overshootScrollDistanceFactor = qBound(min: qreal(0), val: value.toReal(), max: qreal(1)); break;
232 case OvershootScrollTime: d->overshootScrollTime = value.toReal(); break;
233 case HorizontalOvershootPolicy: d->hOvershootPolicy = qvariant_cast<QScrollerProperties::OvershootPolicy>(v: value); break;
234 case VerticalOvershootPolicy: d->vOvershootPolicy = qvariant_cast<QScrollerProperties::OvershootPolicy>(v: value); break;
235 case FrameRate: d->frameRate = qvariant_cast<QScrollerProperties::FrameRates>(v: value); break;
236 case ScrollMetricCount: break;
237 }
238}
239
240/*!
241 \enum QScrollerProperties::FrameRates
242
243 This enum describes the available frame rates used while dragging or scrolling.
244
245 \value Fps60 60 frames per second
246 \value Fps30 30 frames per second
247 \value Fps20 20 frames per second
248 \value Standard the default value is 60 frames per second (which corresponds to QAbstractAnimation).
249*/
250
251/*!
252 \enum QScrollerProperties::OvershootPolicy
253
254 This enum describes the various modes of overshooting.
255
256 \value OvershootWhenScrollable Overshooting is possible when the content is scrollable. This is the
257 default.
258
259 \value OvershootAlwaysOff Overshooting is never enabled, even when the content is scrollable.
260
261 \value OvershootAlwaysOn Overshooting is always enabled, even when the content is not
262 scrollable.
263*/
264
265/*!
266 \enum QScrollerProperties::ScrollMetric
267
268 This enum contains the different scroll metric types. When not indicated otherwise the
269 setScrollMetric function expects a QVariant of type qreal.
270
271 See the QScroller documentation for further details of the concepts behind the different
272 values.
273
274 \value MousePressEventDelay This is the time a mouse press event is delayed when starting
275 a flick gesture in \c{[s]}. If the gesture is triggered within that time, no mouse press or
276 release is sent to the scrolled object. If it triggers after that delay the delayed
277 mouse press plus a faked release event at global position \c{QPoint(-QWIDGETSIZE_MAX,
278 -QWIDGETSIZE_MAX)} is sent. If the gesture is canceled, then both the delayed mouse
279 press plus the real release event are delivered.
280
281 \value DragStartDistance This is the minimum distance the touch or mouse point needs to be
282 moved before the flick gesture is triggered in \c m.
283
284 \value DragVelocitySmoothingFactor A value that describes to which extent new drag velocities are
285 included in the final scrolling velocity. This value should be in the range between \c 0 and
286 \c 1. The lower the value, the more smoothing is applied to the dragging velocity.
287
288 \value AxisLockThreshold Restricts the movement to one axis if the movement is inside an angle
289 around the axis. The threshold must be in the range \c 0 to \c 1.
290
291 \value ScrollingCurve The QEasingCurve used when decelerating the scrolling velocity after an
292 user initiated flick. Please note that this is the easing curve for the positions, \b{not}
293 the velocity: the default is QEasingCurve::OutQuad, which results in a linear decrease in
294 velocity (1st derivative) and a constant deceleration (2nd derivative).
295
296 \value DecelerationFactor This factor influences how long it takes the scroller to decelerate
297 to 0 velocity. The actual value depends on the chosen ScrollingCurve. For most
298 types the value should be in the range from \c 0.1 to \c 2.0
299
300 \value MinimumVelocity The minimum velocity that is needed after ending the touch or releasing
301 the mouse to start scrolling in \c{m/s}.
302
303 \value MaximumVelocity This is the maximum velocity that can be reached in \c{m/s}.
304
305 \value MaximumClickThroughVelocity This is the maximum allowed scroll speed for a click-through
306 in \c{m/s}. This means that a click on a currently (slowly) scrolling object will not only stop
307 the scrolling but the click event will also be delivered to the UI control. This is
308 useful when using exponential-type scrolling curves.
309
310 \value AcceleratingFlickMaximumTime This is the maximum time in \c seconds that a flick gesture
311 can take to be recognized as an accelerating flick. If set to zero no such gesture is
312 detected. An "accelerating flick" is a flick gesture executed on an already scrolling object.
313 In such cases the scrolling speed is multiplied by AcceleratingFlickSpeedupFactor in order to
314 accelerate it.
315
316 \value AcceleratingFlickSpeedupFactor The current speed is multiplied by this number if an
317 accelerating flick is detected. Should be \c{>= 1}.
318
319 \value SnapPositionRatio This is the distance that the user must drag the area between two snap
320 points in order to snap it to the next position. \c{0.33} means that the scroll must only
321 reach one third of the distance between two snap points to snap to the next one. The ratio must
322 be between \c 0 and \c 1.
323
324 \value SnapTime This is the time factor for the scrolling curve. A lower value means that the
325 scrolling will take longer. The scrolling distance is independent of this value.
326
327 \value OvershootDragResistanceFactor This value is the factor between the mouse dragging and
328 the actual scroll area movement (during overshoot). The factor must be between \c 0 and \c 1.
329
330 \value OvershootDragDistanceFactor This is the maximum distance for overshoot movements while
331 dragging. The actual overshoot distance is calculated by multiplying this value with the
332 viewport size of the scrolled object. The factor must be between \c 0 and \c 1.
333
334 \value OvershootScrollDistanceFactor This is the maximum distance for overshoot movements while
335 scrolling. The actual overshoot distance is calculated by multiplying this value with the
336 viewport size of the scrolled object. The factor must be between \c 0 and \c 1.
337
338 \value OvershootScrollTime This is the time in \c seconds that is used to play the
339 complete overshoot animation.
340
341 \value HorizontalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy).
342
343 \value VerticalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy).
344
345 \value FrameRate This is the frame rate which should be used while dragging or scrolling.
346 QScroller uses a QAbstractAnimation timer internally to sync all scrolling operations to other
347 animations that might be active at the same time. If the standard value of 60 frames per
348 second is too fast, it can be lowered with this setting,
349 while still being in-sync with QAbstractAnimation. Please note that only the values of the
350 FrameRates enum are allowed here.
351
352 \value ScrollMetricCount This is always the last entry.
353*/
354
355QT_END_NAMESPACE
356

source code of qtbase/src/widgets/util/qscrollerproperties.cpp