tests/auto/gestures/tst_gestures.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    47 #include <qwidget.h>
    47 #include <qwidget.h>
    48 #include <qlayout.h>
    48 #include <qlayout.h>
    49 #include <qgesture.h>
    49 #include <qgesture.h>
    50 #include <qgesturerecognizer.h>
    50 #include <qgesturerecognizer.h>
    51 #include <qgraphicsitem.h>
    51 #include <qgraphicsitem.h>
       
    52 #include <qgraphicswidget.h>
    52 #include <qgraphicsview.h>
    53 #include <qgraphicsview.h>
    53 #include <qmainwindow.h>
    54 #include <qmainwindow.h>
    54 
    55 
    55 #include <qdebug.h>
    56 #include <qdebug.h>
    56 
    57 
   331     void customGesture();
   332     void customGesture();
   332     void autoCancelingGestures();
   333     void autoCancelingGestures();
   333     void gestureOverChild();
   334     void gestureOverChild();
   334     void multipleWidgetOnlyGestureInTree();
   335     void multipleWidgetOnlyGestureInTree();
   335     void conflictingGestures();
   336     void conflictingGestures();
       
   337     void conflictingGesturesInGraphicsView();
   336     void finishedWithoutStarted();
   338     void finishedWithoutStarted();
   337     void unknownGesture();
   339     void unknownGesture();
   338     void graphicsItemGesture();
   340     void graphicsItemGesture();
   339     void graphicsView();
   341     void graphicsView();
   340     void graphicsItemTreeGesture();
   342     void graphicsItemTreeGesture();
   356     void deleteGestureTargetItem_data();
   358     void deleteGestureTargetItem_data();
   357     void deleteGestureTargetItem();
   359     void deleteGestureTargetItem();
   358     void viewportCoordinates();
   360     void viewportCoordinates();
   359     void partialGesturePropagation();
   361     void partialGesturePropagation();
   360     void testQGestureRecognizerCleanup();
   362     void testQGestureRecognizerCleanup();
       
   363     void testReuseCanceledGestures();
   361 };
   364 };
   362 
   365 
   363 tst_Gestures::tst_Gestures()
   366 tst_Gestures::tst_Gestures()
   364 {
   367 {
   365 }
   368 }
  2067     w->show();
  2070     w->show();
  2068     QTest::qWaitForWindowShown(w);
  2071     QTest::qWaitForWindowShown(w);
  2069     delete w;
  2072     delete w;
  2070 }
  2073 }
  2071 
  2074 
       
  2075 class ReuseCanceledGesturesRecognizer : public QGestureRecognizer
       
  2076 {
       
  2077 public:
       
  2078     enum Type {
       
  2079         RmbAndCancelAllType,
       
  2080         LmbType
       
  2081     };
       
  2082 
       
  2083     ReuseCanceledGesturesRecognizer(Type type) : m_type(type) {}
       
  2084 
       
  2085     QGesture *create(QObject *) {
       
  2086         QGesture *g = new QGesture;
       
  2087         return g;
       
  2088     }
       
  2089 
       
  2090     Result recognize(QGesture *gesture, QObject *, QEvent *event) {
       
  2091         QMouseEvent *me = static_cast<QMouseEvent *>(event);
       
  2092         Qt::MouseButton mouseButton(m_type == LmbType ? Qt::LeftButton : Qt::RightButton);
       
  2093 
       
  2094         switch(event->type()) {
       
  2095         case QEvent::MouseButtonPress:
       
  2096             if (me->button() == mouseButton && gesture->state() == Qt::NoGesture) {
       
  2097                 gesture->setHotSpot(QPointF(me->globalPos()));
       
  2098                 if (m_type == RmbAndCancelAllType)
       
  2099                     gesture->setGestureCancelPolicy(QGesture::CancelAllInContext);
       
  2100                 return QGestureRecognizer::TriggerGesture;
       
  2101             }
       
  2102             break;
       
  2103         case QEvent::MouseButtonRelease:
       
  2104             if (me->button() == mouseButton && gesture->state() > Qt::NoGesture)
       
  2105                 return QGestureRecognizer::FinishGesture;
       
  2106         default:
       
  2107             break;
       
  2108         }
       
  2109         return QGestureRecognizer::Ignore;
       
  2110     }
       
  2111 private:
       
  2112     Type m_type;
       
  2113 };
       
  2114 
       
  2115 class ReuseCanceledGesturesWidget : public QGraphicsWidget
       
  2116 {
       
  2117   public:
       
  2118     ReuseCanceledGesturesWidget(Qt::GestureType gestureType = Qt::TapGesture, QGraphicsItem *parent = 0)
       
  2119         : QGraphicsWidget(parent),
       
  2120         m_gestureType(gestureType),
       
  2121         m_started(0), m_updated(0), m_canceled(0), m_finished(0)
       
  2122     {
       
  2123     }
       
  2124 
       
  2125     bool event(QEvent *event) {
       
  2126         if (event->type() == QEvent::Gesture) {
       
  2127             QGesture *gesture = static_cast<QGestureEvent*>(event)->gesture(m_gestureType);
       
  2128             if (gesture) {
       
  2129                 switch(gesture->state()) {
       
  2130                 case Qt::GestureStarted: m_started++; break;
       
  2131                 case Qt::GestureUpdated: m_updated++; break;
       
  2132                 case Qt::GestureFinished: m_finished++; break;
       
  2133                 case Qt::GestureCanceled: m_canceled++; break;
       
  2134                 default: break;
       
  2135                 }
       
  2136             }
       
  2137             return true;
       
  2138         }
       
  2139         if (event->type() == QEvent::GraphicsSceneMousePress) {
       
  2140             return true;
       
  2141         }
       
  2142         return QGraphicsWidget::event(event);
       
  2143     }
       
  2144 
       
  2145     int started() { return m_started; }
       
  2146     int updated() { return m_updated; }
       
  2147     int finished() { return m_finished; }
       
  2148     int canceled() { return m_canceled; }
       
  2149 
       
  2150   private:
       
  2151     Qt::GestureType m_gestureType;
       
  2152     int m_started;
       
  2153     int m_updated;
       
  2154     int m_canceled;
       
  2155     int m_finished;
       
  2156 };
       
  2157 
       
  2158 void tst_Gestures::testReuseCanceledGestures()
       
  2159 {
       
  2160     Qt::GestureType cancellingGestureTypeId = QGestureRecognizer::registerRecognizer(
       
  2161             new ReuseCanceledGesturesRecognizer(ReuseCanceledGesturesRecognizer::RmbAndCancelAllType));
       
  2162     Qt::GestureType tapGestureTypeId = QGestureRecognizer::registerRecognizer(
       
  2163             new ReuseCanceledGesturesRecognizer(ReuseCanceledGesturesRecognizer::LmbType));
       
  2164 
       
  2165     QMainWindow mw;
       
  2166     mw.setWindowFlags(Qt::X11BypassWindowManagerHint);
       
  2167     QGraphicsView *gv = new QGraphicsView(&mw);
       
  2168     QGraphicsScene *scene = new QGraphicsScene;
       
  2169 
       
  2170     gv->setScene(scene);
       
  2171     scene->setSceneRect(0,0,100,100);
       
  2172 
       
  2173     // Create container and add to the scene
       
  2174     ReuseCanceledGesturesWidget *container = new ReuseCanceledGesturesWidget;
       
  2175     container->grabGesture(cancellingGestureTypeId); // << container grabs canceling gesture
       
  2176 
       
  2177     // Create widget and add to the scene
       
  2178     ReuseCanceledGesturesWidget *target = new ReuseCanceledGesturesWidget(tapGestureTypeId, container);
       
  2179     target->grabGesture(tapGestureTypeId);
       
  2180 
       
  2181     container->setGeometry(scene->sceneRect());
       
  2182 
       
  2183     scene->addItem(container);
       
  2184 
       
  2185     mw.setCentralWidget(gv);
       
  2186 
       
  2187     // Viewport needs to grab all gestures that widgets in scene grab
       
  2188     gv->viewport()->grabGesture(cancellingGestureTypeId);
       
  2189     gv->viewport()->grabGesture(tapGestureTypeId);
       
  2190 
       
  2191     mw.show();
       
  2192     QTest::qWaitForWindowShown(&mw);
       
  2193 
       
  2194     QPoint targetPos(gv->mapFromScene(target->mapToScene(target->rect().center())));
       
  2195     targetPos = gv->viewport()->mapFromParent(targetPos);
       
  2196 
       
  2197     // "Tap" starts on child widget
       
  2198     QTest::mousePress(gv->viewport(), Qt::LeftButton, 0, targetPos);
       
  2199     QCOMPARE(target->started(),  1);
       
  2200     QCOMPARE(target->updated(),  0);
       
  2201     QCOMPARE(target->finished(), 0);
       
  2202     QCOMPARE(target->canceled(), 0);
       
  2203 
       
  2204     // Canceling gesture starts on parent
       
  2205     QTest::mousePress(gv->viewport(), Qt::RightButton, 0, targetPos);
       
  2206     QCOMPARE(target->started(),  1);
       
  2207     QCOMPARE(target->updated(),  0);
       
  2208     QCOMPARE(target->finished(), 0);
       
  2209     QCOMPARE(target->canceled(), 1); // <- child canceled
       
  2210 
       
  2211     // Canceling gesture ends
       
  2212     QTest::mouseRelease(gv->viewport(), Qt::RightButton, 0, targetPos);
       
  2213     QCOMPARE(target->started(),  1);
       
  2214     QCOMPARE(target->updated(),  0);
       
  2215     QCOMPARE(target->finished(), 0);
       
  2216     QCOMPARE(target->canceled(), 1);
       
  2217 
       
  2218     // Tap would end if not canceled
       
  2219     QTest::mouseRelease(gv->viewport(), Qt::LeftButton, 0, targetPos);
       
  2220     QCOMPARE(target->started(),  1);
       
  2221     QCOMPARE(target->updated(),  0);
       
  2222     QCOMPARE(target->finished(), 0);
       
  2223     QCOMPARE(target->canceled(), 1);
       
  2224 
       
  2225     // New "Tap" starts
       
  2226     QTest::mousePress(gv->viewport(), Qt::LeftButton, 0, targetPos);
       
  2227     QCOMPARE(target->started(),  2);
       
  2228     QCOMPARE(target->updated(),  0);
       
  2229     QCOMPARE(target->finished(), 0);
       
  2230     QCOMPARE(target->canceled(), 1);
       
  2231 
       
  2232     QTest::mouseRelease(gv->viewport(), Qt::LeftButton, 0, targetPos);
       
  2233     QCOMPARE(target->started(),  2);
       
  2234     QCOMPARE(target->updated(),  0);
       
  2235     QCOMPARE(target->finished(), 1);
       
  2236     QCOMPARE(target->canceled(), 1);
       
  2237 }
       
  2238 
       
  2239 void tst_Gestures::conflictingGesturesInGraphicsView()
       
  2240 {
       
  2241     QGraphicsScene scene;
       
  2242     GraphicsView view(&scene);
       
  2243     view.setWindowFlags(Qt::X11BypassWindowManagerHint);
       
  2244 
       
  2245     GestureItem *item1 = new GestureItem("item1");
       
  2246     item1->grabGesture(CustomGesture::GestureType);
       
  2247     item1->size = QRectF(0, 0, 100, 100);
       
  2248     item1->setZValue(2);
       
  2249     scene.addItem(item1);
       
  2250 
       
  2251     GestureItem *item2 = new GestureItem("item2");
       
  2252     item2->grabGesture(CustomGesture::GestureType);
       
  2253     item2->size = QRectF(0, 0, 100, 100);
       
  2254     item2->setZValue(5);
       
  2255     scene.addItem(item2);
       
  2256 
       
  2257     view.show();
       
  2258     QTest::qWaitForWindowShown(&view);
       
  2259     view.ensureVisible(scene.sceneRect());
       
  2260 
       
  2261     static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
       
  2262 
       
  2263     CustomEvent event;
       
  2264 
       
  2265     // nobody accepts override
       
  2266     item1->acceptGestureOverride = false;
       
  2267     item2->acceptGestureOverride = false;
       
  2268     event.hotSpot = mapToGlobal(item2->boundingRect().center(), item2, &view);
       
  2269     event.hasHotSpot = true;
       
  2270     sendCustomGesture(&event, item2, &scene);
       
  2271     QCOMPARE(item2->gestureOverrideEventsReceived, 1);
       
  2272     QCOMPARE(item2->gestureEventsReceived, TotalGestureEventsCount);
       
  2273     QCOMPARE(item1->gestureOverrideEventsReceived, 1);
       
  2274     QCOMPARE(item1->gestureEventsReceived, 0);
       
  2275 
       
  2276     item1->reset(); item2->reset();
       
  2277 
       
  2278     // the original target accepts override
       
  2279     item1->acceptGestureOverride = false;
       
  2280     item2->acceptGestureOverride = true;
       
  2281     event.hotSpot = mapToGlobal(item2->boundingRect().center(), item2, &view);
       
  2282     event.hasHotSpot = true;
       
  2283     sendCustomGesture(&event, item2, &scene);
       
  2284     QCOMPARE(item2->gestureOverrideEventsReceived, 1);
       
  2285     QCOMPARE(item2->gestureEventsReceived, TotalGestureEventsCount);
       
  2286     QCOMPARE(item1->gestureOverrideEventsReceived, 0);
       
  2287     QCOMPARE(item1->gestureEventsReceived, 0);
       
  2288 
       
  2289     item1->reset(); item2->reset();
       
  2290 
       
  2291     // the item behind accepts override
       
  2292     item1->acceptGestureOverride = true;
       
  2293     item2->acceptGestureOverride = false;
       
  2294     event.hotSpot = mapToGlobal(item2->boundingRect().center(), item2, &view);
       
  2295     event.hasHotSpot = true;
       
  2296     sendCustomGesture(&event, item2, &scene);
       
  2297 
       
  2298     QCOMPARE(item2->gestureOverrideEventsReceived, 1);
       
  2299     QCOMPARE(item2->gestureEventsReceived, 0);
       
  2300     QCOMPARE(item1->gestureOverrideEventsReceived, 1);
       
  2301     QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount);
       
  2302 }
       
  2303 
  2072 QTEST_MAIN(tst_Gestures)
  2304 QTEST_MAIN(tst_Gestures)
  2073 #include "tst_gestures.moc"
  2305 #include "tst_gestures.moc"