aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brasser <michael.brasser@nokia.com>2011-08-23 13:30:38 +1000
committerQt by Nokia <qt-info@nokia.com>2011-10-25 06:06:14 +0200
commit1d445eb5b1a14da342382a088f4e1cc5492ea32e (patch)
tree6e53b89f8d944b9b4b269c1bc4eeee09e3f2ac6f /src
parentcae9402e7bda876e83aa0d5ef4ba0f4ee0d0eca0 (diff)
Add MultiPointTouchArea element.
Change-Id: I3a4f774cd96ab7f5d08e85c965f59e1416f02e0e Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/declarative/items/items.pri2
-rw-r--r--src/declarative/items/qquickcanvas.cpp17
-rw-r--r--src/declarative/items/qquickcanvas_p.h2
-rw-r--r--src/declarative/items/qquickitem.cpp95
-rw-r--r--src/declarative/items/qquickitem.h6
-rw-r--r--src/declarative/items/qquickitem_p.h2
-rw-r--r--src/declarative/items/qquickitemsmodule.cpp5
-rw-r--r--src/declarative/items/qquickmultipointtoucharea.cpp729
-rw-r--r--src/declarative/items/qquickmultipointtoucharea_p.h267
9 files changed, 1114 insertions, 11 deletions
diff --git a/src/declarative/items/items.pri b/src/declarative/items/items.pri
index c3d6a2ab73..f83c65c203 100644
--- a/src/declarative/items/items.pri
+++ b/src/declarative/items/items.pri
@@ -64,6 +64,7 @@ HEADERS += \
$$PWD/qquickspriteimage_p.h \
$$PWD/qquickdrag_p.h \
$$PWD/qquickdroparea_p.h \
+ $$PWD/qquickmultipointtoucharea_p.h \
$$PWD/qquickitemview_p.h \
$$PWD/qquickitemview_p_p.h
@@ -110,6 +111,7 @@ SOURCES += \
$$PWD/qquickspriteimage.cpp \
$$PWD/qquickdrag.cpp \
$$PWD/qquickdroparea.cpp \
+ $$PWD/qquickmultipointtoucharea.cpp \
$$PWD/qquickitemview.cpp
SOURCES += \
diff --git a/src/declarative/items/qquickcanvas.cpp b/src/declarative/items/qquickcanvas.cpp
index 52ef421213..6df0c65c94 100644
--- a/src/declarative/items/qquickcanvas.cpp
+++ b/src/declarative/items/qquickcanvas.cpp
@@ -1496,7 +1496,7 @@ bool QQuickCanvasPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickIte
return accepted;
}
-bool QQuickCanvasPrivate::sendFilteredMouseEvent(QQuickItem *target, QQuickItem *item, QMouseEvent *event)
+bool QQuickCanvasPrivate::sendFilteredMouseEvent(QQuickItem *target, QQuickItem *item, QEvent *event)
{
if (!target)
return false;
@@ -1550,12 +1550,9 @@ bool QQuickCanvas::sendEvent(QQuickItem *item, QEvent *e)
case QEvent::MouseButtonDblClick:
case QEvent::MouseMove:
// XXX todo - should sendEvent be doing this? how does it relate to forwarded events?
- {
- QMouseEvent *se = static_cast<QMouseEvent *>(e);
- if (!d->sendFilteredMouseEvent(item->parentItem(), item, se)) {
- se->accept();
- QQuickItemPrivate::get(item)->deliverMouseEvent(se);
- }
+ if (!d->sendFilteredMouseEvent(item->parentItem(), item, e)) {
+ e->accept();
+ QQuickItemPrivate::get(item)->deliverMouseEvent(static_cast<QMouseEvent *>(e));
}
break;
case QEvent::Wheel:
@@ -1569,7 +1566,11 @@ bool QQuickCanvas::sendEvent(QQuickItem *item, QEvent *e)
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
- QQuickItemPrivate::get(item)->deliverTouchEvent(static_cast<QTouchEvent *>(e));
+ // XXX todo - should sendEvent be doing this? how does it relate to forwarded events?
+ if (!d->sendFilteredMouseEvent(item->parentItem(), item, e)) {
+ e->accept();
+ QQuickItemPrivate::get(item)->deliverTouchEvent(static_cast<QTouchEvent *>(e));
+ }
break;
case QEvent::DragEnter:
case QEvent::DragMove:
diff --git a/src/declarative/items/qquickcanvas_p.h b/src/declarative/items/qquickcanvas_p.h
index 5c68442f29..610ebe7912 100644
--- a/src/declarative/items/qquickcanvas_p.h
+++ b/src/declarative/items/qquickcanvas_p.h
@@ -110,7 +110,7 @@ public:
static void transformTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints, const QTransform &transform);
bool deliverInitialMousePressEvent(QQuickItem *, QMouseEvent *);
bool deliverMouseEvent(QMouseEvent *);
- bool sendFilteredMouseEvent(QQuickItem *, QQuickItem *, QMouseEvent *);
+ bool sendFilteredMouseEvent(QQuickItem *, QQuickItem *, QEvent *);
bool deliverWheelEvent(QQuickItem *, QWheelEvent *);
bool deliverTouchPoints(QQuickItem *, QTouchEvent *, const QList<QTouchEvent::TouchPoint> &, QSet<int> *,
QHash<QQuickItem *, QList<QTouchEvent::TouchPoint> > *);
diff --git a/src/declarative/items/qquickitem.cpp b/src/declarative/items/qquickitem.cpp
index b6951d9a77..f50a4f1a91 100644
--- a/src/declarative/items/qquickitem.cpp
+++ b/src/declarative/items/qquickitem.cpp
@@ -2185,7 +2185,7 @@ QQuickItemPrivate::QQuickItemPrivate()
: _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QQuickItem::Center),
flags(0), widthValid(false), heightValid(false), componentComplete(true),
- keepMouse(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
+ keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
@@ -2856,6 +2856,11 @@ void QQuickItem::mouseUngrabEvent()
// XXX todo
}
+void QQuickItem::touchUngrabEvent()
+{
+ // XXX todo
+}
+
void QQuickItem::wheelEvent(QWheelEvent *event)
{
event->ignore();
@@ -4529,6 +4534,94 @@ void QQuickItem::setKeepMouseGrab(bool keep)
}
/*!
+ Grabs the touch points specified by \a ids.
+
+ These touch points will be owned by the item until
+ they are released. Alternatively, the grab can be stolen
+ by a filtering item like Flickable. Use setKeepTouchGrab()
+ to prevent the grab from being stolen.
+
+ \sa ungrabTouchPoints(), setKeepTouchGrab()
+*/
+void QQuickItem::grabTouchPoints(const QList<int> &ids)
+{
+ Q_D(QQuickItem);
+ if (!d->canvas)
+ return;
+ QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
+
+ QSet<QQuickItem*> ungrab;
+ for (int i = 0; i < ids.count(); ++i) {
+ QQuickItem *oldGrabber = canvasPriv->itemForTouchPointId.value(ids.at(i));
+ if (oldGrabber == this)
+ return;
+
+ canvasPriv->itemForTouchPointId[ids.at(i)] = this;
+ if (oldGrabber)
+ ungrab.insert(oldGrabber);
+ }
+ foreach (QQuickItem *oldGrabber, ungrab)
+ oldGrabber->touchUngrabEvent();
+}
+
+/*!
+ Ungrabs the touch points owned by this item.
+
+ \sa grabTouchPoints()
+*/
+void QQuickItem::ungrabTouchPoints()
+{
+ Q_D(QQuickItem);
+ if (!d->canvas)
+ return;
+ QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(d->canvas);
+
+ QMutableHashIterator<int, QQuickItem*> i(canvasPriv->itemForTouchPointId);
+ while (i.hasNext()) {
+ i.next();
+ if (i.value() == this)
+ i.remove();
+ }
+ touchUngrabEvent();
+}
+
+/*!
+ Returns a value indicating whether the touch points grabbed by this item
+ should remain with this item exclusively.
+
+ \sa setKeepTouchGrab(), keepMouseGrab()
+*/
+bool QQuickItem::keepTouchGrab() const
+{
+ Q_D(const QQuickItem);
+ return d->keepTouch;
+}
+
+/*!
+ The flag indicating whether the touch points grabbed
+ by this item should remain with this item is set to \a keep.
+
+ This is useful for items that wish to grab and keep specific touch
+ points following a predefined gesture. For example,
+ an item that is interested in horizontal touch point movement
+ may set setKeepTouchGrab to true once a threshold has been
+ exceeded. Once setKeepTouchGrab has been set to true, filtering
+ items will not react to the relevant touch points.
+
+ If the item does not indicate that it wishes to retain touch point grab,
+ a filtering item may steal the grab. For example, Flickable may attempt
+ to steal a touch point grab if it detects that the user has begun to
+ move the viewport.
+
+ \sa keepTouchGrab(), setKeepMouseGrab()
+ */
+void QQuickItem::setKeepTouchGrab(bool keep)
+{
+ Q_D(QQuickItem);
+ d->keepTouch = keep;
+}
+
+/*!
\qmlmethod object QtQuick2::Item::mapFromItem(Item item, real x, real y)
Maps the point (\a x, \a y), which is in \a item's coordinate system, to
diff --git a/src/declarative/items/qquickitem.h b/src/declarative/items/qquickitem.h
index be50677bf1..0cbcfb890d 100644
--- a/src/declarative/items/qquickitem.h
+++ b/src/declarative/items/qquickitem.h
@@ -282,6 +282,11 @@ public:
bool filtersChildMouseEvents() const;
void setFiltersChildMouseEvents(bool filter);
+ void grabTouchPoints(const QList<int> &ids);
+ void ungrabTouchPoints();
+ bool keepTouchGrab() const;
+ void setKeepTouchGrab(bool);
+
QTransform itemTransform(QQuickItem *, bool *) const;
QPointF mapToItem(const QQuickItem *item, const QPointF &point) const;
QPointF mapToScene(const QPointF &point) const;
@@ -368,6 +373,7 @@ protected:
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void mouseDoubleClickEvent(QMouseEvent *event);
virtual void mouseUngrabEvent(); // XXX todo - params?
+ virtual void touchUngrabEvent();
virtual void wheelEvent(QWheelEvent *event);
virtual void touchEvent(QTouchEvent *event);
virtual void hoverEnterEvent(QHoverEvent *event);
diff --git a/src/declarative/items/qquickitem_p.h b/src/declarative/items/qquickitem_p.h
index 94b195f2d8..47f86c48aa 100644
--- a/src/declarative/items/qquickitem_p.h
+++ b/src/declarative/items/qquickitem_p.h
@@ -237,6 +237,7 @@ public:
bool heightValid:1;
bool componentComplete:1;
bool keepMouse:1;
+ bool keepTouch:1;
bool hoverEnabled:1;
bool smooth:1;
bool focus:1;
@@ -255,7 +256,6 @@ public:
bool inheritMirrorFromParent:1;
bool inheritMirrorFromItem:1;
bool childrenDoNotOverlap:1;
- quint32 dummy:1;
QQuickCanvas *canvas;
QSGContext *sceneGraphContext() const { Q_ASSERT(canvas); return static_cast<QQuickCanvasPrivate *>(QObjectPrivate::get(canvas))->context; }
diff --git a/src/declarative/items/qquickitemsmodule.cpp b/src/declarative/items/qquickitemsmodule.cpp
index 38b5a91e56..0a04e884ae 100644
--- a/src/declarative/items/qquickitemsmodule.cpp
+++ b/src/declarative/items/qquickitemsmodule.cpp
@@ -80,6 +80,7 @@
#include "qquickspriteimage_p.h"
#include "qquickdrag_p.h"
#include "qquickdroparea_p.h"
+#include "qquickmultipointtoucharea_p.h"
static QDeclarativePrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject *parent)
{
@@ -201,6 +202,10 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickDropEvent>();
qmlRegisterType<QQuickDropAreaDrag>();
qmlRegisterUncreatableType<QQuickDrag>("QtQuick", 2, 0, "Drag", QQuickDragAttached::tr("Drag is only available via attached properties"));
+
+ qmlRegisterType<QQuickMultiPointTouchArea>("QtQuick", 2, 0, "MultiPointTouchArea");
+ qmlRegisterType<QQuickTouchPoint>("QtQuick", 2, 0, "TouchPoint");
+ qmlRegisterType<QQuickGrabGestureEvent>();
}
void QQuickItemsModule::defineModule()
diff --git a/src/declarative/items/qquickmultipointtoucharea.cpp b/src/declarative/items/qquickmultipointtoucharea.cpp
new file mode 100644
index 0000000000..f7fdf97fb7
--- /dev/null
+++ b/src/declarative/items/qquickmultipointtoucharea.cpp
@@ -0,0 +1,729 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickmultipointtoucharea_p.h"
+#include <qquickcanvas.h>
+#include <QEvent>
+#include <QMouseEvent>
+#include <math.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmlclass TouchPoint QQuickTouchPoint
+ \inqmlmodule QtQuick 2
+ \ingroup qml-event-elements
+ \brief The TouchPoint element describes a touch point in a MultiPointTouchArea.
+
+ The TouchPoint element contains information about a touch point, such as the current
+ position, pressure, and area.
+*/
+
+/*!
+ \qmlproperty int QtQuick2::TouchPoint::pointId
+
+ This property holds the point id of the touch point.
+
+ Each touch point within a MultiPointTouchArea will have a unique id.
+*/
+void QQuickTouchPoint::setPointId(int id)
+{
+ if (_id == id)
+ return;
+ _id = id;
+ emit pointIdChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick2::TouchPoint::x
+ \qmlproperty real QtQuick2::TouchPoint::y
+
+ These properties hold the current position of the touch point.
+*/
+
+void QQuickTouchPoint::setX(qreal x)
+{
+ if (_x == x)
+ return;
+ _x = x;
+ emit xChanged();
+}
+
+void QQuickTouchPoint::setY(qreal y)
+{
+ if (_y == y)
+ return;
+ _y = y;
+ emit yChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick2::TouchPoint::pressure
+ \qmlproperty rectangle QtQuick2::TouchPoint::area
+
+ These properties hold additional information about the current state of the touch point.
+
+ \list
+ \i \c pressure is a value in the range of 0.0 to 1.0.
+ \i \c area is a rectangle covering the area of the touch point, centered on the current position of the touch point.
+ \endlist
+*/
+void QQuickTouchPoint::setPressure(qreal pressure)
+{
+ if (_pressure == pressure)
+ return;
+ _pressure = pressure;
+ emit pressureChanged();
+}
+
+void QQuickTouchPoint::setArea(const QRectF &area)
+{
+ if (_area == area)
+ return;
+ _area = area;
+ emit areaChanged();
+}
+
+/*!
+ \qmlproperty bool QtQuick2::TouchPoint::valid
+
+ This property holds whether the touch point is valid.
+
+ An invalid touch point is one that has not yet been pressed,
+ or has already been released.
+*/
+void QQuickTouchPoint::setValid(bool valid)
+{
+ if (_valid == valid)
+ return;
+ _valid = valid;
+ emit validityChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick2::TouchPoint::startX
+ \qmlproperty real QtQuick2::TouchPoint::startY
+
+ These properties hold the starting position of the touch point.
+*/
+
+void QQuickTouchPoint::setStartX(qreal startX)
+{
+ if (_startX == startX)
+ return;
+ _startX = startX;
+ emit startXChanged();
+}
+
+void QQuickTouchPoint::setStartY(qreal startY)
+{
+ if (_startY == startY)
+ return;
+ _startY = startY;
+ emit startYChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick2::TouchPoint::previousX
+ \qmlproperty real QtQuick2::TouchPoint::previousY
+
+ These properties hold the previous position of the touch point.
+*/
+void QQuickTouchPoint::setPreviousX(qreal previousX)
+{
+ if (_previousX == previousX)
+ return;
+ _previousX = previousX;
+ emit previousXChanged();
+}
+
+void QQuickTouchPoint::setPreviousY(qreal previousY)
+{
+ if (_previousY == previousY)
+ return;
+ _previousY = previousY;
+ emit previousYChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick2::TouchPoint::sceneX
+ \qmlproperty real QtQuick2::TouchPoint::sceneY
+
+ These properties hold the current position of the touch point in scene coordinates.
+*/
+
+void QQuickTouchPoint::setSceneX(qreal sceneX)
+{
+ if (_sceneX == sceneX)
+ return;
+ _sceneX = sceneX;
+ emit sceneXChanged();
+}
+
+void QQuickTouchPoint::setSceneY(qreal sceneY)
+{
+ if (_sceneY == sceneY)
+ return;
+ _sceneY = sceneY;
+ emit sceneYChanged();
+}
+
+/*!
+ \qmlclass MultiPointTouchArea QQuickMultiPointTouchArea
+ \inqmlmodule QtQuick 2
+ \brief The MultiPointTouchArea item enables handling of multiple touch points.
+ \inherits Item
+
+ A MultiPointTouchArea is an invisible item that is used to track multiple touch points.
+
+ The \l enabled property is used to enable and disable touch handling. When disabled,
+ the touch area becomes transparent to mouse/touch events.
+
+ MultiPointTouchArea can be used in two ways:
+
+ \list
+ \o setting \c touchPoints to provide touch point objects with properties that can be bound to
+ \o using the onTouchUpdated or onTouchPointsPressed, onTouchPointsUpdated and onTouchPointsReleased handlers
+ \endlist
+
+ While a MultiPointTouchArea \i can take exclusive ownership of certain touch points, it is also possible to have
+ multiple MultiPointTouchAreas active at the same time, each operating on a different set of touch points.
+
+ \sa TouchPoint
+*/
+
+/*!
+ \qmlsignal QtQuick2::MultiPointTouchArea::touchPointsPressed(list<TouchPoint> touchPoints)
+
+ This handler is called when new touch points are added. \a touchPoints is a list of these new points.
+
+ If minimumTouchPoints is set to a value greater than one, this handler will not be called until the minimum number
+ of required touch points has been reached. At that point, touchPointsPressed will be called with all the current touch points.
+*/
+
+/*!
+ \qmlsignal QtQuick2::MultiPointTouchArea::touchPointsUpdated(list<TouchPoint> touchPoints)
+
+ This handler is called when existing touch points are updated. \a touchPoints is a list of these updated points.
+*/
+
+/*!
+ \qmlsignal QtQuick2::MultiPointTouchArea::touchPointsReleased(list<TouchPoint> touchPoints)
+
+ This handler is called when existing touch points are removed. \a touchPoints is a list of these removed points.
+*/
+
+/*!
+ \qmlsignal QtQuick2::MultiPointTouchArea::touchPointsCanceled(list<TouchPoint> touchPoints)
+
+ This handler is called when new touch events have been canceled because another element stole the touch event handling.
+
+ This signal is for advanced use: it is useful when there is more than one MultiPointTouchArea
+ that is handling input, or when there is a MultiPointTouchArea inside a \l Flickable. In the latter
+ case, if you execute some logic on the touchPointsPressed signal and then start dragging, the
+ \l Flickable may steal the touch handling from the MultiPointTouchArea. In these cases, to reset
+ the logic when the MultiPointTouchArea has lost the touch handling to the \l Flickable,
+ \c onTouchPointsCanceled should be used in addition to onTouchPointsReleased.
+
+ \a touchPoints is the list of canceled points.
+*/
+
+/*!
+ \qmlsignal QtQuick2::MultiPointTouchArea::gestureStarted(GestureEvent gesture)
+
+ This handler is called when the global drag threshold has been reached.
+
+ This function is typically used when a MultiPointTouchAreas has been nested in a Flickable or another MultiPointTouchArea.
+ Wnen the threshold has been reached, and the handler called, you can determine whether or not the touch
+ area should grab the current touch points. By default they will not be grabbed; to grab them call \c gesture.grab(). If the
+ gesture is not grabbed, the nesting Flickable, for example, would also have an opportunity to grab.
+
+ The gesture object also includes information on the current set of \c touchPoints and the \c dragThreshold.
+*/
+
+/*!
+ \qmlsignal QtQuick2::MultiPointTouchArea::touchUpdated(list<TouchPoint> touchPoints)
+
+ This handler is called when the touch points handled by the MultiPointTouchArea change. This includes adding new touch points,
+ removing previous touch points, as well as updating current touch point data. \a touchPoints is the list of all current touch
+ points.
+*/
+
+/*!
+ \qmlproperty list<TouchPoint> QtQuick2::MultiPointTouchArea::touchPoints
+
+ This property holds a set of user-defined touch point objects that can be bound to.
+
+ In the following example, we have two small rectangles that follow our touch points.
+
+ \snippet doc/src/snippets/declarative/multipointtoucharea/multipointtoucharea.qml 0
+
+ By default this property holds an empty list.
+
+ \sa TouchPoint
+*/
+
+QQuickMultiPointTouchArea::QQuickMultiPointTouchArea(QQuickItem *parent)
+ : QQuickItem(parent),
+ _minimumTouchPoints(0),
+ _maximumTouchPoints(INT_MAX),
+ _stealMouse(false)
+{
+ setAcceptedMouseButtons(Qt::LeftButton);
+ setFiltersChildMouseEvents(true);
+}
+
+QQuickMultiPointTouchArea::~QQuickMultiPointTouchArea()
+{
+ clearTouchLists();
+ foreach (QObject *obj, _touchPoints) {
+ QQuickTouchPoint *dtp = static_cast<QQuickTouchPoint*>(obj);
+ if (!dtp->isQmlDefined())
+ delete dtp;
+ }
+}
+
+/*!
+ \qmlproperty int QtQuick2::MultiPointTouchArea::minimumTouchPoints
+ \qmlproperty int QtQuick2::MultiPointTouchArea::maximumTouchPoints
+
+ These properties hold the range of touch points to be handled by the touch area.
+
+ These are convenience that allow you to, for example, have nested MultiPointTouchAreas,
+ one handling two finger touches, and another handling three finger touches.
+
+ By default, all touch points within the touch area are handled.
+*/
+
+int QQuickMultiPointTouchArea::minimumTouchPoints() const
+{
+ return _minimumTouchPoints;
+}
+
+void QQuickMultiPointTouchArea::setMinimumTouchPoints(int num)
+{
+ if (_minimumTouchPoints == num)
+ return;
+ _minimumTouchPoints = num;
+ emit minimumTouchPointsChanged();
+}
+
+int QQuickMultiPointTouchArea::maximumTouchPoints() const
+{
+ return _maximumTouchPoints;
+}
+
+void QQuickMultiPointTouchArea::setMaximumTouchPoints(int num)
+{
+ if (_maximumTouchPoints == num)
+ return;
+ _maximumTouchPoints = num;
+ emit maximumTouchPointsChanged();
+}
+
+void QQuickMultiPointTouchArea::touchEvent(QTouchEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd: {
+ //if e.g. a parent Flickable has the mouse grab, don't process the touch events
+ QQuickCanvas *c = canvas();
+ QQuickItem *grabber = c ? c->mouseGrabberItem() : 0;
+ if (grabber && grabber != this && grabber->keepMouseGrab() && grabber->isEnabled()) {
+ QQuickItem *item = this;
+ while ((item = item->parentItem())) {
+ if (item == grabber)
+ return;
+ }
+ }
+ updateTouchData(event);
+ if (event->type() == QEvent::TouchEnd) {
+ //TODO: move to canvas
+ _stealMouse = false;
+ setKeepMouseGrab(false);
+ QQuickCanvas *c = canvas();
+ if (c && c->mouseGrabberItem() == this)
+ ungrabMouse();
+ setKeepTouchGrab(false);
+ ungrabTouchPoints();
+ }
+ break;
+ }
+ default:
+ QQuickItem::touchEvent(event);
+ break;
+ }
+}
+
+void QQuickMultiPointTouchArea::grabGesture()
+{
+ _stealMouse = true;
+
+ grabMouse();
+ setKeepMouseGrab(true);
+
+ grabTouchPoints(_touchPoints.keys());
+ setKeepTouchGrab(true);
+}
+
+void QQuickMultiPointTouchArea::updateTouchData(QEvent *event)
+{
+ bool ended = false;
+ bool moved = false;
+ bool started = false;
+
+ clearTouchLists();
+ QTouchEvent *e = static_cast<QTouchEvent*>(event);
+ QList<QTouchEvent::TouchPoint> touchPoints = e->touchPoints();
+ int numTouchPoints = touchPoints.count();
+ //always remove released touches, and make sure we handle all releases before adds.
+ foreach (QTouchEvent::TouchPoint p, touchPoints) {
+ Qt::TouchPointState touchPointState = p.state();
+ int id = p.id();
+ if (touchPointState & Qt::TouchPointReleased) {
+ QQuickTouchPoint* dtp = static_cast<QQuickTouchPoint*>(_touchPoints.value(id));
+ if (!dtp)
+ continue;
+ _releasedTouchPoints.append(dtp);
+ _touchPoints.remove(id);
+ ended = true;
+ }
+ }
+ if (numTouchPoints >= _minimumTouchPoints && numTouchPoints <= _maximumTouchPoints) {
+ foreach (QTouchEvent::TouchPoint p, touchPoints) {
+ Qt::TouchPointState touchPointState = p.state();
+ int id = p.id();
+ if (touchPointState & Qt::TouchPointReleased) {
+ //handled above
+ } else if (!_touchPoints.contains(id)) { //could be pressed, moved, or stationary
+ addTouchPoint(&p);
+ started = true;
+ } else if (touchPointState & Qt::TouchPointMoved) {
+ QQuickTouchPoint* dtp = static_cast<QQuickTouchPoint*>(_touchPoints[id]);
+ Q_ASSERT(dtp);
+ _movedTouchPoints.append(dtp);
+ updateTouchPoint(dtp,&p);
+ moved = true;
+ } else {
+ QQuickTouchPoint* dtp = static_cast<QQuickTouchPoint*>(_touchPoints[id]);
+ Q_ASSERT(dtp);
+ updateTouchPoint(dtp,&p);
+ }
+ }
+
+ //see if we should be grabbing the gesture
+ if (!_stealMouse /* !ignoring gesture*/) {
+ bool offerGrab = false;
+ const int dragThreshold = qApp->styleHints()->startDragDistance();
+ foreach (const QTouchEvent::TouchPoint &p, touchPoints) {
+ if (p.state() == Qt::TouchPointReleased)
+ continue;
+ const QPointF &currentPos = p.scenePos();
+ const QPointF &startPos = p.startScenePos();
+ if (qAbs(currentPos.x() - startPos.x()) > dragThreshold)
+ offerGrab = true;
+ else if (qAbs(currentPos.y() - startPos.y()) > dragThreshold)
+ offerGrab = true;
+ if (offerGrab)
+ break;
+ }
+
+ if (offerGrab) {
+ QQuickGrabGestureEvent event;
+ event._touchPoints = _touchPoints.values();
+ emit gestureStarted(&event);
+ if (event.wantsGrab())
+ grabGesture();
+ }
+ }
+
+ if (ended) emit(touchPointsReleased(_releasedTouchPoints));
+ if (moved) emit(touchPointsUpdated(_movedTouchPoints));
+ if (started) emit(touchPointsPressed(_pressedTouchPoints));
+ if (!_touchPoints.isEmpty()) emit touchUpdated(_touchPoints.values());
+ }
+}
+
+void QQuickMultiPointTouchArea::clearTouchLists()
+{
+ foreach (QObject *obj, _releasedTouchPoints) {
+ QQuickTouchPoint *dtp = static_cast<QQuickTouchPoint*>(obj);
+ if (!dtp->isQmlDefined())
+ delete dtp;
+ else
+ dtp->setValid(false);
+ }
+ _releasedTouchPoints.clear();
+ _pressedTouchPoints.clear();
+ _movedTouchPoints.clear();
+}
+
+void QQuickMultiPointTouchArea::addTouchPoint(const QTouchEvent::TouchPoint *p)
+{
+ QQuickTouchPoint *dtp = 0;
+ foreach (QQuickTouchPoint* tp, _touchPrototypes) {
+ if (!tp->isValid()) {
+ tp->setValid(true);
+ dtp = tp;
+ break;
+ }
+ }
+
+ if (dtp == 0)
+ dtp = new QQuickTouchPoint(false);
+ dtp->setPointId(p->id());
+ updateTouchPoint(dtp,p);
+ _touchPoints.insert(p->id(),dtp);
+ //we may have just obtained enough points to start tracking them -- in that case moved or stationary count as newly pressed
+ if (p->state() & Qt::TouchPointPressed || p->state() & Qt::TouchPointMoved || p->state() & Qt::TouchPointStationary)
+ _pressedTouchPoints.append(dtp);
+}
+
+void QQuickMultiPointTouchArea::addTouchPrototype(QQuickTouchPoint *prototype)
+{
+ int id = _touchPrototypes.count();
+ prototype->setPointId(id);
+ _touchPrototypes.insert(id, prototype);
+}
+
+void QQuickMultiPointTouchArea::updateTouchPoint(QQuickTouchPoint *dtp, const QTouchEvent::TouchPoint *p)
+{
+ //TODO: if !qmlDefined, could bypass setters.
+ // also, should only emit signals after all values have been set
+ dtp->setX(p->pos().x());
+ dtp->setY(p->pos().y());
+ dtp->setPressure(p->pressure());
+ dtp->setArea(p->rect());
+ dtp->setStartX(p->startPos().x());
+ dtp->setStartY(p->startPos().y());
+ dtp->setPreviousX(p->lastPos().x());
+ dtp->setPreviousY(p->lastPos().y());
+ dtp->setSceneX(p->scenePos().x());
+ dtp->setSceneY(p->scenePos().y());
+}
+
+void QQuickMultiPointTouchArea::mousePressEvent(QMouseEvent *event)
+{
+ if (!isEnabled()) {
+ QQuickItem::mousePressEvent(event);
+ return;
+ }
+
+ _stealMouse = false;
+ setKeepMouseGrab(false);
+ event->setAccepted(true);
+}
+
+void QQuickMultiPointTouchArea::mouseMoveEvent(QMouseEvent *event)
+{
+ if (!isEnabled()) {
+ QQuickItem::mouseMoveEvent(event);
+ return;
+ }
+
+ //do nothing
+}
+
+void QQuickMultiPointTouchArea::mouseReleaseEvent(QMouseEvent *event)
+{
+ _stealMouse = false;
+ if (!isEnabled()) {
+ QQuickItem::mouseReleaseEvent(event);
+ return;
+ }
+ QQuickCanvas *c = canvas();
+ if (c && c->mouseGrabberItem() == this)
+ ungrabMouse();
+ setKeepMouseGrab(false);
+}
+
+void QQuickMultiPointTouchArea::ungrab()
+{
+ if (_touchPoints.count()) {
+ QQuickCanvas *c = canvas();
+ if (c && c->mouseGrabberItem() == this) {
+ _stealMouse = false;
+ setKeepMouseGrab(false);
+ }
+ setKeepTouchGrab(false);
+ emit touchPointsCanceled(_touchPoints.values());
+ clearTouchLists();
+ foreach (QObject *obj, _touchPoints) {
+ QQuickTouchPoint *dtp = static_cast<QQuickTouchPoint*>(obj);
+ if (!dtp->isQmlDefined())
+ delete dtp;
+ else
+ dtp->setValid(false);
+ }
+ _touchPoints.clear();
+ }
+}
+
+void QQuickMultiPointTouchArea::mouseUngrabEvent()
+{
+ ungrab();
+}
+
+void QQuickMultiPointTouchArea::touchUngrabEvent()
+{
+ ungrab();
+}
+
+bool QQuickMultiPointTouchArea::sendMouseEvent(QMouseEvent *event)
+{
+ QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
+
+ QQuickCanvas *c = canvas();
+ QQuickItem *grabber = c ? c->mouseGrabberItem() : 0;
+ bool stealThisEvent = _stealMouse;
+ if ((stealThisEvent || myRect.contains(event->windowPos())) && (!grabber || !grabber->keepMouseGrab())) {
+ QMouseEvent mouseEvent(event->type(), mapFromScene(event->windowPos()), event->windowPos(), event->screenPos(),
+ event->button(), event->buttons(), event->modifiers());
+ mouseEvent.setAccepted(false);
+
+ switch (mouseEvent.type()) {
+ case QEvent::MouseMove:
+ mouseMoveEvent(&mouseEvent);
+ break;
+ case QEvent::MouseButtonPress:
+ mousePressEvent(&mouseEvent);
+ break;
+ case QEvent::MouseButtonRelease:
+ mouseReleaseEvent(&mouseEvent);
+ break;
+ default:
+ break;
+ }
+ grabber = c->mouseGrabberItem();
+ if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
+ grabMouse();
+
+ return stealThisEvent;
+ }
+ if (event->type() == QEvent::MouseButtonRelease) {
+ _stealMouse = false;
+ if (c && c->mouseGrabberItem() == this)
+ ungrabMouse();
+ setKeepMouseGrab(false);
+ }
+ return false;
+}
+
+bool QQuickMultiPointTouchArea::childMouseEventFilter(QQuickItem *i, QEvent *event)
+{
+ if (!isEnabled() || !isVisible())
+ return QQuickItem::childMouseEventFilter(i, event);
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease:
+ return sendMouseEvent(static_cast<QMouseEvent *>(event));
+ break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ if (!shouldFilter(event))
+ return false;
+ updateTouchData(event);
+ return _stealMouse;
+ case QEvent::TouchEnd: {
+ if (!shouldFilter(event))
+ return false;
+ updateTouchData(event);
+ //TODO: verify this behavior
+ _stealMouse = false;
+ setKeepMouseGrab(false);
+ QQuickCanvas *c = canvas();
+ if (c && c->mouseGrabberItem() == this)
+ ungrabMouse();
+ setKeepTouchGrab(false);
+ ungrabTouchPoints();
+ }
+ break;
+ default:
+ break;
+ }
+ return QQuickItem::childMouseEventFilter(i, event);
+}
+
+bool QQuickMultiPointTouchArea::shouldFilter(QEvent *event)
+{
+ QQuickCanvas *c = canvas();
+ QQuickItem *grabber = c ? c->mouseGrabberItem() : 0;
+ bool disabledItem = grabber && !grabber->isEnabled();
+ bool stealThisEvent = _stealMouse;
+ bool contains = false;
+ if (!stealThisEvent) {
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonRelease: {
+ QMouseEvent *me = static_cast<QMouseEvent*>(event);
+ QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
+ contains = myRect.contains(me->windowPos());
+ }
+ break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd: {
+ QTouchEvent *te = static_cast<QTouchEvent*>(event);
+ QRectF myRect = mapRectToScene(QRectF(0, 0, width(), height()));
+ foreach (const QTouchEvent::TouchPoint &point, te->touchPoints()) {
+ if (myRect.contains(point.scenePos())) {
+ contains = true;
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if ((stealThisEvent || contains) && (!grabber || !grabber->keepMouseGrab() || disabledItem)) {
+ return true;
+ }
+ ungrab();
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/items/qquickmultipointtoucharea_p.h b/src/declarative/items/qquickmultipointtoucharea_p.h
new file mode 100644
index 0000000000..dac70453c5
--- /dev/null
+++ b/src/declarative/items/qquickmultipointtoucharea_p.h
@@ -0,0 +1,267 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKMULTIPOINTTOUCHAREA_H
+#define QQUICKMULTIPOINTTOUCHAREA_H
+
+#include "qquickitem.h"
+#include "qevent.h"
+
+#include <QMap>
+#include <QList>
+#include <QtGui/qguiapplication.h>
+#include <QtGui/qstylehints.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QQuickMultiPointTouchArea;
+class Q_AUTOTEST_EXPORT QQuickTouchPoint : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool valid READ isValid NOTIFY validityChanged)
+ Q_PROPERTY(int pointId READ pointId NOTIFY pointIdChanged)
+ Q_PROPERTY(qreal x READ x NOTIFY xChanged)
+ Q_PROPERTY(qreal y READ y NOTIFY yChanged)
+ Q_PROPERTY(qreal pressure READ pressure NOTIFY pressureChanged)
+ Q_PROPERTY(QRectF area READ area NOTIFY areaChanged)
+
+ Q_PROPERTY(qreal startX READ startX NOTIFY startXChanged)
+ Q_PROPERTY(qreal startY READ startY NOTIFY startYChanged)
+ Q_PROPERTY(qreal previousX READ previousX NOTIFY previousXChanged)
+ Q_PROPERTY(qreal previousY READ previousY NOTIFY previousYChanged)
+ Q_PROPERTY(qreal sceneX READ sceneX NOTIFY sceneXChanged)
+ Q_PROPERTY(qreal sceneY READ sceneY NOTIFY sceneYChanged)
+
+public:
+ QQuickTouchPoint(bool qmlDefined = true)
+ : _id(0),
+ _x(0.0), _y(0.0),
+ _pressure(0.0),
+ _qmlDefined(qmlDefined),
+ _valid(!qmlDefined),
+ _previousX(0.0), _previousY(0.0),
+ _sceneX(0.0), _sceneY(0.0)
+ {}
+
+ int pointId() const { return _id; }
+ void setPointId(int id);
+
+ qreal x() const { return _x; }
+ void setX(qreal x);
+
+ qreal y() const { return _y; }
+ void setY(qreal y);
+
+ qreal pressure() const { return _pressure; }
+ void setPressure(qreal pressure);
+
+ QRectF area() const { return _area; }
+ void setArea(const QRectF &area);
+
+ bool isQmlDefined() { return _qmlDefined; }
+
+ bool isValid() { return _valid; }
+ void setValid(bool valid);
+
+ qreal startX() const { return _startX; }
+ void setStartX(qreal startX);
+
+ qreal startY() const { return _startY; }
+ void setStartY(qreal startY);
+
+ qreal previousX() const { return _previousX; }
+ void setPreviousX(qreal previousX);
+
+ qreal previousY() const { return _previousY; }
+ void setPreviousY(qreal previousY);
+
+ qreal sceneX() const { return _sceneX; }
+ void setSceneX(qreal sceneX);
+
+ qreal sceneY() const { return _sceneY; }
+ void setSceneY(qreal sceneY);
+
+
+Q_SIGNALS:
+ void pointIdChanged();
+ void xChanged();
+ void yChanged();
+ void pressureChanged();
+ void areaChanged();
+ void validityChanged();
+ void startXChanged();
+ void startYChanged();
+ void previousXChanged();
+ void previousYChanged();
+ void sceneXChanged();
+ void sceneYChanged();
+
+private:
+ friend class QQuickMultiPointTouchArea;
+ int _id;
+ qreal _x;
+ qreal _y;
+ qreal _pressure;
+ QRectF _area;
+ bool _qmlDefined;
+ bool _valid;
+ qreal _startX;
+ qreal _startY;
+ qreal _previousX;
+ qreal _previousY;
+ qreal _sceneX;
+ qreal _sceneY;
+};
+
+class QQuickGrabGestureEvent : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QDeclarativeListProperty<QObject> touchPoints READ touchPoints)
+ Q_PROPERTY(qreal dragThreshold READ dragThreshold)
+public:
+ QQuickGrabGestureEvent() : _grab(false), _dragThreshold(qApp->styleHints()->startDragDistance()) {}
+
+ Q_INVOKABLE void grab() { _grab = true; }
+ bool wantsGrab() const { return _grab; }
+
+ QDeclarativeListProperty<QObject> touchPoints() {
+ return QDeclarativeListProperty<QObject>(this, _touchPoints);
+ }
+ qreal dragThreshold() const { return _dragThreshold; }
+
+private:
+ friend class QQuickMultiPointTouchArea;
+ bool _grab;
+ qreal _dragThreshold;
+ QList<QObject*> _touchPoints;
+};
+
+class Q_AUTOTEST_EXPORT QQuickMultiPointTouchArea : public QQuickItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QDeclarativeListProperty<QQuickTouchPoint> touchPoints READ touchPoints)
+ Q_PROPERTY(int minimumTouchPoints READ minimumTouchPoints WRITE setMinimumTouchPoints NOTIFY minimumTouchPointsChanged)
+ Q_PROPERTY(int maximumTouchPoints READ maximumTouchPoints WRITE setMaximumTouchPoints NOTIFY maximumTouchPointsChanged)
+
+public:
+ QQuickMultiPointTouchArea(QQuickItem *parent=0);
+ ~QQuickMultiPointTouchArea();
+
+ int minimumTouchPoints() const;
+ void setMinimumTouchPoints(int num);
+ int maximumTouchPoints() const;
+ void setMaximumTouchPoints(int num);
+
+ QDeclarativeListProperty<QQuickTouchPoint> touchPoints() {
+ return QDeclarativeListProperty<QQuickTouchPoint>(this, 0, QQuickMultiPointTouchArea::touchPoint_append, QQuickMultiPointTouchArea::touchPoint_count, QQuickMultiPointTouchArea::touchPoint_at, 0);
+ }
+
+ static void touchPoint_append(QDeclarativeListProperty<QQuickTouchPoint> *list, QQuickTouchPoint* touch) {
+ QQuickMultiPointTouchArea *q = static_cast<QQuickMultiPointTouchArea*>(list->object);
+ q->addTouchPrototype(touch);
+ }
+
+ static int touchPoint_count(QDeclarativeListProperty<QQuickTouchPoint> *list) {
+ QQuickMultiPointTouchArea *q = static_cast<QQuickMultiPointTouchArea*>(list->object);
+ return q->_touchPrototypes.count();
+ }
+
+ static QQuickTouchPoint* touchPoint_at(QDeclarativeListProperty<QQuickTouchPoint> *list, int index) {
+ QQuickMultiPointTouchArea *q = static_cast<QQuickMultiPointTouchArea*>(list->object);
+ return q->_touchPrototypes[index];
+ }
+
+Q_SIGNALS:
+ void touchPointsPressed(const QList<QObject*> &touchPoints);
+ void touchPointsUpdated(const QList<QObject*> &touchPoints);
+ void touchPointsReleased(const QList<QObject*> &touchPoints);
+ void touchPointsCanceled(const QList<QObject*> &touchPoints);
+ void gestureStarted(QQuickGrabGestureEvent *gesture);
+ void touchUpdated(const QList<QObject*> &touchPoints);
+ void minimumTouchPointsChanged();
+ void maximumTouchPointsChanged();
+
+protected:
+ void touchEvent(QTouchEvent *);
+ bool childMouseEventFilter(QQuickItem *i, QEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void mouseUngrabEvent();
+ void touchUngrabEvent();
+
+ void addTouchPrototype(QQuickTouchPoint* prototype);
+ void addTouchPoint(const QTouchEvent::TouchPoint *p);
+ void clearTouchLists();
+
+ void updateTouchPoint(QQuickTouchPoint*, const QTouchEvent::TouchPoint*);
+ void updateTouchData(QEvent*);
+
+ bool sendMouseEvent(QMouseEvent *event);
+ bool shouldFilter(QEvent *event);
+ void grabGesture();
+
+private:
+ void ungrab();
+ QMap<int,QQuickTouchPoint*> _touchPrototypes; //TouchPoints defined in QML
+ QMap<int,QObject*> _touchPoints; //All current touch points
+ QList<QObject*> _releasedTouchPoints;
+ QList<QObject*> _pressedTouchPoints;
+ QList<QObject*> _movedTouchPoints;
+ int _minimumTouchPoints;
+ int _maximumTouchPoints;
+ bool _stealMouse;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickTouchPoint)
+QML_DECLARE_TYPE(QQuickGrabGestureEvent)
+QML_DECLARE_TYPE(QQuickMultiPointTouchArea)
+
+QT_END_HEADER
+
+#endif // QQUICKMULTIPOINTTOUCHAREA_H