summaryrefslogtreecommitdiffstats
path: root/doc/src/snippets
diff options
context:
space:
mode:
authorJason Barron <jbarron@trolltech.com>2009-08-18 06:34:18 (GMT)
committerJason Barron <jbarron@trolltech.com>2009-08-18 06:34:18 (GMT)
commitfd6740b6ade6e7f8e51a9cc558b723e7fae15ccf (patch)
treeaa2ba4ce64d047d73c29ab0616e8a89d352c3abd /doc/src/snippets
parentd24029e3d4639f1300e7a68858936911df969f69 (diff)
parent572e165dcb8cc8fcdfaa4ab9bdab050f6a6cc173 (diff)
downloadQt-fd6740b6ade6e7f8e51a9cc558b723e7fae15ccf.zip
Qt-fd6740b6ade6e7f8e51a9cc558b723e7fae15ccf.tar.gz
Qt-fd6740b6ade6e7f8e51a9cc558b723e7fae15ccf.tar.bz2
Merge commit 'qt/master'
Conflicts: doc/src/examples.qdoc doc/src/plugins-howto.qdoc doc/src/topics.qdoc examples/phonon/musicplayer/mainwindow.cpp src/3rdparty/freetype/src/base/ftobjs.c src/corelib/global/qglobal.h src/corelib/tools/qalgorithms.h src/corelib/tools/qshareddata.cpp src/corelib/tools/qsharedpointer.cpp src/corelib/tools/tools.pri src/corelib/xml/qxmlstream.h src/gui/painting/painting.pri src/gui/widgets/qdatetimeedit.cpp tests/auto/qdesktopservices/qdesktopservices.pro tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp tests/auto/qtextcodec/test/test.pro
Diffstat (limited to 'doc/src/snippets')
-rw-r--r--doc/src/snippets/code/doc_src_qalgorithms.qdoc2
-rw-r--r--doc/src/snippets/code/doc_src_qtmultimedia.qdoc8
-rw-r--r--doc/src/snippets/gestures/imageviewer/imagewidget.cpp364
-rw-r--r--doc/src/snippets/gestures/imageviewer/imagewidget.h137
-rw-r--r--doc/src/snippets/gestures/imageviewer/tapandholdgesture.cpp159
-rw-r--r--doc/src/snippets/gestures/imageviewer/tapandholdgesture.h74
-rw-r--r--doc/src/snippets/gestures/qgesture.cpp283
-rw-r--r--doc/src/snippets/gestures/qgesture.h101
-rw-r--r--doc/src/snippets/gestures/qstandardgestures.cpp483
-rw-r--r--doc/src/snippets/gestures/qstandardgestures.h126
10 files changed, 1736 insertions, 1 deletions
diff --git a/doc/src/snippets/code/doc_src_qalgorithms.qdoc b/doc/src/snippets/code/doc_src_qalgorithms.qdoc
index 69d943c..e2126dd 100644
--- a/doc/src/snippets/code/doc_src_qalgorithms.qdoc
+++ b/doc/src/snippets/code/doc_src_qalgorithms.qdoc
@@ -302,7 +302,7 @@ list.clear();
QList<int> list;
list << 33 << 12 << 68 << 6 << 12;
qSort(list.begin(), list.end(), qLess<int>());
-// list: [ 68, 33, 12, 12, 6 ]
+// list: [ 6, 12, 12, 33, 68 ]
//! [24]
diff --git a/doc/src/snippets/code/doc_src_qtmultimedia.qdoc b/doc/src/snippets/code/doc_src_qtmultimedia.qdoc
new file mode 100644
index 0000000..87a03a4
--- /dev/null
+++ b/doc/src/snippets/code/doc_src_qtmultimedia.qdoc
@@ -0,0 +1,8 @@
+//! [0]
+QT += multimedia
+//! [0]
+
+
+//! [1]
+#include <QtMultimedia>
+//! [1]
diff --git a/doc/src/snippets/gestures/imageviewer/imagewidget.cpp b/doc/src/snippets/gestures/imageviewer/imagewidget.cpp
new file mode 100644
index 0000000..f9d6a77
--- /dev/null
+++ b/doc/src/snippets/gestures/imageviewer/imagewidget.cpp
@@ -0,0 +1,364 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 "imagewidget.h"
+
+#include <QtGui>
+
+ImageWidget::ImageWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ setAttribute(Qt::WA_AcceptTouchEvents);
+ setAttribute(Qt::WA_PaintOnScreen);
+ setAttribute(Qt::WA_OpaquePaintEvent);
+ setAttribute(Qt::WA_NoSystemBackground);
+
+ setObjectName("ImageWidget");
+
+ setMinimumSize(QSize(100,100));
+
+ position = 0;
+ zoomed = rotated = false;
+
+ zoomedIn = false;
+ horizontalOffset = 0;
+ verticalOffset = 0;
+
+//! [imagewidget-connect]
+ panGesture = new QPanGesture(this);
+ connect(panGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered()));
+
+ tapAndHoldGesture = new TapAndHoldGesture(this);
+ connect(tapAndHoldGesture, SIGNAL(triggered()), this, SLOT(gestureTriggered()));
+ connect(tapAndHoldGesture, SIGNAL(finished()), this, SLOT(gestureFinished()));
+//! [imagewidget-connect]
+}
+
+void ImageWidget::paintEvent(QPaintEvent*)
+{
+ QPainter p(this);
+ if (currentImage.isNull()) {
+ p.fillRect(geometry(), Qt::white);
+ return;
+ }
+ int hoffset = 0;
+ int voffset = 0;
+ const int w = pixmap.width();
+ const int h = pixmap.height();
+ p.save();
+ if (zoomedIn) {
+ hoffset = horizontalOffset;
+ voffset = verticalOffset;
+ if (horizontalOffset > 0)
+ p.fillRect(0, 0, horizontalOffset, height(), Qt::white);
+ if (verticalOffset > 0)
+ p.fillRect(0, 0, width(), verticalOffset, Qt::white);
+ }
+ p.drawPixmap(hoffset, voffset, pixmap);
+ if (hoffset + w < width())
+ p.fillRect(hoffset + w, 0, width() - w - hoffset, height(), Qt::white);
+ if (voffset + h < height())
+ p.fillRect(0, voffset + h, width(), height() - h - voffset, Qt::white);
+
+ // paint touch feedback
+ if (touchFeedback.tapped || touchFeedback.doubleTapped) {
+ p.setPen(QPen(Qt::gray, 2));
+ p.drawEllipse(touchFeedback.position, 5, 5);
+ if (touchFeedback.doubleTapped) {
+ p.setPen(QPen(Qt::darkGray, 2, Qt::DotLine));
+ p.drawEllipse(touchFeedback.position, 15, 15);
+ } else if (touchFeedback.tapAndHoldState != 0) {
+ QPoint pts[8] = {
+ touchFeedback.position + QPoint( 0, -15),
+ touchFeedback.position + QPoint( 10, -10),
+ touchFeedback.position + QPoint( 15, 0),
+ touchFeedback.position + QPoint( 10, 10),
+ touchFeedback.position + QPoint( 0, 15),
+ touchFeedback.position + QPoint(-10, 10),
+ touchFeedback.position + QPoint(-15, 0)
+ };
+ for (int i = 0; i < touchFeedback.tapAndHoldState/5; ++i)
+ p.drawEllipse(pts[i], 3, 3);
+ }
+ } else if (touchFeedback.sliding) {
+ p.setPen(QPen(Qt::red, 3));
+ QPoint endPos = QPoint(touchFeedback.position.x(), touchFeedback.slidingStartPosition.y());
+ p.drawLine(touchFeedback.slidingStartPosition, endPos);
+ int dx = 10;
+ if (touchFeedback.slidingStartPosition.x() < endPos.x())
+ dx = -1*dx;
+ p.drawLine(endPos, endPos + QPoint(dx, 5));
+ p.drawLine(endPos, endPos + QPoint(dx, -5));
+ }
+
+ for (int i = 0; i < TouchFeedback::MaximumNumberOfTouches; ++i) {
+ if (touchFeedback.touches[i].isNull())
+ break;
+ p.drawEllipse(touchFeedback.touches[i], 10, 10);
+ }
+ p.restore();
+}
+
+void ImageWidget::mousePressEvent(QMouseEvent *event)
+{
+ touchFeedback.tapped = true;
+ touchFeedback.position = event->pos();
+}
+
+void ImageWidget::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ touchFeedback.doubleTapped = true;
+ const QPoint p = event->pos();
+ touchFeedback.position = p;
+ horizontalOffset = p.x() - currentImage.width()*1.0*p.x()/width();
+ verticalOffset = p.y() - currentImage.height()*1.0*p.y()/height();
+ setZoomedIn(!zoomedIn);
+ zoomed = rotated = false;
+ updateImage();
+
+ feedbackFadeOutTimer.start(500, this);
+}
+
+//! [imagewidget-triggered-1]
+void ImageWidget::gestureTriggered()
+{
+ if (sender() == panGesture) {
+//! [imagewidget-triggered-1]
+ touchFeedback.tapped = false;
+ touchFeedback.doubleTapped = false;
+ QPanGesture *pg = qobject_cast<QPanGesture*>(sender());
+ if (zoomedIn) {
+#ifndef QT_NO_CURSOR
+ switch (pg->state()) {
+ case Qt::GestureStarted:
+ case Qt::GestureUpdated:
+ setCursor(Qt::SizeAllCursor);
+ break;
+ default:
+ setCursor(Qt::ArrowCursor);
+ }
+#endif
+ horizontalOffset += pg->lastOffset().width();
+ verticalOffset += pg->lastOffset().height();
+ } else {
+ // only slide gesture should be accepted
+ if (pg->state() == Qt::GestureFinished) {
+ touchFeedback.sliding = false;
+ zoomed = rotated = false;
+ if (pg->totalOffset().width() > 0)
+ goNextImage();
+ else
+ goPrevImage();
+ updateImage();
+ }
+ }
+ update();
+ feedbackFadeOutTimer.start(500, this);
+ } else if (sender() == tapAndHoldGesture) {
+ if (tapAndHoldGesture->state() == Qt::GestureFinished) {
+ qDebug() << "tap and hold detected";
+ touchFeedback.reset();
+ update();
+
+ QMenu menu;
+ menu.addAction("Action 1");
+ menu.addAction("Action 2");
+ menu.addAction("Action 3");
+ menu.exec(mapToGlobal(tapAndHoldGesture->pos()));
+ } else {
+ ++touchFeedback.tapAndHoldState;
+ update();
+ }
+ feedbackFadeOutTimer.start(500, this);
+ }
+}
+
+void ImageWidget::gestureFinished()
+{
+ qDebug() << "gesture finished" << sender();
+}
+
+void ImageWidget::gestureCancelled()
+{
+ qDebug() << "gesture cancelled" << sender();
+}
+
+void ImageWidget::resizeEvent(QResizeEvent*)
+{
+ updateImage();
+}
+
+void ImageWidget::updateImage()
+{
+ // should use qtconcurrent here?
+ transformation = QTransform();
+ if (zoomedIn) {
+ } else {
+ if (currentImage.isNull())
+ return;
+ if (zoomed) {
+ transformation = transformation.scale(zoom, zoom);
+ } else {
+ double xscale = (double)width()/currentImage.width();
+ double yscale = (double)height()/currentImage.height();
+ if (xscale < yscale)
+ yscale = xscale;
+ else
+ xscale = yscale;
+ transformation = transformation.scale(xscale, yscale);
+ }
+ if (rotated)
+ transformation = transformation.rotate(angle);
+ }
+ pixmap = QPixmap::fromImage(currentImage).transformed(transformation);
+ update();
+}
+
+void ImageWidget::openDirectory(const QString &path)
+{
+ this->path = path;
+ QDir dir(path);
+ QStringList nameFilters;
+ nameFilters << "*.jpg" << "*.png";
+ files = dir.entryList(nameFilters, QDir::Files|QDir::Readable, QDir::Name);
+
+ position = 0;
+ goToImage(0);
+ updateImage();
+}
+
+QImage ImageWidget::loadImage(const QString &fileName)
+{
+ QImageReader reader(fileName);
+ if (!reader.canRead()) {
+ qDebug() << fileName << ": can't load image";
+ return QImage();
+ }
+ QImage image;
+ if (!reader.read(&image)) {
+ qDebug() << fileName << ": corrupted image";
+ return QImage();
+ }
+ return image;
+}
+
+void ImageWidget::setZoomedIn(bool zoomed)
+{
+ zoomedIn = zoomed;
+}
+
+void ImageWidget::goNextImage()
+{
+ if (files.isEmpty())
+ return;
+ if (position < files.size()-1) {
+ ++position;
+ prevImage = currentImage;
+ currentImage = nextImage;
+ if (position+1 < files.size())
+ nextImage = loadImage(path+QLatin1String("/")+files.at(position+1));
+ else
+ nextImage = QImage();
+ }
+ setZoomedIn(false);
+ updateImage();
+}
+
+void ImageWidget::goPrevImage()
+{
+ if (files.isEmpty())
+ return;
+ if (position > 0) {
+ --position;
+ nextImage = currentImage;
+ currentImage = prevImage;
+ if (position > 0)
+ prevImage = loadImage(path+QLatin1String("/")+files.at(position-1));
+ else
+ prevImage = QImage();
+ }
+ setZoomedIn(false);
+ updateImage();
+}
+
+void ImageWidget::goToImage(int index)
+{
+ if (files.isEmpty())
+ return;
+ if (index < 0 || index >= files.size()) {
+ qDebug() << "goToImage: invalid index: " << index;
+ return;
+ }
+ if (index == position+1) {
+ goNextImage();
+ return;
+ }
+ if (position > 0 && index == position-1) {
+ goPrevImage();
+ return;
+ }
+ position = index;
+ pixmap = QPixmap();
+ if (index > 0)
+ prevImage = loadImage(path+QLatin1String("/")+files.at(position-1));
+ else
+ prevImage = QImage();
+ currentImage = loadImage(path+QLatin1String("/")+files.at(position));
+ if (position+1 < files.size())
+ nextImage = loadImage(path+QLatin1String("/")+files.at(position+1));
+ else
+ nextImage = QImage();
+ setZoomedIn(false);
+ updateImage();
+}
+
+void ImageWidget::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == touchFeedback.tapTimer.timerId()) {
+ touchFeedback.tapTimer.stop();
+ } else if (event->timerId() == feedbackFadeOutTimer.timerId()) {
+ feedbackFadeOutTimer.stop();
+ touchFeedback.reset();
+ }
+ update();
+}
+
+#include "moc_imagewidget.cpp"
diff --git a/doc/src/snippets/gestures/imageviewer/imagewidget.h b/doc/src/snippets/gestures/imageviewer/imagewidget.h
new file mode 100644
index 0000000..fcad5b9
--- /dev/null
+++ b/doc/src/snippets/gestures/imageviewer/imagewidget.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 IMAGEWIDGET_H
+#define IMAGEWIDGET_H
+
+#include <QWidget>
+#include <QImage>
+#include <QPixmap>
+
+#include <QtGui>
+
+#include "tapandholdgesture.h"
+
+class ImageWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ImageWidget(QWidget *parent = 0);
+
+ void openDirectory(const QString &path);
+
+protected:
+ void paintEvent(QPaintEvent*);
+ void resizeEvent(QResizeEvent*);
+ void timerEvent(QTimerEvent*);
+ void mousePressEvent(QMouseEvent*);
+ void mouseDoubleClickEvent(QMouseEvent*);
+
+//! [imagewidget-slots]
+private slots:
+ void gestureTriggered();
+ void gestureFinished();
+ void gestureCancelled();
+//! [imagewidget-slots]
+
+private:
+ void updateImage();
+ QImage loadImage(const QString &fileName);
+ void loadImage();
+ void setZoomedIn(bool zoomed);
+ void goNextImage();
+ void goPrevImage();
+ void goToImage(int index);
+
+ QPanGesture *panGesture;
+ TapAndHoldGesture *tapAndHoldGesture;
+
+ QString path;
+ QStringList files;
+ int position;
+
+ QImage prevImage, nextImage;
+ QImage currentImage;
+ QPixmap pixmap;
+ QTransform transformation;
+
+ bool zoomedIn;
+ int horizontalOffset;
+ int verticalOffset;
+
+ bool zoomed;
+ qreal zoom;
+ bool rotated;
+ qreal angle;
+
+ struct TouchFeedback
+ {
+ bool tapped;
+ QPoint position;
+ bool sliding;
+ QPoint slidingStartPosition;
+ QBasicTimer tapTimer;
+ int tapState;
+ bool doubleTapped;
+ int tapAndHoldState;
+
+ enum { MaximumNumberOfTouches = 5 };
+ QPoint touches[MaximumNumberOfTouches];
+
+ inline TouchFeedback() { reset(); }
+ inline void reset()
+ {
+ tapped = false;
+ sliding = false;
+ tapTimer.stop();
+ tapState = 0;
+ doubleTapped = false;
+ tapAndHoldState = 0;
+ for (int i = 0; i < MaximumNumberOfTouches; ++i) {
+ touches[i] = QPoint();
+ }
+ }
+ } touchFeedback;
+ QBasicTimer feedbackFadeOutTimer;
+};
+
+#endif
diff --git a/doc/src/snippets/gestures/imageviewer/tapandholdgesture.cpp b/doc/src/snippets/gestures/imageviewer/tapandholdgesture.cpp
new file mode 100644
index 0000000..03898dc
--- /dev/null
+++ b/doc/src/snippets/gestures/imageviewer/tapandholdgesture.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 "tapandholdgesture.h"
+
+#include <QtGui/qevent.h>
+
+// #define TAPANDHOLD_USING_MOUSE
+
+/*!
+ \class TapAndHoldGesture
+ \since 4.6
+
+ \brief The TapAndHoldGesture class represents a Tap-and-Hold gesture,
+ providing additional information.
+*/
+
+const int TapAndHoldGesture::iterationCount = 40;
+const int TapAndHoldGesture::iterationTimeout = 50;
+
+/*!
+ Creates a new Tap and Hold gesture handler object and marks it as a child
+ of \a parent.
+
+ On some platforms like Windows there is a system-wide tap and hold gesture
+ that cannot be overriden, hence the gesture might never trigger and default
+ context menu will be shown instead.
+*/
+TapAndHoldGesture::TapAndHoldGesture(QWidget *parent)
+ : QGesture(parent), iteration(0)
+{
+}
+
+/*! \internal */
+bool TapAndHoldGesture::filterEvent(QEvent *event)
+{
+ if (!event->spontaneous())
+ return false;
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ if (timer.isActive())
+ timer.stop();
+ timer.start(TapAndHoldGesture::iterationTimeout, this);
+ const QPoint p = ev->touchPoints().at(0).pos().toPoint();
+ position = p;
+ break;
+ }
+ case QEvent::TouchUpdate:
+ if (ev->touchPoints().size() == 1) {
+ const QPoint startPos = ev->touchPoints().at(0).startPos().toPoint();
+ const QPoint pos = ev->touchPoints().at(0).pos().toPoint();
+ if ((startPos - pos).manhattanLength() > 15)
+ reset();
+ } else {
+ reset();
+ }
+ break;
+ case QEvent::TouchEnd:
+ reset();
+ break;
+#ifdef TAPANDHOLD_USING_MOUSE
+ case QEvent::MouseButtonPress: {
+ if (timer.isActive())
+ timer.stop();
+ timer.start(TapAndHoldGesture::iterationTimeout, this);
+ const QPoint p = static_cast<QMouseEvent*>(event)->pos();
+ position = startPosition = p;
+ break;
+ }
+ case QEvent::MouseMove: {
+ const QPoint startPos = startPosition;
+ const QPoint pos = static_cast<QMouseEvent*>(event)->pos();
+ if ((startPos - pos).manhattanLength() > 15)
+ reset();
+ break;
+ }
+ case QEvent::MouseButtonRelease:
+ reset();
+ break;
+#endif // TAPANDHOLD_USING_MOUSE
+ default:
+ break;
+ }
+ return false;
+}
+
+/*! \internal */
+void TapAndHoldGesture::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() != timer.timerId())
+ return;
+ if (iteration == TapAndHoldGesture::iterationCount) {
+ timer.stop();
+ updateState(Qt::GestureFinished);
+ } else {
+ updateState(Qt::GestureUpdated);
+ }
+ ++iteration;
+}
+
+/*! \internal */
+//! [tapandhold-reset]
+void TapAndHoldGesture::reset()
+{
+ timer.stop();
+ iteration = 0;
+ position = startPosition = QPoint();
+ updateState(Qt::NoGesture);
+}
+//! [tapandhold-reset]
+
+/*!
+ \property TapAndHoldGesture::pos
+
+ \brief The position of the gesture.
+*/
+QPoint TapAndHoldGesture::pos() const
+{
+ return position;
+}
diff --git a/doc/src/snippets/gestures/imageviewer/tapandholdgesture.h b/doc/src/snippets/gestures/imageviewer/tapandholdgesture.h
new file mode 100644
index 0000000..bf0f867
--- /dev/null
+++ b/doc/src/snippets/gestures/imageviewer/tapandholdgesture.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 TAPANDHOLDGESTURE_H
+#define TAPANDHOLDGESTURE_H
+
+#include <QtCore/QBasicTimer>
+#include <QtGui/QGesture>
+#include <QtGui/QWidget>
+
+class TapAndHoldGesture : public QGesture
+{
+ Q_OBJECT
+ Q_PROPERTY(QPoint pos READ pos)
+
+public:
+ TapAndHoldGesture(QWidget *parent);
+
+ bool filterEvent(QEvent *event);
+ void reset();
+
+ QPoint pos() const;
+
+protected:
+ void timerEvent(QTimerEvent *event);
+
+private:
+ QBasicTimer timer;
+ int iteration;
+ QPoint position;
+ QPoint startPosition;
+ static const int iterationCount;
+ static const int iterationTimeout;
+};
+
+#endif // TAPANDHOLDGESTURE_H
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