summaryrefslogtreecommitdiffstats
path: root/examples/gestures/collidingmice
diff options
context:
space:
mode:
Diffstat (limited to 'examples/gestures/collidingmice')
-rw-r--r--examples/gestures/collidingmice/collidingmice.pro18
-rw-r--r--examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp172
-rw-r--r--examples/gestures/collidingmice/gesturerecognizerlinjazax.h65
-rw-r--r--examples/gestures/collidingmice/images/cheese.jpgbin0 -> 3029 bytes
-rw-r--r--examples/gestures/collidingmice/linjazaxgesture.h61
-rw-r--r--examples/gestures/collidingmice/main.cpp163
-rw-r--r--examples/gestures/collidingmice/mice.qrc5
-rw-r--r--examples/gestures/collidingmice/mouse.cpp200
-rw-r--r--examples/gestures/collidingmice/mouse.h72
9 files changed, 756 insertions, 0 deletions
diff --git a/examples/gestures/collidingmice/collidingmice.pro b/examples/gestures/collidingmice/collidingmice.pro
new file mode 100644
index 0000000..15164ce
--- /dev/null
+++ b/examples/gestures/collidingmice/collidingmice.pro
@@ -0,0 +1,18 @@
+HEADERS += \
+ mouse.h \
+ gesturerecognizerlinjazax.h \
+ linjazaxgesture.h
+
+SOURCES += \
+ main.cpp \
+ mouse.cpp \
+ gesturerecognizerlinjazax.cpp
+
+RESOURCES += \
+ mice.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/gestures/collidingmice
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS collidingmice.pro images
+sources.path = $$[QT_INSTALL_EXAMPLES]/gestures/collidingmice
+INSTALLS += target sources
diff --git a/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp b/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp
new file mode 100644
index 0000000..41bb113
--- /dev/null
+++ b/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp
@@ -0,0 +1,172 @@
+#include "gesturerecognizerlinjazax.h"
+
+#include <QRegExp>
+#include <QDebug>
+
+static const int SIZE = 20;
+
+DirectionSimpleRecognizer::DirectionSimpleRecognizer()
+{
+}
+
+Direction DirectionSimpleRecognizer::addPosition(const QPoint &pos)
+{
+ if (!directions.isEmpty()) {
+ const QPoint tmp = pos - directions.back().point;
+ if (tmp.manhattanLength() < 5)
+ return Direction();
+ }
+ if (lastPoint.isNull()) {
+ lastPoint = pos;
+ return Direction();
+ }
+ int dx = pos.x() - lastPoint.x();
+ int dy = pos.y() - lastPoint.y();
+ QString direction;
+ if (dx < 0) {
+ if (-1*dx >= SIZE/2)
+ direction = "4";
+ } else {
+ if (dx >= SIZE/2)
+ direction = "6";
+ }
+ if (dy < 0) {
+ if (-1*dy >= SIZE/2)
+ direction = "8";
+ } else {
+ if (dy >= SIZE/2)
+ direction = "2";
+ }
+ if (direction.isEmpty())
+ return Direction();
+
+ lastPoint = pos;
+ directions.push_back(Direction(direction, pos));
+ return Direction(direction, pos);
+}
+
+
+DirectionList DirectionSimpleRecognizer::getDirections() const
+{
+ return directions;
+}
+
+void DirectionSimpleRecognizer::reset()
+{
+ directions.clear();
+ lastPoint = QPoint();
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+GestureRecognizerLinjaZax::GestureRecognizerLinjaZax()
+ : QGestureRecognizer(QLatin1String("LinjaZax")), mousePressed(false), gestureFinished(false),
+ zoomState(LinjaZaxGesture::NoZoom)
+{
+}
+
+QGestureRecognizer::Result GestureRecognizerLinjaZax::filterEvent(const QEvent *event)
+{
+ if (zoomState != LinjaZaxGesture::NoZoom && !lastDirections.isEmpty()) {
+ lastDirections = lastDirections.right(1);
+ zoomState = LinjaZaxGesture::NoZoom;
+ }
+
+ if (event->type() == QEvent::MouseButtonPress) {
+ if (!currentDirection.isEmpty()) {
+ reset();
+ return QGestureRecognizer::NotGesture;
+ }
+ mousePressed = true;
+ const QMouseEvent *ev = static_cast<const QMouseEvent*>(event);
+ pressedPos = lastPos = currentPos = ev->pos();
+ return QGestureRecognizer::MaybeGesture;
+ } else if (event->type() == QEvent::MouseButtonRelease) {
+ const QMouseEvent *ev = static_cast<const QMouseEvent*>(event);
+ if (mousePressed && !currentDirection.isEmpty()) {
+ gestureFinished = true;
+ currentPos = ev->pos();
+ internalReset();
+ return QGestureRecognizer::GestureFinished;
+ }
+ reset();
+ return QGestureRecognizer::NotGesture;
+ } else if (event->type() == QEvent::MouseMove) {
+ if (!mousePressed)
+ return QGestureRecognizer::NotGesture;
+ lastPos = currentPos;
+ const QMouseEvent *ev = static_cast<const QMouseEvent*>(event);
+ currentPos = ev->pos();
+ QString direction =
+ simpleRecognizer.addPosition(ev->pos()).direction;
+ QGestureRecognizer::Result result = QGestureRecognizer::NotGesture;
+ if (currentDirection.isEmpty()) {
+ if (direction.isEmpty())
+ result = QGestureRecognizer::MaybeGesture;
+ else
+ result = QGestureRecognizer::GestureStarted;
+ } else {
+ result = QGestureRecognizer::GestureStarted;
+ }
+ if (!direction.isEmpty()) {
+ lastDirections.append(direction);
+ currentDirection = direction;
+ if (lastDirections.length() > 5)
+ lastDirections.remove(0, 1);
+ if (lastDirections.contains("248") || lastDirections.contains("2448"))
+ zoomState = LinjaZaxGesture::ZoomingIn;
+ else if (lastDirections.contains("268") || lastDirections.contains("2668"))
+ zoomState = LinjaZaxGesture::ZoomingOut;
+ }
+ return result;
+ }
+ return QGestureRecognizer::NotGesture;
+}
+
+static inline LinjaZaxGesture::DirectionType convertPanningDirection(const QString &direction)
+{
+ if (direction.length() == 1) {
+ if (direction == "4")
+ return LinjaZaxGesture::Left;
+ else if (direction == "6")
+ return LinjaZaxGesture::Right;
+ else if (direction == "8")
+ return LinjaZaxGesture::Up;
+ else if (direction == "2")
+ return LinjaZaxGesture::Down;
+ }
+ return LinjaZaxGesture::None;
+}
+
+QGesture* GestureRecognizerLinjaZax::getGesture()
+{
+ LinjaZaxGesture::DirectionType dir = convertPanningDirection(currentDirection);
+ LinjaZaxGesture::DirectionType lastDir = convertPanningDirection(lastDirections.right(1));
+ if (dir == LinjaZaxGesture::None)
+ return 0;
+ LinjaZaxGesture *g =
+ new LinjaZaxGesture(this, pressedPos, lastPos, currentPos,
+ QRect(), pressedPos, QDateTime(), 0,
+ gestureFinished ? Qt::GestureFinished : Qt::GestureStarted);
+ g->lastDirection_ = lastDir;
+ g->direction_ = dir;
+ g->zoomState_ = zoomState;
+
+ return g;
+}
+
+void GestureRecognizerLinjaZax::reset()
+{
+ mousePressed = false;
+ lastDirections.clear();
+ currentDirection.clear();
+ gestureFinished = false;
+ simpleRecognizer.reset();
+ zoomState = LinjaZaxGesture::NoZoom;
+}
+
+void GestureRecognizerLinjaZax::internalReset()
+{
+ mousePressed = false;
+ simpleRecognizer.reset();
+}
diff --git a/examples/gestures/collidingmice/gesturerecognizerlinjazax.h b/examples/gestures/collidingmice/gesturerecognizerlinjazax.h
new file mode 100644
index 0000000..07172f1
--- /dev/null
+++ b/examples/gestures/collidingmice/gesturerecognizerlinjazax.h
@@ -0,0 +1,65 @@
+#ifndef GESTURERECOGNIZERLINJAZAX_H
+#define GESTURERECOGNIZERLINJAZAX_H
+
+#include <QList>
+#include <QPoint>
+#include <QString>
+#include <QGesture>
+#include <QGestureRecognizer>
+
+#include "linjazaxgesture.h"
+
+struct Direction
+{
+ QString direction;
+ QPoint point;
+
+ Direction(QString dir, const QPoint &pt)
+ : direction(dir), point(pt) { }
+ Direction()
+ : direction() { }
+
+ inline bool isEmpty() const { return direction.isEmpty(); }
+ inline bool isNull() const { return direction.isEmpty(); }
+};
+typedef QList<Direction> DirectionList;
+
+class DirectionSimpleRecognizer
+{
+public:
+ DirectionSimpleRecognizer();
+ Direction addPosition(const QPoint &pos);
+ DirectionList getDirections() const;
+ void reset();
+
+private:
+ QPoint lastPoint;
+ DirectionList directions;
+};
+
+class GestureRecognizerLinjaZax : public QGestureRecognizer
+{
+ Q_OBJECT
+public:
+ GestureRecognizerLinjaZax();
+
+ QGestureRecognizer::Result filterEvent(const QEvent *event);
+ QGesture* getGesture();
+
+ void reset();
+
+private:
+ void internalReset();
+
+ QPoint pressedPos;
+ QPoint lastPos;
+ QPoint currentPos;
+ bool mousePressed;
+ bool gestureFinished;
+ QString lastDirections;
+ QString currentDirection;
+ DirectionSimpleRecognizer simpleRecognizer;
+ LinjaZaxGesture::ZoomState zoomState;
+};
+
+#endif
diff --git a/examples/gestures/collidingmice/images/cheese.jpg b/examples/gestures/collidingmice/images/cheese.jpg
new file mode 100644
index 0000000..dea5795
--- /dev/null
+++ b/examples/gestures/collidingmice/images/cheese.jpg
Binary files differ
diff --git a/examples/gestures/collidingmice/linjazaxgesture.h b/examples/gestures/collidingmice/linjazaxgesture.h
new file mode 100644
index 0000000..92343cf
--- /dev/null
+++ b/examples/gestures/collidingmice/linjazaxgesture.h
@@ -0,0 +1,61 @@
+#ifndef LINJAZAXGESTURE_H
+#define LINJAZAXGESTURE_H
+
+#include <QGesture>
+
+class LinjaZaxGesture : public QGesture
+{
+public:
+ enum DirectionType
+ {
+ None = 0,
+ LeftDown = 1,
+ DownLeft = LeftDown,
+ Down = 2,
+ RightDown = 3,
+ DownRight = RightDown,
+ Left = 4,
+ Right = 6,
+ LeftUp = 7,
+ UpLeft = LeftUp,
+ Up = 8,
+ RightUp = 9,
+ UpRight = RightUp
+ };
+
+ enum ZoomState
+ {
+ NoZoom,
+ ZoomingIn,
+ ZoomingOut
+ };
+
+public:
+ explicit LinjaZaxGesture(QObject *parent,
+ Qt::GestureState state = Qt::GestureStarted)
+ : QGesture(parent, QLatin1String("LinjaZax"), state), lastDirection_(None),
+ direction_(None), zoomState_(NoZoom) { }
+ LinjaZaxGesture(QObject *parent, const QPoint &startPos,
+ const QPoint &lastPos, const QPoint &pos, const QRect &rect,
+ const QPoint &hotSpot, const QDateTime &startTime,
+ uint duration, Qt::GestureState state)
+ : QGesture(parent, QLatin1String("LinjaZax"), startPos, lastPos,
+ pos, rect, hotSpot, startTime, duration, state) { }
+ ~LinjaZaxGesture() { }
+
+ DirectionType lastDirection() const
+ { return lastDirection_; }
+ DirectionType direction() const
+ { return direction_; }
+
+ ZoomState zoomState() const
+ { return zoomState_; }
+
+private:
+ DirectionType lastDirection_;
+ DirectionType direction_;
+ ZoomState zoomState_;
+ friend class GestureRecognizerLinjaZax;
+};
+
+#endif
diff --git a/examples/gestures/collidingmice/main.cpp b/examples/gestures/collidingmice/main.cpp
new file mode 100644
index 0000000..4309bc0
--- /dev/null
+++ b/examples/gestures/collidingmice/main.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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 qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mouse.h"
+
+#include "gesturerecognizerlinjazax.h"
+#include "linjazaxgesture.h"
+
+#include <QtGui>
+
+#include <math.h>
+
+#define ZOOMING_ANIMATION
+#ifdef ZOOMING_ANIMATION
+static const int AnimationSteps = 10;
+#endif
+
+static const int MouseCount = 7;
+
+class PannableGraphicsView : public QGraphicsView
+{
+ Q_OBJECT
+public:
+ PannableGraphicsView(QGraphicsScene *scene, QWidget *parent = 0)
+ : QGraphicsView(scene, parent)
+ {
+ grabGesture(QLatin1String("LinjaZax"));
+#ifdef ZOOMING_ANIMATION
+ timeline = new QTimeLine(700, this);
+ timeline->setFrameRange(0, AnimationSteps);
+ connect(timeline, SIGNAL(frameChanged(int)), this, SLOT(animationStep(int)));
+#endif
+ }
+protected:
+ bool event(QEvent *event)
+ {
+ if (event->type() == QEvent::Gesture) {
+ QGestureEvent *ge = static_cast<QGestureEvent*>(event);
+ const LinjaZaxGesture *g = static_cast<const LinjaZaxGesture*>(ge->gesture("LinjaZax"));
+ if (g) {
+ switch (g->zoomState()) {
+ case LinjaZaxGesture::ZoomingIn:
+#ifdef ZOOMING_ANIMATION
+ scaleStep = 1. + 0.5/AnimationSteps;
+ timeline->stop();
+ timeline->start();
+#else
+ scale(1.5, 1.5);
+#endif
+ break;
+ case LinjaZaxGesture::ZoomingOut:
+#ifdef ZOOMING_ANIMATION
+ scaleStep = 1. - 0.5/AnimationSteps;
+ timeline->stop();
+ timeline->start();
+#else
+ scale(0.6, 0.6);
+#endif
+ break;
+ default:
+ break;
+ };
+ QPoint pt = g->pos() - g->lastPos();
+ horizontalScrollBar()->setValue(horizontalScrollBar()->value() - pt.x());
+ verticalScrollBar()->setValue(verticalScrollBar()->value() - pt.y());
+ event->accept();
+ return true;
+ }
+ }
+ return QGraphicsView::event(event);
+ }
+private slots:
+#ifdef ZOOMING_ANIMATION
+ void animationStep(int step)
+ {
+ scale(scaleStep, scaleStep);
+ }
+private:
+ qreal scaleStep;
+ QTimeLine *timeline;
+#endif
+};
+
+//! [0]
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ app.addGestureRecognizer(new GestureRecognizerLinjaZax);
+ qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
+//! [0]
+
+//! [1]
+ QGraphicsScene scene;
+ scene.setSceneRect(-600, -600, 1200, 1200);
+//! [1] //! [2]
+ scene.setItemIndexMethod(QGraphicsScene::NoIndex);
+//! [2]
+
+//! [3]
+ for (int i = 0; i < MouseCount; ++i) {
+ Mouse *mouse = new Mouse;
+ mouse->setPos(::sin((i * 6.28) / MouseCount) * 200,
+ ::cos((i * 6.28) / MouseCount) * 200);
+ scene.addItem(mouse);
+ }
+//! [3]
+
+//! [4]
+ PannableGraphicsView view(&scene);
+ view.setRenderHint(QPainter::Antialiasing);
+ view.setBackgroundBrush(QPixmap(":/images/cheese.jpg"));
+//! [4] //! [5]
+ view.setCacheMode(QGraphicsView::CacheBackground);
+ view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
+ //view.setDragMode(QGraphicsView::ScrollHandDrag);
+//! [5] //! [6]
+ view.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Colliding Mice"));
+ view.resize(400, 300);
+ view.show();
+
+ return app.exec();
+}
+//! [6]
+
+#include "main.moc"
diff --git a/examples/gestures/collidingmice/mice.qrc b/examples/gestures/collidingmice/mice.qrc
new file mode 100644
index 0000000..accdb4d
--- /dev/null
+++ b/examples/gestures/collidingmice/mice.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/" >
+ <file>images/cheese.jpg</file>
+ </qresource>
+</RCC>
diff --git a/examples/gestures/collidingmice/mouse.cpp b/examples/gestures/collidingmice/mouse.cpp
new file mode 100644
index 0000000..1d9fa89
--- /dev/null
+++ b/examples/gestures/collidingmice/mouse.cpp
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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 qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mouse.h"
+
+#include <QGraphicsScene>
+#include <QPainter>
+#include <QStyleOption>
+
+#include <math.h>
+
+static const double Pi = 3.14159265358979323846264338327950288419717;
+static double TwoPi = 2.0 * Pi;
+
+static qreal normalizeAngle(qreal angle)
+{
+ while (angle < 0)
+ angle += TwoPi;
+ while (angle > TwoPi)
+ angle -= TwoPi;
+ return angle;
+}
+
+//! [0]
+Mouse::Mouse()
+ : angle(0), speed(0), mouseEyeDirection(0),
+ color(qrand() % 256, qrand() % 256, qrand() % 256)
+{
+ rotate(qrand() % (360 * 16));
+ startTimer(1000 / 33);
+}
+//! [0]
+
+//! [1]
+QRectF Mouse::boundingRect() const
+{
+ qreal adjust = 0.5;
+ return QRectF(-18 - adjust, -22 - adjust,
+ 36 + adjust, 60 + adjust);
+}
+//! [1]
+
+//! [2]
+QPainterPath Mouse::shape() const
+{
+ QPainterPath path;
+ path.addRect(-10, -20, 20, 40);
+ return path;
+}
+//! [2]
+
+//! [3]
+void Mouse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ // Body
+ painter->setBrush(color);
+ painter->drawEllipse(-10, -20, 20, 40);
+
+ // Eyes
+ painter->setBrush(Qt::white);
+ painter->drawEllipse(-10, -17, 8, 8);
+ painter->drawEllipse(2, -17, 8, 8);
+
+ // Nose
+ painter->setBrush(Qt::black);
+ painter->drawEllipse(QRectF(-2, -22, 4, 4));
+
+ // Pupils
+ painter->drawEllipse(QRectF(-8.0 + mouseEyeDirection, -17, 4, 4));
+ painter->drawEllipse(QRectF(4.0 + mouseEyeDirection, -17, 4, 4));
+
+ // Ears
+ painter->setBrush(scene()->collidingItems(this).isEmpty() ? Qt::darkYellow : Qt::red);
+ painter->drawEllipse(-17, -12, 16, 16);
+ painter->drawEllipse(1, -12, 16, 16);
+
+ // Tail
+ QPainterPath path(QPointF(0, 20));
+ path.cubicTo(-5, 22, -5, 22, 0, 25);
+ path.cubicTo(5, 27, 5, 32, 0, 30);
+ path.cubicTo(-5, 32, -5, 42, 0, 35);
+ painter->setBrush(Qt::NoBrush);
+ painter->drawPath(path);
+}
+//! [3]
+
+//! [4]
+void Mouse::timerEvent(QTimerEvent *)
+{
+//! [4]
+ // Don't move too far away
+//! [5]
+ QLineF lineToCenter(QPointF(0, 0), mapFromScene(0, 0));
+ if (lineToCenter.length() > 150) {
+ qreal angleToCenter = ::acos(lineToCenter.dx() / lineToCenter.length());
+ if (lineToCenter.dy() < 0)
+ angleToCenter = TwoPi - angleToCenter;
+ angleToCenter = normalizeAngle((Pi - angleToCenter) + Pi / 2);
+
+ if (angleToCenter < Pi && angleToCenter > Pi / 4) {
+ // Rotate left
+ angle += (angle < -Pi / 2) ? 0.25 : -0.25;
+ } else if (angleToCenter >= Pi && angleToCenter < (Pi + Pi / 2 + Pi / 4)) {
+ // Rotate right
+ angle += (angle < Pi / 2) ? 0.25 : -0.25;
+ }
+ } else if (::sin(angle) < 0) {
+ angle += 0.25;
+ } else if (::sin(angle) > 0) {
+ angle -= 0.25;
+//! [5] //! [6]
+ }
+//! [6]
+
+ // Try not to crash with any other mice
+//! [7]
+ QList<QGraphicsItem *> dangerMice = scene()->items(QPolygonF()
+ << mapToScene(0, 0)
+ << mapToScene(-30, -50)
+ << mapToScene(30, -50));
+ foreach (QGraphicsItem *item, dangerMice) {
+ if (item == this)
+ continue;
+
+ QLineF lineToMouse(QPointF(0, 0), mapFromItem(item, 0, 0));
+ qreal angleToMouse = ::acos(lineToMouse.dx() / lineToMouse.length());
+ if (lineToMouse.dy() < 0)
+ angleToMouse = TwoPi - angleToMouse;
+ angleToMouse = normalizeAngle((Pi - angleToMouse) + Pi / 2);
+
+ if (angleToMouse >= 0 && angleToMouse < Pi / 2) {
+ // Rotate right
+ angle += 0.5;
+ } else if (angleToMouse <= TwoPi && angleToMouse > (TwoPi - Pi / 2)) {
+ // Rotate left
+ angle -= 0.5;
+//! [7] //! [8]
+ }
+//! [8] //! [9]
+ }
+//! [9]
+
+ // Add some random movement
+//! [10]
+ if (dangerMice.size() > 1 && (qrand() % 10) == 0) {
+ if (qrand() % 1)
+ angle += (qrand() % 100) / 500.0;
+ else
+ angle -= (qrand() % 100) / 500.0;
+ }
+//! [10]
+
+//! [11]
+ speed += (-50 + qrand() % 100) / 100.0;
+
+ qreal dx = ::sin(angle) * 10;
+ mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5;
+
+ rotate(dx);
+ setPos(mapToParent(0, -(3 + sin(speed) * 3)));
+}
+//! [11]
diff --git a/examples/gestures/collidingmice/mouse.h b/examples/gestures/collidingmice/mouse.h
new file mode 100644
index 0000000..7545fe6
--- /dev/null
+++ b/examples/gestures/collidingmice/mouse.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the $MODULE$ of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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 qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MOUSE_H
+#define MOUSE_H
+
+#include <QGraphicsItem>
+#include <QObject>
+
+//! [0]
+class Mouse : public QObject, public QGraphicsItem
+{
+ Q_OBJECT
+
+public:
+ Mouse();
+
+ QRectF boundingRect() const;
+ QPainterPath shape() const;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget);
+
+protected:
+ void timerEvent(QTimerEvent *event);
+
+private:
+ qreal angle;
+ qreal speed;
+ qreal mouseEyeDirection;
+ QColor color;
+};
+//! [0]
+
+#endif