diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-03-06 15:55:02 (GMT) |
---|---|---|
committer | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-05-11 13:42:40 (GMT) |
commit | 90ead023ec593bd3dba0ef8eb4e38f2299cfb783 (patch) | |
tree | 5931b45e60109143e3f23084a017146597e5ac1c | |
parent | 15588496830fee6fbe38fda76411e483a51ddd08 (diff) | |
download | Qt-90ead023ec593bd3dba0ef8eb4e38f2299cfb783.zip Qt-90ead023ec593bd3dba0ef8eb4e38f2299cfb783.tar.gz Qt-90ead023ec593bd3dba0ef8eb4e38f2299cfb783.tar.bz2 |
Implemented LinjaZax-like gesture in collidingmice example.
-rw-r--r-- | examples/gestures/collidingmice/collidingmice.pro | 8 | ||||
-rw-r--r-- | examples/gestures/collidingmice/gesturerecognizerlinjazax.cpp | 189 | ||||
-rw-r--r-- | examples/gestures/collidingmice/gesturerecognizerlinjazax.h | 65 | ||||
-rw-r--r-- | examples/gestures/collidingmice/images/cheese.jpg | bin | 0 -> 3029 bytes | |||
-rw-r--r-- | examples/gestures/collidingmice/linjazaxgesture.h | 58 | ||||
-rw-r--r-- | examples/gestures/collidingmice/main.cpp | 19 |
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 Binary files differnew file mode 100644 index 0000000..dea5795 --- /dev/null +++ b/examples/gestures/collidingmice/images/cheese.jpg 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] |