** 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.
+** 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
+** 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.
-**
-**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
#include <qtest.h>
#include <QDebug>
#include <QTouchEvent>
-
-#include "qsgitem.h"
-#include "qsgcanvas.h"
-#include "private/qsgrectangle_p.h"
-#include "../../../shared/util.h"
+#include <QtDeclarative/QSGItem>
+#include <QtDeclarative/QSGCanvas>
+#include <QtDeclarative/private/qsgrectangle_p.h>
+#include <QtGui/QWindowSystemInterface>
struct TouchEventData {
QEvent::Type type;
QWidget *widget;
+ QWindow *window;
Qt::TouchPointStates states;
QList<QTouchEvent::TouchPoint> touchPoints;
};
QPointF last = lastPoint.isNull() ? p : lastPoint;
QTouchEvent::TouchPoint tp;
+
tp.setPos(p);
tp.setLastPos(last);
tp.setScenePos(item->mapToScene(p));
static TouchEventData makeTouchData(QEvent::Type type, QWidget *w, Qt::TouchPointStates states, const QList<QTouchEvent::TouchPoint> &touchPoints)
{
- TouchEventData d = { type, w, states, touchPoints };
+ TouchEventData d = { type, w, 0, states, touchPoints };
return d;
}
points << touchPoint;
return makeTouchData(type, w, states, points);
}
+static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QList<QTouchEvent::TouchPoint>& touchPoints)
+{
+ TouchEventData d = { type, 0, w, states, touchPoints };
+ return d;
+}
+static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QTouchEvent::TouchPoint &touchPoint)
+{
+ QList<QTouchEvent::TouchPoint> points;
+ points << touchPoint;
+ return makeTouchData(type, w, states, points);
+}
#define COMPARE_TOUCH_POINTS(tp1, tp2) \
{ \
Q_OBJECT
public:
TestTouchItem(QSGItem *parent = 0)
- : QSGRectangle(parent), acceptEvents(true)
+ : QSGRectangle(parent), acceptEvents(true), mousePressId(0)
{
border()->setWidth(1);
+ setAcceptedMouseButtons(Qt::LeftButton);
+ setFiltersChildMouseEvents(true);
}
void reset() {
setEnabled(true);
setOpacity(1.0);
- lastEvent = makeTouchData(QEvent::None, 0, 0, QList<QTouchEvent::TouchPoint>());
+ lastEvent = makeTouchData(QEvent::None, canvas(), 0, QList<QTouchEvent::TouchPoint>());//CHECK_VALID
}
bool acceptEvents;
TouchEventData lastEvent;
+ int mousePressId;
protected:
virtual void touchEvent(QTouchEvent *event) {
lastEvent = makeTouchData(event->type(), event->widget(), event->touchPointStates(), event->touchPoints());
event->accept();
}
+
+ virtual void mousePressEvent(QMouseEvent *event) {
+ mousePressId = ++mousePressNum;
+ }
+
+ bool childMouseEventFilter(QSGItem *, QEvent *) {
+ mousePressId = ++mousePressNum;
+ return false;
+ }
+
+ static int mousePressNum;
};
+int TestTouchItem::mousePressNum = 0;
class ConstantUpdateItem : public QSGItem
{
void touchEvent_propagation_data();
void clearCanvas();
+ void mouseFiltering();
};
tst_qsgcanvas::tst_qsgcanvas()
{
QSGCanvas *canvas = new QSGCanvas;
canvas->resize(250, 250);
- canvas->window()->move(100, 100);
+ canvas->move(100, 100);
canvas->show();
TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem());
QPointF pos(10, 10);
// press single point
- QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint());
+ QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas);
+ QTest::qWait(50);
+
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
+
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
+ TouchEventData d = makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem,pos));
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos)));
topItem->reset();
// press multiple points
- QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint())
- .press(1, bottomItem->mapToScene(pos).toPoint());
+ QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas)
+ .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
+ QTest::qWait(50);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
bottomItem->reset();
// touch point on top item moves to bottom item, but top item should still receive the event
- QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint());
- QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint());
+ QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(), canvas);
+ QTest::qWait(50);
+ QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint(), canvas);
+ QTest::qWait(50);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved,
makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
topItem->reset();
// touch point on bottom item moves to top item, but bottom item should still receive the event
- QTest::touchEvent(canvas).press(0, bottomItem->mapToScene(pos).toPoint());
- QTest::touchEvent(canvas).move(0, topItem->mapToScene(pos).toPoint());
+ QTest::touchEvent(canvas).press(0, bottomItem->mapToScene(pos).toPoint(), canvas);
+ QTest::qWait(50);
+ QTest::touchEvent(canvas).move(0, topItem->mapToScene(pos).toPoint(), canvas);
+ QTest::qWait(50);
QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved,
makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos), pos)));
bottomItem->reset();
// a single stationary press on an item shouldn't cause an event
- QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint());
+ QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(), canvas);
+ QTest::qWait(50);
QTest::touchEvent(canvas).stationary(0)
- .press(1, bottomItem->mapToScene(pos).toPoint());
+ .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
+ QTest::qWait(50);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); // received press only, not stationary
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
bottomItem->reset();
// move touch point from top item to bottom, and release
- QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint());
- QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint());
+ QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas);
+ QTest::qWait(50);
+ QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint(),canvas);
+ QTest::qWait(50);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, canvas, Qt::TouchPointReleased,
makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos)));
topItem->reset();
// release while another point is pressed
- QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint())
- .press(1, bottomItem->mapToScene(pos).toPoint());
- QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint());
- QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint())
+ QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas)
+ .press(1, bottomItem->mapToScene(pos).toPoint(), canvas);
+ QTest::qWait(50);
+ QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint(), canvas);
+ QTest::qWait(50);
+ QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint(), canvas)
.stationary(1);
+ QTest::qWait(50);
QCOMPARE(topItem->lastEvent.touchPoints.count(), 1);
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1);
QSGCanvas *canvas = new QSGCanvas;
canvas->resize(250, 250);
- canvas->window()->move(100, 100);
+ canvas->move(100, 100);
canvas->show();
TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem());
topItem->setOpacity(itemOpacity);
// single touch to top item, should be received by middle item
- QTest::touchEvent(canvas).press(0, pointInTopItem);
+ QTest::touchEvent(canvas).press(0, pointInTopItem, canvas);
+ QTest::qWait(50);
QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
QCOMPARE(middleItem->lastEvent.touchPoints.count(), 1);
QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos))));
// touch top and middle items, middle item should get both events
- QTest::touchEvent(canvas).press(0, pointInTopItem)
- .press(1, pointInMiddleItem);
+ QTest::touchEvent(canvas).press(0, pointInTopItem, canvas)
+ .press(1, pointInMiddleItem, canvas);
+ QTest::qWait(50);
QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
QCOMPARE(middleItem->lastEvent.touchPoints.count(), 2);
QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed,
- (QList<QTouchEvent::TouchPoint>() << makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos))
+ (QList<QTouchEvent::TouchPoint>() << makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos))
<< makeTouchPoint(middleItem, pos) )));
middleItem->reset();
middleItem->setOpacity(itemOpacity);
// touch top and middle items, bottom item should get all events
- QTest::touchEvent(canvas).press(0, pointInTopItem)
- .press(1, pointInMiddleItem);
+ QTest::touchEvent(canvas).press(0, pointInTopItem, canvas)
+ .press(1, pointInMiddleItem, canvas);
+ QTest::qWait(50);
QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 2);
bottomItem->setOpacity(itemOpacity);
// no events should be received
- QTest::touchEvent(canvas).press(0, pointInTopItem)
- .press(1, pointInMiddleItem)
- .press(2, pointInBottomItem);
+ QTest::touchEvent(canvas).press(0, pointInTopItem, canvas)
+ .press(1, pointInMiddleItem, canvas)
+ .press(2, pointInBottomItem, canvas);
+ QTest::qWait(50);
QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
QVERIFY(middleItem->lastEvent.touchPoints.isEmpty());
QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty());
middleItem->acceptEvents = acceptEvents;
middleItem->setEnabled(enableItem);
middleItem->setOpacity(itemOpacity);
- QTest::touchEvent(canvas).press(0, pointInTopItem);
+ QTest::touchEvent(canvas).press(0, pointInTopItem, canvas);
+ QTest::qWait(50);
if (!enableItem || itemOpacity == 0) {
// middle item is disabled or has 0 opacity, bottom item receives the event
QVERIFY(topItem->lastEvent.touchPoints.isEmpty());
delete item;
}
+void tst_qsgcanvas::mouseFiltering()
+{
+ QSGCanvas *canvas = new QSGCanvas;
+ canvas->resize(250, 250);
+ canvas->move(100, 100);
+ canvas->show();
+
+ TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem());
+ bottomItem->setObjectName("Bottom Item");
+ bottomItem->setSize(QSizeF(150, 150));
+
+ TestTouchItem *middleItem = new TestTouchItem(bottomItem);
+ middleItem->setObjectName("Middle Item");
+ middleItem->setPos(QPointF(50, 50));
+ middleItem->setSize(QSizeF(150, 150));
+
+ TestTouchItem *topItem = new TestTouchItem(middleItem);
+ topItem->setObjectName("Top Item");
+ topItem->setPos(QPointF(50, 50));
+ topItem->setSize(QSizeF(150, 150));
+
+ QPoint pos(100, 100);
+
+ QTest::mousePress(canvas, Qt::LeftButton, 0, pos);
+ QTest::qWait(50);
+
+ // Mouse filtering propagates down the stack, so the
+ // correct order is
+ // 1. middleItem filters event
+ // 2. bottomItem filters event
+ // 3. topItem receives event
+ QCOMPARE(middleItem->mousePressId, 1);
+ QCOMPARE(bottomItem->mousePressId, 2);
+ QCOMPARE(topItem->mousePressId, 3);
+}
QTEST_MAIN(tst_qsgcanvas)