diff options
author | David Boddie <dboddie@trolltech.com> | 2009-08-14 15:18:48 (GMT) |
---|---|---|
committer | David Boddie <dboddie@trolltech.com> | 2009-08-14 15:18:48 (GMT) |
commit | 9db9c1f2215e32047c7329ab769d54dd3c1ddeb7 (patch) | |
tree | 98acb9a60cf237138f939b5dadb0d9ae7722ddeb /doc/src/snippets/gestures | |
parent | e9d32707afeddfdd2906af7bed60c375b1035dd6 (diff) | |
parent | 3c8f4512df30dee4a867a498fff6d2b27b881e4b (diff) | |
download | Qt-9db9c1f2215e32047c7329ab769d54dd3c1ddeb7.zip Qt-9db9c1f2215e32047c7329ab769d54dd3c1ddeb7.tar.gz Qt-9db9c1f2215e32047c7329ab769d54dd3c1ddeb7.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt
Diffstat (limited to 'doc/src/snippets/gestures')
-rw-r--r-- | doc/src/snippets/gestures/qgesture.cpp | 283 | ||||
-rw-r--r-- | doc/src/snippets/gestures/qgesture.h | 101 | ||||
-rw-r--r-- | doc/src/snippets/gestures/qstandardgestures.cpp | 483 | ||||
-rw-r--r-- | doc/src/snippets/gestures/qstandardgestures.h | 126 |
4 files changed, 993 insertions, 0 deletions
diff --git a/doc/src/snippets/gestures/qgesture.cpp b/doc/src/snippets/gestures/qgesture.cpp new file mode 100644 index 0000000..79dcae1 --- /dev/null +++ b/doc/src/snippets/gestures/qgesture.cpp @@ -0,0 +1,283 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgesture.h" +#include <private/qgesture_p.h> +#include "qgraphicsitem.h" + +QT_BEGIN_NAMESPACE + + +class QEventFilterProxyGraphicsItem : public QGraphicsItem +{ +public: + QEventFilterProxyGraphicsItem(QGesture *g) + : gesture(g) + { + } + bool sceneEventFilter(QGraphicsItem *, QEvent *event) + { + return gesture ? gesture->filterEvent(event) : false; + } + QRectF boundingRect() const { return QRectF(); } + void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) { } + +private: + QGesture *gesture; +}; + +/*! + \class QGesture + \since 4.6 + + \brief The QGesture class is the base class for implementing custom + gestures. + + This class represents both an object that recognizes a gesture out of a set + of input events (a gesture recognizer), and a gesture object itself that + can be used to get extended information about the triggered gesture. + + The class has a list of properties that can be queried by the user to get + some gesture-specific parameters (for example, an offset of a Pan gesture). + + Usually gesture recognizer implements a state machine, storing its state + internally in the recognizer object. The recognizer receives input events + through the \l{QGesture::}{filterEvent()} virtual function and decides + whether the event should change the state of the recognizer by emitting an + appropriate signal. + + Input events should be either fed to the recognizer one by one with a + filterEvent() function, or the gesture recognizer should be attached to an + object it filters events for by specifying it as a parent object. The + QGesture object installs itself as an event filter to the parent object + automatically, the unsetObject() function should be used to remove an event + filter from the parent object. To make a + gesture that operates on a QGraphicsItem, both the appropriate QGraphicsView + should be passed as a parent object and setGraphicsItem() functions should + be used to attach a gesture to a graphics item. + + This is a base class, to create a custom gesture type, you should subclass + it and implement its pure virtual functions. + + \sa QPanGesture +*/ + +/*! \fn bool QGesture::filterEvent(QEvent *event) + + Parses input \a event and emits a signal when detects a gesture. + + In your reimplementation of this function, if you want to filter the \a + event out, i.e. stop it being handled further, return true; otherwise + return false; + + This is a pure virtual function that needs to be implemented in subclasses. +*/ + +/*! \fn void QGesture::started() + + The signal is emitted when the gesture is started. Extended information + about the gesture is contained in the signal sender object. + + In addition to started(), a triggered() signal should also be emitted. +*/ + +/*! \fn void QGesture::triggered() + + The signal is emitted when the gesture is detected. Extended information + about the gesture is contained in the signal sender object. +*/ + +/*! \fn void QGesture::finished() + + The signal is emitted when the gesture is finished. Extended information + about the gesture is contained in the signal sender object. +*/ + +/*! \fn void QGesture::cancelled() + + The signal is emitted when the gesture is cancelled, for example the reset() + function is called while the gesture was in the process of emitting a + triggered() signal. Extended information about the gesture is contained in + the sender object. +*/ + + +/*! + Creates a new gesture handler object and marks it as a child of \a parent. + + The \a parent object is also the default event source for the gesture, + meaning that the gesture installs itself as an event filter for the \a + parent. + + \sa setGraphicsItem() +*/ +QGesture::QGesture(QObject *parent) + : QObject(*new QGesturePrivate, parent) +{ + if (parent) + parent->installEventFilter(this); +} + +/*! \internal + */ +QGesture::QGesture(QGesturePrivate &dd, QObject *parent) + : QObject(dd, parent) +{ + if (parent) + parent->installEventFilter(this); +} + +/*! + Destroys the gesture object. +*/ +QGesture::~QGesture() +{ +} + +/*! \internal + */ +bool QGesture::eventFilter(QObject *receiver, QEvent *event) +{ + Q_D(QGesture); + if (d->graphicsItem && receiver == parent()) + return false; + return filterEvent(event); +} + +/*! + \property QGesture::state + + \brief The current state of the gesture. +*/ + +/*! + Returns the gesture recognition state. + */ +Qt::GestureState QGesture::state() const +{ + return d_func()->state; +} + +/*! + Sets this gesture's recognition state to \a state and emits appropriate + signals. + + This functions emits the signals according to the old state and the new + \a state, and it should be called after all the internal properties have been + initialized. + + \sa started(), triggered(), finished(), cancelled() + */ +void QGesture::updateState(Qt::GestureState state) +{ + Q_D(QGesture); + if (d->state == state) { + if (state == Qt::GestureUpdated) + emit triggered(); + return; + } + const Qt::GestureState oldState = d->state; + d->state = state; + if (state != Qt::NoGesture && oldState > state) { + // comparing the state as ints: state should only be changed from + // started to (optionally) updated and to finished. + qWarning("QGesture::updateState: incorrect new state"); + return; + } + if (oldState == Qt::NoGesture) + emit started(); + if (state == Qt::GestureUpdated) + emit triggered(); + else if (state == Qt::GestureFinished) + emit finished(); + else if (state == Qt::NoGesture) + emit cancelled(); + + if (state == Qt::GestureFinished) { + // gesture is finished, so we reset the internal state. + d->state = Qt::NoGesture; + } +} + +/*! + Sets the \a graphicsItem the gesture is filtering events for. + + The gesture will install an event filter to the \a graphicsItem and + redirect them to the filterEvent() function. + + \sa graphicsItem() +*/ +void QGesture::setGraphicsItem(QGraphicsItem *graphicsItem) +{ + Q_D(QGesture); + if (d->graphicsItem && d->eventFilterProxyGraphicsItem) + d->graphicsItem->removeSceneEventFilter(d->eventFilterProxyGraphicsItem); + d->graphicsItem = graphicsItem; + if (!d->eventFilterProxyGraphicsItem) + d->eventFilterProxyGraphicsItem = new QEventFilterProxyGraphicsItem(this); + if (graphicsItem) + graphicsItem->installSceneEventFilter(d->eventFilterProxyGraphicsItem); +} + +/*! + Returns the graphics item the gesture is filtering events for. + + \sa setGraphicsItem() +*/ +QGraphicsItem* QGesture::graphicsItem() const +{ + return d_func()->graphicsItem; +} + +/*! \fn void QGesture::reset() + + Resets the internal state of the gesture. This function might be called by + the filterEvent() implementation in a derived class, or by the user to + cancel a gesture. The base class implementation calls + updateState(Qt::NoGesture) which emits the cancelled() + signal if the state() of the gesture indicated it was active. +*/ +void QGesture::reset() +{ + updateState(Qt::NoGesture); +} + +QT_END_NAMESPACE diff --git a/doc/src/snippets/gestures/qgesture.h b/doc/src/snippets/gestures/qgesture.h new file mode 100644 index 0000000..beb3de0 --- /dev/null +++ b/doc/src/snippets/gestures/qgesture.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGESTURE_H +#define QGESTURE_H + +#include <QtCore/qobject.h> +#include <QtCore/qlist.h> +#include <QtCore/qdatetime.h> +#include <QtCore/qpoint.h> +#include <QtCore/qrect.h> +#include <QtCore/qmetatype.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QGraphicsItem; +class QGesturePrivate; +class Q_GUI_EXPORT QGesture : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QGesture) + + Q_PROPERTY(Qt::GestureState state READ state) + +public: + explicit QGesture(QObject *parent = 0); + ~QGesture(); + + virtual bool filterEvent(QEvent *event) = 0; + + void setGraphicsItem(QGraphicsItem *); + QGraphicsItem *graphicsItem() const; + + Qt::GestureState state() const; + +protected: + QGesture(QGesturePrivate &dd, QObject *parent); + bool eventFilter(QObject*, QEvent*); + + virtual void reset(); + void updateState(Qt::GestureState state); + +//! [qgesture-signals] +Q_SIGNALS: + void started(); + void triggered(); + void finished(); + void cancelled(); +//! [qgesture-signals] + +private: + friend class QWidget; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGESTURE_H diff --git a/doc/src/snippets/gestures/qstandardgestures.cpp b/doc/src/snippets/gestures/qstandardgestures.cpp new file mode 100644 index 0000000..fbeb050 --- /dev/null +++ b/doc/src/snippets/gestures/qstandardgestures.cpp @@ -0,0 +1,483 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstandardgestures.h" +#include "qstandardgestures_p.h" + +#include <qabstractscrollarea.h> +#include <qscrollbar.h> +#include <private/qapplication_p.h> +#include <private/qevent_p.h> +#include <private/qwidget_p.h> + +QT_BEGIN_NAMESPACE + +#ifdef Q_WS_WIN +QWidgetPrivate *qt_widget_private(QWidget *widget); +#endif + +/*! + \class QPanGesture + \since 4.6 + + \brief The QPanGesture class represents a Pan gesture, + providing additional information related to panning. +*/ + +/*! + Creates a new Pan 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. +*/ +QPanGesture::QPanGesture(QWidget *parent) + : QGesture(*new QPanGesturePrivate, parent) +{ + if (parent) { + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); + qAppPriv->widgetGestures[parent].pan = this; +#ifdef Q_WS_WIN + qt_widget_private(parent)->winSetupGestures(); +#endif + } +} + +/*! \internal */ +bool QPanGesture::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::ParentAboutToChange: + if (QWidget *w = qobject_cast<QWidget*>(parent())) { + QApplicationPrivate::instance()->widgetGestures[w].pan = 0; +#ifdef Q_WS_WIN + qt_widget_private(w)->winSetupGestures(); +#endif + } + break; + case QEvent::ParentChange: + if (QWidget *w = qobject_cast<QWidget*>(parent())) { + QApplicationPrivate::instance()->widgetGestures[w].pan = this; +#ifdef Q_WS_WIN + qt_widget_private(w)->winSetupGestures(); +#endif + } + break; + default: + break; + } + +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + Q_D(QPanGesture); + if (event->type() == QEvent::Timer) { + const QTimerEvent *te = static_cast<QTimerEvent *>(event); + if (te->timerId() == d->panFinishedTimer) { + killTimer(d->panFinishedTimer); + d->panFinishedTimer = 0; + d->lastOffset = QSize(0, 0); + updateState(Qt::GestureFinished); + } + } +#endif + + return QObject::event(event); +} + +bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) +{ +#ifdef Q_WS_WIN + Q_D(QPanGesture); + if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { + QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); + QApplicationPrivate::WidgetStandardGesturesMap::iterator it; + it = qAppPriv->widgetGestures.find(static_cast<QWidget*>(receiver)); + if (it == qAppPriv->widgetGestures.end()) + return false; + if (this != it.value().pan) + 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; + return false; + case QNativeGestureEvent::Pan: + 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 (state() == Qt::NoGesture) { + d->lastOffset = d->totalOffset = QSize(); + } else { + d->lastOffset = QSize(ev->position.x() - d->lastPosition.x(), + ev->position.y() - d->lastPosition.y()); + d->totalOffset += d->lastOffset; + } + d->lastPosition = ev->position; + updateState(nextState); + return true; + } +#endif + return QGesture::eventFilter(receiver, event); +} + +/*! \internal */ +bool QPanGesture::filterEvent(QEvent *event) +{ + Q_D(QPanGesture); + if (!event->spontaneous()) + return false; + const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); + if (event->type() == QEvent::TouchBegin) { + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + d->lastPosition = p.pos().toPoint(); + d->lastOffset = d->totalOffset = QSize(); + } else if (event->type() == QEvent::TouchEnd) { + if (state() != Qt::NoGesture) { + if (!ev->touchPoints().isEmpty()) { + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + const QPoint pos = p.pos().toPoint(); + const QPoint lastPos = p.lastPos().toPoint(); + const QPoint startPos = p.startPos().toPoint(); + d->lastOffset = QSize(pos.x() - lastPos.x(), pos.y() - lastPos.y()); + d->totalOffset = QSize(pos.x() - startPos.x(), pos.y() - startPos.y()); + } + updateState(Qt::GestureFinished); + } + reset(); + } else if (event->type() == QEvent::TouchUpdate) { + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + const QPoint pos = p.pos().toPoint(); + const QPoint lastPos = p.lastPos().toPoint(); + const QPoint startPos = p.startPos().toPoint(); + d->lastOffset = QSize(pos.x() - lastPos.x(), pos.y() - lastPos.y()); + d->totalOffset = QSize(pos.x() - startPos.x(), pos.y() - startPos.y()); + if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 || + d->totalOffset.width() < -10 || d->totalOffset.height() < -10) { + updateState(Qt::GestureUpdated); + } + } +#ifdef Q_OS_MAC + else if (event->type() == QEvent::Wheel) { + // On Mac, there is really no native panning gesture. Instead, a two + // finger pan is delivered as mouse wheel events. Otoh, on Windows, you + // either get mouse wheel events or pan events. We have decided to make this + // the Qt behaviour as well, meaning that on Mac, wheel + // events will be masked away when listening for pan events. +#ifndef QT_MAC_USE_COCOA + // In Carbon we receive neither touch-, nor pan gesture events. + // So we create pan gestures by converting wheel events. After all, this + // is how things are supposed to work on mac in the first place. + const QWheelEvent *wev = static_cast<const QWheelEvent*>(event); + int offset = wev->delta() / -120; + d->lastOffset = wev->orientation() == Qt::Horizontal ? QSize(offset, 0) : QSize(0, offset); + + if (state() == Qt::NoGesture) { + d->totalOffset = d->lastOffset; + } else { + d->totalOffset += d->lastOffset; + } + + killTimer(d->panFinishedTimer); + d->panFinishedTimer = startTimer(200); + updateState(Qt::GestureUpdated); +#endif + return true; + } +#endif + return false; +} + +/*! \internal */ +void QPanGesture::reset() +{ + Q_D(QPanGesture); + d->lastOffset = d->totalOffset = QSize(); + d->lastPosition = QPoint(); +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + if (d->panFinishedTimer) { + killTimer(d->panFinishedTimer); + d->panFinishedTimer = 0; + } +#endif + QGesture::reset(); +} + +/*! + \property QPanGesture::totalOffset + + Specifies a total pan offset since the start of the gesture. +*/ +QSize QPanGesture::totalOffset() const +{ + Q_D(const QPanGesture); + return d->totalOffset; +} + +/*! + \property QPanGesture::lastOffset + + Specifies a pan offset since the last time the gesture was + triggered. +*/ +QSize QPanGesture::lastOffset() const +{ + Q_D(const QPanGesture); + 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 = QApplicationPrivate::instance(); + 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())) { + QApplicationPrivate::instance()->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())) { + QApplicationPrivate::instance()->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 = QApplicationPrivate::instance(); + 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" + diff --git a/doc/src/snippets/gestures/qstandardgestures.h b/doc/src/snippets/gestures/qstandardgestures.h new file mode 100644 index 0000000..8b5421b --- /dev/null +++ b/doc/src/snippets/gestures/qstandardgestures.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTANDARDGESTURES_H +#define QSTANDARDGESTURES_H + +#include <QtGui/qevent.h> +#include <QtCore/qbasictimer.h> + +#include <QtGui/qgesture.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QPanGesturePrivate; +class Q_GUI_EXPORT QPanGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QPanGesture) + + Q_PROPERTY(QSize totalOffset READ totalOffset) + Q_PROPERTY(QSize lastOffset READ lastOffset) + +public: + QPanGesture(QWidget *parent); + + bool filterEvent(QEvent *event); + + QSize totalOffset() const; + QSize lastOffset() const; + +protected: + void reset(); + +private: + bool event(QEvent *event); + bool eventFilter(QObject *receiver, QEvent *event); + + friend class QWidget; +}; + +class QPinchGesturePrivate; +class Q_GUI_EXPORT QPinchGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QPinchGesture) + + Q_PROPERTY(qreal scaleFactor READ scaleFactor) + Q_PROPERTY(qreal lastScaleFactor READ lastScaleFactor) + + Q_PROPERTY(qreal rotationAngle READ rotationAngle) + Q_PROPERTY(qreal lastRotationAngle READ lastRotationAngle) + + Q_PROPERTY(QPoint startCenterPoint READ startCenterPoint) + Q_PROPERTY(QPoint lastCenterPoint READ lastCenterPoint) + Q_PROPERTY(QPoint centerPoint READ centerPoint) + +public: + QPinchGesture(QWidget *parent); + + bool filterEvent(QEvent *event); + void reset(); + + QPoint startCenterPoint() const; + QPoint lastCenterPoint() const; + QPoint centerPoint() const; + + qreal scaleFactor() const; + qreal lastScaleFactor() const; + + qreal rotationAngle() const; + qreal lastRotationAngle() const; + +private: + bool event(QEvent *event); + bool eventFilter(QObject *receiver, QEvent *event); + + friend class QWidget; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSTANDARDGESTURES_H |