--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp Tue Jul 06 15:10:48 2010 +0300
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp Wed Aug 18 10:37:55 2010 +0300
@@ -122,7 +122,7 @@
QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate()
- : viewport(new QDeclarativeItem)
+ : contentItem(new QDeclarativeItem)
, hData(this, &QDeclarativeFlickablePrivate::setRoundedViewportX)
, vData(this, &QDeclarativeFlickablePrivate::setRoundedViewportY)
, flickingHorizontally(false), flickingVertically(false)
@@ -140,8 +140,8 @@
void QDeclarativeFlickablePrivate::init()
{
Q_Q(QDeclarativeFlickable);
- QDeclarative_setParent_noEvent(viewport, q);
- viewport->setParentItem(q);
+ QDeclarative_setParent_noEvent(contentItem, q);
+ contentItem->setParentItem(q);
static int timelineUpdatedIdx = -1;
static int timelineCompletedIdx = -1;
static int flickableTickedIdx = -1;
@@ -158,8 +158,9 @@
q, flickableMovementEndingIdx, Qt::DirectConnection);
q->setAcceptedMouseButtons(Qt::LeftButton);
q->setFiltersChildEvents(true);
- QDeclarativeItemPrivate *viewportPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(viewport));
+ QDeclarativeItemPrivate *viewportPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(contentItem));
viewportPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
+ lastPosTime.invalidate();
}
/*
@@ -181,7 +182,7 @@
void QDeclarativeFlickablePrivate::itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeom, const QRectF &oldGeom)
{
Q_Q(QDeclarativeFlickable);
- if (item == viewport) {
+ if (item == contentItem) {
if (newGeom.x() != oldGeom.x())
emit q->contentXChanged();
if (newGeom.y() != oldGeom.y())
@@ -350,6 +351,8 @@
Flickable places its children on a surface that can be dragged and flicked.
\code
+ import Qt 4.7
+
Flickable {
width: 200; height: 200
contentWidth: image.width; contentHeight: image.height
@@ -576,10 +579,28 @@
viewportMoved();
}
-QDeclarativeItem *QDeclarativeFlickable::viewport()
+/*!
+ \qmlproperty Item Flickable::contentItem
+
+ The internal item that contains the Items to be moved in the Flickable.
+
+ Items declared as children of a Flickable are automatically parented to the Flickable's contentItem.
+
+ Items created dynamically need to be explicitly parented to the \e contentItem:
+ \code
+ Flickable {
+ id: myFlickable
+ function addItem(file) {
+ var component = Qt.createComponent(file)
+ component.createObject(myFlickable.contentItem);
+ }
+ }
+ \endcode
+*/
+QDeclarativeItem *QDeclarativeFlickable::contentItem()
{
Q_D(QDeclarativeFlickable);
- return d->viewport;
+ return d->contentItem;
}
QDeclarativeFlickableVisibleArea *QDeclarativeFlickable::visibleArea()
@@ -620,18 +641,6 @@
}
}
-QDeclarativeFlickable::FlickableDirection QDeclarativeFlickable::flickDirection() const
-{
- qmlInfo(this) << "'flickDirection' is deprecated. Please use 'flickableDirection' instead.";
- return flickableDirection();
-}
-
-void QDeclarativeFlickable::setFlickDirection(FlickableDirection direction)
-{
- qmlInfo(this) << "'flickDirection' is deprecated. Please use 'flickableDirection' instead.";
- setFlickableDirection(direction);
-}
-
void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (interactive && timeline.isActive() && (qAbs(hData.velocity) > 10 || qAbs(vData.velocity) > 10))
@@ -656,7 +665,7 @@
void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
Q_Q(QDeclarativeFlickable);
- if (!interactive || lastPosTime.isNull())
+ if (!interactive || !lastPosTime.isValid())
return;
bool rejectY = false;
bool rejectX = false;
@@ -752,7 +761,7 @@
stealMouse = false;
q->setKeepMouseGrab(false);
pressed = false;
- if (lastPosTime.isNull())
+ if (!lastPosTime.isValid())
return;
if (QDeclarativeItemPrivate::elapsed(lastPosTime) > 100) {
@@ -780,7 +789,7 @@
fixupX();
}
- lastPosTime = QTime();
+ lastPosTime.invalidate();
if (!timeline.isActive())
q->movementEnding();
@@ -896,12 +905,12 @@
void QDeclarativeFlickablePrivate::setRoundedViewportX(qreal x)
{
- viewport->setX(qRound(x));
+ contentItem->setX(qRound(x));
}
void QDeclarativeFlickablePrivate::setRoundedViewportY(qreal y)
{
- viewport->setY(qRound(y));
+ contentItem->setY(qRound(y));
}
void QDeclarativeFlickable::timerEvent(QTimerEvent *event)
@@ -911,8 +920,14 @@
d->delayedPressTimer.stop();
if (d->delayedPressEvent) {
QDeclarativeItem *grabber = scene() ? qobject_cast<QDeclarativeItem*>(scene()->mouseGrabberItem()) : 0;
- if (!grabber || grabber != this)
- scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent);
+ 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 (scene()->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(scene(), d->delayedPressEvent);
+ }
delete d->delayedPressEvent;
d->delayedPressEvent = 0;
}
@@ -944,20 +959,19 @@
{
Q_D(QDeclarativeFlickable);
- int elapsed = QDeclarativeItemPrivate::restart(d->velocityTime);
- if (!elapsed)
- return;
-
qreal prevY = d->lastFlickablePosition.x();
qreal prevX = d->lastFlickablePosition.y();
d->velocityTimeline.clear();
if (d->pressed) {
- qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed;
- qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / elapsed;
- d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing);
- d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing);
- d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing);
- d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing);
+ int elapsed = QDeclarativeItemPrivate::restart(d->velocityTime);
+ if (elapsed > 0) {
+ qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed;
+ qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / elapsed;
+ d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing);
+ d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing);
+ d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing);
+ d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing);
+ }
} else {
if (d->timeline.time() > d->vTime) {
qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
@@ -982,13 +996,13 @@
bool changed = false;
if (newGeometry.width() != oldGeometry.width()) {
if (d->hData.viewSize < 0) {
- d->viewport->setWidth(width());
+ d->contentItem->setWidth(width());
emit contentWidthChanged();
}
}
if (newGeometry.height() != oldGeometry.height()) {
if (d->vData.viewSize < 0) {
- d->viewport->setHeight(height());
+ d->contentItem->setHeight(height());
emit contentHeightChanged();
}
}
@@ -1009,7 +1023,7 @@
{
QDeclarativeItem *i = qobject_cast<QDeclarativeItem *>(o);
if (i)
- i->setParentItem(static_cast<QDeclarativeFlickablePrivate*>(prop->data)->viewport);
+ i->setParentItem(static_cast<QDeclarativeFlickablePrivate*>(prop->data)->contentItem);
else
o->setParent(prop->object);
}
@@ -1023,25 +1037,7 @@
QDeclarativeListProperty<QGraphicsObject> QDeclarativeFlickable::flickableChildren()
{
Q_D(QDeclarativeFlickable);
- return QGraphicsItemPrivate::get(d->viewport)->childrenList();
-}
-
-bool QDeclarativeFlickable::overShoot() const
-{
- Q_D(const QDeclarativeFlickable);
- return d->boundsBehavior == DragAndOvershootBounds;
-}
-
-void QDeclarativeFlickable::setOverShoot(bool o)
-{
- Q_D(QDeclarativeFlickable);
- if ((o && d->boundsBehavior == DragAndOvershootBounds)
- || (!o && d->boundsBehavior == StopAtBounds))
- return;
- qmlInfo(this) << "overshoot is deprecated and will be removed imminently - use boundsBehavior.";
- d->boundsBehavior = o ? DragAndOvershootBounds : StopAtBounds;
- emit boundsBehaviorChanged();
- emit overShootChanged();
+ return QGraphicsItemPrivate::get(d->contentItem)->childrenList();
}
/*!
@@ -1056,11 +1052,11 @@
The \c boundsBehavior can be one of:
\list
- \o \e Flickable.StopAtBounds - the contents can not be dragged beyond the boundary
+ \o Flickable.StopAtBounds - the contents can not be dragged beyond the boundary
of the flickable, and flicks will not overshoot.
- \o \e Flickable.DragOverBounds - the contents can be dragged beyond the boundary
+ \o Flickable.DragOverBounds - the contents can be dragged beyond the boundary
of the Flickable, but flicks will not overshoot.
- \o \e Flickable.DragAndOvershootBounds (default) - the contents can be dragged
+ \o Flickable.DragAndOvershootBounds (default) - the contents can be dragged
beyond the boundary of the Flickable, and can overshoot the
boundary when flicked.
\endlist
@@ -1078,7 +1074,6 @@
return;
d->boundsBehavior = b;
emit boundsBehaviorChanged();
- emit overShootChanged();
}
/*!
@@ -1112,9 +1107,9 @@
return;
d->hData.viewSize = w;
if (w < 0)
- d->viewport->setWidth(width());
+ d->contentItem->setWidth(width());
else
- d->viewport->setWidth(w);
+ d->contentItem->setWidth(w);
// Make sure that we're entirely in view.
if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
int oldDuration = d->fixupDuration;
@@ -1139,9 +1134,9 @@
return;
d->vData.viewSize = h;
if (h < 0)
- d->viewport->setHeight(height());
+ d->contentItem->setHeight(height());
else
- d->viewport->setHeight(h);
+ d->contentItem->setHeight(h);
// Make sure that we're entirely in view.
if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
int oldDuration = d->fixupDuration;
@@ -1219,11 +1214,21 @@
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) {
- scene()->sendEvent(d->delayedPressTarget, 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 (s->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(scene(), d->delayedPressEvent);
d->clearDelayedPress();
+ // We send the release
+ scene()->sendEvent(s->mouseGrabberItem(), event);
+ // And the event has been consumed
+ return true;
}
d->handleMouseReleaseEvent(&mouseEvent);
break;
@@ -1237,8 +1242,8 @@
}
return stealThisEvent || d->delayedPressEvent;
- } else if (!d->lastPosTime.isNull()) {
- d->lastPosTime = QTime();
+ } else if (d->lastPosTime.isValid()) {
+ d->lastPosTime.invalidate();
}
if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
d->clearDelayedPress();
@@ -1337,7 +1342,7 @@
This property holds the time to delay (ms) delivering a press to
children of the Flickable. This can be useful where reacting
- to a press before a flicking action has undesireable effects.
+ to a press before a flicking action has undesirable effects.
If the flickable is dragged/flicked before the delay times out
the press event will not be delivered. If the button is released