From 99aef9769379a74accce481f6290a30bf8024216 Mon Sep 17 00:00:00 2001 From: Sami Merila Date: Thu, 7 Jul 2011 13:08:05 +0300 Subject: Regression: Some QMenus are shown completely transparent in Symbian Fix for menu transparency (QTBUG-16857) unveiled an issue in the QS60Style when drawing QMenu background. Style skips drawing of the menu background, since placeHolder texture for QPalette::Window is not replaced with real background for menus. Therefore, we need to check if the widget's palette is still untouched when deciding whether or not to draw the menu background. Task-number: QTBUG-20255 Reviewed-by: Tomi Vihria --- src/gui/styles/qs60style.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 13157ff..bb2d701 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -506,8 +506,10 @@ bool QS60StylePrivate::equalToThemePalette(qint64 cacheKey, QPalette::ColorRole { if (!m_themePalette) return false; - if (cacheKey == m_themePalette->brush(role).texture().cacheKey()) + if ((m_placeHolderTexture && (cacheKey == m_placeHolderTexture->cacheKey())) + || (cacheKey == m_themePalette->brush(role).texture().cacheKey())) return true; + return false; } -- cgit v0.12 From 73df7890923f377f19147466d9317fe1ec064b1d Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 7 Jul 2011 14:17:58 +0100 Subject: Fix memory leak in QHostInfo QHostInfo was leaking in the code path where it removes duplicate name lookups after one has completed. Task-number: QT-5121 Reviewed-by: Markus Goetz --- src/network/kernel/qhostinfo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 328145c..94fd692 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -481,6 +481,7 @@ void QHostInfoRunnable::run() iterator.remove(); hostInfo.setLookupId(postponed->id); postponed->resultEmitter.emitResultsReady(hostInfo); + delete postponed; } } } -- cgit v0.12 From 55cfbdb7c64068ae68f7baaceb8acfb96cb0c07e Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 28 Jun 2011 15:35:58 +1000 Subject: Velocities reported by Flickable in onFlickStarted can be 0 Ensure the smoothed velocity is set at the start of the flick. Ensure that the smoothed velocity animation isn't restarted unless there is new valid data. Change-Id: I00f8bbf1fe91faeea752b093c4658ad0f53ad06d Task-number: QTBUG-19676 Reviewed-by: Bea Lam (cherry picked from commit a2d97672bfaace677a4308db93f5802ba53af46e) --- .../graphicsitems/qdeclarativeflickable.cpp | 30 +++++++--- .../tst_qdeclarativeflickable.cpp | 69 ++++++++++++++++++++++ 2 files changed, 90 insertions(+), 9 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 4a465cc..b8577e9 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -910,18 +910,24 @@ void QDeclarativeFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEv qreal velocity = vData.velocity; if (vData.atBeginning || vData.atEnd) velocity /= 2; - if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) + if (q->yflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) { + velocityTimeline.reset(vData.smoothVelocity); + vData.smoothVelocity.setValue(-velocity); flickY(velocity); - else + } else { fixupY(); + } velocity = hData.velocity; if (hData.atBeginning || hData.atEnd) velocity /= 2; - if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) + if (q->xflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) { + velocityTimeline.reset(hData.smoothVelocity); + hData.smoothVelocity.setValue(-velocity); flickX(velocity); - else + } else { fixupX(); + } if (!timeline.isActive()) q->movementEnding(); @@ -1121,19 +1127,25 @@ void QDeclarativeFlickable::viewportMoved() qreal prevX = d->lastFlickablePosition.x(); qreal prevY = d->lastFlickablePosition.y(); - d->velocityTimeline.clear(); if (d->pressed || d->calcVelocity) { int elapsed = QDeclarativeItemPrivate::restart(d->velocityTime); if (elapsed > 0) { qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed; + if (qAbs(horizontalVelocity) > 0) { + d->velocityTimeline.reset(d->hData.smoothVelocity); + d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing); + d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing); + } 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); + if (qAbs(verticalVelocity) > 0) { + d->velocityTimeline.reset(d->vData.smoothVelocity); + 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) { + d->velocityTimeline.clear(); 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); diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index b077fdc..31a6b10 100644 --- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -78,6 +78,7 @@ private slots: void testQtQuick11Attributes(); void testQtQuick11Attributes_data(); void wheel(); + void flickVelocity(); private: QDeclarativeEngine engine; @@ -480,6 +481,74 @@ void tst_qdeclarativeflickable::wheel() delete canvas; } +void tst_qdeclarativeflickable::flickVelocity() +{ + QDeclarativeView *canvas = new QDeclarativeView; + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/flickable03.qml")); + canvas->show(); + canvas->setFocus(); + QVERIFY(canvas->rootObject() != 0); + + QDeclarativeFlickable *flickable = qobject_cast(canvas->rootObject()); + QVERIFY(flickable != 0); + + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 90))); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,80)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,70)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,60)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,50)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 50))); + + QVERIFY(flickable->verticalVelocity() > 0.0); + QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 10))); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,20)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,30)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,40)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,50)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 50))); + + QVERIFY(flickable->verticalVelocity() < 0.0); + QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + + delete canvas; +} + template T *tst_qdeclarativeflickable::findItem(QGraphicsObject *parent, const QString &objectName) -- cgit v0.12 From 0d670396f7e4b24f0800ad0e7f219727a47bfba6 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 29 Jun 2011 16:23:28 +1000 Subject: Reduce timing dependancy in flickable test Interval of 10ms between synthesized flick move events is too prone to timing difference on CI platforms. Change-Id: Id5da794a7294868c8f5e544fa71edeec967e31ca Task-number: QTBUG-19676 Reviewed-by: Bea Lam (cherry picked from commit 6fb7cdf8741ca924413dd7cbc09fad91ddc04823) --- .../qdeclarativeflickable/data/flickable03.qml | 2 +- .../tst_qdeclarativeflickable.cpp | 69 +++++++--------------- 2 files changed, 22 insertions(+), 49 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeflickable/data/flickable03.qml b/tests/auto/declarative/qdeclarativeflickable/data/flickable03.qml index a3e92fe..8359ad1 100644 --- a/tests/auto/declarative/qdeclarativeflickable/data/flickable03.qml +++ b/tests/auto/declarative/qdeclarativeflickable/data/flickable03.qml @@ -1,7 +1,7 @@ import QtQuick 1.0 Flickable { - width: 100; height: 100 + width: 100; height: 200 contentWidth: column.width; contentHeight: column.height Column { diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index 31a6b10..05925cd 100644 --- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -83,6 +83,7 @@ private slots: private: QDeclarativeEngine engine; + void flick(QGraphicsView *canvas, const QPoint &from, const QPoint &to, int duration); template T *findItem(QGraphicsObject *parent, const QString &objectName); }; @@ -492,63 +493,35 @@ void tst_qdeclarativeflickable::flickVelocity() QDeclarativeFlickable *flickable = qobject_cast(canvas->rootObject()); QVERIFY(flickable != 0); - QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 90))); - { - QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,80)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas->viewport(), &mv); - } - QTest::qWait(10); - { - QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,70)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas->viewport(), &mv); - } - QTest::qWait(10); - { - QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,60)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas->viewport(), &mv); - } - QTest::qWait(10); - { - QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,50)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas->viewport(), &mv); - } - QTest::qWait(10); - - QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 50))); - + // flick up + flick(canvas, QPoint(20,190), QPoint(20, 50), 100); QVERIFY(flickable->verticalVelocity() > 0.0); QTRY_VERIFY(flickable->verticalVelocity() == 0.0); - QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 10))); - { - QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,20)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas->viewport(), &mv); - } - QTest::qWait(10); - { - QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,30)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas->viewport(), &mv); - } - QTest::qWait(10); - { - QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,40)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas->viewport(), &mv); - } - QTest::qWait(10); - { - QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,50)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas->viewport(), &mv); - } - QTest::qWait(10); - - QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 50))); - + // flick down + flick(canvas, QPoint(20,10), QPoint(20, 100), 100); QVERIFY(flickable->verticalVelocity() < 0.0); QTRY_VERIFY(flickable->verticalVelocity() == 0.0); delete canvas; } +void tst_qdeclarativeflickable::flick(QGraphicsView *canvas, const QPoint &from, const QPoint &to, int duration) +{ + const int pointCount = 5; + QPoint diff = to - from; + + // send press, five equally spaced moves, and release. + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(from)); + + for (int i = 0; i < pointCount; ++i) { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(from + (i+1)*diff/pointCount), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::qWait(duration/pointCount); + } + + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(to)); +} template T *tst_qdeclarativeflickable::findItem(QGraphicsObject *parent, const QString &objectName) -- cgit v0.12 From ca877686aa220d20905dce171efc4c8b035c0af5 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Wed, 29 Jun 2011 16:33:04 +1000 Subject: Flickable is too sensitive. Drag, stop, release should result in a pan, which does not trigger a flick. The current flick threshold velocity is too low, leading to flicks when a pan gesture is more desireable. Change-Id: I3aa3bf28cc0ccbb043f3390ff4e044ea587ba3ff Task-number: QTBUG-19933 Reviewed-by: Bea Lam (cherry picked from commit 20f8357c8ee570f57091e20b9c0a9a1455dc1e8d) --- src/declarative/graphicsitems/qdeclarativeflickable_p_p.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h index 46b2104..1c749cd 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h @@ -67,7 +67,11 @@ QT_BEGIN_NAMESPACE // Really slow flicks can be annoying. -const qreal MinimumFlickVelocity = 75.0; +#ifndef QML_FLICK_MINVELOCITY +#define QML_FLICK_MINVELOCITY 175 +#endif + +const qreal MinimumFlickVelocity = QML_FLICK_MINVELOCITY; class QDeclarativeFlickableVisibleArea; class QDeclarativeFlickablePrivate : public QDeclarativeItemPrivate, public QDeclarativeItemChangeListener -- cgit v0.12 From 247c0d8c3030267720766a48ed9ee681edc62085 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 30 Jun 2011 12:05:14 +1000 Subject: Try to fix Mac CI test failure Try slowing down the flick to give the slow CI machine a better chance of success. Change-Id: Id61473e73a38bb888b9bee47cffb913c936155b9 Task-number: QTBUG-19676 Reviewed-by: Bea Lam (cherry picked from commit 343069c7843321b33f06bfd42d476abae76dcece) --- .../declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index 05925cd..7cb7e6f 100644 --- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -494,12 +494,12 @@ void tst_qdeclarativeflickable::flickVelocity() QVERIFY(flickable != 0); // flick up - flick(canvas, QPoint(20,190), QPoint(20, 50), 100); + flick(canvas, QPoint(20,190), QPoint(20, 50), 200); QVERIFY(flickable->verticalVelocity() > 0.0); QTRY_VERIFY(flickable->verticalVelocity() == 0.0); // flick down - flick(canvas, QPoint(20,10), QPoint(20, 100), 100); + flick(canvas, QPoint(20,10), QPoint(20, 140), 200); QVERIFY(flickable->verticalVelocity() < 0.0); QTRY_VERIFY(flickable->verticalVelocity() == 0.0); -- cgit v0.12 From d8af562509f8624837f6fa4a617bc6e976b0731d Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 30 Jun 2011 17:09:34 +1000 Subject: Try again to fix flickable velocity on Mac. Change-Id: Id2693a69739886f9a171f3f6438a5404dff8e901 Task-number: QTBUG-19676 Reviewed-by: Bea Lam (cherry picked from commit 927b22b06ee2e749395e73f457fe3c16ea087864) --- .../auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index 7cb7e6f..d3763a7 100644 --- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -518,6 +518,7 @@ void tst_qdeclarativeflickable::flick(QGraphicsView *canvas, const QPoint &from, QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(from + (i+1)*diff/pointCount), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); QApplication::sendEvent(canvas->viewport(), &mv); QTest::qWait(duration/pointCount); + QCoreApplication::processEvents(); } QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(to)); -- cgit v0.12 From b05a2394e13a12fcb2f7e3b766e0b37bb1163eb7 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 4 Jul 2011 09:52:15 +1000 Subject: Skip flick velocity test on Mac. Change-Id: Ib995961d7b1a939e5feb86d72a82408d1ceebe88 Task-number: QTBUG-19676 Reviewed-by: Bea Lam (cherry picked from commit 8fbb802fa50d0a01c9c01d007a3e016c45fa863c) --- .../declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index d3763a7..4d4c30b 100644 --- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -484,6 +484,10 @@ void tst_qdeclarativeflickable::wheel() void tst_qdeclarativeflickable::flickVelocity() { +#ifdef Q_WS_MAC + QSKIP("Producing flicks on Mac CI impossible due to timing problems", SkipAll); +#endif + QDeclarativeView *canvas = new QDeclarativeView; canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/flickable03.qml")); canvas->show(); -- cgit v0.12 From cf23188de237009136fa1480ab8fd9e3ca364769 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 4 Jul 2011 10:08:15 +1000 Subject: Flicking behaviour of ListView/GridView SnapOnItem is inconsistent Improve the response of the views when SnapOneItem/Row is enabled. In this case it is best to be much more reactive to the user input since even a small movement in a particular direction indicates a change to the next/previous item. Change-Id: I6a8eb689c3b12cdc67f24106032e36bba82d2846 Task-number: QTBUG-19874 Reviewed-by: Bea Lam (cherry picked from commit e7bebcf0c59368340df524db4a53ae2595d057d7) --- .../graphicsitems/qdeclarativeflickable.cpp | 106 ++++++++-------- .../graphicsitems/qdeclarativeflickable_p_p.h | 9 +- .../graphicsitems/qdeclarativegridview.cpp | 97 ++++++++++----- .../graphicsitems/qdeclarativelistview.cpp | 133 ++++++++++++--------- .../tst_qdeclarativegridview.cpp | 8 +- 5 files changed, 200 insertions(+), 153 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index b8577e9..0a98c01 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -168,9 +168,7 @@ QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate() : contentItem(new QDeclarativeItem) , hData(this, &QDeclarativeFlickablePrivate::setRoundedViewportX) , vData(this, &QDeclarativeFlickablePrivate::setRoundedViewportY) - , flickingHorizontally(false), flickingVertically(false) , hMoved(false), vMoved(false) - , movingHorizontally(false), movingVertically(false) , stealMouse(false), pressed(false), interactive(true), calcVelocity(false) , deceleration(QML_FLICK_DEFAULTDECELERATION) , maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100) @@ -294,18 +292,18 @@ void QDeclarativeFlickablePrivate::flick(AxisData &data, qreal minExtent, qreal else timeline.accel(data.move, v, deceleration, maxDistance); timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); - if (!flickingHorizontally && q->xflick()) { - flickingHorizontally = true; + if (!hData.flicking && q->xflick()) { + hData.flicking = true; emit q->flickingChanged(); emit q->flickingHorizontallyChanged(); - if (!flickingVertically) + if (!vData.flicking) emit q->flickStarted(); } - if (!flickingVertically && q->yflick()) { - flickingVertically = true; + if (!vData.flicking && q->yflick()) { + vData.flicking = true; emit q->flickingChanged(); emit q->flickingVerticallyChanged(); - if (!flickingHorizontally) + if (!hData.flicking) emit q->flickStarted(); } } else { @@ -614,11 +612,11 @@ void QDeclarativeFlickable::setInteractive(bool interactive) Q_D(QDeclarativeFlickable); if (interactive != d->interactive) { d->interactive = interactive; - if (!interactive && (d->flickingHorizontally || d->flickingVertically)) { + if (!interactive && (d->hData.flicking || d->vData.flicking)) { d->timeline.clear(); d->vTime = d->timeline.time(); - d->flickingHorizontally = false; - d->flickingVertically = false; + d->hData.flicking = false; + d->vData.flicking = false; emit flickingChanged(); emit flickingHorizontallyChanged(); emit flickingVerticallyChanged(); @@ -771,8 +769,8 @@ void QDeclarativeFlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEven pressPos = event->pos(); hData.pressPos = hData.move.value(); vData.pressPos = vData.move.value(); - flickingHorizontally = false; - flickingVertically = false; + hData.flicking = false; + vData.flicking = false; QDeclarativeItemPrivate::start(pressTime); QDeclarativeItemPrivate::start(velocityTime); } @@ -897,17 +895,13 @@ void QDeclarativeFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEv return; // if we drag then pause before release we should not cause a flick. - if (QDeclarativeItemPrivate::elapsed(lastPosTime) < 100) { - vData.updateVelocity(); - hData.updateVelocity(); - } else { - hData.velocity = 0.0; - vData.velocity = 0.0; - } + qint64 elapsed = QDeclarativeItemPrivate::elapsed(lastPosTime); + vData.updateVelocity(); + hData.updateVelocity(); vTime = timeline.time(); - qreal velocity = vData.velocity; + qreal velocity = elapsed < 100 ? vData.velocity : 0; if (vData.atBeginning || vData.atEnd) velocity /= 2; if (q->yflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) { @@ -918,7 +912,7 @@ void QDeclarativeFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEv fixupY(); } - velocity = hData.velocity; + velocity = elapsed < 100 ? hData.velocity : 0; if (hData.atBeginning || hData.atEnd) velocity /= 2; if (q->xflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) { @@ -984,9 +978,9 @@ void QDeclarativeFlickable::wheelEvent(QGraphicsSceneWheelEvent *event) valid = true; } if (valid) { - d->flickingVertically = false; + d->vData.flicking = false; d->flickY(d->vData.velocity); - if (d->flickingVertically) { + if (d->vData.flicking) { d->vMoved = true; movementStarting(); } @@ -1002,9 +996,9 @@ void QDeclarativeFlickable::wheelEvent(QGraphicsSceneWheelEvent *event) valid = true; } if (valid) { - d->flickingHorizontally = false; + d->hData.flicking = false; d->flickX(d->hData.velocity); - if (d->flickingHorizontally) { + if (d->hData.flicking) { d->hMoved = true; movementStarting(); } @@ -1153,7 +1147,7 @@ void QDeclarativeFlickable::viewportMoved() } } - if (!d->vData.inOvershoot && !d->vData.fixingUp && d->flickingVertically + if (!d->vData.inOvershoot && !d->vData.fixingUp && d->vData.flicking && (d->vData.move.value() > minYExtent() || d->vData.move.value() < maxYExtent()) && qAbs(d->vData.smoothVelocity.value()) > 100) { // Increase deceleration if we've passed a bound @@ -1163,7 +1157,7 @@ void QDeclarativeFlickable::viewportMoved() d->timeline.accel(d->vData.move, -d->vData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance); d->timeline.callback(QDeclarativeTimeLineCallback(&d->vData.move, d->fixupY_callback, d)); } - if (!d->hData.inOvershoot && !d->hData.fixingUp && d->flickingHorizontally + if (!d->hData.inOvershoot && !d->hData.fixingUp && d->hData.flicking && (d->hData.move.value() > minXExtent() || d->hData.move.value() < maxXExtent()) && qAbs(d->hData.smoothVelocity.value()) > 100) { // Increase deceleration if we've passed a bound @@ -1195,7 +1189,7 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry, emit contentWidthChanged(); } // Make sure that we're entirely in view. - if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { + if (!d->pressed && !d->hData.moving && !d->vData.moving) { d->fixupMode = QDeclarativeFlickablePrivate::Immediate; d->fixupX(); } @@ -1208,7 +1202,7 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry, emit contentHeightChanged(); } // Make sure that we're entirely in view. - if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { + if (!d->pressed && !d->hData.moving && !d->vData.moving) { d->fixupMode = QDeclarativeFlickablePrivate::Immediate; d->fixupY(); } @@ -1384,7 +1378,7 @@ void QDeclarativeFlickable::setContentWidth(qreal w) else d->contentItem->setWidth(w); // Make sure that we're entirely in view. - if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { + if (!d->pressed && !d->hData.moving && !d->vData.moving) { d->fixupMode = QDeclarativeFlickablePrivate::Immediate; d->fixupX(); } else if (!d->pressed && d->hData.fixingUp) { @@ -1412,7 +1406,7 @@ void QDeclarativeFlickable::setContentHeight(qreal h) else d->contentItem->setHeight(h); // Make sure that we're entirely in view. - if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { + if (!d->pressed && !d->hData.moving && !d->vData.moving) { d->fixupMode = QDeclarativeFlickablePrivate::Immediate; d->fixupY(); } else if (!d->pressed && d->vData.fixingUp) { @@ -1668,7 +1662,7 @@ void QDeclarativeFlickable::setFlickDeceleration(qreal deceleration) bool QDeclarativeFlickable::isFlicking() const { Q_D(const QDeclarativeFlickable); - return d->flickingHorizontally || d->flickingVertically; + return d->hData.flicking || d->vData.flicking; } /*! @@ -1682,13 +1676,13 @@ bool QDeclarativeFlickable::isFlicking() const bool QDeclarativeFlickable::isFlickingHorizontally() const { Q_D(const QDeclarativeFlickable); - return d->flickingHorizontally; + return d->hData.flicking; } bool QDeclarativeFlickable::isFlickingVertically() const { Q_D(const QDeclarativeFlickable); - return d->flickingVertically; + return d->vData.flicking; } /*! @@ -1724,7 +1718,7 @@ void QDeclarativeFlickable::setPressDelay(int delay) bool QDeclarativeFlickable::isMoving() const { Q_D(const QDeclarativeFlickable); - return d->movingHorizontally || d->movingVertically; + return d->hData.moving || d->vData.moving; } /*! @@ -1739,30 +1733,30 @@ bool QDeclarativeFlickable::isMoving() const bool QDeclarativeFlickable::isMovingHorizontally() const { Q_D(const QDeclarativeFlickable); - return d->movingHorizontally; + return d->hData.moving; } bool QDeclarativeFlickable::isMovingVertically() const { Q_D(const QDeclarativeFlickable); - return d->movingVertically; + return d->vData.moving; } void QDeclarativeFlickable::movementStarting() { Q_D(QDeclarativeFlickable); - if (d->hMoved && !d->movingHorizontally) { - d->movingHorizontally = true; + if (d->hMoved && !d->hData.moving) { + d->hData.moving = true; emit movingChanged(); emit movingHorizontallyChanged(); - if (!d->movingVertically) + if (!d->vData.moving) emit movementStarted(); } - else if (d->vMoved && !d->movingVertically) { - d->movingVertically = true; + else if (d->vMoved && !d->vData.moving) { + d->vData.moving = true; emit movingChanged(); emit movingVerticallyChanged(); - if (!d->movingHorizontally) + if (!d->hData.moving) emit movementStarted(); } } @@ -1779,20 +1773,20 @@ void QDeclarativeFlickable::movementEnding() void QDeclarativeFlickable::movementXEnding() { Q_D(QDeclarativeFlickable); - if (d->flickingHorizontally) { - d->flickingHorizontally = false; + if (d->hData.flicking) { + d->hData.flicking = false; emit flickingChanged(); emit flickingHorizontallyChanged(); - if (!d->flickingVertically) + if (!d->vData.flicking) emit flickEnded(); } if (!d->pressed && !d->stealMouse) { - if (d->movingHorizontally) { - d->movingHorizontally = false; + if (d->hData.moving) { + d->hData.moving = false; d->hMoved = false; emit movingChanged(); emit movingHorizontallyChanged(); - if (!d->movingVertically) + if (!d->vData.moving) emit movementEnded(); } } @@ -1802,20 +1796,20 @@ void QDeclarativeFlickable::movementXEnding() void QDeclarativeFlickable::movementYEnding() { Q_D(QDeclarativeFlickable); - if (d->flickingVertically) { - d->flickingVertically = false; + if (d->vData.flicking) { + d->vData.flicking = false; emit flickingChanged(); emit flickingVerticallyChanged(); - if (!d->flickingHorizontally) + if (!d->hData.flicking) emit flickEnded(); } if (!d->pressed && !d->stealMouse) { - if (d->movingVertically) { - d->movingVertically = false; + if (d->vData.moving) { + d->vData.moving = false; d->vMoved = false; emit movingChanged(); emit movingVerticallyChanged(); - if (!d->movingHorizontally) + if (!d->hData.moving) emit movementEnded(); } } diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h index 1c749cd..d73a907 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h @@ -63,6 +63,7 @@ #include #include +#include "qplatformdefs.h" QT_BEGIN_NAMESPACE @@ -98,7 +99,7 @@ public: struct AxisData { AxisData(QDeclarativeFlickablePrivate *fp, void (QDeclarativeFlickablePrivate::*func)(qreal)) : move(fp, func), viewSize(-1), smoothVelocity(fp), atEnd(false), atBeginning(true) - , fixingUp(false), inOvershoot(false) + , fixingUp(false), inOvershoot(false), moving(false), flicking(false) {} void reset() { @@ -125,6 +126,8 @@ public: bool atBeginning : 1; bool fixingUp : 1; bool inOvershoot : 1; + bool moving : 1; + bool flicking : 1; }; void flickX(qreal velocity); @@ -156,12 +159,8 @@ public: AxisData vData; QDeclarativeTimeLine timeline; - bool flickingHorizontally : 1; - bool flickingVertically : 1; bool hMoved : 1; bool vMoved : 1; - bool movingHorizontally : 1; - bool movingVertically : 1; bool stealMouse : 1; bool pressed : 1; bool interactive : 1; diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index afc3eac..59e4cbb 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -52,9 +52,13 @@ #include #include +#include "qplatformdefs.h" QT_BEGIN_NAMESPACE +#ifndef QML_FLICK_SNAPONETHRESHOLD +#define QML_FLICK_SNAPONETHRESHOLD 30 +#endif //---------------------------------------------------------------------------- @@ -344,9 +348,12 @@ public: Q_Q(const QDeclarativeGridView); qreal snapPos = 0; if (!visibleItems.isEmpty()) { + qreal highlightStart = isRightToLeftTopToBottom() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart; + pos += highlightStart; pos += rowSize()/2; snapPos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize(); snapPos = pos - fmodf(pos - snapPos, qreal(rowSize())); + snapPos -= highlightStart; qreal maxExtent; qreal minExtent; if (isRightToLeftTopToBottom()) { @@ -872,7 +879,7 @@ void QDeclarativeGridViewPrivate::updateHighlight() { if ((!currentItem && highlight) || (currentItem && !highlight)) createHighlight(); - if (currentItem && autoHighlight && highlight && !movingHorizontally && !movingVertically) { + if (currentItem && autoHighlight && highlight && !hData.moving && !vData.moving) { // auto-update highlight highlightXAnimator->to = currentItem->item->x(); highlightYAnimator->to = currentItem->item->y(); @@ -1059,6 +1066,18 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m if (snapMode != QDeclarativeGridView::NoSnap) { qreal tempPosition = isRightToLeftTopToBottom() ? -position()-size() : position(); + if (snapMode == QDeclarativeGridView::SnapOneRow && moveReason == Mouse) { + // if we've been dragged < rowSize()/2 then bias towards the next row + qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); + qreal bias = 0; + if (data.velocity > 0 && dist > QML_FLICK_SNAPONETHRESHOLD && dist < rowSize()/2) + bias = rowSize()/2; + else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -rowSize()/2) + bias = -rowSize()/2; + if (isRightToLeftTopToBottom()) + bias = -bias; + tempPosition -= bias; + } FxGridItem *topItem = snapItemAt(tempPosition+highlightStart); FxGridItem *bottomItem = snapItemAt(tempPosition+highlightEnd); qreal pos; @@ -1080,25 +1099,13 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m } } else if (bottomItem) { if (isRightToLeftTopToBottom()) - pos = qMax(qMin(-bottomItem->rowPos() + highlightStart - size(), -maxExtent), -minExtent); + pos = qMax(qMin(-bottomItem->rowPos() + highlightEnd - size(), -maxExtent), -minExtent); else - pos = qMax(qMin(bottomItem->rowPos() - highlightStart, -maxExtent), -minExtent); + pos = qMax(qMin(bottomItem->rowPos() - highlightEnd, -maxExtent), -minExtent); } else { QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); return; } - if (currentItem && haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { - updateHighlight(); - qreal currPos = currentItem->rowPos(); - if (isRightToLeftTopToBottom()) - pos = -pos-size(); // Transform Pos if required - if (pos < currPos + rowSize() - highlightEnd) - pos = currPos + rowSize() - highlightEnd; - if (pos > currPos - highlightStart) - pos = currPos - highlightStart; - if (isRightToLeftTopToBottom()) - pos = -pos-size(); // Untransform - } qreal dist = qAbs(data.move + pos); if (dist > 0) { timeline.reset(data.move); @@ -1155,9 +1162,14 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m if (velocity > 0) { if (data.move.value() < minExtent) { if (snapMode == QDeclarativeGridView::SnapOneRow) { - if (FxGridItem *item = firstVisibleItem()) { - maxDistance = qAbs(item->rowPos() + dataValue); - } + // if we've been dragged < averageSize/2 then bias towards the next item + qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); + qreal bias = dist < rowSize()/2 ? rowSize()/2 : 0; + if (isRightToLeftTopToBottom()) + bias = -bias; + data.flickTarget = -snapPosAt(-dataValue - bias); + maxDistance = qAbs(data.flickTarget - data.move.value()); + velocity = maxVelocity; } else { maxDistance = qAbs(minExtent - data.move.value()); } @@ -1167,8 +1179,14 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m } else { if (data.move.value() > maxExtent) { if (snapMode == QDeclarativeGridView::SnapOneRow) { - qreal pos = snapPosAt(-dataValue) + (isRightToLeftTopToBottom() ? 0 : rowSize()); - maxDistance = qAbs(pos + dataValue); + // if we've been dragged < averageSize/2 then bias towards the next item + qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); + qreal bias = -dist < rowSize()/2 ? rowSize()/2 : 0; + if (isRightToLeftTopToBottom()) + bias = -bias; + data.flickTarget = -snapPosAt(-dataValue + bias); + maxDistance = qAbs(data.flickTarget - data.move.value()); + velocity = -maxVelocity; } else { maxDistance = qAbs(maxExtent - data.move.value()); } @@ -1178,7 +1196,6 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m } bool overShoot = boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds; - qreal highlightStart = isRightToLeftTopToBottom() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart; if (maxDistance > 0 || overShoot) { // This mode requires the grid to stop exactly on a row boundary. @@ -1198,9 +1215,20 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m dist = qMin(dist, maxDistance); if (v > 0) dist = -dist; - qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist; - data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart; + if (snapMode != QDeclarativeGridView::SnapOneRow) { + qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist; + data.flickTarget = -snapPosAt(-dataValue + distTemp); + } data.flickTarget = isRightToLeftTopToBottom() ? -data.flickTarget+size() : data.flickTarget; + if (overShoot) { + if (data.flickTarget >= minExtent) { + overshootDist = overShootDistance(vSize); + data.flickTarget += overshootDist; + } else if (data.flickTarget <= maxExtent) { + overshootDist = overShootDistance(vSize); + data.flickTarget -= overshootDist; + } + } qreal adjDist = -data.flickTarget + data.move.value(); if (qAbs(adjDist) > qAbs(dist)) { // Prevent painfully slow flicking - adjust velocity to suit flickDeceleration @@ -1221,14 +1249,14 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m timeline.reset(data.move); timeline.accel(data.move, v, accel, maxDistance + overshootDist); timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); - if (!flickingHorizontally && q->xflick()) { - flickingHorizontally = true; + if (!hData.flicking && q->xflick()) { + hData.flicking = true; emit q->flickingChanged(); emit q->flickingHorizontallyChanged(); emit q->flickStarted(); } - if (!flickingVertically && q->yflick()) { - flickingVertically = true; + if (!vData.flicking && q->yflick()) { + vData.flicking = true; emit q->flickingChanged(); emit q->flickingVerticallyChanged(); emit q->flickStarted(); @@ -1552,6 +1580,8 @@ void QDeclarativeGridView::setCurrentIndex(int index) if (index == d->currentIndex) return; if (isComponentComplete() && d->isValid()) { + if (d->layoutScheduled) + d->layout(); d->moveReason = QDeclarativeGridViewPrivate::SetIndex; d->updateCurrent(index); } else { @@ -2096,7 +2126,8 @@ bool QDeclarativeGridView::event(QEvent *event) { Q_D(QDeclarativeGridView); if (event->type() == QEvent::User) { - d->layout(); + if (d->layoutScheduled) + d->layout(); return true; } @@ -2110,7 +2141,7 @@ void QDeclarativeGridView::viewportMoved() if (!d->itemCount) return; d->lazyRelease = true; - if (d->flickingHorizontally || d->flickingVertically) { + if (d->hData.flicking || d->vData.flicking) { if (yflick()) { if (d->vData.velocity > 0) d->bufferMode = QDeclarativeGridViewPrivate::BufferBefore; @@ -2126,7 +2157,7 @@ void QDeclarativeGridView::viewportMoved() } } refill(); - if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically) + if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving) d->moveReason = QDeclarativeGridViewPrivate::Mouse; if (d->moveReason != QDeclarativeGridViewPrivate::SetIndex) { if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { @@ -2871,7 +2902,6 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) d->itemCount -= count; bool currentRemoved = d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count; bool removedVisible = false; - // Remove the items from the visible list, skipping anything already marked for removal QList::Iterator it = d->visibleItems.begin(); while (it != d->visibleItems.end()) { @@ -2905,6 +2935,11 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count) } } + // If we removed items before visible items a layout may be + // required to ensure item 0 is in the first column. + if (!removedVisible && modelIndex < d->visibleIndex) + d->scheduleLayout(); + // fix current if (d->currentIndex >= modelIndex + count) { d->currentIndex -= count; diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 8695bc6..57b7dea 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -53,9 +53,14 @@ #include #include #include +#include "qplatformdefs.h" QT_BEGIN_NAMESPACE +#ifndef QML_FLICK_SNAPONETHRESHOLD +#define QML_FLICK_SNAPONETHRESHOLD 30 +#endif + void QDeclarativeViewSection::setProperty(const QString &property) { if (property != m_property) { @@ -234,21 +239,6 @@ public: return visibleItems.count() ? visibleItems.first() : 0; } - FxListItem *nextVisibleItem() const { - const qreal pos = isRightToLeft() ? -position()-size() : position(); - bool foundFirst = false; - for (int i = 0; i < visibleItems.count(); ++i) { - FxListItem *item = visibleItems.at(i); - if (item->index != -1) { - if (foundFirst) - return item; - else if (item->position() < pos && item->endPosition() > pos) - foundFirst = true; - } - } - return 0; - } - // Returns the item before modelIndex, if created. // May return an item marked for removal. FxListItem *itemBefore(int modelIndex) const { @@ -1007,7 +997,7 @@ void QDeclarativeListViewPrivate::updateHighlight() { if ((!currentItem && highlight) || (currentItem && !highlight)) createHighlight(); - if (currentItem && autoHighlight && highlight && !movingHorizontally && !movingVertically) { + if (currentItem && autoHighlight && highlight && !hData.moving && !vData.moving) { // auto-update highlight highlightPosAnimator->to = isRightToLeft() ? -currentItem->itemPosition()-currentItem->itemSize() @@ -1318,29 +1308,20 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m highlightEnd = highlightRangeEnd; } - if (currentItem && haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange - && moveReason != QDeclarativeListViewPrivate::SetIndex) { - updateHighlight(); - qreal pos = currentItem->itemPosition(); - if (viewPos < pos + currentItem->itemSize() - highlightEnd) - viewPos = pos + currentItem->itemSize() - highlightEnd; - if (viewPos > pos - highlightStart) - viewPos = pos - highlightStart; - if (isRightToLeft()) - viewPos = -viewPos-size(); - - timeline.reset(data.move); - if (viewPos != position()) { - if (fixupMode != Immediate) { - timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - data.fixingUp = true; - } else { - timeline.set(data.move, -viewPos); - } - } - vTime = timeline.time(); - } else if (snapMode != QDeclarativeListView::NoSnap && moveReason != QDeclarativeListViewPrivate::SetIndex) { + if (snapMode != QDeclarativeListView::NoSnap && moveReason != QDeclarativeListViewPrivate::SetIndex) { qreal tempPosition = isRightToLeft() ? -position()-size() : position(); + if (snapMode == QDeclarativeListView::SnapOneItem && moveReason == Mouse) { + // if we've been dragged < averageSize/2 then bias towards the next item + qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); + qreal bias = 0; + if (data.velocity > 0 && dist > QML_FLICK_SNAPONETHRESHOLD && dist < averageSize/2) + bias = averageSize/2; + else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -averageSize/2) + bias = -averageSize/2; + if (isRightToLeft()) + bias = -bias; + tempPosition -= bias; + } FxListItem *topItem = snapItemAt(tempPosition+highlightStart); FxListItem *bottomItem = snapItemAt(tempPosition+highlightEnd); qreal pos; @@ -1356,9 +1337,9 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m } } else if (bottomItem && isInBounds) { if (isRightToLeft()) - pos = qMax(qMin(-bottomItem->position() + highlightStart - size(), -maxExtent), -minExtent); + pos = qMax(qMin(-bottomItem->position() + highlightEnd - size(), -maxExtent), -minExtent); else - pos = qMax(qMin(bottomItem->position() - highlightStart, -maxExtent), -minExtent); + pos = qMax(qMin(bottomItem->position() - highlightEnd, -maxExtent), -minExtent); } else { QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); return; @@ -1375,6 +1356,27 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m } vTime = timeline.time(); } + } else if (currentItem && haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange + && moveReason != QDeclarativeListViewPrivate::SetIndex) { + updateHighlight(); + qreal pos = currentItem->itemPosition(); + if (viewPos < pos + currentItem->itemSize() - highlightEnd) + viewPos = pos + currentItem->itemSize() - highlightEnd; + if (viewPos > pos - highlightStart) + viewPos = pos - highlightStart; + if (isRightToLeft()) + viewPos = -viewPos-size(); + + timeline.reset(data.move); + if (viewPos != position()) { + if (fixupMode != Immediate) { + timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); + data.fixingUp = true; + } else { + timeline.set(data.move, -viewPos); + } + } + vTime = timeline.time(); } else { QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); } @@ -1396,12 +1398,19 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m } qreal maxDistance = 0; qreal dataValue = isRightToLeft() ? -data.move.value()+size() : data.move.value(); + qreal highlightStart = isRightToLeft() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart; // -ve velocity means list is moving up/left if (velocity > 0) { if (data.move.value() < minExtent) { - if (snapMode == QDeclarativeListView::SnapOneItem) { - if (FxListItem *item = isRightToLeft() ? nextVisibleItem() : firstVisibleItem()) - maxDistance = qAbs(item->position() + dataValue); + if (snapMode == QDeclarativeListView::SnapOneItem && !hData.flicking && !vData.flicking) { + // if we've been dragged < averageSize/2 then bias towards the next item + qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); + qreal bias = dist < averageSize/2 ? averageSize/2 : 0; + if (isRightToLeft()) + bias = -bias; + data.flickTarget = -snapPosAt(-(dataValue - highlightStart) - bias) + highlightStart; + maxDistance = qAbs(data.flickTarget - data.move.value()); + velocity = maxVelocity; } else { maxDistance = qAbs(minExtent - data.move.value()); } @@ -1410,9 +1419,15 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m data.flickTarget = minExtent; } else { if (data.move.value() > maxExtent) { - if (snapMode == QDeclarativeListView::SnapOneItem) { - if (FxListItem *item = isRightToLeft() ? firstVisibleItem() : nextVisibleItem()) - maxDistance = qAbs(item->position() + dataValue); + if (snapMode == QDeclarativeListView::SnapOneItem && !hData.flicking && !vData.flicking) { + // if we've been dragged < averageSize/2 then bias towards the next item + qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset); + qreal bias = -dist < averageSize/2 ? averageSize/2 : 0; + if (isRightToLeft()) + bias = -bias; + data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + bias) + highlightStart; + maxDistance = qAbs(data.flickTarget - data.move.value()); + velocity = -maxVelocity; } else { maxDistance = qAbs(maxExtent - data.move.value()); } @@ -1422,7 +1437,6 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m } bool overShoot = boundsBehavior == QDeclarativeFlickable::DragAndOvershootBounds; - qreal highlightStart = isRightToLeft() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart; if (maxDistance > 0 || overShoot) { // These modes require the list to stop exactly on an item boundary. @@ -1436,7 +1450,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m else v = maxVelocity; } - if (!flickingHorizontally && !flickingVertically) { + if (!hData.flicking && !vData.flicking) { // the initial flick - estimate boundary qreal accel = deceleration; qreal v2 = v * v; @@ -1448,8 +1462,10 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m if (v > 0) dist = -dist; if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeListView::SnapOneItem) { - qreal distTemp = isRightToLeft() ? -dist : dist; - data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart; + if (snapMode != QDeclarativeListView::SnapOneItem) { + qreal distTemp = isRightToLeft() ? -dist : dist; + data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart; + } data.flickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget; if (overShoot) { if (data.flickTarget >= minExtent) { @@ -1487,14 +1503,14 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m timeline.reset(data.move); timeline.accel(data.move, v, accel, maxDistance + overshootDist); timeline.callback(QDeclarativeTimeLineCallback(&data.move, fixupCallback, this)); - if (!flickingHorizontally && q->xflick()) { - flickingHorizontally = true; + if (!hData.flicking && q->xflick()) { + hData.flicking = true; emit q->flickingChanged(); emit q->flickingHorizontallyChanged(); emit q->flickStarted(); } - if (!flickingVertically && q->yflick()) { - flickingVertically = true; + if (!vData.flicking && q->yflick()) { + vData.flicking = true; emit q->flickingChanged(); emit q->flickingVerticallyChanged(); emit q->flickStarted(); @@ -1870,6 +1886,8 @@ void QDeclarativeListView::setCurrentIndex(int index) if (index == d->currentIndex) return; if (isComponentComplete() && d->isValid()) { + if (d->layoutScheduled) + d->layout(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; d->updateCurrent(index); } else if (d->currentIndex != index) { @@ -2555,7 +2573,8 @@ bool QDeclarativeListView::event(QEvent *event) { Q_D(QDeclarativeListView); if (event->type() == QEvent::User) { - d->layout(); + if (d->layoutScheduled) + d->layout(); return true; } @@ -2574,7 +2593,7 @@ void QDeclarativeListView::viewportMoved() d->inViewportMoved = true; d->lazyRelease = true; refill(); - if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically) + if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving) d->moveReason = QDeclarativeListViewPrivate::Mouse; if (d->moveReason != QDeclarativeListViewPrivate::SetIndex) { if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) { @@ -2608,7 +2627,7 @@ void QDeclarativeListView::viewportMoved() } } - if ((d->flickingHorizontally || d->flickingVertically) && d->correctFlick && !d->inFlickCorrection) { + if ((d->hData.flicking || d->vData.flicking) && d->correctFlick && !d->inFlickCorrection) { d->inFlickCorrection = true; // 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. diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index e3f7980..4342ff3 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -450,12 +450,12 @@ void tst_QDeclarativeGridView::removed() model.removeItem(1); // Confirm items positioned correctly - for (int i = 6; i < 18; ++i) { + for (int i = 3; i < 15; ++i) { QDeclarativeItem *item = findItem(contentItem, "wrapper", i); if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); + QTRY_COMPARE(item->x(), (i%3)*80.0); + QTRY_COMPARE(item->y(), 60+(i/3)*60.0); } // Remove currentIndex @@ -476,7 +476,7 @@ void tst_QDeclarativeGridView::removed() if (!item) qWarning() << "Item" << i << "not found"; QTRY_VERIFY(item); QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); + QTRY_VERIFY(item->y() == 60+(i/3)*60); } // remove item outside current view. -- cgit v0.12 From 9eb176928280acaabcee99d52c2379ddd3a44490 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 8 Jul 2011 10:42:49 +0200 Subject: Use memmove in QListData::append(int) as regions overlap. It's undefined behaviour to memcpy regions with overlapping area. You have to use memmove. Change-Id: I912c819bf7ab26ba1e60028ee9d7c833dfc5138a Reviewed-on: http://codereview.qt.nokia.com/1355 Reviewed-by: Olivier Goffart (cherry picked from commit d96b7b809e614dd416709acec768529457120b9f) --- src/corelib/tools/qlist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index 36a9c60..e68ddd5 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -237,7 +237,7 @@ void **QListData::append(int n) if (b - n >= 2 * d->alloc / 3) { // we have enough space. Just not at the end -> move it. e -= b; - ::memcpy(d->array, d->array + b, e * sizeof(void *)); + ::memmove(d->array, d->array + b, e * sizeof(void *)); d->begin = 0; } else { realloc(grow(d->alloc + n)); -- cgit v0.12 From 96960787f7cb6f3937cdf7e3da77988259979008 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 8 Jul 2011 16:49:28 +0100 Subject: Fix resource leak in symbian socket engine Timer created when a socket is being used synchronously was not being closed on destruction of the socket engine. Reviewed-by: mread --- src/network/socket/qsymbiansocketengine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/socket/qsymbiansocketengine.cpp b/src/network/socket/qsymbiansocketengine.cpp index 0aa5a5a..966af88 100644 --- a/src/network/socket/qsymbiansocketengine.cpp +++ b/src/network/socket/qsymbiansocketengine.cpp @@ -264,6 +264,7 @@ QSymbianSocketEnginePrivate::QSymbianSocketEnginePrivate() : QSymbianSocketEnginePrivate::~QSymbianSocketEnginePrivate() { + selectTimer.Close(); } -- cgit v0.12 From 8ce9dc02cd5031f26c7fec10484a8c47904c46f5 Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Fri, 8 Jul 2011 18:52:36 +0200 Subject: sync win32-g++-cross with win32-g++ (lib prefix and extension) qmake now needs library prefix and extension to be supplied. This was added to plain win32-g++ in dbbf06e. Now added to win32-g++-cross. Without this, static libraries get named 'X.lib' instead of 'libX.a'. Merge-request: 1283 Reviewed-by: Oswald Buddenhagen --- mkspecs/unsupported/win32-g++-cross/qmake.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mkspecs/unsupported/win32-g++-cross/qmake.conf b/mkspecs/unsupported/win32-g++-cross/qmake.conf index 01e2f10..0538e86 100644 --- a/mkspecs/unsupported/win32-g++-cross/qmake.conf +++ b/mkspecs/unsupported/win32-g++-cross/qmake.conf @@ -62,6 +62,8 @@ QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows QMAKE_LFLAGS_DLL = -shared QMAKE_LINK_OBJECT_MAX = 10 QMAKE_LINK_OBJECT_SCRIPT= object_script +QMAKE_PREFIX_STATICLIB = lib +QMAKE_EXTENSION_STATICLIB = a QMAKE_LIBS = -- cgit v0.12