src/declarative/graphicsitems/qdeclarativeflickable.cpp
changeset 37 758a864f9613
parent 33 3e2da88830cd
equal deleted inserted replaced
36:ef0373b55136 37:758a864f9613
    52 // FlickThreshold determines how far the "mouse" must have moved
    52 // FlickThreshold determines how far the "mouse" must have moved
    53 // before we perform a flick.
    53 // before we perform a flick.
    54 static const int FlickThreshold = 20;
    54 static const int FlickThreshold = 20;
    55 
    55 
    56 // Really slow flicks can be annoying.
    56 // Really slow flicks can be annoying.
    57 static const int minimumFlickVelocity = 200;
    57 static const int MinimumFlickVelocity = 75;
    58 
    58 
    59 QDeclarativeFlickableVisibleArea::QDeclarativeFlickableVisibleArea(QDeclarativeFlickable *parent)
    59 QDeclarativeFlickableVisibleArea::QDeclarativeFlickableVisibleArea(QDeclarativeFlickable *parent)
    60     : QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.)
    60     : QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.)
    61     , m_yPosition(0.), m_heightRatio(0.)
    61     , m_yPosition(0.), m_heightRatio(0.)
    62 {
    62 {
   343 }
   343 }
   344 
   344 
   345 /*!
   345 /*!
   346     \qmlclass Flickable QDeclarativeFlickable
   346     \qmlclass Flickable QDeclarativeFlickable
   347     \since 4.7
   347     \since 4.7
       
   348     \ingroup qml-basic-interaction-elements
       
   349 
   348     \brief The Flickable item provides a surface that can be "flicked".
   350     \brief The Flickable item provides a surface that can be "flicked".
   349     \inherits Item
   351     \inherits Item
   350 
   352 
   351     Flickable places its children on a surface that can be dragged and flicked.
   353     Flickable places its children on a surface that can be dragged and flicked.
   352 
   354 
   649         stealMouse = false;
   651         stealMouse = false;
   650     pressed = true;
   652     pressed = true;
   651     timeline.clear();
   653     timeline.clear();
   652     hData.velocity = 0;
   654     hData.velocity = 0;
   653     vData.velocity = 0;
   655     vData.velocity = 0;
       
   656     hData.dragStartOffset = 0;
       
   657     vData.dragStartOffset = 0;
   654     lastPos = QPoint();
   658     lastPos = QPoint();
   655     QDeclarativeItemPrivate::start(lastPosTime);
   659     QDeclarativeItemPrivate::start(lastPosTime);
   656     pressPos = event->pos();
   660     pressPos = event->pos();
   657     hData.pressPos = hData.move.value();
   661     hData.pressPos = hData.move.value();
   658     vData.pressPos = vData.move.value();
   662     vData.pressPos = vData.move.value();
   671     bool rejectX = false;
   675     bool rejectX = false;
   672 
   676 
   673     if (q->yflick()) {
   677     if (q->yflick()) {
   674         int dy = int(event->pos().y() - pressPos.y());
   678         int dy = int(event->pos().y() - pressPos.y());
   675         if (qAbs(dy) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) {
   679         if (qAbs(dy) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) {
   676             qreal newY = dy + vData.pressPos;
   680             if (!vMoved)
       
   681                 vData.dragStartOffset = dy;
       
   682             qreal newY = dy + vData.pressPos - vData.dragStartOffset;
   677             const qreal minY = q->minYExtent();
   683             const qreal minY = q->minYExtent();
   678             const qreal maxY = q->maxYExtent();
   684             const qreal maxY = q->maxYExtent();
   679             if (newY > minY)
   685             if (newY > minY)
   680                 newY = minY + (newY - minY) / 2;
   686                 newY = minY + (newY - minY) / 2;
   681             if (newY < maxY && maxY - minY <= 0)
   687             if (newY < maxY && maxY - minY <= 0)
   682                 newY = maxY + (newY - maxY) / 2;
   688                 newY = maxY + (newY - maxY) / 2;
   683             if (boundsBehavior == QDeclarativeFlickable::StopAtBounds && (newY > minY || newY < maxY)) {
   689             if (boundsBehavior == QDeclarativeFlickable::StopAtBounds && (newY > minY || newY < maxY)) {
   684                 if (newY > minY)
   690                 rejectY = true;
       
   691                 if (newY < maxY) {
       
   692                     newY = maxY;
       
   693                     rejectY = false;
       
   694                 }
       
   695                 if (newY > minY) {
   685                     newY = minY;
   696                     newY = minY;
   686                 else if (newY < maxY)
   697                     rejectY = false;
   687                     newY = maxY;
   698                 }
   688                 else
       
   689                     rejectY = true;
       
   690             }
   699             }
   691             if (!rejectY && stealMouse) {
   700             if (!rejectY && stealMouse) {
   692                 vData.move.setValue(qRound(newY));
   701                 vData.move.setValue(qRound(newY));
   693                 vMoved = true;
   702                 vMoved = true;
   694             }
   703             }
   698     }
   707     }
   699 
   708 
   700     if (q->xflick()) {
   709     if (q->xflick()) {
   701         int dx = int(event->pos().x() - pressPos.x());
   710         int dx = int(event->pos().x() - pressPos.x());
   702         if (qAbs(dx) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) {
   711         if (qAbs(dx) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) {
   703             qreal newX = dx + hData.pressPos;
   712             if (!hMoved)
       
   713                 hData.dragStartOffset = dx;
       
   714             qreal newX = dx + hData.pressPos - hData.dragStartOffset;
   704             const qreal minX = q->minXExtent();
   715             const qreal minX = q->minXExtent();
   705             const qreal maxX = q->maxXExtent();
   716             const qreal maxX = q->maxXExtent();
   706             if (newX > minX)
   717             if (newX > minX)
   707                 newX = minX + (newX - minX) / 2;
   718                 newX = minX + (newX - minX) / 2;
   708             if (newX < maxX && maxX - minX <= 0)
   719             if (newX < maxX && maxX - minX <= 0)
   709                 newX = maxX + (newX - maxX) / 2;
   720                 newX = maxX + (newX - maxX) / 2;
   710             if (boundsBehavior == QDeclarativeFlickable::StopAtBounds && (newX > minX || newX < maxX)) {
   721             if (boundsBehavior == QDeclarativeFlickable::StopAtBounds && (newX > minX || newX < maxX)) {
   711                 if (newX > minX)
   722                 rejectX = true;
       
   723                 if (newX < maxX) {
       
   724                     newX = maxX;
       
   725                     rejectX = false;
       
   726                 }
       
   727                 if (newX > minX) {
   712                     newX = minX;
   728                     newX = minX;
   713                 else if (newX < maxX)
   729                     rejectX = false;
   714                     newX = maxX;
   730                 }
   715                 else
       
   716                     rejectX = true;
       
   717             }
   731             }
   718             if (!rejectX && stealMouse) {
   732             if (!rejectX && stealMouse) {
   719                 hData.move.setValue(qRound(newX));
   733                 hData.move.setValue(qRound(newX));
   720                 hMoved = true;
   734                 hMoved = true;
   721             }
   735             }
   769         hData.velocity = 0.0;
   783         hData.velocity = 0.0;
   770         vData.velocity = 0.0;
   784         vData.velocity = 0.0;
   771     }
   785     }
   772 
   786 
   773     vTime = timeline.time();
   787     vTime = timeline.time();
   774     if (qAbs(vData.velocity) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) {
   788     if (qAbs(vData.velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold)
   775         qreal velocity = vData.velocity;
   789         flickY(vData.velocity);
   776         if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks.
   790     else
   777             velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity;
       
   778         flickY(velocity);
       
   779     } else {
       
   780         fixupY();
   791         fixupY();
   781     }
   792 
   782 
   793     if (qAbs(hData.velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold)
   783     if (qAbs(hData.velocity) > 10 && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) {
   794         flickX(hData.velocity);
   784         qreal velocity = hData.velocity;
   795     else
   785         if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks.
       
   786             velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity;
       
   787         flickX(velocity);
       
   788     } else {
       
   789         fixupX();
   796         fixupX();
   790     }
       
   791 
   797 
   792     lastPosTime.invalidate();
   798     lastPosTime.invalidate();
   793 
   799 
   794     if (!timeline.isActive())
   800     if (!timeline.isActive())
   795         q->movementEnding();
   801         q->movementEnding();
   993     Q_D(QDeclarativeFlickable);
   999     Q_D(QDeclarativeFlickable);
   994     QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
  1000     QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
   995 
  1001 
   996     bool changed = false;
  1002     bool changed = false;
   997     if (newGeometry.width() != oldGeometry.width()) {
  1003     if (newGeometry.width() != oldGeometry.width()) {
       
  1004         if (xflick())
       
  1005             changed = true;
   998         if (d->hData.viewSize < 0) {
  1006         if (d->hData.viewSize < 0) {
   999             d->contentItem->setWidth(width());
  1007             d->contentItem->setWidth(width());
  1000             emit contentWidthChanged();
  1008             emit contentWidthChanged();
  1001         }
  1009         }
  1002     }
  1010     }
  1003     if (newGeometry.height() != oldGeometry.height()) {
  1011     if (newGeometry.height() != oldGeometry.height()) {
       
  1012         if (yflick())
       
  1013             changed = true;
  1004         if (d->vData.viewSize < 0) {
  1014         if (d->vData.viewSize < 0) {
  1005             d->contentItem->setHeight(height());
  1015             d->contentItem->setHeight(height());
  1006             emit contentHeightChanged();
  1016             emit contentHeightChanged();
  1007         }
  1017         }
  1008     }
  1018     }
  1019     movementEnding();
  1029     movementEnding();
  1020 }
  1030 }
  1021 
  1031 
  1022 void QDeclarativeFlickablePrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
  1032 void QDeclarativeFlickablePrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
  1023 {
  1033 {
  1024     QDeclarativeItem *i = qobject_cast<QDeclarativeItem *>(o);
  1034     QGraphicsObject *i = qobject_cast<QGraphicsObject *>(o);
  1025     if (i)
  1035     if (i)
  1026         i->setParentItem(static_cast<QDeclarativeFlickablePrivate*>(prop->data)->contentItem);
  1036         i->setParentItem(static_cast<QDeclarativeFlickablePrivate*>(prop->data)->contentItem);
  1027     else
  1037     else
  1028         o->setParent(prop->object);
  1038         o->setParent(prop->object);
  1029 }
  1039 }
  1246         d->lastPosTime.invalidate();
  1256         d->lastPosTime.invalidate();
  1247     }
  1257     }
  1248     if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
  1258     if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
  1249         d->clearDelayedPress();
  1259         d->clearDelayedPress();
  1250         d->stealMouse = false;
  1260         d->stealMouse = false;
       
  1261         d->pressed = false;
  1251     }
  1262     }
  1252     return false;
  1263     return false;
  1253 }
  1264 }
  1254 
  1265 
  1255 bool QDeclarativeFlickable::sceneEventFilter(QGraphicsItem *i, QEvent *e)
  1266 bool QDeclarativeFlickable::sceneEventFilter(QGraphicsItem *i, QEvent *e)
  1424         emit flickingChanged();
  1435         emit flickingChanged();
  1425         emit flickingVerticallyChanged();
  1436         emit flickingVerticallyChanged();
  1426         if (!d->flickingHorizontally)
  1437         if (!d->flickingHorizontally)
  1427            emit flickEnded();
  1438            emit flickEnded();
  1428     }
  1439     }
  1429     if (d->movingHorizontally) {
  1440     if (!d->pressed && !d->stealMouse) {
  1430         d->movingHorizontally = false;
  1441         if (d->movingHorizontally) {
  1431         d->hMoved = false;
  1442             d->movingHorizontally = false;
  1432         emit movingChanged();
  1443             d->hMoved = false;
  1433         emit movingHorizontallyChanged();
  1444             emit movingChanged();
  1434         if (!d->movingVertically)
  1445             emit movingHorizontallyChanged();
  1435             emit movementEnded();
  1446             if (!d->movingVertically)
  1436     }
  1447                 emit movementEnded();
  1437     if (d->movingVertically) {
  1448         }
  1438         d->movingVertically = false;
  1449         if (d->movingVertically) {
  1439         d->vMoved = false;
  1450             d->movingVertically = false;
  1440         emit movingChanged();
  1451             d->vMoved = false;
  1441         emit movingVerticallyChanged();
  1452             emit movingChanged();
  1442         if (!d->movingHorizontally)
  1453             emit movingVerticallyChanged();
  1443             emit movementEnded();
  1454             if (!d->movingHorizontally)
       
  1455                 emit movementEnded();
       
  1456         }
  1444     }
  1457     }
  1445     d->hData.smoothVelocity.setValue(0);
  1458     d->hData.smoothVelocity.setValue(0);
  1446     d->vData.smoothVelocity.setValue(0);
  1459     d->vData.smoothVelocity.setValue(0);
  1447 }
  1460 }
  1448 
  1461