diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/gestures/customgesturerecognizer.cpp | 167 | ||||
-rw-r--r-- | tests/auto/gestures/customgesturerecognizer.h | 187 | ||||
-rw-r--r-- | tests/auto/gestures/gestures.pro | 3 | ||||
-rw-r--r-- | tests/auto/gestures/tst_gestures.cpp | 949 | ||||
-rw-r--r-- | tests/auto/qapplication/tst_qapplication.cpp | 143 | ||||
-rw-r--r-- | tests/auto/qtouchevent/qtouchevent.pro | 3 | ||||
-rw-r--r-- | tests/auto/qtouchevent/tst_qtouchevent.cpp | 335 | ||||
-rw-r--r-- | tests/manual/qtouchevent/form.ui | 1897 | ||||
-rw-r--r-- | tests/manual/qtouchevent/main.cpp | 554 | ||||
-rw-r--r-- | tests/manual/qtouchevent/multitouch.pro | 5 | ||||
-rw-r--r-- | tests/manual/qtouchevent/touchwidget.cpp | 94 | ||||
-rw-r--r-- | tests/manual/qtouchevent/touchwidget.h | 31 |
12 files changed, 4368 insertions, 0 deletions
diff --git a/tests/auto/gestures/customgesturerecognizer.cpp b/tests/auto/gestures/customgesturerecognizer.cpp new file mode 100644 index 0000000..12d07b1 --- /dev/null +++ b/tests/auto/gestures/customgesturerecognizer.cpp @@ -0,0 +1,167 @@ +#include "customgesturerecognizer.h" +#include "qgesture.h" + +const char* SingleshotGestureRecognizer::Name = "SingleshotGesture"; +const char* PinchGestureRecognizer::Name = "PinchGesture"; +const char* SecondFingerGestureRecognizer::Name = "SecondFingerGesture"; +const char* PanGestureRecognizer::Name = "PanGesture"; + +SingleshotGestureRecognizer::SingleshotGestureRecognizer(QObject *parent) + : QGestureRecognizer(QString(SingleshotGestureRecognizer::Name), parent) +{ + gesture = new SingleshotGesture(this, SingleshotGestureRecognizer::Name); +} + +QGestureRecognizer::Result SingleshotGestureRecognizer::filterEvent(const QEvent *event) +{ + if (event->type() == SingleshotEvent::Type) { + gesture->setHotSpot(static_cast<const SingleshotEvent*>(event)->point); + return QGestureRecognizer::GestureFinished; + } + return QGestureRecognizer::NotGesture; +} + +void SingleshotGestureRecognizer::reset() +{ + gesture->setHotSpot(QPoint()); + gesture->offset = QPoint(); +} + +PinchGestureRecognizer::PinchGestureRecognizer(QObject *parent) + : QGestureRecognizer(PinchGestureRecognizer::Name, parent) +{ + gesture = new PinchGesture(this, PinchGestureRecognizer::Name); +} + +QGestureRecognizer::Result PinchGestureRecognizer::filterEvent(const QEvent *event) +{ + if (event->type() != TouchEvent::Type) + return QGestureRecognizer::Ignore; + + const TouchEvent *e = static_cast<const TouchEvent*>(event); + if (e->points[0].state == TouchPoint::Begin) + gesture->startPoints[0] = e->points[0]; + if (e->points[1].state == TouchPoint::Begin) + gesture->startPoints[1] = e->points[1]; + gesture->lastPoints[0] = gesture->points[0]; + gesture->lastPoints[1] = gesture->points[1]; + gesture->points[0] = e->points[0]; + gesture->points[1] = e->points[1]; + if (((e->points[0].state == TouchPoint::Begin || e->points[0].state == TouchPoint::Update))) { + if (e->points[1].state == TouchPoint::End || e->points[1].state == TouchPoint::None) + return MaybeGesture; + return GestureStarted; + } else if (((e->points[1].state == TouchPoint::Begin || e->points[1].state == TouchPoint::Update))) { + if (e->points[0].state == TouchPoint::End || e->points[0].state == TouchPoint::None) + return MaybeGesture; + return GestureStarted; + } else if ((e->points[0].state == TouchPoint::End && e->points[1].state == TouchPoint::End) || + (e->points[0].state == TouchPoint::End && e->points[1].state == TouchPoint::None) || + (e->points[0].state == TouchPoint::None && e->points[1].state == TouchPoint::End)) { + return QGestureRecognizer::NotGesture; + } + return QGestureRecognizer::NotGesture; +} + +void PinchGestureRecognizer::reset() +{ + gesture->startPoints[0] = TouchPoint(); + gesture->startPoints[1] = TouchPoint(); + gesture->lastPoints[0] = TouchPoint(); + gesture->lastPoints[1] = TouchPoint(); + gesture->points[0] = TouchPoint(); + gesture->points[1] = TouchPoint(); + gesture->offset = QPoint(); +} + +SecondFingerGestureRecognizer::SecondFingerGestureRecognizer(QObject *parent) + : QGestureRecognizer(SecondFingerGestureRecognizer::Name, parent) +{ + gesture = new SecondFingerGesture(this, SecondFingerGestureRecognizer::Name); +} + +QGestureRecognizer::Result SecondFingerGestureRecognizer::filterEvent(const QEvent *event) +{ + if (event->type() != TouchEvent::Type) + return QGestureRecognizer::Ignore; + + const TouchEvent *e = static_cast<const TouchEvent*>(event); + if (e->points[1].state != TouchPoint::None) { + if (e->points[1].state == TouchPoint::Begin) + gesture->startPoint = e->points[1]; + gesture->lastPoint = gesture->point; + gesture->point = e->points[1]; + if (e->points[1].state == TouchPoint::End) + return QGestureRecognizer::GestureFinished; + else if (e->points[1].state != TouchPoint::None) + return QGestureRecognizer::GestureStarted; + } + return QGestureRecognizer::NotGesture; +} + +void SecondFingerGestureRecognizer::reset() +{ + gesture->startPoint = TouchPoint(); + gesture->lastPoint = TouchPoint(); + gesture->point = TouchPoint(); + gesture->offset = QPoint(); +} + +PanGestureRecognizer::PanGestureRecognizer(QObject *parent) + : QGestureRecognizer(PanGestureRecognizer::Name, parent) +{ + gesture = new PanGesture(this, PanGestureRecognizer::Name); +} + +QGestureRecognizer::Result PanGestureRecognizer::filterEvent(const QEvent *event) +{ + if (event->type() != QEvent::TouchBegin && + event->type() != QEvent::TouchUpdate && + event->type() != QEvent::TouchEnd) + return QGestureRecognizer::Ignore; + + const QTouchEvent *e = static_cast<const QTouchEvent*>(event); + const QList<QTouchEvent::TouchPoint> &points = e->touchPoints(); + + if (points.size() >= 1) { + gesture->lastPoints[0] = gesture->points[0]; + gesture->points[0].id = points.at(0).id(); + gesture->points[0].pt = points.at(0).startPos().toPoint(); + gesture->points[0].state = (TouchPoint::State)points.at(0).state(); + if (points.at(0).state() == Qt::TouchPointPressed) { + gesture->startPoints[0] = gesture->points[0]; + gesture->lastPoints[0] = gesture->points[0]; + } + } + if (points.size() >= 2) { + gesture->lastPoints[1] = gesture->points[1]; + gesture->points[1].id = points.at(1).id(); + gesture->points[1].pt = points.at(1).startPos().toPoint(); + gesture->points[1].state = (TouchPoint::State)points.at(1).state(); + if (points.at(1).state() == Qt::TouchPointPressed) { + gesture->startPoints[1] = gesture->points[1]; + gesture->lastPoints[1] = gesture->points[1]; + } + } + + if (points.size() == 2) + return QGestureRecognizer::GestureStarted; + if (points.size() > 2) + return QGestureRecognizer::MaybeGesture; + if (points.at(0).state() == Qt::TouchPointPressed) + return QGestureRecognizer::MaybeGesture; + if (points.at(0).state() == Qt::TouchPointReleased) + return QGestureRecognizer::GestureFinished; + return QGestureRecognizer::GestureStarted; +} + +void PanGestureRecognizer::reset() +{ + gesture->startPoints[0] = TouchPoint(); + gesture->startPoints[1] = TouchPoint(); + gesture->lastPoints[0] = TouchPoint(); + gesture->lastPoints[1] = TouchPoint(); + gesture->points[0] = TouchPoint(); + gesture->points[1] = TouchPoint(); + gesture->offset = QPoint(); +} diff --git a/tests/auto/gestures/customgesturerecognizer.h b/tests/auto/gestures/customgesturerecognizer.h new file mode 100644 index 0000000..519aba8 --- /dev/null +++ b/tests/auto/gestures/customgesturerecognizer.h @@ -0,0 +1,187 @@ +#ifndef CUSTOMGESTURERECOGNIZER_H +#define CUSTOMGESTURERECOGNIZER_H + +#include "qgesturerecognizer.h" +#include "qgesture.h" +#include "qevent.h" + +class SingleshotEvent : public QEvent +{ +public: + static const int Type = QEvent::User + 1; + + QPoint point; + + explicit SingleshotEvent(int x = 0, int y = 0) + : QEvent(QEvent::Type(Type)), point(x, y) { } +}; + +class SingleshotGesture : public QGesture +{ + Q_OBJECT +public: + SingleshotGesture(QObject *parent, const QString &type) + : QGesture(parent, type) { } + + QPoint offset; + +protected: + void translate(const QPoint &pt) + { + offset += pt; + } +}; + +class SingleshotGestureRecognizer : public QGestureRecognizer +{ + Q_OBJECT +public: + static const char *Name; + + SingleshotGestureRecognizer(QObject *parent = 0); + + QGestureRecognizer::Result filterEvent(const QEvent *event); + QGesture* getGesture() { return gesture; } + void reset(); + +private: + SingleshotGesture *gesture; +}; + +struct TouchPoint { + enum State + { + None = 0, + Begin = Qt::TouchPointPressed, + Update = Qt::TouchPointMoved, + End = Qt::TouchPointReleased + }; + int id; + QPoint pt; + State state; + TouchPoint() : id(0), state(None) { } + TouchPoint(int id_, int x_, int y_, State state_) : id(id_), pt(x_, y_), state(state_) { } +}; + +class TouchEvent : public QEvent +{ +public: + static const int Type = QEvent::User + 2; + + TouchEvent() + : QEvent(QEvent::Type(Type)) + { + } + + TouchPoint points[2]; +}; + +class PinchGesture : public QGesture +{ + Q_OBJECT +public: + PinchGesture(QObject *parent, const QString &type) + : QGesture(parent, type) { } + + TouchPoint startPoints[2]; + TouchPoint lastPoints[2]; + TouchPoint points[2]; + + QPoint offset; + +protected: + void translate(const QPoint &pt) + { + offset += pt; + } +}; + +class PinchGestureRecognizer : public QGestureRecognizer +{ + Q_OBJECT +public: + static const char *Name; + + PinchGestureRecognizer(QObject *parent = 0); + + QGestureRecognizer::Result filterEvent(const QEvent *event); + QGesture* getGesture() { return gesture; } + void reset(); + +private: + PinchGesture *gesture; +}; + +class SecondFingerGesture : public QGesture +{ + Q_OBJECT +public: + SecondFingerGesture(QObject *parent, const QString &type) + : QGesture(parent, type) { } + + TouchPoint startPoint; + TouchPoint lastPoint; + TouchPoint point; + + QPoint offset; + +protected: + void translate(const QPoint &pt) + { + offset += pt; + } +}; + +class SecondFingerGestureRecognizer : public QGestureRecognizer +{ + Q_OBJECT +public: + static const char *Name; + + SecondFingerGestureRecognizer(QObject *parent = 0); + + QGestureRecognizer::Result filterEvent(const QEvent *event); + QGesture* getGesture() { return gesture; } + void reset(); + +private: + SecondFingerGesture *gesture; +}; + +class PanGesture : public QGesture +{ + Q_OBJECT +public: + PanGesture(QObject *parent, const QString &type) + : QGesture(parent, type) { } + + TouchPoint startPoints[2]; + TouchPoint lastPoints[2]; + TouchPoint points[2]; + + QPoint offset; + +protected: + void translate(const QPoint &pt) + { + offset += pt; + } +}; + +class PanGestureRecognizer : public QGestureRecognizer +{ + Q_OBJECT +public: + static const char *Name; + + PanGestureRecognizer(QObject *parent = 0); + + QGestureRecognizer::Result filterEvent(const QEvent *event); + QGesture* getGesture() { return gesture; } + void reset(); + +private: + PanGesture *gesture; +}; + +#endif diff --git a/tests/auto/gestures/gestures.pro b/tests/auto/gestures/gestures.pro new file mode 100644 index 0000000..ac99b19 --- /dev/null +++ b/tests/auto/gestures/gestures.pro @@ -0,0 +1,3 @@ +load(qttest_p4) +SOURCES += tst_gestures.cpp customgesturerecognizer.cpp +HEADERS += customgesturerecognizer.h diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp new file mode 100644 index 0000000..9c9d279 --- /dev/null +++ b/tests/auto/gestures/tst_gestures.cpp @@ -0,0 +1,949 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtGui> + +#include <QtTest/QtTest> + +#include "customgesturerecognizer.h" + +//TESTED_CLASS= +//TESTED_FILES= + +// color generator for syntax highlighting from QQ-26 by Helder Correia +QVector<QColor> highlight(const QColor &bg, const + QColor &fg, int noColors) +{ + QVector<QColor> colors; + const int HUE_BASE = (bg.hue() == -1) ? 90 : bg.hue(); + int h, s, v; + for (int i = 0; i < noColors; i++) { + h = int(HUE_BASE + (360.0 / noColors * i)) % 360; + s = 240; + v = int(qMax(bg.value(), fg.value()) * 0.85); + + const int M = 35; + if ((h < bg.hue() + M && h > bg.hue() - M) + || (h < fg.hue() + M && h > fg.hue() - M)) + { + h = ((bg.hue() + fg.hue()) / (i+1)) % 360; + s = ((bg.saturation() + fg.saturation() + 2*i) + / 2) % 256; + v = ((bg.value() + fg.value() + 2*i) / 2) + % 256; + } + colors.append(QColor::fromHsv(h, s, v)); + } + return colors; +} + + +// a hack to mark an event as spontaneous. +class QETWidget +{ +public: + static void setSpont(QEvent *event, bool spont) { event->spont = spont; } +}; + +struct GestureState +{ + int seenGestureEvent; + struct LastGestureEvent + { + struct SingleshotGesture + { + bool delivered; + QPoint offset; + } singleshot; + struct PinchGesture + { + bool delivered; + TouchPoint startPoints[2]; + TouchPoint lastPoints[2]; + TouchPoint points[2]; + QPoint offset; + } pinch; + struct SecondFingerGesture + { + bool delivered; + TouchPoint startPoint; + TouchPoint lastPoint; + TouchPoint point; + QPoint offset; + } secondfinger; + struct PanGesture + { + bool delivered; + TouchPoint startPoints[2]; + TouchPoint lastPoints[2]; + TouchPoint points[2]; + QPoint offset; + } pan; + QSet<QString> cancelled; + } last; + + GestureState() { reset(); } + void reset() + { + seenGestureEvent = 0; + last.singleshot.delivered = false; + last.singleshot.offset = QPoint(); + last.pinch.delivered = false; + last.pinch.startPoints[0] = TouchPoint(); + last.pinch.startPoints[1] = TouchPoint(); + last.pinch.lastPoints[0] = TouchPoint(); + last.pinch.lastPoints[1] = TouchPoint(); + last.pinch.points[0] = TouchPoint(); + last.pinch.points[1] = TouchPoint(); + last.pinch.offset = QPoint(); + last.secondfinger.delivered = false; + last.secondfinger.startPoint = TouchPoint(); + last.secondfinger.lastPoint = TouchPoint(); + last.secondfinger.point = TouchPoint(); + last.secondfinger.offset = QPoint(); + last.cancelled.clear(); + } +}; + +struct TouchState +{ + int seenTouchBeginEvent; + int seenTouchUpdateEvent; + int seenTouchEndEvent; + + TouchState() { reset(); } + void reset() + { + seenTouchBeginEvent = seenTouchUpdateEvent = seenTouchEndEvent = 0; + } +}; + +class GestureWidget : public QWidget +{ + Q_OBJECT + static QVector<QColor> colors; + static int numberOfWidgets; + +public: + enum Type { DoNotGrabGestures, GrabAllGestures, GrabSingleshot, + GrabPinch, GrabSecondFinger, GrabPan }; + + static const int LeftMargin = 10; + static const int TopMargin = 20; + + GestureWidget(Type type = GrabAllGestures) + { + if (colors.isEmpty()) { + colors = highlight(palette().color(QPalette::Window), palette().color(QPalette::Text), 5); + } + QPalette p = palette(); + p.setColor(QPalette::Window, colors[numberOfWidgets % colors.size()]); + setPalette(p); + setAutoFillBackground(true); + ++numberOfWidgets; + + QVBoxLayout *l = new QVBoxLayout(this); + l->setSpacing(0); + l->setContentsMargins(LeftMargin, TopMargin, LeftMargin, TopMargin); + + singleshotGestureId = -1; + pinchGestureId = -1; + secondFingerGestureId = -1; + panGestureId = -1; + if (type == GrabAllGestures || type == GrabSingleshot) { + singleshotGestureId = grabGesture(SingleshotGestureRecognizer::Name); + } + if (type == GrabAllGestures || type == GrabPinch) { + pinchGestureId = grabGesture(PinchGestureRecognizer::Name); + } + if (type == GrabAllGestures || type == GrabSecondFinger) { + secondFingerGestureId = grabGesture(SecondFingerGestureRecognizer::Name); + } + if (type == GrabAllGestures || type == GrabPan) { + panGestureId = grabGesture(PanGestureRecognizer::Name); + } + reset(); + } + ~GestureWidget() + { + --numberOfWidgets; + ungrabGestures(); + } + + void grabSingleshotGesture() + { + singleshotGestureId = grabGesture(SingleshotGestureRecognizer::Name); + } + void grabPinchGesture() + { + pinchGestureId = grabGesture(PinchGestureRecognizer::Name); + } + void grabSecondFingerGesture() + { + secondFingerGestureId = grabGesture(SecondFingerGestureRecognizer::Name); + } + void grabPanGesture() + { + panGestureId = grabGesture(PanGestureRecognizer::Name); + } + void ungrabGestures() + { + releaseGesture(singleshotGestureId); + singleshotGestureId = -1; + releaseGesture(pinchGestureId); + pinchGestureId = -1; + releaseGesture(secondFingerGestureId); + secondFingerGestureId = -1; + releaseGesture(panGestureId); + panGestureId = -1; + } + + int singleshotGestureId; + int pinchGestureId; + int secondFingerGestureId; + int panGestureId; + + bool shouldAcceptSingleshotGesture; + bool shouldAcceptPinchGesture; + bool shouldAcceptSecondFingerGesture; + bool shouldAcceptPanGesture; + + GestureState gesture; + TouchState touch; + + void reset() + { + shouldAcceptSingleshotGesture = true; + shouldAcceptPinchGesture = true; + shouldAcceptSecondFingerGesture = true; + shouldAcceptPanGesture = true; + gesture.reset(); + touch.reset(); + } +protected: + bool event(QEvent *event) + { + if (event->type() == QEvent::TouchBegin) { + event->accept(); + ++touch.seenTouchBeginEvent; + return true; + } else if (event->type() == QEvent::TouchUpdate) { + ++touch.seenTouchUpdateEvent; + } else if (event->type() == QEvent::TouchEnd) { + ++touch.seenTouchEndEvent; + } else if (event->type() == QEvent::Gesture) { + QGestureEvent *e = static_cast<QGestureEvent*>(event); + ++gesture.seenGestureEvent; + if (SingleshotGesture *g = (SingleshotGesture*)e->gesture(SingleshotGestureRecognizer::Name)) { + gesture.last.singleshot.delivered = true; + gesture.last.singleshot.offset = g->offset; + if (shouldAcceptSingleshotGesture) + g->accept(); + } + if (PinchGesture *g = (PinchGesture*)e->gesture(PinchGestureRecognizer::Name)) { + gesture.last.pinch.delivered = true; + gesture.last.pinch.startPoints[0] = g->startPoints[0]; + gesture.last.pinch.startPoints[1] = g->startPoints[1]; + gesture.last.pinch.lastPoints[0] = g->lastPoints[0]; + gesture.last.pinch.lastPoints[1] = g->lastPoints[1]; + gesture.last.pinch.points[0] = g->points[0]; + gesture.last.pinch.points[1] = g->points[1]; + gesture.last.pinch.offset = g->offset; + if (shouldAcceptPinchGesture) + g->accept(); + } + if (SecondFingerGesture *g = (SecondFingerGesture*)e->gesture(SecondFingerGestureRecognizer::Name)) { + gesture.last.secondfinger.delivered = true; + gesture.last.secondfinger.startPoint = g->startPoint; + gesture.last.secondfinger.lastPoint = g->lastPoint; + gesture.last.secondfinger.point = g->point; + gesture.last.secondfinger.offset = g->offset; + if (shouldAcceptSecondFingerGesture) + g->accept(); + } + if (PanGesture *g = (PanGesture*)e->gesture(PanGestureRecognizer::Name)) { + gesture.last.pan.delivered = true; + gesture.last.pan.startPoints[0] = g->startPoints[0]; + gesture.last.pan.startPoints[1] = g->startPoints[1]; + gesture.last.pan.lastPoints[0] = g->lastPoints[0]; + gesture.last.pan.lastPoints[1] = g->lastPoints[1]; + gesture.last.pan.points[0] = g->points[0]; + gesture.last.pan.points[1] = g->points[1]; + gesture.last.pan.offset = g->offset; + if (shouldAcceptPanGesture) + g->accept(); + } + gesture.last.cancelled = e->cancelledGestures(); + return true; + } + return QWidget::event(event); + } +}; +QVector<QColor> GestureWidget::colors; +int GestureWidget::numberOfWidgets = 0; + +class GraphicsScene : public QGraphicsScene +{ +public: + GraphicsScene() + { + reset(); + } + bool shouldAcceptSingleshotGesture; + bool shouldAcceptPinchGesture; + bool shouldAcceptSecondFingerGesture; + GestureState gesture; + + void reset() + { + shouldAcceptSingleshotGesture = false; + shouldAcceptPinchGesture = false; + shouldAcceptSecondFingerGesture = false; + gesture.reset(); + } +protected: + bool event(QEvent *event) + { + if (event->type() == QEvent::GraphicsSceneGesture) { + QGraphicsSceneGestureEvent *e = static_cast<QGraphicsSceneGestureEvent*>(event); + ++gesture.seenGestureEvent; + QGraphicsScene::event(event); + if (SingleshotGesture *g = (SingleshotGesture*)e->gesture(SingleshotGestureRecognizer::Name)) { + gesture.last.singleshot.delivered = true; + gesture.last.singleshot.offset = g->offset; + if (shouldAcceptSingleshotGesture) + g->accept(); + } + if (PinchGesture *g = (PinchGesture*)e->gesture(PinchGestureRecognizer::Name)) { + gesture.last.pinch.delivered = true; + gesture.last.pinch.startPoints[0] = g->startPoints[0]; + gesture.last.pinch.startPoints[1] = g->startPoints[1]; + gesture.last.pinch.lastPoints[0] = g->lastPoints[0]; + gesture.last.pinch.lastPoints[1] = g->lastPoints[1]; + gesture.last.pinch.points[0] = g->points[0]; + gesture.last.pinch.points[1] = g->points[1]; + gesture.last.pinch.offset = g->offset; + if (shouldAcceptPinchGesture) + g->accept(); + } + if (SecondFingerGesture *g = (SecondFingerGesture*)e->gesture(SecondFingerGestureRecognizer::Name)) { + gesture.last.secondfinger.delivered = true; + gesture.last.secondfinger.startPoint = g->startPoint; + gesture.last.secondfinger.lastPoint = g->lastPoint; + gesture.last.secondfinger.point = g->point; + gesture.last.secondfinger.offset = g->offset; + if (shouldAcceptSecondFingerGesture) + g->accept(); + } + gesture.last.cancelled = e->cancelledGestures(); + return true; + } + return QGraphicsScene::event(event); + } +}; + +class GraphicsItem : public QGraphicsItem +{ +public: + GraphicsItem(int w = 100, int h = 100) + : width(w), height(h) + { + reset(); + } + + QRectF boundingRect() const + { + return QRectF(0, 0, width, height); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*) + { + painter->setBrush(Qt::green); + painter->drawRect(0, 0, width, height); + } + + void grabSingleshotGesture() + { + singleshotGestureId = grabGesture(SingleshotGestureRecognizer::Name); + } + void grabPinchGesture() + { + pinchGestureId = grabGesture(PinchGestureRecognizer::Name); + } + void grabSecondFingerGesture() + { + secondFingerGestureId = grabGesture(SecondFingerGestureRecognizer::Name); + } + void ungrabGestures() + { + releaseGesture(singleshotGestureId); + singleshotGestureId = -1; + releaseGesture(pinchGestureId); + pinchGestureId = -1; + releaseGesture(secondFingerGestureId); + secondFingerGestureId = -1; + } + + int width; + int height; + + int singleshotGestureId; + int pinchGestureId; + int secondFingerGestureId; + + bool shouldAcceptSingleshotGesture; + bool shouldAcceptPinchGesture; + bool shouldAcceptSecondFingerGesture; + GestureState gesture; + + TouchState touch; + + void reset() + { + shouldAcceptSingleshotGesture = true; + shouldAcceptPinchGesture = true; + shouldAcceptSecondFingerGesture = true; + gesture.reset(); + } +protected: + bool sceneEvent(QEvent *event) + { + if (event->type() == QEvent::TouchBegin) { + event->accept(); + ++touch.seenTouchBeginEvent; + return true; + } else if (event->type() == QEvent::TouchUpdate) { + ++touch.seenTouchUpdateEvent; + } else if (event->type() == QEvent::TouchEnd) { + ++touch.seenTouchEndEvent; + } else if (event->type() == QEvent::GraphicsSceneGesture) { + QGraphicsSceneGestureEvent *e = static_cast<QGraphicsSceneGestureEvent*>(event); + ++gesture.seenGestureEvent; + if (SingleshotGesture *g = (SingleshotGesture*)e->gesture(SingleshotGestureRecognizer::Name)) { + gesture.last.singleshot.delivered = true; + gesture.last.singleshot.offset = g->offset; + if (shouldAcceptSingleshotGesture) + g->accept(); + } + if (PinchGesture *g = (PinchGesture*)e->gesture(PinchGestureRecognizer::Name)) { + gesture.last.pinch.delivered = true; + gesture.last.pinch.startPoints[0] = g->startPoints[0]; + gesture.last.pinch.startPoints[1] = g->startPoints[1]; + gesture.last.pinch.lastPoints[0] = g->lastPoints[0]; + gesture.last.pinch.lastPoints[1] = g->lastPoints[1]; + gesture.last.pinch.points[0] = g->points[0]; + gesture.last.pinch.points[1] = g->points[1]; + gesture.last.pinch.offset = g->offset; + if (shouldAcceptPinchGesture) + g->accept(); + } + if (SecondFingerGesture *g = (SecondFingerGesture*)e->gesture(SecondFingerGestureRecognizer::Name)) { + gesture.last.secondfinger.delivered = true; + gesture.last.secondfinger.startPoint = g->startPoint; + gesture.last.secondfinger.lastPoint = g->lastPoint; + gesture.last.secondfinger.point = g->point; + gesture.last.secondfinger.offset = g->offset; + if (shouldAcceptSecondFingerGesture) + g->accept(); + } + gesture.last.cancelled = e->cancelledGestures(); + return true; + } + return QGraphicsItem::sceneEvent(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 singleshotGesture(); + void pinchGesture(); + + void simplePropagation(); + void simplePropagation2(); + void acceptedGesturePropagation(); + + void simpleGraphicsView(); + void simpleGraphicsItem(); + void overlappingGraphicsItems(); + + void touch_widget(); + void touch_graphicsView(); + + void panOnWidgets(); + +private: + SingleshotGestureRecognizer *singleshotRecognizer; + PinchGestureRecognizer *pinchRecognizer; + SecondFingerGestureRecognizer *secondFingerRecognizer; + PanGestureRecognizer *panGestureRecognizer; + GestureWidget *mainWidget; + + void sendPinchEvents(QWidget *receiver, const QPoint &fromFinger1, const QPoint &fromFinger2); +}; + +tst_Gestures::tst_Gestures() +{ + singleshotRecognizer = new SingleshotGestureRecognizer; + pinchRecognizer = new PinchGestureRecognizer; + secondFingerRecognizer = new SecondFingerGestureRecognizer; + panGestureRecognizer = new PanGestureRecognizer; + qApp->addGestureRecognizer(singleshotRecognizer); + qApp->addGestureRecognizer(pinchRecognizer); + qApp->addGestureRecognizer(secondFingerRecognizer); + qApp->addGestureRecognizer(panGestureRecognizer); +} + +tst_Gestures::~tst_Gestures() +{ +} + + +void tst_Gestures::initTestCase() +{ + mainWidget = new GestureWidget(GestureWidget::DoNotGrabGestures); + mainWidget->setObjectName("MainGestureWidget"); + mainWidget->resize(500, 600); + mainWidget->show(); +} + +void tst_Gestures::cleanupTestCase() +{ + delete mainWidget; mainWidget = 0; +} + +void tst_Gestures::init() +{ + // TODO: Add initialization code here. + // This will be executed immediately before each test is run. + mainWidget->reset(); +} + +void tst_Gestures::cleanup() +{ +} + +bool sendSpontaneousEvent(QWidget *receiver, QEvent *event) +{ + QETWidget::setSpont(event, true); + return qApp->notify(receiver, event); +} + +void tst_Gestures::singleshotGesture() +{ + mainWidget->grabSingleshotGesture(); + SingleshotEvent event; + sendSpontaneousEvent(mainWidget, &event); + QVERIFY(mainWidget->gesture.seenGestureEvent); + QVERIFY(mainWidget->gesture.last.singleshot.delivered); + QVERIFY(mainWidget->gesture.last.cancelled.isEmpty()); +} + +void tst_Gestures::sendPinchEvents(QWidget *receiver, const QPoint &fromFinger1, const QPoint &fromFinger2) +{ + int x1 = fromFinger1.x(); + int y1 = fromFinger1.x(); + int x2 = fromFinger2.x(); + int y2 = fromFinger2.x(); + + TouchEvent event; + event.points[0] = TouchPoint(0,x1,y1, TouchPoint::Begin); + event.points[1] = TouchPoint(); + sendSpontaneousEvent(receiver, &event); + event.points[0] = TouchPoint(0, x1+=2,y1+=2, TouchPoint::Update); + event.points[1] = TouchPoint(); + sendSpontaneousEvent(receiver, &event); + event.points[0] = TouchPoint(0, x1,y1, TouchPoint::Update); + event.points[1] = TouchPoint(1, x2,y2, TouchPoint::Begin); + sendSpontaneousEvent(receiver, &event); + event.points[0] = TouchPoint(0, x1+=5,y1+=10, TouchPoint::End); + event.points[1] = TouchPoint(1, x2+=3,y2+=6, TouchPoint::Update); + sendSpontaneousEvent(receiver, &event); + event.points[0] = TouchPoint(); + event.points[1] = TouchPoint(1, x2+=10,y2+=15, TouchPoint::Update); + sendSpontaneousEvent(receiver, &event); + event.points[0] = TouchPoint(); + event.points[1] = TouchPoint(1, x2,y2, TouchPoint::End); + sendSpontaneousEvent(receiver, &event); +} + +void tst_Gestures::pinchGesture() +{ + mainWidget->grabPinchGesture(); + sendPinchEvents(mainWidget, QPoint(10,10), QPoint(20,20)); + + QVERIFY(mainWidget->gesture.seenGestureEvent); + QVERIFY(!mainWidget->gesture.last.singleshot.delivered); + QVERIFY(mainWidget->gesture.last.cancelled.isEmpty()); + QVERIFY(mainWidget->gesture.last.pinch.delivered); + QCOMPARE(mainWidget->gesture.last.pinch.startPoints[0].pt, QPoint(10,10)); + QCOMPARE(mainWidget->gesture.last.pinch.startPoints[1].pt, QPoint(20,20)); + QCOMPARE(mainWidget->gesture.last.pinch.offset, QPoint(0,0)); +} + +void tst_Gestures::simplePropagation() +{ + mainWidget->grabSingleshotGesture(); + GestureWidget offsetWidget(GestureWidget::DoNotGrabGestures); + offsetWidget.setFixedSize(30, 30); + mainWidget->layout()->addWidget(&offsetWidget); + GestureWidget nonGestureWidget(GestureWidget::DoNotGrabGestures); + mainWidget->layout()->addWidget(&nonGestureWidget); + QApplication::processEvents(); + + SingleshotEvent event; + sendSpontaneousEvent(&nonGestureWidget, &event); + QVERIFY(!offsetWidget.gesture.seenGestureEvent); + QVERIFY(!nonGestureWidget.gesture.seenGestureEvent); + QVERIFY(mainWidget->gesture.seenGestureEvent); + QVERIFY(mainWidget->gesture.last.cancelled.isEmpty()); + QVERIFY(mainWidget->gesture.last.singleshot.delivered); + QCOMPARE(mainWidget->gesture.last.singleshot.offset, QPoint(GestureWidget::LeftMargin, 30 + GestureWidget::TopMargin)); +} + +void tst_Gestures::simplePropagation2() +{ + mainWidget->grabSingleshotGesture(); + mainWidget->grabPinchGesture(); + GestureWidget nonGestureMiddleWidget(GestureWidget::DoNotGrabGestures); + GestureWidget secondGestureWidget(GestureWidget::GrabPinch); + nonGestureMiddleWidget.layout()->addWidget(&secondGestureWidget); + mainWidget->layout()->addWidget(&nonGestureMiddleWidget); + QApplication::processEvents(); + + SingleshotEvent event; + sendSpontaneousEvent(&secondGestureWidget, &event); + QVERIFY(!secondGestureWidget.gesture.seenGestureEvent); + QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent); + QVERIFY(mainWidget->gesture.seenGestureEvent); + QVERIFY(mainWidget->gesture.last.singleshot.delivered); + QVERIFY(mainWidget->gesture.last.cancelled.isEmpty()); + QCOMPARE(mainWidget->gesture.last.singleshot.offset, QPoint(GestureWidget::LeftMargin*2,GestureWidget::TopMargin*2)); + + mainWidget->reset(); + nonGestureMiddleWidget.reset(); + secondGestureWidget.reset(); + + sendPinchEvents(&secondGestureWidget, QPoint(10,10), QPoint(20,20)); + QVERIFY(secondGestureWidget.gesture.seenGestureEvent); + QVERIFY(!secondGestureWidget.gesture.last.singleshot.delivered); + QVERIFY(secondGestureWidget.gesture.last.pinch.delivered); + QCOMPARE(secondGestureWidget.gesture.last.pinch.startPoints[0].pt, QPoint(10,10)); + QCOMPARE(secondGestureWidget.gesture.last.pinch.startPoints[1].pt, QPoint(20,20)); + QCOMPARE(secondGestureWidget.gesture.last.pinch.offset, QPoint(0,0)); + QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent); + QVERIFY(!mainWidget->gesture.seenGestureEvent); +} + +void tst_Gestures::acceptedGesturePropagation() +{ + mainWidget->grabSingleshotGesture(); + mainWidget->grabPinchGesture(); + mainWidget->grabSecondFingerGesture(); + GestureWidget nonGestureMiddleWidget(GestureWidget::DoNotGrabGestures); + nonGestureMiddleWidget.setObjectName("nonGestureMiddleWidget"); + GestureWidget secondGestureWidget(GestureWidget::GrabSecondFinger); + secondGestureWidget.setObjectName("secondGestureWidget"); + nonGestureMiddleWidget.layout()->addWidget(&secondGestureWidget); + mainWidget->layout()->addWidget(&nonGestureMiddleWidget); + QApplication::processEvents(); + + sendPinchEvents(&secondGestureWidget, QPoint(10, 10), QPoint(40, 40)); + QVERIFY(secondGestureWidget.gesture.seenGestureEvent); + QVERIFY(!secondGestureWidget.gesture.last.singleshot.delivered); + QVERIFY(!secondGestureWidget.gesture.last.pinch.delivered); + QVERIFY(secondGestureWidget.gesture.last.secondfinger.delivered); + QCOMPARE(secondGestureWidget.gesture.last.secondfinger.startPoint.pt, QPoint(40,40)); + QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent); + QVERIFY(mainWidget->gesture.seenGestureEvent); + QVERIFY(!mainWidget->gesture.last.singleshot.delivered); + QVERIFY(!mainWidget->gesture.last.secondfinger.delivered); + QVERIFY(mainWidget->gesture.last.pinch.delivered); + QCOMPARE(mainWidget->gesture.last.pinch.startPoints[0].pt, QPoint(10,10)); + QCOMPARE(mainWidget->gesture.last.pinch.startPoints[1].pt, QPoint(40,40)); + + mainWidget->reset(); + nonGestureMiddleWidget.reset(); + secondGestureWidget.reset(); + + // don't accept it and make sure it propagates to parent + secondGestureWidget.shouldAcceptSecondFingerGesture = false; + sendPinchEvents(&secondGestureWidget, QPoint(10, 10), QPoint(40, 40)); + QVERIFY(secondGestureWidget.gesture.seenGestureEvent); + QVERIFY(secondGestureWidget.gesture.last.secondfinger.delivered); + QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent); + QVERIFY(mainWidget->gesture.seenGestureEvent); + QVERIFY(!mainWidget->gesture.last.singleshot.delivered); + QVERIFY(mainWidget->gesture.last.secondfinger.delivered); + QVERIFY(mainWidget->gesture.last.pinch.delivered); +} + +void tst_Gestures::simpleGraphicsView() +{ + mainWidget->grabSingleshotGesture(); + GraphicsScene scene; + QGraphicsView view(&scene); + view.grabGesture(SingleshotGestureRecognizer::Name); + mainWidget->layout()->addWidget(&view); + QApplication::processEvents(); + + scene.shouldAcceptSingleshotGesture = true; + + SingleshotEvent event; + sendSpontaneousEvent(&view, &event); + QVERIFY(!mainWidget->gesture.seenGestureEvent); + QVERIFY(scene.gesture.seenGestureEvent); + QVERIFY(scene.gesture.last.singleshot.delivered); + QVERIFY(scene.gesture.last.cancelled.isEmpty()); +} + +void tst_Gestures::simpleGraphicsItem() +{ + mainWidget->grabSingleshotGesture(); + GraphicsScene scene; + QGraphicsView view(&scene); + mainWidget->layout()->addWidget(&view); + GraphicsItem *item = new GraphicsItem; + item->grabSingleshotGesture(); + item->setPos(30, 50); + scene.addItem(item); + QApplication::processEvents(); + + SingleshotEvent event(50, 80); + sendSpontaneousEvent(&view, &event); + QVERIFY(item->gesture.seenGestureEvent); + QVERIFY(scene.gesture.seenGestureEvent); + QVERIFY(!mainWidget->gesture.seenGestureEvent); + + item->reset(); + scene.reset(); + mainWidget->reset(); + + item->shouldAcceptSingleshotGesture = false; + SingleshotEvent event2(20, 40); + sendSpontaneousEvent(&view, &event2); + QVERIFY(!item->gesture.seenGestureEvent); + QVERIFY(scene.gesture.seenGestureEvent); + QVERIFY(mainWidget->gesture.seenGestureEvent); +} + +void tst_Gestures::overlappingGraphicsItems() +{ + mainWidget->grabSingleshotGesture(); + GraphicsScene scene; + QGraphicsView view(&scene); + mainWidget->layout()->addWidget(&view); + + GraphicsItem *item = new GraphicsItem(300, 100); + item->setPos(30, 50); + scene.addItem(item); + GraphicsItem *subitem1 = new GraphicsItem(50, 70); + subitem1->setPos(70, 70); + scene.addItem(subitem1); + GraphicsItem *subitem2 = new GraphicsItem(50, 70); + subitem2->setPos(250, 70); + scene.addItem(subitem2); + QApplication::processEvents(); + + item->grabSingleshotGesture(); + item->grabPinchGesture(); + item->grabSecondFingerGesture(); + subitem1->grabSingleshotGesture(); + subitem2->grabSecondFingerGesture(); + + SingleshotEvent event(100, 100); + sendSpontaneousEvent(&view, &event); + QVERIFY(subitem1->gesture.seenGestureEvent); + QVERIFY(!subitem2->gesture.seenGestureEvent); + QVERIFY(!item->gesture.seenGestureEvent); + QVERIFY(scene.gesture.seenGestureEvent); + QVERIFY(!mainWidget->gesture.seenGestureEvent); + QVERIFY(subitem1->gesture.last.singleshot.delivered); + + item->reset(); + subitem1->reset(); + subitem2->reset(); + scene.reset(); + mainWidget->reset(); + + subitem1->shouldAcceptSingleshotGesture = false; + SingleshotEvent event2(100, 100); + sendSpontaneousEvent(&view, &event2); + QVERIFY(subitem1->gesture.seenGestureEvent); + QVERIFY(!subitem2->gesture.seenGestureEvent); + QVERIFY(item->gesture.seenGestureEvent); + QVERIFY(scene.gesture.seenGestureEvent); + QVERIFY(!mainWidget->gesture.seenGestureEvent); + QVERIFY(subitem1->gesture.last.singleshot.delivered); + QVERIFY(item->gesture.last.singleshot.delivered); +} + +void tst_Gestures::touch_widget() +{ + GestureWidget leftWidget(GestureWidget::DoNotGrabGestures); + leftWidget.setObjectName("leftWidget"); + leftWidget.setAttribute(Qt::WA_AcceptTouchEvents); + GestureWidget rightWidget(GestureWidget::DoNotGrabGestures); + rightWidget.setObjectName("rightWidget"); + rightWidget.setAttribute(Qt::WA_AcceptTouchEvents); + delete mainWidget->layout(); + (void)new QHBoxLayout(mainWidget); + mainWidget->layout()->addWidget(&leftWidget); + mainWidget->layout()->addWidget(&rightWidget); + QApplication::processEvents(); + + QTest::touchEvent() + .press(0, QPoint(10, 10), &leftWidget); + QTest::touchEvent() + .move(0, QPoint(12, 30), &leftWidget); + QTest::touchEvent() + .stationary(0) + .press(1, QPoint(15, 15), &rightWidget); + QTest::touchEvent() + .move(0, QPoint(10, 35), &leftWidget) + .press(1, QPoint(15, 15), &rightWidget); + QTest::touchEvent() + .move(0, QPoint(10, 40), &leftWidget) + .move(1, QPoint(20, 50), &rightWidget); + QTest::touchEvent() + .release(0, QPoint(10, 40), &leftWidget) + .release(1, QPoint(20, 50), &rightWidget); + QVERIFY(!mainWidget->touch.seenTouchBeginEvent); + QVERIFY(leftWidget.touch.seenTouchBeginEvent); + QVERIFY(leftWidget.touch.seenTouchUpdateEvent); + QVERIFY(leftWidget.touch.seenTouchEndEvent); + QVERIFY(rightWidget.touch.seenTouchBeginEvent); + QVERIFY(rightWidget.touch.seenTouchUpdateEvent); + QVERIFY(rightWidget.touch.seenTouchEndEvent); +} + +void tst_Gestures::touch_graphicsView() +{ + mainWidget->setAttribute(Qt::WA_AcceptTouchEvents); + GraphicsScene scene; + QGraphicsView view(&scene); + view.viewport()->setAttribute(Qt::WA_AcceptTouchEvents); + mainWidget->layout()->addWidget(&view); + + GraphicsItem *item = new GraphicsItem(300, 100); + item->setAcceptTouchEvents(true); + item->setPos(30, 50); + scene.addItem(item); + GraphicsItem *subitem1 = new GraphicsItem(50, 70); + subitem1->setAcceptTouchEvents(true); + subitem1->setPos(70, 70); + scene.addItem(subitem1); + GraphicsItem *subitem2 = new GraphicsItem(50, 70); + subitem2->setAcceptTouchEvents(true); + subitem2->setPos(250, 70); + scene.addItem(subitem2); + QApplication::processEvents(); + + QRect itemRect = view.mapFromScene(item->mapRectToScene(item->boundingRect())).boundingRect(); + QPoint pt = itemRect.center(); + QTest::touchEvent(view.viewport()) + .press(0, pt) + .press(1, pt); + QTest::touchEvent(view.viewport()) + .move(0, pt + QPoint(20, 30)) + .move(1, QPoint(300, 300)); + QTest::touchEvent(view.viewport()) + .stationary(0) + .move(1, QPoint(330, 330)); + QTest::touchEvent(view.viewport()) + .release(0, QPoint(120, 120)) + .release(1, QPoint(300, 300)); + + QVERIFY(item->touch.seenTouchBeginEvent); + QVERIFY(item->touch.seenTouchUpdateEvent); + QVERIFY(item->touch.seenTouchEndEvent); +} + +void tst_Gestures::panOnWidgets() +{ + GestureWidget leftWidget(GestureWidget::GrabPan); + leftWidget.setObjectName("leftWidget"); + leftWidget.setAttribute(Qt::WA_AcceptTouchEvents); + GestureWidget rightWidget(GestureWidget::GrabPan); + rightWidget.setObjectName("rightWidget"); + rightWidget.setAttribute(Qt::WA_AcceptTouchEvents); + delete mainWidget->layout(); + (void)new QHBoxLayout(mainWidget); + mainWidget->layout()->addWidget(&leftWidget); + mainWidget->layout()->addWidget(&rightWidget); + QApplication::processEvents(); + + QTest::touchEvent() + .press(0, QPoint(10, 10), &leftWidget); + QTest::touchEvent() + .move(0, QPoint(12, 30), &leftWidget); + QTest::touchEvent() + .stationary(0) + .press(1, QPoint(15, 15), &rightWidget); + QTest::touchEvent() + .move(0, QPoint(10, 35), &leftWidget) + .press(1, QPoint(15, 15), &rightWidget); + QTest::touchEvent() + .move(0, QPoint(10, 40), &leftWidget) + .move(1, QPoint(20, 50), &rightWidget); + QTest::touchEvent() + .release(0, QPoint(10, 40), &leftWidget) + .release(1, QPoint(20, 50), &rightWidget); + + QVERIFY(leftWidget.gesture.last.pan.delivered); + QVERIFY(rightWidget.gesture.last.pan.delivered); +} + +QTEST_MAIN(tst_Gestures) +#include "tst_gestures.moc" diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp index a11b159..2fa7584 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -48,6 +48,7 @@ #include "qabstracteventdispatcher.h" #include <QtGui> +#include "private/qapplication_p.h" #include "private/qstylesheetstyle_p.h" #ifdef Q_OS_WINCE #include <windows.h> @@ -117,6 +118,8 @@ private slots: void windowsCommandLine_data(); void windowsCommandLine(); + + void touchEventPropagation(); }; class MyInputContext : public QInputContext @@ -1773,6 +1776,146 @@ void tst_QApplication::windowsCommandLine() #endif } +class TouchEventPropagationTestWidget : public QWidget +{ + Q_OBJECT + +public: + bool seenTouchEvent, acceptTouchEvent, seenMouseEvent, acceptMouseEvent; + + TouchEventPropagationTestWidget(QWidget *parent = 0) + : QWidget(parent), seenTouchEvent(false), acceptTouchEvent(false), seenMouseEvent(false), acceptMouseEvent(false) + { } + + void reset() + { + seenTouchEvent = acceptTouchEvent = seenMouseEvent = acceptMouseEvent = false; + } + + bool event(QEvent *event) + { + switch (event->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseMove: + case QEvent::MouseButtonRelease: + // qDebug() << objectName() << "seenMouseEvent = true"; + seenMouseEvent = true; + event->setAccepted(acceptMouseEvent); + break; + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + // qDebug() << objectName() << "seenTouchEvent = true"; + seenTouchEvent = true; + event->setAccepted(acceptTouchEvent); + break; + default: + return QWidget::event(event); + } + return true; + } +}; + +void tst_QApplication::touchEventPropagation() +{ + int argc = 1; + QApplication app(argc, &argv0, QApplication::GuiServer); + QTouchEvent::TouchPoint touchPoint(0); + QTouchEvent touchEvent(QEvent::TouchBegin, Qt::NoModifier, QList<QTouchEvent::TouchPoint *>() << (&touchPoint)); + + { + // touch event behavior on a window + TouchEventPropagationTestWidget window; + window.setObjectName("1. window"); + + QApplicationPrivate::sendTouchEvent(&window, &touchEvent); + QVERIFY(!window.seenTouchEvent); + QVERIFY(window.seenMouseEvent); + + window.reset(); + window.setAttribute(Qt::WA_AcceptsTouchEvents); + QApplicationPrivate::sendTouchEvent(&window, &touchEvent); + QVERIFY(window.seenTouchEvent); + QVERIFY(window.seenMouseEvent); + + window.reset(); + window.acceptTouchEvent = true; + QApplicationPrivate::sendTouchEvent(&window, &touchEvent); + QVERIFY(window.seenTouchEvent); + QVERIFY(!window.seenMouseEvent); + } + + { + // touch event behavior on a window with a child widget + TouchEventPropagationTestWidget window; + window.setObjectName("2. window"); + TouchEventPropagationTestWidget widget(&window); + widget.setObjectName("2. widget"); + + QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + QVERIFY(!widget.seenTouchEvent); + QVERIFY(widget.seenMouseEvent); + QVERIFY(!window.seenTouchEvent); + QVERIFY(window.seenMouseEvent); + + window.reset(); + widget.reset(); + widget.setAttribute(Qt::WA_AcceptsTouchEvents); + QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + QVERIFY(widget.seenTouchEvent); + QVERIFY(widget.seenMouseEvent); + QVERIFY(!window.seenTouchEvent); + QVERIFY(window.seenMouseEvent); + + window.reset(); + widget.reset(); + widget.acceptMouseEvent = true; + QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + QVERIFY(widget.seenTouchEvent); + QVERIFY(widget.seenMouseEvent); + QVERIFY(!window.seenTouchEvent); + QVERIFY(!window.seenMouseEvent); + + window.reset(); + widget.reset(); + widget.acceptTouchEvent = true; + QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + QVERIFY(widget.seenTouchEvent); + QVERIFY(!widget.seenMouseEvent); + QVERIFY(!window.seenTouchEvent); + QVERIFY(!window.seenMouseEvent); + + window.reset(); + widget.reset(); + widget.setAttribute(Qt::WA_AcceptsTouchEvents, false); + window.setAttribute(Qt::WA_AcceptsTouchEvents); + QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + QVERIFY(!widget.seenTouchEvent); + QVERIFY(widget.seenMouseEvent); + QVERIFY(window.seenTouchEvent); + QVERIFY(window.seenMouseEvent); + + window.reset(); + widget.reset(); + window.acceptTouchEvent = true; + QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + QVERIFY(!widget.seenTouchEvent); + QVERIFY(!widget.seenMouseEvent); + QVERIFY(window.seenTouchEvent); + QVERIFY(!window.seenMouseEvent); + + window.reset(); + widget.reset(); + widget.acceptMouseEvent = true; // doesn't matter, touch events are propagated first + window.acceptTouchEvent = true; + QApplicationPrivate::sendTouchEvent(&widget, &touchEvent); + QVERIFY(!widget.seenTouchEvent); + QVERIFY(!widget.seenMouseEvent); + QVERIFY(window.seenTouchEvent); + QVERIFY(!window.seenMouseEvent); + } +} + //QTEST_APPLESS_MAIN(tst_QApplication) int main(int argc, char *argv[]) { diff --git a/tests/auto/qtouchevent/qtouchevent.pro b/tests/auto/qtouchevent/qtouchevent.pro new file mode 100644 index 0000000..8f6aa87 --- /dev/null +++ b/tests/auto/qtouchevent/qtouchevent.pro @@ -0,0 +1,3 @@ +SOURCES=tst_qtouchevent.cpp +TARGET=tst_qtouchevent +QT+=testlib diff --git a/tests/auto/qtouchevent/tst_qtouchevent.cpp b/tests/auto/qtouchevent/tst_qtouchevent.cpp new file mode 100644 index 0000000..f27641b --- /dev/null +++ b/tests/auto/qtouchevent/tst_qtouchevent.cpp @@ -0,0 +1,335 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> +#include <QtTest> + +class tst_QTouchEventWidget : public QWidget +{ +public: + QList<QTouchEvent::TouchPoint> touchBeginPoints, touchUpdatePoints, touchEndPoints; + bool seenTouchBegin, seenTouchUpdate, seenTouchEnd; + bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd; + + tst_QTouchEventWidget() + : QWidget() + { + reset(); + } + + void reset() + { + touchBeginPoints.clear(); + touchUpdatePoints.clear(); + touchEndPoints.clear(); + seenTouchBegin = seenTouchUpdate = seenTouchEnd = false; + acceptTouchBegin = acceptTouchUpdate = acceptTouchEnd = true; + } + + bool event(QEvent *event) + { + switch (event->type()) { + case QEvent::TouchBegin: + if (seenTouchBegin) qWarning("TouchBegin: already seen a TouchBegin"); + if (seenTouchUpdate) qWarning("TouchBegin: TouchUpdate cannot happen before TouchBegin"); + if (seenTouchEnd) qWarning("TouchBegin: TouchEnd cannot happen before TouchBegin"); + seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd; + touchBeginPoints = static_cast<QTouchEvent *>(event)->touchPoints(); + event->setAccepted(acceptTouchBegin); + break; + case QEvent::TouchUpdate: + if (!seenTouchBegin) qWarning("TouchUpdate: have not seen TouchBegin"); + if (seenTouchEnd) qWarning("TouchUpdate: TouchEnd cannot happen before TouchUpdate"); + seenTouchUpdate = seenTouchBegin && !seenTouchEnd; + touchUpdatePoints = static_cast<QTouchEvent *>(event)->touchPoints(); + event->setAccepted(acceptTouchUpdate); + break; + case QEvent::TouchEnd: + if (!seenTouchBegin) qWarning("TouchEnd: have not seen TouchBegin"); + if (seenTouchEnd) qWarning("TouchEnd: already seen a TouchEnd"); + seenTouchEnd = seenTouchBegin && !seenTouchEnd; + touchEndPoints = static_cast<QTouchEvent *>(event)->touchPoints(); + event->setAccepted(acceptTouchEnd); + break; + default: + return QWidget::event(event); + } + return true; + } +}; + +class tst_QTouchEvent : public QObject +{ + Q_OBJECT +public: + tst_QTouchEvent() { } + ~tst_QTouchEvent() { } + +private slots: + void touchDisabledByDefault(); + void touchEventAcceptedByDefault(); + void touchBeginPropagatesWhenIgnored(); + void touchUpdateAndEndNeverPropagate(); + void basicRawEventTranslation(); +}; + +void tst_QTouchEvent::touchDisabledByDefault() +{ + // the widget attribute is not enabled by default + QWidget widget; + QVERIFY(!widget.testAttribute(Qt::WA_AcceptTouchEvents)); + + // events should not be accepted since they are not enabled + QList<QTouchEvent::TouchPoint> touchPoints; + touchPoints.append(QTouchEvent::TouchPoint(0)); + QTouchEvent touchEvent(QEvent::TouchBegin, + Qt::NoModifier, + Qt::TouchPointPressed, + touchPoints); + bool res = QApplication::sendEvent(&widget, &touchEvent); + QVERIFY(!res); + QVERIFY(!touchEvent.isAccepted()); +} + +void tst_QTouchEvent::touchEventAcceptedByDefault() +{ + // enabling touch events should automatically accept touch events + QWidget widget; + widget.setAttribute(Qt::WA_AcceptTouchEvents); + + // QWidget handles touch event by converting them into a mouse event, so the event is both + // accepted and handled (res == true) + QList<QTouchEvent::TouchPoint> touchPoints; + touchPoints.append(QTouchEvent::TouchPoint(0)); + QTouchEvent touchEvent(QEvent::TouchBegin, + Qt::NoModifier, + Qt::TouchPointPressed, + touchPoints); + bool res = QApplication::sendEvent(&widget, &touchEvent); + QVERIFY(res); + QVERIFY(touchEvent.isAccepted()); + + // tst_QTouchEventWidget does handle, sending succeeds + tst_QTouchEventWidget touchWidget; + touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); + touchEvent.ignore(); + res = QApplication::sendEvent(&touchWidget, &touchEvent); + QVERIFY(res); + QVERIFY(touchEvent.isAccepted()); +} + +void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() +{ + tst_QTouchEventWidget window, child, grandchild; + child.setParent(&window); + grandchild.setParent(&child); + + // all widgets accept touch events, grandchild ignores, so child sees the event, but not window + window.setAttribute(Qt::WA_AcceptTouchEvents); + child.setAttribute(Qt::WA_AcceptTouchEvents); + grandchild.setAttribute(Qt::WA_AcceptTouchEvents); + grandchild.acceptTouchBegin = false; + + QList<QTouchEvent::TouchPoint> touchPoints; + touchPoints.append(QTouchEvent::TouchPoint(0)); + QTouchEvent touchEvent(QEvent::TouchBegin, + Qt::NoModifier, + Qt::TouchPointPressed, + touchPoints); + bool res = QApplication::sendEvent(&grandchild, &touchEvent); + QVERIFY(res); + QVERIFY(touchEvent.isAccepted()); + QVERIFY(grandchild.seenTouchBegin); + QVERIFY(child.seenTouchBegin); + QVERIFY(!window.seenTouchBegin); + + // disable touch on grandchild. even though it doesn't accept it, child should still get the + // TouchBegin + grandchild.reset(); + child.reset(); + window.reset(); + grandchild.setAttribute(Qt::WA_AcceptTouchEvents, false); + + touchEvent.ignore(); + res = QApplication::sendEvent(&grandchild, &touchEvent); + QVERIFY(res); + QVERIFY(touchEvent.isAccepted()); + QVERIFY(!grandchild.seenTouchBegin); + QVERIFY(child.seenTouchBegin); + QVERIFY(!window.seenTouchBegin); +} + +void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() +{ + tst_QTouchEventWidget window, child; + child.setParent(&window); + + window.setAttribute(Qt::WA_AcceptTouchEvents); + child.setAttribute(Qt::WA_AcceptTouchEvents); + child.acceptTouchUpdate = false; + child.acceptTouchEnd = false; + + QList<QTouchEvent::TouchPoint> touchPoints; + touchPoints.append(QTouchEvent::TouchPoint(0)); + QTouchEvent touchBeginEvent(QEvent::TouchBegin, + Qt::NoModifier, + Qt::TouchPointPressed, + touchPoints); + bool res = QApplication::sendEvent(&child, &touchBeginEvent); + QVERIFY(res); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(child.seenTouchBegin); + QVERIFY(!window.seenTouchBegin); + + // send the touch update to the child, but ignore it, it doesn't propagate + QTouchEvent touchUpdateEvent(QEvent::TouchUpdate, + Qt::NoModifier, + Qt::TouchPointMoved, + touchPoints); + res = QApplication::sendEvent(&child, &touchUpdateEvent); + QVERIFY(res); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(child.seenTouchUpdate); + QVERIFY(!window.seenTouchUpdate); + + // send the touch end, same thing should happen as with touch update + QTouchEvent touchEndEvent(QEvent::TouchEnd, + Qt::NoModifier, + Qt::TouchPointReleased, + touchPoints); + res = QApplication::sendEvent(&child, &touchEndEvent); + QVERIFY(res); + QVERIFY(!touchEndEvent.isAccepted()); + QVERIFY(child.seenTouchEnd); + QVERIFY(!window.seenTouchEnd); +} + +void tst_QTouchEvent::basicRawEventTranslation() +{ + tst_QTouchEventWidget touchWidget; + touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); + + QPointF pos = touchWidget.rect().center(); + QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint()); + QPointF delta(10, 10); + + QTouchEvent::TouchPoint rawTouchPoint; + rawTouchPoint.setId(0); + + // this should be translated to a TouchBegin + rawTouchPoint.setState(Qt::TouchPointPressed); + rawTouchPoint.setScreenPos(screenPos); + qt_translateRawTouchEvent(QList<QTouchEvent::TouchPoint>() << rawTouchPoint, &touchWidget); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(!touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchBeginPoints.count(), 1); + QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.first(); + QCOMPARE(touchBeginPoint.id(), rawTouchPoint.id()); + QCOMPARE(touchBeginPoint.state(), rawTouchPoint.state()); + QCOMPARE(touchBeginPoint.pos(), pos); + QCOMPARE(touchBeginPoint.startPos(), pos); + QCOMPARE(touchBeginPoint.lastPos(), pos); + QCOMPARE(touchBeginPoint.scenePos(), rawTouchPoint.screenPos()); + QCOMPARE(touchBeginPoint.startScenePos(), rawTouchPoint.screenPos()); + QCOMPARE(touchBeginPoint.lastScenePos(), rawTouchPoint.screenPos()); + QCOMPARE(touchBeginPoint.screenPos(), rawTouchPoint.screenPos()); + QCOMPARE(touchBeginPoint.startScreenPos(), rawTouchPoint.screenPos()); + QCOMPARE(touchBeginPoint.lastScreenPos(), rawTouchPoint.screenPos()); + QCOMPARE(touchBeginPoint.rect(), QRectF(pos, QSizeF(0, 0))); + QCOMPARE(touchBeginPoint.screenRect(), QRectF(rawTouchPoint.screenPos(), QSizeF(0, 0))); + QCOMPARE(touchBeginPoint.sceneRect(), touchBeginPoint.screenRect()); + QCOMPARE(touchBeginPoint.pressure(), qreal(-1.)); + + // moving the point should translate to TouchUpdate + rawTouchPoint.setState(Qt::TouchPointMoved); + rawTouchPoint.setScreenPos(screenPos + delta); + qt_translateRawTouchEvent(QList<QTouchEvent::TouchPoint>() << rawTouchPoint, &touchWidget); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchUpdatePoints.count(), 1); + QTouchEvent::TouchPoint touchUpdatePoint = touchWidget.touchUpdatePoints.first(); + QCOMPARE(touchUpdatePoint.id(), rawTouchPoint.id()); + QCOMPARE(touchUpdatePoint.state(), rawTouchPoint.state()); + QCOMPARE(touchUpdatePoint.pos(), pos + delta); + QCOMPARE(touchUpdatePoint.startPos(), pos); + QCOMPARE(touchUpdatePoint.lastPos(), pos); + QCOMPARE(touchUpdatePoint.scenePos(), rawTouchPoint.screenPos()); + QCOMPARE(touchUpdatePoint.startScenePos(), screenPos); + QCOMPARE(touchUpdatePoint.lastScenePos(), screenPos); + QCOMPARE(touchUpdatePoint.screenPos(), rawTouchPoint.screenPos()); + QCOMPARE(touchUpdatePoint.startScreenPos(), screenPos); + QCOMPARE(touchUpdatePoint.lastScreenPos(), screenPos); + QCOMPARE(touchUpdatePoint.rect(), QRectF(pos + delta, QSizeF(0, 0))); + QCOMPARE(touchUpdatePoint.screenRect(), QRectF(rawTouchPoint.screenPos(), QSizeF(0, 0))); + QCOMPARE(touchUpdatePoint.sceneRect(), touchUpdatePoint.screenRect()); + QCOMPARE(touchUpdatePoint.pressure(), qreal(-1.)); + + // releasing the point translates to TouchEnd + rawTouchPoint.setState(Qt::TouchPointReleased); + rawTouchPoint.setScreenPos(screenPos + delta + delta); + qt_translateRawTouchEvent(QList<QTouchEvent::TouchPoint>() << rawTouchPoint, &touchWidget); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchEndPoints.count(), 1); + QTouchEvent::TouchPoint touchEndPoint = touchWidget.touchEndPoints.first(); + QCOMPARE(touchEndPoint.id(), rawTouchPoint.id()); + QCOMPARE(touchEndPoint.state(), rawTouchPoint.state()); + QCOMPARE(touchEndPoint.pos(), pos + delta + delta); + QCOMPARE(touchEndPoint.startPos(), pos); + QCOMPARE(touchEndPoint.lastPos(), pos + delta); + QCOMPARE(touchEndPoint.scenePos(), rawTouchPoint.screenPos()); + QCOMPARE(touchEndPoint.startScenePos(), screenPos); + QCOMPARE(touchEndPoint.lastScenePos(), screenPos + delta); + QCOMPARE(touchEndPoint.screenPos(), rawTouchPoint.screenPos()); + QCOMPARE(touchEndPoint.startScreenPos(), screenPos); + QCOMPARE(touchEndPoint.lastScreenPos(), screenPos + delta); + QCOMPARE(touchEndPoint.rect(), QRectF(pos + delta + delta, QSizeF(0, 0))); + QCOMPARE(touchEndPoint.screenRect(), QRectF(rawTouchPoint.screenPos(), QSizeF(0, 0))); + QCOMPARE(touchEndPoint.sceneRect(), touchEndPoint.screenRect()); + QCOMPARE(touchEndPoint.pressure(), qreal(-1.)); +} + +QTEST_MAIN(tst_QTouchEvent) + +#include "tst_qtouchevent.moc" diff --git a/tests/manual/qtouchevent/form.ui b/tests/manual/qtouchevent/form.ui new file mode 100644 index 0000000..c7fbb78 --- /dev/null +++ b/tests/manual/qtouchevent/form.ui @@ -0,0 +1,1897 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Form</class> + <widget class="QWidget" name="Form"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>770</width> + <height>424</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="testNameLabel"> + <property name="font"> + <font> + <pointsize>16</pointsize> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Test Name</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="testDescriptionLabel"> + <property name="font"> + <font> + <pointsize>16</pointsize> + </font> + </property> + <property name="text"> + <string>Test description</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="TouchWidget" name="greenWidget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>170</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>255</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>212</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>85</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>113</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>170</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="159"> + <red>127</red> + <green>212</green> + <blue>127</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>170</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>255</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>212</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>85</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>113</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>170</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="159"> + <red>127</red> + <green>212</green> + <blue>127</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>85</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>170</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>255</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>212</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>85</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>113</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>85</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>85</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>170</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>170</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>170</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="1" column="0"> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1"> + <widget class="TouchWidget" name="blueWidget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>180</width> + <height>120</height> + </size> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>170</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>212</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>85</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>113</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>170</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="159"> + <red>127</red> + <green>127</green> + <blue>212</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>170</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>212</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>85</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>113</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>170</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="159"> + <red>127</red> + <green>127</green> + <blue>212</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>85</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>170</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>212</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>85</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>113</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>85</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>85</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>170</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>170</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>170</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="2"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1"> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <widget class="TouchWidget" name="redWidget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>170</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>212</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>85</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>113</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>170</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="159"> + <red>212</red> + <green>127</green> + <blue>127</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>170</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>212</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>85</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>113</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>170</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="159"> + <red>212</red> + <green>127</green> + <blue>127</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>85</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>170</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>255</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>212</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>85</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>113</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>85</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>85</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>170</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>170</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>170</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="1"> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1"> + <widget class="TouchWidget" name="greyWidget" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>180</width> + <height>120</height> + </size> + </property> + <property name="palette"> + <palette> + <active> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="159"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </active> + <inactive> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="159"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </inactive> + <disabled> + <colorrole role="WindowText"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Button"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Light"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Midlight"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Dark"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Mid"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Text"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="BrightText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </brush> + </colorrole> + <colorrole role="ButtonText"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Base"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Window"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="Shadow"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="AlternateBase"> + <brush brushstyle="SolidPattern"> + <color alpha="63"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipBase"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>255</red> + <green>255</green> + <blue>220</blue> + </color> + </brush> + </colorrole> + <colorrole role="ToolTipText"> + <brush brushstyle="SolidPattern"> + <color alpha="255"> + <red>0</red> + <green>0</green> + <blue>0</blue> + </color> + </brush> + </colorrole> + </disabled> + </palette> + </property> + <property name="autoFillBackground"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="2"> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1"> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>TouchWidget</class> + <extends>QWidget</extends> + <header>touchwidget.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/tests/manual/qtouchevent/main.cpp b/tests/manual/qtouchevent/main.cpp new file mode 100644 index 0000000..8097ab0 --- /dev/null +++ b/tests/manual/qtouchevent/main.cpp @@ -0,0 +1,554 @@ +#include <QtGui> +#include <QtTest> + +#include "ui_form.h" +#include "touchwidget.h" + +class MultitouchTestWidget : public QWidget, public Ui::Form +{ + Q_OBJECT + +public: + MultitouchTestWidget(QWidget *parent = 0) + : QWidget(parent) + { + setAttribute(Qt::WA_QuitOnClose, false); + setupUi(this); + } + + void closeEvent(QCloseEvent *event) + { + event->accept(); + QTimer::singleShot(1000, qApp, SLOT(quit())); + } +}; + +class tst_ManualMultitouch : public QObject +{ + Q_OBJECT + +public: + tst_ManualMultitouch(); + ~tst_ManualMultitouch(); + +private slots: + void ignoringTouchEventsEmulatesMouseEvents(); + void basicSingleTouchEventHandling(); + void basicMultiTouchEventHandling(); + void acceptingTouchBeginStopsPropagation(); + void ignoringTouchBeginPropagatesToParent(); + void secondTouchPointOnParentGoesToChild(); + void secondTouchPointOnChildGoesToParent(); + void secondTouchPointOnSiblingGoesToSibling(); + void secondTouchPointOnCousinGoesToCousin(); +}; + +tst_ManualMultitouch::tst_ManualMultitouch() +{ } + +tst_ManualMultitouch::~tst_ManualMultitouch() +{ } + +void tst_ManualMultitouch::ignoringTouchEventsEmulatesMouseEvents() +{ + // first, make sure that we get mouse events when not enabling touch events + MultitouchTestWidget testWidget; + testWidget.testNameLabel->setText("Mouse Event Emulation Test"); + testWidget.testDescriptionLabel->setText("Touch, hold, and release your finger on the green widget."); + testWidget.redWidget->hide(); + testWidget.blueWidget->hide(); + testWidget.greenWidget->closeWindowOnMouseRelease = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(!testWidget.greenWidget->seenTouchBegin); + // QVERIFY(!testWidget.greenWidget->seenTouchUpdate); + QVERIFY(!testWidget.greenWidget->seenTouchEnd); + QVERIFY(testWidget.greenWidget->seenMousePress); + // QVERIFY(testWidget.greenWidget->seenMouseMove); + QVERIFY(testWidget.greenWidget->seenMouseRelease); + + // enable touch, but don't accept the events + testWidget.greenWidget->reset(); + testWidget.greenWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.greenWidget->closeWindowOnMouseRelease = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.greenWidget->seenTouchBegin); + // QVERIFY(!testWidget.greenWidget->seenTouchUpdate); + QVERIFY(!testWidget.greenWidget->seenTouchEnd); + QVERIFY(testWidget.greenWidget->seenMousePress); + // QVERIFY(testWidget.greenWidget->seenMouseMove); + QVERIFY(testWidget.greenWidget->seenMouseRelease); +} + +void tst_ManualMultitouch::basicSingleTouchEventHandling() +{ + // now enable touch and make sure we get the touch events + MultitouchTestWidget testWidget; + testWidget.testNameLabel->setText("Basic Single-Touch Event Handling Test"); + testWidget.testDescriptionLabel->setText("Touch, hold, and release your finger on the green widget."); + testWidget.redWidget->hide(); + testWidget.blueWidget->hide(); + testWidget.greenWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.greenWidget->acceptTouchBegin = true; + testWidget.greenWidget->acceptTouchUpdate = true; + testWidget.greenWidget->acceptTouchEnd = true; + testWidget.greenWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.greenWidget->seenTouchBegin); + // QVERIFY(testWidget.greenWidget->seenTouchUpdate); + QVERIFY(testWidget.greenWidget->seenTouchEnd); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); + + // again, ignoring the TouchEnd + testWidget.greenWidget->reset(); + testWidget.greenWidget->acceptTouchBegin = true; + testWidget.greenWidget->acceptTouchUpdate = true; + // testWidget.greenWidget->acceptTouchEnd = true; + testWidget.greenWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.greenWidget->seenTouchBegin); + // QVERIFY(testWidget.greenWidget->seenTouchUpdate); + QVERIFY(testWidget.greenWidget->seenTouchEnd); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); + + // again, ignoring TouchUpdates + testWidget.greenWidget->reset(); + testWidget.greenWidget->acceptTouchBegin = true; + // testWidget.greenWidget->acceptTouchUpdate = true; + testWidget.greenWidget->acceptTouchEnd = true; + testWidget.greenWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.greenWidget->seenTouchBegin); + // QVERIFY(testWidget.greenWidget->seenTouchUpdate); + QVERIFY(testWidget.greenWidget->seenTouchEnd); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); + + // last time, ignoring TouchUpdates and TouchEnd + testWidget.greenWidget->reset(); + testWidget.greenWidget->acceptTouchBegin = true; + // testWidget.greenWidget->acceptTouchUpdate = true; + // testWidget.greenWidget->acceptTouchEnd = true; + testWidget.greenWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.greenWidget->seenTouchBegin); + // QVERIFY(testWidget.greenWidget->seenTouchUpdate); + QVERIFY(testWidget.greenWidget->seenTouchEnd); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); +} + +void tst_ManualMultitouch::basicMultiTouchEventHandling() +{ + // repeat, this time looking for multiple fingers + MultitouchTestWidget testWidget; + testWidget.testNameLabel->setText("Basic Multi-Touch Event Handling Test"); + testWidget.testDescriptionLabel->setText("Touch, hold, and release several fingers on the red widget."); + testWidget.greenWidget->hide(); + testWidget.greyWidget->hide(); + testWidget.redWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.redWidget->acceptTouchBegin = true; + testWidget.redWidget->acceptTouchUpdate = true; + testWidget.redWidget->acceptTouchEnd = true; + testWidget.redWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.redWidget->seenTouchBegin); + QVERIFY(testWidget.redWidget->seenTouchUpdate); + QVERIFY(testWidget.redWidget->seenTouchEnd); + QVERIFY(testWidget.redWidget->touchPointCount > 1); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); + + testWidget.redWidget->reset(); + testWidget.redWidget->acceptTouchBegin = true; + // testWidget.redWidget->acceptTouchUpdate = true; + testWidget.redWidget->acceptTouchEnd = true; + testWidget.redWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.redWidget->seenTouchBegin); + QVERIFY(testWidget.redWidget->seenTouchUpdate); + QVERIFY(testWidget.redWidget->seenTouchEnd); + QVERIFY(testWidget.redWidget->touchPointCount > 1); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); + + testWidget.redWidget->reset(); + testWidget.redWidget->acceptTouchBegin = true; + testWidget.redWidget->acceptTouchUpdate = true; + // testWidget.redWidget->acceptTouchEnd = true; + testWidget.redWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.redWidget->seenTouchBegin); + QVERIFY(testWidget.redWidget->seenTouchUpdate); + QVERIFY(testWidget.redWidget->seenTouchEnd); + QVERIFY(testWidget.redWidget->touchPointCount > 1); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); + + testWidget.redWidget->reset(); + testWidget.redWidget->acceptTouchBegin = true; + // testWidget.redWidget->acceptTouchUpdate = true; + // testWidget.redWidget->acceptTouchEnd = true; + testWidget.redWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.redWidget->seenTouchBegin); + QVERIFY(testWidget.redWidget->seenTouchUpdate); + QVERIFY(testWidget.redWidget->seenTouchEnd); + QVERIFY(testWidget.redWidget->touchPointCount > 1); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); +} + +void tst_ManualMultitouch::acceptingTouchBeginStopsPropagation() +{ + // test that accepting the TouchBegin event on the + // blueWidget stops propagation to the greenWidget + MultitouchTestWidget testWidget; + testWidget.testNameLabel->setText("Touch Event Propagation Test: Accepting in Blue Blocks Green"); + testWidget.testDescriptionLabel->setText("Touch, hold, and release your finger on the blue widget."); + testWidget.redWidget->hide(); + testWidget.blueWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.greenWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.blueWidget->acceptTouchBegin = true; + testWidget.blueWidget->acceptTouchUpdate = true; + testWidget.blueWidget->acceptTouchEnd = true; + testWidget.blueWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.blueWidget->seenTouchBegin); + // QVERIFY(testWidget.blueWidget->seenTouchUpdate); + QVERIFY(testWidget.blueWidget->seenTouchEnd); + QVERIFY(!testWidget.blueWidget->seenMousePress); + QVERIFY(!testWidget.blueWidget->seenMouseMove); + QVERIFY(!testWidget.blueWidget->seenMouseRelease); + QVERIFY(!testWidget.greenWidget->seenTouchBegin); + QVERIFY(!testWidget.greenWidget->seenTouchUpdate); + QVERIFY(!testWidget.greenWidget->seenTouchEnd); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); + + // ignoring TouchEnd + testWidget.blueWidget->reset(); + testWidget.greenWidget->reset(); + testWidget.blueWidget->acceptTouchBegin = true; + testWidget.blueWidget->acceptTouchUpdate = true; + // testWidget.blueWidget->acceptTouchEnd = true; + testWidget.blueWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.blueWidget->seenTouchBegin); + // QVERIFY(testWidget.blueWidget->seenTouchUpdate); + QVERIFY(testWidget.blueWidget->seenTouchEnd); + QVERIFY(!testWidget.blueWidget->seenMousePress); + QVERIFY(!testWidget.blueWidget->seenMouseMove); + QVERIFY(!testWidget.blueWidget->seenMouseRelease); + QVERIFY(!testWidget.greenWidget->seenTouchBegin); + QVERIFY(!testWidget.greenWidget->seenTouchUpdate); + QVERIFY(!testWidget.greenWidget->seenTouchEnd); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); + + // ignoring TouchUpdate + testWidget.blueWidget->reset(); + testWidget.greenWidget->reset(); + testWidget.blueWidget->acceptTouchBegin = true; + // testWidget.blueWidget->acceptTouchUpdate = true; + testWidget.blueWidget->acceptTouchEnd = true; + testWidget.blueWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.blueWidget->seenTouchBegin); + // QVERIFY(testWidget.blueWidget->seenTouchUpdate); + QVERIFY(testWidget.blueWidget->seenTouchEnd); + QVERIFY(!testWidget.blueWidget->seenMousePress); + QVERIFY(!testWidget.blueWidget->seenMouseMove); + QVERIFY(!testWidget.blueWidget->seenMouseRelease); + QVERIFY(!testWidget.greenWidget->seenTouchBegin); + QVERIFY(!testWidget.greenWidget->seenTouchUpdate); + QVERIFY(!testWidget.greenWidget->seenTouchEnd); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); + + // ignoring TouchUpdate and TouchEnd + testWidget.blueWidget->reset(); + testWidget.greenWidget->reset(); + testWidget.blueWidget->acceptTouchBegin = true; + // testWidget.blueWidget->acceptTouchUpdate = true; + // testWidget.blueWidget->acceptTouchEnd = true; + testWidget.blueWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.blueWidget->seenTouchBegin); + // QVERIFY(testWidget.blueWidget->seenTouchUpdate); + QVERIFY(testWidget.blueWidget->seenTouchEnd); + QVERIFY(!testWidget.blueWidget->seenMousePress); + QVERIFY(!testWidget.blueWidget->seenMouseMove); + QVERIFY(!testWidget.blueWidget->seenMouseRelease); + QVERIFY(!testWidget.greenWidget->seenTouchBegin); + QVERIFY(!testWidget.greenWidget->seenTouchUpdate); + QVERIFY(!testWidget.greenWidget->seenTouchEnd); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); +} + +void tst_ManualMultitouch::ignoringTouchBeginPropagatesToParent() +{ + // repeat the test above, now ignoring touch events in the + // greyWidget, they should be propagated to the redWidget + MultitouchTestWidget testWidget; + testWidget.testNameLabel->setText("Touch Event Propagation Test: Ignoring in Grey Propagates to Red"); + testWidget.testDescriptionLabel->setText("Touch, hold, and release your finger on the grey widget."); + testWidget.greenWidget->hide(); + testWidget.greyWidget->setAttribute(Qt::WA_AcceptTouchEvents, false); + testWidget.redWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.greyWidget->reset(); + testWidget.redWidget->reset(); + testWidget.redWidget->acceptTouchBegin = true; + testWidget.redWidget->acceptTouchUpdate = true; + testWidget.redWidget->acceptTouchEnd = true; + testWidget.redWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(!testWidget.greyWidget->seenTouchBegin); + QVERIFY(!testWidget.greyWidget->seenTouchUpdate); + QVERIFY(!testWidget.greyWidget->seenTouchEnd); + QVERIFY(!testWidget.greyWidget->seenMousePress); + QVERIFY(!testWidget.greyWidget->seenMouseMove); + QVERIFY(!testWidget.greyWidget->seenMouseRelease); + QVERIFY(testWidget.redWidget->seenTouchBegin); + // QVERIFY(testWidget.redWidget->seenTouchUpdate); + QVERIFY(testWidget.redWidget->seenTouchEnd); + QVERIFY(!testWidget.redWidget->seenMousePress); + QVERIFY(!testWidget.redWidget->seenMouseMove); + QVERIFY(!testWidget.redWidget->seenMouseRelease); + + // again, but this time greyWidget should see the TouchBegin + testWidget.greyWidget->reset(); + testWidget.redWidget->reset(); + testWidget.greyWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.redWidget->acceptTouchBegin = true; + testWidget.redWidget->acceptTouchUpdate = true; + testWidget.redWidget->acceptTouchEnd = true; + testWidget.redWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.greyWidget->seenTouchBegin); + QVERIFY(!testWidget.greyWidget->seenTouchUpdate); + QVERIFY(!testWidget.greyWidget->seenTouchEnd); + QVERIFY(!testWidget.greyWidget->seenMousePress); + QVERIFY(!testWidget.greyWidget->seenMouseMove); + QVERIFY(!testWidget.greyWidget->seenMouseRelease); + QVERIFY(testWidget.redWidget->seenTouchBegin); + // QVERIFY(testWidget.redWidget->seenTouchUpdate); + QVERIFY(testWidget.redWidget->seenTouchEnd); + QVERIFY(!testWidget.redWidget->seenMousePress); + QVERIFY(!testWidget.redWidget->seenMouseMove); + QVERIFY(!testWidget.redWidget->seenMouseRelease); + + // again, ignoring the TouchEnd + testWidget.greyWidget->reset(); + testWidget.redWidget->reset(); + testWidget.redWidget->acceptTouchBegin = true; + testWidget.redWidget->acceptTouchUpdate = true; + // testWidget.redWidget->acceptTouchEnd = true; + testWidget.redWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.greyWidget->seenTouchBegin); + QVERIFY(!testWidget.greyWidget->seenTouchUpdate); + QVERIFY(!testWidget.greyWidget->seenTouchEnd); + QVERIFY(!testWidget.greyWidget->seenMousePress); + QVERIFY(!testWidget.greyWidget->seenMouseMove); + QVERIFY(!testWidget.greyWidget->seenMouseRelease); + QVERIFY(testWidget.redWidget->seenTouchBegin); + // QVERIFY(testWidget.redWidget->seenTouchUpdate); + QVERIFY(testWidget.redWidget->seenTouchEnd); + QVERIFY(!testWidget.redWidget->seenMousePress); + QVERIFY(!testWidget.redWidget->seenMouseMove); + QVERIFY(!testWidget.redWidget->seenMouseRelease); + + // again, ignoring TouchUpdates + testWidget.greyWidget->reset(); + testWidget.redWidget->reset(); + testWidget.redWidget->acceptTouchBegin = true; + // testWidget.redWidget->acceptTouchUpdate = true; + testWidget.redWidget->acceptTouchEnd = true; + testWidget.redWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.greyWidget->seenTouchBegin); + QVERIFY(!testWidget.greyWidget->seenTouchUpdate); + QVERIFY(!testWidget.greyWidget->seenTouchEnd); + QVERIFY(!testWidget.greyWidget->seenMousePress); + QVERIFY(!testWidget.greyWidget->seenMouseMove); + QVERIFY(!testWidget.greyWidget->seenMouseRelease); + QVERIFY(testWidget.redWidget->seenTouchBegin); + // QVERIFY(testWidget.redWidget->seenTouchUpdate); + QVERIFY(testWidget.redWidget->seenTouchEnd); + QVERIFY(!testWidget.redWidget->seenMousePress); + QVERIFY(!testWidget.redWidget->seenMouseMove); + QVERIFY(!testWidget.redWidget->seenMouseRelease); + + // last time, ignoring TouchUpdates and TouchEnd + testWidget.greyWidget->reset(); + testWidget.redWidget->reset(); + testWidget.redWidget->acceptTouchBegin = true; + // testWidget.redWidget->acceptTouchUpdate = true; + // testWidget.redWidget->acceptTouchEnd = true; + testWidget.redWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.greyWidget->seenTouchBegin); + QVERIFY(!testWidget.greyWidget->seenTouchUpdate); + QVERIFY(!testWidget.greyWidget->seenTouchEnd); + QVERIFY(!testWidget.greyWidget->seenMousePress); + QVERIFY(!testWidget.greyWidget->seenMouseMove); + QVERIFY(!testWidget.blueWidget->seenMouseRelease); + QVERIFY(testWidget.redWidget->seenTouchBegin); + // QVERIFY(testWidget.redWidget->seenTouchUpdate); + QVERIFY(testWidget.redWidget->seenTouchEnd); + QVERIFY(!testWidget.redWidget->seenMousePress); + QVERIFY(!testWidget.redWidget->seenMouseMove); + QVERIFY(!testWidget.redWidget->seenMouseRelease); +} + +void tst_ManualMultitouch::secondTouchPointOnParentGoesToChild() +{ + MultitouchTestWidget testWidget; + testWidget.testNameLabel->setText("Additional Touch-Points Outside Child's Rect Go to Child"); + testWidget.testDescriptionLabel->setText("Press and hold a finger on the blue widget, then on the green one, and release."); + testWidget.redWidget->hide(); + testWidget.greenWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.blueWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.blueWidget->acceptTouchBegin = true; + testWidget.greenWidget->acceptTouchBegin = true; + testWidget.blueWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.blueWidget->seenTouchBegin); + // QVERIFY(testWidget.blueWidget->seenTouchUpdate); + QVERIFY(testWidget.blueWidget->seenTouchEnd); + QVERIFY(!testWidget.blueWidget->seenMousePress); + QVERIFY(!testWidget.blueWidget->seenMouseMove); + QVERIFY(!testWidget.blueWidget->seenMouseRelease); + QVERIFY(testWidget.blueWidget->touchPointCount > 1); + QVERIFY(!testWidget.greenWidget->seenTouchBegin); + QVERIFY(!testWidget.greenWidget->seenTouchUpdate); + QVERIFY(!testWidget.greenWidget->seenTouchEnd); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); +} + +void tst_ManualMultitouch::secondTouchPointOnChildGoesToParent() +{ + MultitouchTestWidget testWidget; + testWidget.testNameLabel->setText("Additional Touch-Points Over Child's Rect Go to Parent"); + testWidget.testDescriptionLabel->setText("Press and hold a finger on the red widget, then on the grey one, and release."); + testWidget.greenWidget->hide(); + testWidget.redWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.greyWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.greyWidget->acceptTouchBegin = true; + testWidget.redWidget->acceptTouchBegin = true; + testWidget.redWidget->closeWindowOnTouchEnd = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.redWidget->seenTouchBegin); + // QVERIFY(testWidget.redWidget->seenTouchUpdate); + QVERIFY(testWidget.redWidget->seenTouchEnd); + QVERIFY(!testWidget.redWidget->seenMousePress); + QVERIFY(!testWidget.redWidget->seenMouseMove); + QVERIFY(!testWidget.redWidget->seenMouseRelease); + QVERIFY(testWidget.redWidget->touchPointCount > 1); + QVERIFY(!testWidget.greyWidget->seenTouchBegin); + QVERIFY(!testWidget.greyWidget->seenTouchUpdate); + QVERIFY(!testWidget.greyWidget->seenTouchEnd); + QVERIFY(!testWidget.greyWidget->seenMousePress); + QVERIFY(!testWidget.greyWidget->seenMouseMove); + QVERIFY(!testWidget.greyWidget->seenMouseRelease); +} + +void tst_ManualMultitouch::secondTouchPointOnSiblingGoesToSibling() +{ + MultitouchTestWidget testWidget; + testWidget.testNameLabel->setText("Multi-Touch Interaction Test, Unrelated Widgets Get Separate Events"); + testWidget.testDescriptionLabel->setText("Press and hold a finger on the green widget, then the red one, and release."); + testWidget.blueWidget->hide(); + testWidget.greenWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.greenWidget->acceptTouchBegin = true; + testWidget.greenWidget->closeWindowOnTouchEnd = true; + testWidget.greyWidget->hide(); + testWidget.redWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.redWidget->acceptTouchBegin = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.greenWidget->seenTouchBegin); + // QVERIFY(testWidget.greenWidget->seenTouchUpdate); + QVERIFY(testWidget.greenWidget->seenTouchEnd); + QVERIFY(!testWidget.greenWidget->seenMousePress); + QVERIFY(!testWidget.greenWidget->seenMouseMove); + QVERIFY(!testWidget.greenWidget->seenMouseRelease); + QVERIFY(testWidget.redWidget->seenTouchBegin); + // QVERIFY(testWidget.redWidget->seenTouchUpdate); + QVERIFY(testWidget.redWidget->seenTouchEnd); + QVERIFY(!testWidget.redWidget->seenMousePress); + QVERIFY(!testWidget.redWidget->seenMouseMove); + QVERIFY(!testWidget.redWidget->seenMouseRelease); + QVERIFY(testWidget.greenWidget->touchPointCount == 1); + QVERIFY(testWidget.redWidget->touchPointCount == 1); +} + +void tst_ManualMultitouch::secondTouchPointOnCousinGoesToCousin() +{ + MultitouchTestWidget testWidget; + testWidget.testNameLabel->setText("Multi-Touch Interaction Test, Unrelated Widgets Get Separate Events"); + testWidget.testDescriptionLabel->setText("Press and hold a finger on the blue widget, then the grey one, and release."); + testWidget.blueWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.blueWidget->acceptTouchBegin = true; + testWidget.blueWidget->closeWindowOnTouchEnd = true; + testWidget.greyWidget->setAttribute(Qt::WA_AcceptTouchEvents); + testWidget.greyWidget->acceptTouchBegin = true; + testWidget.showMaximized(); + (void) qApp->exec(); + QVERIFY(testWidget.blueWidget->seenTouchBegin); + // QVERIFY(testWidget.blueWidget->seenTouchUpdate); + QVERIFY(testWidget.blueWidget->seenTouchEnd); + QVERIFY(!testWidget.blueWidget->seenMousePress); + QVERIFY(!testWidget.blueWidget->seenMouseMove); + QVERIFY(!testWidget.blueWidget->seenMouseRelease); + QVERIFY(testWidget.greyWidget->seenTouchBegin); + // QVERIFY(testWidget.greyWidget->seenTouchUpdate); + QVERIFY(testWidget.greyWidget->seenTouchEnd); + QVERIFY(!testWidget.greyWidget->seenMousePress); + QVERIFY(!testWidget.greyWidget->seenMouseMove); + QVERIFY(!testWidget.greyWidget->seenMouseRelease); + QVERIFY(testWidget.blueWidget->touchPointCount == 1); + QVERIFY(testWidget.greyWidget->touchPointCount == 1); +} + +QTEST_MAIN(tst_ManualMultitouch) + +#include "main.moc" diff --git a/tests/manual/qtouchevent/multitouch.pro b/tests/manual/qtouchevent/multitouch.pro new file mode 100644 index 0000000..de1ee06 --- /dev/null +++ b/tests/manual/qtouchevent/multitouch.pro @@ -0,0 +1,5 @@ +QT += testlib +SOURCES = main.cpp \ + touchwidget.cpp +FORMS += form.ui +HEADERS += touchwidget.h diff --git a/tests/manual/qtouchevent/touchwidget.cpp b/tests/manual/qtouchevent/touchwidget.cpp new file mode 100644 index 0000000..a8141cc --- /dev/null +++ b/tests/manual/qtouchevent/touchwidget.cpp @@ -0,0 +1,94 @@ +#include "touchwidget.h" + +#include <QApplication> +#include <QtEvents> +#include <QTimer> +#include <QTouchEvent> + +void TouchWidget::reset() +{ + acceptTouchBegin + = acceptTouchUpdate + = acceptTouchEnd + = seenTouchBegin + = seenTouchUpdate + = seenTouchEnd + = closeWindowOnTouchEnd + + = acceptMousePress + = acceptMouseMove + = acceptMouseRelease + = seenMousePress + = seenMouseMove + = seenMouseRelease + = closeWindowOnMouseRelease + + = false; + touchPointCount = 0; +} + +bool TouchWidget::event(QEvent *event) +{ + switch (event->type()) { + case QEvent::TouchBegin: + if (seenTouchBegin) qWarning("TouchBegin: already seen a TouchBegin"); + if (seenTouchUpdate) qWarning("TouchBegin: TouchUpdate cannot happen before TouchBegin"); + if (seenTouchEnd) qWarning("TouchBegin: TouchEnd cannot happen before TouchBegin"); + seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd; + touchPointCount = qMax(touchPointCount, static_cast<QTouchEvent *>(event)->touchPoints().count()); + if (acceptTouchBegin) { + event->accept(); + return true; + } + break; + case QEvent::TouchUpdate: + if (!seenTouchBegin) qWarning("TouchUpdate: have not seen TouchBegin"); + if (seenTouchEnd) qWarning("TouchUpdate: TouchEnd cannot happen before TouchUpdate"); + seenTouchUpdate = seenTouchBegin && !seenTouchEnd; + touchPointCount = qMax(touchPointCount, static_cast<QTouchEvent *>(event)->touchPoints().count()); + if (acceptTouchUpdate) { + event->accept(); + return true; + } + break; + case QEvent::TouchEnd: + if (!seenTouchBegin) qWarning("TouchEnd: have not seen TouchBegin"); + if (seenTouchEnd) qWarning("TouchEnd: already seen a TouchEnd"); + seenTouchEnd = seenTouchBegin && !seenTouchEnd; + touchPointCount = qMax(touchPointCount, static_cast<QTouchEvent *>(event)->touchPoints().count()); + if (closeWindowOnTouchEnd) + window()->close(); + if (acceptTouchEnd) { + event->accept(); + return true; + } + break; + case QEvent::MouseButtonPress: + case QEvent::MouseButtonDblClick: + seenMousePress = true; + if (acceptMousePress) { + event->accept(); + return true; + } + break; + case QEvent::MouseMove: + seenMouseMove = true; + if (acceptMouseMove) { + event->accept(); + return true; + } + break; + case QEvent::MouseButtonRelease: + seenMouseRelease = true; + if (closeWindowOnMouseRelease) + window()->close(); + if (acceptMouseRelease) { + event->accept(); + return true; + } + break; + default: + break; + } + return QWidget::event(event); +} diff --git a/tests/manual/qtouchevent/touchwidget.h b/tests/manual/qtouchevent/touchwidget.h new file mode 100644 index 0000000..2726deb --- /dev/null +++ b/tests/manual/qtouchevent/touchwidget.h @@ -0,0 +1,31 @@ +#ifndef TOUCHWIDGET_H +#define TOUCHWIDGET_H + +#include <QWidget> + +class TouchWidget : public QWidget +{ + Q_OBJECT + +public: + bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd; + bool seenTouchBegin, seenTouchUpdate, seenTouchEnd; + bool closeWindowOnTouchEnd; + int touchPointCount; + + bool acceptMousePress, acceptMouseMove, acceptMouseRelease; + bool seenMousePress, seenMouseMove, seenMouseRelease; + bool closeWindowOnMouseRelease; + + inline TouchWidget(QWidget *parent = 0) + : QWidget(parent) + { + reset(); + } + + void reset(); + + bool event(QEvent *event); +}; + +#endif // TOUCHWIDGET_H |