summaryrefslogtreecommitdiffstats
path: root/src/gui/graphicsview
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp25
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h2
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h2
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp166
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h6
-rw-r--r--src/gui/graphicsview/qgraphicssceneevent.cpp338
-rw-r--r--src/gui/graphicsview/qgraphicssceneevent.h64
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp106
-rw-r--r--src/gui/graphicsview/qgraphicsview_p.h5
9 files changed, 703 insertions, 11 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 743c16d..3eef396 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -2106,6 +2106,31 @@ void QGraphicsItem::setAcceptsHoverEvents(bool enabled)
setAcceptHoverEvents(enabled);
}
+/*! \since 4.6
+
+ Returns true if an item accepts touch events
+ (QGraphicsSceneTouchEvent); otherwise, returns false. By default,
+ items do not accept touch events.
+
+ \sa setAcceptTouchEvents()
+*/
+bool QGraphicsItem::acceptTouchEvents() const
+{
+ return d_ptr->acceptTouchEvents;
+}
+
+/*!
+ \since 4.6
+
+ If \a enabled is true, this item will accept touch events;
+ otherwise, it will ignore them. By default, items do not accept
+ touch events.
+*/
+void QGraphicsItem::setAcceptTouchEvents(bool enabled)
+{
+ d_ptr->acceptTouchEvents = quint32(enabled);
+}
+
/*!
Returns true if this item handles child events (i.e., all events
intended for any of its children are instead sent to this item);
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index b98882d..ec3373a 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -203,6 +203,8 @@ public:
void setAcceptsHoverEvents(bool enabled); // obsolete
bool acceptHoverEvents() const;
void setAcceptHoverEvents(bool enabled);
+ bool acceptTouchEvents() const;
+ void setAcceptTouchEvents(bool enabled);
bool handlesChildEvents() const;
void setHandlesChildEvents(bool enabled);
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 2936cf1..5e77dfd 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -143,6 +143,7 @@ public:
emptyClipPath(0),
inSetPosHelper(0),
allChildrenCombineOpacity(1),
+ acceptTouchEvents(0),
globalStackingOrder(-1),
sceneTransformIndex(-1),
q_ptr(0)
@@ -327,6 +328,7 @@ public:
quint32 emptyClipPath : 1;
quint32 inSetPosHelper : 1;
quint32 allChildrenCombineOpacity : 1;
+ quint32 acceptTouchEvents : 1;
// Optional stacking order
int globalStackingOrder;
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 69e08d1..f322305 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -3796,6 +3796,9 @@ bool QGraphicsScene::event(QEvent *event)
case QEvent::GraphicsSceneHoverEnter:
case QEvent::GraphicsSceneHoverLeave:
case QEvent::GraphicsSceneHoverMove:
+ case QEvent::GraphicsSceneTouchBegin:
+ case QEvent::GraphicsSceneTouchUpdate:
+ case QEvent::GraphicsSceneTouchEnd:
// Reset the under-mouse list to ensure that this event gets fresh
// item-under-mouse data. Be careful about this list; if people delete
// items from inside event handlers, this list can quickly end up
@@ -3947,6 +3950,15 @@ bool QGraphicsScene::event(QEvent *event)
// geometries that do not have an explicit style set.
update();
break;
+ case QEvent::GraphicsSceneTouchBegin:
+ d->touchBeginEvent(static_cast<QGraphicsSceneTouchEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneTouchUpdate:
+ d->touchUpdateEvent(static_cast<QGraphicsSceneTouchEvent *>(event));
+ break;
+ case QEvent::GraphicsSceneTouchEnd:
+ d->touchEndEvent(static_cast<QGraphicsSceneTouchEvent *>(event));
+ break;
case QEvent::Timer:
if (d->indexTimerId && static_cast<QTimerEvent *>(event)->timerId() == d->indexTimerId) {
if (d->restartIndexTimer) {
@@ -5574,6 +5586,160 @@ void QGraphicsScene::setActiveWindow(QGraphicsWidget *widget)
}
}
+// ### FIXME: the code for touch event support is mosly copied from
+// ### QGraphicsScenePrivate::mousePressEventHandler() and friends, need to
+// ### refactor to reduce code duplication
+
+void QGraphicsScenePrivate::sendTouchEvent(QGraphicsSceneTouchEvent *touchEvent)
+{
+ if (touchEvent->type() == QEvent::GraphicsSceneTouchEnd && lastMouseGrabberItemHasImplicitMouseGrab) {
+ clearMouseGrabber();
+ return;
+ }
+
+ QGraphicsItem *item = mouseGrabberItems.last();
+ QList<QGraphicsSceneTouchEvent::TouchPoint *> touchPoints = touchEvent->touchPoints();
+ for (int i = 0; i < touchPoints.count(); ++i) {
+ QGraphicsSceneTouchEvent::TouchPoint *touchPoint = touchPoints.at(i);
+ touchPoint->setPos(item->d_ptr->genericMapFromScene(touchPoint->scenePos(), touchEvent->widget()));
+ touchPoint->setStartPos(item->d_ptr->genericMapFromScene(touchPoint->startScenePos(), touchEvent->widget()));
+ touchPoint->setLastPos(item->d_ptr->genericMapFromScene(touchPoint->lastScenePos(), touchEvent->widget()));
+ }
+ sendEvent(item, touchEvent);
+}
+
+void QGraphicsScenePrivate::touchBeginEvent(QGraphicsSceneTouchEvent *touchEvent)
+{
+ Q_Q(QGraphicsScene);
+
+ // Ignore by default, unless we find a mouse grabber that accepts it.
+ touchEvent->ignore();
+
+ // Deliver to any existing mouse grabber.
+ if (!mouseGrabberItems.isEmpty()) {
+ // The event is ignored by default, but we disregard the event's
+ // accepted state after delivery; the mouse is grabbed, after all.
+ sendTouchEvent(touchEvent);
+ return;
+ }
+
+ // Start by determining the number of items at the current position.
+ // Reuse value from earlier calculations if possible.
+ if (cachedItemsUnderMouse.isEmpty()) {
+ QGraphicsSceneTouchEvent::TouchPoint *touchPoint = touchEvent->touchPoints().first();
+ // ### FIXME: should the itemsAtPosition() function support sub-pixel screenPos?
+ cachedItemsUnderMouse = itemsAtPosition(touchPoint->screenPos().toPoint(),
+ touchPoint->scenePos(),
+ touchEvent->widget());
+ }
+
+ // Update window activation.
+ QGraphicsWidget *newActiveWindow = windowForItem(cachedItemsUnderMouse.value(0));
+ if (newActiveWindow != activeWindow)
+ q->setActiveWindow(newActiveWindow);
+
+ // Set focus on the topmost enabled item that can take focus.
+ bool setFocus = false;
+ foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
+ if (item->isEnabled() && (item->flags() & QGraphicsItem::ItemIsFocusable)) {
+ if (!item->isWidget() || ((QGraphicsWidget *)item)->focusPolicy() & Qt::ClickFocus) {
+ setFocus = true;
+ if (item != q->focusItem())
+ q->setFocusItem(item, Qt::MouseFocusReason);
+ break;
+ }
+ }
+ }
+
+ // If nobody could take focus, clear it.
+ if (!stickyFocus && !setFocus)
+ q->setFocusItem(0, Qt::MouseFocusReason);
+
+ // Find a mouse grabber by sending touch events to all mouse grabber
+ // candidates one at a time, until the event is accepted. It's accepted by
+ // default, so the receiver has to explicitly ignore it for it to pass
+ // through.
+ foreach (QGraphicsItem *item, cachedItemsUnderMouse) {
+ if (!item->acceptTouchEvents()) {
+ // Skip items that don't accept the touch events
+ continue;
+ }
+
+ grabMouse(item, /* implicit = */ true);
+ touchEvent->accept();
+
+ // check if the item we are sending to are disabled (before we send the event)
+ bool disabled = !item->isEnabled();
+ bool isWindow = item->isWindow();
+ sendTouchEvent(touchEvent);
+
+ bool dontSendUngrabEvents = mouseGrabberItems.isEmpty() || mouseGrabberItems.last() != item;
+ if (disabled) {
+ ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
+ break;
+ }
+ if (touchEvent->isAccepted()) {
+ lastMouseGrabberItem = item;
+ return;
+ }
+ ungrabMouse(item, /* itemIsDying = */ dontSendUngrabEvents);
+
+ // Don't propagate through windows.
+ if (isWindow)
+ break;
+ }
+
+ // Is the event still ignored? Then the mouse press goes to the scene.
+ // Reset the mouse grabber, clear the selection, clear focus, and leave
+ // the event ignored so that it can propagate through the originating
+ // view.
+ if (!touchEvent->isAccepted()) {
+ clearMouseGrabber();
+
+ QGraphicsView *view = touchEvent->widget() ? qobject_cast<QGraphicsView *>(touchEvent->widget()->parentWidget()) : 0;
+ bool dontClearSelection = view && view->dragMode() == QGraphicsView::ScrollHandDrag;
+ if (!dontClearSelection) {
+ // Clear the selection if the originating view isn't in scroll
+ // hand drag mode. The view will clear the selection if no drag
+ // happened.
+ q->clearSelection();
+ }
+ }
+}
+
+void QGraphicsScenePrivate::touchUpdateEvent(QGraphicsSceneTouchEvent *touchEvent)
+{
+ if (mouseGrabberItems.isEmpty()) {
+ touchEvent->ignore();
+ return;
+ }
+
+ // Forward the event to the mouse grabber
+ sendTouchEvent(touchEvent);
+ touchEvent->accept();
+}
+
+void QGraphicsScenePrivate::touchEndEvent(QGraphicsSceneTouchEvent *touchEvent)
+{
+ if (mouseGrabberItems.isEmpty()) {
+ touchEvent->ignore();
+ return;
+ }
+
+ // Forward the event to the mouse grabber
+ sendTouchEvent(touchEvent);
+ touchEvent->accept();
+
+ // Reset the mouse grabber
+ if (!mouseGrabberItems.isEmpty()) {
+ lastMouseGrabberItem = mouseGrabberItems.last();
+ if (lastMouseGrabberItemHasImplicitMouseGrab)
+ mouseGrabberItems.last()->ungrabMouse();
+ } else {
+ lastMouseGrabberItem = 0;
+ }
+}
+
QT_END_NAMESPACE
#include "moc_qgraphicsscene.cpp"
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 9ace725..de39205 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -73,6 +73,7 @@ QT_BEGIN_NAMESPACE
class QGraphicsView;
class QGraphicsWidget;
+class QGraphicsSceneTouchEvent;
class QGraphicsScenePrivate : public QObjectPrivate
{
@@ -266,6 +267,11 @@ public:
mutable QVector<QTransform> sceneTransformCache;
mutable QBitArray validTransforms;
mutable QVector<int> freeSceneTransformSlots;
+
+ void sendTouchEvent(QGraphicsSceneTouchEvent *touchEvent);
+ void touchBeginEvent(QGraphicsSceneTouchEvent *touchEvent);
+ void touchUpdateEvent(QGraphicsSceneTouchEvent *touchEvent);
+ void touchEndEvent(QGraphicsSceneTouchEvent *touchEvent);
};
QT_END_NAMESPACE
diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp
index b819c2c..3c9799b 100644
--- a/src/gui/graphicsview/qgraphicssceneevent.cpp
+++ b/src/gui/graphicsview/qgraphicssceneevent.cpp
@@ -76,14 +76,14 @@
received by the view (see
\l{QGraphicsSceneMouseEvent::}{lastScreenPos()},
\l{QGraphicsSceneMouseEvent::}{lastScenePos()}, and
- \l{QGraphicsSceneMouseEvent::}{lastPos()}).
+ \l{QGraphicsSceneMouseEvent::}{lastPos()}).
\sa QEvent
*/
/*!
\class QGraphicsSceneMouseEvent
- \brief The QGraphicsSceneMouseEvent class provides mouse events
+ \brief The QGraphicsSceneMouseEvent class provides mouse events
in the graphics view framework.
\since 4.2
\ingroup multimedia
@@ -106,7 +106,7 @@
/*!
\class QGraphicsSceneWheelEvent
- \brief The QGraphicsSceneWheelEvent class provides wheel events
+ \brief The QGraphicsSceneWheelEvent class provides wheel events
in the graphics view framework.
\brief The QGraphicsSceneWheelEvent class provides wheel events in the
graphics view framework.
@@ -157,7 +157,7 @@
/*!
\class QGraphicsSceneHoverEvent
- \brief The QGraphicsSceneHoverEvent class provides hover events
+ \brief The QGraphicsSceneHoverEvent class provides hover events
in the graphics view framework.
\since 4.2
\ingroup multimedia
@@ -173,7 +173,7 @@
/*!
\class QGraphicsSceneHelpEvent
- \brief The QGraphicsSceneHelpEvent class provides events when a
+ \brief The QGraphicsSceneHelpEvent class provides events when a
tooltip is requested.
\since 4.2
\ingroup multimedia
@@ -199,7 +199,7 @@
/*!
\class QGraphicsSceneDragDropEvent
\brief The QGraphicsSceneDragDropEvent class provides events for
- drag and drop in the graphics view framework.
+ drag and drop in the graphics view framework.
\since 4.2
\ingroup multimedia
\ingroup graphicsview-api
@@ -257,6 +257,37 @@
QGraphicsItem::ItemPositionHasChanged
*/
+/*!
+ \class QGraphicsSceneTouchEvent
+ \brief The QGraphicsSceneTouchEvent class provides touch events in the graphics view framework.
+ \since 4.6
+ \ingroup multimedia
+ \ingroup graphicsview-api
+
+ When a QGraphicsView receives a QTouchEvent, it translates it to a
+ QGraphicsSceneTouchEvent. The event is then forwarded to the
+ QGraphicsScene associated with the view.
+
+ The touchPoints() function returns a list of touch points for the
+ event. In addition to containing the item, scene, and screen
+ coordinates, each touch point also contains its starting and
+ previous coordinates.
+
+ \sa QTouchEvent
+*/
+
+/*!
+ \class QGraphicsSceneTouchEvent::TouchPoint
+ \brief The QGraphicsSceneTouchEvent::TouchPoint class represents a single touch point in a QGraphicsSceneTouchEvent.
+ \since 4.6
+ \ingroup multimedia
+ \ingroup graphicsview-api
+
+ Each touch point in a QGraphicsSceneTouchEvent has an id() and
+ state() in addition to current, starting, and previous coordinates
+ for the touch point in item, scene, and screen coordinates.
+*/
+
#include "qgraphicssceneevent.h"
#ifndef QT_NO_GRAPHICSVIEW
@@ -522,7 +553,7 @@ void QGraphicsSceneMouseEvent::setLastPos(const QPointF &pos)
}
/*!
- Returns the last recorded mouse cursor position in scene
+ Returns the last recorded mouse cursor position in scene
coordinates. The last recorded position is the position of
the previous mouse event received by the view that created
the event.
@@ -545,7 +576,7 @@ void QGraphicsSceneMouseEvent::setLastScenePos(const QPointF &pos)
}
/*!
- Returns the last recorded mouse cursor position in screen
+ Returns the last recorded mouse cursor position in screen
coordinates. The last recorded position is the position of
the previous mouse event received by the view that created
the event.
@@ -1275,7 +1306,7 @@ QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent()
/*!
Returns the mouse position of the event relative to the
view that sent the event.
-
+
\sa QGraphicsView, screenPos(), scenePos()
*/
QPointF QGraphicsSceneDragDropEvent::pos() const
@@ -1373,7 +1404,7 @@ void QGraphicsSceneDragDropEvent::setButtons(Qt::MouseButtons buttons)
/*!
Returns the keyboard modifiers that were pressed when the drag
- and drop event was created.
+ and drop event was created.
\sa Qt::KeyboardModifiers
*/
@@ -1428,7 +1459,7 @@ void QGraphicsSceneDragDropEvent::setPossibleActions(Qt::DropActions actions)
The action must be one of the possible actions as defined by
\c possibleActions().
- \sa Qt::DropAction, possibleActions()
+ \sa Qt::DropAction, possibleActions()
*/
Qt::DropAction QGraphicsSceneDragDropEvent::proposedAction() const
@@ -1673,6 +1704,291 @@ void QGraphicsSceneMoveEvent::setNewPos(const QPointF &pos)
d->newPos = pos;
}
+class QGraphicsSceneTouchEventPrivate : public QGraphicsSceneEventPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsSceneTouchEvent)
+public:
+ inline QGraphicsSceneTouchEventPrivate()
+ : modifiers(Qt::NoModifier)
+ { }
+
+ QList<QGraphicsSceneTouchEvent::TouchPoint *> touchPoints;
+ Qt::KeyboardModifiers modifiers;
+};
+
+/*!
+ \internal
+
+ Constructs a generic QGraphicsSceneTouchEvent of type \a type.
+*/
+QGraphicsSceneTouchEvent::QGraphicsSceneTouchEvent(Type type)
+ : QGraphicsSceneEvent(*new QGraphicsSceneTouchEventPrivate, type)
+{ }
+
+/*!
+ Destroys the QGraphicsSceneTouchEvent.
+*/
+QGraphicsSceneTouchEvent::~QGraphicsSceneTouchEvent()
+{
+ Q_D(QGraphicsSceneTouchEvent);
+ qDeleteAll(d->touchPoints);
+}
+
+/*!
+ Returns the list of touch points for this event.
+
+ \sa QGraphicsSceneTouchEvent::TouchPoint
+*/
+const QList<QGraphicsSceneTouchEvent::TouchPoint *> &QGraphicsSceneTouchEvent::touchPoints() const
+{
+ Q_D(const QGraphicsSceneTouchEvent);
+ return d->touchPoints;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::setTouchPoints(const QList<QGraphicsSceneTouchEvent::TouchPoint *> &touchPoints)
+{
+ Q_D(QGraphicsSceneTouchEvent);
+ d->touchPoints = touchPoints;
+}
+
+/*!
+ Returns the keyboard modifiers in use at the time the event was
+ sent.
+*/
+Qt::KeyboardModifiers QGraphicsSceneTouchEvent::modifiers() const
+{
+ Q_D(const QGraphicsSceneTouchEvent);
+ return d->modifiers;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::setModifiers(Qt::KeyboardModifiers modifiers)
+{
+ Q_D(QGraphicsSceneTouchEvent);
+ d->modifiers = modifiers;
+}
+
+class QGraphicsSceneTouchEventTouchPointPrivate
+{
+public:
+ inline QGraphicsSceneTouchEventTouchPointPrivate()
+ : id(-1), state(Qt::TouchPointReleased), pressure(qreal(0.))
+ { }
+
+ int id;
+ Qt::TouchPointState state;
+ QPointF pos, startPos, lastPos;
+ QPointF scenePos, startScenePos, lastScenePos;
+ QPointF screenPos, startScreenPos, lastScreenPos;
+ qreal pressure;
+};
+
+/*! \internal
+
+ Constructs a new touch point for use in a QGraphicsSceneTouchEvent.
+*/
+QGraphicsSceneTouchEvent::TouchPoint::TouchPoint()
+ : d(new QGraphicsSceneTouchEventTouchPointPrivate)
+{
+}
+
+/*! \internal
+
+ Destroys the QGraphicsSceneTouchEvent::TouchPoint.
+*/
+QGraphicsSceneTouchEvent::TouchPoint::~TouchPoint()
+{
+ delete d;
+}
+
+/*!
+ Returns the identifier for this touch point.
+*/
+int QGraphicsSceneTouchEvent::TouchPoint::id() const
+{
+ return d->id;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setId(int id)
+{
+ d->id = id;
+}
+
+/*!
+ Returns the state of this touch point at the time the
+ QGraphicsSceneTouchEvent occurred.
+*/
+Qt::TouchPointState QGraphicsSceneTouchEvent::TouchPoint::state() const
+{
+ return d->state;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setState(Qt::TouchPointState state)
+{
+ d->state = state;
+}
+
+/*!
+ Returns the current position of this touch point in item coordinates.
+
+ \sa scenePos(), screenPos()
+*/
+QPointF QGraphicsSceneTouchEvent::TouchPoint::pos() const
+{
+ return d->pos;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setPos(const QPointF &pos)
+{
+ d->pos = pos;
+}
+
+/*!
+ Returns the starting position of this touch point in item coordinates.
+
+ \sa startScenePos(), startScreenPos()
+*/
+QPointF QGraphicsSceneTouchEvent::TouchPoint::startPos() const
+{
+ return d->startPos;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setStartPos(const QPointF &startPos)
+{
+ d->startPos = startPos;
+}
+
+/*!
+ Returns the previous position of this touch point in item coordinates.
+
+ \sa lastScenePos(), lastScreenPos()
+*/
+QPointF QGraphicsSceneTouchEvent::TouchPoint::lastPos() const
+{
+ return d->lastPos;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setLastPos(const QPointF &lastPos)
+{
+ d->lastPos = lastPos;
+}
+
+/*!
+ Returns the current position of this touch point in scene coordinates.
+
+ \sa pos(), screenPos()
+*/
+QPointF QGraphicsSceneTouchEvent::TouchPoint::scenePos() const
+{
+ return d->scenePos;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setScenePos(const QPointF &scenePos)
+{
+ d->scenePos = scenePos;
+}
+
+/*!
+ Returns the starting position of this touch point in scene coordinates.
+
+ \sa startPos(), startScreenPos()
+*/
+QPointF QGraphicsSceneTouchEvent::TouchPoint::startScenePos() const
+{
+ return d->startScenePos;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setStartScenePos(const QPointF &startScenePos)
+{
+ d->startScenePos = startScenePos;
+}
+
+/*!
+ Returns the previous position of this touch point in scene coordinates.
+
+ \sa lastPos(), lastScreenPos()
+*/
+QPointF QGraphicsSceneTouchEvent::TouchPoint::lastScenePos() const
+{
+ return d->lastScenePos;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setLastScenePos(const QPointF &lastScenePos)
+{
+ d->lastScenePos = lastScenePos;
+}
+
+/*!
+ Returns the current position of this touch point in screen coordinates.
+
+ \sa pos(), scenePos()
+*/
+QPointF QGraphicsSceneTouchEvent::TouchPoint::screenPos() const
+{
+ return d->screenPos;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setScreenPos(const QPointF &screenPos)
+{
+ d->screenPos = screenPos;
+}
+
+/*!
+ Returns the starting position of this touch point in screen coordinates.
+
+ \sa startPos(), startScenePos()
+*/
+QPointF QGraphicsSceneTouchEvent::TouchPoint::startScreenPos() const
+{
+ return d->startScreenPos;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setStartScreenPos(const QPointF &startScreenPos)
+{
+ d->startScreenPos = startScreenPos;
+}
+
+/*!
+ Returns the previous position of this touch point in screen coordinates.
+
+ \sa lastPos(), lastScenePos()
+*/
+QPointF QGraphicsSceneTouchEvent::TouchPoint::lastScreenPos() const
+{
+ return d->lastScreenPos;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setLastScreenPos(const QPointF &lastScreenPos)
+{
+ d->lastScreenPos = lastScreenPos;
+}
+
+/*!
+ Returns the pressure of this touch point.
+*/
+qreal QGraphicsSceneTouchEvent::TouchPoint::pressure() const
+{
+ return d->pressure;
+}
+
+/*! \internal */
+void QGraphicsSceneTouchEvent::TouchPoint::setPressure(qreal pressure)
+{
+ d->pressure = pressure;
+}
+
QT_END_NAMESPACE
#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicssceneevent.h b/src/gui/graphicsview/qgraphicssceneevent.h
index be50e96..8ae3a99 100644
--- a/src/gui/graphicsview/qgraphicssceneevent.h
+++ b/src/gui/graphicsview/qgraphicssceneevent.h
@@ -302,6 +302,70 @@ public:
void setNewPos(const QPointF &pos);
};
+class QGraphicsSceneTouchEventPrivate;
+class QGraphicsSceneTouchEventTouchPointPrivate;
+class Q_GUI_EXPORT QGraphicsSceneTouchEvent : public QGraphicsSceneEvent
+{
+public:
+ QGraphicsSceneTouchEvent(Type type = None);
+ ~QGraphicsSceneTouchEvent();
+
+ class Q_GUI_EXPORT TouchPoint
+ {
+ public:
+ TouchPoint();
+ ~TouchPoint();
+
+ int id() const;
+ void setId(int id);
+
+ Qt::TouchPointState state() const;
+ void setState(Qt::TouchPointState state);
+
+ QPointF pos() const;
+ void setPos(const QPointF &pos);
+
+ QPointF startPos() const;
+ void setStartPos(const QPointF &startPos);
+
+ QPointF lastPos() const;
+ void setLastPos(const QPointF &lastPos);
+
+ QPointF scenePos() const;
+ void setScenePos(const QPointF &scenePos);
+
+ QPointF startScenePos() const;
+ void setStartScenePos(const QPointF &startScenePos);
+
+ QPointF lastScenePos() const;
+ void setLastScenePos(const QPointF &lastScenePos);
+
+ QPointF screenPos() const;
+ void setScreenPos(const QPointF &screenPos);
+
+ QPointF startScreenPos() const;
+ void setStartScreenPos(const QPointF &startScreenPos);
+
+ QPointF lastScreenPos() const;
+ void setLastScreenPos(const QPointF &lastScreenPos);
+
+ qreal pressure() const; // 0.0 -> 1.0
+ void setPressure(qreal pressure);
+
+ private:
+ QGraphicsSceneTouchEventTouchPointPrivate *d;
+ };
+
+ const QList<TouchPoint *> &touchPoints() const;
+ void setTouchPoints(const QList<TouchPoint *> &touchPoints);
+
+ Qt::KeyboardModifiers modifiers() const;
+ void setModifiers(Qt::KeyboardModifiers modifiers);
+
+private:
+ Q_DECLARE_PRIVATE(QGraphicsSceneTouchEvent);
+};
+
#endif // QT_NO_GRAPHICSVIEW
QT_END_NAMESPACE
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index 2876016..1aaaab9 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -2940,6 +2940,28 @@ bool QGraphicsView::viewportEvent(QEvent *event)
d->scene->d_func()->updateAll = false;
}
break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ {
+ if (!isEnabled())
+ return false;
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
+ switch (touchEvent->type()) {
+ case QEvent::TouchBegin:
+ d->touchBeginEvent(touchEvent);
+ break;
+ case QEvent::TouchUpdate:
+ d->touchUpdateEvent(touchEvent);
+ break;
+ case QEvent::TouchEnd:
+ d->touchEndEvent(touchEvent);
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
default:
break;
}
@@ -3878,6 +3900,90 @@ void QGraphicsView::resetTransform()
setTransform(QTransform());
}
+static void qt_convertTouchEventToGraphicsSceneTouchEvent(QGraphicsViewPrivate *d, QTouchEvent *originalEvent, QGraphicsSceneTouchEvent *touchEvent)
+{
+ QList<QTouchEvent::TouchPoint *> originalTouchPoints = originalEvent->touchPoints();
+ QList<QGraphicsSceneTouchEvent::TouchPoint *> touchPoints;
+ for (int i = 0; i < originalTouchPoints.count(); ++i) {
+ QTouchEvent::TouchPoint *originalTouchPoint = originalTouchPoints.at(i);
+
+ QGraphicsSceneTouchEvent::TouchPoint *touchPoint = new QGraphicsSceneTouchEvent::TouchPoint();
+ touchPoint->setId(originalTouchPoint->id());
+ touchPoint->setState(originalTouchPoint->state());
+ // the scene will set the pos before delivering to an item
+ touchPoint->setScenePos(d->mapToScene(originalTouchPoint->pos()));
+ touchPoint->setScreenPos(originalTouchPoint->globalPos());
+ // the scene will set the startPos before delivering to an item
+ touchPoint->setStartScenePos(d->mapToScene(originalTouchPoint->startPos()));
+ touchPoint->setStartScreenPos(originalTouchPoint->startGlobalPos());
+ // the scene will set the lastPos before delivering to an item
+ touchPoint->setLastScenePos(d->mapToScene(originalTouchPoint->lastPos()));
+ touchPoint->setLastScreenPos(originalTouchPoint->lastGlobalPos());
+ touchPoint->setPressure(originalTouchPoint->pressure());
+
+ touchPoints.append(touchPoint);
+ }
+
+ touchEvent->setTouchPoints(touchPoints);
+ touchEvent->setModifiers(originalEvent->modifiers());
+}
+
+QPointF QGraphicsViewPrivate::mapToScene(const QPointF &point) const
+{
+ QPointF p = point;
+ p.rx() += horizontalScroll();
+ p.ry() += verticalScroll();
+ return identityMatrix ? p : matrix.inverted().map(p);
+}
+
+void QGraphicsViewPrivate::touchBeginEvent(QTouchEvent *event)
+{
+ Q_Q(QGraphicsView);
+
+ if (!scene || !sceneInteractionAllowed)
+ return;
+
+ // Convert and deliver the touch event to the scene.
+ QGraphicsSceneTouchEvent touchEvent(QEvent::GraphicsSceneTouchBegin);
+ touchEvent.setWidget(q->viewport());
+ qt_convertTouchEventToGraphicsSceneTouchEvent(this, event, &touchEvent);
+ touchEvent.setAccepted(false);
+ QApplication::sendEvent(scene, &touchEvent);
+ event->setAccepted(touchEvent.isAccepted());
+}
+
+void QGraphicsViewPrivate::touchUpdateEvent(QTouchEvent *event)
+{
+ Q_Q(QGraphicsView);
+
+ if (!scene || !sceneInteractionAllowed)
+ return;
+
+ // Convert and deliver the touch event to the scene.
+ QGraphicsSceneTouchEvent touchEvent(QEvent::GraphicsSceneTouchUpdate);
+ touchEvent.setWidget(q->viewport());
+ qt_convertTouchEventToGraphicsSceneTouchEvent(this, event, &touchEvent);
+ touchEvent.setAccepted(false);
+ QApplication::sendEvent(scene, &touchEvent);
+ event->setAccepted(touchEvent.isAccepted());
+}
+
+void QGraphicsViewPrivate::touchEndEvent(QTouchEvent *event)
+{
+ Q_Q(QGraphicsView);
+
+ if (!scene || !sceneInteractionAllowed)
+ return;
+
+ // Convert and deliver the touch event to the scene.
+ QGraphicsSceneTouchEvent touchEvent(QEvent::GraphicsSceneTouchEnd);
+ touchEvent.setWidget(q->viewport());
+ qt_convertTouchEventToGraphicsSceneTouchEvent(this, event, &touchEvent);
+ touchEvent.setAccepted(false);
+ QApplication::sendEvent(scene, &touchEvent);
+ event->setAccepted(touchEvent.isAccepted());
+}
+
QT_END_NAMESPACE
#include "moc_qgraphicsview.cpp"
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
index a76279e..abab921 100644
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ b/src/gui/graphicsview/qgraphicsview_p.h
@@ -181,6 +181,11 @@ public:
const QTransform &worldTransform,
bool allItems,
const QRegion &exposedRegion) const;
+
+ QPointF mapToScene(const QPointF &point) const;
+ void touchBeginEvent(QTouchEvent *event);
+ void touchUpdateEvent(QTouchEvent *event);
+ void touchEndEvent(QTouchEvent *event);
};
QT_END_NAMESPACE