Multiple fast flicks with large content moves faster
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickflickable_p_p.h
1 // Commit: 160f1867868cdea916923652b00484ed11f90aaa
2 /****************************************************************************
3 **
4 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 **
39 ** $QT_END_LICENSE$
40 **
41 ****************************************************************************/
42
43 #ifndef QQUICKFLICKABLE_P_P_H
44 #define QQUICKFLICKABLE_P_P_H
45
46 //
47 //  W A R N I N G
48 //  -------------
49 //
50 // This file is not part of the Qt API.  It exists purely as an
51 // implementation detail.  This header file may change from version to
52 // version without notice, or even be removed.
53 //
54 // We mean it.
55 //
56
57 #include "qquickflickable_p.h"
58 #include "qquickitem_p.h"
59 #include "qquickitemchangelistener_p.h"
60
61 #include <QtDeclarative/qdeclarative.h>
62 #include <QtCore/qdatetime.h>
63 #include "qplatformdefs.h"
64
65 #include <private/qdeclarativetimeline_p_p.h>
66 #include <private/qdeclarativeanimation_p_p.h>
67
68 QT_BEGIN_NAMESPACE
69
70 // Really slow flicks can be annoying.
71 const qreal MinimumFlickVelocity = 75.0;
72
73 class QQuickFlickableVisibleArea;
74 class Q_AUTOTEST_EXPORT QQuickFlickablePrivate : public QQuickItemPrivate, public QQuickItemChangeListener
75 {
76     Q_DECLARE_PUBLIC(QQuickFlickable)
77
78 public:
79     static inline QQuickFlickablePrivate *get(QQuickFlickable *o) { return o->d_func(); }
80
81     QQuickFlickablePrivate();
82     void init();
83
84     struct Velocity : public QDeclarativeTimeLineValue
85     {
86         Velocity(QQuickFlickablePrivate *p)
87             : parent(p) {}
88         virtual void setValue(qreal v) {
89             if (v != value()) {
90                 QDeclarativeTimeLineValue::setValue(v);
91                 parent->updateVelocity();
92             }
93         }
94         QQuickFlickablePrivate *parent;
95     };
96
97     struct AxisData {
98         AxisData(QQuickFlickablePrivate *fp, void (QQuickFlickablePrivate::*func)(qreal))
99             : move(fp, func), viewSize(-1), startMargin(0), endMargin(0)
100             , continuousFlickVelocity(0)
101             , smoothVelocity(fp), atEnd(false), atBeginning(true)
102             , fixingUp(false), inOvershoot(false), moving(false), flicking(false)
103             , dragging(false), extentsChanged(false)
104             , explicitValue(false), minExtentDirty(true), maxExtentDirty(true)
105         {}
106
107         void reset() {
108             velocityBuffer.clear();
109             dragStartOffset = 0;
110             fixingUp = false;
111             inOvershoot = false;
112         }
113
114         void markExtentsDirty() {
115             minExtentDirty = true;
116             maxExtentDirty = true;
117             extentsChanged = true;
118         }
119
120         void addVelocitySample(qreal v, qreal maxVelocity);
121         void updateVelocity();
122
123         QDeclarativeTimeLineValueProxy<QQuickFlickablePrivate> move;
124         qreal viewSize;
125         qreal pressPos;
126         qreal dragStartOffset;
127         qreal dragMinBound;
128         qreal dragMaxBound;
129         qreal velocity;
130         qreal flickTarget;
131         qreal startMargin;
132         qreal endMargin;
133         qreal continuousFlickVelocity;
134         QQuickFlickablePrivate::Velocity smoothVelocity;
135         QPODVector<qreal,10> velocityBuffer;
136         bool atEnd : 1;
137         bool atBeginning : 1;
138         bool fixingUp : 1;
139         bool inOvershoot : 1;
140         bool moving : 1;
141         bool flicking : 1;
142         bool dragging : 1;
143         bool extentsChanged : 1;
144         bool explicitValue : 1;
145         mutable bool minExtentDirty : 1;
146         mutable bool maxExtentDirty : 1;
147     };
148
149     void flickX(qreal velocity);
150     void flickY(qreal velocity);
151     virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
152                         QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity);
153
154     void fixupX();
155     void fixupY();
156     virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
157
158     void updateBeginningEnd();
159
160     bool isOutermostPressDelay() const;
161     void captureDelayedPress(QMouseEvent *event);
162     void clearDelayedPress();
163
164     void setViewportX(qreal x);
165     void setViewportY(qreal y);
166
167     qreal overShootDistance(qreal size);
168
169     void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &);
170
171     void draggingStarting();
172     void draggingEnding();
173
174 public:
175     QQuickItem *contentItem;
176
177     AxisData hData;
178     AxisData vData;
179
180     QDeclarativeTimeLine timeline;
181     bool hMoved : 1;
182     bool vMoved : 1;
183     bool stealMouse : 1;
184     bool pressed : 1;
185     bool interactive : 1;
186     bool calcVelocity : 1;
187     bool pixelAligned : 1;
188     QElapsedTimer timer;
189     qint64 lastPosTime;
190     qint64 lastPressTime;
191     QPointF lastPos;
192     QPointF pressPos;
193     qreal deceleration;
194     qreal maxVelocity;
195     QElapsedTimer velocityTime;
196     QPointF lastFlickablePosition;
197     qreal reportedVelocitySmoothing;
198     QMouseEvent *delayedPressEvent;
199     QQuickItem *delayedPressTarget;
200     QBasicTimer delayedPressTimer;
201     int pressDelay;
202     int fixupDuration;
203     qreal flickBoost;
204
205     enum FixupMode { Normal, Immediate, ExtentChanged };
206     FixupMode fixupMode;
207
208     static void fixupY_callback(void *);
209     static void fixupX_callback(void *);
210
211     void updateVelocity();
212     int vTime;
213     QDeclarativeTimeLine velocityTimeline;
214     QQuickFlickableVisibleArea *visibleArea;
215     QQuickFlickable::FlickableDirection flickableDirection;
216     QQuickFlickable::BoundsBehavior boundsBehavior;
217
218     void handleMousePressEvent(QMouseEvent *);
219     void handleMouseMoveEvent(QMouseEvent *);
220     void handleMouseReleaseEvent(QMouseEvent *);
221
222     qint64 computeCurrentTime(QInputEvent *event);
223
224     // flickableData property
225     static void data_append(QDeclarativeListProperty<QObject> *, QObject *);
226     static int data_count(QDeclarativeListProperty<QObject> *);
227     static QObject *data_at(QDeclarativeListProperty<QObject> *, int);
228     static void data_clear(QDeclarativeListProperty<QObject> *);
229 };
230
231 class QQuickFlickableVisibleArea : public QObject
232 {
233     Q_OBJECT
234
235     Q_PROPERTY(qreal xPosition READ xPosition NOTIFY xPositionChanged)
236     Q_PROPERTY(qreal yPosition READ yPosition NOTIFY yPositionChanged)
237     Q_PROPERTY(qreal widthRatio READ widthRatio NOTIFY widthRatioChanged)
238     Q_PROPERTY(qreal heightRatio READ heightRatio NOTIFY heightRatioChanged)
239
240 public:
241     QQuickFlickableVisibleArea(QQuickFlickable *parent=0);
242
243     qreal xPosition() const;
244     qreal widthRatio() const;
245     qreal yPosition() const;
246     qreal heightRatio() const;
247
248     void updateVisible();
249
250 signals:
251     void xPositionChanged(qreal xPosition);
252     void yPositionChanged(qreal yPosition);
253     void widthRatioChanged(qreal widthRatio);
254     void heightRatioChanged(qreal heightRatio);
255
256 private:
257     QQuickFlickable *flickable;
258     qreal m_xPosition;
259     qreal m_widthRatio;
260     qreal m_yPosition;
261     qreal m_heightRatio;
262 };
263
264 QT_END_NAMESPACE
265
266 QML_DECLARE_TYPE(QQuickFlickableVisibleArea)
267
268 #endif // QQUICKFLICKABLE_P_P_H