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#ifndef QSCROLLER_P_H
5#define QSCROLLER_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtWidgets/private/qtwidgetsglobal_p.h>
19#include <QObject>
20#include <QPointer>
21#include <QQueue>
22#include <QSet>
23#include <QEasingCurve>
24#include <QElapsedTimer>
25#include <QSizeF>
26#include <QPointF>
27#include <QRectF>
28#include <qscroller.h>
29#include <qscrollerproperties.h>
30#include <private/qscrollerproperties_p.h>
31#if QT_CONFIG(animation)
32#include <QAbstractAnimation>
33#endif
34
35QT_BEGIN_NAMESPACE
36
37#ifndef QT_NO_GESTURES
38class QFlickGestureRecognizer;
39#endif
40
41#if QT_CONFIG(animation)
42class QScrollTimer;
43#endif
44class QScrollerPrivate : public QObject
45{
46 Q_OBJECT
47 Q_DECLARE_PUBLIC(QScroller)
48
49public:
50 QScrollerPrivate(QScroller *q, QObject *target);
51 void init();
52
53 void sendEvent(QObject *o, QEvent *e);
54
55 void setState(QScroller::State s);
56
57 enum ScrollType {
58 ScrollTypeFlick = 0,
59 ScrollTypeScrollTo,
60 ScrollTypeOvershoot
61 };
62
63 struct ScrollSegment {
64 qint64 startTime;
65 qint64 deltaTime;
66 qreal startPos;
67 qreal deltaPos;
68 QEasingCurve curve;
69 qreal stopProgress; // whatever is..
70 qreal stopPos; // ..reached first
71 ScrollType type;
72 };
73
74 bool pressWhileInactive(const QPointF &position, qint64 timestamp);
75 bool moveWhilePressed(const QPointF &position, qint64 timestamp);
76 bool releaseWhilePressed(const QPointF &position, qint64 timestamp);
77 bool moveWhileDragging(const QPointF &position, qint64 timestamp);
78 bool releaseWhileDragging(const QPointF &position, qint64 timestamp);
79 bool pressWhileScrolling(const QPointF &position, qint64 timestamp);
80
81 void timerTick();
82 void timerEventWhileDragging();
83 void timerEventWhileScrolling();
84
85 bool prepareScrolling(const QPointF &position);
86 void handleDrag(const QPointF &position, qint64 timestamp);
87
88 QPointF dpi() const;
89 void setDpi(const QPointF &dpi);
90 void setDpiFromWidget(QWidget *widget);
91
92 void updateVelocity(const QPointF &deltaPixelRaw, qint64 deltaTime);
93 void pushSegment(ScrollType type, qreal deltaTime, qreal stopProgress, qreal startPos, qreal deltaPos, qreal stopPos, QEasingCurve::Type curve, Qt::Orientation orientation);
94 void recalcScrollingSegments(bool forceRecalc = false);
95 qreal scrollingSegmentsEndPos(Qt::Orientation orientation) const;
96 bool scrollingSegmentsValid(Qt::Orientation orientation) const;
97 void createScrollToSegments(qreal v, qreal deltaTime, qreal endPos, Qt::Orientation orientation, ScrollType type);
98 void createScrollingSegments(qreal v, qreal startPos,
99 qreal deltaTime, qreal deltaPos,
100 Qt::Orientation orientation);
101 void createScrollingSegments(const QPointF &v, const QPointF &startPos, const QPointF &ppm);
102
103 void setContentPositionHelperDragging(const QPointF &deltaPos);
104 void setContentPositionHelperScrolling();
105
106 qreal nextSnapPos(qreal p, int dir, Qt::Orientation orientation) const;
107 static qreal nextSegmentPosition(QQueue<ScrollSegment> &segments, qint64 now, qreal oldPos);
108
109 inline int frameRateSkip() const { return properties.d.data()->frameRate; }
110
111 static const char *stateName(QScroller::State state);
112 static const char *inputName(QScroller::Input input);
113
114public slots:
115 void targetDestroyed();
116
117public:
118 // non static
119 QObject *target;
120 QScrollerProperties properties;
121#ifndef QT_NO_GESTURES
122 QFlickGestureRecognizer *recognizer;
123 Qt::GestureType recognizerType;
124#endif
125
126 // scroller state:
127
128 // QPointer<QObject> scrollTarget;
129 QSizeF viewportSize;
130 QRectF contentPosRange;
131 QPointF contentPosition;
132 QPointF overshootPosition; // the number of pixels we are overshooting (before overshootDragResistanceFactor)
133
134 // state
135
136 bool enabled;
137 QScroller::State state;
138 bool firstScroll; // true if we haven't already send a scroll event
139
140 QPointF oldVelocity; // the release velocity of the last drag
141
142 QPointF pressPosition;
143 QPointF lastPosition;
144 qint64 pressTimestamp;
145 qint64 lastTimestamp;
146
147 QPointF dragDistance; // the distance we should move during the next drag timer event
148
149 QQueue<ScrollSegment> xSegments;
150 QQueue<ScrollSegment> ySegments;
151
152 // snap positions
153 QList<qreal> snapPositionsX;
154 qreal snapFirstX;
155 qreal snapIntervalX;
156 QList<qreal> snapPositionsY;
157 qreal snapFirstY;
158 qreal snapIntervalY;
159
160 QPointF pixelPerMeter;
161
162 QElapsedTimer monotonicTimer;
163
164 QPointF releaseVelocity; // the starting velocity of the scrolling state
165#if QT_CONFIG(animation)
166 QScrollTimer *scrollTimer;
167#endif
168
169 QScroller *q_ptr;
170};
171template <>
172class QTypeInfo<QScrollerPrivate::ScrollSegment>
173 : public QTypeInfoMerger<QScrollerPrivate::ScrollSegment, QEasingCurve> {};
174
175
176QT_END_NAMESPACE
177
178#endif // QSCROLLER_P_H
179
180

source code of qtbase/src/widgets/util/qscroller_p.h