diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2011-01-05 11:01:27 +0100 |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2011-01-05 11:02:31 +0100 |
commit | 785ea734068275783d39b267e76db3729f6312d9 (patch) | |
tree | 4c415620edbc91a2cbdabc4b7828fa870fb34080 | |
parent | 5e6f8cdf53c097af99cab68ee1b8343926d8cbd7 (diff) |
Fix some of the mouse/tap issues.
-rw-r--r-- | src/canvas/qxgraphicsview.cpp | 4 | ||||
-rw-r--r-- | src/graphicsitems/qxflickable.cpp | 200 | ||||
-rw-r--r-- | src/graphicsitems/qxitem.cpp | 20 |
3 files changed, 127 insertions, 97 deletions
diff --git a/src/canvas/qxgraphicsview.cpp b/src/canvas/qxgraphicsview.cpp index af661b8..321f138 100644 --- a/src/canvas/qxgraphicsview.cpp +++ b/src/canvas/qxgraphicsview.cpp @@ -292,6 +292,7 @@ QGraphicsSceneMouseEvent *QxGraphicsViewPrivate::sceneMouseEvent(QMouseEvent *e, g->setButtons(e->buttons()); g->setButton(e->button()); g->setModifiers(e->modifiers()); + g->setAccepted(false); return g; } @@ -323,7 +324,8 @@ bool QxGraphicsViewPrivate::deliverInitialMouseEvent(QxItem *o, QMouseEvent *e) children = QxItemPrivate::get(children)->nextSibling; } - if (filter) mouseFilters.removeLast(); + if (filter && !mouseFilters.isEmpty()) + mouseFilters.removeLast(); if (op->acceptedButtons & e->button()) { bool ok = false; diff --git a/src/graphicsitems/qxflickable.cpp b/src/graphicsitems/qxflickable.cpp index 0287205..ce2ebc6 100644 --- a/src/graphicsitems/qxflickable.cpp +++ b/src/graphicsitems/qxflickable.cpp @@ -634,10 +634,12 @@ void QxFlickable::setFlickDirection(FlickableDirection direction) void QxFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event) { + Q_Q(QxFlickable); if (interactive && timeline.isActive() && (qAbs(hData.velocity) > 10 || qAbs(vData.velocity) > 10)) stealMouse = true; // If we've been flicked then steal the click. else stealMouse = false; + q->setKeepMouseGrab(stealMouse); pressed = true; timeline.clear(); hData.velocity = 0; @@ -662,6 +664,8 @@ void QxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) return; bool rejectY = false; bool rejectX = false; + bool stealY = stealMouse; + bool stealX = stealMouse; if (q->yflick()) { int dy = int(event->pos().y() - pressPos.y()); @@ -676,19 +680,22 @@ void QxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) if (newY < maxY && maxY - minY <= 0) newY = maxY + (newY - maxY) / 2; if (boundsBehavior == QxFlickable::StopAtBounds && (newY > minY || newY < maxY)) { - if (newY > minY) - newY = minY; - else if (newY < maxY) + rejectY = true; + if (newY < maxY) { newY = maxY; - else - rejectY = true; + rejectY = false; + } + if (newY > minY) { + newY = minY; + rejectY = false; + } } if (!rejectY && stealMouse) { vData.move.setValue(qRound(newY)); vMoved = true; } if (qAbs(dy) > QApplication::startDragDistance()) - stealMouse = true; + stealY = true; } } @@ -705,12 +712,15 @@ void QxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) if (newX < maxX && maxX - minX <= 0) newX = maxX + (newX - maxX) / 2; if (boundsBehavior == QxFlickable::StopAtBounds && (newX > minX || newX < maxX)) { - if (newX > minX) - newX = minX; - else if (newX < maxX) + rejectX = true; + if (newX < maxX) { newX = maxX; - else - rejectX = true; + rejectX = false; + } + if (newX > minX) { + newX = minX; + rejectX = false; + } } if (!rejectX && stealMouse) { hData.move.setValue(qRound(newX)); @@ -718,10 +728,15 @@ void QxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) } if (qAbs(dx) > QApplication::startDragDistance()) - stealMouse = true; + stealX = true; + } } + stealMouse = stealX || stealY; + if (stealMouse) + q->setKeepMouseGrab(true); + if (!lastPos.isNull()) { qreal elapsed = qreal(lastPosTime.restart()) / 1000.; if (elapsed <= 0) @@ -768,23 +783,15 @@ void QxFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event } vTime = timeline.time(); - if (qAbs(vData.velocity) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) { - qreal velocity = vData.velocity; - if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks. - velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity; - flickY(velocity); - } else { + if (qAbs(vData.velocity) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) + flickY(vData.velocity); + else fixupY(); - } - if (qAbs(hData.velocity) > 10 && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) { - qreal velocity = hData.velocity; - if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks. - velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity; - flickX(velocity); - } else { + if (qAbs(hData.velocity) > 10 && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) + flickX(hData.velocity); + else fixupX(); - } lastPosTime.invalidate(); @@ -808,8 +815,6 @@ void QxFlickable::mouseMoveEvent(QGraphicsSceneMouseEvent *event) Q_D(QxFlickable); if (d->interactive) { d->handleMouseMoveEvent(event); - if (d->stealMouse) - setKeepMouseGrab(true); event->accept(); } else { QxItem::mouseMoveEvent(event); @@ -913,19 +918,24 @@ void QxFlickablePrivate::setRoundedViewportY(qreal y) void QxFlickable::timerEvent(QTimerEvent *event) { Q_D(QxFlickable); + if (event->timerId() == d->delayedPressTimer.timerId()) { d->delayedPressTimer.stop(); if (d->delayedPressEvent) { - // XXX akennedy - /* - QxItem *grabber = qobject_cast<QxItem *>(mouseGrabberItem()); - if (!grabber || grabber != this) - scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent); - */ + QxItem *grabber = mouseGrabberItem(); + if (!grabber || grabber != this) { + // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay) + // so we reset the grabber + if (grabber == d->delayedPressTarget) + d->delayedPressTarget->ungrabMouse(); + //Use the event handler that will take care of finding the proper item to propagate the event + QApplication::sendEvent(QApplication::focusWidget(), d->delayedPressEvent); + } delete d->delayedPressEvent; d->delayedPressEvent = 0; } } + } qreal QxFlickable::minYExtent() const @@ -1179,64 +1189,72 @@ bool QxFlickable::yflick() const bool QxFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QxFlickable); - QGraphicsSceneMouseEvent mouseEvent(event->type()); - QRectF myRect = mapToScene(QRectF(0, 0, width(), height())); - - QxItem *grabber = qobject_cast<QxItem *>(mouseGrabberItem()); - bool stealThisEvent = d->stealMouse; - - if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) { - mouseEvent.setAccepted(false); - for (int i = 0x1; i <= 0x10; i <<= 1) { - if (event->buttons() & i) { - Qt::MouseButton button = Qt::MouseButton(i); - mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button))); - } - } - mouseEvent.setScenePos(event->scenePos()); - mouseEvent.setLastScenePos(event->lastScenePos()); - mouseEvent.setPos(mapFromScene(event->scenePos())); - mouseEvent.setLastPos(mapFromScene(event->lastScenePos())); - - switch(mouseEvent.type()) { - case QEvent::GraphicsSceneMouseMove: - d->handleMouseMoveEvent(&mouseEvent); - break; - case QEvent::GraphicsSceneMousePress: - if (d->delayedPressEvent) - return false; - - d->handleMousePressEvent(&mouseEvent); - d->captureDelayedPress(event); - break; - case QEvent::GraphicsSceneMouseRelease: - if (d->delayedPressEvent) { - // XXX akennedy - /* - scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent); - d->clearDelayedPress(); - */ - } - d->handleMouseReleaseEvent(&mouseEvent); - break; - default: - break; - } - grabber = qobject_cast<QxItem*>(mouseGrabberItem()); - if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) { - d->clearDelayedPress(); - grabMouse(); - } - return stealThisEvent || d->delayedPressEvent; - } else if (d->lastPosTime.isValid()) { - d->lastPosTime.invalidate(); - } - if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) { - d->clearDelayedPress(); - d->stealMouse = false; - } - return false; + QGraphicsSceneMouseEvent mouseEvent(event->type()); + QRectF myRect = mapToScene(QRectF(0, 0, width(), height())); + + QxItem *grabber = mouseGrabberItem(); + bool stealThisEvent = d->stealMouse; + if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) { + mouseEvent.setAccepted(false); + for (int i = 0x1; i <= 0x10; i <<= 1) { + if (event->buttons() & i) { + Qt::MouseButton button = Qt::MouseButton(i); + mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button))); + } + } + mouseEvent.setScenePos(event->scenePos()); + mouseEvent.setLastScenePos(event->lastScenePos()); + mouseEvent.setPos(mapFromScene(event->scenePos())); + mouseEvent.setLastPos(mapFromScene(event->lastScenePos())); + + switch(mouseEvent.type()) { + case QEvent::GraphicsSceneMouseMove: + d->handleMouseMoveEvent(&mouseEvent); + break; + case QEvent::GraphicsSceneMousePress: + if (d->delayedPressEvent) + return false; + + d->handleMousePressEvent(&mouseEvent); + d->captureDelayedPress(event); + stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above + break; + case QEvent::GraphicsSceneMouseRelease: + if (d->delayedPressEvent) { + // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay) + // so we reset the grabber + if (mouseGrabberItem() == d->delayedPressTarget) + d->delayedPressTarget->ungrabMouse(); + //Use the event handler that will take care of finding the proper item to propagate the event + QApplication::sendEvent(QApplication::focusWidget(), d->delayedPressEvent); + d->clearDelayedPress(); + // We send the release + QApplication::sendEvent(mouseGrabberItem(), event); + // And the event has been consumed + return true; + } + d->handleMouseReleaseEvent(&mouseEvent); + break; + default: + break; + } + grabber = qobject_cast<QxItem*>(mouseGrabberItem()); + if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) { + d->clearDelayedPress(); + grabMouse(); + } + + return stealThisEvent || d->delayedPressEvent; + } else if (d->lastPosTime.isValid()) { + d->lastPosTime.invalidate(); + } + if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) { + d->clearDelayedPress(); + d->stealMouse = false; + d->pressed = false; + } + return false; } bool QxFlickable::sceneEventFilter(QxItem *i, QEvent *e) diff --git a/src/graphicsitems/qxitem.cpp b/src/graphicsitems/qxitem.cpp index 4af41e7..b297dcb 100644 --- a/src/graphicsitems/qxitem.cpp +++ b/src/graphicsitems/qxitem.cpp @@ -67,6 +67,7 @@ #include <QGraphicsSceneMouseEvent> #include <QtCore/qnumeric.h> #include <QtScript/qscriptengine.h> +#include <QtGui/qapplication.h> #ifndef FLT_MAX #define FLT_MAX 1E+37 @@ -1328,10 +1329,13 @@ void QxItem::grabMouse() { Q_D(QxItem); - QxGraphicsViewPrivate *v = QxGraphicsViewPrivate::get(d->view); + QxGraphicsView *view = d->view; + if (!view && qApp) + view = qobject_cast<QxGraphicsView *>(QApplication::focusWidget()); - if (mouseGrabberItem()) { - QxItem *grabber = v->mouseGrabber; + QxGraphicsViewPrivate *v = QxGraphicsViewPrivate::get(view); + + if (QxItem *grabber = mouseGrabberItem()) { v->mouseFilters.clear(); QEvent e(QEvent::UngrabMouse); grabber->sceneEvent(&e); @@ -1345,7 +1349,10 @@ void QxItem::ungrabMouse() Q_D(QxItem); if (this == mouseGrabberItem()) { - QxGraphicsViewPrivate *v = QxGraphicsViewPrivate::get(d->view); + QxGraphicsView *view = d->view; + if (!view && qApp) + view = qobject_cast<QxGraphicsView *>(QApplication::focusWidget()); + QxGraphicsViewPrivate *v = QxGraphicsViewPrivate::get(view); QxItem *grabber = v->mouseGrabber; v->mouseFilters.clear(); QEvent e(QEvent::UngrabMouse); @@ -1357,7 +1364,10 @@ void QxItem::ungrabMouse() QxItem *QxItem::mouseGrabberItem() const { Q_D(const QxItem); - return d->view?QxGraphicsViewPrivate::get(d->view)->mouseGrabber:0; + QxGraphicsView *view = d->view; + if (!view && qApp) + view = qobject_cast<QxGraphicsView *>(QApplication::focusWidget()); + return view ? QxGraphicsViewPrivate::get(view)->mouseGrabber : 0; } static void children_append(QDeclarativeListProperty<QxItem> *p, QxItem *o) |