summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2011-01-05 11:01:27 +0100
committerBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2011-01-05 11:02:31 +0100
commit785ea734068275783d39b267e76db3729f6312d9 (patch)
tree4c415620edbc91a2cbdabc4b7828fa870fb34080
parent5e6f8cdf53c097af99cab68ee1b8343926d8cbd7 (diff)
Fix some of the mouse/tap issues.
-rw-r--r--src/canvas/qxgraphicsview.cpp4
-rw-r--r--src/graphicsitems/qxflickable.cpp200
-rw-r--r--src/graphicsitems/qxitem.cpp20
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)