1// Copyright (C) 2019 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 QQUICKFLICKABLE_P_P_H
5#define QQUICKFLICKABLE_P_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 "qquickflickable_p.h"
19#include "qquickitem_p.h"
20#include "qquickitemchangelistener_p.h"
21
22#include <QtQml/qqml.h>
23#include <QtCore/qdatetime.h>
24#include "qplatformdefs.h"
25
26#include <private/qquicktimeline_p_p.h>
27#include <private/qquickanimation_p_p.h>
28#include <private/qquicktransitionmanager_p_p.h>
29#include <private/qpodvector_p.h>
30
31QT_BEGIN_NAMESPACE
32
33class QQuickFlickableVisibleArea;
34class QQuickTransition;
35class QQuickFlickableReboundTransition;
36
37class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
38{
39 Q_DECLARE_PUBLIC(QQuickFlickable)
40
41public:
42 static inline QQuickFlickablePrivate *get(QQuickFlickable *o) { return o->d_func(); }
43
44 QQuickFlickablePrivate();
45 void init();
46
47 struct Velocity : public QQuickTimeLineValue
48 {
49 Velocity(QQuickFlickablePrivate *p)
50 : parent(p) {}
51 void setValue(qreal v) override {
52 if (v != value()) {
53 QQuickTimeLineValue::setValue(v);
54 parent->updateVelocity();
55 }
56 }
57 QQuickFlickablePrivate *parent;
58 };
59
60 enum MovementReason { Other, SetIndex, Mouse };
61
62 struct AxisData {
63 AxisData(QQuickFlickablePrivate *fp, void (QQuickFlickablePrivate::*func)(qreal))
64 : move(fp, func)
65 , transitionToBounds(nullptr)
66 , viewSize(-1), lastPos(0), previousDragDelta(0), velocity(0), startMargin(0), endMargin(0)
67 , origin(0), overshoot(0)
68 , transitionTo(0)
69 , continuousFlickVelocity(0), velocityTime(), vTime(0)
70 , smoothVelocity(fp), atEnd(false), atBeginning(true)
71 , transitionToSet(false)
72 , fixingUp(false), inOvershoot(false), inRebound(false), moving(false), flicking(false)
73 , flickingWhenDragBegan(false), dragging(false), extentsChanged(false)
74 , explicitValue(false), minExtentDirty(true), maxExtentDirty(true)
75 , contentPositionChangedExternallyDuringDrag(false)
76 , unused(0)
77 {}
78
79 ~AxisData();
80
81 void reset() {
82 velocityBuffer.clear();
83 dragStartOffset = 0;
84 fixingUp = false;
85 inOvershoot = false;
86 contentPositionChangedExternallyDuringDrag = false;
87 }
88
89 void markExtentsDirty() {
90 minExtentDirty = true;
91 maxExtentDirty = true;
92 extentsChanged = true;
93 }
94
95 void resetTransitionTo() {
96 transitionTo = 0;
97 transitionToSet = false;
98 }
99
100 void addVelocitySample(qreal v, qreal maxVelocity);
101 void updateVelocity();
102
103 QQuickTimeLineValueProxy<QQuickFlickablePrivate> move;
104 QQuickFlickableReboundTransition *transitionToBounds;
105 qreal viewSize;
106 qreal pressPos;
107 qreal lastPos;
108 qreal dragStartOffset;
109 qreal dragMinBound;
110 qreal dragMaxBound;
111 qreal previousDragDelta;
112 qreal velocity;
113 qreal flickTarget;
114 qreal startMargin;
115 qreal endMargin;
116 qreal origin;
117 qreal overshoot;
118 qreal transitionTo;
119 qreal continuousFlickVelocity;
120 QElapsedTimer velocityTime;
121 int vTime;
122 QQuickFlickablePrivate::Velocity smoothVelocity;
123 QPODVector<qreal,10> velocityBuffer;
124 uint atEnd : 1;
125 uint atBeginning : 1;
126 uint transitionToSet : 1;
127 uint fixingUp : 1;
128 uint inOvershoot : 1;
129 uint inRebound : 1;
130 uint moving : 1;
131 uint flicking : 1;
132 uint flickingWhenDragBegan : 1;
133 uint dragging : 1;
134 uint extentsChanged : 1;
135 uint explicitValue : 1;
136 mutable uint minExtentDirty : 1;
137 mutable uint maxExtentDirty : 1;
138 uint contentPositionChangedExternallyDuringDrag : 1;
139 uint unused : 17;
140 };
141
142 bool flickX(QEvent::Type eventType, qreal velocity);
143 bool flickY(QEvent::Type eventType, qreal velocity);
144 virtual bool flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
145 QQuickTimeLineCallback::Callback fixupCallback,
146 QEvent::Type eventType, qreal velocity);
147 void flickingStarted(bool flickingH, bool flickingV);
148
149 void fixupX();
150 void fixupY();
151 virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
152 void adjustContentPos(AxisData &data, qreal toPos);
153 void resetTimeline(AxisData &data);
154 void clearTimeline();
155
156 void updateBeginningEnd();
157
158 bool isInnermostPressDelay(QQuickItem *item) const;
159 void captureDelayedPress(QQuickItem *item, QPointerEvent *event);
160 void clearDelayedPress();
161 void replayDelayedPress();
162
163 void setViewportX(qreal x);
164 void setViewportY(qreal y);
165
166 qreal overShootDistance(qreal velocity) const;
167
168 void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
169
170 void draggingStarting();
171 void draggingEnding();
172
173 bool isViewMoving() const;
174
175 void cancelInteraction();
176
177 void addPointerHandler(QQuickPointerHandler *h) override;
178
179 virtual bool wantsPointerEvent(const QPointerEvent *) { return true; }
180
181public:
182 QQuickItem *contentItem;
183
184 AxisData hData;
185 AxisData vData;
186
187 MovementReason moveReason = Other;
188
189 QQuickTimeLine timeline;
190 bool hMoved : 1;
191 bool vMoved : 1;
192 bool stealMouse : 1;
193 bool pressed : 1;
194 bool scrollingPhase : 1;
195 bool interactive : 1;
196 bool calcVelocity : 1;
197 bool pixelAligned : 1;
198 bool syncDrag : 1;
199 QElapsedTimer timer;
200 qint64 lastPosTime;
201 qint64 lastPressTime;
202 QPointF lastPos;
203 QPointF pressPos;
204 QVector2D accumulatedWheelPixelDelta;
205 qreal deceleration;
206 qreal wheelDeceleration;
207 qreal maxVelocity;
208 QPointerEvent *delayedPressEvent;
209 QBasicTimer delayedPressTimer;
210 int pressDelay;
211 int fixupDuration;
212 qreal flickBoost;
213 qreal initialWheelFlickDistance;
214
215 enum FixupMode { Normal, Immediate, ExtentChanged };
216 FixupMode fixupMode;
217
218 static void fixupY_callback(void *);
219 static void fixupX_callback(void *);
220
221 void updateVelocity();
222 int vTime;
223 QQuickTimeLine velocityTimeline;
224 QQuickFlickableVisibleArea *visibleArea;
225 QQuickFlickable::FlickableDirection flickableDirection;
226 QQuickFlickable::BoundsBehavior boundsBehavior;
227 QQuickFlickable::BoundsMovement boundsMovement;
228 QQuickTransition *rebound;
229
230 void viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent,
231 QQuickTimeLineCallback::Callback fixupCallback);
232
233 void handlePressEvent(QPointerEvent *);
234 void handleMoveEvent(QPointerEvent *);
235 void handleReleaseEvent(QPointerEvent *);
236
237 void maybeBeginDrag(qint64 currentTimestamp, const QPointF &pressPosn);
238 void drag(qint64 currentTimestamp, QEvent::Type eventType, const QPointF &localPos,
239 const QVector2D &deltas, bool overThreshold, bool momentum,
240 bool velocitySensitiveOverBounds, const QVector2D &velocity);
241
242 QVector2D firstPointLocalVelocity(QPointerEvent *event);
243 qint64 computeCurrentTime(QInputEvent *event) const;
244 qreal devicePixelRatio() const;
245
246 // flickableData property
247 static void data_append(QQmlListProperty<QObject> *, QObject *);
248 static qsizetype data_count(QQmlListProperty<QObject> *);
249 static QObject *data_at(QQmlListProperty<QObject> *, qsizetype);
250 static void data_clear(QQmlListProperty<QObject> *);
251};
252
253class Q_QUICK_PRIVATE_EXPORT QQuickFlickableVisibleArea : public QObject
254{
255 Q_OBJECT
256
257 Q_PROPERTY(qreal xPosition READ xPosition NOTIFY xPositionChanged FINAL)
258 Q_PROPERTY(qreal yPosition READ yPosition NOTIFY yPositionChanged FINAL)
259 Q_PROPERTY(qreal widthRatio READ widthRatio NOTIFY widthRatioChanged FINAL)
260 Q_PROPERTY(qreal heightRatio READ heightRatio NOTIFY heightRatioChanged FINAL)
261 QML_ANONYMOUS
262 QML_ADDED_IN_VERSION(2, 0)
263
264public:
265 QQuickFlickableVisibleArea(QQuickFlickable *parent=nullptr);
266
267 qreal xPosition() const;
268 qreal widthRatio() const;
269 qreal yPosition() const;
270 qreal heightRatio() const;
271
272 void updateVisible();
273
274Q_SIGNALS:
275 void xPositionChanged(qreal xPosition);
276 void yPositionChanged(qreal yPosition);
277 void widthRatioChanged(qreal widthRatio);
278 void heightRatioChanged(qreal heightRatio);
279
280private:
281 QQuickFlickable *flickable;
282 qreal m_xPosition;
283 qreal m_widthRatio;
284 qreal m_yPosition;
285 qreal m_heightRatio;
286};
287
288QT_END_NAMESPACE
289
290QML_DECLARE_TYPE(QQuickFlickableVisibleArea)
291
292#endif // QQUICKFLICKABLE_P_P_H
293

source code of qtdeclarative/src/quick/items/qquickflickable_p_p.h