From 7f06ac49129d9048e98afb14b0ff4ebdcb821c35 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 20 Apr 2017 16:28:59 +0200 Subject: Prepare QQuickPopup for touch event handling Add acceptTouch() and handlePress/Move/Release/Ungrab() to QQuickPopupPrivate, similarly to the recent changes to QQuickControl. Task-number: QTBUG-58389 Change-Id: I45bc0c51f7db79d0d3291f4beee6dab45b158e8a Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickdrawer.cpp | 8 +++ src/quicktemplates2/qquickpopup.cpp | 102 +++++++++++++++++++++++++++++++--- src/quicktemplates2/qquickpopup_p_p.h | 8 +++ 3 files changed, 111 insertions(+), 7 deletions(-) diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp index b4a7190a..ca1df07e 100644 --- a/src/quicktemplates2/qquickdrawer.cpp +++ b/src/quicktemplates2/qquickdrawer.cpp @@ -644,6 +644,14 @@ bool QQuickDrawer::overlayEvent(QQuickItem *item, QEvent *event) { Q_D(QQuickDrawer); switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + case QEvent::TouchCancel: + // TODO: QQuickDrawer still relies on synthesized mouse events + event->ignore(); + return false; + case QEvent::MouseButtonPress: d->tryClose(item, static_cast(event)); return d->handleMousePressEvent(item, static_cast(event)); diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index 915cf8f8..cc62db10 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -225,6 +225,7 @@ QQuickPopupPrivate::QQuickPopupPrivate() allowHorizontalResize(true), hadActiveFocusBeforeExitTransition(false), interactive(true), + touchId(-1), x(0), y(0), effectiveX(0), @@ -290,6 +291,44 @@ bool QQuickPopupPrivate::tryClose(QQuickItem *item, QMouseEvent *event) return false; } +bool QQuickPopupPrivate::acceptTouch(const QTouchEvent::TouchPoint &point) +{ + if (point.id() == touchId) + return true; + + if (touchId == -1 && point.state() == Qt::TouchPointPressed) { + touchId = point.id(); + return true; + } + + return false; +} + +void QQuickPopupPrivate::handlePress(const QPointF &) +{ +} + +void QQuickPopupPrivate::handleMove(const QPointF &) +{ +} + +void QQuickPopupPrivate::handleRelease(const QPointF &) +{ + touchId = -1; +} + +void QQuickPopupPrivate::handleUngrab() +{ + Q_Q(QQuickPopup); + QQuickOverlay *overlay = QQuickOverlay::overlay(window); + if (overlay) { + QQuickOverlayPrivate *p = QQuickOverlayPrivate::get(overlay); + if (p->mouseGrabberPopup == q) + p->mouseGrabberPopup = nullptr; + } + touchId = -1; +} + bool QQuickPopupPrivate::prepareEnterTransition() { Q_Q(QQuickPopup); @@ -1800,16 +1839,22 @@ void QQuickPopup::keyReleaseEvent(QKeyEvent *event) void QQuickPopup::mousePressEvent(QMouseEvent *event) { + Q_D(QQuickPopup); + d->handlePress(event->localPos()); event->accept(); } void QQuickPopup::mouseMoveEvent(QMouseEvent *event) { + Q_D(QQuickPopup); + d->handleMove(event->localPos()); event->accept(); } void QQuickPopup::mouseReleaseEvent(QMouseEvent *event) { + Q_D(QQuickPopup); + d->handleRelease(event->localPos()); event->accept(); } @@ -1820,12 +1865,8 @@ void QQuickPopup::mouseDoubleClickEvent(QMouseEvent *event) void QQuickPopup::mouseUngrabEvent() { - QQuickOverlay *overlay = QQuickOverlay::overlay(window()); - if (overlay) { - QQuickOverlayPrivate *p = QQuickOverlayPrivate::get(overlay); - if (p->mouseGrabberPopup == this) - p->mouseGrabberPopup = nullptr; - } + Q_D(QQuickPopup); + d->handleUngrab(); } bool QQuickPopup::overlayEvent(QQuickItem *item, QEvent *event) @@ -1854,12 +1895,59 @@ bool QQuickPopup::overlayEvent(QQuickItem *item, QEvent *event) void QQuickPopup::touchEvent(QTouchEvent *event) { - // TODO: QQuickPopup and QQuickDrawer still rely on synthesized mouse events + Q_D(QQuickPopup); + switch (event->type()) { + case QEvent::TouchBegin: + for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { + if (d->acceptTouch(point)) + d->handlePress(point.pos()); + } + break; + + case QEvent::TouchUpdate: + for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { + if (!d->acceptTouch(point)) + continue; + + switch (point.state()) { + case Qt::TouchPointPressed: + d->handlePress(point.pos()); + break; + case Qt::TouchPointMoved: + d->handleMove(point.pos()); + break; + case Qt::TouchPointReleased: + d->handleRelease(point.pos()); + break; + default: + break; + } + } + break; + + case QEvent::TouchEnd: + for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { + if (d->acceptTouch(point)) + d->handleRelease(point.pos()); + } + break; + + case QEvent::TouchCancel: + d->handleUngrab(); + break; + + default: + break; + } + + // TODO: QQuickPopup still relies on synthesized mouse events event->ignore(); } void QQuickPopup::touchUngrabEvent() { + Q_D(QQuickPopup); + d->handleUngrab(); } #if QT_CONFIG(wheelevent) diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h index 084642ec..8490532c 100644 --- a/src/quicktemplates2/qquickpopup_p_p.h +++ b/src/quicktemplates2/qquickpopup_p_p.h @@ -96,6 +96,13 @@ public: void init(); void closeOrReject(); bool tryClose(QQuickItem *item, QMouseEvent *event); + + virtual bool acceptTouch(const QTouchEvent::TouchPoint &point); + virtual void handlePress(const QPointF &point); + virtual void handleMove(const QPointF &point); + virtual void handleRelease(const QPointF &point); + virtual void handleUngrab(); + virtual void reposition(); virtual void resizeOverlay(); @@ -139,6 +146,7 @@ public: bool allowHorizontalResize; bool hadActiveFocusBeforeExitTransition; bool interactive; + int touchId; qreal x; qreal y; qreal effectiveX; -- cgit v1.2.3