summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBea Lam <bea.lam@nokia.com>2010-03-08 03:05:22 (GMT)
committerBea Lam <bea.lam@nokia.com>2010-03-08 03:05:22 (GMT)
commitb35bc4ba38992dde4c35c138caa52c018d80b350 (patch)
treebe333c1957d1d4a8d41164476d5a3e34164d10dc
parent364dcc0b434fedd18adea73ee99ffad44ca4442a (diff)
parenteb45d1cc264dbec26575b2bd6cd23b09e3ade653 (diff)
downloadQt-b35bc4ba38992dde4c35c138caa52c018d80b350.zip
Qt-b35bc4ba38992dde4c35c138caa52c018d80b350.tar.gz
Qt-b35bc4ba38992dde4c35c138caa52c018d80b350.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp385
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable_p_p.h79
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp33
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimage.cpp9
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimage_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase.cpp12
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp287
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview.cpp196
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview_p.h51
-rw-r--r--src/declarative/graphicsitems/qdeclarativepathview_p_p.h7
-rw-r--r--src/declarative/graphicsitems/qdeclarativerectangle.cpp3
-rw-r--r--src/declarative/graphicsitems/qdeclarativerectangle_p_p.h15
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext_p_p.h10
-rw-r--r--tests/auto/declarative/qdeclarativepathview/data/pathview.qml11
-rw-r--r--tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp46
-rw-r--r--tests/benchmarks/declarative/creation/tst_creation.cpp2
22 files changed, 593 insertions, 567 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index 63c97e0..67068a0 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -90,7 +90,7 @@ void QDeclarativeFlickableVisibleArea::updateVisible()
// Vertical
const qreal viewheight = flickable->height();
const qreal maxyextent = -flickable->maxYExtent() + flickable->minYExtent();
- qreal pagePos = (-p->_moveY.value() + flickable->minYExtent()) / (maxyextent + viewheight);
+ qreal pagePos = (-p->vData.move.value() + flickable->minYExtent()) / (maxyextent + viewheight);
qreal pageSize = viewheight / (maxyextent + viewheight);
if (pageSize != m_heightRatio) {
@@ -105,7 +105,7 @@ void QDeclarativeFlickableVisibleArea::updateVisible()
// Horizontal
const qreal viewwidth = flickable->width();
const qreal maxxextent = -flickable->maxXExtent() + flickable->minXExtent();
- pagePos = (-p->_moveX.value() + flickable->minXExtent()) / (maxxextent + viewwidth);
+ pagePos = (-p->hData.move.value() + flickable->minXExtent()) / (maxxextent + viewwidth);
pageSize = viewwidth / (maxxextent + viewwidth);
if (pageSize != m_widthRatio) {
@@ -123,13 +123,13 @@ void QDeclarativeFlickableVisibleArea::updateVisible()
QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate()
: viewport(new QDeclarativeItem)
- , _moveX(this, &QDeclarativeFlickablePrivate::setRoundedViewportX)
- , _moveY(this, &QDeclarativeFlickablePrivate::setRoundedViewportY)
- , vWidth(-1), vHeight(-1), overShoot(true), flicked(false), moving(false), stealMouse(false)
- , pressed(false), atXEnd(false), atXBeginning(true), atYEnd(false), atYBeginning(true)
+ , hData(this, &QDeclarativeFlickablePrivate::setRoundedViewportX)
+ , vData(this, &QDeclarativeFlickablePrivate::setRoundedViewportY)
+ , overShoot(true), flicked(false), moving(false), stealMouse(false)
+ , pressed(false)
, interactive(true), deceleration(500), maxVelocity(2000), reportedVelocitySmoothing(100)
, delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(600)
- , horizontalVelocity(this), verticalVelocity(this), vTime(0), visibleArea(0)
+ , vTime(0), visibleArea(0)
, flickDirection(QDeclarativeFlickable::AutoFlickDirection)
{
}
@@ -138,14 +138,24 @@ void QDeclarativeFlickablePrivate::init()
{
Q_Q(QDeclarativeFlickable);
viewport->setParent(q);
- QObject::connect(&timeline, SIGNAL(updated()), q, SLOT(ticked()));
- QObject::connect(&timeline, SIGNAL(completed()), q, SLOT(movementEnding()));
+ static int timelineUpdatedIdx = -1;
+ static int timelineCompletedIdx = -1;
+ static int flickableTickedIdx = -1;
+ static int flickableMovementEndingIdx = -1;
+ if (timelineUpdatedIdx == -1) {
+ timelineUpdatedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("updated()");
+ timelineCompletedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("completed()");
+ flickableTickedIdx = QDeclarativeFlickable::staticMetaObject.indexOfSlot("ticked()");
+ flickableMovementEndingIdx = QDeclarativeFlickable::staticMetaObject.indexOfSlot("movementEnding()");
+ }
+ QMetaObject::connect(&timeline, timelineUpdatedIdx,
+ q, flickableTickedIdx, Qt::DirectConnection);
+ QMetaObject::connect(&timeline, timelineCompletedIdx,
+ q, flickableMovementEndingIdx, Qt::DirectConnection);
q->setAcceptedMouseButtons(Qt::LeftButton);
q->setFiltersChildEvents(true);
- QObject::connect(viewport, SIGNAL(xChanged()), q, SIGNAL(contentXChanged()));
- QObject::connect(viewport, SIGNAL(yChanged()), q, SIGNAL(contentYChanged()));
- QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(heightChange()));
- QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(widthChange()));
+ QDeclarativeItemPrivate *viewportPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(viewport));
+ viewportPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
}
/*
@@ -164,59 +174,43 @@ qreal QDeclarativeFlickablePrivate::overShootDistance(qreal velocity, qreal size
return dist;
}
-void QDeclarativeFlickablePrivate::flickX(qreal velocity)
+void QDeclarativeFlickablePrivate::itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeom, const QRectF &oldGeom)
{
Q_Q(QDeclarativeFlickable);
- qreal maxDistance = -1;
- // -ve velocity means list is moving up
- if (velocity > 0) {
- const qreal minX = q->minXExtent();
- if (_moveX.value() < minX)
- maxDistance = qAbs(minX -_moveX.value() + (overShoot?overShootDistance(velocity,q->width()):0));
- flickTargetX = minX;
- } else {
- const qreal maxX = q->maxXExtent();
- if (_moveX.value() > maxX)
- maxDistance = qAbs(maxX - _moveX.value()) + (overShoot?overShootDistance(velocity,q->width()):0);
- flickTargetX = maxX;
- }
- if (maxDistance > 0) {
- qreal v = velocity;
- if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
- if (v < 0)
- v = -maxVelocity;
- else
- v = maxVelocity;
- }
- timeline.reset(_moveX);
- timeline.accel(_moveX, v, deceleration, maxDistance);
- timeline.callback(QDeclarativeTimeLineCallback(&_moveX, fixupX_callback, this));
- if (!flicked) {
- flicked = true;
- emit q->flickingChanged();
- emit q->flickStarted();
- }
- } else {
- timeline.reset(_moveX);
- fixupX();
+ if (item == viewport) {
+ if (newGeom.x() != oldGeom.x())
+ emit q->contentXChanged();
+ if (newGeom.y() != oldGeom.y())
+ emit q->contentYChanged();
}
}
+void QDeclarativeFlickablePrivate::flickX(qreal velocity)
+{
+ Q_Q(QDeclarativeFlickable);
+ flick(hData, q->minXExtent(), q->maxXExtent(), q->width(), fixupX_callback, velocity);
+}
+
void QDeclarativeFlickablePrivate::flickY(qreal velocity)
{
Q_Q(QDeclarativeFlickable);
+ flick(vData, q->minYExtent(), q->maxYExtent(), q->height(), fixupY_callback, velocity);
+}
+
+void QDeclarativeFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+ QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
+{
+ Q_Q(QDeclarativeFlickable);
qreal maxDistance = -1;
// -ve velocity means list is moving up
if (velocity > 0) {
- const qreal minY = q->minYExtent();
- if (_moveY.value() < minY)
- maxDistance = qAbs(minY -_moveY.value() + (overShoot?overShootDistance(velocity,q->height()):0));
- flickTargetY = minY;
+ if (data.move.value() < minExtent)
+ maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity,vSize):0));
+ data.flickTarget = minExtent;
} else {
- const qreal maxY = q->maxYExtent();
- if (_moveY.value() > maxY)
- maxDistance = qAbs(maxY - _moveY.value()) + (overShoot?overShootDistance(velocity,q->height()):0);
- flickTargetY = maxY;
+ if (data.move.value() > maxExtent)
+ maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity,vSize):0);
+ data.flickTarget = maxExtent;
}
if (maxDistance > 0) {
qreal v = velocity;
@@ -226,55 +220,20 @@ void QDeclarativeFlickablePrivate::flickY(qreal velocity)
else
v = maxVelocity;
}
- timeline.reset(_moveY);
- timeline.accel(_moveY, v, deceleration, maxDistance);
- timeline.callback(QDeclarativeTimeLineCallback(&_moveY, fixupY_callback, this));
+ timeline.reset(data.move);
+ timeline.accel(data.move, v, deceleration, maxDistance);
+ timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
if (!flicked) {
flicked = true;
emit q->flickingChanged();
emit q->flickStarted();
}
} else {
- timeline.reset(_moveY);
- fixupY();
+ timeline.reset(data.move);
+ fixup(data, minExtent, maxExtent);
}
}
-void QDeclarativeFlickablePrivate::fixupX()
-{
- Q_Q(QDeclarativeFlickable);
- if (!q->xflick() || _moveX.timeLine())
- return;
-
- if (_moveX.value() > q->minXExtent() || (q->maxXExtent() > q->minXExtent())) {
- timeline.reset(_moveX);
- if (_moveX.value() != q->minXExtent()) {
- if (fixupDuration) {
- qreal dist = q->minXExtent() - _moveX;
- timeline.move(_moveX, q->minXExtent() - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
- timeline.move(_moveX, q->minXExtent(), QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
- } else {
- _moveX.setValue(q->minXExtent());
- }
- }
- //emit flickingChanged();
- } else if (_moveX.value() < q->maxXExtent()) {
- timeline.reset(_moveX);
- if (fixupDuration) {
- qreal dist = q->maxXExtent() - _moveX;
- timeline.move(_moveX, q->maxXExtent() - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
- timeline.move(_moveX, q->maxXExtent(), QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
- } else {
- _moveX.setValue(q->maxXExtent());
- }
- //emit flickingChanged();
- } else {
- flicked = false;
- }
-
- vTime = timeline.time();
-}
-
void QDeclarativeFlickablePrivate::fixupY_callback(void *data)
{
((QDeclarativeFlickablePrivate *)data)->fixupY();
@@ -285,32 +244,46 @@ void QDeclarativeFlickablePrivate::fixupX_callback(void *data)
((QDeclarativeFlickablePrivate *)data)->fixupX();
}
+void QDeclarativeFlickablePrivate::fixupX()
+{
+ Q_Q(QDeclarativeFlickable);
+ if (!q->xflick() || hData.move.timeLine())
+ return;
+
+ fixup(hData, q->minXExtent(), q->maxXExtent());
+}
+
void QDeclarativeFlickablePrivate::fixupY()
{
Q_Q(QDeclarativeFlickable);
- if (!q->yflick() || _moveY.timeLine())
+ if (!q->yflick() || vData.move.timeLine())
return;
- if (_moveY.value() > q->minYExtent() || (q->maxYExtent() > q->minYExtent())) {
- timeline.reset(_moveY);
- if (_moveY.value() != q->minYExtent()) {
+ fixup(vData, q->minYExtent(), q->maxYExtent());
+}
+
+void QDeclarativeFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
+{
+ if (data.move.value() > minExtent || maxExtent > minExtent) {
+ timeline.reset(data.move);
+ if (data.move.value() != minExtent) {
if (fixupDuration) {
- qreal dist = q->minYExtent() - _moveY;
- timeline.move(_moveY, q->minYExtent() - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
- timeline.move(_moveY, q->minYExtent(), QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
+ qreal dist = minExtent - data.move;
+ timeline.move(data.move, minExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
+ timeline.move(data.move, minExtent, QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
} else {
- _moveY.setValue(q->minYExtent());
+ data.move.setValue(minExtent);
}
}
//emit flickingChanged();
- } else if (_moveY.value() < q->maxYExtent()) {
- timeline.reset(_moveY);
+ } else if (data.move.value() < maxExtent) {
+ timeline.reset(data.move);
if (fixupDuration) {
- qreal dist = q->maxYExtent() - _moveY;
- timeline.move(_moveY, q->maxYExtent() - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
- timeline.move(_moveY, q->maxYExtent(), QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
+ qreal dist = maxExtent - data.move;
+ timeline.move(data.move, maxExtent - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
+ timeline.move(data.move, maxExtent, QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
} else {
- _moveY.setValue(q->maxYExtent());
+ data.move.setValue(maxExtent);
}
//emit flickingChanged();
} else {
@@ -327,31 +300,31 @@ void QDeclarativeFlickablePrivate::updateBeginningEnd()
// Vertical
const int maxyextent = int(-q->maxYExtent());
- const qreal ypos = -_moveY.value();
+ const qreal ypos = -vData.move.value();
bool atBeginning = (ypos <= -q->minYExtent());
bool atEnd = (maxyextent <= ypos);
- if (atBeginning != atYBeginning) {
- atYBeginning = atBeginning;
+ if (atBeginning != vData.atBeginning) {
+ vData.atBeginning = atBeginning;
atBoundaryChange = true;
}
- if (atEnd != atYEnd) {
- atYEnd = atEnd;
+ if (atEnd != vData.atEnd) {
+ vData.atEnd = atEnd;
atBoundaryChange = true;
}
// Horizontal
const int maxxextent = int(-q->maxXExtent());
- const qreal xpos = -_moveX.value();
+ const qreal xpos = -hData.move.value();
atBeginning = (xpos <= -q->minXExtent());
atEnd = (maxxextent <= xpos);
- if (atBeginning != atXBeginning) {
- atXBeginning = atBeginning;
+ if (atBeginning != hData.atBeginning) {
+ hData.atBeginning = atBeginning;
atBoundaryChange = true;
}
- if (atEnd != atXEnd) {
- atXEnd = atEnd;
+ if (atEnd != hData.atEnd) {
+ hData.atEnd = atEnd;
atBoundaryChange = true;
}
@@ -468,17 +441,17 @@ QDeclarativeFlickable::~QDeclarativeFlickable()
qreal QDeclarativeFlickable::contentX() const
{
Q_D(const QDeclarativeFlickable);
- return -d->_moveX.value();
+ return -d->hData.move.value();
}
void QDeclarativeFlickable::setContentX(qreal pos)
{
Q_D(QDeclarativeFlickable);
pos = qRound(pos);
- d->timeline.reset(d->_moveX);
+ d->timeline.reset(d->hData.move);
d->vTime = d->timeline.time();
- if (-pos != d->_moveX.value()) {
- d->_moveX.setValue(-pos);
+ if (-pos != d->hData.move.value()) {
+ d->hData.move.setValue(-pos);
viewportMoved();
}
}
@@ -486,17 +459,17 @@ void QDeclarativeFlickable::setContentX(qreal pos)
qreal QDeclarativeFlickable::contentY() const
{
Q_D(const QDeclarativeFlickable);
- return -d->_moveY.value();
+ return -d->vData.move.value();
}
void QDeclarativeFlickable::setContentY(qreal pos)
{
Q_D(QDeclarativeFlickable);
pos = qRound(pos);
- d->timeline.reset(d->_moveY);
+ d->timeline.reset(d->vData.move);
d->vTime = d->timeline.time();
- if (-pos != d->_moveY.value()) {
- d->_moveY.setValue(-pos);
+ if (-pos != d->vData.move.value()) {
+ d->vData.move.setValue(-pos);
viewportMoved();
}
}
@@ -543,13 +516,13 @@ void QDeclarativeFlickable::setInteractive(bool interactive)
qreal QDeclarativeFlickable::horizontalVelocity() const
{
Q_D(const QDeclarativeFlickable);
- return d->horizontalVelocity.value();
+ return d->hData.smoothVelocity.value();
}
qreal QDeclarativeFlickable::verticalVelocity() const
{
Q_D(const QDeclarativeFlickable);
- return d->verticalVelocity.value();
+ return d->vData.smoothVelocity.value();
}
/*!
@@ -564,25 +537,25 @@ qreal QDeclarativeFlickable::verticalVelocity() const
bool QDeclarativeFlickable::isAtXEnd() const
{
Q_D(const QDeclarativeFlickable);
- return d->atXEnd;
+ return d->hData.atEnd;
}
bool QDeclarativeFlickable::isAtXBeginning() const
{
Q_D(const QDeclarativeFlickable);
- return d->atXBeginning;
+ return d->hData.atBeginning;
}
bool QDeclarativeFlickable::isAtYEnd() const
{
Q_D(const QDeclarativeFlickable);
- return d->atYEnd;
+ return d->vData.atEnd;
}
bool QDeclarativeFlickable::isAtYBeginning() const
{
Q_D(const QDeclarativeFlickable);
- return d->atYBeginning;
+ return d->vData.atBeginning;
}
void QDeclarativeFlickable::ticked()
@@ -636,19 +609,19 @@ void QDeclarativeFlickable::setFlickDirection(FlickDirection direction)
void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEvent *event)
{
- if (interactive && timeline.isActive() && (qAbs(velocityX) > 10 || qAbs(velocityY) > 10))
+ if (interactive && timeline.isActive() && (qAbs(hData.velocity) > 10 || qAbs(vData.velocity) > 10))
stealMouse = true; // If we've been flicked then steal the click.
else
stealMouse = false;
pressed = true;
timeline.clear();
- velocityX = 0;
- velocityY = 0;
+ hData.velocity = 0;
+ vData.velocity = 0;
lastPos = QPoint();
QDeclarativeItemPrivate::start(lastPosTime);
pressPos = event->pos();
- pressX = _moveX.value();
- pressY = _moveY.value();
+ hData.pressPos = hData.move.value();
+ vData.pressPos = vData.move.value();
flicked = false;
QDeclarativeItemPrivate::start(pressTime);
QDeclarativeItemPrivate::start(velocityTime);
@@ -666,7 +639,7 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
if (q->yflick()) {
int dy = int(event->pos().y() - pressPos.y());
if (qAbs(dy) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) {
- qreal newY = dy + pressY;
+ qreal newY = dy + vData.pressPos;
const qreal minY = q->minYExtent();
const qreal maxY = q->maxYExtent();
if (newY > minY)
@@ -682,7 +655,7 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
rejectY = true;
}
if (!rejectY && stealMouse) {
- _moveY.setValue(newY);
+ vData.move.setValue(newY);
moved = true;
}
if (qAbs(dy) > QApplication::startDragDistance())
@@ -693,7 +666,7 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
if (q->xflick()) {
int dx = int(event->pos().x() - pressPos.x());
if (qAbs(dx) > QApplication::startDragDistance() || QDeclarativeItemPrivate::elapsed(pressTime) > 200) {
- qreal newX = dx + pressX;
+ qreal newX = dx + hData.pressPos;
const qreal minX = q->minXExtent();
const qreal maxX = q->maxXExtent();
if (newX > minX)
@@ -709,7 +682,7 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
rejectX = true;
}
if (!rejectX && stealMouse) {
- _moveX.setValue(newX);
+ hData.move.setValue(newX);
moved = true;
}
@@ -725,20 +698,20 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent
if (q->yflick()) {
qreal diff = event->pos().y() - lastPos.y();
// average to reduce the effect of spurious moves
- velocityY += diff / elapsed;
- velocityY /= 2;
+ vData.velocity += diff / elapsed;
+ vData.velocity /= 2;
}
if (q->xflick()) {
qreal diff = event->pos().x() - lastPos.x();
// average to reduce the effect of spurious moves
- velocityX += diff / elapsed;
- velocityX /= 2;
+ hData.velocity += diff / elapsed;
+ hData.velocity /= 2;
}
}
- if (rejectY) velocityY = 0;
- if (rejectX) velocityX = 0;
+ if (rejectY) vData.velocity = 0;
+ if (rejectX) hData.velocity = 0;
if (moved) {
q->movementStarting();
@@ -759,13 +732,13 @@ void QDeclarativeFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEv
if (QDeclarativeItemPrivate::elapsed(lastPosTime) > 100) {
// if we drag then pause before release we should not cause a flick.
- velocityX = 0.0;
- velocityY = 0.0;
+ hData.velocity = 0.0;
+ vData.velocity = 0.0;
}
vTime = timeline.time();
- if (qAbs(velocityY) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) {
- qreal velocity = velocityY;
+ if (qAbs(vData.velocity) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) {
+ qreal velocity = vData.velocity;
if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks.
velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity;
flickY(velocity);
@@ -773,8 +746,8 @@ void QDeclarativeFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEv
fixupY();
}
- if (qAbs(velocityX) > 10 && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) {
- qreal velocity = velocityX;
+ if (qAbs(hData.velocity) > 10 && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) {
+ qreal velocity = hData.velocity;
if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks.
velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity;
flickX(velocity);
@@ -832,19 +805,19 @@ void QDeclarativeFlickable::wheelEvent(QGraphicsSceneWheelEvent *event)
QDeclarativeItem::wheelEvent(event);
} else if (yflick()) {
if (event->delta() > 0)
- d->velocityY = qMax(event->delta() - d->verticalVelocity.value(), qreal(250.0));
+ d->vData.velocity = qMax(event->delta() - d->vData.smoothVelocity.value(), qreal(250.0));
else
- d->velocityY = qMin(event->delta() - d->verticalVelocity.value(), qreal(-250.0));
+ d->vData.velocity = qMin(event->delta() - d->vData.smoothVelocity.value(), qreal(-250.0));
d->flicked = false;
- d->flickY(d->velocityY);
+ d->flickY(d->vData.velocity);
event->accept();
} else if (xflick()) {
if (event->delta() > 0)
- d->velocityX = qMax(event->delta() - d->horizontalVelocity.value(), qreal(250.0));
+ d->hData.velocity = qMax(event->delta() - d->hData.smoothVelocity.value(), qreal(250.0));
else
- d->velocityX = qMin(event->delta() - d->horizontalVelocity.value(), qreal(-250.0));
+ d->hData.velocity = qMin(event->delta() - d->hData.smoothVelocity.value(), qreal(-250.0));
d->flicked = false;
- d->flickX(d->velocityX);
+ d->flickX(d->hData.velocity);
event->accept();
} else {
QDeclarativeItem::wheelEvent(event);
@@ -946,32 +919,56 @@ void QDeclarativeFlickable::viewportMoved()
qreal prevX = d->lastFlickablePosition.y();
d->velocityTimeline.clear();
if (d->pressed) {
- qreal horizontalVelocity = (prevX - d->_moveX.value()) * 1000 / elapsed;
- qreal verticalVelocity = (prevY - d->_moveY.value()) * 1000 / elapsed;
- d->velocityTimeline.move(d->horizontalVelocity, horizontalVelocity, d->reportedVelocitySmoothing);
- d->velocityTimeline.move(d->horizontalVelocity, 0, d->reportedVelocitySmoothing);
- d->velocityTimeline.move(d->verticalVelocity, verticalVelocity, d->reportedVelocitySmoothing);
- d->velocityTimeline.move(d->verticalVelocity, 0, d->reportedVelocitySmoothing);
+ 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->_moveX.value()) * 1000 / (d->timeline.time() - d->vTime);
- qreal verticalVelocity = (prevY - d->_moveY.value()) * 1000 / (d->timeline.time() - d->vTime);
- d->horizontalVelocity.setValue(horizontalVelocity);
- d->verticalVelocity.setValue(verticalVelocity);
+ qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
+ qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
+ d->hData.smoothVelocity.setValue(horizontalVelocity);
+ d->vData.smoothVelocity.setValue(verticalVelocity);
}
}
- d->lastFlickablePosition = QPointF(d->_moveY.value(), d->_moveX.value());
+ d->lastFlickablePosition = QPointF(d->vData.move.value(), d->hData.move.value());
d->vTime = d->timeline.time();
d->updateBeginningEnd();
}
+void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry)
+{
+ Q_D(QDeclarativeFlickable);
+ QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
+
+ bool changed = false;
+ if (newGeometry.width() != oldGeometry.width()) {
+ if (d->hData.viewSize < 0) {
+ d->viewport->setWidth(width());
+ emit contentWidthChanged();
+ }
+ }
+ if (newGeometry.height() != oldGeometry.height()) {
+ if (d->vData.viewSize < 0) {
+ d->viewport->setHeight(height());
+ emit contentHeightChanged();
+ }
+ }
+
+ if (changed)
+ d->updateBeginningEnd();
+}
+
void QDeclarativeFlickable::cancelFlick()
{
Q_D(QDeclarativeFlickable);
- d->timeline.reset(d->_moveX);
- d->timeline.reset(d->_moveY);
+ d->timeline.reset(d->hData.move);
+ d->timeline.reset(d->vData.move);
movementEnding();
}
@@ -1038,15 +1035,15 @@ void QDeclarativeFlickable::setOverShoot(bool o)
qreal QDeclarativeFlickable::contentWidth() const
{
Q_D(const QDeclarativeFlickable);
- return d->vWidth;
+ return d->hData.viewSize;
}
void QDeclarativeFlickable::setContentWidth(qreal w)
{
Q_D(QDeclarativeFlickable);
- if (d->vWidth == w)
+ if (d->hData.viewSize == w)
return;
- d->vWidth = w;
+ d->hData.viewSize = w;
if (w < 0)
d->viewport->setWidth(width());
else
@@ -1058,38 +1055,18 @@ void QDeclarativeFlickable::setContentWidth(qreal w)
d->updateBeginningEnd();
}
-void QDeclarativeFlickable::widthChange()
-{
- Q_D(QDeclarativeFlickable);
- if (d->vWidth < 0) {
- d->viewport->setWidth(width());
- emit contentWidthChanged();
- }
- d->updateBeginningEnd();
-}
-
-void QDeclarativeFlickable::heightChange()
-{
- Q_D(QDeclarativeFlickable);
- if (d->vHeight < 0) {
- d->viewport->setHeight(height());
- emit contentHeightChanged();
- }
- d->updateBeginningEnd();
-}
-
qreal QDeclarativeFlickable::contentHeight() const
{
Q_D(const QDeclarativeFlickable);
- return d->vHeight;
+ return d->vData.viewSize;
}
void QDeclarativeFlickable::setContentHeight(qreal h)
{
Q_D(QDeclarativeFlickable);
- if (d->vHeight == h)
+ if (d->vData.viewSize == h)
return;
- d->vHeight = h;
+ d->vData.viewSize = h;
if (h < 0)
d->viewport->setHeight(height());
else
@@ -1104,19 +1081,19 @@ void QDeclarativeFlickable::setContentHeight(qreal h)
qreal QDeclarativeFlickable::vWidth() const
{
Q_D(const QDeclarativeFlickable);
- if (d->vWidth < 0)
+ if (d->hData.viewSize < 0)
return width();
else
- return d->vWidth;
+ return d->hData.viewSize;
}
qreal QDeclarativeFlickable::vHeight() const
{
Q_D(const QDeclarativeFlickable);
- if (d->vHeight < 0)
+ if (d->vData.viewSize < 0)
return height();
else
- return d->vHeight;
+ return d->vData.viewSize;
}
bool QDeclarativeFlickable::xflick() const
@@ -1327,8 +1304,8 @@ void QDeclarativeFlickable::movementEnding()
emit flickingChanged();
emit flickEnded();
}
- d->horizontalVelocity.setValue(0);
- d->verticalVelocity.setValue(0);
+ d->hData.smoothVelocity.setValue(0);
+ d->vData.smoothVelocity.setValue(0);
}
void QDeclarativeFlickablePrivate::updateVelocity()
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p.h
index 4617688..7dcab98 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeflickable_p.h
@@ -174,8 +174,6 @@ protected Q_SLOTS:
virtual void ticked();
void movementStarting();
void movementEnding();
- void heightChange();
- void widthChange();
protected:
virtual qreal minXExtent() const;
@@ -185,6 +183,8 @@ protected:
qreal vWidth() const;
qreal vHeight() const;
virtual void viewportMoved();
+ virtual void geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry);
bool sendMouseEvent(QGraphicsSceneMouseEvent *event);
bool xflick() const;
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
index ad7a04d..c963c2b 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
@@ -56,6 +56,7 @@
#include "qdeclarativeflickable_p.h"
#include "qdeclarativeitem_p.h"
+#include "qdeclarativeitemchangelistener_p.h"
#include <qdeclarative.h>
#include <qdeclarativetimeline_p_p.h>
@@ -66,17 +67,51 @@
QT_BEGIN_NAMESPACE
class QDeclarativeFlickableVisibleArea;
-class QDeclarativeFlickablePrivate : public QDeclarativeItemPrivate
+class QDeclarativeFlickablePrivate : public QDeclarativeItemPrivate, public QDeclarativeItemChangeListener
{
Q_DECLARE_PUBLIC(QDeclarativeFlickable)
public:
QDeclarativeFlickablePrivate();
void init();
- virtual void flickX(qreal velocity);
- virtual void flickY(qreal velocity);
- virtual void fixupX();
- virtual void fixupY();
+
+ struct Velocity : public QDeclarativeTimeLineValue
+ {
+ Velocity(QDeclarativeFlickablePrivate *p)
+ : parent(p) {}
+ virtual void setValue(qreal v) {
+ if (v != value()) {
+ QDeclarativeTimeLineValue::setValue(v);
+ parent->updateVelocity();
+ }
+ }
+ QDeclarativeFlickablePrivate *parent;
+ };
+
+ struct AxisData {
+ AxisData(QDeclarativeFlickablePrivate *fp, void (QDeclarativeFlickablePrivate::*func)(qreal))
+ : move(fp, func), viewSize(-1), smoothVelocity(fp), atEnd(false), atBeginning(true)
+ {}
+
+ QDeclarativeTimeLineValueProxy<QDeclarativeFlickablePrivate> move;
+ qreal viewSize;
+ qreal pressPos;
+ qreal velocity;
+ qreal flickTarget;
+ QDeclarativeFlickablePrivate::Velocity smoothVelocity;
+ bool atEnd : 1;
+ bool atBeginning : 1;
+ };
+
+ void flickX(qreal velocity);
+ void flickY(qreal velocity);
+ virtual void flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+ QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity);
+
+ void fixupX();
+ void fixupY();
+ virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
+
void updateBeginningEnd();
void captureDelayedPress(QGraphicsSceneMouseEvent *event);
@@ -87,38 +122,30 @@ public:
qreal overShootDistance(qreal velocity, qreal size);
+ void itemGeometryChanged(QDeclarativeItem *, const QRectF &, const QRectF &);
+
public:
QDeclarativeItem *viewport;
- QDeclarativeTimeLineValueProxy<QDeclarativeFlickablePrivate> _moveX;
- QDeclarativeTimeLineValueProxy<QDeclarativeFlickablePrivate> _moveY;
+
+ AxisData hData;
+ AxisData vData;
+
QDeclarativeTimeLine timeline;
- qreal vWidth;
- qreal vHeight;
bool overShoot : 1;
bool flicked : 1;
bool moving : 1;
bool stealMouse : 1;
bool pressed : 1;
- bool atXEnd : 1;
- bool atXBeginning : 1;
- bool atYEnd : 1;
- bool atYBeginning : 1;
bool interactive : 1;
QTime lastPosTime;
QPointF lastPos;
QPointF pressPos;
- qreal pressX;
- qreal pressY;
- qreal velocityX;
- qreal velocityY;
QTime pressTime;
qreal deceleration;
qreal maxVelocity;
QTime velocityTime;
QPointF lastFlickablePosition;
qreal reportedVelocitySmoothing;
- qreal flickTargetX;
- qreal flickTargetY;
QGraphicsSceneMouseEvent *delayedPressEvent;
QGraphicsItem *delayedPressTarget;
QBasicTimer delayedPressTimer;
@@ -129,20 +156,6 @@ public:
static void fixupX_callback(void *);
void updateVelocity();
- struct Velocity : public QDeclarativeTimeLineValue
- {
- Velocity(QDeclarativeFlickablePrivate *p)
- : parent(p) {}
- virtual void setValue(qreal v) {
- if (v != value()) {
- QDeclarativeTimeLineValue::setValue(v);
- parent->updateVelocity();
- }
- }
- QDeclarativeFlickablePrivate *parent;
- };
- Velocity horizontalVelocity;
- Velocity verticalVelocity;
int vTime;
QDeclarativeTimeLine velocityTimeline;
QDeclarativeFlickableVisibleArea *visibleArea;
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index 463b238..76ad9b7 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -236,6 +236,19 @@ public:
return -1; // Not in visibleList
}
+ void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) {
+ Q_Q(const QDeclarativeGridView);
+ QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry);
+ if (item == q) {
+ if (newGeometry.height() != oldGeometry.height()
+ || newGeometry.width() != oldGeometry.width()) {
+ if (q->isComponentComplete()) {
+ updateGrid();
+ layout();
+ }
+ }
+ }
+ }
// for debugging only
void checkVisible() const {
int skip = 0;
@@ -288,9 +301,8 @@ void QDeclarativeGridViewPrivate::init()
{
Q_Q(QDeclarativeGridView);
q->setFlag(QGraphicsItem::ItemIsFocusScope);
- QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(sizeChange()));
- QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(sizeChange()));
q->setFlickDirection(QDeclarativeFlickable::VerticalFlick);
+ addItemChangeListener(this, Geometry);
}
void QDeclarativeGridViewPrivate::clear()
@@ -1142,15 +1154,6 @@ void QDeclarativeGridView::setCellHeight(int cellHeight)
}
}
-void QDeclarativeGridView::sizeChange()
-{
- Q_D(QDeclarativeGridView);
- if (isComponentComplete()) {
- d->updateGrid();
- d->layout();
- }
-}
-
void QDeclarativeGridView::viewportMoved()
{
Q_D(QDeclarativeGridView);
@@ -1158,16 +1161,16 @@ void QDeclarativeGridView::viewportMoved()
d->lazyRelease = true;
if (d->flicked) {
if (yflick()) {
- if (d->velocityY > 0)
+ if (d->vData.velocity > 0)
d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore;
- else if (d->velocityY < 0)
+ else if (d->vData.velocity < 0)
d->bufferMode = QDeclarativeGridViewPrivate::BufferAfter;
}
if (xflick()) {
- if (d->velocityX > 0)
+ if (d->hData.velocity > 0)
d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore;
- else if (d->velocityX < 0)
+ else if (d->hData.velocity < 0)
d->bufferMode = QDeclarativeGridViewPrivate::BufferAfter;
}
}
diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h
index 22fcef6..7255d3d 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h
@@ -154,7 +154,6 @@ private Q_SLOTS:
void destroyRemoved();
void createdItem(int index, QDeclarativeItem *item);
void destroyingItem(QDeclarativeItem *item);
- void sizeChange();
void layout();
private:
diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp
index 2739ab8..a20d6bc 100644
--- a/src/declarative/graphicsitems/qdeclarativeimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp
@@ -127,7 +127,6 @@ QT_BEGIN_NAMESPACE
QDeclarativeImage::QDeclarativeImage(QDeclarativeItem *parent)
: QDeclarativeImageBase(*(new QDeclarativeImagePrivate), parent)
{
- connect(this, SIGNAL(pixmapChanged()), this, SLOT(updatePaintedGeometry()));
}
QDeclarativeImage::QDeclarativeImage(QDeclarativeImagePrivate &dd, QDeclarativeItem *parent)
@@ -172,7 +171,7 @@ void QDeclarativeImagePrivate::setPixmap(const QPixmap &pixmap)
status = pix.isNull() ? QDeclarativeImageBase::Null : QDeclarativeImageBase::Ready;
q->update();
- emit q->pixmapChanged();
+ q->pixmapChange();
}
/*!
@@ -384,4 +383,10 @@ void QDeclarativeImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWi
}
}
+void QDeclarativeImage::pixmapChange()
+{
+ updatePaintedGeometry();
+ QDeclarativeImageBase::pixmapChange();
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativeimage_p.h b/src/declarative/graphicsitems/qdeclarativeimage_p.h
index fb77ac9..7394774 100644
--- a/src/declarative/graphicsitems/qdeclarativeimage_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeimage_p.h
@@ -85,6 +85,7 @@ Q_SIGNALS:
protected:
QDeclarativeImage(QDeclarativeImagePrivate &dd, QDeclarativeItem *parent);
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+ void pixmapChange();
protected Q_SLOTS:
void updatePaintedGeometry();
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
index a8cce3f..0e9638d 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
@@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE
QDeclarativeImageBase::QDeclarativeImageBase(QDeclarativeImageBasePrivate &dd, QDeclarativeItem *parent)
: QDeclarativeItem(dd, parent)
{
- setFlag(QGraphicsItem::ItemHasNoContents, false);
}
QDeclarativeImageBase::~QDeclarativeImageBase()
@@ -131,7 +130,7 @@ void QDeclarativeImageBase::load()
setImplicitWidth(0);
setImplicitHeight(0);
emit statusChanged(d->status);
- emit pixmapChanged();
+ pixmapChange();
update();
} else {
d->status = Loading;
@@ -173,7 +172,7 @@ void QDeclarativeImageBase::load()
d->progress = 1.0;
emit statusChanged(d->status);
emit progressChanged(d->progress);
- emit pixmapChanged();
+ pixmapChange();
update();
}
}
@@ -197,7 +196,7 @@ void QDeclarativeImageBase::requestFinished()
d->progress = 1.0;
emit statusChanged(d->status);
emit progressChanged(1.0);
- emit pixmapChanged();
+ pixmapChange();
update();
}
@@ -218,4 +217,9 @@ void QDeclarativeImageBase::componentComplete()
load();
}
+void QDeclarativeImageBase::pixmapChange()
+{
+ emit pixmapChanged();
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase_p.h b/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
index c8c50ac..cfebdca 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
@@ -81,6 +81,7 @@ Q_SIGNALS:
protected:
virtual void load();
virtual void componentComplete();
+ virtual void pixmapChange();
QDeclarativeImageBase(QDeclarativeImageBasePrivate &dd, QDeclarativeItem *parent);
private Q_SLOTS:
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
index 2e062a8..c4a61f3 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
@@ -71,6 +71,7 @@ public:
pendingPixmapCache(false),
async(false)
{
+ QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents;
}
QPixmap pix;
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index cd8d143..d54bb70 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -139,7 +139,7 @@ public:
//----------------------------------------------------------------------------
-class QDeclarativeListViewPrivate : public QDeclarativeFlickablePrivate, private QDeclarativeItemChangeListener
+class QDeclarativeListViewPrivate : public QDeclarativeFlickablePrivate
{
Q_DECLARE_PUBLIC(QDeclarativeListView)
@@ -389,11 +389,14 @@ public:
}
}
- void itemGeometryChanged(QDeclarativeItem *, const QRectF &newGeometry, const QRectF &oldGeometry) {
- if ((orient == QDeclarativeListView::Vertical && newGeometry.height() != oldGeometry.height())
- || newGeometry.width() != oldGeometry.width()) {
- layout();
- fixupPosition();
+ void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) {
+ QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry);
+ if (item != viewport) {
+ if ((orient == QDeclarativeListView::Vertical && newGeometry.height() != oldGeometry.height())
+ || newGeometry.width() != oldGeometry.width()) {
+ layout();
+ fixupPosition();
+ }
}
}
@@ -425,10 +428,9 @@ public:
void updateHeader();
void updateFooter();
void fixupPosition();
- virtual void fixupY();
- virtual void fixupX();
- virtual void flickX(qreal velocity);
- virtual void flickY(qreal velocity);
+ virtual void fixup(AxisData &data, qreal minExtent, qreal maxExtent);
+ virtual void flick(QDeclarativeFlickablePrivate::AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+ QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity);
QDeclarativeGuard<QDeclarativeVisualModel> model;
QVariant modelVariant;
@@ -1061,52 +1063,16 @@ void QDeclarativeListViewPrivate::fixupPosition()
fixupX();
}
-void QDeclarativeListViewPrivate::fixupY()
+void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent)
{
Q_Q(QDeclarativeListView);
- if (orient == QDeclarativeListView::Horizontal)
- return;
- if (!q->yflick() || _moveY.timeLine())
+ if ((orient == QDeclarativeListView::Horizontal && &data == &vData)
+ || (orient == QDeclarativeListView::Vertical && &data == &hData))
return;
- int oldDuration = fixupDuration;
- fixupDuration = moveReason == Mouse ? fixupDuration : 0;
-
- if (haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) {
- if (currentItem && currentItem->position() - position() != highlightRangeStart) {
- qreal pos = currentItem->position() - highlightRangeStart;
- timeline.reset(_moveY);
- if (fixupDuration)
- timeline.move(_moveY, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
- _moveY.setValue(-pos);
- vTime = timeline.time();
- }
- } else if (snapMode != QDeclarativeListView::NoSnap) {
- if (FxListItem *item = snapItemAt(position())) {
- qreal pos = qMin(item->position() - highlightRangeStart, -q->maxYExtent());
- qreal dist = qAbs(_moveY + pos);
- if (dist > 0) {
- timeline.reset(_moveY);
- if (fixupDuration)
- timeline.move(_moveY, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- else
- _moveY.setValue(-pos);
- vTime = timeline.time();
- }
- }
- } else {
- QDeclarativeFlickablePrivate::fixupY();
- }
- fixupDuration = oldDuration;
-}
-
-void QDeclarativeListViewPrivate::fixupX()
-{
- Q_Q(QDeclarativeListView);
- if (orient == QDeclarativeListView::Vertical)
- return;
- if (!q->xflick() || _moveX.timeLine())
+ if ((&data == &vData && !q->yflick())
+ || (&data == &hData && !q->xflick())
+ || data.move.timeLine())
return;
int oldDuration = fixupDuration;
@@ -1115,161 +1081,62 @@ void QDeclarativeListViewPrivate::fixupX()
if (haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) {
if (currentItem && currentItem->position() - position() != highlightRangeStart) {
qreal pos = currentItem->position() - highlightRangeStart;
- timeline.reset(_moveX);
+ timeline.reset(data.move);
if (fixupDuration)
- timeline.move(_moveX, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration);
+ timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
else
- _moveX.setValue(-pos);
+ data.move.setValue(-pos);
vTime = timeline.time();
}
} else if (snapMode != QDeclarativeListView::NoSnap) {
if (FxListItem *item = snapItemAt(position())) {
- qreal pos = qMin(item->position() - highlightRangeStart, -q->maxXExtent());
- qreal dist = qAbs(_moveX + pos);
+ qreal pos = qMin(item->position() - highlightRangeStart, -maxExtent);
+ qreal dist = qAbs(data.move + pos);
if (dist > 0) {
- timeline.reset(_moveX);
+ timeline.reset(data.move);
if (fixupDuration)
- timeline.move(_moveX, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration);
+ timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
else
- _moveX.setValue(-pos);
+ data.move.setValue(-pos);
vTime = timeline.time();
}
}
} else {
- QDeclarativeFlickablePrivate::fixupX();
+ QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent);
}
fixupDuration = oldDuration;
}
-void QDeclarativeListViewPrivate::flickX(qreal velocity)
-{
- Q_Q(QDeclarativeListView);
-
- moveReason = Mouse;
- if ((!haveHighlightRange || highlightRange != QDeclarativeListView::StrictlyEnforceRange) && snapMode == QDeclarativeListView::NoSnap) {
- QDeclarativeFlickablePrivate::flickX(velocity);
- return;
- }
- qreal maxDistance = -1;
- const qreal maxX = q->maxXExtent();
- const qreal minX = q->minXExtent();
- // -ve velocity means list is moving up
- if (velocity > 0) {
- if (snapMode == QDeclarativeListView::SnapOneItem) {
- if (FxListItem *item = firstVisibleItem())
- maxDistance = qAbs(item->position() + _moveX.value());
- } else if (_moveX.value() < minX) {
- maxDistance = qAbs(minX -_moveX.value() + (overShoot?overShootDistance(velocity, q->width()):0));
- }
- if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange)
- flickTargetX = minX;
- } else {
- if (snapMode == QDeclarativeListView::SnapOneItem) {
- if (FxListItem *item = nextVisibleItem())
- maxDistance = qAbs(item->position() + _moveX.value());
- } else if (_moveX.value() > maxX) {
- maxDistance = qAbs(maxX - _moveX.value()) + (overShoot?overShootDistance(velocity, q->width()):0);
- }
- if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange)
- flickTargetX = maxX;
- }
- if (maxDistance > 0 && (snapMode != QDeclarativeListView::NoSnap || highlightRange == QDeclarativeListView::StrictlyEnforceRange)) {
- // These modes require the list to stop exactly on an item boundary.
- // The initial flick will estimate the boundary to stop on.
- // Since list items can have variable sizes, the boundary will be
- // reevaluated and adjusted as we approach the boundary.
- qreal v = velocity;
- if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
- if (v < 0)
- v = -maxVelocity;
- else
- v = maxVelocity;
- }
- if (!flicked) {
- // the initial flick - estimate boundary
- qreal accel = deceleration;
- qreal v2 = v * v;
- qreal maxAccel = v2 / (2.0f * maxDistance);
- if (maxAccel < accel) {
- qreal dist = v2 / (accel * 2.0);
- if (v > 0)
- dist = -dist;
- flickTargetX = -snapPosAt(-(_moveX.value() - highlightRangeStart) + dist) + highlightRangeStart;
- dist = -flickTargetX + _moveX.value();
- accel = v2 / (2.0f * qAbs(dist));
- overshootDist = 0.0;
- } else {
- flickTargetX = velocity > 0 ? minX : maxX;
- overshootDist = overShoot ? overShootDistance(v, q->width()) : 0;
- }
- timeline.reset(_moveX);
- timeline.accel(_moveX, v, accel, maxDistance + overshootDist);
- timeline.callback(QDeclarativeTimeLineCallback(&_moveX, fixupX_callback, this));
- flicked = true;
- emit q->flickingChanged();
- emit q->flickStarted();
- correctFlick = true;
- } else {
- // reevaluate the target boundary.
- qreal newtarget = flickTargetX;
- if (snapMode != QDeclarativeListView::NoSnap || highlightRange == QDeclarativeListView::StrictlyEnforceRange)
- newtarget = -snapPosAt(-(flickTargetX - highlightRangeStart)) + highlightRangeStart;
- if (velocity < 0 && newtarget < maxX)
- newtarget = maxX;
- else if (velocity > 0 && newtarget > minX)
- newtarget = minX;
- if (newtarget == flickTargetX) // boundary unchanged - nothing to do
- return;
- flickTargetX = newtarget;
- qreal dist = -newtarget + _moveX.value();
- if ((v < 0 && dist < 0) || (v > 0 && dist > 0)) {
- correctFlick = false;
- timeline.reset(_moveX);
- fixupX();
- return;
- }
- timeline.reset(_moveX);
- timeline.accelDistance(_moveX, v, -dist + (v < 0 ? -overshootDist : overshootDist));
- timeline.callback(QDeclarativeTimeLineCallback(&_moveX, fixupX_callback, this));
- }
- } else {
- correctFlick = false;
- timeline.reset(_moveX);
- fixupX();
- }
-}
-
-void QDeclarativeListViewPrivate::flickY(qreal velocity)
+void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+ QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity)
{
Q_Q(QDeclarativeListView);
moveReason = Mouse;
if ((!haveHighlightRange || highlightRange != QDeclarativeListView::StrictlyEnforceRange) && snapMode == QDeclarativeListView::NoSnap) {
- QDeclarativeFlickablePrivate::flickY(velocity);
+ QDeclarativeFlickablePrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, velocity);
return;
}
qreal maxDistance = -1;
- const qreal maxY = q->maxYExtent();
- const qreal minY = q->minYExtent();
// -ve velocity means list is moving up
if (velocity > 0) {
if (snapMode == QDeclarativeListView::SnapOneItem) {
if (FxListItem *item = firstVisibleItem())
- maxDistance = qAbs(item->position() + _moveY.value());
- } else if (_moveY.value() < minY) {
- maxDistance = qAbs(minY -_moveY.value() + (overShoot?overShootDistance(velocity, q->height()):0));
+ maxDistance = qAbs(item->position() + data.move.value());
+ } else if (data.move.value() < minExtent) {
+ maxDistance = qAbs(minExtent - data.move.value() + (overShoot?overShootDistance(velocity, vSize):0));
}
if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange)
- flickTargetY = minY;
+ data.flickTarget = minExtent;
} else {
if (snapMode == QDeclarativeListView::SnapOneItem) {
if (FxListItem *item = nextVisibleItem())
- maxDistance = qAbs(item->position() + _moveY.value());
- } else if (_moveY.value() > maxY) {
- maxDistance = qAbs(maxY - _moveY.value()) + (overShoot?overShootDistance(velocity, q->height()):0);
+ maxDistance = qAbs(item->position() + data.move.value());
+ } else if (data.move.value() > maxExtent) {
+ maxDistance = qAbs(maxExtent - data.move.value()) + (overShoot?overShootDistance(velocity, vSize):0);
}
if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange)
- flickTargetY = maxY;
+ data.flickTarget = maxExtent;
}
if (maxDistance > 0 && (snapMode != QDeclarativeListView::NoSnap || highlightRange == QDeclarativeListView::StrictlyEnforceRange)) {
// These modes require the list to stop exactly on an item boundary.
@@ -1292,48 +1159,48 @@ void QDeclarativeListViewPrivate::flickY(qreal velocity)
qreal dist = v2 / (accel * 2.0);
if (v > 0)
dist = -dist;
- flickTargetY = -snapPosAt(-(_moveY.value() - highlightRangeStart) + dist) + highlightRangeStart;
- dist = -flickTargetY + _moveY.value();
+ data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart;
+ dist = -data.flickTarget + data.move.value();
accel = v2 / (2.0f * qAbs(dist));
overshootDist = 0.0;
} else {
- flickTargetY = velocity > 0 ? minY : maxY;
- overshootDist = overShoot ? overShootDistance(v, q->height()) : 0;
+ data.flickTarget = velocity > 0 ? minExtent : maxExtent;
+ overshootDist = overShoot ? overShootDistance(v, vSize) : 0;
}
- timeline.reset(_moveY);
- timeline.accel(_moveY, v, accel, maxDistance + overshootDist);
- timeline.callback(QDeclarativeTimeLineCallback(&_moveY, fixupY_callback, this));
+ timeline.reset(data.move);
+ timeline.accel(data.move, v, accel, maxDistance + overshootDist);
+ timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
flicked = true;
emit q->flickingChanged();
emit q->flickStarted();
correctFlick = true;
} else {
// reevaluate the target boundary.
- qreal newtarget = flickTargetY;
+ qreal newtarget = data.flickTarget;
if (snapMode != QDeclarativeListView::NoSnap || highlightRange == QDeclarativeListView::StrictlyEnforceRange)
- newtarget = -snapPosAt(-(flickTargetY - highlightRangeStart)) + highlightRangeStart;
- if (velocity < 0 && newtarget < maxY)
- newtarget = maxY;
- else if (velocity > 0 && newtarget > minY)
- newtarget = minY;
- if (newtarget == flickTargetY) // boundary unchanged - nothing to do
+ newtarget = -snapPosAt(-(data.flickTarget - highlightRangeStart)) + highlightRangeStart;
+ if (velocity < 0 && newtarget < maxExtent)
+ newtarget = maxExtent;
+ else if (velocity > 0 && newtarget > minExtent)
+ newtarget = minExtent;
+ if (newtarget == data.flickTarget) // boundary unchanged - nothing to do
return;
- flickTargetY = newtarget;
- qreal dist = -newtarget + _moveY.value();
+ data.flickTarget = newtarget;
+ qreal dist = -newtarget + data.move.value();
if ((v < 0 && dist < 0) || (v > 0 && dist > 0)) {
correctFlick = false;
- timeline.reset(_moveY);
- fixupY();
+ timeline.reset(data.move);
+ fixup(data, minExtent, maxExtent);
return;
}
- timeline.reset(_moveY);
- timeline.accelDistance(_moveY, v, -dist + (v < 0 ? -overshootDist : overshootDist));
- timeline.callback(QDeclarativeTimeLineCallback(&_moveY, fixupY_callback, this));
+ timeline.reset(data.move);
+ timeline.accelDistance(data.move, v, -dist + (v < 0 ? -overshootDist : overshootDist));
+ timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this));
}
} else {
correctFlick = false;
- timeline.reset(_moveY);
- fixupY();
+ timeline.reset(data.move);
+ fixup(data, minExtent, maxExtent);
}
}
@@ -2107,33 +1974,33 @@ void QDeclarativeListView::viewportMoved()
// Near an end and it seems that the extent has changed?
// Recalculate the flick so that we don't end up in an odd position.
if (yflick()) {
- if (d->velocityY > 0) {
+ if (d->vData.velocity > 0) {
const qreal minY = minYExtent();
- if ((minY - d->_moveY.value() < height()/2 || d->flickTargetY - d->_moveY.value() < height()/2)
- && minY != d->flickTargetY)
- d->flickY(-d->verticalVelocity.value());
+ if ((minY - d->vData.move.value() < height()/2 || d->vData.flickTarget - d->vData.move.value() < height()/2)
+ && minY != d->vData.flickTarget)
+ d->flickY(-d->vData.smoothVelocity.value());
d->bufferMode = QDeclarativeListViewPrivate::BufferBefore;
- } else if (d->velocityY < 0) {
+ } else if (d->vData.velocity < 0) {
const qreal maxY = maxYExtent();
- if ((d->_moveY.value() - maxY < height()/2 || d->_moveY.value() - d->flickTargetY < height()/2)
- && maxY != d->flickTargetY)
- d->flickY(-d->verticalVelocity.value());
+ if ((d->vData.move.value() - maxY < height()/2 || d->vData.move.value() - d->vData.flickTarget < height()/2)
+ && maxY != d->vData.flickTarget)
+ d->flickY(-d->vData.smoothVelocity.value());
d->bufferMode = QDeclarativeListViewPrivate::BufferAfter;
}
}
if (xflick()) {
- if (d->velocityX > 0) {
+ if (d->hData.velocity > 0) {
const qreal minX = minXExtent();
- if ((minX - d->_moveX.value() < height()/2 || d->flickTargetX - d->_moveX.value() < height()/2)
- && minX != d->flickTargetX)
- d->flickX(-d->horizontalVelocity.value());
+ if ((minX - d->hData.move.value() < width()/2 || d->hData.flickTarget - d->hData.move.value() < width()/2)
+ && minX != d->hData.flickTarget)
+ d->flickX(-d->hData.smoothVelocity.value());
d->bufferMode = QDeclarativeListViewPrivate::BufferBefore;
- } else if (d->velocityX < 0) {
+ } else if (d->hData.velocity < 0) {
const qreal maxX = maxXExtent();
- if ((d->_moveX.value() - maxX < height()/2 || d->_moveX.value() - d->flickTargetX < height()/2)
- && maxX != d->flickTargetX)
- d->flickX(-d->horizontalVelocity.value());
+ if ((d->hData.move.value() - maxX < width()/2 || d->hData.move.value() - d->hData.flickTarget < width()/2)
+ && maxX != d->hData.flickTarget)
+ d->flickX(-d->hData.smoothVelocity.value());
d->bufferMode = QDeclarativeListViewPrivate::BufferAfter;
}
}
diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h
index f9b7b50..d66ac2b 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h
@@ -300,10 +300,10 @@ Q_SIGNALS:
public:
QDeclarativeListView *m_view;
- bool m_isCurrent;
mutable QString m_section;
QString m_prevSection;
- bool m_delayRemove;
+ bool m_isCurrent : 1;
+ bool m_delayRemove : 1;
};
diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp
index 50aa9ef..cc17157 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp
@@ -44,7 +44,6 @@
#include <qdeclarativestate_p.h>
#include <qdeclarativeopenmetaobject_p.h>
-
#include <QDebug>
#include <QEvent>
#include <qlistmodelinterface_p.h>
@@ -64,48 +63,31 @@ inline qreal qmlMod(qreal x, qreal y)
return fmod(x, y);
}
+static QDeclarativeOpenMetaObjectType *qPathViewAttachedType = 0;
-class QDeclarativePathViewAttached : public QObject
+QDeclarativePathViewAttached::QDeclarativePathViewAttached(QObject *parent)
+: QObject(parent), m_view(0), m_onPath(false), m_isCurrent(false)
{
- Q_OBJECT
-
- Q_PROPERTY(bool onPath READ isOnPath NOTIFY onPathChanged)
-public:
- QDeclarativePathViewAttached(QObject *parent)
- : QObject(parent), mo(new QDeclarativeOpenMetaObject(this)), onPath(false)
- {
- }
-
- ~QDeclarativePathViewAttached()
- {
- QDeclarativePathView::attachedProperties.remove(parent());
- }
-
- QVariant value(const QByteArray &name) const
- {
- return mo->value(name);
- }
- void setValue(const QByteArray &name, const QVariant &val)
- {
- mo->setValue(name, val);
- }
-
- bool isOnPath() const { return onPath; }
- void setOnPath(bool on) {
- if (on != onPath) {
- onPath = on;
- emit onPathChanged();
- }
+ if (qPathViewAttachedType) {
+ m_metaobject = new QDeclarativeOpenMetaObject(this, qPathViewAttachedType);
+ m_metaobject->setCached(true);
+ } else {
+ m_metaobject = new QDeclarativeOpenMetaObject(this);
}
+}
-Q_SIGNALS:
- void onPathChanged();
-
-private:
- QDeclarativeOpenMetaObject *mo;
- bool onPath;
-};
+QDeclarativePathViewAttached::~QDeclarativePathViewAttached()
+{
+}
+QVariant QDeclarativePathViewAttached::value(const QByteArray &name) const
+{
+ return m_metaobject->value(name);
+}
+void QDeclarativePathViewAttached::setValue(const QByteArray &name, const QVariant &val)
+{
+ m_metaobject->setValue(name, val);
+}
QDeclarativeItem *QDeclarativePathViewPrivate::getItem(int modelIndex)
{
@@ -113,8 +95,20 @@ QDeclarativeItem *QDeclarativePathViewPrivate::getItem(int modelIndex)
requestedIndex = modelIndex;
QDeclarativeItem *item = model->item(modelIndex, false);
if (item) {
- if (QObject *obj = QDeclarativePathView::qmlAttachedProperties(item))
- static_cast<QDeclarativePathViewAttached *>(obj)->setOnPath(true);
+ if (!attType) {
+ // pre-create one metatype to share with all attached objects
+ attType = new QDeclarativeOpenMetaObjectType(&QDeclarativePathViewAttached::staticMetaObject, qmlEngine(q));
+ foreach(const QString &attr, path->attributes()) {
+ attType->createProperty(attr.toUtf8());
+ }
+ }
+ qPathViewAttachedType = attType;
+ QDeclarativePathViewAttached *att = static_cast<QDeclarativePathViewAttached *>(qmlAttachedPropertiesObject<QDeclarativePathView>(item));
+ qPathViewAttachedType = 0;
+ if (att) {
+ att->m_view = q;
+ att->setOnPath(true);
+ }
item->setParentItem(q);
}
requestedIndex = -1;
@@ -125,14 +119,26 @@ void QDeclarativePathViewPrivate::releaseItem(QDeclarativeItem *item)
{
if (!item || !model)
return;
- if (QObject *obj = QDeclarativePathView::qmlAttachedProperties(item))
- static_cast<QDeclarativePathViewAttached *>(obj)->setOnPath(false);
- if (model->release(item) == 0) {
- if (QObject *obj = QDeclarativePathView::qmlAttachedProperties(item))
- static_cast<QDeclarativePathViewAttached *>(obj)->setOnPath(false);
+ if (QDeclarativePathViewAttached *att = attached(item))
+ att->setOnPath(false);
+ model->release(item);
+}
+
+QDeclarativePathViewAttached *QDeclarativePathViewPrivate::attached(QDeclarativeItem *item)
+{
+ return static_cast<QDeclarativePathViewAttached *>(qmlAttachedPropertiesObject<QDeclarativePathView>(item, false));
+}
+
+void QDeclarativePathViewPrivate::clear()
+{
+ for (int i=0; i<items.count(); i++){
+ QDeclarativeItem *p = items[i];
+ releaseItem(p);
}
+ items.clear();
}
+
/*!
\qmlclass PathView QDeclarativePathView
\since 4.7
@@ -147,6 +153,11 @@ void QDeclarativePathViewPrivate::releaseItem(QDeclarativeItem *item)
\image pathview.gif
+ Note that views do not enable \e clip automatically. If the view
+ is not clipped by another item or the screen, it will be necessary
+ to set \e {clip: true} in order to have the out of view items clipped
+ nicely.
+
\sa Path
*/
@@ -160,6 +171,9 @@ QDeclarativePathView::QDeclarativePathView(QDeclarativeItem *parent)
QDeclarativePathView::~QDeclarativePathView()
{
Q_D(QDeclarativePathView);
+ d->clear();
+ if (d->attType)
+ d->attType->release();
if (d->ownModel)
delete d->model;
}
@@ -185,6 +199,15 @@ QDeclarativePathView::~QDeclarativePathView()
*/
/*!
+ \qmlattachedproperty bool PathView::isCurrentItem
+ This attached property is true if this delegate is the current item; otherwise false.
+
+ It is attached to each instance of the delegate.
+
+ This property may be used to adjust the appearance of the current item.
+*/
+
+/*!
\qmlproperty model PathView::model
This property holds the model providing data for the view.
@@ -275,8 +298,15 @@ void QDeclarativePathView::setPath(QDeclarativePath *path)
Q_D(QDeclarativePathView);
if (d->path == path)
return;
+ if (d->path)
+ disconnect(d->path, SIGNAL(changed()), this, SLOT(refill()));
d->path = path;
connect(d->path, SIGNAL(changed()), this, SLOT(refill()));
+ d->clear();
+ if (d->attType) {
+ d->attType->release();
+ d->attType = 0;
+ }
d->regenerate();
emit pathChanged();
}
@@ -297,12 +327,25 @@ void QDeclarativePathView::setCurrentIndex(int idx)
if (d->model && d->model->count())
idx = qAbs(idx % d->model->count());
if (d->model && idx != d->currentIndex) {
+ if (d->model->count()) {
+ int itemIndex = (d->currentIndex - d->firstIndex + d->model->count()) % d->model->count();
+ if (itemIndex < d->items.count()) {
+ if (QDeclarativeItem *item = d->items.at(d->currentIndex)) {
+ if (QDeclarativePathViewAttached *att = d->attached(item))
+ att->setIsCurrentItem(false);
+ }
+ }
+ }
d->currentIndex = idx;
if (d->model->count()) {
d->snapToCurrent();
int itemIndex = (idx - d->firstIndex + d->model->count()) % d->model->count();
- if (itemIndex < d->items.count())
- d->items.at(itemIndex)->setFocus(true);
+ if (itemIndex < d->items.count()) {
+ QDeclarativeItem *item = d->items.at(itemIndex);
+ item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = d->attached(item))
+ att->setIsCurrentItem(true);
+ }
}
emit currentIndexChanged();
}
@@ -649,11 +692,7 @@ void QDeclarativePathViewPrivate::regenerate()
if (!q->isComponentComplete())
return;
- for (int i=0; i<items.count(); i++){
- QDeclarativeItem *p = items[i];
- releaseItem(p);
- }
- items.clear();
+ clear();
if (!isValid())
return;
@@ -673,18 +712,25 @@ void QDeclarativePathViewPrivate::regenerate()
}
items.append(item);
item->setZValue(i);
+ qreal percent = i * (100. / numItems) + _offset;
+ percent = qAbs(qmlMod(percent, qreal(100.0))/100.0);
+ updateItem(item, percent);
model->completeItem();
- if (currentIndex == index)
+ if (currentIndex == index) {
item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = attached(item))
+ att->setIsCurrentItem(true);
+ }
}
- q->refill();
+ if (pathItems != -1)
+ q->refill();
}
void QDeclarativePathViewPrivate::updateItem(QDeclarativeItem *item, qreal percent)
{
- if (QObject *obj = QDeclarativePathView::qmlAttachedProperties(item)) {
+ if (QDeclarativePathViewAttached *att = attached(item)) {
foreach(const QString &attr, path->attributes())
- static_cast<QDeclarativePathViewAttached *>(obj)->setValue(attr.toUtf8(), path->attributeAt(attr, percent));
+ att->setValue(attr.toUtf8(), path->attributeAt(attr, percent));
}
QPointF pf = path->pointAt(percent);
item->setX(pf.x() - item->width()*item->scale()/2);
@@ -735,8 +781,11 @@ void QDeclarativePathView::refill()
QDeclarativeItem *item = d->getItem(index);
item->setZValue(wrapIndex);
d->model->completeItem();
- if (d->currentIndex == index)
+ if (d->currentIndex == index) {
item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = d->attached(item))
+ att->setIsCurrentItem(true);
+ }
d->items << item;
d->pathOffset++;
d->pathOffset=d->pathOffset % d->items.count();
@@ -752,8 +801,11 @@ void QDeclarativePathView::refill()
QDeclarativeItem *item = d->getItem(d->firstIndex);
item->setZValue(d->firstIndex);
d->model->completeItem();
- if (d->currentIndex == d->firstIndex)
+ if (d->currentIndex == d->firstIndex) {
item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = d->attached(item))
+ att->setIsCurrentItem(true);
+ }
d->items.prepend(item);
d->pathOffset--;
if (d->pathOffset < 0)
@@ -909,10 +961,21 @@ void QDeclarativePathViewPrivate::updateCurrent()
return;
int idx = calcCurrentIndex();
if (model && idx != currentIndex) {
+ int itemIndex = (currentIndex - firstIndex + model->count()) % model->count();
+ if (itemIndex < items.count()) {
+ if (QDeclarativeItem *item = items.at(itemIndex)) {
+ if (QDeclarativePathViewAttached *att = attached(item))
+ att->setIsCurrentItem(false);
+ }
+ }
currentIndex = idx;
- int itemIndex = (idx - firstIndex + model->count()) % model->count();
- if (itemIndex < items.count())
- items.at(itemIndex)->setFocus(true);
+ itemIndex = (idx - firstIndex + model->count()) % model->count();
+ if (itemIndex < items.count()) {
+ QDeclarativeItem *item = items.at(itemIndex);
+ item->setFocus(true);
+ if (QDeclarativePathViewAttached *att = attached(item))
+ att->setIsCurrentItem(true);
+ }
emit q->currentIndexChanged();
}
}
@@ -993,17 +1056,10 @@ void QDeclarativePathViewPrivate::snapToCurrent()
}
}
-QHash<QObject*, QObject*> QDeclarativePathView::attachedProperties;
-QObject *QDeclarativePathView::qmlAttachedProperties(QObject *obj)
+QDeclarativePathViewAttached *QDeclarativePathView::qmlAttachedProperties(QObject *obj)
{
- QObject *rv = attachedProperties.value(obj);
- if (!rv) {
- rv = new QDeclarativePathViewAttached(obj);
- attachedProperties.insert(obj, rv);
- }
- return rv;
+ return new QDeclarativePathViewAttached(obj);
}
QT_END_NAMESPACE
-#include <qdeclarativepathview.moc>
diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p.h
index df9c6ae..6dbd044 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview_p.h
+++ b/src/declarative/graphicsitems/qdeclarativepathview_p.h
@@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QDeclarativePathViewPrivate;
+class QDeclarativePathViewAttached;
class Q_DECLARATIVE_EXPORT QDeclarativePathView : public QDeclarativeItem
{
Q_OBJECT
@@ -96,7 +97,7 @@ public:
int pathItemCount() const;
void setPathItemCount(int);
- static QObject *qmlAttachedProperties(QObject *);
+ static QDeclarativePathViewAttached *qmlAttachedProperties(QObject *);
Q_SIGNALS:
void currentIndexChanged();
@@ -127,11 +128,57 @@ private Q_SLOTS:
private:
friend class QDeclarativePathViewAttached;
- static QHash<QObject*, QObject*> attachedProperties;
Q_DISABLE_COPY(QDeclarativePathView)
Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativePathView)
};
+class QDeclarativeOpenMetaObject;
+class QDeclarativePathViewAttached : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QDeclarativePathView *view READ view CONSTANT)
+ Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged)
+ Q_PROPERTY(bool onPath READ isOnPath NOTIFY pathChanged)
+
+public:
+ QDeclarativePathViewAttached(QObject *parent);
+ ~QDeclarativePathViewAttached();
+
+ QDeclarativePathView *view() { return m_view; }
+
+ bool isCurrentItem() const { return m_isCurrent; }
+ void setIsCurrentItem(bool c) {
+ if (m_isCurrent != c) {
+ m_isCurrent = c;
+ emit currentItemChanged();
+ }
+ }
+
+ QVariant value(const QByteArray &name) const;
+ void setValue(const QByteArray &name, const QVariant &val);
+
+ bool isOnPath() const { return m_onPath; }
+ void setOnPath(bool on) {
+ if (on != m_onPath) {
+ m_onPath = on;
+ emit pathChanged();
+ }
+ }
+
+Q_SIGNALS:
+ void currentItemChanged();
+ void pathChanged();
+
+private:
+ friend class QDeclarativePathViewPrivate;
+ QDeclarativePathView *m_view;
+ QDeclarativeOpenMetaObject *m_metaobject;
+ bool m_onPath : 1;
+ bool m_isCurrent : 1;
+};
+
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QDeclarativePathView)
diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h
index 6344a8a..4083ab5 100644
--- a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h
@@ -71,6 +71,8 @@ typedef struct PathViewItem{
QDeclarativeItem* item;
}PathViewItem;
+class QDeclarativeOpenMetaObjectType;
+class QDeclarativePathViewAttached;
class QDeclarativePathViewPrivate : public QDeclarativeItemPrivate
{
Q_DECLARE_PUBLIC(QDeclarativePathView)
@@ -81,7 +83,7 @@ public:
, lastElapsed(0), stealMouse(false), ownModel(false), activeItem(0)
, snapPos(0), dragMargin(0), moveOffset(this, &QDeclarativePathViewPrivate::setOffset)
, firstIndex(0), pathItems(-1), pathOffset(0), requestedIndex(-1)
- , moveReason(Other)
+ , moveReason(Other), attType(0)
{
}
@@ -97,6 +99,8 @@ public:
QDeclarativeItem *getItem(int modelIndex);
void releaseItem(QDeclarativeItem *item);
+ QDeclarativePathViewAttached *attached(QDeclarativeItem *item);
+ void clear();
bool isValid() const {
return model && model->count() > 0 && model->isValid() && path;
@@ -137,6 +141,7 @@ public:
QVariant modelVariant;
enum MovementReason { Other, Key, Mouse };
MovementReason moveReason;
+ QDeclarativeOpenMetaObjectType *attType;
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativerectangle.cpp b/src/declarative/graphicsitems/qdeclarativerectangle.cpp
index 05fe0f7..207d05e 100644
--- a/src/declarative/graphicsitems/qdeclarativerectangle.cpp
+++ b/src/declarative/graphicsitems/qdeclarativerectangle.cpp
@@ -180,9 +180,6 @@ void QDeclarativeGradient::doUpdate()
QDeclarativeRectangle::QDeclarativeRectangle(QDeclarativeItem *parent)
: QDeclarativeItem(*(new QDeclarativeRectanglePrivate), parent)
{
- Q_D(QDeclarativeRectangle);
- d->init();
- setFlag(QGraphicsItem::ItemHasNoContents, false);
}
void QDeclarativeRectangle::doUpdate()
diff --git a/src/declarative/graphicsitems/qdeclarativerectangle_p_p.h b/src/declarative/graphicsitems/qdeclarativerectangle_p_p.h
index b87c57f..6bae219 100644
--- a/src/declarative/graphicsitems/qdeclarativerectangle_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativerectangle_p_p.h
@@ -67,6 +67,7 @@ public:
QDeclarativeRectanglePrivate() :
color(Qt::white), gradient(0), pen(0), radius(0), paintmargin(0)
{
+ QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents;
}
~QDeclarativeRectanglePrivate()
@@ -74,13 +75,13 @@ public:
delete pen;
}
- void init()
- {
- }
-
- QColor getColor();
QColor color;
QDeclarativeGradient *gradient;
+ QDeclarativePen *pen;
+ qreal radius;
+ qreal paintmargin;
+ QPixmap rectImage;
+
QDeclarativePen *getPen() {
if (!pen) {
Q_Q(QDeclarativeRectangle);
@@ -89,10 +90,6 @@ public:
}
return pen;
}
- QDeclarativePen *pen;
- qreal radius;
- qreal paintmargin;
- QPixmap rectImage;
void setPaintMargin(qreal margin)
{
diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp
index ca253df..05139f6 100644
--- a/src/declarative/graphicsitems/qdeclarativetext.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetext.cpp
@@ -110,8 +110,6 @@ QT_BEGIN_NAMESPACE
QDeclarativeText::QDeclarativeText(QDeclarativeItem *parent)
: QDeclarativeItem(*(new QDeclarativeTextPrivate), parent)
{
- setAcceptedMouseButtons(Qt::LeftButton);
- setFlag(QGraphicsItem::ItemHasNoContents, false);
}
QDeclarativeText::~QDeclarativeText()
diff --git a/src/declarative/graphicsitems/qdeclarativetext_p_p.h b/src/declarative/graphicsitems/qdeclarativetext_p_p.h
index a0c8abe..0d9a0a6 100644
--- a/src/declarative/graphicsitems/qdeclarativetext_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetext_p_p.h
@@ -70,14 +70,16 @@ class QDeclarativeTextPrivate : public QDeclarativeItemPrivate
Q_DECLARE_PUBLIC(QDeclarativeText)
public:
QDeclarativeTextPrivate()
- : color((QRgb)0), style(QDeclarativeText::Normal), imgDirty(true),
+ : color((QRgb)0), style(QDeclarativeText::Normal),
hAlign(QDeclarativeText::AlignLeft), vAlign(QDeclarativeText::AlignTop), elideMode(QDeclarativeText::ElideNone),
- dirty(true), wrap(false), richText(false), singleline(false), cache(true), doc(0),
+ imgDirty(true), dirty(true), wrap(false), richText(false), singleline(false), cache(true), doc(0),
format(QDeclarativeText::AutoText)
{
#if defined(QML_NO_TEXT_CACHE)
cache = false;
#endif
+ QGraphicsItemPrivate::acceptedMouseButtons = Qt::LeftButton;
+ QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents;
}
~QDeclarativeTextPrivate();
@@ -106,12 +108,12 @@ public:
QDeclarativeText::TextStyle style;
QColor styleColor;
QString activeLink;
- bool imgDirty;
QPixmap imgCache;
QPixmap imgStyleCache;
QDeclarativeText::HAlignment hAlign;
QDeclarativeText::VAlignment vAlign;
- QDeclarativeText::TextElideMode elideMode;
+ QDeclarativeText::TextElideMode elideMode;
+ bool imgDirty:1;
bool dirty:1;
bool wrap:1;
bool richText:1;
diff --git a/tests/auto/declarative/qdeclarativepathview/data/pathview.qml b/tests/auto/declarative/qdeclarativepathview/data/pathview.qml
index c5d88cd..ae0c86a 100644
--- a/tests/auto/declarative/qdeclarativepathview/data/pathview.qml
+++ b/tests/auto/declarative/qdeclarativepathview/data/pathview.qml
@@ -1,6 +1,9 @@
import Qt 4.6
Rectangle {
+ id: root
+ property int currentA: -1
+ property int currentB: -1
width: 240
height: 320
color: "#ffffff"
@@ -12,7 +15,7 @@ Rectangle {
objectName: "wrapper"
height: 20
width: 60
- color: "white"
+ color: PathView.isCurrentItem ? "lightsteelblue" : "white"
border.color: "black"
Text {
text: index
@@ -29,6 +32,12 @@ Rectangle {
objectName: "textNumber"
text: number
}
+ PathView.onCurrentItemChanged: {
+ if (PathView.isCurrentItem) {
+ root.currentA = index;
+ root.currentB = wrapper.PathView.view.currentIndex;
+ }
+ }
}
}
]
diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp
index fa4e9d3..62eb8c3 100644
--- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp
+++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp
@@ -71,6 +71,7 @@ private slots:
void pathview3();
void path();
void pathMoved();
+ void setCurrentIndex();
void resetModel();
void propertyChanges();
void pathChanges();
@@ -207,6 +208,7 @@ void tst_QDeclarativePathView::items()
model.addItem("Fred", "12345");
model.addItem("John", "2345");
model.addItem("Bob", "54321");
+ model.addItem("Bill", "4321");
QDeclarativeContext *ctxt = canvas->rootContext();
ctxt->setContextProperty("testModel", &model);
@@ -421,7 +423,6 @@ void tst_QDeclarativePathView::pathMoved()
offset.setY(firstItem->height()/2);
QCOMPARE(firstItem->pos() + offset, start);
pathview->setOffset(10);
- QTest::qWait(1000);//Moving is animated?
for(int i=0; i<model.count(); i++){
QDeclarativeRectangle *curItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", i);
@@ -429,12 +430,53 @@ void tst_QDeclarativePathView::pathMoved()
}
pathview->setOffset(100);
- QTest::qWait(1000);//Moving is animated?
QCOMPARE(firstItem->pos() + offset, start);
delete canvas;
}
+void tst_QDeclarativePathView::setCurrentIndex()
+{
+ QDeclarativeView *canvas = createView();
+
+ TestModel model;
+ model.addItem("Ben", "12345");
+ model.addItem("Bohn", "2345");
+ model.addItem("Bob", "54321");
+ model.addItem("Bill", "4321");
+
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pathview.qml"));
+ qApp->processEvents();
+
+ QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view");
+ QVERIFY(pathview != 0);
+
+ QDeclarativeRectangle *firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 0);
+ QVERIFY(firstItem);
+ QDeclarativePath *path = qobject_cast<QDeclarativePath*>(pathview->path());
+ QVERIFY(path);
+ QPointF start = path->pointAt(0.0);
+ QPointF offset;//Center of item is at point, but pos is from corner
+ offset.setX(firstItem->width()/2);
+ offset.setY(firstItem->height()/2);
+ QCOMPARE(firstItem->pos() + offset, start);
+ QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 0);
+ QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 0);
+
+ pathview->setCurrentIndex(2);
+ QTest::qWait(1000);
+
+ firstItem = findItem<QDeclarativeRectangle>(pathview, "wrapper", 2);
+ QCOMPARE(firstItem->pos() + offset, start);
+ QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 2);
+ QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 2);
+
+ delete canvas;
+}
+
void tst_QDeclarativePathView::resetModel()
{
QDeclarativeView *canvas = createView();
diff --git a/tests/benchmarks/declarative/creation/tst_creation.cpp b/tests/benchmarks/declarative/creation/tst_creation.cpp
index 4319208..5b0004f 100644
--- a/tests/benchmarks/declarative/creation/tst_creation.cpp
+++ b/tests/benchmarks/declarative/creation/tst_creation.cpp
@@ -163,6 +163,8 @@ void tst_creation::objects_qmltype()
{
QFETCH(QByteArray, type);
QDeclarativeType *t = QDeclarativeMetaType::qmlType(type, 4, 6);
+ if (!t || !t->isCreatable())
+ QSKIP("Non-creatable type", SkipSingle);
QBENCHMARK {
QObject *obj = t->create();