\li New \l{PathView::}{maximumFlickVelocity} property controls the maximum flick velocity of the
view.
\li New \l{PathView::}{snapMode} property controls the snap model when flicking between items
+ \li If the model is changed after the component is completed, the offset and currentIndex are
+ reset to 0.
\endlist
\endlist
releaseItem(p);
}
items.clear();
+ tl.clear();
}
void QQuickPathViewPrivate::updateMappedRange()
For large or dynamic datasets the model is usually provided by a C++ model object.
Models can also be created directly in QML, using the ListModel type.
+ \note changing the model will reset the offset and currentIndex to 0.
+
\sa {qmlmodels}{Data Models}
*/
QVariant QQuickPathView::model() const
this, QQuickPathView, SLOT(createdItem(int,QQuickItem*)));
qmlobject_disconnect(d->model, QQuickVisualModel, SIGNAL(initItem(int,QQuickItem*)),
this, QQuickPathView, SLOT(initItem(int,QQuickItem*)));
- for (int i=0; i<d->items.count(); i++){
- QQuickItem *p = d->items[i];
- d->releaseItem(p);
- }
- d->items.clear();
+ d->clear();
}
d->modelVariant = model;
if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model))
dataModel->setModel(model);
}
+ int oldModelCount = d->modelCount;
d->modelCount = 0;
if (d->model) {
qmlobject_connect(d->model, QQuickVisualModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)),
qmlobject_connect(d->model, QQuickVisualModel, SIGNAL(initItem(int,QQuickItem*)),
this, QQuickPathView, SLOT(initItem(int,QQuickItem*)));
d->modelCount = d->model->count();
- if (d->model->count())
- d->offset = qmlMod(d->offset, qreal(d->model->count()));
- if (d->offset < 0)
- d->offset = d->model->count() + d->offset;
-}
+ }
+ if (isComponentComplete()) {
+ if (d->currentIndex != 0) {
+ d->currentIndex = 0;
+ emit currentIndexChanged();
+ }
+ if (d->offset != 0.0) {
+ d->offset = 0;
+ emit offsetChanged();
+ }
+ }
d->regenerate();
- if (d->currentIndex < d->modelCount)
- setOffset(qmlMod(d->modelCount - d->currentIndex, d->modelCount));
- else
- d->fixOffset();
- emit countChanged();
+ if (d->modelCount != oldModelCount)
+ emit countChanged();
emit modelChanged();
}
void QQuickPathView::setCurrentIndex(int idx)
{
Q_D(QQuickPathView);
+ if (!isComponentComplete()) {
+ if (idx != d->currentIndex) {
+ d->currentIndex = idx;
+ emit currentIndexChanged();
+ }
+ return;
+ }
+
idx = d->modelCount
? ((idx % d->modelCount) + d->modelCount) % d->modelCount
: 0;
QQuickItem::componentComplete();
- d->createHighlight();
- // It is possible that a refill has already happended to to Path
- // bindings being handled in the componentComplete(). If so
- // don't do it again.
- if (d->items.count() == 0 && d->model) {
+ if (d->model) {
d->modelCount = d->model->count();
- d->regenerate();
+ if (d->modelCount && d->currentIndex != 0) // an initial value has been provided for currentIndex
+ d->offset = qmlMod(d->modelCount - d->currentIndex, d->modelCount);
}
+
+ d->createHighlight();
+ d->regenerate();
d->updateHighlight();
d->updateCurrent();
return;
int idx = calcCurrentIndex();
- if (model && idx != currentIndex) {
+ if (model && (idx != currentIndex || !currentItem)) {
if (currentItem) {
if (QQuickPathViewAttached *att = attached(currentItem))
att->setIsCurrentItem(false);
releaseItem(currentItem);
}
+ int oldCurrentIndex = currentIndex;
currentIndex = idx;
currentItem = 0;
createCurrentItem();
- emit q->currentIndexChanged();
+ if (oldCurrentIndex != currentIndex)
+ emit q->currentIndexChanged();
+ emit q->currentItemChanged();
}
}
--- /dev/null
+import QtQuick 2.0
+
+PathView {
+ id: photoPathView
+ y: 100; width: 800; height: 330; pathItemCount: 4
+ currentIndex: 3
+ dragMargin: 24
+ preferredHighlightBegin: 0.50
+ preferredHighlightEnd: 0.50
+
+ path: Path {
+ startX: -50; startY: 40;
+
+ PathAttribute { name: "scale"; value: 0.5 }
+ PathAttribute { name: "angle"; value: -45 }
+
+ PathCubic {
+ x: 400; y: 220
+ control1X: 140; control1Y: 40
+ control2X: 210; control2Y: 220
+ }
+
+ PathAttribute { name: "scale"; value: 1.2 }
+ PathAttribute { name: "angle"; value: 0 }
+
+ PathCubic {
+ x: 850; y: 40
+ control2X: 660; control2Y: 40
+ control1X: 590; control1Y: 220
+ }
+
+ PathAttribute { name: "scale"; value: 0.5 }
+ PathAttribute { name: "angle"; value: 45 }
+ }
+
+ model: ListModel {
+ id: rssModel
+ ListElement { lColor: "red" }
+ ListElement { lColor: "green" }
+ ListElement { lColor: "yellow" }
+ ListElement { lColor: "blue" }
+ ListElement { lColor: "purple" }
+ ListElement { lColor: "gray" }
+ ListElement { lColor: "brown" }
+ ListElement { lColor: "thistle" }
+ }
+
+ delegate: Component {
+ id: photoDelegate
+ Rectangle {
+ id: wrapper
+ width: 85; height: 85; color: lColor
+
+ transform: Rotation {
+ id: itemRotation; origin.x: wrapper.width/2; origin.y: wrapper.height/2
+ axis.y: 1; axis.z: 0
+ }
+ }
+ }
+}
#include <QtQuick/private/qquickrectangle_p.h>
#include <QtQml/private/qquicklistmodel_p.h>
#include <QtQml/private/qqmlvaluetype_p.h>
+#include <QtGui/qstandarditemmodel.h>
#include <QStringListModel>
#include <QFile>
Q_DECLARE_METATYPE(QQuickPathView::HighlightRangeMode)
-#ifndef QT_NO_WIDGETS
-#include <QStandardItemModel>
static void initStandardTreeModel(QStandardItemModel *model)
{
QStandardItem *item;
item->setIcon(QIcon());
model->insertRow(2, item);
}
-#endif
-
class tst_QQuickPathView : public QQmlDataTest
{
void dataModel();
void pathview2();
void pathview3();
+ void initialCurrentIndex();
void insertModel_data();
void insertModel();
void removeModel_data();
void visualDataModel();
void undefinedPath();
void mouseDrag();
-#ifndef QT_NO_WIDGETS
void treeModel();
-#endif
void changePreferredHighlight();
void missingPercent();
void creationContext();
delete obj;
}
+void tst_QQuickPathView::initialCurrentIndex()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("initialCurrentIndex.qml"));
+ QQuickPathView *obj = qobject_cast<QQuickPathView*>(c.create());
+
+ QVERIFY(obj != 0);
+ QVERIFY(obj->path() != 0);
+ QVERIFY(obj->delegate() != 0);
+ QVERIFY(obj->model() != QVariant());
+ QCOMPARE(obj->currentIndex(), 3);
+ QCOMPARE(obj->offset(), 5.0);
+ QCOMPARE(obj->preferredHighlightBegin(), 0.5);
+ QCOMPARE(obj->dragMargin(), 24.);
+ QCOMPARE(obj->count(), 8);
+ QCOMPARE(obj->pathItemCount(), 4);
+
+ delete obj;
+}
+
void tst_QQuickPathView::insertModel_data()
{
QTest::addColumn<int>("mode");
QQuickPathView *pathView = window->rootObject()->findChild<QQuickPathView*>("pathView");
QVERIFY(pathView);
+ pathView->setCurrentIndex(3);
+ QTRY_COMPARE(pathView->offset(), 6.0);
QQuickListModel *alternateModel = window->rootObject()->findChild<QQuickListModel*>("alternateModel");
QVERIFY(alternateModel);
QVariant modelVariant = QVariant::fromValue<QObject *>(alternateModel);
QSignalSpy modelSpy(pathView, SIGNAL(modelChanged()));
+ QSignalSpy currentIndexSpy(pathView, SIGNAL(currentIndexChanged()));
+ QCOMPARE(pathView->currentIndex(), 3);
pathView->setModel(modelVariant);
QCOMPARE(pathView->model(), modelVariant);
QCOMPARE(modelSpy.count(),1);
+ QCOMPARE(pathView->currentIndex(), 0);
+ QCOMPARE(currentIndexSpy.count(), 1);
pathView->setModel(modelVariant);
QCOMPARE(modelSpy.count(),1);
pathView->setModel(QVariant());
QCOMPARE(modelSpy.count(),2);
+ QCOMPARE(pathView->currentIndex(), 0);
+ QCOMPARE(currentIndexSpy.count(), 1);
delete window;
}
delete window;
}
-#ifndef QT_NO_WIDGETS
void tst_QQuickPathView::treeModel()
{
QQuickView *window = createView();
delete window;
}
-#endif
void tst_QQuickPathView::changePreferredHighlight()
{
QVERIFY(pathview->currentIndex() != currentIndex);
else
QVERIFY(pathview->currentIndex() == currentIndex);
+
+ delete window;
}
void tst_QQuickPathView::snapToItem_data()
QVERIFY(pathview->currentIndex() == currentIndex+1);
else
QVERIFY(pathview->currentIndex() == currentIndex);
+
+ delete window;
}
void tst_QQuickPathView::snapOneItem_data()