summaryrefslogtreecommitdiffstats
path: root/examples/gestures/collidingmice
diff options
context:
space:
mode:
authorDenis Dzyubenko <denis.dzyubenko@nokia.com>2009-03-06 15:55:02 (GMT)
committerDenis Dzyubenko <denis.dzyubenko@nokia.com>2009-05-11 13:42:40 (GMT)
commit90ead023ec593bd3dba0ef8eb4e38f2299cfb783 (patch)
tree5931b45e60109143e3f23084a017146597e5ac1c /examples/gestures/collidingmice
parent15588496830fee6fbe38fda76411e483a51ddd08 (diff)
downloadQt-90ead023ec593bd3dba0ef8eb4e38f2299cfb783.zip
Qt-90ead023ec593bd3dba0ef8eb4e38f2299cfb783.tar.gz
Qt-90ead023ec593bd3dba0ef8eb4e38f2299cfb783.tar.bz2
Implemented LinjaZax-like gesture in collidingmice example.
Diffstat (limited to 'examples/gestures/collidingmice')
-rw-r--r--examples/gestures/collidingmice/collidingmice.pro8
-rw-r--r--examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp189
-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.h58
-rw-r--r--examples/gestures/collidingmice/main.cpp19
6 files changed, 335 insertions, 4 deletions
diff --git a/examples/gestures/collidingmice/collidingmice.pro b/examples/gestures/collidingmice/collidingmice.pro
index 5c7b42b..15164ce 100644
--- a/examples/gestures/collidingmice/collidingmice.pro
+++ b/examples/gestures/collidingmice/collidingmice.pro
@@ -1,8 +1,12 @@
HEADERS += \
- mouse.h
+ mouse.h \
+ gesturerecognizerlinjazax.h \
+ linjazaxgesture.h
+
SOURCES += \
main.cpp \
- mouse.cpp
+ mouse.cpp \
+ gesturerecognizerlinjazax.cpp
RESOURCES += \
mice.qrc
diff --git a/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp b/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp
new file mode 100644
index 0000000..4c57209
--- /dev/null
+++ b/examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp
@@ -0,0 +1,189 @@
+#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("LinjaZax"), mousePressed(false), gestureFinished(false),
+ zoomState(LinjaZaxGesture::NoZoom)
+{
+}
+
+QGestureRecognizer::Result GestureRecognizerLinjaZax::recognize(const QList<QEvent*> &inputEvents)
+{
+ // get all mouse events
+ QList<QMouseEvent*> events;
+ for(int i = 0; i < inputEvents.count(); ++i) {
+ QEvent *event = inputEvents.at(i);
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ events.push_back(static_cast<QMouseEvent*>(event));
+ default:
+ break;
+ }
+ }
+
+ if (zoomState != LinjaZaxGesture::NoZoom && !lastDirections.isEmpty()) {
+ lastDirections = lastDirections.right(1);
+ zoomState = LinjaZaxGesture::NoZoom;
+ }
+
+ QGestureRecognizer::Result result = QGestureRecognizer::NotGesture;
+ for(int i = 0; i < events.count(); ++i) {
+ QMouseEvent *event = events.at(i);
+ if (event->type() == QEvent::MouseButtonPress) {
+ if (!currentDirection.isEmpty()) {
+ result = QGestureRecognizer::NotGesture;
+ reset();
+ break;
+ }
+ result = QGestureRecognizer::MaybeGesture;
+ mousePressed = true;
+ pressedPos = lastPos = currentPos = event->pos();
+ } else if (event->type() == QEvent::MouseButtonRelease) {
+ if (mousePressed && !currentDirection.isEmpty()) {
+ result = QGestureRecognizer::GestureFinished;
+ gestureFinished = true;
+ currentPos = event->pos();
+ internalReset();
+ break;
+ }
+ result = QGestureRecognizer::NotGesture;
+ reset();
+ break;
+ } else if (event->type() == QEvent::MouseMove) {
+ if (!mousePressed)
+ continue;
+ lastPos = currentPos;
+ currentPos = event->pos();
+ QString direction =
+ simpleRecognizer.addPosition(event->pos()).direction;
+ if (currentDirection.isEmpty()) {
+ if (direction.isEmpty())
+ result = QGestureRecognizer::MaybeGesture;
+ else
+ result = QGestureRecognizer::GestureStarted;
+ } else {
+ result = QGestureRecognizer::GestureStarted;
+ }
+ if (!direction.isEmpty()) {
+ if (currentDirection != direction)
+ lastDirections.append(direction);
+ currentDirection = direction;
+ if (lastDirections.length() > 5)
+ lastDirections.remove(0, 1);
+ if (lastDirections.contains("248"))
+ zoomState = LinjaZaxGesture::ZoomingIn;
+ else if (lastDirections.contains("268"))
+ zoomState = LinjaZaxGesture::ZoomingOut;
+ }
+ }
+ }
+ return result;
+}
+
+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::makeEvent() const
+{
+ LinjaZaxGesture::DirectionType dir = convertPanningDirection(currentDirection);
+ LinjaZaxGesture::DirectionType lastDir = convertPanningDirection(lastDirections.right(1));
+ if (dir == LinjaZaxGesture::None)
+ return 0;
+ LinjaZaxGesture *g =
+ new LinjaZaxGesture("LinjaZax", 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..6579059
--- /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 recognize(const QList<QEvent*> &inputEvents);
+ QGesture* makeEvent() const;
+
+ 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..9601675
--- /dev/null
+++ b/examples/gestures/collidingmice/linjazaxgesture.h
@@ -0,0 +1,58 @@
+#ifndef LINJAZAXGESTURE_H
+#define LINJAZAXGESTURE_H
+
+#include <QGesture>
+
+class Q_GUI_EXPORT 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(const Qt::GestureType &type, Qt::GestureState state = Qt::GestureStarted)
+ : QGesture(type, state), lastDirection_(None), direction_(None), zoomState_(NoZoom) { }
+ LinjaZaxGesture(const Qt::GestureType &type, const QPoint &startPos,
+ const QPoint &lastPos, const QPoint &pos, const QRect &rect,
+ const QPoint &hotSpot, const QDateTime &startTime,
+ uint duration, Qt::GestureState state)
+ : QGesture(type, 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
index 56e9f7f..9f50379 100644
--- a/examples/gestures/collidingmice/main.cpp
+++ b/examples/gestures/collidingmice/main.cpp
@@ -41,6 +41,9 @@
#include "mouse.h"
+#include "gesturerecognizerlinjazax.h"
+#include "linjazaxgesture.h"
+
#include <QtGui>
#include <math.h>
@@ -53,14 +56,25 @@ public:
PannableGraphicsView(QGraphicsScene *scene, QWidget *parent = 0)
: QGraphicsView(scene, parent)
{
- grabGesture(Qt::Pan);
+ grabGesture("LinjaZax");
}
protected:
bool event(QEvent *event)
{
if (event->type() == QEvent::Gesture) {
QGestureEvent *ge = static_cast<QGestureEvent*>(event);
- if (const QPannableGesture *g = dynamic_cast<const QPannableGesture*>(ge->gesture(Qt::Pan))) {
+ const LinjaZaxGesture *g = dynamic_cast<const LinjaZaxGesture*>(ge->gesture("LinjaZax"));
+ if (g) {
+ switch (g->zoomState()) {
+ case LinjaZaxGesture::ZoomingIn:
+ scale(1.5, 1.5);
+ break;
+ case LinjaZaxGesture::ZoomingOut:
+ scale(0.6, 0.6);
+ break;
+ default:
+ break;
+ };
QPoint pt = g->pos() - g->lastPos();
horizontalScrollBar()->setValue(horizontalScrollBar()->value() - pt.x());
verticalScrollBar()->setValue(verticalScrollBar()->value() - pt.y());
@@ -77,6 +91,7 @@ int main(int argc, char **argv)
{
QApplication app(argc, argv);
QApplication::setAttribute(Qt::AA_EnableGestures);
+ app.addGestureRecognizer(new GestureRecognizerLinjaZax);
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
//! [0]