diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-08-05 16:57:25 (GMT) |
---|---|---|
committer | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-08-10 12:21:44 (GMT) |
commit | 6826490774d66e0470fc1e5848ab89b3a0d0bb86 (patch) | |
tree | 553656766c1625ca837e3d07f59f77e6f3461ace /src/gui/kernel/qstandardgestures.cpp | |
parent | 47f58dfad1eb7fe61a523597023df33f3d320377 (diff) | |
download | Qt-6826490774d66e0470fc1e5848ab89b3a0d0bb86.zip Qt-6826490774d66e0470fc1e5848ab89b3a0d0bb86.tar.gz Qt-6826490774d66e0470fc1e5848ab89b3a0d0bb86.tar.bz2 |
Implemented QPinchGesture.
Added a new standard gesture, which is implemented using a native zoom and
rotate gestures on Windows and with a direct touch event handling on other
platforms.
Improved pan support - we subscribe to native pan gesture only when it's really
needed, and we pass proper flags for single finger horizontal/vertical panning.
Reviewed-by: Richard Moe Gustavsen
Diffstat (limited to 'src/gui/kernel/qstandardgestures.cpp')
-rw-r--r-- | src/gui/kernel/qstandardgestures.cpp | 210 |
1 files changed, 207 insertions, 3 deletions
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 7078dbf..ac03cd2 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -132,8 +132,7 @@ bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) it = qAppPriv->widgetGestures.find(static_cast<QWidget*>(receiver)); if (it == qAppPriv->widgetGestures.end()) return false; - QPanGesture *gesture = it.value().pan; - if (this != gesture) + if (this != it.value().pan) return false; Qt::GestureState nextState = Qt::NoGesture; switch(ev->gestureType) { @@ -162,7 +161,7 @@ bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) d->totalOffset += d->lastOffset; } d->lastPosition = ev->position; - gesture->updateState(nextState); + updateState(nextState); return true; } #endif @@ -248,6 +247,7 @@ void QPanGesture::reset() d->panFinishedTimer = 0; } #endif + QGesture::reset(); } /*! @@ -273,6 +273,210 @@ QSize QPanGesture::lastOffset() const return d->lastOffset; } + +/*! + \class QPinchGesture + \since 4.6 + + \brief The QPinchGesture class represents a Pinch gesture, + providing additional information related to zooming and/or rotation. +*/ + +/*! + Creates a new Pinch gesture handler object and marks it as a child of \a + parent. + + On some platform like Windows it's necessary to provide a non-null widget + as \a parent to get native gesture support. +*/ +QPinchGesture::QPinchGesture(QWidget *parent) + : QGesture(*new QPinchGesturePrivate, parent) +{ + if (parent) { + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + qAppPriv->widgetGestures[parent].pinch = this; +#ifdef Q_WS_WIN + qt_widget_private(parent)->winSetupGestures(); +#endif + } +} + +/*! \internal */ +bool QPinchGesture::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::ParentAboutToChange: + if (QWidget *w = qobject_cast<QWidget*>(parent())) { + getQApplicationPrivateInternal()->widgetGestures[w].pinch = 0; +#ifdef Q_WS_WIN + qt_widget_private(w)->winSetupGestures(); +#endif + } + break; + case QEvent::ParentChange: + if (QWidget *w = qobject_cast<QWidget*>(parent())) { + getQApplicationPrivateInternal()->widgetGestures[w].pinch = this; +#ifdef Q_WS_WIN + qt_widget_private(w)->winSetupGestures(); +#endif + } + break; + default: + break; + } + return QObject::event(event); +} + +bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) +{ +#ifdef Q_WS_WIN + Q_D(QPinchGesture); + if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { + QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + QApplicationPrivate::WidgetStandardGesturesMap::iterator it; + it = qAppPriv->widgetGestures.find(static_cast<QWidget*>(receiver)); + if (it == qAppPriv->widgetGestures.end()) + return false; + if (this != it.value().pinch) + return false; + Qt::GestureState nextState = Qt::NoGesture; + switch(ev->gestureType) { + case QNativeGestureEvent::GestureBegin: + // next we might receive the first gesture update event, so we + // prepare for it. + d->state = Qt::NoGesture; + d->scaleFactor = d->lastScaleFactor = 1; + d->rotationAngle = d->lastRotationAngle = 0; + d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPoint(); + d->initialDistance = 0; + return false; + case QNativeGestureEvent::Rotate: + d->lastRotationAngle = d->rotationAngle; + d->rotationAngle = -1 * GID_ROTATE_ANGLE_FROM_ARGUMENT(ev->argument); + nextState = Qt::GestureUpdated; + event->accept(); + break; + case QNativeGestureEvent::Zoom: + if (d->initialDistance != 0) { + d->lastScaleFactor = d->scaleFactor; + int distance = int(qint64(ev->argument)); + d->scaleFactor = (qreal) distance / d->initialDistance; + } else { + d->initialDistance = int(qint64(ev->argument)); + } + nextState = Qt::GestureUpdated; + event->accept(); + break; + case QNativeGestureEvent::GestureEnd: + if (state() == Qt::NoGesture) + return false; // some other gesture has ended + nextState = Qt::GestureFinished; + break; + default: + return false; + } + if (d->startCenterPoint.isNull()) + d->startCenterPoint = d->centerPoint; + d->lastCenterPoint = d->centerPoint; + d->centerPoint = static_cast<QWidget*>(receiver)->mapFromGlobal(ev->position); + updateState(nextState); + return true; + } +#endif + return QGesture::eventFilter(receiver, event); +} + +/*! \internal */ +bool QPinchGesture::filterEvent(QEvent *event) +{ + Q_UNUSED(event); + return false; +} + +/*! \internal */ +void QPinchGesture::reset() +{ + Q_D(QPinchGesture); + d->scaleFactor = d->lastScaleFactor = 0; + d->rotationAngle = d->lastRotationAngle = 0; + d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPoint(); + QGesture::reset(); +} + +/*! + \property QPinchGesture::scaleFactor + + Specifies a scale factor of the pinch gesture. +*/ +qreal QPinchGesture::scaleFactor() const +{ + return d_func()->scaleFactor; +} + +/*! + \property QPinchGesture::lastScaleFactor + + Specifies a previous scale factor of the pinch gesture. +*/ +qreal QPinchGesture::lastScaleFactor() const +{ + return d_func()->lastScaleFactor; +} + +/*! + \property QPinchGesture::rotationAngle + + Specifies a rotation angle of the gesture. +*/ +qreal QPinchGesture::rotationAngle() const +{ + return d_func()->rotationAngle; +} + +/*! + \property QPinchGesture::lastRotationAngle + + Specifies a previous rotation angle of the gesture. +*/ +qreal QPinchGesture::lastRotationAngle() const +{ + return d_func()->lastRotationAngle; +} + +/*! + \property QPinchGesture::centerPoint + + Specifies a center point of the gesture. The point can be used as a center + point that the object is rotated around. +*/ +QPoint QPinchGesture::centerPoint() const +{ + return d_func()->centerPoint; +} + +/*! + \property QPinchGesture::lastCenterPoint + + Specifies a previous center point of the gesture. +*/ +QPoint QPinchGesture::lastCenterPoint() const +{ + return d_func()->lastCenterPoint; +} + +/*! + \property QPinchGesture::startCenterPoint + + Specifies an initial center point of the gesture. Difference between the + startCenterPoint and the centerPoint is the distance at which pinching + fingers has shifted. +*/ +QPoint QPinchGesture::startCenterPoint() const +{ + return d_func()->startCenterPoint; +} + QT_END_NAMESPACE #include "moc_qstandardgestures.cpp" |