diff options
author | Martin Jones <martin.jones@nokia.com> | 2009-09-08 00:11:10 (GMT) |
---|---|---|
committer | Martin Jones <martin.jones@nokia.com> | 2009-09-08 00:11:10 (GMT) |
commit | 276a44c0867a76a90b425baa8dcbda733d25b3fb (patch) | |
tree | d08f643a5bea2249447d428999f6ac3ea9679ded | |
parent | 89e0ecfb4afe8b6f1d8cbfe64cfd493ad423919e (diff) | |
download | Qt-276a44c0867a76a90b425baa8dcbda733d25b3fb.zip Qt-276a44c0867a76a90b425baa8dcbda733d25b3fb.tar.gz Qt-276a44c0867a76a90b425baa8dcbda733d25b3fb.tar.bz2 |
Add a pressDelay property to Flickable.
Helps reduce undesireable effects of reacting to a press immediately
before a drag/flick.
-rw-r--r-- | src/declarative/fx/qfxflickable.cpp | 88 | ||||
-rw-r--r-- | src/declarative/fx/qfxflickable.h | 5 | ||||
-rw-r--r-- | src/declarative/fx/qfxflickable_p.h | 7 |
3 files changed, 98 insertions, 2 deletions
diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp index 007fa0e..5fe9617 100644 --- a/src/declarative/fx/qfxflickable.cpp +++ b/src/declarative/fx/qfxflickable.cpp @@ -148,6 +148,7 @@ QFxFlickablePrivate::QFxFlickablePrivate() , vWidth(-1), vHeight(-1), overShoot(true), flicked(false), moving(false), stealMouse(false) , pressed(false), atXEnd(false), atXBeginning(true), atYEnd(false), atYBeginning(true) , interactive(true), maxVelocity(-1), reportedVelocitySmoothing(100) + , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0) , horizontalVelocity(this), verticalVelocity(this), vTime(0), visibleArea(0) { fixupXEvent = QmlTimeLineEvent::timeLineEvent<QFxFlickablePrivate, &QFxFlickablePrivate::fixupX>(&_moveX, this); @@ -707,11 +708,57 @@ void QFxFlickable::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void QFxFlickable::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QFxFlickable); + d->clearDelayedPress(); d->handleMouseReleaseEvent(event); event->accept(); ungrabMouse(); } +void QFxFlickablePrivate::captureDelayedPress(QGraphicsSceneMouseEvent *event) +{ + Q_Q(QFxFlickable); + if (!q->scene() || pressDelay <= 0) + return; + delayedPressTarget = q->scene()->mouseGrabberItem(); + delayedPressEvent = new QGraphicsSceneMouseEvent(event->type()); + delayedPressEvent->setAccepted(false); + for (int i = 0x1; i <= 0x10; i <<= 1) { + if (event->buttons() & i) { + Qt::MouseButton button = Qt::MouseButton(i); + delayedPressEvent->setButtonDownPos(button, event->buttonDownPos(button)); + } + } + delayedPressEvent->setScenePos(event->scenePos()); + delayedPressEvent->setLastScenePos(event->lastScenePos()); + delayedPressEvent->setPos(event->pos()); + delayedPressEvent->setLastPos(event->lastPos()); + delayedPressTimer.start(pressDelay, q); +} + +void QFxFlickablePrivate::clearDelayedPress() +{ + if (delayedPressEvent) { + delayedPressTimer.stop(); + delete delayedPressEvent; + delayedPressEvent = 0; + } +} + +void QFxFlickable::timerEvent(QTimerEvent *event) +{ + Q_D(QFxFlickable); + if (event->timerId() == d->delayedPressTimer.timerId()) { + d->delayedPressTimer.stop(); + if (d->delayedPressEvent) { + QFxItem *grabber = scene() ? qobject_cast<QFxItem*>(scene()->mouseGrabberItem()) : 0; + if (!grabber || grabber != this) + scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent); + delete d->delayedPressEvent; + d->delayedPressEvent = 0; + } + } +} + qreal QFxFlickable::minYExtent() const { return 0.0; @@ -996,22 +1043,34 @@ bool QFxFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) d->handleMouseMoveEvent(&mouseEvent); break; case QEvent::GraphicsSceneMousePress: + if (d->delayedPressEvent) + return false; + d->handleMousePressEvent(&mouseEvent); + d->captureDelayedPress(event); break; case QEvent::GraphicsSceneMouseRelease: + if (d->delayedPressEvent) { + scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent); + d->clearDelayedPress(); + } d->handleMouseReleaseEvent(&mouseEvent); break; default: break; } grabber = qobject_cast<QFxItem*>(s->mouseGrabberItem()); - if (grabber && d->stealMouse && !grabber->keepMouseGrab() && grabber != this) + if (grabber && d->stealMouse && !grabber->keepMouseGrab() && grabber != this) { + d->clearDelayedPress(); grabMouse(); + } - return d->stealMouse; + return d->stealMouse || d->delayedPressEvent; } else if (!d->lastPosTime.isNull()) { d->lastPosTime = QTime(); } + if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) + d->clearDelayedPress(); return false; } @@ -1055,6 +1114,31 @@ bool QFxFlickable::isFlicking() const return d->flicked; } +/*! + \qmlproperty int Flickable::pressDelay + + This property holds the time to delay (ms) delivering a press to + children of the Flickable. This can be useful where reacting + to a press before a flicking action has undesireable effects. + + If the flickable is dragged/flicked before the delay times out + the press event will not be delivered. If the button is released + within the timeout, both the press and release will be delivered. +*/ +int QFxFlickable::pressDelay() const +{ + Q_D(const QFxFlickable); + return d->pressDelay; +} + +void QFxFlickable::setPressDelay(int delay) +{ + Q_D(QFxFlickable); + if (d->pressDelay == delay) + return; + d->pressDelay = delay; +} + qreal QFxFlickable::reportedVelocitySmoothing() const { Q_D(const QFxFlickable); diff --git a/src/declarative/fx/qfxflickable.h b/src/declarative/fx/qfxflickable.h index 4905101..b3339b0 100644 --- a/src/declarative/fx/qfxflickable.h +++ b/src/declarative/fx/qfxflickable.h @@ -71,6 +71,7 @@ class Q_DECLARATIVE_EXPORT QFxFlickable : public QFxItem Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged) Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive) + Q_PROPERTY(int pressDelay READ pressDelay WRITE setPressDelay) Q_PROPERTY(bool atXEnd READ isAtXEnd NOTIFY isAtBoundaryChanged) Q_PROPERTY(bool atYEnd READ isAtYEnd NOTIFY isAtBoundaryChanged) @@ -108,6 +109,9 @@ public: bool isMoving() const; bool isFlicking() const; + int pressDelay() const; + void setPressDelay(int delay); + qreal reportedVelocitySmoothing() const; void setReportedVelocitySmoothing(qreal); @@ -148,6 +152,7 @@ protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void timerEvent(QTimerEvent *event); qreal visibleX() const; qreal visibleY() const; diff --git a/src/declarative/fx/qfxflickable_p.h b/src/declarative/fx/qfxflickable_p.h index a506027..7224f21 100644 --- a/src/declarative/fx/qfxflickable_p.h +++ b/src/declarative/fx/qfxflickable_p.h @@ -76,6 +76,9 @@ public: virtual void fixupY(); void updateBeginningEnd(); + void captureDelayedPress(QGraphicsSceneMouseEvent *event); + void clearDelayedPress(); + public: QFxItem *viewport; QmlTimeLineValueProxy<QFxItem> _moveX; @@ -109,6 +112,10 @@ public: qreal reportedVelocitySmoothing; int flickTargetX; int flickTargetY; + QGraphicsSceneMouseEvent *delayedPressEvent; + QGraphicsItem *delayedPressTarget; + QBasicTimer delayedPressTimer; + int pressDelay; void updateVelocity(); struct Velocity : public QmlTimeLineValue |