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 | |
35 | QT_BEGIN_NAMESPACE |
36 | |
37 | #ifndef QT_NO_GESTURES |
38 | class QFlickGestureRecognizer; |
39 | #endif |
40 | |
41 | #if QT_CONFIG(animation) |
42 | class QScrollTimer; |
43 | #endif |
44 | class QScrollerPrivate : public QObject |
45 | { |
46 | Q_OBJECT |
47 | Q_DECLARE_PUBLIC(QScroller) |
48 | |
49 | public: |
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 | |
114 | public slots: |
115 | void targetDestroyed(); |
116 | |
117 | public: |
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 | }; |
171 | template <> |
172 | class QTypeInfo<QScrollerPrivate::ScrollSegment> |
173 | : public QTypeInfoMerger<QScrollerPrivate::ScrollSegment, QEasingCurve> {}; |
174 | |
175 | |
176 | QT_END_NAMESPACE |
177 | |
178 | #endif // QSCROLLER_P_H |
179 | |
180 | |