qt/gestures/smoke_qtgestures.cpp
branchSymbian3
changeset 43 14fcccfb4c0c
parent 41 72f7e4177ac7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qt/gestures/smoke_qtgestures.cpp	Mon Jun 14 12:26:38 2010 +0100
@@ -0,0 +1,491 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 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 <QtTest/QtTest>
+#include "../shared/util.h"
+
+#include <qevent.h>
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qgesture.h>
+#include <qgesturerecognizer.h>
+#include <qgraphicsitem.h>
+#include <qgraphicsview.h>
+
+#include <qdebug.h>
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+static QPointF mapToGlobal(const QPointF &pt, QGraphicsItem *item, QGraphicsView *view)
+{
+    return view->mapToGlobal(view->mapFromScene(item->mapToScene(pt)));
+}
+
+class CustomGesture : public QGesture
+{
+    Q_OBJECT
+public:
+    static Qt::GestureType GestureType;
+
+    CustomGesture(QObject *parent = 0)
+        : QGesture(parent), serial(0)
+    {
+    }
+
+    int serial;
+
+    static const int SerialMaybeThreshold;
+    static const int SerialStartedThreshold;
+    static const int SerialFinishedThreshold;
+};
+Qt::GestureType CustomGesture::GestureType = Qt::CustomGesture;
+const int CustomGesture::SerialMaybeThreshold = 1;
+const int CustomGesture::SerialStartedThreshold = 3;
+const int CustomGesture::SerialFinishedThreshold = 6;
+
+class CustomEvent : public QEvent
+{
+public:
+    static int EventType;
+
+    CustomEvent(int serial_ = 0)
+        : QEvent(QEvent::Type(CustomEvent::EventType)),
+          serial(serial_), hasHotSpot(false)
+    {
+    }
+
+    int serial;
+    QPointF hotSpot;
+    bool hasHotSpot;
+};
+int CustomEvent::EventType = 0;
+
+class CustomGestureRecognizer : public QGestureRecognizer
+{
+public:
+    static bool ConsumeEvents;
+
+    CustomGestureRecognizer()
+    {
+        if (!CustomEvent::EventType)
+            CustomEvent::EventType = QEvent::registerEventType();
+    }
+
+    QGesture* create(QObject *)
+    {
+        return new CustomGesture;
+    }
+
+    QGestureRecognizer::Result recognize(QGesture *state, QObject*, QEvent *event)
+    {
+        if (event->type() == CustomEvent::EventType) {
+            QGestureRecognizer::Result result = 0;
+            if (CustomGestureRecognizer::ConsumeEvents)
+                result |= QGestureRecognizer::ConsumeEventHint;
+            CustomGesture *g = static_cast<CustomGesture*>(state);
+            CustomEvent *e = static_cast<CustomEvent*>(event);
+            g->serial = e->serial;
+            if (e->hasHotSpot)
+                g->setHotSpot(e->hotSpot);
+            if (g->serial >= CustomGesture::SerialFinishedThreshold)
+                result |= QGestureRecognizer::FinishGesture;
+            else if (g->serial >= CustomGesture::SerialStartedThreshold)
+                result |= QGestureRecognizer::TriggerGesture;
+            else if (g->serial >= CustomGesture::SerialMaybeThreshold)
+                result |= QGestureRecognizer::MayBeGesture;
+            else
+                result = QGestureRecognizer::CancelGesture;
+            return result;
+        }
+        return QGestureRecognizer::Ignore;
+    }
+
+    void reset(QGesture *state)
+    {
+        CustomGesture *g = static_cast<CustomGesture *>(state);
+        g->serial = 0;
+        QGestureRecognizer::reset(state);
+    }
+};
+bool CustomGestureRecognizer::ConsumeEvents = false;
+
+// same as CustomGestureRecognizer but triggers early without the maybe state
+class CustomContinuousGestureRecognizer : public QGestureRecognizer
+{
+public:
+    CustomContinuousGestureRecognizer()
+    {
+        if (!CustomEvent::EventType)
+            CustomEvent::EventType = QEvent::registerEventType();
+    }
+
+    QGesture* create(QObject *)
+    {
+        return new CustomGesture;
+    }
+
+    QGestureRecognizer::Result recognize(QGesture *state, QObject*, QEvent *event)
+    {
+        if (event->type() == CustomEvent::EventType) {
+            QGestureRecognizer::Result result = QGestureRecognizer::ConsumeEventHint;
+            CustomGesture *g = static_cast<CustomGesture *>(state);
+            CustomEvent *e = static_cast<CustomEvent *>(event);
+            g->serial = e->serial;
+            if (e->hasHotSpot)
+                g->setHotSpot(e->hotSpot);
+            if (g->serial >= CustomGesture::SerialFinishedThreshold)
+                result |= QGestureRecognizer::FinishGesture;
+            else if (g->serial >= CustomGesture::SerialMaybeThreshold)
+                result |= QGestureRecognizer::TriggerGesture;
+            else
+                result = QGestureRecognizer::CancelGesture;
+            return result;
+        }
+        return QGestureRecognizer::Ignore;
+    }
+
+    void reset(QGesture *state)
+    {
+        CustomGesture *g = static_cast<CustomGesture *>(state);
+        g->serial = 0;
+        QGestureRecognizer::reset(state);
+    }
+};
+
+class GestureWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    GestureWidget(const char *name = 0, QWidget *parent = 0)
+        : QWidget(parent)
+    {
+        if (name)
+            setObjectName(QLatin1String(name));
+        reset();
+        acceptGestureOverride = false;
+    }
+    void reset()
+    {
+        customEventsReceived = 0;
+        gestureEventsReceived = 0;
+        gestureOverrideEventsReceived = 0;
+        events.clear();
+        overrideEvents.clear();
+        ignoredGestures.clear();
+    }
+
+    int customEventsReceived;
+    int gestureEventsReceived;
+    int gestureOverrideEventsReceived;
+    struct Events
+    {
+        QList<Qt::GestureType> all;
+        QList<Qt::GestureType> started;
+        QList<Qt::GestureType> updated;
+        QList<Qt::GestureType> finished;
+        QList<Qt::GestureType> canceled;
+
+        void clear()
+        {
+            all.clear();
+            started.clear();
+            updated.clear();
+            finished.clear();
+            canceled.clear();
+        }
+    } events, overrideEvents;
+
+    bool acceptGestureOverride;
+    QSet<Qt::GestureType> ignoredGestures;
+
+protected:
+    bool event(QEvent *event)
+    {
+        Events *eventsPtr = 0;
+        if (event->type() == QEvent::Gesture) {
+            QGestureEvent *e = static_cast<QGestureEvent*>(event);
+            ++gestureEventsReceived;
+            eventsPtr = &events;
+            foreach(Qt::GestureType type, ignoredGestures)
+                e->ignore(e->gesture(type));
+        } else if (event->type() == QEvent::GestureOverride) {
+            ++gestureOverrideEventsReceived;
+            eventsPtr = &overrideEvents;
+            if (acceptGestureOverride)
+                event->accept();
+        }
+        if (eventsPtr) {
+            QGestureEvent *e = static_cast<QGestureEvent*>(event);
+            QList<QGesture*> gestures = e->gestures();
+            foreach(QGesture *g, gestures) {
+                eventsPtr->all << g->gestureType();
+                switch(g->state()) {
+                case Qt::GestureStarted:
+                    eventsPtr->started << g->gestureType();
+                    break;
+                case Qt::GestureUpdated:
+                    eventsPtr->updated << g->gestureType();
+                    break;
+                case Qt::GestureFinished:
+                    eventsPtr->finished << g->gestureType();
+                    break;
+                case Qt::GestureCanceled:
+                    eventsPtr->canceled << g->gestureType();
+                    break;
+                default:
+                    Q_ASSERT(false);
+                }
+            }
+        } else if (event->type() == CustomEvent::EventType) {
+            ++customEventsReceived;
+        } else {
+            return QWidget::event(event);
+        }
+        return true;
+    }
+};
+
+// TODO rename to sendGestureSequence
+static void sendCustomGesture(CustomEvent *event, QObject *object, QGraphicsScene *scene = 0)
+{
+    for (int i = CustomGesture::SerialMaybeThreshold;
+         i <= CustomGesture::SerialFinishedThreshold; ++i) {
+        event->serial = i;
+        if (scene)
+            scene->sendEvent(qobject_cast<QGraphicsObject *>(object), event);
+        else
+            QApplication::sendEvent(object, event);
+    }
+}
+
+class tst_Gestures : public QObject
+{
+Q_OBJECT
+
+public:
+    tst_Gestures();
+    virtual ~tst_Gestures();
+
+public slots:
+    void initTestCase();
+    void cleanupTestCase();
+    void init();
+    void cleanup();
+
+private slots:
+    void customGesture();
+};
+
+tst_Gestures::tst_Gestures()
+{
+}
+
+tst_Gestures::~tst_Gestures()
+{
+}
+
+void tst_Gestures::initTestCase()
+{
+    CustomGesture::GestureType = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
+    QVERIFY(CustomGesture::GestureType != Qt::GestureType(0));
+    QVERIFY(CustomGesture::GestureType != Qt::CustomGesture);
+}
+
+void tst_Gestures::cleanupTestCase()
+{
+    QGestureRecognizer::unregisterRecognizer(CustomGesture::GestureType);
+}
+
+void tst_Gestures::init()
+{
+}
+
+void tst_Gestures::cleanup()
+{
+}
+
+void tst_Gestures::customGesture()
+{
+    GestureWidget widget;
+    widget.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
+    CustomEvent event;
+    sendCustomGesture(&event, &widget);
+
+    static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+    static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;
+    QCOMPARE(widget.customEventsReceived, TotalCustomEventsCount);
+    QCOMPARE(widget.gestureEventsReceived, TotalGestureEventsCount);
+    QCOMPARE(widget.gestureOverrideEventsReceived, 0);
+    QCOMPARE(widget.events.all.size(), TotalGestureEventsCount);
+    for(int i = 0; i < widget.events.all.size(); ++i)
+        QCOMPARE(widget.events.all.at(i), CustomGesture::GestureType);
+    QCOMPARE(widget.events.started.size(), 1);
+    QCOMPARE(widget.events.updated.size(), TotalGestureEventsCount - 2);
+    QCOMPARE(widget.events.finished.size(), 1);
+    QCOMPARE(widget.events.canceled.size(), 0);
+}
+
+static const QColor InstanceColors[] = {
+    Qt::blue, Qt::red, Qt::green, Qt::gray, Qt::yellow
+};
+
+class GestureItem : public QGraphicsObject
+{
+    static int InstanceCount;
+
+public:
+    GestureItem(const char *name = 0)
+    {
+        instanceNumber = InstanceCount++;
+        if (name)
+            setObjectName(QLatin1String(name));
+        size = QRectF(0, 0, 100, 100);
+        customEventsReceived = 0;
+        gestureEventsReceived = 0;
+        gestureOverrideEventsReceived = 0;
+        events.clear();
+        overrideEvents.clear();
+        acceptGestureOverride = false;
+    }
+    ~GestureItem()
+    {
+        --InstanceCount;
+    }
+
+    int customEventsReceived;
+    int gestureEventsReceived;
+    int gestureOverrideEventsReceived;
+    struct Events
+    {
+        QList<Qt::GestureType> all;
+        QList<Qt::GestureType> started;
+        QList<Qt::GestureType> updated;
+        QList<Qt::GestureType> finished;
+        QList<Qt::GestureType> canceled;
+
+        void clear()
+        {
+            all.clear();
+            started.clear();
+            updated.clear();
+            finished.clear();
+            canceled.clear();
+        }
+    } events, overrideEvents;
+
+    bool acceptGestureOverride;
+    QSet<Qt::GestureType> ignoredGestures;
+
+    QRectF size;
+    int instanceNumber;
+
+    void reset()
+    {
+        customEventsReceived = 0;
+        gestureEventsReceived = 0;
+        gestureOverrideEventsReceived = 0;
+        events.clear();
+        overrideEvents.clear();
+        ignoredGestures.clear();
+    }
+
+protected:
+    QRectF boundingRect() const
+    {
+        return size;
+    }
+    void paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
+    {
+        QColor color = InstanceColors[instanceNumber % (sizeof(InstanceColors)/sizeof(InstanceColors[0]))];
+        p->fillRect(boundingRect(), color);
+    }
+
+    bool event(QEvent *event)
+    {
+        Events *eventsPtr = 0;
+        if (event->type() == QEvent::Gesture) {
+            ++gestureEventsReceived;
+            eventsPtr = &events;
+            QGestureEvent *e = static_cast<QGestureEvent *>(event);
+            foreach(Qt::GestureType type, ignoredGestures)
+                e->ignore(e->gesture(type));
+        } else if (event->type() == QEvent::GestureOverride) {
+            ++gestureOverrideEventsReceived;
+            eventsPtr = &overrideEvents;
+            if (acceptGestureOverride)
+                event->accept();
+        }
+        if (eventsPtr) {
+            QGestureEvent *e = static_cast<QGestureEvent*>(event);
+            QList<QGesture*> gestures = e->gestures();
+            foreach(QGesture *g, gestures) {
+                eventsPtr->all << g->gestureType();
+                switch(g->state()) {
+                case Qt::GestureStarted:
+                    eventsPtr->started << g->gestureType();
+                    break;
+                case Qt::GestureUpdated:
+                    eventsPtr->updated << g->gestureType();
+                    break;
+                case Qt::GestureFinished:
+                    eventsPtr->finished << g->gestureType();
+                    break;
+                case Qt::GestureCanceled:
+                    eventsPtr->canceled << g->gestureType();
+                    break;
+                default:
+                    Q_ASSERT(false);
+                }
+            }
+        } else if (event->type() == CustomEvent::EventType) {
+            ++customEventsReceived;
+        } else {
+            return QGraphicsObject::event(event);
+        }
+        return true;
+    }
+};
+int GestureItem::InstanceCount = 0;
+
+QTEST_MAIN(tst_Gestures)
+#include "smoke_qtgestures.moc"