aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquickitem.cpp3
-rw-r--r--src/quick/items/qquickpincharea.cpp176
-rw-r--r--src/quick/items/qquickpincharea_p.h7
-rw-r--r--src/quick/items/qquickwindow.cpp35
-rw-r--r--src/quick/items/qquickwindow_p.h1
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(&copy);
+ 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 *);