summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Krupenko <krnekit@gmail.com>2016-01-31 23:38:55 +0200
committerNikita Krupenko <krnekit@gmail.com>2016-08-18 13:49:12 +0000
commit69af774a54198a83f774c89b5d5d7135b8fb1f7a (patch)
tree3e58d03b48b70499de0b741b2141667141468589
parentc0f58d5283ce981b8cfbc43f602a3b6553e26ce2 (diff)
downloadqtquickcontrols-69af774a54198a83f774c89b5d5d7135b8fb1f7a.tar.gz
Update scroll indicator position on content size change
If scroll indicator is at the beginning and data prepended to contentItem, scroll indicator should change position to previous content beginning. This is especially important with so-called "infinite scrolling", when scrolling goes upwards and new content added at the top of the view. Task-number: QTBUG-50795 Change-Id: I250d6535b1146a54c6a70062b659cc49ed43709f Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
-rw-r--r--src/controls/Private/ScrollViewHelper.qml10
-rw-r--r--tests/auto/controls/data/tst_scrollview.qml63
-rw-r--r--tests/auto/testplugin/testcppmodels.h52
-rw-r--r--tests/auto/testplugin/testplugin.cpp1
4 files changed, 126 insertions, 0 deletions
diff --git a/src/controls/Private/ScrollViewHelper.qml b/src/controls/Private/ScrollViewHelper.qml
index b4a589bf..bc3d9eb8 100644
--- a/src/controls/Private/ScrollViewHelper.qml
+++ b/src/controls/Private/ScrollViewHelper.qml
@@ -131,6 +131,11 @@ Item {
anchors.right: cornerFill.left
anchors.leftMargin: leftMargin
anchors.bottomMargin: bottomMargin
+ onScrollAmountChanged: {
+ if (flickableItem && (flickableItem.atXBeginning || flickableItem.atXEnd)) {
+ value = flickableItem.contentX - flickableItem.originX
+ }
+ }
onValueChanged: {
if (!blockUpdates) {
flickableItem.contentX = value + flickableItem.originX
@@ -180,6 +185,11 @@ Item {
anchors.top: parent.top
anchors.topMargin: __scrollBarTopMargin + topMargin
anchors.rightMargin: rightMargin
+ onScrollAmountChanged: {
+ if (flickableItem && (flickableItem.atYBeginning || flickableItem.atYEnd)) {
+ value = flickableItem.contentY - flickableItem.originY
+ }
+ }
onValueChanged: {
if (flickableItem && !blockUpdates && enabled) {
flickableItem.contentY = value + flickableItem.originY
diff --git a/tests/auto/controls/data/tst_scrollview.qml b/tests/auto/controls/data/tst_scrollview.qml
index e687c9bc..cb96c3db 100644
--- a/tests/auto/controls/data/tst_scrollview.qml
+++ b/tests/auto/controls/data/tst_scrollview.qml
@@ -41,6 +41,7 @@
import QtQuick 2.2
import QtTest 1.0
import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.1
import QtQuickControlsTests 1.0
Item {
@@ -90,6 +91,68 @@ TestCase {
scrollView.destroy()
}
+ Component {
+ id: dragFetchAppendComponent
+
+ ScrollView {
+ width: 400; height: 400
+ frameVisible: false
+ style: ScrollViewStyle {
+ transientScrollBars: false
+ handle: Rectangle {
+ implicitWidth: 16; implicitHeight: 16
+ color: "red"
+ }
+ scrollBarBackground: Item {width: 16 ; height: 16}
+ incrementControl: Rectangle {
+ width: 16; height: 16
+ color: "blue"
+ }
+ decrementControl: Rectangle {
+ width: 16; height: 16
+ color: "blue"
+ }
+ }
+ ListView {
+ id: view
+
+ verticalLayoutDirection: ListView.BottomToTop
+ model: TestFetchAppendModel { }
+ delegate: Text {
+ width: view.width
+ height: 60
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ text: "Item %1".arg(model.index)
+ }
+ }
+ }
+ }
+
+ function test_dragFetchAppend() { // QTBUG-50795
+ var scrollView = dragFetchAppendComponent.createObject(container)
+ verify(scrollView !== null, "view created is null")
+ waitForRendering(scrollView)
+ verify(scrollView.flickableItem.contentHeight === 60 * 20)
+
+ // After scrolling to the end, view should ask the model to fetch more
+ // data, content height should increase and scrollbar handle should move
+ // to the center.
+ mouseDrag(scrollView, scrollView.width - 2, scrollView.height - 8 - 16, 0, -scrollView.height + 8 + 16)
+ waitForRendering(scrollView)
+
+ // Move it again to fetch more data from the model.
+ mouseDrag(scrollView, scrollView.width - 2, scrollView.height / 2, 0, -scrollView.height / 2 + 8 + 16)
+ waitForRendering(scrollView)
+
+ mouseRelease(scrollView, scrollView.width - 2, 8 + 16)
+ waitForRendering(scrollView)
+
+ verify(Math.round(scrollView.flickableItem.contentHeight) > 60 * 20)
+ verify(Math.round(scrollView.flickableItem.contentY) < -(60 * 20))
+
+ scrollView.destroy()
+ }
function test_scrollbars() {
var component = scrollViewComponent
diff --git a/tests/auto/testplugin/testcppmodels.h b/tests/auto/testplugin/testcppmodels.h
index f5cc6298..6298bd13 100644
--- a/tests/auto/testplugin/testcppmodels.h
+++ b/tests/auto/testplugin/testcppmodels.h
@@ -96,6 +96,58 @@ private:
QList<TestObject> m_testobject;
};
+class TestFetchAppendModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ explicit TestFetchAppendModel(QObject *parent = 0)
+ : QAbstractListModel(parent) { }
+
+ virtual int rowCount(const QModelIndex &parent) const
+ {
+ if (parent.isValid()) {
+ return 0;
+ }
+
+ return m_data.size();
+ }
+ virtual QVariant data(const QModelIndex &index, int role) const
+ {
+ if (!index.isValid() || role != Qt::DisplayRole) {
+ return QVariant();
+ }
+
+ return QVariant::fromValue(index.row());
+ }
+
+ virtual bool canFetchMore(const QModelIndex &parent) const
+ {
+ Q_UNUSED(parent)
+
+ return true;
+ }
+ virtual void fetchMore(const QModelIndex & parent)
+ {
+ Q_UNUSED(parent)
+
+ addMoreData();
+ }
+
+private:
+ void addMoreData()
+ {
+ static const int insertCount = 20;
+
+ beginInsertRows(QModelIndex(), m_data.size(), m_data.size() + insertCount - 1);
+ for (int i = 0; i < insertCount; i++) {
+ m_data.append(int());
+ }
+ endInsertRows();
+ }
+
+ QList<int> m_data;
+};
+
#endif // TESTCPPMODELS_H
diff --git a/tests/auto/testplugin/testplugin.cpp b/tests/auto/testplugin/testplugin.cpp
index 0f23f0b4..ee6a9711 100644
--- a/tests/auto/testplugin/testplugin.cpp
+++ b/tests/auto/testplugin/testplugin.cpp
@@ -48,6 +48,7 @@ void TestPlugin::registerTypes(const char *uri)
qmlRegisterType<TestObject>(uri, 1, 0, "TestObject");
qmlRegisterType<TestItemModel>(uri, 1, 0, "TestItemModel");
qmlRegisterType<TestModel>(uri, 1, 0, "TreeModel");
+ qmlRegisterType<TestFetchAppendModel>(uri, 1, 0, "TestFetchAppendModel");
}
void TestPlugin::initializeEngine(QQmlEngine *engine, const char * /*uri*/)