Fix content position for key navigation with StrictlyEnforceRange
authorBea Lam <bea.lam@nokia.com>
Mon, 1 Aug 2011 06:56:45 +0000 (16:56 +1000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 2 Aug 2011 06:50:21 +0000 (08:50 +0200)
If a ListView had highlight ranges and StrictlyEnforceRange, but no
highlight item, the content would not move to the correct position
when incrementCurrentIndex() and decrementCurrentIndex() were invoked.

trackedPositionChanged() shouldn't take the current section pos into
account because this is already calculated by FxListItemSG::position()
(this wasn't the case when the code in trackedPositionChanged() was
originally written).

Task-number: QTBUG-20287
Change-Id: I1624b5afd1efbe27630349143b7af2b486cfa260
Reviewed-on: http://codereview.qt.nokia.com/2429
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Bea Lam <bea.lam@nokia.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/declarative/items/qsgitemview.cpp
src/qtquick1/graphicsitems/qdeclarativelistview.cpp
tests/auto/declarative/qsglistview/data/listview-enforcerange-nohighlight.qml [new file with mode: 0644]
tests/auto/declarative/qsglistview/tst_qsglistview.cpp

index bcb4a8a..d698125 100644 (file)
@@ -723,7 +723,6 @@ void QSGItemView::trackedPositionChanged()
         qreal trackedPos = d->trackedItem->position();
         qreal trackedSize = d->trackedItem->size();
         if (d->trackedItem != d->currentItem) {
-            trackedPos -= d->currentItem->sectionSize();
             trackedSize += d->currentItem->sectionSize();
         }
         qreal viewPos;
index 0474591..244a2b8 100644 (file)
@@ -3131,7 +3131,6 @@ void QDeclarative1ListView::trackedPositionChanged()
         qreal trackedPos = qCeil(d->trackedItem->position());
         qreal trackedSize = d->trackedItem->size();
         if (d->trackedItem != d->currentItem) {
-            trackedPos -= d->currentItem->sectionSize();
             trackedSize += d->currentItem->sectionSize();
         }
         qreal viewPos;
diff --git a/tests/auto/declarative/qsglistview/data/listview-enforcerange-nohighlight.qml b/tests/auto/declarative/qsglistview/data/listview-enforcerange-nohighlight.qml
new file mode 100644 (file)
index 0000000..946f4f2
--- /dev/null
@@ -0,0 +1,60 @@
+import QtQuick 2.0
+
+Rectangle {
+    width: 240
+    height: 320
+
+    Component {
+        id: myDelegate
+        Rectangle {
+            id: wrapper
+            objectName: "wrapper"
+            height: 20
+            width: 240
+            color: "transparent"
+            Text {
+                text: index
+            }
+            Text {
+                x: 30
+                id: textName
+                objectName: "textName"
+                text: name
+            }
+            Text {
+                x: 120
+                id: textNumber
+                objectName: "textNumber"
+                text: number
+            }
+            Text {
+                x: 200
+                text: wrapper.y
+            }
+        }
+    }
+
+    Rectangle {     // current listview item should be always in this area
+        y: 100
+        height: 20
+        width: 240
+        color: "purple"
+    }
+
+    ListView {
+        id: list
+        objectName: "list"
+        width: 240
+        height: 320
+        model: testModel
+        delegate: myDelegate
+
+        preferredHighlightBegin: 100
+        preferredHighlightEnd: 100
+        highlightRangeMode: "StrictlyEnforceRange"
+
+        section.property: "number"
+        section.delegate: Rectangle { width: 240; height: 10; color: "lightsteelblue" }
+    }
+}
+
index 5ee13e8..f4a2384 100644 (file)
@@ -98,6 +98,7 @@ private slots:
     void currentIndex();
     void noCurrentIndex();
     void enforceRange();
+    void enforceRange_withoutHighlight();
     void spacing();
     void sections();
     void sectionsDelegate();
@@ -1113,6 +1114,51 @@ void tst_QSGListView::enforceRange()
     delete canvas;
 }
 
+void tst_QSGListView::enforceRange_withoutHighlight()
+{
+    // QTBUG-20287
+    // If no highlight is set but StrictlyEnforceRange is used, the content should still move
+    // to the correct position (i.e. to the next/previous item, not next/previous section)
+    // when moving up/down via incrementCurrentIndex() and decrementCurrentIndex()
+
+    QSGView *canvas = createView();
+    canvas->show();
+
+    TestModel model;
+    model.addItem("Item 0", "a");
+    model.addItem("Item 1", "b");
+    model.addItem("Item 2", "b");
+    model.addItem("Item 3", "c");
+
+    QDeclarativeContext *ctxt = canvas->rootContext();
+    ctxt->setContextProperty("testModel", &model);
+
+    canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/listview-enforcerange-nohighlight.qml"));
+    qApp->processEvents();
+
+    QSGListView *listview = findItem<QSGListView>(canvas->rootObject(), "list");
+    QTRY_VERIFY(listview != 0);
+
+    qreal expectedPos = -100.0;
+
+    expectedPos += 10.0;    // scroll past 1st section's delegate (10px height)
+    QTRY_COMPARE(listview->contentY(), expectedPos);
+
+    expectedPos += 20 + 10;     // scroll past 1st section and section delegate of 2nd section
+    QTest::keyClick(canvas, Qt::Key_Down);
+    QTRY_COMPARE(listview->contentY(), expectedPos);
+
+    expectedPos += 20;     // scroll past 1st item of 2nd section
+    QTest::keyClick(canvas, Qt::Key_Down);
+    QTRY_COMPARE(listview->contentY(), expectedPos);
+
+    expectedPos += 20 + 10;     // scroll past 2nd item of 2nd section and section delegate of 3rd section
+    QTest::keyClick(canvas, Qt::Key_Down);
+    QTRY_COMPARE(listview->contentY(), expectedPos);
+
+    delete canvas;
+}
+
 void tst_QSGListView::spacing()
 {
     QSGView *canvas = createView();