aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2017-04-24 20:41:44 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2017-04-25 12:40:13 +0000
commit381a2cf4a5a65f446b41240e8a6e6a6356988cb2 (patch)
tree0c653a2c1f8ef7b95b16a0060693154fd0997a9d
parent039c25daac5ec6b96c0aa074eae2a983a1b5aabd (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.cpp13
-rw-r--r--src/quicktemplates2/qquickpopup.cpp171
-rw-r--r--src/quicktemplates2/qquickpopup_p_p.h5
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();