Skip to content

Latest commit

 

History

History
2137 lines (1874 loc) · 66.1 KB

qquickflickable.cpp

File metadata and controls

2137 lines (1874 loc) · 66.1 KB
 
Apr 27, 2011
Apr 27, 2011
1
2
/****************************************************************************
**
Jan 5, 2012
Jan 5, 2012
3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
Jan 23, 2012
Jan 23, 2012
4
** Contact: http://www.qt-project.org/
Apr 27, 2011
Apr 27, 2011
5
**
Feb 24, 2012
Feb 24, 2012
6
** This file is part of the QtQml module of the Qt Toolkit.
Apr 27, 2011
Apr 27, 2011
7
8
9
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
Jul 8, 2011
Jul 8, 2011
10
11
12
13
14
15
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Apr 27, 2011
Apr 27, 2011
16
17
**
** In addition, as a special exception, Nokia gives you certain additional
Jul 8, 2011
Jul 8, 2011
18
** rights. These rights are described in the Nokia Qt LGPL Exception
Apr 27, 2011
Apr 27, 2011
19
20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
Jul 8, 2011
Jul 8, 2011
21
22
23
24
25
26
27
28
29
30
31
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
Apr 27, 2011
Apr 27, 2011
32
33
34
35
36
**
**
**
**
**
Jan 30, 2012
Jan 30, 2012
37
**
Apr 27, 2011
Apr 27, 2011
38
39
40
41
** $QT_END_LICENSE$
**
****************************************************************************/
Oct 21, 2011
Oct 21, 2011
42
43
44
45
#include "qquickflickable_p.h"
#include "qquickflickable_p_p.h"
#include "qquickcanvas.h"
#include "qquickcanvas_p.h"
Feb 10, 2012
Feb 10, 2012
46
#include "qquickevents_p_p.h"
Apr 27, 2011
Apr 27, 2011
47
Feb 24, 2012
Feb 24, 2012
48
49
50
#include <private/qqmlglobal_p.h>
#include <QtQml/qqmlinfo.h>
Sep 1, 2011
Sep 1, 2011
51
#include <QtGui/qevent.h>
Sep 1, 2011
Sep 1, 2011
52
53
#include <QtGui/qguiapplication.h>
#include <QtGui/qstylehints.h>
May 4, 2011
May 4, 2011
54
#include "qplatformdefs.h"
Apr 27, 2011
Apr 27, 2011
55
56
57
QT_BEGIN_NAMESPACE
May 4, 2011
May 4, 2011
58
59
60
61
62
63
64
65
66
67
68
69
70
// The maximum number of pixels a flick can overshoot
#ifndef QML_FLICK_OVERSHOOT
#define QML_FLICK_OVERSHOOT 200
#endif
// The number of samples to use in calculating the velocity of a flick
#ifndef QML_FLICK_SAMPLEBUFFER
#define QML_FLICK_SAMPLEBUFFER 3
#endif
// The number of samples to discard when calculating the flick velocity.
// Touch panels often produce inaccurate results as the finger is lifted.
#ifndef QML_FLICK_DISCARDSAMPLES
Mar 15, 2012
Mar 15, 2012
71
#define QML_FLICK_DISCARDSAMPLES 0
May 4, 2011
May 4, 2011
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#endif
// The default maximum velocity of a flick.
#ifndef QML_FLICK_DEFAULTMAXVELOCITY
#define QML_FLICK_DEFAULTMAXVELOCITY 2500
#endif
// The default deceleration of a flick.
#ifndef QML_FLICK_DEFAULTDECELERATION
#define QML_FLICK_DEFAULTDECELERATION 1500
#endif
// How much faster to decelerate when overshooting
#ifndef QML_FLICK_OVERSHOOTFRICTION
#define QML_FLICK_OVERSHOOTFRICTION 8
#endif
Feb 2, 2012
Feb 2, 2012
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Multiflick acceleration minimum flick velocity threshold
#ifndef QML_FLICK_MULTIFLICK_THRESHOLD
#define QML_FLICK_MULTIFLICK_THRESHOLD 1250
#endif
// Multiflick acceleration minimum contentSize/viewSize ratio
#ifndef QML_FLICK_MULTIFLICK_RATIO
#define QML_FLICK_MULTIFLICK_RATIO 10
#endif
// Multiflick acceleration maximum velocity multiplier
#ifndef QML_FLICK_MULTIFLICK_MAXBOOST
#define QML_FLICK_MULTIFLICK_MAXBOOST 3.0
#endif
Apr 27, 2011
Apr 27, 2011
104
105
// FlickThreshold determines how far the "mouse" must have moved
// before we perform a flick.
Mar 15, 2012
Mar 15, 2012
106
static const int FlickThreshold = 15;
Apr 27, 2011
Apr 27, 2011
107
108
109
// RetainGrabVelocity is the maxmimum instantaneous velocity that
// will ensure the Flickable retains the grab on consecutive flicks.
Mar 13, 2012
Mar 13, 2012
110
static const int RetainGrabVelocity = 100;
Apr 27, 2011
Apr 27, 2011
111
Oct 21, 2011
Oct 21, 2011
112
QQuickFlickableVisibleArea::QQuickFlickableVisibleArea(QQuickFlickable *parent)
Apr 27, 2011
Apr 27, 2011
113
114
115
116
117
: QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.)
, m_yPosition(0.), m_heightRatio(0.)
{
}
Oct 21, 2011
Oct 21, 2011
118
qreal QQuickFlickableVisibleArea::widthRatio() const
Apr 27, 2011
Apr 27, 2011
119
120
121
122
{
return m_widthRatio;
}
Oct 21, 2011
Oct 21, 2011
123
qreal QQuickFlickableVisibleArea::xPosition() const
Apr 27, 2011
Apr 27, 2011
124
125
126
127
{
return m_xPosition;
}
Oct 21, 2011
Oct 21, 2011
128
qreal QQuickFlickableVisibleArea::heightRatio() const
Apr 27, 2011
Apr 27, 2011
129
130
131
132
{
return m_heightRatio;
}
Oct 21, 2011
Oct 21, 2011
133
qreal QQuickFlickableVisibleArea::yPosition() const
Apr 27, 2011
Apr 27, 2011
134
135
136
137
{
return m_yPosition;
}
Oct 21, 2011
Oct 21, 2011
138
void QQuickFlickableVisibleArea::updateVisible()
Apr 27, 2011
Apr 27, 2011
139
{
Oct 21, 2011
Oct 21, 2011
140
QQuickFlickablePrivate *p = QQuickFlickablePrivate::get(flickable);
Apr 27, 2011
Apr 27, 2011
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
bool changeX = false;
bool changeY = false;
bool changeWidth = false;
bool changeHeight = false;
// Vertical
const qreal viewheight = flickable->height();
const qreal maxyextent = -flickable->maxYExtent() + flickable->minYExtent();
qreal pagePos = (-p->vData.move.value() + flickable->minYExtent()) / (maxyextent + viewheight);
qreal pageSize = viewheight / (maxyextent + viewheight);
if (pageSize != m_heightRatio) {
m_heightRatio = pageSize;
changeHeight = true;
}
if (pagePos != m_yPosition) {
m_yPosition = pagePos;
changeY = true;
}
// Horizontal
const qreal viewwidth = flickable->width();
const qreal maxxextent = -flickable->maxXExtent() + flickable->minXExtent();
pagePos = (-p->hData.move.value() + flickable->minXExtent()) / (maxxextent + viewwidth);
pageSize = viewwidth / (maxxextent + viewwidth);
if (pageSize != m_widthRatio) {
m_widthRatio = pageSize;
changeWidth = true;
}
if (pagePos != m_xPosition) {
m_xPosition = pagePos;
changeX = true;
}
if (changeX)
emit xPositionChanged(m_xPosition);
if (changeY)
emit yPositionChanged(m_yPosition);
if (changeWidth)
emit widthRatioChanged(m_widthRatio);
if (changeHeight)
emit heightRatioChanged(m_heightRatio);
}
Oct 21, 2011
Oct 21, 2011
188
189
190
191
QQuickFlickablePrivate::QQuickFlickablePrivate()
: contentItem(new QQuickItem)
, hData(this, &QQuickFlickablePrivate::setViewportX)
, vData(this, &QQuickFlickablePrivate::setViewportY)
Apr 27, 2011
Apr 27, 2011
192
193
, hMoved(false), vMoved(false)
, stealMouse(false), pressed(false), interactive(true), calcVelocity(false)
Sep 12, 2011
Sep 12, 2011
194
, pixelAligned(false)
Dec 20, 2011
Dec 20, 2011
195
196
, lastPosTime(-1)
, lastPressTime(0)
May 4, 2011
May 4, 2011
197
198
199
, deceleration(QML_FLICK_DEFAULTDECELERATION)
, maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100)
, delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(400)
Feb 2, 2012
Feb 2, 2012
200
, flickBoost(1.0), fixupMode(Normal), vTime(0), visibleArea(0)
Oct 21, 2011
Oct 21, 2011
201
202
, flickableDirection(QQuickFlickable::AutoFlickDirection)
, boundsBehavior(QQuickFlickable::DragAndOvershootBounds)
Apr 27, 2011
Apr 27, 2011
203
204
205
{
}
Oct 21, 2011
Oct 21, 2011
206
void QQuickFlickablePrivate::init()
Apr 27, 2011
Apr 27, 2011
207
{
Oct 21, 2011
Oct 21, 2011
208
Q_Q(QQuickFlickable);
Feb 24, 2012
Feb 24, 2012
209
QQml_setParent_noEvent(contentItem, q);
Apr 27, 2011
Apr 27, 2011
210
contentItem->setParentItem(q);
Sep 27, 2011
Sep 27, 2011
211
FAST_CONNECT(&timeline, SIGNAL(completed()), q, SLOT(movementEnding()))
Apr 27, 2011
Apr 27, 2011
212
213
q->setAcceptedMouseButtons(Qt::LeftButton);
q->setFiltersChildMouseEvents(true);
Oct 21, 2011
Oct 21, 2011
214
215
QQuickItemPrivate *viewportPrivate = QQuickItemPrivate::get(contentItem);
viewportPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
Apr 27, 2011
Apr 27, 2011
216
217
218
219
220
221
}
/*
Returns the amount to overshoot by given a velocity.
Will be roughly in range 0 - size/4
*/
Oct 21, 2011
Oct 21, 2011
222
qreal QQuickFlickablePrivate::overShootDistance(qreal size)
Apr 27, 2011
Apr 27, 2011
223
224
225
226
{
if (maxVelocity <= 0)
return 0.0;
May 4, 2011
May 4, 2011
227
228
229
return qMin(qreal(QML_FLICK_OVERSHOOT), size/3);
}
Oct 21, 2011
Oct 21, 2011
230
void QQuickFlickablePrivate::AxisData::addVelocitySample(qreal v, qreal maxVelocity)
May 4, 2011
May 4, 2011
231
232
233
234
235
236
237
238
239
240
{
if (v > maxVelocity)
v = maxVelocity;
else if (v < -maxVelocity)
v = -maxVelocity;
velocityBuffer.append(v);
if (velocityBuffer.count() > QML_FLICK_SAMPLEBUFFER)
velocityBuffer.remove(0);
}
Oct 21, 2011
Oct 21, 2011
241
void QQuickFlickablePrivate::AxisData::updateVelocity()
May 4, 2011
May 4, 2011
242
{
Sep 12, 2011
Sep 12, 2011
243
velocity = 0;
May 4, 2011
May 4, 2011
244
245
246
247
248
249
250
251
if (velocityBuffer.count() > QML_FLICK_DISCARDSAMPLES) {
int count = velocityBuffer.count()-QML_FLICK_DISCARDSAMPLES;
for (int i = 0; i < count; ++i) {
qreal v = velocityBuffer.at(i);
velocity += v;
}
velocity /= count;
}
Apr 27, 2011
Apr 27, 2011
252
253
}
Oct 21, 2011
Oct 21, 2011
254
void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, const QRectF &newGeom, const QRectF &oldGeom)
Apr 27, 2011
Apr 27, 2011
255
{
Oct 21, 2011
Oct 21, 2011
256
Q_Q(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
257
if (item == contentItem) {
Jan 6, 2012
Jan 6, 2012
258
259
260
261
262
bool xChanged = newGeom.x() != oldGeom.x();
bool yChanged = newGeom.y() != oldGeom.y();
if (xChanged || yChanged)
q->viewportMoved();
if (xChanged)
Apr 27, 2011
Apr 27, 2011
263
emit q->contentXChanged();
Jan 6, 2012
Jan 6, 2012
264
if (yChanged)
Apr 27, 2011
Apr 27, 2011
265
266
267
268
emit q->contentYChanged();
}
}
Oct 21, 2011
Oct 21, 2011
269
void QQuickFlickablePrivate::flickX(qreal velocity)
Apr 27, 2011
Apr 27, 2011
270
{
Oct 21, 2011
Oct 21, 2011
271
Q_Q(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
272
273
274
flick(hData, q->minXExtent(), q->maxXExtent(), q->width(), fixupX_callback, velocity);
}
Oct 21, 2011
Oct 21, 2011
275
void QQuickFlickablePrivate::flickY(qreal velocity)
Apr 27, 2011
Apr 27, 2011
276
{
Oct 21, 2011
Oct 21, 2011
277
Q_Q(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
278
279
280
flick(vData, q->minYExtent(), q->maxYExtent(), q->height(), fixupY_callback, velocity);
}
Oct 21, 2011
Oct 21, 2011
281
void QQuickFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal,
Feb 24, 2012
Feb 24, 2012
282
QQuickTimeLineCallback::Callback fixupCallback, qreal velocity)
Apr 27, 2011
Apr 27, 2011
283
{
Oct 21, 2011
Oct 21, 2011
284
Q_Q(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
285
286
287
288
qreal maxDistance = -1;
data.fixingUp = false;
// -ve velocity means list is moving up
if (velocity > 0) {
May 4, 2011
May 4, 2011
289
maxDistance = qAbs(minExtent - data.move.value());
Apr 27, 2011
Apr 27, 2011
290
291
data.flickTarget = minExtent;
} else {
May 4, 2011
May 4, 2011
292
maxDistance = qAbs(maxExtent - data.move.value());
Apr 27, 2011
Apr 27, 2011
293
294
295
296
297
298
299
300
301
302
303
data.flickTarget = maxExtent;
}
if (maxDistance > 0) {
qreal v = velocity;
if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
if (v < 0)
v = -maxVelocity;
else
v = maxVelocity;
}
timeline.reset(data.move);
Oct 21, 2011
Oct 21, 2011
304
if (boundsBehavior == QQuickFlickable::DragAndOvershootBounds)
May 4, 2011
May 4, 2011
305
306
307
timeline.accel(data.move, v, deceleration);
else
timeline.accel(data.move, v, deceleration, maxDistance);
Feb 24, 2012
Feb 24, 2012
308
timeline.callback(QQuickTimeLineCallback(&data.move, fixupCallback, this));
Feb 7, 2012
Feb 7, 2012
309
if (!hData.flicking && q->xflick() && (&data == &hData)) {
Sep 27, 2011
Sep 27, 2011
310
hData.flicking = true;
Apr 27, 2011
Apr 27, 2011
311
312
emit q->flickingChanged();
emit q->flickingHorizontallyChanged();
Sep 27, 2011
Sep 27, 2011
313
if (!vData.flicking)
Apr 27, 2011
Apr 27, 2011
314
315
emit q->flickStarted();
}
Feb 7, 2012
Feb 7, 2012
316
if (!vData.flicking && q->yflick() && (&data == &vData)) {
Sep 27, 2011
Sep 27, 2011
317
vData.flicking = true;
Apr 27, 2011
Apr 27, 2011
318
319
emit q->flickingChanged();
emit q->flickingVerticallyChanged();
Sep 27, 2011
Sep 27, 2011
320
if (!hData.flicking)
Apr 27, 2011
Apr 27, 2011
321
322
323
324
325
326
327
328
emit q->flickStarted();
}
} else {
timeline.reset(data.move);
fixup(data, minExtent, maxExtent);
}
}
Oct 21, 2011
Oct 21, 2011
329
void QQuickFlickablePrivate::fixupY_callback(void *data)
Apr 27, 2011
Apr 27, 2011
330
{
Oct 21, 2011
Oct 21, 2011
331
((QQuickFlickablePrivate *)data)->fixupY();
Apr 27, 2011
Apr 27, 2011
332
333
}
Oct 21, 2011
Oct 21, 2011
334
void QQuickFlickablePrivate::fixupX_callback(void *data)
Apr 27, 2011
Apr 27, 2011
335
{
Oct 21, 2011
Oct 21, 2011
336
((QQuickFlickablePrivate *)data)->fixupX();
Apr 27, 2011
Apr 27, 2011
337
338
}
Oct 21, 2011
Oct 21, 2011
339
void QQuickFlickablePrivate::fixupX()
Apr 27, 2011
Apr 27, 2011
340
{
Oct 21, 2011
Oct 21, 2011
341
Q_Q(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
342
343
344
fixup(hData, q->minXExtent(), q->maxXExtent());
}
Oct 21, 2011
Oct 21, 2011
345
void QQuickFlickablePrivate::fixupY()
Apr 27, 2011
Apr 27, 2011
346
{
Oct 21, 2011
Oct 21, 2011
347
Q_Q(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
348
349
350
fixup(vData, q->minYExtent(), q->maxYExtent());
}
Oct 21, 2011
Oct 21, 2011
351
void QQuickFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
Apr 27, 2011
Apr 27, 2011
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
{
if (data.move.value() > minExtent || maxExtent > minExtent) {
timeline.reset(data.move);
if (data.move.value() != minExtent) {
switch (fixupMode) {
case Immediate:
timeline.set(data.move, minExtent);
break;
case ExtentChanged:
// The target has changed. Don't start from the beginning; just complete the
// second half of the animation using the new extent.
timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
data.fixingUp = true;
break;
default: {
qreal dist = minExtent - data.move;
timeline.move(data.move, minExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
data.fixingUp = true;
}
}
}
} else if (data.move.value() < maxExtent) {
timeline.reset(data.move);
switch (fixupMode) {
case Immediate:
timeline.set(data.move, maxExtent);
break;
case ExtentChanged:
// The target has changed. Don't start from the beginning; just complete the
// second half of the animation using the new extent.
timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
data.fixingUp = true;
break;
default: {
qreal dist = maxExtent - data.move;
timeline.move(data.move, maxExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
data.fixingUp = true;
}
}
}
May 4, 2011
May 4, 2011
394
data.inOvershoot = false;
Apr 27, 2011
Apr 27, 2011
395
396
397
398
fixupMode = Normal;
vTime = timeline.time();
}
Oct 21, 2011
Oct 21, 2011
399
void QQuickFlickablePrivate::updateBeginningEnd()
Apr 27, 2011
Apr 27, 2011
400
{
Oct 21, 2011
Oct 21, 2011
401
Q_Q(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
bool atBoundaryChange = false;
// Vertical
const int maxyextent = int(-q->maxYExtent());
const qreal ypos = -vData.move.value();
bool atBeginning = (ypos <= -q->minYExtent());
bool atEnd = (maxyextent <= ypos);
if (atBeginning != vData.atBeginning) {
vData.atBeginning = atBeginning;
atBoundaryChange = true;
}
if (atEnd != vData.atEnd) {
vData.atEnd = atEnd;
atBoundaryChange = true;
}
// Horizontal
const int maxxextent = int(-q->maxXExtent());
const qreal xpos = -hData.move.value();
atBeginning = (xpos <= -q->minXExtent());
atEnd = (maxxextent <= xpos);
if (atBeginning != hData.atBeginning) {
hData.atBeginning = atBeginning;
atBoundaryChange = true;
}
if (atEnd != hData.atEnd) {
hData.atEnd = atEnd;
atBoundaryChange = true;
}
Sep 26, 2011
Sep 26, 2011
434
435
436
437
438
439
440
441
442
443
if (vData.extentsChanged) {
vData.extentsChanged = false;
emit q->yOriginChanged();
}
if (hData.extentsChanged) {
hData.extentsChanged = false;
emit q->xOriginChanged();
}
Apr 27, 2011
Apr 27, 2011
444
445
446
447
448
449
450
if (atBoundaryChange)
emit q->isAtBoundaryChanged();
if (visibleArea)
visibleArea->updateVisible();
}
Jul 28, 2011
Jul 28, 2011
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
/*
XXXTODO add docs describing moving, dragging, flicking properties, e.g.
When the user starts dragging the Flickable, the dragging and moving properties
will be true.
If the velocity is sufficient when the drag is ended, flicking may begin.
The moving properties will remain true until all dragging and flicking
is finished.
*/
/*!
\qmlsignal QtQuick2::Flickable::onDragStarted()
This handler is called when the view starts to be dragged due to user
interaction.
*/
/*!
\qmlsignal QtQuick2::Flickable::onDragEnded()
This handler is called when the user stops dragging the view.
If the velocity of the drag is suffient at the time the
touch/mouse button is released then a flick will start.
*/
Aug 9, 2011
Aug 9, 2011
479
/*!
Oct 21, 2011
Oct 21, 2011
480
\qmlclass Flickable QQuickFlickable
Aug 9, 2011
Aug 9, 2011
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
\inqmlmodule QtQuick 2
\ingroup qml-basic-interaction-elements
\brief The Flickable item provides a surface that can be "flicked".
\inherits Item
The Flickable item places its children on a surface that can be dragged
and flicked, causing the view onto the child items to scroll. This
behavior forms the basis of Items that are designed to show large numbers
of child items, such as \l ListView and \l GridView.
In traditional user interfaces, views can be scrolled using standard
controls, such as scroll bars and arrow buttons. In some situations, it
is also possible to drag the view directly by pressing and holding a
mouse button while moving the cursor. In touch-based user interfaces,
this dragging action is often complemented with a flicking action, where
scrolling continues after the user has stopped touching the view.
Flickable does not automatically clip its contents. If it is not used as
a full-screen item, you should consider setting the \l{Item::}{clip} property
to true.
\section1 Example Usage
\div {class="float-right"}
\inlineimage flickable.gif
\enddiv
The following example shows a small view onto a large image in which the
user can drag or flick the image in order to view different parts of it.
Feb 24, 2012
Feb 24, 2012
512
\snippet doc/src/snippets/qml/flickable.qml document
Aug 9, 2011
Aug 9, 2011
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
\clearfloat
Items declared as children of a Flickable are automatically parented to the
Flickable's \l contentItem. This should be taken into account when
operating on the children of the Flickable; it is usually the children of
\c contentItem that are relevant. For example, the bound of Items added
to the Flickable will be available by \c contentItem.childrenRect
\section1 Limitations
\note Due to an implementation detail, items placed inside a Flickable cannot anchor to it by
\c id. Use \c parent instead.
*/
/*!
\qmlsignal QtQuick2::Flickable::onMovementStarted()
This handler is called when the view begins moving due to user
interaction.
*/
/*!
\qmlsignal QtQuick2::Flickable::onMovementEnded()
This handler is called when the view stops moving due to user
interaction. If a flick was generated, this handler will
be triggered once the flick stops. If a flick was not
generated, the handler will be triggered when the
user stops dragging - i.e. a mouse or touch release.
*/
/*!
\qmlsignal QtQuick2::Flickable::onFlickStarted()
This handler is called when the view is flicked. A flick
starts from the point that the mouse or touch is released,
while still in motion.
*/
/*!
\qmlsignal QtQuick2::Flickable::onFlickEnded()
This handler is called when the view stops moving due to a flick.
*/
/*!
\qmlproperty real QtQuick2::Flickable::visibleArea.xPosition
\qmlproperty real QtQuick2::Flickable::visibleArea.widthRatio
\qmlproperty real QtQuick2::Flickable::visibleArea.yPosition
\qmlproperty real QtQuick2::Flickable::visibleArea.heightRatio
These properties describe the position and size of the currently viewed area.
The size is defined as the percentage of the full view currently visible,
scaled to 0.0 - 1.0. The page position is usually in the range 0.0 (beginning) to
1.0 minus size ratio (end), i.e. \c yPosition is in the range 0.0 to 1.0-\c heightRatio.
However, it is possible for the contents to be dragged outside of the normal
range, resulting in the page positions also being outside the normal range.
These properties are typically used to draw a scrollbar. For example:
Feb 24, 2012
Feb 24, 2012
574
\snippet doc/src/snippets/qml/flickableScrollbar.qml 0
Aug 9, 2011
Aug 9, 2011
575
\dots 8
Feb 24, 2012
Feb 24, 2012
576
\snippet doc/src/snippets/qml/flickableScrollbar.qml 1
Aug 9, 2011
Aug 9, 2011
577
578
579
\sa {declarative/ui-components/scrollbar}{scrollbar example}
*/
Oct 21, 2011
Oct 21, 2011
580
581
QQuickFlickable::QQuickFlickable(QQuickItem *parent)
: QQuickItem(*(new QQuickFlickablePrivate), parent)
Apr 27, 2011
Apr 27, 2011
582
{
Oct 21, 2011
Oct 21, 2011
583
Q_D(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
584
585
586
d->init();
}
Oct 21, 2011
Oct 21, 2011
587
588
QQuickFlickable::QQuickFlickable(QQuickFlickablePrivate &dd, QQuickItem *parent)
: QQuickItem(dd, parent)
Apr 27, 2011
Apr 27, 2011
589
{
Oct 21, 2011
Oct 21, 2011
590
Q_D(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
591
592
593
d->init();
}
Oct 21, 2011
Oct 21, 2011
594
QQuickFlickable::~QQuickFlickable()
Apr 27, 2011
Apr 27, 2011
595
596
597
{
}
Aug 9, 2011
Aug 9, 2011
598
599
600
601
602
603
604
605
/*!
\qmlproperty real QtQuick2::Flickable::contentX
\qmlproperty real QtQuick2::Flickable::contentY
These properties hold the surface coordinate currently at the top-left
corner of the Flickable. For example, if you flick an image up 100 pixels,
\c contentY will be 100.
*/
Oct 21, 2011
Oct 21, 2011
606
qreal QQuickFlickable::contentX() const
Apr 27, 2011
Apr 27, 2011
607
{
Oct 21, 2011
Oct 21, 2011
608
Q_D(const QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
609
610
611
return -d->contentItem->x();
}
Oct 21, 2011
Oct 21, 2011
612
void QQuickFlickable::setContentX(qreal pos)
Apr 27, 2011
Apr 27, 2011
613
{
Oct 21, 2011
Oct 21, 2011
614
Q_D(QQuickFlickable);
Sep 26, 2011
Sep 26, 2011
615
d->hData.explicitValue = true;
Apr 27, 2011
Apr 27, 2011
616
617
618
d->timeline.reset(d->hData.move);
d->vTime = d->timeline.time();
movementXEnding();
Jan 6, 2012
Jan 6, 2012
619
if (-pos != d->hData.move.value())
Apr 27, 2011
Apr 27, 2011
620
621
622
d->hData.move.setValue(-pos);
}
Oct 21, 2011
Oct 21, 2011
623
qreal QQuickFlickable::contentY() const
Apr 27, 2011
Apr 27, 2011
624
{
Oct 21, 2011
Oct 21, 2011
625
Q_D(const QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
626
627
628
return -d->contentItem->y();
}
Oct 21, 2011
Oct 21, 2011
629
void QQuickFlickable::setContentY(qreal pos)
Apr 27, 2011
Apr 27, 2011
630
{
Oct 21, 2011
Oct 21, 2011
631
Q_D(QQuickFlickable);
Sep 26, 2011
Sep 26, 2011
632
d->vData.explicitValue = true;
Apr 27, 2011
Apr 27, 2011
633
634
635
d->timeline.reset(d->vData.move);
d->vTime = d->timeline.time();
movementYEnding();
Jan 6, 2012
Jan 6, 2012
636
if (-pos != d->vData.move.value())
Apr 27, 2011
Apr 27, 2011
637
638
639
d->vData.move.setValue(-pos);
}
Aug 9, 2011
Aug 9, 2011
640
641
642
643
644
645
646
647
648
649
650
651
652
/*!
\qmlproperty bool QtQuick2::Flickable::interactive
This property describes whether the user can interact with the Flickable.
A user cannot drag or flick a Flickable that is not interactive.
By default, this property is true.
This property is useful for temporarily disabling flicking. This allows
special interaction with Flickable's children; for example, you might want
to freeze a flickable map while scrolling through a pop-up dialog that
is a child of the Flickable.
*/
Oct 21, 2011
Oct 21, 2011
653
bool QQuickFlickable::isInteractive() const
Apr 27, 2011
Apr 27, 2011
654
{
Oct 21, 2011
Oct 21, 2011
655
Q_D(const QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
656
657
658
return d->interactive;
}
Oct 21, 2011
Oct 21, 2011
659
void QQuickFlickable::setInteractive(bool interactive)
Apr 27, 2011
Apr 27, 2011
660
{
Oct 21, 2011
Oct 21, 2011
661
Q_D(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
662
663
if (interactive != d->interactive) {
d->interactive = interactive;
Sep 27, 2011
Sep 27, 2011
664
if (!interactive && (d->hData.flicking || d->vData.flicking)) {
Apr 27, 2011
Apr 27, 2011
665
666
d->timeline.clear();
d->vTime = d->timeline.time();
Sep 27, 2011
Sep 27, 2011
667
668
d->hData.flicking = false;
d->vData.flicking = false;
Apr 27, 2011
Apr 27, 2011
669
670
671
672
673
674
675
676
677
emit flickingChanged();
emit flickingHorizontallyChanged();
emit flickingVerticallyChanged();
emit flickEnded();
}
emit interactiveChanged();
}
}
Aug 9, 2011
Aug 9, 2011
678
679
680
681
682
683
684
/*!
\qmlproperty real QtQuick2::Flickable::horizontalVelocity
\qmlproperty real QtQuick2::Flickable::verticalVelocity
The instantaneous velocity of movement along the x and y axes, in pixels/sec.
The reported velocity is smoothed to avoid erratic output.
Feb 2, 2012
Feb 2, 2012
685
686
687
688
689
Note that for views with a large content size (more than 10 times the view size),
the velocity of the flick may exceed the velocity of the touch in the case
of multiple quick consecutive flicks. This allows the user to flick faster
through large content.
Aug 9, 2011
Aug 9, 2011
690
*/
Oct 21, 2011
Oct 21, 2011
691
qreal QQuickFlickable::horizontalVelocity() const
Apr 27, 2011
Apr 27, 2011
692
{
Oct 21, 2011
Oct 21, 2011
693
Q_D(const QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
694
695
696
return d->hData.smoothVelocity.value();
}
Oct 21, 2011
Oct 21, 2011
697
qreal QQuickFlickable::verticalVelocity() const
Apr 27, 2011
Apr 27, 2011
698
{
Oct 21, 2011
Oct 21, 2011
699
Q_D(const QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
700
701
702
return d->vData.smoothVelocity.value();
}
Aug 9, 2011
Aug 9, 2011
703
704
705
706
707
708
709
/*!
\qmlproperty bool QtQuick2::Flickable::atXBeginning
\qmlproperty bool QtQuick2::Flickable::atXEnd
\qmlproperty bool QtQuick2::Flickable::atYBeginning
\qmlproperty bool QtQuick2::Flickable::atYEnd
These properties are true if the flickable view is positioned at the beginning,
Nov 7, 2011
Nov 7, 2011
710
or end respectively.
Aug 9, 2011
Aug 9, 2011
711
*/
Oct 21, 2011
Oct 21, 2011
712
bool QQuickFlickable::isAtXEnd() const
Apr 27, 2011
Apr 27, 2011
713
{
Oct 21, 2011
Oct 21, 2011
714
Q_D(const QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
715
716
717
return d->hData.atEnd;
}
Oct 21, 2011
Oct 21, 2011
718
bool QQuickFlickable::isAtXBeginning() const
Apr 27, 2011
Apr 27, 2011
719
{
Oct 21, 2011
Oct 21, 2011
720
Q_D(const QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
721
722
723
return d->hData.atBeginning;
}
Oct 21, 2011
Oct 21, 2011
724
bool QQuickFlickable::isAtYEnd() const
Apr 27, 2011
Apr 27, 2011
725
{
Oct 21, 2011
Oct 21, 2011
726
Q_D(const QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
727
728
729
return d->vData.atEnd;
}
Oct 21, 2011
Oct 21, 2011
730
bool QQuickFlickable::isAtYBeginning() const
Apr 27, 2011
Apr 27, 2011
731
{
Oct 21, 2011
Oct 21, 2011
732
Q_D(const QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
733
734
735
return d->vData.atBeginning;
}
Aug 9, 2011
Aug 9, 2011
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
/*!
\qmlproperty Item QtQuick2::Flickable::contentItem
The internal item that contains the Items to be moved in the Flickable.
Items declared as children of a Flickable are automatically parented to the Flickable's contentItem.
Items created dynamically need to be explicitly parented to the \e contentItem:
\code
Flickable {
id: myFlickable
function addItem(file) {
var component = Qt.createComponent(file)
component.createObject(myFlickable.contentItem);
}
}
\endcode
*/
Oct 21, 2011
Oct 21, 2011
754
QQuickItem *QQuickFlickable::contentItem()
Apr 27, 2011
Apr 27, 2011
755
{
Oct 21, 2011
Oct 21, 2011
756
Q_D(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
757
758
759
return d->contentItem;
}
Oct 21, 2011
Oct 21, 2011
760
QQuickFlickableVisibleArea *QQuickFlickable::visibleArea()
Apr 27, 2011
Apr 27, 2011
761
{
Oct 21, 2011
Oct 21, 2011
762
Q_D(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
763
if (!d->visibleArea)
Oct 21, 2011
Oct 21, 2011
764
d->visibleArea = new QQuickFlickableVisibleArea(this);
Apr 27, 2011
Apr 27, 2011
765
766
767
return d->visibleArea;
}
Aug 9, 2011
Aug 9, 2011
768
769
770
771
772
773
/*!
\qmlproperty enumeration QtQuick2::Flickable::flickableDirection
This property determines which directions the view can be flicked.
\list
Mar 13, 2012
Mar 13, 2012
774
\li Flickable.AutoFlickDirection (default) - allows flicking vertically if the
Aug 9, 2011
Aug 9, 2011
775
776
777
\e contentHeight is not equal to the \e height of the Flickable.
Allows flicking horizontally if the \e contentWidth is not equal
to the \e width of the Flickable.
Mar 13, 2012
Mar 13, 2012
778
779
780
\li Flickable.HorizontalFlick - allows flicking horizontally.
\li Flickable.VerticalFlick - allows flicking vertically.
\li Flickable.HorizontalAndVerticalFlick - allows flicking in both directions.
Aug 9, 2011
Aug 9, 2011
781
782
\endlist
*/
Oct 21, 2011
Oct 21, 2011
783
QQuickFlickable::FlickableDirection QQuickFlickable::flickableDirection() const
Apr 27, 2011
Apr 27, 2011
784
{
Oct 21, 2011
Oct 21, 2011
785
Q_D(const QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
786
787
788
return d->flickableDirection;
}
Oct 21, 2011
Oct 21, 2011
789
void QQuickFlickable::setFlickableDirection(FlickableDirection direction)
Apr 27, 2011
Apr 27, 2011
790
{
Oct 21, 2011
Oct 21, 2011
791
Q_D(QQuickFlickable);
Apr 27, 2011
Apr 27, 2011
792
793
794
795
796
797
if (direction != d->flickableDirection) {
d->flickableDirection = direction;
emit flickableDirectionChanged();
}
}
Oct 21, 2011
Oct 21, 2011
798
bool QQuickFlickable::pixelAligned() const
Sep 12, 2011
Sep 12, 2011
799
{
Oct 21, 2011
Oct 21, 2011
800
Q_D(const QQuickFlickable);
Sep 12, 2011
Sep 12, 2011
801
802
803
return d->pixelAligned;
}
Oct 21, 2011
Oct 21, 2011
804
void QQuickFlickable::setPixelAligned(bool align)
Sep 12, 2011
Sep 12, 2011
805
{
Oct 21, 2011
Oct 21, 2011
806
Q_D(QQuickFlickable);
Sep 12, 2011
Sep 12, 2011
807
808
809
810
811
812
if (align != d->pixelAligned) {
d->pixelAligned = align;
emit pixelAlignedChanged();
}
}
Dec 20, 2011
Dec 20, 2011
813
814
815
816
817
818
819
820
qint64 QQuickFlickablePrivate::computeCurrentTime(QInputEvent *event)
{
if (0 != event->timestamp() && QQuickItemPrivate::consistentTime == -1)
return event->timestamp();
return QQuickItemPrivate::elapsed(timer);
}
Oct 21, 2011
Oct 21, 2011
821
void QQuickFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
Apr 27, 2011
Apr 27, 2011
822
{
Oct 21, 2011
Oct 21, 2011
823
Q_Q(QQuickFlickable);
Dec 20, 2011
Dec 20, 2011
824
QQuickItemPrivate::start(timer);
Apr 27, 2011
Apr 27, 2011
825
if (interactive && timeline.isActive()
Mar 13, 2012
Mar 13, 2012
826
827
&& ((qAbs(hData.smoothVelocity.value()) > RetainGrabVelocity && !hData.fixingUp && !hData.inOvershoot)
|| (qAbs(vData.smoothVelocity.value()) > RetainGrabVelocity && !vData.fixingUp && !vData.inOvershoot))) {
Apr 27, 2011
Apr 27, 2011
828
stealMouse = true; // If we've been flicked then steal the click.
Feb 2, 2012
Feb 2, 2012
829
830
831
832
833
834
835
836
837
838
839
840
int flickTime = timeline.time();
if (flickTime > 600) {
// too long between flicks - cancel boost
hData.continuousFlickVelocity = 0;
vData.continuousFlickVelocity = 0;
flickBoost = 1.0;
} else {
hData.continuousFlickVelocity = -hData.smoothVelocity.value();
vData.continuousFlickVelocity = -vData.smoothVelocity.value();
if (flickTime > 300) // slower flicking - reduce boost
flickBoost = qMax(1.0, flickBoost - 0.5);
}
Apr 27, 2011
Apr 27, 2011
841
842
} else {
stealMouse = false;
Feb 2, 2012
Feb 2, 2012
843
844
845
hData.continuousFlickVelocity = 0;
vData.continuousFlickVelocity = 0;
flickBoost = 1.0;
Apr 27, 2011
Apr 27, 2011
846
847
848
}
q->setKeepMouseGrab(stealMouse);
pressed = true;
Mar 13, 2012
Mar 13, 2012
849
850
851
852
if (!hData.fixingUp)
timeline.reset(hData.move);
if (!vData.fixingUp)
timeline.reset(vData.move);
May 4, 2011
May 4, 2011
853
854
hData.reset();
vData.reset();
Apr 27, 2011
Apr 27, 2011
855
856
857
858
hData.dragMinBound = q->minXExtent();
vData.dragMinBound = q->minYExtent();
hData.dragMaxBound = q->maxXExtent();
vData.dragMaxBound = q->maxYExtent();
May 4, 2011
May 4, 2011
859
fixupMode = Normal;
Nov 25, 2011
Nov 25, 2011
860
lastPos = QPointF();
Sep 1, 2011
Sep 1, 2011
861
pressPos = event->localPos();
Apr 27, 2011
Apr 27, 2011
862
863
hData.pressPos = hData.move.value();
vData.pressPos = vData.move.value();
Feb 7, 2012
Feb 7, 2012
864
865
866
867
868
869
870
871
872
873
874
bool wasFlicking = hData.flicking || vData.flicking;
if (hData.flicking) {
hData.flicking = false;
emit q->flickingHorizontallyChanged();
}
if (vData.flicking) {
vData.flicking = false;
emit q->flickingVerticallyChanged();
}
if (wasFlicking)
emit q->flickingChanged();
Feb 2, 2012
Feb 2, 2012
875
lastPosTime = lastPressTime = computeCurrentTime(event);
Oct 21, 2011
Oct 21, 2011
876
QQuickItemPrivate::start(velocityTime);
Apr 27, 2011
Apr 27, 2011
877
878
}
Oct 21, 2011
Oct 21, 2011
879
void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
Apr 27, 2011
Apr 27, 2011
880
{
Oct 21, 2011
Oct 21, 2011
881
Q_Q(QQuickFlickable);
Dec 20, 2011
Dec 20, 2011
882
if (!interactive || lastPosTime == -1)
Apr 27, 2011
Apr 27, 2011
883
884
885
886
887
888
889
return;
bool rejectY = false;
bool rejectX = false;
bool stealY = stealMouse;
bool stealX = stealMouse;
Mar 21, 2012
Mar 21, 2012
890
qint64 elapsedSincePress = computeCurrentTime(event) - lastPressTime;
Dec 20, 2011
Dec 20, 2011
891
Apr 27, 2011
Apr 27, 2011
892
if (q->yflick()) {
Nov 25, 2011
Nov 25, 2011
893
qreal dy = event->localPos().y() - pressPos.y();
Mar 21, 2012
Mar 21, 2012
894
if (qAbs(dy) > qApp->styleHints()->startDragDistance() || elapsedSincePress > 200) {
Apr 27, 2011
Apr 27, 2011
895
896
897
898
899
900
901
902
903
if (!vMoved)
vData.dragStartOffset = dy;
qreal newY = dy + vData.pressPos - vData.dragStartOffset;
const qreal minY = vData.dragMinBound;
const qreal maxY = vData.dragMaxBound;
if (newY > minY)
newY = minY + (newY - minY) / 2;
if (newY < maxY && maxY - minY <= 0)
newY = maxY + (newY - maxY) / 2;
Oct 21, 2011
Oct 21, 2011
904
if (boundsBehavior == QQuickFlickable::StopAtBounds && (newY > minY || newY < maxY)) {
Apr 27, 2011
Apr 27, 2011
905
906
907
908
909
910
911
912
913
914
rejectY = true;
if (newY < maxY) {
newY = maxY;
rejectY = false;
}
if (newY > minY) {
newY = minY;
rejectY = false;
}
}
Feb 7, 2012
Feb 7, 2012
915
if (!rejectY && stealMouse && dy != 0.0) {
Mar 13, 2012
Mar 13, 2012
916
timeline.clear();
Feb 10, 2012
Feb 10, 2012
917
vData.move.setValue(newY);
Apr 27, 2011
Apr 27, 2011
918
919
vMoved = true;
}
Sep 1, 2011
Sep 1, 2011
920
if (qAbs(dy) > qApp->styleHints()->startDragDistance())
Apr 27, 2011
Apr 27, 2011
921
922
923
924
925
stealY = true;
}
}
if (q->xflick()) {
Nov 25, 2011
Nov 25, 2011
926
qreal dx = event->localPos().x() - pressPos.x();
Mar 21, 2012
Mar 21, 2012
927
if (qAbs(dx) > qApp->styleHints()->startDragDistance() || elapsedSincePress > 200) {
Apr 27, 2011
Apr 27, 2011
928
929
930
931
932
933
934
935
936
if (!hMoved)
hData.dragStartOffset = dx;
qreal newX = dx + hData.pressPos - hData.dragStartOffset;
const qreal minX = hData.dragMinBound;
const qreal maxX = hData.dragMaxBound;
if (newX > minX)
newX = minX + (newX - minX) / 2;
if (newX < maxX && maxX - minX <= 0)
newX = maxX + (newX - maxX) / 2;
Oct 21, 2011
Oct 21, 2011
937
if (boundsBehavior == QQuickFlickable::StopAtBounds && (newX > minX || newX < maxX)) {
Apr 27, 2011
Apr 27, 2011
938
939
940
941
942
943
944
945
946
947
rejectX = true;
if (newX < maxX) {
newX = maxX;
rejectX = false;
}
if (newX > minX) {
newX = minX;
rejectX = false;
}
}
Feb 7, 2012
Feb 7, 2012
948
if (!rejectX && stealMouse && dx != 0.0) {
Mar 13, 2012
Mar 13, 2012
949
timeline.clear();
Feb 10, 2012
Feb 10, 2012
950
hData.move.setValue(newX);
Apr 27, 2011
Apr 27, 2011
951
952
953
hMoved = true;
}
Sep 1, 2011
Sep 1, 2011
954
if (qAbs(dx) > qApp->styleHints()->startDragDistance())
Apr 27, 2011
Apr 27, 2011
955
956
957
958
959
960
961
962
stealX = true;
}
}
stealMouse = stealX || stealY;
if (stealMouse)
q->setKeepMouseGrab(true);
May 4, 2011
May 4, 2011
963
964
965
966
967
968
969
if (rejectY) {
vData.velocityBuffer.clear();
vData.velocity = 0;
}
if (rejectX) {
hData.velocityBuffer.clear();
hData.velocity = 0;
Apr 27, 2011
Apr 27, 2011
970
971
972
}
if (hMoved || vMoved) {
Jul 28, 2011
Jul 28, 2011
973
draggingStarting();
Apr 27, 2011
Apr 27, 2011
974
975
976
q->movementStarting();
}
Mar 21, 2012
Mar 21, 2012
977
978
979
980
981
982
983
984
985
986
987
988
qint64 currentTimestamp = computeCurrentTime(event);
qreal elapsed = qreal(currentTimestamp - (lastPos.isNull() ? lastPressTime : lastPosTime)) / 1000.;
if (elapsed <= 0)
return;
lastPosTime = currentTimestamp;
QQuickMouseEventEx *extended = QQuickMouseEventEx::extended(event);
if (q->yflick() && !rejectY) {
if (extended && extended->capabilities().testFlag(QTouchDevice::Velocity)) {
vData.addVelocitySample(extended->velocity().y(), maxVelocity);
} else {
qreal dy = event->localPos().y() - (lastPos.isNull() ? pressPos.y() : lastPos.y());
vData.addVelocitySample(dy/elapsed, maxVelocity);
Feb 10, 2012
Feb 10, 2012
989
}
Mar 21, 2012
Mar 21, 2012
990
991
992
993
994
995
996
}
if (q->xflick() && !rejectX) {
if (extended && extended->capabilities().testFlag(QTouchDevice::Velocity)) {
hData.addVelocitySample(extended->velocity().x(), maxVelocity);
} else {
qreal dx = event->localPos().x() - (lastPos.isNull() ? pressPos.x() : lastPos.x());
hData.addVelocitySample(dx/elapsed, maxVelocity);
Feb 10, 2012
Feb 10, 2012
997
}
May 4, 2011
May 4, 2011
998
999
}
Sep 1, 2011
Sep 1, 2011
1000
lastPos = event->localPos();