From 8454a21b837ccf3968f6dbc56ed4f06d60d63c8f Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Wed, 23 Jul 2014 15:40:42 +0200 Subject: Flickable: Cancel interaction on interactive changes Otherwise if you have a listview with a flickable inside with a mouseare inside the pressed is never set to false if you make the interactive property of the outer list depend on the moving of the inner flickable. This makes that when later you change currentIndex of the list and you have StrictlyEnforceRange set, the list won't move because it still thinks it is pressed Change-Id: I2c2021f486fc0a31840c3f2199bc7cb76dc01e3e Reviewed-by: Martin Jones --- src/quick/items/qquickflickable.cpp | 41 ++++++++++++++-------------- src/quick/items/qquickflickable_p_p.h | 2 ++ tests/auto/qmltest/listview/tst_listview.qml | 41 ++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 21 deletions(-) diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index ee71ea8a76..63dde661d9 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -763,15 +763,8 @@ void QQuickFlickable::setInteractive(bool interactive) Q_D(QQuickFlickable); if (interactive != d->interactive) { d->interactive = interactive; - if (!interactive && (d->hData.flicking || d->vData.flicking)) { - d->clearTimeline(); - d->hData.vTime = d->vData.vTime = d->timeline.time(); - d->hData.flicking = false; - d->vData.flicking = false; - emit flickingChanged(); - emit flickingHorizontallyChanged(); - emit flickingVerticallyChanged(); - emit flickEnded(); + if (!interactive) { + d->cancelInteraction(); } emit interactiveChanged(); } @@ -2015,18 +2008,24 @@ bool QQuickFlickable::yflick() const void QQuickFlickable::mouseUngrabEvent() { Q_D(QQuickFlickable); - if (d->pressed) { - // if our mouse grab has been removed (probably by another Flickable), - // fix our state - d->clearDelayedPress(); - d->pressed = false; - d->draggingEnding(); - d->stealMouse = false; - setKeepMouseGrab(false); - d->fixupX(); - d->fixupY(); - if (!d->isViewMoving()) - movementEnding(); + // if our mouse grab has been removed (probably by another Flickable), + // fix our state + d->cancelInteraction(); +} + +void QQuickFlickablePrivate::cancelInteraction() +{ + Q_Q(QQuickFlickable); + if (pressed) { + clearDelayedPress(); + pressed = false; + draggingEnding(); + stealMouse = false; + q->setKeepMouseGrab(false); + fixupX(); + fixupY(); + if (!isViewMoving()) + q->movementEnding(); } } diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index 33a642eb69..13af2e055c 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -200,6 +200,8 @@ public: bool isViewMoving() const; + void cancelInteraction(); + public: QQuickItem *contentItem; diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml index 03be57909f..069b62a726 100644 --- a/tests/auto/qmltest/listview/tst_listview.qml +++ b/tests/auto/qmltest/listview/tst_listview.qml @@ -108,6 +108,33 @@ Item { property int createdDelegates: 0 } + ListView + { + id: listInteractiveCurrentIndexEnforce + width: 600 + height: 600 + + snapMode: ListView.SnapOneItem + orientation: ListView.Horizontal + interactive: !currentItem.moving + highlightRangeMode: ListView.StrictlyEnforceRange + + model: 4 + + focus: true + Keys.onPressed: if (event.key == Qt.Key_K) currentIndex = currentIndex + 1; + + delegate: Flickable { + width: 600 + height: 600 + contentWidth: 600 + contentHeight: 1200 + + MouseArea { anchors.fill: parent } + Rectangle { anchors.fill: parent; color: index == 0 ? "red" : index == 1 ? "green" : index == 2 ? "blue" : "white" } + } + } + Component { id: delegateModelAfterCreateComponent Rectangle { @@ -272,5 +299,19 @@ Item { listViewDelegateModelAfterCreate.model = 40; verify(listViewDelegateModelAfterCreate.createdDelegates > 0); } + + function test_listInteractiveCurrentIndexEnforce() { + mousePress(listInteractiveCurrentIndexEnforce, 10, 50); + mouseMove(listInteractiveCurrentIndexEnforce, 10, 40); + mouseMove(listInteractiveCurrentIndexEnforce, 10, 30); + mouseMove(listInteractiveCurrentIndexEnforce, 10, 20); + mouseMove(listInteractiveCurrentIndexEnforce, 10, 10); + compare(listInteractiveCurrentIndexEnforce.interactive, false); + mouseRelease(listInteractiveCurrentIndexEnforce, 10, 10); + tryCompare(listInteractiveCurrentIndexEnforce, "interactive", true); + keyClick("k"); + compare(listInteractiveCurrentIndexEnforce.currentIndex, 1); + tryCompare(listInteractiveCurrentIndexEnforce, "contentX", listInteractiveCurrentIndexEnforce.width); + } } } -- cgit v1.2.3