1/****************************************************************************
2**
3** Copyright (C) 2019 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQuick module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QQUICKFLICKABLE_P_P_H
41#define QQUICKFLICKABLE_P_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include "qquickflickable_p.h"
55#include "qquickitem_p.h"
56#include "qquickitemchangelistener_p.h"
57
58#include <QtQml/qqml.h>
59#include <QtCore/qdatetime.h>
60#include "qplatformdefs.h"
61
62#include <private/qquicktimeline_p_p.h>
63#include <private/qquickanimation_p_p.h>
64#include <private/qquicktransitionmanager_p_p.h>
65#include <private/qpodvector_p.h>
66
67QT_BEGIN_NAMESPACE
68
69// Really slow flicks can be annoying.
70const qreal MinimumFlickVelocity = 75.0;
71
72class QQuickFlickableVisibleArea;
73class QQuickTransition;
74class QQuickFlickableReboundTransition;
75
76class Q_QUICK_PRIVATE_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
77{
78 Q_DECLARE_PUBLIC(QQuickFlickable)
79
80public:
81 static inline QQuickFlickablePrivate *get(QQuickFlickable *o) { return o->d_func(); }
82
83 QQuickFlickablePrivate();
84 void init();
85
86 struct Velocity : public QQuickTimeLineValue
87 {
88 Velocity(QQuickFlickablePrivate *p)
89 : parent(p) {}
90 void setValue(qreal v) override {
91 if (v != value()) {
92 QQuickTimeLineValue::setValue(v);
93 parent->updateVelocity();
94 }
95 }
96 QQuickFlickablePrivate *parent;
97 };
98
99 struct AxisData {
100 AxisData(QQuickFlickablePrivate *fp, void (QQuickFlickablePrivate::*func)(qreal))
101 : move(fp, func)
102 , transitionToBounds(nullptr)
103 , viewSize(-1), lastPos(0), previousDragDelta(0), velocity(0), startMargin(0), endMargin(0)
104 , origin(0), overshoot(0)
105 , transitionTo(0)
106 , continuousFlickVelocity(0), velocityTime(), vTime(0)
107 , smoothVelocity(fp), atEnd(false), atBeginning(true)
108 , transitionToSet(false)
109 , fixingUp(false), inOvershoot(false), inRebound(false), moving(false), flicking(false)
110 , dragging(false), extentsChanged(false)
111 , explicitValue(false), minExtentDirty(true), maxExtentDirty(true)
112 , unused(0)
113 {}
114
115 ~AxisData();
116
117 void reset() {
118 velocityBuffer.clear();
119 dragStartOffset = 0;
120 fixingUp = false;
121 inOvershoot = false;
122 }
123
124 void markExtentsDirty() {
125 minExtentDirty = true;
126 maxExtentDirty = true;
127 extentsChanged = true;
128 }
129
130 void resetTransitionTo() {
131 transitionTo = 0;
132 transitionToSet = false;
133 }
134
135 void addVelocitySample(qreal v, qreal maxVelocity);
136 void updateVelocity();
137
138 QQuickTimeLineValueProxy<QQuickFlickablePrivate> move;
139 QQuickFlickableReboundTransition *transitionToBounds;
140 qreal viewSize;
141 qreal pressPos;
142 qreal lastPos;
143 qreal dragStartOffset;
144 qreal dragMinBound;
145 qreal dragMaxBound;
146 qreal previousDragDelta;
147 qreal velocity;
148 qreal flickTarget;
149 qreal startMargin;
150 qreal endMargin;
151 qreal origin;
152 qreal overshoot;
153 qreal transitionTo;
154 qreal continuousFlickVelocity;
155 QElapsedTimer velocityTime;
156 int vTime;
157 QQuickFlickablePrivate::Velocity smoothVelocity;
158 QPODVector<qreal,10> velocityBuffer;
159 bool atEnd : 1;
160 bool atBeginning : 1;
161 bool transitionToSet : 1;
162 bool fixingUp : 1;
163 bool inOvershoot : 1;
164 bool inRebound : 1;
165 bool moving : 1;
166 bool flicking : 1;
167 bool dragging : 1;
168 bool extentsChanged : 1;
169 bool explicitValue : 1;
170 mutable bool minExtentDirty : 1;
171 mutable bool maxExtentDirty : 1;
172 uint unused : 19;
173 };
174
175 bool flickX(qreal velocity);
176 bool flickY(qreal velocity);
177 virtual bool flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
178 QQuickTimeLineCallback::Callback fixupCallback, qreal velocity);
179 void flickingStarted(bool flickingH, bool flickingV);
180
181 void fixupX();
182 void fixupY();
183 virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
184 void adjustContentPos(AxisData &data, qreal toPos);
185 void resetTimeline(AxisData &data);
186 void clearTimeline();
187
188 void updateBeginningEnd();
189
190 bool isInnermostPressDelay(QQuickItem *item) const;
191 void captureDelayedPress(QQuickItem *item, QMouseEvent *event);
192 void clearDelayedPress();
193 void replayDelayedPress();
194
195 void setViewportX(qreal x);
196 void setViewportY(qreal y);
197
198 qreal overShootDistance(qreal size) const;
199
200 void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
201
202 void draggingStarting();
203 void draggingEnding();
204
205 bool isViewMoving() const;
206
207 void cancelInteraction();
208
209 void addPointerHandler(QQuickPointerHandler *h) override;
210
211 // TODO Qt 6: QPointerEvent
212 virtual bool wantsPointerEvent(const QEvent *) { return true; }
213
214public:
215 QQuickItem *contentItem;
216
217 AxisData hData;
218 AxisData vData;
219
220 QQuickTimeLine timeline;
221 bool hMoved : 1;
222 bool vMoved : 1;
223 bool stealMouse : 1;
224 bool pressed : 1;
225 bool scrollingPhase : 1;
226 bool interactive : 1;
227 bool calcVelocity : 1;
228 bool pixelAligned : 1;
229 bool syncDrag : 1;
230 QElapsedTimer timer;
231 qint64 lastPosTime;
232 qint64 lastPressTime;
233 QPointF lastPos;
234 QPointF pressPos;
235 QVector2D accumulatedWheelPixelDelta;
236 qreal deceleration;
237 qreal maxVelocity;
238 qreal reportedVelocitySmoothing;
239 QMouseEvent *delayedPressEvent;
240 QBasicTimer delayedPressTimer;
241 int pressDelay;
242 int fixupDuration;
243 qreal flickBoost;
244 qreal initialWheelFlickDistance;
245
246 enum FixupMode { Normal, Immediate, ExtentChanged };
247 FixupMode fixupMode;
248
249 static void fixupY_callback(void *);
250 static void fixupX_callback(void *);
251
252 void updateVelocity();
253 int vTime;
254 QQuickTimeLine velocityTimeline;
255 QQuickFlickableVisibleArea *visibleArea;
256 QQuickFlickable::FlickableDirection flickableDirection;
257 QQuickFlickable::BoundsBehavior boundsBehavior;
258 QQuickFlickable::BoundsMovement boundsMovement;
259 QQuickTransition *rebound;
260
261 void viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
262 QQuickTimeLineCallback::Callback fixupCallback);
263
264 void handleMousePressEvent(QMouseEvent *);
265 void handleMouseMoveEvent(QMouseEvent *);
266 void handleMouseReleaseEvent(QMouseEvent *);
267
268 void maybeBeginDrag(qint64 currentTimestamp, const QPointF &pressPosn);
269 void drag(qint64 currentTimestamp, QEvent::Type eventType, const QPointF &localPos,
270 const QVector2D &deltas, bool overThreshold, bool momentum,
271 bool velocitySensitiveOverBounds, const QVector2D &velocity);
272
273 qint64 computeCurrentTime(QInputEvent *event) const;
274 qreal devicePixelRatio() const;
275
276 // flickableData property
277 static void data_append(QQmlListProperty<QObject> *, QObject *);
278 static int data_count(QQmlListProperty<QObject> *);
279 static QObject *data_at(QQmlListProperty<QObject> *, int);
280 static void data_clear(QQmlListProperty<QObject> *);
281};
282
283class QQuickFlickableVisibleArea : public QObject
284{
285 Q_OBJECT
286
287 Q_PROPERTY(qreal xPosition READ xPosition NOTIFY xPositionChanged)
288 Q_PROPERTY(qreal yPosition READ yPosition NOTIFY yPositionChanged)
289 Q_PROPERTY(qreal widthRatio READ widthRatio NOTIFY widthRatioChanged)
290 Q_PROPERTY(qreal heightRatio READ heightRatio NOTIFY heightRatioChanged)
291 QML_ANONYMOUS
292
293public:
294 QQuickFlickableVisibleArea(QQuickFlickable *parent=nullptr);
295
296 qreal xPosition() const;
297 qreal widthRatio() const;
298 qreal yPosition() const;
299 qreal heightRatio() const;
300
301 void updateVisible();
302
303Q_SIGNALS:
304 void xPositionChanged(qreal xPosition);
305 void yPositionChanged(qreal yPosition);
306 void widthRatioChanged(qreal widthRatio);
307 void heightRatioChanged(qreal heightRatio);
308
309private:
310 QQuickFlickable *flickable;
311 qreal m_xPosition;
312 qreal m_widthRatio;
313 qreal m_yPosition;
314 qreal m_heightRatio;
315};
316
317QT_END_NAMESPACE
318
319QML_DECLARE_TYPE(QQuickFlickableVisibleArea)
320
321#endif // QQUICKFLICKABLE_P_P_H
322

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