qt/gestures/smoke_qtgestures.cpp
branchSymbian3
changeset 43 14fcccfb4c0c
parent 41 72f7e4177ac7
equal deleted inserted replaced
42:4f2786c97bf4 43:14fcccfb4c0c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 #include "../shared/util.h"
       
    45 
       
    46 #include <qevent.h>
       
    47 #include <qwidget.h>
       
    48 #include <qlayout.h>
       
    49 #include <qgesture.h>
       
    50 #include <qgesturerecognizer.h>
       
    51 #include <qgraphicsitem.h>
       
    52 #include <qgraphicsview.h>
       
    53 
       
    54 #include <qdebug.h>
       
    55 
       
    56 //TESTED_CLASS=
       
    57 //TESTED_FILES=
       
    58 
       
    59 static QPointF mapToGlobal(const QPointF &pt, QGraphicsItem *item, QGraphicsView *view)
       
    60 {
       
    61     return view->mapToGlobal(view->mapFromScene(item->mapToScene(pt)));
       
    62 }
       
    63 
       
    64 class CustomGesture : public QGesture
       
    65 {
       
    66     Q_OBJECT
       
    67 public:
       
    68     static Qt::GestureType GestureType;
       
    69 
       
    70     CustomGesture(QObject *parent = 0)
       
    71         : QGesture(parent), serial(0)
       
    72     {
       
    73     }
       
    74 
       
    75     int serial;
       
    76 
       
    77     static const int SerialMaybeThreshold;
       
    78     static const int SerialStartedThreshold;
       
    79     static const int SerialFinishedThreshold;
       
    80 };
       
    81 Qt::GestureType CustomGesture::GestureType = Qt::CustomGesture;
       
    82 const int CustomGesture::SerialMaybeThreshold = 1;
       
    83 const int CustomGesture::SerialStartedThreshold = 3;
       
    84 const int CustomGesture::SerialFinishedThreshold = 6;
       
    85 
       
    86 class CustomEvent : public QEvent
       
    87 {
       
    88 public:
       
    89     static int EventType;
       
    90 
       
    91     CustomEvent(int serial_ = 0)
       
    92         : QEvent(QEvent::Type(CustomEvent::EventType)),
       
    93           serial(serial_), hasHotSpot(false)
       
    94     {
       
    95     }
       
    96 
       
    97     int serial;
       
    98     QPointF hotSpot;
       
    99     bool hasHotSpot;
       
   100 };
       
   101 int CustomEvent::EventType = 0;
       
   102 
       
   103 class CustomGestureRecognizer : public QGestureRecognizer
       
   104 {
       
   105 public:
       
   106     static bool ConsumeEvents;
       
   107 
       
   108     CustomGestureRecognizer()
       
   109     {
       
   110         if (!CustomEvent::EventType)
       
   111             CustomEvent::EventType = QEvent::registerEventType();
       
   112     }
       
   113 
       
   114     QGesture* create(QObject *)
       
   115     {
       
   116         return new CustomGesture;
       
   117     }
       
   118 
       
   119     QGestureRecognizer::Result recognize(QGesture *state, QObject*, QEvent *event)
       
   120     {
       
   121         if (event->type() == CustomEvent::EventType) {
       
   122             QGestureRecognizer::Result result = 0;
       
   123             if (CustomGestureRecognizer::ConsumeEvents)
       
   124                 result |= QGestureRecognizer::ConsumeEventHint;
       
   125             CustomGesture *g = static_cast<CustomGesture*>(state);
       
   126             CustomEvent *e = static_cast<CustomEvent*>(event);
       
   127             g->serial = e->serial;
       
   128             if (e->hasHotSpot)
       
   129                 g->setHotSpot(e->hotSpot);
       
   130             if (g->serial >= CustomGesture::SerialFinishedThreshold)
       
   131                 result |= QGestureRecognizer::FinishGesture;
       
   132             else if (g->serial >= CustomGesture::SerialStartedThreshold)
       
   133                 result |= QGestureRecognizer::TriggerGesture;
       
   134             else if (g->serial >= CustomGesture::SerialMaybeThreshold)
       
   135                 result |= QGestureRecognizer::MayBeGesture;
       
   136             else
       
   137                 result = QGestureRecognizer::CancelGesture;
       
   138             return result;
       
   139         }
       
   140         return QGestureRecognizer::Ignore;
       
   141     }
       
   142 
       
   143     void reset(QGesture *state)
       
   144     {
       
   145         CustomGesture *g = static_cast<CustomGesture *>(state);
       
   146         g->serial = 0;
       
   147         QGestureRecognizer::reset(state);
       
   148     }
       
   149 };
       
   150 bool CustomGestureRecognizer::ConsumeEvents = false;
       
   151 
       
   152 // same as CustomGestureRecognizer but triggers early without the maybe state
       
   153 class CustomContinuousGestureRecognizer : public QGestureRecognizer
       
   154 {
       
   155 public:
       
   156     CustomContinuousGestureRecognizer()
       
   157     {
       
   158         if (!CustomEvent::EventType)
       
   159             CustomEvent::EventType = QEvent::registerEventType();
       
   160     }
       
   161 
       
   162     QGesture* create(QObject *)
       
   163     {
       
   164         return new CustomGesture;
       
   165     }
       
   166 
       
   167     QGestureRecognizer::Result recognize(QGesture *state, QObject*, QEvent *event)
       
   168     {
       
   169         if (event->type() == CustomEvent::EventType) {
       
   170             QGestureRecognizer::Result result = QGestureRecognizer::ConsumeEventHint;
       
   171             CustomGesture *g = static_cast<CustomGesture *>(state);
       
   172             CustomEvent *e = static_cast<CustomEvent *>(event);
       
   173             g->serial = e->serial;
       
   174             if (e->hasHotSpot)
       
   175                 g->setHotSpot(e->hotSpot);
       
   176             if (g->serial >= CustomGesture::SerialFinishedThreshold)
       
   177                 result |= QGestureRecognizer::FinishGesture;
       
   178             else if (g->serial >= CustomGesture::SerialMaybeThreshold)
       
   179                 result |= QGestureRecognizer::TriggerGesture;
       
   180             else
       
   181                 result = QGestureRecognizer::CancelGesture;
       
   182             return result;
       
   183         }
       
   184         return QGestureRecognizer::Ignore;
       
   185     }
       
   186 
       
   187     void reset(QGesture *state)
       
   188     {
       
   189         CustomGesture *g = static_cast<CustomGesture *>(state);
       
   190         g->serial = 0;
       
   191         QGestureRecognizer::reset(state);
       
   192     }
       
   193 };
       
   194 
       
   195 class GestureWidget : public QWidget
       
   196 {
       
   197     Q_OBJECT
       
   198 public:
       
   199     GestureWidget(const char *name = 0, QWidget *parent = 0)
       
   200         : QWidget(parent)
       
   201     {
       
   202         if (name)
       
   203             setObjectName(QLatin1String(name));
       
   204         reset();
       
   205         acceptGestureOverride = false;
       
   206     }
       
   207     void reset()
       
   208     {
       
   209         customEventsReceived = 0;
       
   210         gestureEventsReceived = 0;
       
   211         gestureOverrideEventsReceived = 0;
       
   212         events.clear();
       
   213         overrideEvents.clear();
       
   214         ignoredGestures.clear();
       
   215     }
       
   216 
       
   217     int customEventsReceived;
       
   218     int gestureEventsReceived;
       
   219     int gestureOverrideEventsReceived;
       
   220     struct Events
       
   221     {
       
   222         QList<Qt::GestureType> all;
       
   223         QList<Qt::GestureType> started;
       
   224         QList<Qt::GestureType> updated;
       
   225         QList<Qt::GestureType> finished;
       
   226         QList<Qt::GestureType> canceled;
       
   227 
       
   228         void clear()
       
   229         {
       
   230             all.clear();
       
   231             started.clear();
       
   232             updated.clear();
       
   233             finished.clear();
       
   234             canceled.clear();
       
   235         }
       
   236     } events, overrideEvents;
       
   237 
       
   238     bool acceptGestureOverride;
       
   239     QSet<Qt::GestureType> ignoredGestures;
       
   240 
       
   241 protected:
       
   242     bool event(QEvent *event)
       
   243     {
       
   244         Events *eventsPtr = 0;
       
   245         if (event->type() == QEvent::Gesture) {
       
   246             QGestureEvent *e = static_cast<QGestureEvent*>(event);
       
   247             ++gestureEventsReceived;
       
   248             eventsPtr = &events;
       
   249             foreach(Qt::GestureType type, ignoredGestures)
       
   250                 e->ignore(e->gesture(type));
       
   251         } else if (event->type() == QEvent::GestureOverride) {
       
   252             ++gestureOverrideEventsReceived;
       
   253             eventsPtr = &overrideEvents;
       
   254             if (acceptGestureOverride)
       
   255                 event->accept();
       
   256         }
       
   257         if (eventsPtr) {
       
   258             QGestureEvent *e = static_cast<QGestureEvent*>(event);
       
   259             QList<QGesture*> gestures = e->gestures();
       
   260             foreach(QGesture *g, gestures) {
       
   261                 eventsPtr->all << g->gestureType();
       
   262                 switch(g->state()) {
       
   263                 case Qt::GestureStarted:
       
   264                     eventsPtr->started << g->gestureType();
       
   265                     break;
       
   266                 case Qt::GestureUpdated:
       
   267                     eventsPtr->updated << g->gestureType();
       
   268                     break;
       
   269                 case Qt::GestureFinished:
       
   270                     eventsPtr->finished << g->gestureType();
       
   271                     break;
       
   272                 case Qt::GestureCanceled:
       
   273                     eventsPtr->canceled << g->gestureType();
       
   274                     break;
       
   275                 default:
       
   276                     Q_ASSERT(false);
       
   277                 }
       
   278             }
       
   279         } else if (event->type() == CustomEvent::EventType) {
       
   280             ++customEventsReceived;
       
   281         } else {
       
   282             return QWidget::event(event);
       
   283         }
       
   284         return true;
       
   285     }
       
   286 };
       
   287 
       
   288 // TODO rename to sendGestureSequence
       
   289 static void sendCustomGesture(CustomEvent *event, QObject *object, QGraphicsScene *scene = 0)
       
   290 {
       
   291     for (int i = CustomGesture::SerialMaybeThreshold;
       
   292          i <= CustomGesture::SerialFinishedThreshold; ++i) {
       
   293         event->serial = i;
       
   294         if (scene)
       
   295             scene->sendEvent(qobject_cast<QGraphicsObject *>(object), event);
       
   296         else
       
   297             QApplication::sendEvent(object, event);
       
   298     }
       
   299 }
       
   300 
       
   301 class tst_Gestures : public QObject
       
   302 {
       
   303 Q_OBJECT
       
   304 
       
   305 public:
       
   306     tst_Gestures();
       
   307     virtual ~tst_Gestures();
       
   308 
       
   309 public slots:
       
   310     void initTestCase();
       
   311     void cleanupTestCase();
       
   312     void init();
       
   313     void cleanup();
       
   314 
       
   315 private slots:
       
   316     void customGesture();
       
   317 };
       
   318 
       
   319 tst_Gestures::tst_Gestures()
       
   320 {
       
   321 }
       
   322 
       
   323 tst_Gestures::~tst_Gestures()
       
   324 {
       
   325 }
       
   326 
       
   327 void tst_Gestures::initTestCase()
       
   328 {
       
   329     CustomGesture::GestureType = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer);
       
   330     QVERIFY(CustomGesture::GestureType != Qt::GestureType(0));
       
   331     QVERIFY(CustomGesture::GestureType != Qt::CustomGesture);
       
   332 }
       
   333 
       
   334 void tst_Gestures::cleanupTestCase()
       
   335 {
       
   336     QGestureRecognizer::unregisterRecognizer(CustomGesture::GestureType);
       
   337 }
       
   338 
       
   339 void tst_Gestures::init()
       
   340 {
       
   341 }
       
   342 
       
   343 void tst_Gestures::cleanup()
       
   344 {
       
   345 }
       
   346 
       
   347 void tst_Gestures::customGesture()
       
   348 {
       
   349     GestureWidget widget;
       
   350     widget.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren);
       
   351     CustomEvent event;
       
   352     sendCustomGesture(&event, &widget);
       
   353 
       
   354     static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
       
   355     static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;
       
   356     QCOMPARE(widget.customEventsReceived, TotalCustomEventsCount);
       
   357     QCOMPARE(widget.gestureEventsReceived, TotalGestureEventsCount);
       
   358     QCOMPARE(widget.gestureOverrideEventsReceived, 0);
       
   359     QCOMPARE(widget.events.all.size(), TotalGestureEventsCount);
       
   360     for(int i = 0; i < widget.events.all.size(); ++i)
       
   361         QCOMPARE(widget.events.all.at(i), CustomGesture::GestureType);
       
   362     QCOMPARE(widget.events.started.size(), 1);
       
   363     QCOMPARE(widget.events.updated.size(), TotalGestureEventsCount - 2);
       
   364     QCOMPARE(widget.events.finished.size(), 1);
       
   365     QCOMPARE(widget.events.canceled.size(), 0);
       
   366 }
       
   367 
       
   368 static const QColor InstanceColors[] = {
       
   369     Qt::blue, Qt::red, Qt::green, Qt::gray, Qt::yellow
       
   370 };
       
   371 
       
   372 class GestureItem : public QGraphicsObject
       
   373 {
       
   374     static int InstanceCount;
       
   375 
       
   376 public:
       
   377     GestureItem(const char *name = 0)
       
   378     {
       
   379         instanceNumber = InstanceCount++;
       
   380         if (name)
       
   381             setObjectName(QLatin1String(name));
       
   382         size = QRectF(0, 0, 100, 100);
       
   383         customEventsReceived = 0;
       
   384         gestureEventsReceived = 0;
       
   385         gestureOverrideEventsReceived = 0;
       
   386         events.clear();
       
   387         overrideEvents.clear();
       
   388         acceptGestureOverride = false;
       
   389     }
       
   390     ~GestureItem()
       
   391     {
       
   392         --InstanceCount;
       
   393     }
       
   394 
       
   395     int customEventsReceived;
       
   396     int gestureEventsReceived;
       
   397     int gestureOverrideEventsReceived;
       
   398     struct Events
       
   399     {
       
   400         QList<Qt::GestureType> all;
       
   401         QList<Qt::GestureType> started;
       
   402         QList<Qt::GestureType> updated;
       
   403         QList<Qt::GestureType> finished;
       
   404         QList<Qt::GestureType> canceled;
       
   405 
       
   406         void clear()
       
   407         {
       
   408             all.clear();
       
   409             started.clear();
       
   410             updated.clear();
       
   411             finished.clear();
       
   412             canceled.clear();
       
   413         }
       
   414     } events, overrideEvents;
       
   415 
       
   416     bool acceptGestureOverride;
       
   417     QSet<Qt::GestureType> ignoredGestures;
       
   418 
       
   419     QRectF size;
       
   420     int instanceNumber;
       
   421 
       
   422     void reset()
       
   423     {
       
   424         customEventsReceived = 0;
       
   425         gestureEventsReceived = 0;
       
   426         gestureOverrideEventsReceived = 0;
       
   427         events.clear();
       
   428         overrideEvents.clear();
       
   429         ignoredGestures.clear();
       
   430     }
       
   431 
       
   432 protected:
       
   433     QRectF boundingRect() const
       
   434     {
       
   435         return size;
       
   436     }
       
   437     void paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
       
   438     {
       
   439         QColor color = InstanceColors[instanceNumber % (sizeof(InstanceColors)/sizeof(InstanceColors[0]))];
       
   440         p->fillRect(boundingRect(), color);
       
   441     }
       
   442 
       
   443     bool event(QEvent *event)
       
   444     {
       
   445         Events *eventsPtr = 0;
       
   446         if (event->type() == QEvent::Gesture) {
       
   447             ++gestureEventsReceived;
       
   448             eventsPtr = &events;
       
   449             QGestureEvent *e = static_cast<QGestureEvent *>(event);
       
   450             foreach(Qt::GestureType type, ignoredGestures)
       
   451                 e->ignore(e->gesture(type));
       
   452         } else if (event->type() == QEvent::GestureOverride) {
       
   453             ++gestureOverrideEventsReceived;
       
   454             eventsPtr = &overrideEvents;
       
   455             if (acceptGestureOverride)
       
   456                 event->accept();
       
   457         }
       
   458         if (eventsPtr) {
       
   459             QGestureEvent *e = static_cast<QGestureEvent*>(event);
       
   460             QList<QGesture*> gestures = e->gestures();
       
   461             foreach(QGesture *g, gestures) {
       
   462                 eventsPtr->all << g->gestureType();
       
   463                 switch(g->state()) {
       
   464                 case Qt::GestureStarted:
       
   465                     eventsPtr->started << g->gestureType();
       
   466                     break;
       
   467                 case Qt::GestureUpdated:
       
   468                     eventsPtr->updated << g->gestureType();
       
   469                     break;
       
   470                 case Qt::GestureFinished:
       
   471                     eventsPtr->finished << g->gestureType();
       
   472                     break;
       
   473                 case Qt::GestureCanceled:
       
   474                     eventsPtr->canceled << g->gestureType();
       
   475                     break;
       
   476                 default:
       
   477                     Q_ASSERT(false);
       
   478                 }
       
   479             }
       
   480         } else if (event->type() == CustomEvent::EventType) {
       
   481             ++customEventsReceived;
       
   482         } else {
       
   483             return QGraphicsObject::event(event);
       
   484         }
       
   485         return true;
       
   486     }
       
   487 };
       
   488 int GestureItem::InstanceCount = 0;
       
   489 
       
   490 QTEST_MAIN(tst_Gestures)
       
   491 #include "smoke_qtgestures.moc"