diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-10-09 17:09:09 (GMT) |
---|---|---|
committer | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-10-09 17:09:09 (GMT) |
commit | f2437d3aa6cc274b9e663801892fd4e40e693546 (patch) | |
tree | 7a5b1425ac403336eb77c80ca0a551e7222f60f8 /tests/manual/gestures | |
parent | 7566a1f15ea32504c10d9467fb69a6399a06c325 (diff) | |
download | Qt-f2437d3aa6cc274b9e663801892fd4e40e693546.zip Qt-f2437d3aa6cc274b9e663801892fd4e40e693546.tar.gz Qt-f2437d3aa6cc274b9e663801892fd4e40e693546.tar.bz2 |
A new implementation of the Gesture API.
Implemented gestures using gesture events and separate
QGesture/QGestureRecognizer classes.
Reviewed-by: trustme
Diffstat (limited to 'tests/manual/gestures')
18 files changed, 821 insertions, 317 deletions
diff --git a/tests/manual/gestures/graphicsview/gestures.cpp b/tests/manual/gestures/graphicsview/gestures.cpp new file mode 100644 index 0000000..c888aa1 --- /dev/null +++ b/tests/manual/gestures/graphicsview/gestures.cpp @@ -0,0 +1,90 @@ +#include "gestures.h" + +#include <QTouchEvent> + +Qt::GestureType ThreeFingerSlideGesture::Type = Qt::CustomGesture; + +QGesture *ThreeFingerSlideGestureRecognizer::createGesture(QObject *) +{ + return new ThreeFingerSlideGesture; +} + +QGestureRecognizer::Result ThreeFingerSlideGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event) +{ + ThreeFingerSlideGesture *d = static_cast<ThreeFingerSlideGesture *>(state); + QGestureRecognizer::Result result; + switch (event->type()) { + case QEvent::TouchBegin: + result = QGestureRecognizer::MaybeGesture; + case QEvent::TouchEnd: + if (d->gestureFired) + result = QGestureRecognizer::GestureFinished; + else + result = QGestureRecognizer::NotGesture; + case QEvent::TouchUpdate: + if (d->state() != Qt::NoGesture) { + QTouchEvent *ev = static_cast<QTouchEvent*>(event); + if (ev->touchPoints().size() == 3) { + d->gestureFired = true; + result = QGestureRecognizer::GestureTriggered; + } else { + result = QGestureRecognizer::MaybeGesture; + for (int i = 0; i < ev->touchPoints().size(); ++i) { + const QTouchEvent::TouchPoint &pt = ev->touchPoints().at(i); + const int distance = (pt.pos().toPoint() - pt.startPos().toPoint()).manhattanLength(); + if (distance > 20) { + result = QGestureRecognizer::NotGesture; + } + } + } + } else { + result = QGestureRecognizer::NotGesture; + } + + break; + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + if (d->state() != Qt::NoGesture) + result = QGestureRecognizer::Ignore; + else + result = QGestureRecognizer::NotGesture; + break; + default: + result = QGestureRecognizer::Ignore; + break; + } + return result; +} + +void ThreeFingerSlideGestureRecognizer::reset(QGesture *state) +{ + static_cast<ThreeFingerSlideGesture *>(state)->gestureFired = false; + QGestureRecognizer::reset(state); +} + + +QGesture *RotateGestureRecognizer::createGesture(QObject *) +{ + return new QGesture; +} + +QGestureRecognizer::Result RotateGestureRecognizer::filterEvent(QGesture *, QObject *, QEvent *event) +{ + switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchEnd: + case QEvent::TouchUpdate: + break; + default: + break; + } + return QGestureRecognizer::Ignore; +} + +void RotateGestureRecognizer::reset(QGesture *state) +{ + QGestureRecognizer::reset(state); +} + +#include "moc_gestures.cpp" diff --git a/tests/manual/gestures/graphicsview/gestures.h b/tests/manual/gestures/graphicsview/gestures.h new file mode 100644 index 0000000..630a7ef --- /dev/null +++ b/tests/manual/gestures/graphicsview/gestures.h @@ -0,0 +1,37 @@ +#ifndef GESTURE_H +#define GESTURE_H + +#include <QGestureRecognizer> +#include <QGesture> + +class ThreeFingerSlideGesture : public QGesture +{ + Q_OBJECT +public: + static Qt::GestureType Type; + + ThreeFingerSlideGesture(QObject *parent = 0) : QGesture(parent) { } + + bool gestureFired; +}; + +class ThreeFingerSlideGestureRecognizer : public QGestureRecognizer +{ +private: + QGesture* createGesture(QObject *target); + QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); +}; + +class RotateGestureRecognizer : public QGestureRecognizer +{ +public: + RotateGestureRecognizer(); + +private: + QGesture* createGesture(QObject *target); + QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); +}; + +#endif // GESTURE_H diff --git a/tests/manual/gestures/graphicsview/graphicsview.pro b/tests/manual/gestures/graphicsview/graphicsview.pro new file mode 100644 index 0000000..a40c323 --- /dev/null +++ b/tests/manual/gestures/graphicsview/graphicsview.pro @@ -0,0 +1,17 @@ +# ##################################################################### +# Automatically generated by qmake (2.01a) Mon Sep 7 13:26:43 2009 +# ##################################################################### +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp \ + imageitem.cpp \ + gestures.cpp \ + mousepangesturerecognizer.cpp + +HEADERS += imageitem.h \ + gestures.h \ + mousepangesturerecognizer.h diff --git a/tests/manual/gestures/graphicsview/imageitem.cpp b/tests/manual/gestures/graphicsview/imageitem.cpp new file mode 100644 index 0000000..d6f406c --- /dev/null +++ b/tests/manual/gestures/graphicsview/imageitem.cpp @@ -0,0 +1,52 @@ +#include "imageitem.h" +#include "gestures.h" + +#include <QPainter> +#include <QEvent> + +ImageItem::ImageItem(const QImage &image) +{ + setImage(image); +} + +void ImageItem::setImage(const QImage &image) +{ + image_ = image; + pixmap_ = QPixmap::fromImage(image.scaled(400, 400, Qt::KeepAspectRatio)); + update(); +} + +QImage ImageItem::image() const +{ + return image_; +} + +QRectF ImageItem::boundingRect() const +{ + const QSize size = pixmap_.size(); + return QRectF(0, 0, size.width(), size.height()); +} + +void ImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*) +{ + painter->drawPixmap(0, 0, pixmap_); +} + + +GestureImageItem::GestureImageItem(const QImage &image) + : ImageItem(image) +{ + grabGesture(Qt::PanGesture); + grabGesture(ThreeFingerSlideGesture::Type); +} + +bool GestureImageItem::event(QEvent *event) +{ + if (event->type() == QEvent::Gesture) { + qDebug("gestureimageitem: gesture triggered"); + return true; + } + return ImageItem::event(event); +} + +#include "moc_imageitem.cpp" diff --git a/tests/manual/gestures/graphicsview/imageitem.h b/tests/manual/gestures/graphicsview/imageitem.h new file mode 100644 index 0000000..ad0e397 --- /dev/null +++ b/tests/manual/gestures/graphicsview/imageitem.h @@ -0,0 +1,36 @@ +#ifndef IMAGEITEM_H +#define IMAGEITEM_H + +#include <QGraphicsItem> +#include <QImage> +#include <QPixmap> +#include <QTransform> + +class ImageItem : public QGraphicsObject +{ + Q_OBJECT +public: + ImageItem(const QImage &image); + void setImage(const QImage &image); + QImage image() const; + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +private: + QImage image_; + QPixmap pixmap_; + QTransform transform; +}; + +class GestureImageItem : public ImageItem +{ + Q_OBJECT + +public: + GestureImageItem(const QImage &image); + +protected: + bool event(QEvent *event); +}; + +#endif // IMAGEITEM_H diff --git a/tests/manual/gestures/graphicsview/main.cpp b/tests/manual/gestures/graphicsview/main.cpp new file mode 100644 index 0000000..1db5614 --- /dev/null +++ b/tests/manual/gestures/graphicsview/main.cpp @@ -0,0 +1,187 @@ +#include <QtGui> + +#include "imageitem.h" +#include "gestures.h" +#include "mousepangesturerecognizer.h" + +class GraphicsView : public QGraphicsView +{ +public: + GraphicsView(QGraphicsScene *scene, QWidget *parent = 0) + : QGraphicsView(scene, parent) + { + } +protected: + bool viewportEvent(QEvent *event) + { + if (event->type() == QEvent::Gesture) { + QGestureEvent *ge = static_cast<QGestureEvent *>(event); + if (QPanGesture *pan = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture))) { + switch (pan->state()) { + case Qt::GestureStarted: qDebug("view: Pan: started"); break; + case Qt::GestureFinished: qDebug("view: Pan: finished"); break; + case Qt::GestureCanceled: qDebug("view: Pan: canceled"); break; + case Qt::GestureUpdated: break; + default: qDebug("view: Pan: <unknown state>"); break; + } + + const QSizeF offset = pan->offset(); + QScrollBar *vbar = verticalScrollBar(); + QScrollBar *hbar = horizontalScrollBar(); + vbar->setValue(vbar->value() - offset.height()); + hbar->setValue(hbar->value() - offset.width()); + ge->accept(pan); + return true; + } + } + return QGraphicsView::viewportEvent(event); + } +}; + +class StandardGestures : public QWidget +{ +public: + StandardGestures(QWidget *parent = 0) + : QWidget(parent) + { + scene = new QGraphicsScene(this); + scene->setSceneRect(-2000, -2000, 4000, 4000); + view = new QGraphicsView(scene, 0); + QVBoxLayout *l = new QVBoxLayout(this); + l->addWidget(view); + } + + QGraphicsScene *scene; + QGraphicsView *view; +}; + +class GlobalViewGestures : public QWidget +{ + Q_OBJECT +public: + GlobalViewGestures(QWidget *parent = 0) + : QWidget(parent) + { + scene = new QGraphicsScene(this); + scene->setSceneRect(-2000, -2000, 4000, 4000); + view = new GraphicsView(scene, 0); + view->viewport()->grabGesture(Qt::PanGesture); + view->viewport()->grabGesture(ThreeFingerSlideGesture::Type); + QVBoxLayout *l = new QVBoxLayout(this); + l->addWidget(view); + } + + QGraphicsScene *scene; + QGraphicsView *view; +}; + +class GraphicsItemGestures : public QWidget +{ + Q_OBJECT +public: + GraphicsItemGestures(QWidget *parent = 0) + : QWidget(parent) + { + scene = new QGraphicsScene(this); + scene->setSceneRect(-2000, -2000, 4000, 4000); + view = new QGraphicsView(scene, 0); + QVBoxLayout *l = new QVBoxLayout(this); + l->addWidget(view); + } + + QGraphicsScene *scene; + QGraphicsView *view; +}; + +class MainWindow : public QMainWindow +{ +public: + MainWindow(); + + void setDirectory(const QString &path); + +private: + QTabWidget *tabWidget; + StandardGestures *standardGestures; + GlobalViewGestures *globalViewGestures; + GraphicsItemGestures *graphicsItemGestures; +}; + +MainWindow::MainWindow() +{ + (void)qApp->registerGestureRecognizer(new MousePanGestureRecognizer); + ThreeFingerSlideGesture::Type = qApp->registerGestureRecognizer(new ThreeFingerSlideGestureRecognizer); + + tabWidget = new QTabWidget; + + standardGestures = new StandardGestures; + tabWidget->addTab(standardGestures, "Standard gestures"); + + globalViewGestures = new GlobalViewGestures; + tabWidget->addTab(globalViewGestures , "Global gestures"); + + graphicsItemGestures = new GraphicsItemGestures; + tabWidget->addTab(graphicsItemGestures, "Graphics item gestures"); + + setCentralWidget(tabWidget); +} + +void MainWindow::setDirectory(const QString &path) +{ + QDir dir(path); + QStringList files = dir.entryList(QDir::Files | QDir::Readable | QDir::NoDotAndDotDot); + foreach(const QString &file, files) { + QImageReader img(path + QLatin1String("/")+file); + QImage image = img.read(); + if (!image.isNull()) { + { + ImageItem *item = new ImageItem(image); + item->setPos(0, 0); + item->setFlags(QGraphicsItem::ItemIsMovable); + standardGestures->scene->addItem(item); + } + { + ImageItem *item = new ImageItem(image); + item->setPos(0, 0); + item->setFlags(QGraphicsItem::ItemIsMovable); + globalViewGestures->scene->addItem(item); + } + { + GestureImageItem *item = new GestureImageItem(image); + item->setPos(0, 0); + item->setFlags(QGraphicsItem::ItemIsMovable); + graphicsItemGestures->scene->addItem(item); + } + } + } + + { + QList<QGraphicsItem*> items = standardGestures->scene->items(); + if (!items.isEmpty()) + standardGestures->view->ensureVisible(items.at(0)); + } + { + QList<QGraphicsItem*> items = globalViewGestures->scene->items(); + if (!items.isEmpty()) + globalViewGestures->view->ensureVisible(items.at(0)); + } + { + QList<QGraphicsItem*> items = graphicsItemGestures->scene->items(); + if (!items.isEmpty()) + graphicsItemGestures->view->ensureVisible(items.at(0)); + } +} + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + MainWindow window; + if (QApplication::arguments().size() > 1) + window.setDirectory(QApplication::arguments().at(1)); + else + window.setDirectory(QFileDialog::getExistingDirectory(0, "Select image folder")); + window.show(); + return app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/gestures/graphicsview/mousepangesturerecognizer.cpp b/tests/manual/gestures/graphicsview/mousepangesturerecognizer.cpp new file mode 100644 index 0000000..f89f247 --- /dev/null +++ b/tests/manual/gestures/graphicsview/mousepangesturerecognizer.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mousepangesturerecognizer.h" + +#include <QEvent> +#include <QMouseEvent> +#include <QGesture> + +MousePanGestureRecognizer::MousePanGestureRecognizer() +{ +} + +QGesture* MousePanGestureRecognizer::createGesture(QObject *) +{ + return new QPanGesture; +} + +QGestureRecognizer::Result MousePanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event) +{ + QPanGesture *g = static_cast<QPanGesture *>(state); + QMouseEvent *me = static_cast<QMouseEvent *>(event); + if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick + || event->type() == QEvent::GraphicsSceneMousePress || event->type() == QEvent::GraphicsSceneMouseDoubleClick) { + g->setHotSpot(me->globalPos()); + g->setProperty("lastPos", me->globalPos()); + g->setProperty("pressed", QVariant::fromValue<bool>(true)); + return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint; + } else if (event->type() == QEvent::MouseMove || event->type() == QEvent::GraphicsSceneMouseMove) { + if (g->property("pressed").toBool()) { + QPoint pos = me->globalPos(); + QPoint lastPos = g->property("lastPos").toPoint(); + g->setLastOffset(g->offset()); + lastPos = pos - lastPos; + g->setOffset(QSizeF(lastPos.x(), lastPos.y())); + g->setTotalOffset(g->totalOffset() + QSizeF(lastPos.x(), lastPos.y())); + g->setProperty("lastPos", pos); + return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint; + } + return QGestureRecognizer::NotGesture; + } else if (event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::GraphicsSceneMouseRelease) { + return QGestureRecognizer::GestureFinished | QGestureRecognizer::ConsumeEventHint; + } + return QGestureRecognizer::Ignore; +} + +void MousePanGestureRecognizer::reset(QGesture *state) +{ + QPanGesture *g = static_cast<QPanGesture *>(state); + g->setTotalOffset(QSizeF()); + g->setLastOffset(QSizeF()); + g->setOffset(QSizeF()); + g->setAcceleration(0); + g->setProperty("lastPos", QVariant()); + g->setProperty("pressed", QVariant::fromValue<bool>(false)); + QGestureRecognizer::reset(state); +} diff --git a/tests/manual/gestures/pinch/main.cpp b/tests/manual/gestures/graphicsview/mousepangesturerecognizer.h index 4d9c14c..e31799e 100644 --- a/tests/manual/gestures/pinch/main.cpp +++ b/tests/manual/gestures/graphicsview/mousepangesturerecognizer.h @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the test suite of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -39,30 +39,19 @@ ** ****************************************************************************/ -#include <QtGui> -#include "pinchwidget.h" +#ifndef MOUSEPANGESTURERECOGNIZER_H +#define MOUSEPANGESTURERECOGNIZER_H -class MainWindow : public QWidget +#include <QGestureRecognizer> + +class MousePanGestureRecognizer : public QGestureRecognizer { public: - MainWindow(); -}; + MousePanGestureRecognizer(); -MainWindow::MainWindow() -{ - QVBoxLayout *l = new QVBoxLayout(this); - QPushButton *btn = new QPushButton(QLatin1String("AcceptTouchEvents")); - l->addWidget(btn); - QImage image(":/images/qt-logo.png"); - PinchWidget *w = new PinchWidget(image); - l->addWidget(w); - connect(btn, SIGNAL(clicked()), w, SLOT(acceptTouchEvents())); -} + QGesture* createGesture(QObject *target); + QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); +}; -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - MainWindow w; - w.show(); - return app.exec(); -} +#endif // MOUSEPANGESTURERECOGNIZER_H diff --git a/tests/manual/gestures/pinch/pinch.pro b/tests/manual/gestures/pinch/pinch.pro deleted file mode 100644 index d1f28cc..0000000 --- a/tests/manual/gestures/pinch/pinch.pro +++ /dev/null @@ -1,4 +0,0 @@ -SOURCES = main.cpp \ - pinchwidget.cpp -HEADERS += pinchwidget.h -RESOURCES += pinch.qrc diff --git a/tests/manual/gestures/pinch/pinch.qrc b/tests/manual/gestures/pinch/pinch.qrc deleted file mode 100644 index 0be9ba1..0000000 --- a/tests/manual/gestures/pinch/pinch.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<RCC> - <qresource prefix="/images" > - <file>qt-logo.png</file> - </qresource> -</RCC> diff --git a/tests/manual/gestures/pinch/pinchwidget.cpp b/tests/manual/gestures/pinch/pinchwidget.cpp deleted file mode 100644 index e93c8b5..0000000 --- a/tests/manual/gestures/pinch/pinchwidget.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite 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 Technology Preview License Agreement accompanying -** this package. -** -** 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.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "pinchwidget.h" - -#include <QPainter> -#include <QImage> -#include <QPixmap> -#include <QPanGesture> -#include <QPinchGesture> -#include <QPushButton> - -PinchWidget::PinchWidget(const QImage &image, QWidget *parent) - : QWidget(parent) -{ - setMinimumSize(100,100); - this->image = image; - pan = new QPanGesture(this); - connect(pan, SIGNAL(triggered()), this, SLOT(onPanTriggered())); - connect(pan, SIGNAL(finished()), this, SLOT(onPanFinished())); - pinch = new QPinchGesture(this); - connect(pinch, SIGNAL(triggered()), this, SLOT(onPinchTriggered())); - connect(pinch, SIGNAL(finished()), this, SLOT(onPinchFinished())); -} - -QSize PinchWidget::sizeHint() const -{ - return image.size()*1.5; -} - -void PinchWidget::paintEvent(QPaintEvent *) -{ - QPainter p(this); - QTransform t = worldTransform * currentPanTransform * currentPinchTransform; - p.setTransform(t); - QPoint center = QPoint(width()/2, height()/2); - QPoint size = QPoint(image.width()/2, image.height()/2); - p.translate(center - size); - p.drawImage(QPoint(0,0), image); -} - -void PinchWidget::acceptTouchEvents() -{ - setAttribute(Qt::WA_AcceptTouchEvents); - if (QWidget *w = qobject_cast<QPushButton*>(sender())) - w->setEnabled(false); -} - -void PinchWidget::onPanTriggered() -{ - currentPanTransform = QTransform() - .translate(pan->totalOffset().width(), - pan->totalOffset().height()); - update(); -} - -void PinchWidget::onPanFinished() -{ - worldTransform *= currentPanTransform; - currentPanTransform.reset(); - update(); -} - -void PinchWidget::onPinchTriggered() -{ - QPoint transformCenter = worldTransform.map(QPoint(width()/2, height()/2)); - currentPinchTransform = QTransform() - .translate(transformCenter.x(), transformCenter.y()) - .scale(pinch->totalScaleFactor(), pinch->totalScaleFactor()) - .rotate(pinch->totalRotationAngle()) - .translate(-transformCenter.x(), -transformCenter.y()); - update(); -} - -void PinchWidget::onPinchFinished() -{ - worldTransform *= currentPinchTransform; - currentPinchTransform.reset(); - update(); -} diff --git a/tests/manual/gestures/pinch/qt-logo.png b/tests/manual/gestures/pinch/qt-logo.png Binary files differdeleted file mode 100644 index 7d3e97e..0000000 --- a/tests/manual/gestures/pinch/qt-logo.png +++ /dev/null diff --git a/tests/manual/gestures/scrollarea/main.cpp b/tests/manual/gestures/scrollarea/main.cpp new file mode 100644 index 0000000..e2fa4d3 --- /dev/null +++ b/tests/manual/gestures/scrollarea/main.cpp @@ -0,0 +1,188 @@ +#include <QtGui> + +#include "mousepangesturerecognizer.h" + +class ScrollArea : public QScrollArea +{ + Q_OBJECT +public: + ScrollArea(QWidget *parent = 0) + : QScrollArea(parent), outside(false) + { + viewport()->grabGesture(Qt::PanGesture); + } + +protected: + bool viewportEvent(QEvent *event) + { + if (event->type() == QEvent::Gesture) { + gestureEvent(static_cast<QGestureEvent *>(event)); + return true; + } else if (event->type() == QEvent::GestureOverride) { + QGestureEvent *ge = static_cast<QGestureEvent *>(event); + if (QPanGesture *pan = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture))) + if (pan->state() == Qt::GestureStarted) { + outside = false; + } + } + return QScrollArea::viewportEvent(event); + } + void gestureEvent(QGestureEvent *event) + { + QPanGesture *pan = static_cast<QPanGesture *>(event->gesture(Qt::PanGesture)); + if (pan) { + switch(pan->state()) { + case Qt::GestureStarted: qDebug("area: Pan: started"); break; + case Qt::GestureFinished: qDebug("area: Pan: finished"); break; + case Qt::GestureCanceled: qDebug("area: Pan: canceled"); break; + case Qt::GestureUpdated: break; + default: qDebug("area: Pan: <unknown state>"); break; + } + + if (pan->state() == Qt::GestureStarted) + outside = false; + event->ignore(); + event->ignore(pan); + if (outside) + return; + + const QSizeF offset = pan->offset(); + const QSizeF totalOffset = pan->totalOffset(); + QScrollBar *vbar = verticalScrollBar(); + QScrollBar *hbar = horizontalScrollBar(); + + if ((vbar->value() == vbar->minimum() && totalOffset.height() > 10) || + (vbar->value() == vbar->maximum() && totalOffset.height() < -10)) { + outside = true; + return; + } + if ((hbar->value() == hbar->minimum() && totalOffset.width() > 10) || + (hbar->value() == hbar->maximum() && totalOffset.width() < -10)) { + outside = true; + return; + } + vbar->setValue(vbar->value() - offset.height()); + hbar->setValue(hbar->value() - offset.width()); + event->accept(pan); + } + } + +private: + bool outside; +}; + +class Slider : public QSlider +{ +public: + Slider(Qt::Orientation orientation, QWidget *parent = 0) + : QSlider(orientation, parent) + { + grabGesture(Qt::PanGesture); + } +protected: + bool event(QEvent *event) + { + if (event->type() == QEvent::Gesture) { + gestureEvent(static_cast<QGestureEvent *>(event)); + return true; + } + return QSlider::event(event); + } + void gestureEvent(QGestureEvent *event) + { + QPanGesture *pan = static_cast<QPanGesture *>(event->gesture(Qt::PanGesture)); + if (pan) { + switch (pan->state()) { + case Qt::GestureStarted: qDebug("slider: Pan: started"); break; + case Qt::GestureFinished: qDebug("slider: Pan: finished"); break; + case Qt::GestureCanceled: qDebug("slider: Pan: canceled"); break; + case Qt::GestureUpdated: break; + default: qDebug("slider: Pan: <unknown state>"); break; + } + + if (pan->state() == Qt::GestureStarted) + outside = false; + event->ignore(); + event->ignore(pan); + if (outside) + return; + const QSizeF offset = pan->offset(); + const QSizeF totalOffset = pan->totalOffset(); + if (orientation() == Qt::Horizontal) { + if ((value() == minimum() && totalOffset.width() < -10) || + (value() == maximum() && totalOffset.width() > 10)) { + outside = true; + return; + } + if (totalOffset.height() < 40 && totalOffset.height() > -40) { + setValue(value() + offset.width()); + event->accept(pan); + } else { + outside = true; + } + } else if (orientation() == Qt::Vertical) { + if ((value() == maximum() && totalOffset.height() < -10) || + (value() == minimum() && totalOffset.height() > 10)) { + outside = true; + return; + } + if (totalOffset.width() < 40 && totalOffset.width() > -40) { + setValue(value() - offset.height()); + event->accept(pan); + } else { + outside = true; + } + } + } + } +private: + bool outside; +}; + +class MainWindow : public QMainWindow +{ +public: + MainWindow() + { + rootScrollArea = new ScrollArea; + setCentralWidget(rootScrollArea); + + QWidget *root = new QWidget; + root->setFixedSize(3000, 3000); + rootScrollArea->setWidget(root); + + Slider *verticalSlider = new Slider(Qt::Vertical, root); + verticalSlider ->move(650, 1100); + Slider *horizontalSlider = new Slider(Qt::Horizontal, root); + horizontalSlider ->move(600, 1000); + + childScrollArea = new ScrollArea(root); + childScrollArea->move(500, 500); + QWidget *w = new QWidget; + w->setMinimumWidth(400); + QVBoxLayout *l = new QVBoxLayout(w); + l->setMargin(20); + for (int i = 0; i < 100; ++i) { + QWidget *w = new QWidget; + QHBoxLayout *ll = new QHBoxLayout(w); + ll->addWidget(new QLabel(QString("Label %1").arg(i))); + ll->addWidget(new QPushButton(QString("Button %1").arg(i))); + l->addWidget(w); + } + childScrollArea->setWidget(w); + } +private: + ScrollArea *rootScrollArea; + ScrollArea *childScrollArea; +}; + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + app.registerGestureRecognizer(new MousePanGestureRecognizer); + MainWindow w; + w.show(); + return app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/gestures/scrollarea/mousepangesturerecognizer.cpp b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.cpp new file mode 100644 index 0000000..6e2171c --- /dev/null +++ b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mousepangesturerecognizer.h" + +#include <QEvent> +#include <QMouseEvent> +#include <QGesture> + +MousePanGestureRecognizer::MousePanGestureRecognizer() +{ +} + +QGesture* MousePanGestureRecognizer::createGesture(QObject *) const +{ + return new QPanGesture; +} + +QGestureRecognizer::Result MousePanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event) +{ + QPanGesture *g = static_cast<QPanGesture *>(state); + QMouseEvent *me = static_cast<QMouseEvent *>(event); + if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) { + g->setHotSpot(me->globalPos()); + g->setProperty("lastPos", me->globalPos()); + g->setProperty("pressed", QVariant::fromValue<bool>(true)); + return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint; + } else if (event->type() == QEvent::MouseMove) { + if (g->property("pressed").toBool()) { + QPoint pos = me->globalPos(); + QPoint lastPos = g->property("lastPos").toPoint(); + g->setLastOffset(g->offset()); + lastPos = pos - lastPos; + g->setOffset(QSizeF(lastPos.x(), lastPos.y())); + g->setTotalOffset(g->totalOffset() + QSizeF(lastPos.x(), lastPos.y())); + g->setProperty("lastPos", pos); + return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint; + } + return QGestureRecognizer::NotGesture; + } else if (event->type() == QEvent::MouseButtonRelease) { + return QGestureRecognizer::GestureFinished | QGestureRecognizer::ConsumeEventHint; + } + return QGestureRecognizer::Ignore; +} + +void MousePanGestureRecognizer::reset(QGesture *state) +{ + QPanGesture *g = static_cast<QPanGesture *>(state); + g->setTotalOffset(QSizeF()); + g->setLastOffset(QSizeF()); + g->setOffset(QSizeF()); + g->setAcceleration(0); + g->setProperty("lastPos", QVariant()); + g->setProperty("pressed", QVariant::fromValue<bool>(false)); + QGestureRecognizer::reset(state); +} diff --git a/tests/manual/gestures/pinch/pinchwidget.h b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.h index 7628ffc..f6df289 100644 --- a/tests/manual/gestures/pinch/pinchwidget.h +++ b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.h @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the test suite of the Qt Toolkit. +** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -39,40 +39,19 @@ ** ****************************************************************************/ -#ifndef PINCHWIDGET_H -#define PINCHWIDGET_H +#ifndef MOUSEPANGESTURERECOGNIZER_H +#define MOUSEPANGESTURERECOGNIZER_H -#include <QWidget> -#include <QTransform> +#include <QGestureRecognizer> -class QPanGesture; -class QPinchGesture; - -class PinchWidget : public QWidget +class MousePanGestureRecognizer : public QGestureRecognizer { - Q_OBJECT public: - PinchWidget(const QImage &image, QWidget *parent = 0); - -private Q_SLOTS: - void acceptTouchEvents(); - void onPanTriggered(); - void onPanFinished(); - void onPinchTriggered(); - void onPinchFinished(); - -private: - void paintEvent(QPaintEvent *); - QSize sizeHint() const; - - QImage image; - - QPanGesture *pan; - QPinchGesture *pinch; + MousePanGestureRecognizer(); - QTransform worldTransform; - QTransform currentPanTransform; - QTransform currentPinchTransform; + QGesture* createGesture(QObject *target) const; + QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); }; -#endif // PINCHWIDGET_H +#endif // MOUSEPANGESTURERECOGNIZER_H diff --git a/tests/manual/gestures/scrollarea/scrollarea.pro b/tests/manual/gestures/scrollarea/scrollarea.pro new file mode 100644 index 0000000..554810e --- /dev/null +++ b/tests/manual/gestures/scrollarea/scrollarea.pro @@ -0,0 +1,3 @@ +SOURCES = main.cpp \ + mousepangesturerecognizer.cpp +HEADERS += mousepangesturerecognizer.h diff --git a/tests/manual/gestures/twopanwidgets/main.cpp b/tests/manual/gestures/twopanwidgets/main.cpp deleted file mode 100644 index 20a35fc..0000000 --- a/tests/manual/gestures/twopanwidgets/main.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite 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 Technology Preview License Agreement accompanying -** this package. -** -** 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.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtGui> - -static const char text[] = - "Hello world! This is just a lot of text with to make sure scrollbar appear"; - -class TextEdit : public QTextEdit -{ - Q_OBJECT -public Q_SLOTS: - void acceptTouch() - { - viewport()->setAttribute(Qt::WA_AcceptTouchEvents); - if (QWidget *w = qobject_cast<QPushButton*>(sender())) - w->setEnabled(false); - } -}; - -class PlainTextEdit : public QPlainTextEdit -{ - Q_OBJECT -public Q_SLOTS: - void acceptTouch() - { - viewport()->setAttribute(Qt::WA_AcceptTouchEvents); - if (QWidget *w = qobject_cast<QPushButton*>(sender())) - w->setEnabled(false); - } -}; - -class MainWindow : public QMainWindow -{ -public: - MainWindow(); -}; - -MainWindow::MainWindow() -{ - QTabWidget *tw = new QTabWidget; - setCentralWidget(tw); - { - QWidget *tab = new QWidget; - QGridLayout *layout = new QGridLayout(tab); - QTextEdit *edit1 = new TextEdit; - QTextEdit *edit2 = new TextEdit; - QString text1 = QString(text).replace(' ', '\n'); - for (int i = 0; i < 5; ++i) text1 += text1; - QString text2 = QString(text); - for (int i = 0; i < 5; ++i) text2 += text2; - edit1->setPlainText(text1); - edit2->setPlainText(text2); - edit2->setWordWrapMode(QTextOption::NoWrap); - QPushButton *btn1 = new QPushButton(QLatin1String("AcceptTouchEvents")); - connect(btn1, SIGNAL(clicked()), edit1, SLOT(acceptTouch())); - QPushButton *btn2 = new QPushButton(QLatin1String("AcceptTouchEvents")); - connect(btn2, SIGNAL(clicked()), edit2, SLOT(acceptTouch())); - layout->addWidget(btn1, 0, 0); - layout->addWidget(btn2, 0, 1); - layout->addWidget(edit1, 1, 0); - layout->addWidget(edit2, 1, 1); - tw->addTab(tab, QLatin1String("QTextEdit")); - } - { - QWidget *tab = new QWidget; - QGridLayout *layout = new QGridLayout(tab); - QPlainTextEdit *edit1 = new PlainTextEdit; - QPlainTextEdit *edit2 = new PlainTextEdit; - QString text1 = QString(text).replace(' ', '\n'); - for (int i = 0; i < 5; ++i) text1 += text1; - QString text2 = QString(text); - for (int i = 0; i < 5; ++i) text2 += text2; - edit1->setPlainText(text1); - edit2->setPlainText(text2); - edit2->setWordWrapMode(QTextOption::NoWrap); - QPushButton *btn1 = new QPushButton(QLatin1String("AcceptTouchEvents")); - connect(btn1, SIGNAL(clicked()), edit1, SLOT(acceptTouch())); - QPushButton *btn2 = new QPushButton(QLatin1String("AcceptTouchEvents")); - connect(btn2, SIGNAL(clicked()), edit2, SLOT(acceptTouch())); - layout->addWidget(btn1, 0, 0); - layout->addWidget(btn2, 0, 1); - layout->addWidget(edit1, 1, 0); - layout->addWidget(edit2, 1, 1); - tw->addTab(tab, QLatin1String("QPlainTextEdit")); - } -} - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - MainWindow window; - window.show(); - return app.exec(); -} - -#include "main.moc" diff --git a/tests/manual/gestures/twopanwidgets/twopanwidgets.pro b/tests/manual/gestures/twopanwidgets/twopanwidgets.pro deleted file mode 100644 index 5254077..0000000 --- a/tests/manual/gestures/twopanwidgets/twopanwidgets.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES = main.cpp
\ No newline at end of file |