summaryrefslogtreecommitdiff
path: root/src/declarative/graphicsitems/qdeclarativeflickable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/graphicsitems/qdeclarativeflickable.cpp')
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp128
1 files changed, 86 insertions, 42 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index 001abca80c..377f3b5407 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -53,9 +53,6 @@ QT_BEGIN_NAMESPACE
// before we perform a flick.
static const int FlickThreshold = 20;
-// Really slow flicks can be annoying.
-static const int MinimumFlickVelocity = 75;
-
QDeclarativeFlickableVisibleArea::QDeclarativeFlickableVisibleArea(QDeclarativeFlickable *parent)
: QObject(parent), flickable(parent), m_xPosition(0.), m_widthRatio(0.)
, m_yPosition(0.), m_heightRatio(0.)
@@ -85,7 +82,11 @@ qreal QDeclarativeFlickableVisibleArea::yPosition() const
void QDeclarativeFlickableVisibleArea::updateVisible()
{
QDeclarativeFlickablePrivate *p = static_cast<QDeclarativeFlickablePrivate *>(QGraphicsItemPrivate::get(flickable));
- bool pageChange = false;
+
+ bool changeX = false;
+ bool changeY = false;
+ bool changeWidth = false;
+ bool changeHeight = false;
// Vertical
const qreal viewheight = flickable->height();
@@ -95,11 +96,11 @@ void QDeclarativeFlickableVisibleArea::updateVisible()
if (pageSize != m_heightRatio) {
m_heightRatio = pageSize;
- pageChange = true;
+ changeHeight = true;
}
if (pagePos != m_yPosition) {
m_yPosition = pagePos;
- pageChange = true;
+ changeY = true;
}
// Horizontal
@@ -110,14 +111,21 @@ void QDeclarativeFlickableVisibleArea::updateVisible()
if (pageSize != m_widthRatio) {
m_widthRatio = pageSize;
- pageChange = true;
+ changeWidth = true;
}
if (pagePos != m_xPosition) {
m_xPosition = pagePos;
- pageChange = true;
+ changeX = true;
}
- if (pageChange)
- emit pageChanged();
+
+ if (changeX)
+ emit xPositionChanged(m_xPosition);
+ if (changeY)
+ emit yPositionChanged(m_yPosition);
+ if (changeWidth)
+ emit widthRatioChanged(m_widthRatio);
+ if (changeHeight)
+ emit heightRatioChanged(m_heightRatio);
}
@@ -273,7 +281,6 @@ void QDeclarativeFlickablePrivate::fixupY()
void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
{
- Q_Q(QDeclarativeFlickable);
if (data.move.value() > minExtent || maxExtent > minExtent) {
timeline.reset(data.move);
if (data.move.value() != minExtent) {
@@ -282,8 +289,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal
timeline.move(data.move, minExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
} else {
- data.move.setValue(minExtent);
- q->viewportMoved();
+ timeline.set(data.move, minExtent);
}
}
} else if (data.move.value() < maxExtent) {
@@ -293,8 +299,7 @@ void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal
timeline.move(data.move, maxExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutExpo), 3*fixupDuration/4);
} else {
- data.move.setValue(maxExtent);
- q->viewportMoved();
+ timeline.set(data.move, minExtent);
}
}
vTime = timeline.time();
@@ -378,6 +383,13 @@ void QDeclarativeFlickablePrivate::updateBeginningEnd()
\snippet doc/src/snippets/declarative/flickable.qml document
\clearfloat
+
+ Items declared as children of a Flickable are automatically parented to the
+ Flickable's \l contentItem. This should be taken into account when
+ operating on the children of the Flickable; it is usually the children of
+ \c contentItem that are relevant. For example, the bound of Items added
+ to the Flickable will be available by \c contentItem.childrenRect
+
\section1 Limitations
\note Due to an implementation detail, items placed inside a Flickable cannot anchor to it by
@@ -472,9 +484,9 @@ qreal QDeclarativeFlickable::contentX() const
void QDeclarativeFlickable::setContentX(qreal pos)
{
Q_D(QDeclarativeFlickable);
- pos = qRound(pos);
d->timeline.reset(d->hData.move);
d->vTime = d->timeline.time();
+ movementXEnding();
if (-pos != d->hData.move.value()) {
d->hData.move.setValue(-pos);
viewportMoved();
@@ -490,9 +502,9 @@ qreal QDeclarativeFlickable::contentY() const
void QDeclarativeFlickable::setContentY(qreal pos)
{
Q_D(QDeclarativeFlickable);
- pos = qRound(pos);
d->timeline.reset(d->vData.move);
d->vTime = d->timeline.time();
+ movementYEnding();
if (-pos != d->vData.move.value()) {
d->vData.move.setValue(-pos);
viewportMoved();
@@ -688,6 +700,9 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
bool rejectY = false;
bool rejectX = false;
+ bool stealY = false;
+ bool stealX = false;
+
if (q->yflick()) {
int dy = int(event->pos().y() - pressPos.y());
if (qAbs(dy) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) {
@@ -716,7 +731,7 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
vMoved = true;
}
if (qAbs(dy) > QApplication::startDragDistance())
- stealMouse = true;
+ stealY = true;
}
}
@@ -749,10 +764,12 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
}
if (qAbs(dx) > QApplication::startDragDistance())
- stealMouse = true;
+ stealX = true;
}
}
+ stealMouse = stealX || stealY;
+
if (!lastPos.isNull()) {
qreal elapsed = qreal(QDeclarativeItemPrivate::restart(lastPosTime)) / 1000.;
if (elapsed <= 0)
@@ -979,8 +996,8 @@ void QDeclarativeFlickable::viewportMoved()
{
Q_D(QDeclarativeFlickable);
- qreal prevY = d->lastFlickablePosition.x();
- qreal prevX = d->lastFlickablePosition.y();
+ qreal prevX = d->lastFlickablePosition.x();
+ qreal prevY = d->lastFlickablePosition.y();
d->velocityTimeline.clear();
if (d->pressed || d->calcVelocity) {
int elapsed = QDeclarativeItemPrivate::restart(d->velocityTime);
@@ -1001,7 +1018,7 @@ void QDeclarativeFlickable::viewportMoved()
}
}
- d->lastFlickablePosition = QPointF(d->vData.move.value(), d->hData.move.value());
+ d->lastFlickablePosition = QPointF(d->hData.move.value(), d->vData.move.value());
d->vTime = d->timeline.time();
d->updateBeginningEnd();
@@ -1021,6 +1038,13 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry,
d->contentItem->setWidth(width());
emit contentWidthChanged();
}
+ // Make sure that we're entirely in view.
+ if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ int oldDuration = d->fixupDuration;
+ d->fixupDuration = 0;
+ d->fixupX();
+ d->fixupDuration = oldDuration;
+ }
}
if (newGeometry.height() != oldGeometry.height()) {
if (yflick())
@@ -1029,6 +1053,13 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry,
d->contentItem->setHeight(height());
emit contentHeightChanged();
}
+ // Make sure that we're entirely in view.
+ if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ int oldDuration = d->fixupDuration;
+ d->fixupDuration = 0;
+ d->fixupY();
+ d->fixupDuration = oldDuration;
+ }
}
if (changed)
@@ -1171,19 +1202,18 @@ void QDeclarativeFlickable::setBoundsBehavior(BoundsBehavior b)
\qmlproperty real Flickable::contentWidth
\qmlproperty real Flickable::contentHeight
- The dimensions of the content (the surface controlled by Flickable). Typically this
- should be set to the combined size of the items placed in the Flickable. Note this
- can be set automatically using \l {Item::childrenRect.width}{childrenRect.width}
- and \l {Item::childrenRect.height}{childrenRect.height}. For example:
+ The dimensions of the content (the surface controlled by Flickable).
+ This should typically be set to the combined size of the items placed in the
+ Flickable.
- \code
- Flickable {
- width: 320; height: 480
- contentWidth: childrenRect.width; contentHeight: childrenRect.height
+ The following snippet shows how these properties are used to display
+ an image that is larger than the Flickable item itself:
- Image { id: image; source: "bigImage.png" }
- }
- \endcode
+ \snippet doc/src/snippets/declarative/flickable.qml document
+
+ In some cases, the the content dimensions can be automatically set
+ using the \l {Item::childrenRect.width}{childrenRect.width}
+ and \l {Item::childrenRect.height}{childrenRect.height} properties.
*/
qreal QDeclarativeFlickable::contentWidth() const
{
@@ -1505,6 +1535,15 @@ void QDeclarativeFlickable::movementStarting()
void QDeclarativeFlickable::movementEnding()
{
Q_D(QDeclarativeFlickable);
+ movementXEnding();
+ movementYEnding();
+ d->hData.smoothVelocity.setValue(0);
+ d->vData.smoothVelocity.setValue(0);
+}
+
+void QDeclarativeFlickable::movementXEnding()
+{
+ Q_D(QDeclarativeFlickable);
if (d->flickingHorizontally) {
d->flickingHorizontally = false;
emit flickingChanged();
@@ -1512,13 +1551,6 @@ void QDeclarativeFlickable::movementEnding()
if (!d->flickingVertically)
emit flickEnded();
}
- if (d->flickingVertically) {
- d->flickingVertically = false;
- emit flickingChanged();
- emit flickingVerticallyChanged();
- if (!d->flickingHorizontally)
- emit flickEnded();
- }
if (!d->pressed && !d->stealMouse) {
if (d->movingHorizontally) {
d->movingHorizontally = false;
@@ -1528,6 +1560,20 @@ void QDeclarativeFlickable::movementEnding()
if (!d->movingVertically)
emit movementEnded();
}
+ }
+}
+
+void QDeclarativeFlickable::movementYEnding()
+{
+ Q_D(QDeclarativeFlickable);
+ if (d->flickingVertically) {
+ d->flickingVertically = false;
+ emit flickingChanged();
+ emit flickingVerticallyChanged();
+ if (!d->flickingHorizontally)
+ emit flickEnded();
+ }
+ if (!d->pressed && !d->stealMouse) {
if (d->movingVertically) {
d->movingVertically = false;
d->vMoved = false;
@@ -1537,8 +1583,6 @@ void QDeclarativeFlickable::movementEnding()
emit movementEnded();
}
}
- d->hData.smoothVelocity.setValue(0);
- d->vData.smoothVelocity.setValue(0);
}
void QDeclarativeFlickablePrivate::updateVelocity()