src/declarative/graphicsitems/qdeclarativeflickable.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
   120         emit pageChanged();
   120         emit pageChanged();
   121 }
   121 }
   122 
   122 
   123 
   123 
   124 QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate()
   124 QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate()
   125   : viewport(new QDeclarativeItem)
   125   : contentItem(new QDeclarativeItem)
   126     , hData(this, &QDeclarativeFlickablePrivate::setRoundedViewportX)
   126     , hData(this, &QDeclarativeFlickablePrivate::setRoundedViewportX)
   127     , vData(this, &QDeclarativeFlickablePrivate::setRoundedViewportY)
   127     , vData(this, &QDeclarativeFlickablePrivate::setRoundedViewportY)
   128     , flickingHorizontally(false), flickingVertically(false)
   128     , flickingHorizontally(false), flickingVertically(false)
   129     , hMoved(false), vMoved(false)
   129     , hMoved(false), vMoved(false)
   130     , movingHorizontally(false), movingVertically(false)
   130     , movingHorizontally(false), movingVertically(false)
   138 }
   138 }
   139 
   139 
   140 void QDeclarativeFlickablePrivate::init()
   140 void QDeclarativeFlickablePrivate::init()
   141 {
   141 {
   142     Q_Q(QDeclarativeFlickable);
   142     Q_Q(QDeclarativeFlickable);
   143     QDeclarative_setParent_noEvent(viewport, q);
   143     QDeclarative_setParent_noEvent(contentItem, q);
   144     viewport->setParentItem(q);
   144     contentItem->setParentItem(q);
   145     static int timelineUpdatedIdx = -1;
   145     static int timelineUpdatedIdx = -1;
   146     static int timelineCompletedIdx = -1;
   146     static int timelineCompletedIdx = -1;
   147     static int flickableTickedIdx = -1;
   147     static int flickableTickedIdx = -1;
   148     static int flickableMovementEndingIdx = -1;
   148     static int flickableMovementEndingIdx = -1;
   149     if (timelineUpdatedIdx == -1) {
   149     if (timelineUpdatedIdx == -1) {
   156                          q, flickableTickedIdx, Qt::DirectConnection);
   156                          q, flickableTickedIdx, Qt::DirectConnection);
   157     QMetaObject::connect(&timeline, timelineCompletedIdx,
   157     QMetaObject::connect(&timeline, timelineCompletedIdx,
   158                          q, flickableMovementEndingIdx, Qt::DirectConnection);
   158                          q, flickableMovementEndingIdx, Qt::DirectConnection);
   159     q->setAcceptedMouseButtons(Qt::LeftButton);
   159     q->setAcceptedMouseButtons(Qt::LeftButton);
   160     q->setFiltersChildEvents(true);
   160     q->setFiltersChildEvents(true);
   161     QDeclarativeItemPrivate *viewportPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(viewport));
   161     QDeclarativeItemPrivate *viewportPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(contentItem));
   162     viewportPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
   162     viewportPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
       
   163     lastPosTime.invalidate();
   163 }
   164 }
   164 
   165 
   165 /*
   166 /*
   166     Returns the amount to overshoot by given a velocity.
   167     Returns the amount to overshoot by given a velocity.
   167     Will be roughly in range 0 - size/4
   168     Will be roughly in range 0 - size/4
   179 }
   180 }
   180 
   181 
   181 void QDeclarativeFlickablePrivate::itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeom, const QRectF &oldGeom)
   182 void QDeclarativeFlickablePrivate::itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeom, const QRectF &oldGeom)
   182 {
   183 {
   183     Q_Q(QDeclarativeFlickable);
   184     Q_Q(QDeclarativeFlickable);
   184     if (item == viewport) {
   185     if (item == contentItem) {
   185         if (newGeom.x() != oldGeom.x())
   186         if (newGeom.x() != oldGeom.x())
   186             emit q->contentXChanged();
   187             emit q->contentXChanged();
   187         if (newGeom.y() != oldGeom.y())
   188         if (newGeom.y() != oldGeom.y())
   188             emit q->contentYChanged();
   189             emit q->contentYChanged();
   189     }
   190     }
   348     \inherits Item
   349     \inherits Item
   349 
   350 
   350     Flickable places its children on a surface that can be dragged and flicked.
   351     Flickable places its children on a surface that can be dragged and flicked.
   351 
   352 
   352     \code
   353     \code
       
   354     import Qt 4.7
       
   355 
   353     Flickable {
   356     Flickable {
   354         width: 200; height: 200
   357         width: 200; height: 200
   355         contentWidth: image.width; contentHeight: image.height
   358         contentWidth: image.width; contentHeight: image.height
   356 
   359 
   357         Image { id: image; source: "bigImage.png" }
   360         Image { id: image; source: "bigImage.png" }
   574 void QDeclarativeFlickable::ticked()
   577 void QDeclarativeFlickable::ticked()
   575 {
   578 {
   576     viewportMoved();
   579     viewportMoved();
   577 }
   580 }
   578 
   581 
   579 QDeclarativeItem *QDeclarativeFlickable::viewport()
   582 /*!
   580 {
   583     \qmlproperty Item Flickable::contentItem
   581     Q_D(QDeclarativeFlickable);
   584 
   582     return d->viewport;
   585     The internal item that contains the Items to be moved in the Flickable.
       
   586 
       
   587     Items declared as children of a Flickable are automatically parented to the Flickable's contentItem.
       
   588 
       
   589     Items created dynamically need to be explicitly parented to the \e contentItem:
       
   590     \code
       
   591     Flickable {
       
   592         id: myFlickable
       
   593         function addItem(file) {
       
   594             var component = Qt.createComponent(file)
       
   595             component.createObject(myFlickable.contentItem);
       
   596         }
       
   597     }
       
   598     \endcode
       
   599 */
       
   600 QDeclarativeItem *QDeclarativeFlickable::contentItem()
       
   601 {
       
   602     Q_D(QDeclarativeFlickable);
       
   603     return d->contentItem;
   583 }
   604 }
   584 
   605 
   585 QDeclarativeFlickableVisibleArea *QDeclarativeFlickable::visibleArea()
   606 QDeclarativeFlickableVisibleArea *QDeclarativeFlickable::visibleArea()
   586 {
   607 {
   587     Q_D(QDeclarativeFlickable);
   608     Q_D(QDeclarativeFlickable);
   616     Q_D(QDeclarativeFlickable);
   637     Q_D(QDeclarativeFlickable);
   617     if (direction != d->flickableDirection) {
   638     if (direction != d->flickableDirection) {
   618         d->flickableDirection = direction;
   639         d->flickableDirection = direction;
   619         emit flickableDirectionChanged();
   640         emit flickableDirectionChanged();
   620     }
   641     }
   621 }
       
   622 
       
   623 QDeclarativeFlickable::FlickableDirection QDeclarativeFlickable::flickDirection() const
       
   624 {
       
   625     qmlInfo(this) << "'flickDirection' is deprecated. Please use 'flickableDirection' instead.";
       
   626     return flickableDirection();
       
   627 }
       
   628 
       
   629 void QDeclarativeFlickable::setFlickDirection(FlickableDirection direction)
       
   630 {
       
   631     qmlInfo(this) << "'flickDirection' is deprecated. Please use 'flickableDirection' instead.";
       
   632     setFlickableDirection(direction);
       
   633 }
   642 }
   634 
   643 
   635 void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event)
   644 void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event)
   636 {
   645 {
   637     if (interactive && timeline.isActive() && (qAbs(hData.velocity) > 10 || qAbs(vData.velocity) > 10))
   646     if (interactive && timeline.isActive() && (qAbs(hData.velocity) > 10 || qAbs(vData.velocity) > 10))
   654 }
   663 }
   655 
   664 
   656 void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event)
   665 void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event)
   657 {
   666 {
   658     Q_Q(QDeclarativeFlickable);
   667     Q_Q(QDeclarativeFlickable);
   659     if (!interactive || lastPosTime.isNull())
   668     if (!interactive || !lastPosTime.isValid())
   660         return;
   669         return;
   661     bool rejectY = false;
   670     bool rejectY = false;
   662     bool rejectX = false;
   671     bool rejectX = false;
   663 
   672 
   664     if (q->yflick()) {
   673     if (q->yflick()) {
   750 {
   759 {
   751     Q_Q(QDeclarativeFlickable);
   760     Q_Q(QDeclarativeFlickable);
   752     stealMouse = false;
   761     stealMouse = false;
   753     q->setKeepMouseGrab(false);
   762     q->setKeepMouseGrab(false);
   754     pressed = false;
   763     pressed = false;
   755     if (lastPosTime.isNull())
   764     if (!lastPosTime.isValid())
   756         return;
   765         return;
   757 
   766 
   758     if (QDeclarativeItemPrivate::elapsed(lastPosTime) > 100) {
   767     if (QDeclarativeItemPrivate::elapsed(lastPosTime) > 100) {
   759         // if we drag then pause before release we should not cause a flick.
   768         // if we drag then pause before release we should not cause a flick.
   760         hData.velocity = 0.0;
   769         hData.velocity = 0.0;
   778         flickX(velocity);
   787         flickX(velocity);
   779     } else {
   788     } else {
   780         fixupX();
   789         fixupX();
   781     }
   790     }
   782 
   791 
   783     lastPosTime = QTime();
   792     lastPosTime.invalidate();
   784 
   793 
   785     if (!timeline.isActive())
   794     if (!timeline.isActive())
   786         q->movementEnding();
   795         q->movementEnding();
   787 }
   796 }
   788 
   797 
   894     }
   903     }
   895 }
   904 }
   896 
   905 
   897 void QDeclarativeFlickablePrivate::setRoundedViewportX(qreal x)
   906 void QDeclarativeFlickablePrivate::setRoundedViewportX(qreal x)
   898 {
   907 {
   899     viewport->setX(qRound(x));
   908     contentItem->setX(qRound(x));
   900 }
   909 }
   901 
   910 
   902 void QDeclarativeFlickablePrivate::setRoundedViewportY(qreal y)
   911 void QDeclarativeFlickablePrivate::setRoundedViewportY(qreal y)
   903 {
   912 {
   904     viewport->setY(qRound(y));
   913     contentItem->setY(qRound(y));
   905 }
   914 }
   906 
   915 
   907 void QDeclarativeFlickable::timerEvent(QTimerEvent *event)
   916 void QDeclarativeFlickable::timerEvent(QTimerEvent *event)
   908 {
   917 {
   909     Q_D(QDeclarativeFlickable);
   918     Q_D(QDeclarativeFlickable);
   910     if (event->timerId() == d->delayedPressTimer.timerId()) {
   919     if (event->timerId() == d->delayedPressTimer.timerId()) {
   911         d->delayedPressTimer.stop();
   920         d->delayedPressTimer.stop();
   912         if (d->delayedPressEvent) {
   921         if (d->delayedPressEvent) {
   913             QDeclarativeItem *grabber = scene() ? qobject_cast<QDeclarativeItem*>(scene()->mouseGrabberItem()) : 0;
   922             QDeclarativeItem *grabber = scene() ? qobject_cast<QDeclarativeItem*>(scene()->mouseGrabberItem()) : 0;
   914             if (!grabber || grabber != this)
   923             if (!grabber || grabber != this) {
   915                 scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent);
   924                 // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay)
       
   925                 // so we reset the grabber
       
   926                 if (scene()->mouseGrabberItem() == d->delayedPressTarget)
       
   927                     d->delayedPressTarget->ungrabMouse();
       
   928                 //Use the event handler that will take care of finding the proper item to propagate the event
       
   929                 QApplication::sendEvent(scene(), d->delayedPressEvent);
       
   930             }
   916             delete d->delayedPressEvent;
   931             delete d->delayedPressEvent;
   917             d->delayedPressEvent = 0;
   932             d->delayedPressEvent = 0;
   918         }
   933         }
   919     }
   934     }
   920 }
   935 }
   941 }
   956 }
   942 
   957 
   943 void QDeclarativeFlickable::viewportMoved()
   958 void QDeclarativeFlickable::viewportMoved()
   944 {
   959 {
   945     Q_D(QDeclarativeFlickable);
   960     Q_D(QDeclarativeFlickable);
   946 
       
   947     int elapsed = QDeclarativeItemPrivate::restart(d->velocityTime);
       
   948     if (!elapsed)
       
   949         return;
       
   950 
   961 
   951     qreal prevY = d->lastFlickablePosition.x();
   962     qreal prevY = d->lastFlickablePosition.x();
   952     qreal prevX = d->lastFlickablePosition.y();
   963     qreal prevX = d->lastFlickablePosition.y();
   953     d->velocityTimeline.clear();
   964     d->velocityTimeline.clear();
   954     if (d->pressed) {
   965     if (d->pressed) {
   955         qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed;
   966         int elapsed = QDeclarativeItemPrivate::restart(d->velocityTime);
   956         qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / elapsed;
   967         if (elapsed > 0) {
   957         d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing);
   968             qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed;
   958         d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing);
   969             qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / elapsed;
   959         d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing);
   970             d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing);
   960         d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing);
   971             d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing);
       
   972             d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing);
       
   973             d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing);
       
   974         }
   961     } else {
   975     } else {
   962         if (d->timeline.time() > d->vTime) {
   976         if (d->timeline.time() > d->vTime) {
   963             qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
   977             qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
   964             qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
   978             qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
   965             d->hData.smoothVelocity.setValue(horizontalVelocity);
   979             d->hData.smoothVelocity.setValue(horizontalVelocity);
   980     QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
   994     QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
   981 
   995 
   982     bool changed = false;
   996     bool changed = false;
   983     if (newGeometry.width() != oldGeometry.width()) {
   997     if (newGeometry.width() != oldGeometry.width()) {
   984         if (d->hData.viewSize < 0) {
   998         if (d->hData.viewSize < 0) {
   985             d->viewport->setWidth(width());
   999             d->contentItem->setWidth(width());
   986             emit contentWidthChanged();
  1000             emit contentWidthChanged();
   987         }
  1001         }
   988     }
  1002     }
   989     if (newGeometry.height() != oldGeometry.height()) {
  1003     if (newGeometry.height() != oldGeometry.height()) {
   990         if (d->vData.viewSize < 0) {
  1004         if (d->vData.viewSize < 0) {
   991             d->viewport->setHeight(height());
  1005             d->contentItem->setHeight(height());
   992             emit contentHeightChanged();
  1006             emit contentHeightChanged();
   993         }
  1007         }
   994     }
  1008     }
   995 
  1009 
   996     if (changed)
  1010     if (changed)
  1007 
  1021 
  1008 void QDeclarativeFlickablePrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
  1022 void QDeclarativeFlickablePrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
  1009 {
  1023 {
  1010     QDeclarativeItem *i = qobject_cast<QDeclarativeItem *>(o);
  1024     QDeclarativeItem *i = qobject_cast<QDeclarativeItem *>(o);
  1011     if (i)
  1025     if (i)
  1012         i->setParentItem(static_cast<QDeclarativeFlickablePrivate*>(prop->data)->viewport);
  1026         i->setParentItem(static_cast<QDeclarativeFlickablePrivate*>(prop->data)->contentItem);
  1013     else
  1027     else
  1014         o->setParent(prop->object);
  1028         o->setParent(prop->object);
  1015 }
  1029 }
  1016 
  1030 
  1017 QDeclarativeListProperty<QObject> QDeclarativeFlickable::flickableData()
  1031 QDeclarativeListProperty<QObject> QDeclarativeFlickable::flickableData()
  1021 }
  1035 }
  1022 
  1036 
  1023 QDeclarativeListProperty<QGraphicsObject> QDeclarativeFlickable::flickableChildren()
  1037 QDeclarativeListProperty<QGraphicsObject> QDeclarativeFlickable::flickableChildren()
  1024 {
  1038 {
  1025     Q_D(QDeclarativeFlickable);
  1039     Q_D(QDeclarativeFlickable);
  1026     return QGraphicsItemPrivate::get(d->viewport)->childrenList();
  1040     return QGraphicsItemPrivate::get(d->contentItem)->childrenList();
  1027 }
       
  1028 
       
  1029 bool QDeclarativeFlickable::overShoot() const
       
  1030 {
       
  1031     Q_D(const QDeclarativeFlickable);
       
  1032     return d->boundsBehavior == DragAndOvershootBounds;
       
  1033 }
       
  1034 
       
  1035 void QDeclarativeFlickable::setOverShoot(bool o)
       
  1036 {
       
  1037     Q_D(QDeclarativeFlickable);
       
  1038     if ((o && d->boundsBehavior == DragAndOvershootBounds)
       
  1039         || (!o && d->boundsBehavior == StopAtBounds))
       
  1040         return;
       
  1041     qmlInfo(this) << "overshoot is deprecated and will be removed imminently - use boundsBehavior.";
       
  1042     d->boundsBehavior = o ? DragAndOvershootBounds : StopAtBounds;
       
  1043     emit boundsBehaviorChanged();
       
  1044     emit overShootChanged();
       
  1045 }
  1041 }
  1046 
  1042 
  1047 /*!
  1043 /*!
  1048     \qmlproperty enumeration Flickable::boundsBehavior
  1044     \qmlproperty enumeration Flickable::boundsBehavior
  1049     This property holds whether the surface may be dragged
  1045     This property holds whether the surface may be dragged
  1054     rather than a hard physical boundary.
  1050     rather than a hard physical boundary.
  1055 
  1051 
  1056     The \c boundsBehavior can be one of:
  1052     The \c boundsBehavior can be one of:
  1057 
  1053 
  1058     \list
  1054     \list
  1059     \o \e Flickable.StopAtBounds - the contents can not be dragged beyond the boundary
  1055     \o Flickable.StopAtBounds - the contents can not be dragged beyond the boundary
  1060     of the flickable, and flicks will not overshoot.
  1056     of the flickable, and flicks will not overshoot.
  1061     \o \e Flickable.DragOverBounds - the contents can be dragged beyond the boundary
  1057     \o Flickable.DragOverBounds - the contents can be dragged beyond the boundary
  1062     of the Flickable, but flicks will not overshoot.
  1058     of the Flickable, but flicks will not overshoot.
  1063     \o \e Flickable.DragAndOvershootBounds (default) - the contents can be dragged
  1059     \o Flickable.DragAndOvershootBounds (default) - the contents can be dragged
  1064     beyond the boundary of the Flickable, and can overshoot the
  1060     beyond the boundary of the Flickable, and can overshoot the
  1065     boundary when flicked.
  1061     boundary when flicked.
  1066     \endlist
  1062     \endlist
  1067 */
  1063 */
  1068 QDeclarativeFlickable::BoundsBehavior QDeclarativeFlickable::boundsBehavior() const
  1064 QDeclarativeFlickable::BoundsBehavior QDeclarativeFlickable::boundsBehavior() const
  1076     Q_D(QDeclarativeFlickable);
  1072     Q_D(QDeclarativeFlickable);
  1077     if (b == d->boundsBehavior)
  1073     if (b == d->boundsBehavior)
  1078         return;
  1074         return;
  1079     d->boundsBehavior = b;
  1075     d->boundsBehavior = b;
  1080     emit boundsBehaviorChanged();
  1076     emit boundsBehaviorChanged();
  1081     emit overShootChanged();
       
  1082 }
  1077 }
  1083 
  1078 
  1084 /*!
  1079 /*!
  1085     \qmlproperty int Flickable::contentWidth
  1080     \qmlproperty int Flickable::contentWidth
  1086     \qmlproperty int Flickable::contentHeight
  1081     \qmlproperty int Flickable::contentHeight
  1110     Q_D(QDeclarativeFlickable);
  1105     Q_D(QDeclarativeFlickable);
  1111     if (d->hData.viewSize == w)
  1106     if (d->hData.viewSize == w)
  1112         return;
  1107         return;
  1113     d->hData.viewSize = w;
  1108     d->hData.viewSize = w;
  1114     if (w < 0)
  1109     if (w < 0)
  1115         d->viewport->setWidth(width());
  1110         d->contentItem->setWidth(width());
  1116     else
  1111     else
  1117         d->viewport->setWidth(w);
  1112         d->contentItem->setWidth(w);
  1118     // Make sure that we're entirely in view.
  1113     // Make sure that we're entirely in view.
  1119     if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
  1114     if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
  1120         int oldDuration = d->fixupDuration;
  1115         int oldDuration = d->fixupDuration;
  1121         d->fixupDuration = 0;
  1116         d->fixupDuration = 0;
  1122         d->fixupX();
  1117         d->fixupX();
  1137     Q_D(QDeclarativeFlickable);
  1132     Q_D(QDeclarativeFlickable);
  1138     if (d->vData.viewSize == h)
  1133     if (d->vData.viewSize == h)
  1139         return;
  1134         return;
  1140     d->vData.viewSize = h;
  1135     d->vData.viewSize = h;
  1141     if (h < 0)
  1136     if (h < 0)
  1142         d->viewport->setHeight(height());
  1137         d->contentItem->setHeight(height());
  1143     else
  1138     else
  1144         d->viewport->setHeight(h);
  1139         d->contentItem->setHeight(h);
  1145     // Make sure that we're entirely in view.
  1140     // Make sure that we're entirely in view.
  1146     if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
  1141     if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
  1147         int oldDuration = d->fixupDuration;
  1142         int oldDuration = d->fixupDuration;
  1148         d->fixupDuration = 0;
  1143         d->fixupDuration = 0;
  1149         d->fixupY();
  1144         d->fixupY();
  1217             if (d->delayedPressEvent)
  1212             if (d->delayedPressEvent)
  1218                 return false;
  1213                 return false;
  1219 
  1214 
  1220             d->handleMousePressEvent(&mouseEvent);
  1215             d->handleMousePressEvent(&mouseEvent);
  1221             d->captureDelayedPress(event);
  1216             d->captureDelayedPress(event);
       
  1217             stealThisEvent = d->stealMouse;   // Update stealThisEvent in case changed by function call above
  1222             break;
  1218             break;
  1223         case QEvent::GraphicsSceneMouseRelease:
  1219         case QEvent::GraphicsSceneMouseRelease:
  1224             if (d->delayedPressEvent) {
  1220             if (d->delayedPressEvent) {
  1225                 scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent);
  1221                 // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay)
       
  1222                 // so we reset the grabber
       
  1223                 if (s->mouseGrabberItem() == d->delayedPressTarget)
       
  1224                     d->delayedPressTarget->ungrabMouse();
       
  1225                 //Use the event handler that will take care of finding the proper item to propagate the event
       
  1226                 QApplication::sendEvent(scene(), d->delayedPressEvent);
  1226                 d->clearDelayedPress();
  1227                 d->clearDelayedPress();
       
  1228                 // We send the release
       
  1229                 scene()->sendEvent(s->mouseGrabberItem(), event);
       
  1230                 // And the event has been consumed
       
  1231                 return true;
  1227             }
  1232             }
  1228             d->handleMouseReleaseEvent(&mouseEvent);
  1233             d->handleMouseReleaseEvent(&mouseEvent);
  1229             break;
  1234             break;
  1230         default:
  1235         default:
  1231             break;
  1236             break;
  1235             d->clearDelayedPress();
  1240             d->clearDelayedPress();
  1236             grabMouse();
  1241             grabMouse();
  1237         }
  1242         }
  1238 
  1243 
  1239         return stealThisEvent || d->delayedPressEvent;
  1244         return stealThisEvent || d->delayedPressEvent;
  1240     } else if (!d->lastPosTime.isNull()) {
  1245     } else if (d->lastPosTime.isValid()) {
  1241         d->lastPosTime = QTime();
  1246         d->lastPosTime.invalidate();
  1242     }
  1247     }
  1243     if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
  1248     if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
  1244         d->clearDelayedPress();
  1249         d->clearDelayedPress();
  1245         d->stealMouse = false;
  1250         d->stealMouse = false;
  1246     }
  1251     }
  1335 /*!
  1340 /*!
  1336     \qmlproperty int Flickable::pressDelay
  1341     \qmlproperty int Flickable::pressDelay
  1337 
  1342 
  1338     This property holds the time to delay (ms) delivering a press to
  1343     This property holds the time to delay (ms) delivering a press to
  1339     children of the Flickable.  This can be useful where reacting
  1344     children of the Flickable.  This can be useful where reacting
  1340     to a press before a flicking action has undesireable effects.
  1345     to a press before a flicking action has undesirable effects.
  1341 
  1346 
  1342     If the flickable is dragged/flicked before the delay times out
  1347     If the flickable is dragged/flicked before the delay times out
  1343     the press event will not be delivered.  If the button is released
  1348     the press event will not be delivered.  If the button is released
  1344     within the timeout, both the press and release will be delivered.
  1349     within the timeout, both the press and release will be delivered.
  1345 */
  1350 */