summaryrefslogtreecommitdiff
path: root/src/widgets/util/qscrollerproperties.cpp
blob: b9f73479323ba71bb50830ecc98e6148658268e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QPointer>
#include <QObject>
#include <QtCore/qmath.h>
#ifdef Q_WS_WIN
#  include <QLibrary>
#endif

#include "qscrollerproperties.h"
#include "private/qscrollerproperties_p.h"

QT_BEGIN_NAMESPACE

static QScrollerPropertiesPrivate *userDefaults = 0;
static QScrollerPropertiesPrivate *systemDefaults = 0;

QScrollerPropertiesPrivate *QScrollerPropertiesPrivate::defaults()
{
    if (!systemDefaults) {
        QScrollerPropertiesPrivate spp;
        spp.mousePressEventDelay = qreal(0.25);
        spp.dragStartDistance = qreal(5.0 / 1000);
        spp.dragVelocitySmoothingFactor = qreal(0.8);
        spp.axisLockThreshold = qreal(0);
        spp.scrollingCurve.setType(QEasingCurve::OutQuad);
        spp.decelerationFactor = qreal(0.125);
        spp.minimumVelocity = qreal(50.0 / 1000);
        spp.maximumVelocity = qreal(500.0 / 1000);
        spp.maximumClickThroughVelocity = qreal(66.5 / 1000);
        spp.acceleratingFlickMaximumTime = qreal(1.25);
        spp.acceleratingFlickSpeedupFactor = qreal(3.0);
        spp.snapPositionRatio = qreal(0.5);
        spp.snapTime = qreal(0.3);
        spp.overshootDragResistanceFactor = qreal(0.5);
        spp.overshootDragDistanceFactor = qreal(1);
        spp.overshootScrollDistanceFactor = qreal(0.5);
        spp.overshootScrollTime = qreal(0.7);
#  ifdef Q_WS_WIN
        if (QLibrary::resolve(QLatin1String("UxTheme"), "BeginPanningFeedback"))
            spp.overshootScrollTime = qreal(0.35);
#  endif
        spp.hOvershootPolicy = QScrollerProperties::OvershootWhenScrollable;
        spp.vOvershootPolicy = QScrollerProperties::OvershootWhenScrollable;
        spp.frameRate = QScrollerProperties::Standard;

        systemDefaults = new QScrollerPropertiesPrivate(spp);
    }
    return new QScrollerPropertiesPrivate(userDefaults ? *userDefaults : *systemDefaults);
}

/*!
    \class QScrollerProperties
    \brief The QScrollerProperties class stores the settings for a QScroller.
    \since 4.8

    \inmodule QtWidgets
 
    The QScrollerProperties class stores the parameters used by QScroller.

    The default settings are platform dependent so that Qt emulates the
    platform behaviour for kinetic scrolling.

    As a convention the QScrollerProperties are in physical units (meter,
    seconds) and are converted by QScroller using the current DPI.

    \sa QScroller
*/

/*!
    Constructs new scroller properties.
*/
QScrollerProperties::QScrollerProperties()
    : d(QScrollerPropertiesPrivate::defaults())
{
}

/*!
    Constructs a copy of \a sp.
*/
QScrollerProperties::QScrollerProperties(const QScrollerProperties &sp)
    : d(new QScrollerPropertiesPrivate(*sp.d))
{
}

/*!
    Assigns \a sp to these scroller properties and returns a reference to these scroller properties.
*/
QScrollerProperties &QScrollerProperties::operator=(const QScrollerProperties &sp)
{
    *d.data() = *sp.d.data();
    return *this;
}

/*!
    Destroys the scroller properties.
*/
QScrollerProperties::~QScrollerProperties()
{
}

/*!
    Returns true if these scroller properties are equal to \a sp; otherwise returns false.
*/
bool QScrollerProperties::operator==(const QScrollerProperties &sp) const
{
    return *d.data() == *sp.d.data();
}

/*!
    Returns true if these scroller properties are different from \a sp; otherwise returns false.
*/
bool QScrollerProperties::operator!=(const QScrollerProperties &sp) const
{
    return !(*d.data() == *sp.d.data());
}

bool QScrollerPropertiesPrivate::operator==(const QScrollerPropertiesPrivate &p) const
{
    bool same = true;
    same &= (mousePressEventDelay == p.mousePressEventDelay);
    same &= (dragStartDistance == p.dragStartDistance);
    same &= (dragVelocitySmoothingFactor == p.dragVelocitySmoothingFactor);
    same &= (axisLockThreshold == p.axisLockThreshold);
    same &= (scrollingCurve == p.scrollingCurve);
    same &= (decelerationFactor == p.decelerationFactor);
    same &= (minimumVelocity == p.minimumVelocity);
    same &= (maximumVelocity == p.maximumVelocity);
    same &= (maximumClickThroughVelocity == p.maximumClickThroughVelocity);
    same &= (acceleratingFlickMaximumTime == p.acceleratingFlickMaximumTime);
    same &= (acceleratingFlickSpeedupFactor == p.acceleratingFlickSpeedupFactor);
    same &= (snapPositionRatio == p.snapPositionRatio);
    same &= (snapTime == p.snapTime);
    same &= (overshootDragResistanceFactor == p.overshootDragResistanceFactor);
    same &= (overshootDragDistanceFactor == p.overshootDragDistanceFactor);
    same &= (overshootScrollDistanceFactor == p.overshootScrollDistanceFactor);
    same &= (overshootScrollTime == p.overshootScrollTime);
    same &= (hOvershootPolicy == p.hOvershootPolicy);
    same &= (vOvershootPolicy == p.vOvershootPolicy);
    same &= (frameRate == p.frameRate);
    return same;
}

/*!
     Sets the scroller properties for all new QScrollerProperties objects to \a sp.

     Use this function to override the platform default properties returned by the default
     constructor. If you only want to change the scroller properties of a single scroller, use
     QScroller::setScrollerProperties()

     \note Calling this function will not change the content of already existing
     QScrollerProperties objects.

     \sa unsetDefaultScrollerProperties()
*/
void QScrollerProperties::setDefaultScrollerProperties(const QScrollerProperties &sp)
{
    if (!userDefaults)
        userDefaults = new QScrollerPropertiesPrivate(*sp.d);
    else
        *userDefaults = *sp.d;
}

/*!
     Sets the scroller properties returned by the default constructor back to the platform default
     properties.

     \sa setDefaultScrollerProperties()
*/
void QScrollerProperties::unsetDefaultScrollerProperties()
{
    delete userDefaults;
    userDefaults = 0;
}

/*!
    Query the \a metric value of the scroller properties.

    \sa setScrollMetric(), ScrollMetric
*/
QVariant QScrollerProperties::scrollMetric(ScrollMetric metric) const
{
    switch (metric) {
    case MousePressEventDelay:          return d->mousePressEventDelay;
    case DragStartDistance:             return d->dragStartDistance;
    case DragVelocitySmoothingFactor:   return d->dragVelocitySmoothingFactor;
    case AxisLockThreshold:             return d->axisLockThreshold;
    case ScrollingCurve:                return d->scrollingCurve;
    case DecelerationFactor:            return d->decelerationFactor;
    case MinimumVelocity:               return d->minimumVelocity;
    case MaximumVelocity:               return d->maximumVelocity;
    case MaximumClickThroughVelocity:   return d->maximumClickThroughVelocity;
    case AcceleratingFlickMaximumTime:  return d->acceleratingFlickMaximumTime;
    case AcceleratingFlickSpeedupFactor:return d->acceleratingFlickSpeedupFactor;
    case SnapPositionRatio:             return d->snapPositionRatio;
    case SnapTime:                      return d->snapTime;
    case OvershootDragResistanceFactor: return d->overshootDragResistanceFactor;
    case OvershootDragDistanceFactor:   return d->overshootDragDistanceFactor;
    case OvershootScrollDistanceFactor: return d->overshootScrollDistanceFactor;
    case OvershootScrollTime:           return d->overshootScrollTime;
    case HorizontalOvershootPolicy:     return QVariant::fromValue(d->hOvershootPolicy);
    case VerticalOvershootPolicy:       return QVariant::fromValue(d->vOvershootPolicy);
    case FrameRate:                     return QVariant::fromValue(d->frameRate);
    case ScrollMetricCount:             break;
    }
    return QVariant();
}

/*!
    Set a specific value of the \a metric ScrollerMetric to \a value.

    \sa scrollMetric(), ScrollMetric
*/
void QScrollerProperties::setScrollMetric(ScrollMetric metric, const QVariant &value)
{
    switch (metric) {
    case MousePressEventDelay:          d->mousePressEventDelay = value.toReal(); break;
    case DragStartDistance:             d->dragStartDistance = value.toReal(); break;
    case DragVelocitySmoothingFactor:   d->dragVelocitySmoothingFactor = qBound(qreal(0), value.toReal(), qreal(1)); break;
    case AxisLockThreshold:             d->axisLockThreshold = qBound(qreal(0), value.toReal(), qreal(1)); break;
    case ScrollingCurve:                d->scrollingCurve = value.toEasingCurve(); break;
    case DecelerationFactor:            d->decelerationFactor = value.toReal(); break;
    case MinimumVelocity:               d->minimumVelocity = value.toReal(); break;
    case MaximumVelocity:               d->maximumVelocity = value.toReal(); break;
    case MaximumClickThroughVelocity:   d->maximumClickThroughVelocity = value.toReal(); break;
    case AcceleratingFlickMaximumTime:  d->acceleratingFlickMaximumTime = value.toReal(); break;
    case AcceleratingFlickSpeedupFactor:d->acceleratingFlickSpeedupFactor = value.toReal(); break;
    case SnapPositionRatio:             d->snapPositionRatio = qBound(qreal(0), value.toReal(), qreal(1)); break;
    case SnapTime:                      d->snapTime = value.toReal(); break;
    case OvershootDragResistanceFactor: d->overshootDragResistanceFactor = value.toReal(); break;
    case OvershootDragDistanceFactor:   d->overshootDragDistanceFactor = qBound(qreal(0), value.toReal(), qreal(1)); break;
    case OvershootScrollDistanceFactor: d->overshootScrollDistanceFactor = qBound(qreal(0), value.toReal(), qreal(1)); break;
    case OvershootScrollTime:           d->overshootScrollTime = value.toReal(); break;
    case HorizontalOvershootPolicy:     d->hOvershootPolicy = value.value<QScrollerProperties::OvershootPolicy>(); break;
    case VerticalOvershootPolicy:       d->vOvershootPolicy = value.value<QScrollerProperties::OvershootPolicy>(); break;
    case FrameRate:                     d->frameRate = value.value<QScrollerProperties::FrameRates>(); break;
    case ScrollMetricCount:             break;
    }
}

/*!
    \enum QScrollerProperties::FrameRates

    This enum describes the available frame rates used while dragging or scrolling.

    \value Fps60 60 frames per second
    \value Fps30 30 frames per second
    \value Fps20 20 frames per second
    \value Standard the default value is 60 frames per second (which corresponds to QAbstractAnimation).
*/

/*!
    \enum QScrollerProperties::OvershootPolicy

    This enum describes the various modes of overshooting.

    \value OvershootWhenScrollable Overshooting is possible when the content is scrollable. This is the
                                   default.

    \value OvershootAlwaysOff Overshooting is never enabled, even when the content is scrollable.

    \value OvershootAlwaysOn Overshooting is always enabled, even when the content is not
                             scrollable.
*/

/*!
    \enum QScrollerProperties::ScrollMetric

    This enum contains the different scroll metric types. When not indicated otherwise the
    setScrollMetric function expects a QVariant of type qreal.

    See the QScroller documentation for further details of the concepts behind the different
    values.

    \value MousePressEventDelay This is the time a mouse press event is delayed when starting
    a flick gesture in \c{[s]}. If the gesture is triggered within that time, no mouse press or
    release is sent to the scrolled object. If it triggers after that delay the delayed
    mouse press plus a faked release event at global position \c{QPoint(-QWIDGETSIZE_MAX,
    -QWIDGETSIZE_MAX)} is sent. If the gesture is canceled, then both the delayed mouse
    press plus the real release event are delivered.

    \value DragStartDistance This is the minimum distance the touch or mouse point needs to be
    moved before the flick gesture is triggered in \c m.

    \value DragVelocitySmoothingFactor A value that describes to which extent new drag velocities are
    included in the final scrolling velocity.  This value should be in the range between \c 0 and
    \c 1.  The lower the value, the more smoothing is applied to the dragging velocity.

    \value AxisLockThreshold Restricts the movement to one axis if the movement is inside an angle
    around the axis. The threshold must be in the range \c 0 to \c 1.

    \value ScrollingCurve The QEasingCurve used when decelerating the scrolling velocity after an
    user initiated flick. Please note that this is the easing curve for the positions, \b{not}
    the velocity: the default is QEasingCurve::OutQuad, which results in a linear decrease in
    velocity (1st derivative) and a constant deceleration (2nd derivative).

    \value DecelerationFactor This factor influences how long it takes the scroller to decelerate
    to 0 velocity. The actual value depends on the chosen ScrollingCurve. For most
    types the value should be in the range from \c 0.1 to \c 2.0

    \value MinimumVelocity The minimum velocity that is needed after ending the touch or releasing
    the mouse to start scrolling in \c{m/s}.

    \value MaximumVelocity This is the maximum velocity that can be reached in \c{m/s}.

    \value MaximumClickThroughVelocity This is the maximum allowed scroll speed for a click-through
    in \c{m/s}. This means that a click on a currently (slowly) scrolling object will not only stop
    the scrolling but the click event will also be delivered to the UI control. This is
    useful when using exponential-type scrolling curves.

    \value AcceleratingFlickMaximumTime This is the maximum time in \c seconds that a flick gesture
    can take to be recognized as an accelerating flick. If set to zero no such gesture is
    detected. An "accelerating flick" is a flick gesture executed on an already scrolling object.
    In such cases the scrolling speed is multiplied by AcceleratingFlickSpeedupFactor in order to
    accelerate it.

    \value AcceleratingFlickSpeedupFactor The current speed is multiplied by this number if an
    accelerating flick is detected. Should be \c{>= 1}.

    \value SnapPositionRatio This is the distance that the user must drag the area beween two snap
    points in order to snap it to the next position. \c{0.33} means that the scroll must only
    reach one third of the distance between two snap points to snap to the next one. The ratio must
    be between \c 0 and \c 1.

    \value SnapTime This is the time factor for the scrolling curve. A lower value means that the
    scrolling will take longer. The scrolling distance is independet of this value.

    \value OvershootDragResistanceFactor This value is the factor between the mouse dragging and
    the actual scroll area movement (during overshoot). The factor must be between \c 0 and \c 1.

    \value OvershootDragDistanceFactor This is the maximum distance for overshoot movements while
    dragging. The actual overshoot distance is calculated by multiplying this value with the
    viewport size of the scrolled object. The factor must be between \c 0 and \c 1.

    \value OvershootScrollDistanceFactor This is the maximum distance for overshoot movements while
    scrolling. The actual overshoot distance is calculated by multiplying this value with the
    viewport size of the scrolled object. The factor must be between \c 0 and \c 1.

    \value OvershootScrollTime This is the time in \c seconds that is used to play the
    complete overshoot animation.

    \value HorizontalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy).

    \value VerticalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy).

    \value FrameRate This is the frame rate which should be used while dragging or scrolling.
    QScroller uses a QAbstractAnimation timer internally to sync all scrolling operations to other
    animations that might be active at the same time.  If the standard value of 60 frames per
    second is too fast, it can be lowered with this setting,
    while still being in-sync with QAbstractAnimation. Please note that only the values of the
    FrameRates enum are allowed here.

    \value ScrollMetricCount This is always the last entry.
*/

QT_END_NAMESPACE