From 7faafa470eee71c51255e276e7b9df5beed2dd5b Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 20 Apr 2017 16:57:59 +0200 Subject: Implement QQuickOverlay::touchEvent() Task-number: QTBUG-58389 Change-Id: I59b2936fd0c984c2dc7c1d3c49fb78c1fa950be7 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickoverlay.cpp | 125 ++++++++++++++++++++++---------- src/quicktemplates2/qquickoverlay_p.h | 1 + src/quicktemplates2/qquickoverlay_p_p.h | 4 + src/quicktemplates2/qquickpopup_p.h | 1 + 4 files changed, 94 insertions(+), 37 deletions(-) diff --git a/src/quicktemplates2/qquickoverlay.cpp b/src/quicktemplates2/qquickoverlay.cpp index cba87849..58ec5582 100644 --- a/src/quicktemplates2/qquickoverlay.cpp +++ b/src/quicktemplates2/qquickoverlay.cpp @@ -181,6 +181,59 @@ QQuickOverlayPrivate::QQuickOverlayPrivate() { } +void QQuickOverlayPrivate::handlePress(QEvent *event) +{ + Q_Q(QQuickOverlay); + emit q->pressed(); + + if (!allDrawers.isEmpty()) { + // the overlay background was pressed, so there are no modal popups open. + // test if the press point lands on any drawer's drag margin + + const QVector drawers = stackingOrderDrawers(); + for (QQuickDrawer *drawer : drawers) { + QQuickDrawerPrivate *p = QQuickDrawerPrivate::get(drawer); + if (p->startDrag(event)) { + setMouseGrabberPopup(drawer); + return; + } + } + } + + if (!mouseGrabberPopup) { + // allow non-modal popups to close themselves + const auto popups = stackingOrderPopups(); + for (QQuickPopup *popup : popups) + popup->overlayEvent(q, event); + } + + event->ignore(); +} + +void QQuickOverlayPrivate::handleMove(QEvent *event) +{ + Q_Q(QQuickOverlay); + if (mouseGrabberPopup) + mouseGrabberPopup->overlayEvent(q, event); +} + +void QQuickOverlayPrivate::handleRelease(QEvent *event) +{ + Q_Q(QQuickOverlay); + emit q->released(); + + if (mouseGrabberPopup) { + mouseGrabberPopup->overlayEvent(q, event); + setMouseGrabberPopup(nullptr); + } else { + const auto popups = stackingOrderPopups(); + for (QQuickPopup *popup : popups) { + if (popup->overlayEvent(q, event)) + break; + } + } +} + void QQuickOverlayPrivate::addPopup(QQuickPopup *popup) { Q_Q(QQuickOverlay); @@ -329,56 +382,54 @@ void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &old void QQuickOverlay::mousePressEvent(QMouseEvent *event) { Q_D(QQuickOverlay); - emit pressed(); - - if (!d->allDrawers.isEmpty()) { - // the overlay background was pressed, so there are no modal popups open. - // test if the press point lands on any drawer's drag margin - - const QVector drawers = d->stackingOrderDrawers(); - for (QQuickDrawer *drawer : drawers) { - QQuickDrawerPrivate *p = QQuickDrawerPrivate::get(drawer); - if (p->startDrag(event)) { - d->setMouseGrabberPopup(drawer); - return; - } - } - } - - if (!d->mouseGrabberPopup) { - const auto popups = d->stackingOrderPopups(); - for (QQuickPopup *popup : popups) { - if (popup->overlayEvent(this, event)) { - d->setMouseGrabberPopup(popup); - return; - } - } - } - - event->ignore(); + d->handlePress(event); } void QQuickOverlay::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickOverlay); - if (d->mouseGrabberPopup) - d->mouseGrabberPopup->overlayEvent(this, event); + d->handleMove(event); } void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickOverlay); - emit released(); + d->handleRelease(event); +} - if (d->mouseGrabberPopup) { - d->mouseGrabberPopup->overlayEvent(this, event); - d->setMouseGrabberPopup(nullptr); - } else { - const auto popups = d->stackingOrderPopups(); - for (QQuickPopup *popup : popups) { - if (popup->overlayEvent(this, event)) +void QQuickOverlay::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickOverlay); + switch (event->type()) { + case QEvent::TouchBegin: + d->handlePress(event); + break; + + case QEvent::TouchUpdate: + for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { + switch (point.state()) { + case Qt::TouchPointPressed: + d->handlePress(event); + break; + case Qt::TouchPointMoved: + d->handleMove(event); + break; + case Qt::TouchPointReleased: + d->handleRelease(event); + break; + default: break; + } } + break; + + case QEvent::TouchEnd: + d->handleRelease(event); + break; + + default: + QQuickItem::touchEvent(event); + break; } } diff --git a/src/quicktemplates2/qquickoverlay_p.h b/src/quicktemplates2/qquickoverlay_p.h index 793edf7e..3a535b93 100644 --- a/src/quicktemplates2/qquickoverlay_p.h +++ b/src/quicktemplates2/qquickoverlay_p.h @@ -87,6 +87,7 @@ protected: void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; + void touchEvent(QTouchEvent *event) override; #if QT_CONFIG(wheelevent) void wheelEvent(QWheelEvent *event) override; #endif diff --git a/src/quicktemplates2/qquickoverlay_p_p.h b/src/quicktemplates2/qquickoverlay_p_p.h index f7237b20..b0145fc9 100644 --- a/src/quicktemplates2/qquickoverlay_p_p.h +++ b/src/quicktemplates2/qquickoverlay_p_p.h @@ -70,6 +70,10 @@ public: return overlay->d_func(); } + void handlePress(QEvent *event); + void handleMove(QEvent *event); + void handleRelease(QEvent *event); + void addPopup(QQuickPopup *popup); void removePopup(QQuickPopup *popup); void setMouseGrabberPopup(QQuickPopup *popup); diff --git a/src/quicktemplates2/qquickpopup_p.h b/src/quicktemplates2/qquickpopup_p.h index 8d311e4a..12bbe91d 100644 --- a/src/quicktemplates2/qquickpopup_p.h +++ b/src/quicktemplates2/qquickpopup_p.h @@ -384,6 +384,7 @@ private: Q_DECLARE_PRIVATE(QQuickPopup) friend class QQuickPopupItem; friend class QQuickOverlay; + friend class QQuickOverlayPrivate; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPopup::ClosePolicy) -- cgit v1.2.3