diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 3 | ||||
-rw-r--r-- | src/quick/items/qquickpincharea.cpp | 176 | ||||
-rw-r--r-- | src/quick/items/qquickpincharea_p.h | 7 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 35 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 1 |
5 files changed, 167 insertions, 55 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 38736e44b2..2d81714ee1 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -7316,6 +7316,9 @@ bool QQuickItem::event(QEvent *ev) dropEvent(static_cast<QDropEvent*>(ev)); break; #endif // QT_NO_DRAGANDDROP + case QEvent::NativeGesture: + ev->ignore(); + break; default: return QObject::event(ev); } diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp index 7e934316d8..c2ea91ed1e 100644 --- a/src/quick/items/qquickpincharea.cpp +++ b/src/quick/items/qquickpincharea.cpp @@ -37,7 +37,10 @@ #include <QtGui/qevent.h> #include <QtGui/qguiapplication.h> #include <QtGui/qstylehints.h> +#include <qpa/qplatformintegration.h> #include <qpa/qplatformnativeinterface.h> +#include <private/qguiapplication_p.h> +#include <QVariant> #include <float.h> #include <math.h> @@ -178,7 +181,10 @@ QQuickPinchAreaPrivate::~QQuickPinchAreaPrivate() \li using the onPinchStarted, onPinchUpdated and onPinchFinished handlers \endlist - \sa PinchEvent + Since Qt 5.5, PinchArea can react to native pinch gesture events from the + operating system if available; otherwise it reacts only to touch events. + + \sa PinchEvent, QNativeGestureEvent, QTouchEvent */ /*! @@ -526,34 +532,40 @@ void QQuickPinchArea::updatePinch() d->lastPoint1 = touchPoint1.scenePos(); d->lastPoint2 = touchPoint2.scenePos(); emit pinchUpdated(&pe); - if (d->pinch && d->pinch->target()) { - qreal s = d->pinchStartScale * scale; - s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale()); - pinch()->target()->setScale(s); - QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos; - if (pinch()->axis() & QQuickPinch::XAxis) { - qreal x = pos.x(); - if (x < pinch()->xmin()) - x = pinch()->xmin(); - else if (x > pinch()->xmax()) - x = pinch()->xmax(); - pinch()->target()->setX(x); - } - if (pinch()->axis() & QQuickPinch::YAxis) { - qreal y = pos.y(); - if (y < pinch()->ymin()) - y = pinch()->ymin(); - else if (y > pinch()->ymax()) - y = pinch()->ymax(); - pinch()->target()->setY(y); - } - if (d->pinchStartRotation >= pinch()->minimumRotation() - && d->pinchStartRotation <= pinch()->maximumRotation()) { - qreal r = d->pinchRotation + d->pinchStartRotation; - r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation()); - pinch()->target()->setRotation(r); - } - } + updatePinchTarget(); + } + } +} + +void QQuickPinchArea::updatePinchTarget() +{ + Q_D(QQuickPinchArea); + if (d->pinch && d->pinch->target()) { + qreal s = d->pinchStartScale * d->pinchLastScale; + s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale()); + pinch()->target()->setScale(s); + QPointF pos = d->sceneLastCenter - d->sceneStartCenter + d->pinchStartPos; + if (pinch()->axis() & QQuickPinch::XAxis) { + qreal x = pos.x(); + if (x < pinch()->xmin()) + x = pinch()->xmin(); + else if (x > pinch()->xmax()) + x = pinch()->xmax(); + pinch()->target()->setX(x); + } + if (pinch()->axis() & QQuickPinch::YAxis) { + qreal y = pos.y(); + if (y < pinch()->ymin()) + y = pinch()->ymin(); + else if (y > pinch()->ymax()) + y = pinch()->ymax(); + pinch()->target()->setY(y); + } + if (d->pinchStartRotation >= pinch()->minimumRotation() + && d->pinchStartRotation <= pinch()->maximumRotation()) { + qreal r = d->pinchRotation + d->pinchStartRotation; + r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation()); + pinch()->target()->setRotation(r); } } } @@ -597,31 +609,95 @@ void QQuickPinchArea::itemChange(ItemChange change, const ItemChangeData &value) QQuickItem::itemChange(change, value); } -#ifdef Q_OS_OSX -void QQuickPinchArea::hoverEnterEvent(QHoverEvent *event) +bool QQuickPinchArea::event(QEvent *event) { - Q_UNUSED(event); - setTouchEventsEnabled(true); -} + Q_D(QQuickPinchArea); + if (!d->enabled || !isVisible()) + return QQuickItem::event(event); -void QQuickPinchArea::hoverLeaveEvent(QHoverEvent *event) -{ - Q_UNUSED(event); - setTouchEventsEnabled(false); -} + switch (event->type()) { +#ifndef QT_NO_GESTURES + case QEvent::NativeGesture: { + QNativeGestureEvent *gesture = static_cast<QNativeGestureEvent *>(event); + switch (gesture->gestureType()) { + case Qt::BeginNativeGesture: + clearPinch(); // probably not necessary; JIC + d->pinchStartCenter = gesture->localPos(); + d->pinchStartAngle = 0.0; + d->pinchStartRotation = 0.0; + d->pinchRotation = 0.0; + d->pinchStartScale = 1.0; + d->pinchLastAngle = 0.0; + d->pinchLastScale = 1.0; + d->sceneStartPoint1 = gesture->windowPos(); + d->sceneStartPoint2 = gesture->windowPos(); // TODO we never really know + d->lastPoint1 = gesture->windowPos(); + d->lastPoint2 = gesture->windowPos(); // TODO we never really know + if (d->pinch && d->pinch->target()) { + d->pinchStartPos = d->pinch->target()->position(); + d->pinchStartScale = d->pinch->target()->scale(); + d->pinchStartRotation = d->pinch->target()->rotation(); + d->pinch->setActive(true); + } + break; + case Qt::EndNativeGesture: + clearPinch(); + break; + case Qt::ZoomNativeGesture: { + qreal scale = d->pinchLastScale * (1.0 + gesture->value()); + QQuickPinchEvent pe(d->pinchStartCenter, scale, d->pinchLastAngle, 0.0); + pe.setStartCenter(d->pinchStartCenter); + pe.setPreviousCenter(d->pinchStartCenter); + pe.setPreviousAngle(d->pinchLastAngle); + pe.setPreviousScale(d->pinchLastScale); + pe.setStartPoint1(mapFromScene(d->sceneStartPoint1)); + pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); + pe.setPoint1(mapFromScene(d->lastPoint1)); + pe.setPoint2(mapFromScene(d->lastPoint2)); + pe.setPointCount(2); + d->pinchLastScale = scale; + if (d->inPinch) + emit pinchUpdated(&pe); + else + emit pinchStarted(&pe); + d->inPinch = true; + updatePinchTarget(); + } break; + case Qt::RotateNativeGesture: { + qreal angle = d->pinchLastAngle + gesture->value(); + QQuickPinchEvent pe(d->pinchStartCenter, d->pinchLastScale, angle, 0.0); + pe.setStartCenter(d->pinchStartCenter); + pe.setPreviousCenter(d->pinchStartCenter); + pe.setPreviousAngle(d->pinchLastAngle); + pe.setPreviousScale(d->pinchLastScale); + pe.setStartPoint1(mapFromScene(d->sceneStartPoint1)); + pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); + pe.setPoint1(mapFromScene(d->lastPoint1)); + pe.setPoint2(mapFromScene(d->lastPoint2)); + pe.setPointCount(2); + d->pinchLastAngle = angle; + if (d->inPinch) + emit pinchUpdated(&pe); + else + emit pinchStarted(&pe); + d->inPinch = true; + d->pinchRotation = angle; + updatePinchTarget(); + } break; +#endif // QT_NO_GESTURES + default: + return QQuickItem::event(event); + } + } break; + case QEvent::Wheel: + event->ignore(); + return false; + default: + return QQuickItem::event(event); + } -void QQuickPinchArea::setTouchEventsEnabled(bool enable) -{ - // Resolve function for enabling touch events from the (cocoa) platform plugin. - typedef void (*RegisterTouchWindowFunction)(QWindow *, bool); - RegisterTouchWindowFunction registerTouchWindow = reinterpret_cast<RegisterTouchWindowFunction>( - QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration("registertouchwindow")); - if (!registerTouchWindow) - return; // Not necessarily an error, Qt might be using a different platform plugin. - - registerTouchWindow(window(), enable); + return true; } -#endif // Q_OS_OSX QQuickPinch *QQuickPinchArea::pinch() { diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h index 28db59fb55..21282237b7 100644 --- a/src/quick/items/qquickpincharea_p.h +++ b/src/quick/items/qquickpincharea_p.h @@ -274,15 +274,12 @@ protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE; void itemChange(ItemChange change, const ItemChangeData& value) Q_DECL_OVERRIDE; -#ifdef Q_OS_OSX - void hoverEnterEvent(QHoverEvent *event) Q_DECL_OVERRIDE; - void hoverLeaveEvent(QHoverEvent *event) Q_DECL_OVERRIDE; - void setTouchEventsEnabled(bool enable); -#endif + bool event(QEvent *) Q_DECL_OVERRIDE; private: void clearPinch(); void updatePinch(); + void updatePinchTarget(); void handlePress(); void handleRelease(); diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index f58bd489fe..a387046d46 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1394,6 +1394,9 @@ bool QQuickWindow::event(QEvent *e) d->windowManager->handleUpdateRequest(this); break; } + case QEvent::NativeGesture: + d->deliverGestureEvent(d->contentItem, static_cast<QNativeGestureEvent*>(e)); + break; default: break; } @@ -1751,6 +1754,38 @@ bool QQuickWindowPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event return false; } +bool QQuickWindowPrivate::deliverGestureEvent(QQuickItem *item, QNativeGestureEvent *event) +{ + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + + if ((itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) && !item->contains(event->localPos())) + return false; + + QList<QQuickItem *> children = itemPrivate->paintOrderChildItems(); + for (int ii = children.count() - 1; ii >= 0; --ii) { + QQuickItem *child = children.at(ii); + if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled) + continue; + if (deliverGestureEvent(child, event)) + return true; + } + + QPointF p = item->mapFromScene(event->localPos()); + + if (item->contains(p)) { + QNativeGestureEvent copy(event->gestureType(), p, event->windowPos(), event->screenPos(), + event->value(), 0L, 0L); // TODO can't copy things I can't access + event->accept(); + item->event(©); + if (copy.isAccepted()) { + event->accept(); + return true; + } + } + + return false; +} + /*! \reimp */ void QQuickWindow::wheelEvent(QWheelEvent *event) { diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 4f6149117a..2bfc928e0d 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -141,6 +141,7 @@ public: #ifndef QT_NO_WHEELEVENT bool deliverWheelEvent(QQuickItem *, QWheelEvent *); #endif + bool deliverGestureEvent(QQuickItem *, QNativeGestureEvent *); bool deliverTouchPoints(QQuickItem *, QTouchEvent *, const QList<QTouchEvent::TouchPoint> &, QSet<int> *, QHash<QQuickItem *, QList<QTouchEvent::TouchPoint> > *, QSet<QQuickItem*> *filtered); void deliverTouchEvent(QTouchEvent *); |