diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2017-04-24 20:41:44 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2017-04-25 12:40:13 +0000 |
commit | 381a2cf4a5a65f446b41240e8a6e6a6356988cb2 (patch) | |
tree | 0c653a2c1f8ef7b95b16a0060693154fd0997a9d | |
parent | 039c25daac5ec6b96c0aa074eae2a983a1b5aabd (diff) |
QQuickPopup: tryClose() via handlePress() & handleRelease()
This is a preparation step to make Drawer compatible with touch events.
It will eventually override handlePress/Move/Release() to deal with
both touch and mouse input.
Change-Id: I8ae21f6909ca51f86f19dbe68a3e820e9af676ab
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r-- | src/quicktemplates2/qquickdrawer.cpp | 13 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup.cpp | 171 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup_p_p.h | 5 |
3 files changed, 96 insertions, 93 deletions
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp index b5b4100d..d8397e92 100644 --- a/src/quicktemplates2/qquickdrawer.cpp +++ b/src/quicktemplates2/qquickdrawer.cpp @@ -395,6 +395,8 @@ bool QQuickDrawerPrivate::ungrabMouse(QMouseEvent *event) bool QQuickDrawerPrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *event) { + handlePress(item->mapToScene(event->localPos())); + offset = 0; pressPoint = event->windowPos(); velocityCalculator.startMeasuring(pressPoint, event->timestamp()); @@ -410,7 +412,7 @@ bool QQuickDrawerPrivate::handleMousePressEvent(QQuickItem *item, QMouseEvent *e bool QQuickDrawerPrivate::handleMouseMoveEvent(QQuickItem *item, QMouseEvent *event) { Q_Q(QQuickDrawer); - Q_UNUSED(item); + handleMove(item->mapToScene(event->localPos())); // Don't react to synthesized mouse move events at INF,INF coordinates. // QQuickWindowPrivate::translateTouchToMouse() uses them to clear hover @@ -446,9 +448,9 @@ bool QQuickDrawerPrivate::handleMouseMoveEvent(QQuickItem *item, QMouseEvent *ev bool QQuickDrawerPrivate::handleMouseReleaseEvent(QQuickItem *item, QMouseEvent *event) { - Q_UNUSED(item); - const bool wasGrabbed = ungrabMouse(event); + if (!wasGrabbed) + handleRelease(item->mapToScene(event->localPos())); popupItem->setKeepMouseGrab(false); pressPoint = QPoint(); @@ -651,21 +653,18 @@ bool QQuickDrawer::childMouseEventFilter(QQuickItem *child, QEvent *event) void QQuickDrawer::mousePressEvent(QMouseEvent *event) { Q_D(QQuickDrawer); - QQuickPopup::mousePressEvent(event); d->handleMousePressEvent(d->popupItem, event); } void QQuickDrawer::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickDrawer); - QQuickPopup::mouseMoveEvent(event); d->handleMouseMoveEvent(d->popupItem, event); } void QQuickDrawer::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickDrawer); - QQuickPopup::mouseReleaseEvent(event); d->handleMouseReleaseEvent(d->popupItem, event); } @@ -690,12 +689,10 @@ bool QQuickDrawer::overlayEvent(QQuickItem *item, QEvent *event) return false; case QEvent::MouseButtonPress: - d->tryClose(item, event); return d->handleMousePressEvent(item, static_cast<QMouseEvent *>(event)); case QEvent::MouseMove: return d->handleMouseMoveEvent(item, static_cast<QMouseEvent *>(event)); case QEvent::MouseButtonRelease: - d->tryClose(item, event); return d->handleMouseReleaseEvent(item, static_cast<QMouseEvent *>(event)); default: return QQuickPopup::overlayEvent(item, event); diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index f03e8182..a3ff4f20 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -44,7 +44,6 @@ #include "qquickdialog_p.h" #include <QtQml/qqmlinfo.h> -#include <QtQml/private/qqmlnullablevalue_p.h> #include <QtQuick/qquickitem.h> #include <QtQuick/private/qquicktransition_p.h> #include <QtQuick/private/qquickitem_p.h> @@ -274,46 +273,19 @@ void QQuickPopupPrivate::closeOrReject() q->close(); } -bool QQuickPopupPrivate::tryClose(QQuickItem *item, QEvent *event) +bool QQuickPopupPrivate::tryClose(const QPointF &pos, QQuickPopup::ClosePolicy flags) { if (!interactive) return false; - bool isPress = false; - QQmlNullableValue<QPointF> pos; + static const QQuickPopup::ClosePolicy outsideFlags = QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnReleaseOutside; + static const QQuickPopup::ClosePolicy outsideParentFlags = QQuickPopup::CloseOnPressOutsideParent | QQuickPopup::CloseOnReleaseOutsideParent; - switch (event->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - pos = static_cast<QMouseEvent *>(event)->pos(); - isPress = event->type() == QEvent::MouseButtonPress; - break; - - case QEvent::TouchBegin: - case QEvent::TouchUpdate: - case QEvent::TouchEnd: - for (const QTouchEvent::TouchPoint &point : static_cast<QTouchEvent *>(event)->touchPoints()) { - if (point.state() == Qt::TouchPointMoved) - continue; - - pos = point.pos(); - isPress = point.state() == Qt::TouchPointPressed; - break; // TODO: multiple touch points - } - break; - - default: - break; - } - - if (pos.isNull) // ignore touch moves - return false; - - const bool onOutside = closePolicy.testFlag(isPress ? QQuickPopup::CloseOnPressOutside : QQuickPopup::CloseOnReleaseOutside); - const bool onOutsideParent = closePolicy.testFlag(isPress ? QQuickPopup::CloseOnPressOutsideParent : QQuickPopup::CloseOnReleaseOutsideParent); + const bool onOutside = closePolicy & (flags & outsideFlags); + const bool onOutsideParent = closePolicy & (flags & outsideParentFlags); if (onOutside || onOutsideParent) { - if (!popupItem->contains(item->mapToItem(popupItem, pos))) { - if (!onOutsideParent || !parentItem || !parentItem->contains(item->mapToItem(parentItem, pos))) { + if (!popupItem->contains(popupItem->mapFromScene(pos))) { + if (!onOutsideParent || !parentItem || !parentItem->contains(parentItem->mapFromScene(pos))) { closeOrReject(); return true; } @@ -335,16 +307,18 @@ bool QQuickPopupPrivate::acceptTouch(const QTouchEvent::TouchPoint &point) return false; } -void QQuickPopupPrivate::handlePress(const QPointF &) +void QQuickPopupPrivate::handlePress(const QPointF &point) { + tryClose(point, QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent); } void QQuickPopupPrivate::handleMove(const QPointF &) { } -void QQuickPopupPrivate::handleRelease(const QPointF &) +void QQuickPopupPrivate::handleRelease(const QPointF &point) { + tryClose(point, QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent); touchId = -1; } @@ -360,6 +334,72 @@ void QQuickPopupPrivate::handleUngrab() touchId = -1; } +void QQuickPopupPrivate::handleMouseEvent(QQuickItem *item, QMouseEvent *event) +{ + QPointF pos = item->mapToScene(event->localPos()); + switch (event->type()) { + case QEvent::MouseButtonPress: + handlePress(pos); + break; + case QEvent::MouseMove: + handleMove(pos); + break; + case QEvent::MouseButtonRelease: + handleRelease(pos); + break; + default: + Q_UNREACHABLE(); + break; + } +} + +void QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event) +{ + switch (event->type()) { + case QEvent::TouchBegin: + for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { + if (acceptTouch(point)) + handlePress(item->mapToScene(point.pos())); + } + break; + + case QEvent::TouchUpdate: + for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { + if (!acceptTouch(point)) + continue; + + switch (point.state()) { + case Qt::TouchPointPressed: + handlePress(item->mapToScene(point.pos())); + break; + case Qt::TouchPointMoved: + handleMove(item->mapToScene(point.pos())); + break; + case Qt::TouchPointReleased: + handleRelease(item->mapToScene(point.pos())); + break; + default: + break; + } + } + break; + + case QEvent::TouchEnd: + for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { + if (acceptTouch(point)) + handleRelease(item->mapToScene(point.pos())); + } + break; + + case QEvent::TouchCancel: + handleUngrab(); + break; + + default: + break; + } +} + bool QQuickPopupPrivate::prepareEnterTransition() { Q_Q(QQuickPopup); @@ -1872,21 +1912,21 @@ void QQuickPopup::keyReleaseEvent(QKeyEvent *event) void QQuickPopup::mousePressEvent(QMouseEvent *event) { Q_D(QQuickPopup); - d->handlePress(event->localPos()); + d->handleMouseEvent(d->popupItem, event); event->accept(); } void QQuickPopup::mouseMoveEvent(QMouseEvent *event) { Q_D(QQuickPopup); - d->handleMove(event->localPos()); + d->handleMouseEvent(d->popupItem, event); event->accept(); } void QQuickPopup::mouseReleaseEvent(QMouseEvent *event) { Q_D(QQuickPopup); - d->handleRelease(event->localPos()); + d->handleMouseEvent(d->popupItem, event); event->accept(); } @@ -1916,11 +1956,16 @@ bool QQuickPopup::overlayEvent(QQuickItem *item, QEvent *event) case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: + if (d->modal) + event->accept(); + d->handleTouchEvent(item, static_cast<QTouchEvent *>(event)); + return d->modal; + case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: if (d->modal) event->accept(); - d->tryClose(item, event); + d->handleMouseEvent(item, static_cast<QMouseEvent *>(event)); return d->modal; default: @@ -1931,49 +1976,7 @@ bool QQuickPopup::overlayEvent(QQuickItem *item, QEvent *event) void QQuickPopup::touchEvent(QTouchEvent *event) { 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; - } + d->handleTouchEvent(d->popupItem, event); // TODO: QQuickPopup still relies on synthesized mouse events event->ignore(); diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h index b68f18f6..2ca11efe 100644 --- a/src/quicktemplates2/qquickpopup_p_p.h +++ b/src/quicktemplates2/qquickpopup_p_p.h @@ -95,7 +95,7 @@ public: void init(); void closeOrReject(); - bool tryClose(QQuickItem *item, QEvent *event); + bool tryClose(const QPointF &pos, QQuickPopup::ClosePolicy flags); virtual bool acceptTouch(const QTouchEvent::TouchPoint &point); virtual void handlePress(const QPointF &point); @@ -103,6 +103,9 @@ public: virtual void handleRelease(const QPointF &point); virtual void handleUngrab(); + void handleMouseEvent(QQuickItem *item, QMouseEvent *event); + void handleTouchEvent(QQuickItem *item, QTouchEvent *event); + virtual void reposition(); virtual void resizeOverlay(); |