diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2017-04-26 13:50:54 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2017-04-26 15:53:39 +0000 |
commit | 3326439361d3ec4e60bcdb189e6bfb75189136ca (patch) | |
tree | 445d502e9edea0b686164b2207fed8310f943a14 | |
parent | cf67bb976e082105994ff00a2616129833edb857 (diff) |
Revise the press/move/release handlers
Otherwise the handlers are not able to control whether presses, moves
and releases should be blocked or not.
a) outside a non-modal popup,
b) to popup children/content, or
b) outside a modal popups's background dimming
Change-Id: I637295fc3122cdcddb7727ec3939ec6a68a3cf98
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r-- | src/quicktemplates2/qquickdrawer.cpp | 28 | ||||
-rw-r--r-- | src/quicktemplates2/qquickdrawer_p_p.h | 6 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup.cpp | 58 | ||||
-rw-r--r-- | src/quicktemplates2/qquickpopup_p_p.h | 12 |
4 files changed, 58 insertions, 46 deletions
diff --git a/src/quicktemplates2/qquickdrawer.cpp b/src/quicktemplates2/qquickdrawer.cpp index c2597cc4..66ba74a2 100644 --- a/src/quicktemplates2/qquickdrawer.cpp +++ b/src/quicktemplates2/qquickdrawer.cpp @@ -330,36 +330,42 @@ bool QQuickDrawerPrivate::grabMouse(QQuickItem *item, QMouseEvent *event) static const qreal openCloseVelocityThreshold = 300; -void QQuickDrawerPrivate::handlePress(const QPointF &point, ulong timestamp) +bool QQuickDrawerPrivate::handlePress(QQuickItem *item, const QPointF &point, ulong timestamp) { - QQuickPopupPrivate::handlePress(point, timestamp); + if (!QQuickPopupPrivate::handlePress(item, point, timestamp)) + return false; offset = 0; pressPoint = point; velocityCalculator.startMeasuring(point, timestamp); + + return true; } -void QQuickDrawerPrivate::handleMove(const QPointF &point, ulong timestamp) +bool QQuickDrawerPrivate::handleMove(QQuickItem *item, const QPointF &point, ulong timestamp) { Q_Q(QQuickDrawer); - QQuickPopupPrivate::handleMove(point, timestamp); + if (!QQuickPopupPrivate::handleMove(item, point, timestamp)) + return false; // limit/reset the offset to the edge of the drawer when pushed from the outside if (qFuzzyCompare(position, 1.0) && !popupItem->contains(popupItem->mapFromScene(point))) offset = 0; - if (popupItem->keepMouseGrab() || popupItem->keepTouchGrab()) + bool isGrabbed = popupItem->keepMouseGrab() || popupItem->keepTouchGrab(); + if (isGrabbed) q->setPosition(positionAt(point) - offset); + + return isGrabbed; } -void QQuickDrawerPrivate::handleRelease(const QPointF &point, ulong timestamp) +bool QQuickDrawerPrivate::handleRelease(QQuickItem *item, const QPointF &point, ulong timestamp) { pressPoint = QPointF(); if (!popupItem->keepMouseGrab() && !popupItem->keepTouchGrab()) { velocityCalculator.reset(); - QQuickPopupPrivate::handleRelease(point, timestamp); - return; + return QQuickPopupPrivate::handleRelease(item, point, timestamp); } velocityCalculator.stopMeasuring(point, timestamp); @@ -414,8 +420,11 @@ void QQuickDrawerPrivate::handleRelease(const QPointF &point, ulong timestamp) } } + bool wasGrabbed = popupItem->keepMouseGrab() || popupItem->keepTouchGrab(); popupItem->setKeepMouseGrab(false); popupItem->setKeepTouchGrab(false); + + return wasGrabbed; } void QQuickDrawerPrivate::handleUngrab() @@ -610,8 +619,7 @@ bool QQuickDrawer::childMouseEventFilter(QQuickItem *child, QEvent *event) return d->grabMouse(child, static_cast<QMouseEvent *>(event)); case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: - d->handleMouseEvent(child, static_cast<QMouseEvent *>(event)); - break; + return d->handleMouseEvent(child, static_cast<QMouseEvent *>(event)); default: break; } diff --git a/src/quicktemplates2/qquickdrawer_p_p.h b/src/quicktemplates2/qquickdrawer_p_p.h index 4c577982..bcfd7206 100644 --- a/src/quicktemplates2/qquickdrawer_p_p.h +++ b/src/quicktemplates2/qquickdrawer_p_p.h @@ -73,9 +73,9 @@ public: bool startDrag(QEvent *event); bool grabMouse(QQuickItem *item, QMouseEvent *event); - void handlePress(const QPointF &point, ulong timestamp) override; - void handleMove(const QPointF &point, ulong timestamp) override; - void handleRelease(const QPointF &point, ulong timestamp) override; + bool handlePress(QQuickItem* item, const QPointF &point, ulong timestamp) override; + bool handleMove(QQuickItem* item, const QPointF &point, ulong timestamp) override; + bool handleRelease(QQuickItem* item, const QPointF &point, ulong timestamp) override; void handleUngrab() override; bool prepareEnterTransition() override; diff --git a/src/quicktemplates2/qquickpopup.cpp b/src/quicktemplates2/qquickpopup.cpp index b4c3b84e..ccbfd3c8 100644 --- a/src/quicktemplates2/qquickpopup.cpp +++ b/src/quicktemplates2/qquickpopup.cpp @@ -307,22 +307,34 @@ bool QQuickPopupPrivate::acceptTouch(const QTouchEvent::TouchPoint &point) return false; } -void QQuickPopupPrivate::handlePress(const QPointF &point, ulong timestamp) +bool QQuickPopupPrivate::blockInput(QQuickItem *item, const QPointF &point) const +{ + // don't block presses and releases + // a) outside a non-modal popup, + // b) to popup children/content, or + // b) outside a modal popups's background dimming + return modal && !popupItem->isAncestorOf(item) && (!dimmer || dimmer->contains(dimmer->mapFromScene(point))); +} + +bool QQuickPopupPrivate::handlePress(QQuickItem *item, const QPointF &point, ulong timestamp) { Q_UNUSED(timestamp); tryClose(point, QQuickPopup::CloseOnPressOutside | QQuickPopup::CloseOnPressOutsideParent); + return blockInput(item, point); } -void QQuickPopupPrivate::handleMove(const QPointF &, ulong timestamp) +bool QQuickPopupPrivate::handleMove(QQuickItem *item, const QPointF &point, ulong timestamp) { Q_UNUSED(timestamp); + return blockInput(item, point); } -void QQuickPopupPrivate::handleRelease(const QPointF &point, ulong timestamp) +bool QQuickPopupPrivate::handleRelease(QQuickItem *item, const QPointF &point, ulong timestamp) { Q_UNUSED(timestamp); tryClose(point, QQuickPopup::CloseOnReleaseOutside | QQuickPopup::CloseOnReleaseOutsideParent); touchId = -1; + return blockInput(item, point); } void QQuickPopupPrivate::handleUngrab() @@ -337,32 +349,29 @@ void QQuickPopupPrivate::handleUngrab() touchId = -1; } -void QQuickPopupPrivate::handleMouseEvent(QQuickItem *item, QMouseEvent *event) +bool QQuickPopupPrivate::handleMouseEvent(QQuickItem *item, QMouseEvent *event) { QPointF pos = item->mapToScene(event->localPos()); switch (event->type()) { case QEvent::MouseButtonPress: - handlePress(pos, event->timestamp()); - break; + return handlePress(item, pos, event->timestamp()); case QEvent::MouseMove: - handleMove(pos, event->timestamp()); - break; + return handleMove(item, pos, event->timestamp()); case QEvent::MouseButtonRelease: - handleRelease(pos, event->timestamp()); - break; + return handleRelease(item, pos, event->timestamp()); default: Q_UNREACHABLE(); - break; + return false; } } -void QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event) +bool 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()), event->timestamp()); + return handlePress(item, item->mapToScene(point.pos()), event->timestamp()); } break; @@ -373,14 +382,11 @@ void QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event) switch (point.state()) { case Qt::TouchPointPressed: - handlePress(item->mapToScene(point.pos()), event->timestamp()); - break; + return handlePress(item, item->mapToScene(point.pos()), event->timestamp()); case Qt::TouchPointMoved: - handleMove(item->mapToScene(point.pos()), event->timestamp()); - break; + return handleMove(item, item->mapToScene(point.pos()), event->timestamp()); case Qt::TouchPointReleased: - handleRelease(item->mapToScene(point.pos()), event->timestamp()); - break; + return handleRelease(item, item->mapToScene(point.pos()), event->timestamp()); default: break; } @@ -390,7 +396,7 @@ void QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event) case QEvent::TouchEnd: for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { if (acceptTouch(point)) - handleRelease(item->mapToScene(point.pos()), event->timestamp()); + return handleRelease(item, item->mapToScene(point.pos()), event->timestamp()); } break; @@ -401,6 +407,8 @@ void QQuickPopupPrivate::handleTouchEvent(QQuickItem *item, QTouchEvent *event) default: break; } + + return false; } bool QQuickPopupPrivate::prepareEnterTransition() @@ -1959,17 +1967,11 @@ 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; + return d->handleTouchEvent(item, static_cast<QTouchEvent *>(event)); case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: - if (d->modal) - event->accept(); - d->handleMouseEvent(item, static_cast<QMouseEvent *>(event)); - return d->modal; + return d->handleMouseEvent(item, static_cast<QMouseEvent *>(event)); default: return false; diff --git a/src/quicktemplates2/qquickpopup_p_p.h b/src/quicktemplates2/qquickpopup_p_p.h index 56226bd9..5c2fe4f7 100644 --- a/src/quicktemplates2/qquickpopup_p_p.h +++ b/src/quicktemplates2/qquickpopup_p_p.h @@ -98,13 +98,15 @@ public: bool tryClose(const QPointF &pos, QQuickPopup::ClosePolicy flags); virtual bool acceptTouch(const QTouchEvent::TouchPoint &point); - virtual void handlePress(const QPointF &point, ulong timestamp); - virtual void handleMove(const QPointF &point, ulong timestamp); - virtual void handleRelease(const QPointF &point, ulong timestamp); + virtual bool blockInput(QQuickItem *item, const QPointF &point) const; + + virtual bool handlePress(QQuickItem* item, const QPointF &point, ulong timestamp); + virtual bool handleMove(QQuickItem* item, const QPointF &point, ulong timestamp); + virtual bool handleRelease(QQuickItem* item, const QPointF &point, ulong timestamp); virtual void handleUngrab(); - void handleMouseEvent(QQuickItem *item, QMouseEvent *event); - void handleTouchEvent(QQuickItem *item, QTouchEvent *event); + bool handleMouseEvent(QQuickItem *item, QMouseEvent *event); + bool handleTouchEvent(QQuickItem *item, QTouchEvent *event); virtual void reposition(); virtual void resizeOverlay(); |