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 { |
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 |