summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2011-01-06 11:22:23 +0100
committerBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2011-01-06 11:27:10 +0100
commit27a2b8fd87f1a34711fab3adcdf1e16f61c4b0b7 (patch)
tree2e1827dcd7a1e2b15446fa5f41344bf944a94bf2
parenta6ac1e6c4b9804df54e8e9f6b16d98ae7077e8e7 (diff)
Fix PathView issues.
-rw-r--r--src/graphicsitems/qxpathview.cpp197
-rw-r--r--src/graphicsitems/qxpathview_p.h3
-rw-r--r--src/graphicsitems/qxpathview_p_p.h8
3 files changed, 137 insertions, 71 deletions
diff --git a/src/graphicsitems/qxpathview.cpp b/src/graphicsitems/qxpathview.cpp
index 52060cb..b542d83 100644
--- a/src/graphicsitems/qxpathview.cpp
+++ b/src/graphicsitems/qxpathview.cpp
@@ -926,97 +926,138 @@ QPointF QxPathViewPrivate::pointNear(const QPointF &point, qreal *nearPercent) c
void QxPathView::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QxPathView);
- if (!d->interactive || !d->items.count())
+ if (d->interactive) {
+ d->handleMousePressEvent(event);
+ event->accept();
+ } else {
+ QxItem::mousePressEvent(event);
+ }
+}
+
+void QxPathViewPrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_Q(QxPathView);
+ if (!interactive || !items.count())
return;
- QPointF scenePoint = mapToScene(event->pos());
+ QPointF scenePoint = q->mapToScene(event->pos());
int idx = 0;
- for (; idx < d->items.count(); ++idx) {
- QRectF rect = d->items.at(idx)->boundingRect();
- rect = d->items.at(idx)->mapToScene(rect);
+ for (; idx < items.count(); ++idx) {
+ QRectF rect = items.at(idx)->boundingRect();
+ rect = items.at(idx)->mapToScene(rect);
if (rect.contains(scenePoint))
break;
}
- if (idx == d->items.count() && d->dragMargin == 0.) // didn't click on an item
+ if (idx == items.count() && dragMargin == 0.) // didn't click on an item
return;
- d->startPoint = d->pointNear(event->pos(), &d->startPc);
- if (idx == d->items.count()) {
- qreal distance = qAbs(event->pos().x() - d->startPoint.x()) + qAbs(event->pos().y() - d->startPoint.y());
- if (distance > d->dragMargin)
+ startPoint = pointNear(event->pos(), &startPc);
+ if (idx == items.count()) {
+ qreal distance = qAbs(event->pos().x() - startPoint.x()) + qAbs(event->pos().y() - startPoint.y());
+ if (distance > dragMargin)
return;
}
- d->stealMouse = false;
- d->lastElapsed = 0;
- d->lastDist = 0;
- QxItemPrivate::start(d->lastPosTime);
- d->tl.clear();
+ if (tl.isActive() && flicking)
+ stealMouse = true; // If we've been flicked then steal the click.
+ else
+ stealMouse = false;
+
+ lastElapsed = 0;
+ lastDist = 0;
+ QxItemPrivate::start(lastPosTime);
+ tl.clear();
}
+
void QxPathView::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QxPathView);
- if (!d->interactive || !d->lastPosTime.isValid())
+ if (d->interactive) {
+ d->handleMouseMoveEvent(event);
+ if (d->stealMouse)
+ setKeepMouseGrab(true);
+ event->accept();
+ } else {
+ QxItem::mouseMoveEvent(event);
+ }
+}
+
+void QxPathViewPrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_Q(QxPathView);
+ if (!interactive || !lastPosTime.isValid())
return;
qreal newPc;
- QPointF pathPoint = d->pointNear(event->pos(), &newPc);
- if (!d->stealMouse) {
- QPointF delta = pathPoint - d->startPoint;
+ QPointF pathPoint = pointNear(event->pos(), &newPc);
+ if (!stealMouse) {
+ QPointF delta = pathPoint - startPoint;
if (qAbs(delta.x()) > QApplication::startDragDistance() || qAbs(delta.y()) > QApplication::startDragDistance()) {
- d->stealMouse = true;
- d->startPc = newPc;
+ stealMouse = true;
+ startPc = newPc;
}
}
- if (d->stealMouse) {
- d->moveReason = QxPathViewPrivate::Mouse;
- qreal diff = (newPc - d->startPc)*d->model->count()*d->mappedRange;
+ if (stealMouse) {
+ moveReason = QxPathViewPrivate::Mouse;
+ qreal diff = (newPc - startPc)*model->count()*mappedRange;
if (diff) {
- setOffset(d->offset + diff);
+ setOffset(offset + diff);
- if (diff > d->model->count()/2)
- diff -= d->model->count();
- else if (diff < -d->model->count()/2)
- diff += d->model->count();
+ if (diff > model->count()/2)
+ diff -= model->count();
+ else if (diff < -model->count()/2)
+ diff += model->count();
- d->lastElapsed = QxItemPrivate::restart(d->lastPosTime);
- d->lastDist = diff;
- d->startPc = newPc;
+ lastElapsed = QxItemPrivate::restart(lastPosTime);
+ lastDist = diff;
+ startPc = newPc;
}
- if (!d->moving) {
- d->moving = true;
- emit movingChanged();
- emit movementStarted();
+ if (!moving) {
+ moving = true;
+ emit q->movingChanged();
+ emit q->movementStarted();
}
}
}
-void QxPathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *)
+void QxPathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QxPathView);
- d->stealMouse = false;
- setKeepMouseGrab(false);
- if (!d->interactive || !d->lastPosTime.isValid())
+ if (d->interactive) {
+ d->handleMouseReleaseEvent(event);
+ event->accept();
+ ungrabMouse();
+ } else {
+ QxItem::mouseReleaseEvent(event);
+ }
+}
+
+void QxPathViewPrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *)
+{
+ Q_Q(QxPathView);
+ stealMouse = false;
+ q->setKeepMouseGrab(false);
+ if (!interactive || !lastPosTime.isValid())
return;
- qreal elapsed = qreal(d->lastElapsed + QxItemPrivate::elapsed(d->lastPosTime)) / 1000.;
- qreal velocity = elapsed > 0. ? d->lastDist / elapsed : 0;
- if (d->model && d->model->count() && qAbs(velocity) > 1.) {
- qreal count = d->pathItems == -1 ? d->model->count() : d->pathItems;
+ qreal elapsed = qreal(lastElapsed + QxItemPrivate::elapsed(lastPosTime)) / 1000.;
+ qreal velocity = elapsed > 0. ? lastDist / elapsed : 0;
+ if (model && model->count() && qAbs(velocity) > 1.) {
+ qreal count = pathItems == -1 ? model->count() : pathItems;
if (qAbs(velocity) > count * 2) // limit velocity
velocity = (velocity > 0 ? count : -count) * 2;
// Calculate the distance to be travelled
qreal v2 = velocity*velocity;
- qreal accel = d->deceleration/10;
+ qreal accel = deceleration/10;
// + 0.25 to encourage moving at least one item in the flick direction
- qreal dist = qMin(qreal(d->model->count()-1), qreal(v2 / (accel * 2.0) + 0.25));
- if (d->haveHighlightRange && d->highlightRangeMode == QxPathView::StrictlyEnforceRange) {
+ qreal dist = qMin(qreal(model->count()-1), qreal(v2 / (accel * 2.0) + 0.25));
+ if (haveHighlightRange && highlightRangeMode == QxPathView::StrictlyEnforceRange) {
// round to nearest item.
if (velocity > 0.)
- dist = qRound(dist + d->offset) - d->offset;
+ dist = qRound(dist + offset) - offset;
else
- dist = qRound(dist - d->offset) + d->offset;
+ dist = qRound(dist - offset) + offset;
// Calculate accel required to stop on item boundary
if (dist <= 0.) {
dist = 0.;
@@ -1025,15 +1066,36 @@ void QxPathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *)
accel = v2 / (2.0f * qAbs(dist));
}
}
- d->moveOffset.setValue(d->offset);
- d->tl.accel(d->moveOffset, velocity, accel, dist);
- d->tl.callback(QDeclarativeTimeLineCallback(&d->moveOffset, d->fixOffsetCallback, d));
+ moveOffset.setValue(offset);
+ tl.accel(moveOffset, velocity, accel, dist);
+ tl.callback(QDeclarativeTimeLineCallback(&moveOffset, fixOffsetCallback, this));
+ if (!flicking) {
+ flicking = true;
+ emit q->flickingChanged();
+ emit q->flickStarted();
+ }
} else {
- d->fixOffset();
+ fixOffset();
}
- d->lastPosTime.invalidate();
- ungrabMouse();
+ lastPosTime.invalidate();
+ if (!tl.isActive())
+ movementEnding();
+}
+
+void QxPathViewPrivate::movementEnding()
+{
+ Q_Q(QxPathView);
+ if (flicking) {
+ flicking = false;
+ emit q->flickingChanged();
+ emit q->flickEnded();
+ }
+ if (moving && !stealMouse) {
+ moving = false;
+ emit q->movingChanged();
+ emit q->movementEnded();
+ }
}
bool QxPathView::sendMouseEvent(QGraphicsSceneMouseEvent *event)
@@ -1041,8 +1103,9 @@ bool QxPathView::sendMouseEvent(QGraphicsSceneMouseEvent *event)
Q_D(QxPathView);
QGraphicsSceneMouseEvent mouseEvent(event->type());
QRectF myRect = mapToScene(QRectF(0, 0, width(), height()));
- QxItem *grabber = d->view ? qobject_cast<QxItem*>(d->view->mouseGrabberItem()) : 0;
- if ((d->stealMouse || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) {
+ 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) {
@@ -1061,6 +1124,7 @@ bool QxPathView::sendMouseEvent(QGraphicsSceneMouseEvent *event)
break;
case QEvent::GraphicsSceneMousePress:
mousePressEvent(&mouseEvent);
+ stealThisEvent = d->stealMouse;
break;
case QEvent::GraphicsSceneMouseRelease:
mouseReleaseEvent(&mouseEvent);
@@ -1068,14 +1132,16 @@ bool QxPathView::sendMouseEvent(QGraphicsSceneMouseEvent *event)
default:
break;
}
- grabber = d->view ? qobject_cast<QxItem*>(d->view->mouseGrabberItem()) : 0;
- if (grabber && d->stealMouse && !grabber->keepMouseGrab() && grabber != this)
+ grabber = mouseGrabberItem();
+ if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
grabMouse();
return d->stealMouse;
} else if (d->lastPosTime.isValid()) {
d->lastPosTime.invalidate();
}
+ if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease)
+ d->stealMouse = false;
return false;
}
@@ -1090,12 +1156,7 @@ bool QxPathView::sceneEventFilter(QxItem *i, QEvent *e)
case QEvent::GraphicsSceneMousePress:
case QEvent::GraphicsSceneMouseMove:
case QEvent::GraphicsSceneMouseRelease:
- {
- bool ret = sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e));
- if (e->type() == QEvent::GraphicsSceneMouseRelease)
- return ret;
- break;
- }
+ return sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e));
default:
break;
}
@@ -1364,11 +1425,7 @@ void QxPathView::ticked()
void QxPathView::onTimeLineCompleted()
{
Q_D(QxPathView);
- if (d->moving && !d->stealMouse) {
- d->moving = false;
- emit movingChanged();
- emit movementEnded();
- }
+ d->movementEnding();
}
// find the item closest to the snap position
diff --git a/src/graphicsitems/qxpathview_p.h b/src/graphicsitems/qxpathview_p.h
index 9c8dee0..64bd2ae 100644
--- a/src/graphicsitems/qxpathview_p.h
+++ b/src/graphicsitems/qxpathview_p.h
@@ -142,6 +142,9 @@ Q_SIGNALS:
void movingChanged();
void movementStarted();
void movementEnded();
+ void flickingChanged();
+ void flickStarted();
+ void flickEnded();
void preferredHighlightBeginChanged();
void preferredHighlightEndChanged();
void highlightRangeModeChanged();
diff --git a/src/graphicsitems/qxpathview_p_p.h b/src/graphicsitems/qxpathview_p_p.h
index 210cc7c..d2f0698 100644
--- a/src/graphicsitems/qxpathview_p_p.h
+++ b/src/graphicsitems/qxpathview_p_p.h
@@ -77,7 +77,7 @@ public:
, lastElapsed(0), mappedRange(1.0)
, stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true)
, autoHighlight(true), highlightUp(false), layoutScheduled(false)
- , moving(false)
+ , moving(false), flicking(false)
, dragMargin(0), deceleration(100)
, moveOffset(this, &QxPathViewPrivate::setOffset)
, firstIndex(-1), pathItems(-1), requestedIndex(-1)
@@ -116,6 +116,11 @@ public:
}
}
+ void movementEnding();
+ void handleMousePressEvent(QGraphicsSceneMouseEvent *event);
+ void handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void handleMouseMoveEvent(QGraphicsSceneMouseEvent *event);
+
QxItem *getItem(int modelIndex);
void releaseItem(QxItem *item);
QxPathViewAttached *attached(QxItem *item);
@@ -157,6 +162,7 @@ public:
bool highlightUp : 1;
bool layoutScheduled : 1;
bool moving;
+ bool flicking;
QElapsedTimer lastPosTime;
QPointF lastPos;
qreal dragMargin;