Geometry listeners were called for deleted header/footer.
Change-Id: I47854178232f8a4ab5e19a931901b49741fec388
Reviewed-by: Bea Lam <bea.lam@nokia.com>
class FxGridItemSG : public FxViewItem
{
public:
- FxGridItemSG(QQuickItem *i, QQuickGridView *v, bool own) : FxViewItem(i, own), view(v) {
+ FxGridItemSG(QQuickItem *i, QQuickGridView *v, bool own, bool trackGeometry) : FxViewItem(i, own, trackGeometry), view(v) {
attached = static_cast<QQuickGridViewAttached*>(qmlAttachedPropertiesObject<QQuickGridView>(item));
if (attached)
static_cast<QQuickGridViewAttached*>(attached)->setView(view);
+ if (trackGeometry) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->addItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
+ }
}
- ~FxGridItemSG() {}
+ ~FxGridItemSG() {
+ if (trackGeom) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->removeItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
+ }
+ }
qreal position() const {
return rowPos();
{
Q_Q(QQuickGridView);
Q_UNUSED(modelIndex);
- return new FxGridItemSG(item, q, false);
+ return new FxGridItemSG(item, q, false, false);
}
void QQuickGridViewPrivate::initializeViewItem(FxViewItem *item)
if (currentItem) {
QQuickItem *item = createHighlightItem();
if (item) {
- FxGridItemSG *newHighlight = new FxGridItemSG(item, q, true);
+ FxGridItemSG *newHighlight = new FxGridItemSG(item, q, true, true);
if (autoHighlight)
resetHighlightPosition();
highlightXAnimator = new QSmoothedAnimation;
Q_Q(QQuickGridView);
bool created = false;
if (!footer) {
- QQuickItem *item = createComponentItem(footerComponent, true);
+ QQuickItem *item = createComponentItem(footerComponent);
if (!item)
return;
item->setZ(1);
- footer = new FxGridItemSG(item, q, true);
+ footer = new FxGridItemSG(item, q, true, true);
created = true;
}
Q_Q(QQuickGridView);
bool created = false;
if (!header) {
- QQuickItem *item = createComponentItem(headerComponent, true);
+ QQuickItem *item = createComponentItem(headerComponent);
if (!item)
return;
item->setZ(1);
- header = new FxGridItemSG(item, q, true);
+ header = new FxGridItemSG(item, q, true, true);
created = true;
}
QT_BEGIN_NAMESPACE
-FxViewItem::FxViewItem(QQuickItem *i, bool own)
+FxViewItem::FxViewItem(QQuickItem *i, bool own, bool trackGeometry)
: item(i)
, transitionableItem(0)
, ownItem(own)
, releaseAfterTransition(false)
+ , trackGeom(trackGeometry)
{
}
QQuickItem *QQuickItemViewPrivate::createHighlightItem()
{
- return createComponentItem(highlightComponent, true, true);
+ return createComponentItem(highlightComponent, true);
}
-QQuickItem *QQuickItemViewPrivate::createComponentItem(QQmlComponent *component, bool receiveItemGeometryChanges, bool createDefault)
+QQuickItem *QQuickItemViewPrivate::createComponentItem(QQmlComponent *component, bool createDefault)
{
Q_Q(QQuickItemView);
if (item) {
QQml_setParent_noEvent(item, q->contentItem());
item->setParentItem(q->contentItem());
- if (receiveItemGeometryChanges) {
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
- itemPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
- }
}
return item;
}
class FxViewItem
{
public:
- FxViewItem(QQuickItem *, bool own);
+ FxViewItem(QQuickItem *, bool own, bool trackGeometry);
virtual ~FxViewItem();
qreal itemX() const;
int index;
bool ownItem;
bool releaseAfterTransition;
+ bool trackGeom;
};
QQuickItemViewPrivate();
~QQuickItemViewPrivate();
+ static inline QQuickItemViewPrivate *get(QQuickItemView *o) { return o->d_func(); }
+
struct ChangeResult {
QQmlNullableValue<qreal> visiblePos;
bool changedFirstItem;
virtual bool releaseItem(FxViewItem *item);
QQuickItem *createHighlightItem();
- QQuickItem *createComponentItem(QQmlComponent *component, bool receiveItemGeometryChanges, bool createDefault = false);
+ QQuickItem *createComponentItem(QQmlComponent *component, bool createDefault = false);
void updateCurrent(int modelIndex);
void updateTrackedItem();
class FxListItemSG : public FxViewItem
{
public:
- FxListItemSG(QQuickItem *i, QQuickListView *v, bool own) : FxViewItem(i, own), view(v) {
+ FxListItemSG(QQuickItem *i, QQuickListView *v, bool own, bool trackGeometry) : FxViewItem(i, own, trackGeometry), view(v) {
attached = static_cast<QQuickListViewAttached*>(qmlAttachedPropertiesObject<QQuickListView>(item));
if (attached)
static_cast<QQuickListViewAttached*>(attached)->setView(view);
+ if (trackGeometry) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->addItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
+ }
}
- ~FxListItemSG() {}
+ ~FxListItemSG() {
+ if (trackGeom) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->removeItemChangeListener(QQuickItemViewPrivate::get(view), QQuickItemPrivate::Geometry);
+ }
+ }
inline QQuickItem *section() const {
return attached ? static_cast<QQuickListViewAttached*>(attached)->m_sectionItem : 0;
{
Q_Q(QQuickListView);
- FxListItemSG *listItem = new FxListItemSG(item, q, false);
+ FxListItemSG *listItem = new FxListItemSG(item, q, false, false);
listItem->index = modelIndex;
// initialise attached properties
if (currentItem) {
QQuickItem *item = createHighlightItem();
if (item) {
- FxListItemSG *newHighlight = new FxListItemSG(item, q, true);
+ FxListItemSG *newHighlight = new FxListItemSG(item, q, true, true);
if (autoHighlight) {
newHighlight->setSize(static_cast<FxListItemSG*>(currentItem)->itemSize());
Q_Q(QQuickListView);
bool created = false;
if (!footer) {
- QQuickItem *item = createComponentItem(footerComponent, true);
+ QQuickItem *item = createComponentItem(footerComponent);
if (!item)
return;
item->setZ(1);
- footer = new FxListItemSG(item, q, true);
+ footer = new FxListItemSG(item, q, true, true);
created = true;
}
Q_Q(QQuickListView);
bool created = false;
if (!header) {
- QQuickItem *item = createComponentItem(headerComponent, true);
+ QQuickItem *item = createComponentItem(headerComponent);
if (!item)
return;
item->setZ(1);
- header = new FxListItemSG(item, q, true);
+ header = new FxListItemSG(item, q, true, true);
created = true;
}
--- /dev/null
+import QtQuick 2.0
+
+GridView {
+ id: view
+ property bool horizontal: false
+ property bool rtl: false
+ width: 240
+ height: 320
+
+ model: testModel
+
+ flow: horizontal ? GridView.TopToBottom : GridView.LeftToRight
+ header: Rectangle {
+ objectName: "header"
+ width: horizontal ? 20 : view.width
+ height: horizontal ? view.height : 20
+ color: "red"
+ }
+ footer: Rectangle {
+ objectName: "footer"
+ width: horizontal ? 30 : view.width
+ height: horizontal ? view.height : 30
+ color: "blue"
+ }
+
+ cellWidth: 80;
+ cellHeight: 80;
+
+ delegate: Text { width: 80; height: 80; text: index + "(" + x + ")" }
+ layoutDirection: rtl ? Qt.RightToLeft : Qt.LeftToRight
+}
void footer_data();
void header();
void header_data();
+ void headerFooter();
void resizeViewAndRepaint();
void changeColumnCount();
void indexAt_itemAt_data();
<< QPointF(-(240 - 40), 0);
}
+class GVAccessor : public QQuickGridView
+{
+public:
+ qreal minY() const { return minYExtent(); }
+ qreal maxY() const { return maxYExtent(); }
+ qreal minX() const { return minXExtent(); }
+ qreal maxX() const { return maxXExtent(); }
+};
+
+void tst_QQuickGridView::headerFooter()
+{
+ {
+ // Vertical
+ QQuickView *canvas = createView();
+
+ QmlListModel model;
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(testFileUrl("headerfooter.qml"));
+ qApp->processEvents();
+
+ QQuickGridView *gridview = qobject_cast<QQuickGridView*>(canvas->rootObject());
+ QTRY_VERIFY(gridview != 0);
+
+ QQuickItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->y(), -header->height());
+
+ QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->y(), 0.);
+
+ QCOMPARE(static_cast<GVAccessor*>(gridview)->minY(), header->height());
+ QCOMPARE(static_cast<GVAccessor*>(gridview)->maxY(), header->height());
+
+ delete canvas;
+ }
+ {
+ // Horizontal
+ QQuickView *canvas = createView();
+
+ QmlListModel model;
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(testFileUrl("headerfooter.qml"));
+ canvas->rootObject()->setProperty("horizontal", true);
+ qApp->processEvents();
+
+ QQuickGridView *gridview = qobject_cast<QQuickGridView*>(canvas->rootObject());
+ QTRY_VERIFY(gridview != 0);
+
+ QQuickItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->x(), -header->width());
+
+ QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->x(), 0.);
+
+ QCOMPARE(static_cast<GVAccessor*>(gridview)->minX(), header->width());
+ QCOMPARE(static_cast<GVAccessor*>(gridview)->maxX(), header->width());
+
+ delete canvas;
+ }
+ {
+ // Horizontal RTL
+ QQuickView *canvas = createView();
+
+ QmlListModel model;
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(testFileUrl("headerfooter.qml"));
+ canvas->rootObject()->setProperty("horizontal", true);
+ canvas->rootObject()->setProperty("rtl", true);
+ qApp->processEvents();
+
+ QQuickGridView *gridview = qobject_cast<QQuickGridView*>(canvas->rootObject());
+ QTRY_VERIFY(gridview != 0);
+
+ QQuickItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->x(), 0.);
+
+ QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->x(), -footer->width());
+
+ QCOMPARE(static_cast<GVAccessor*>(gridview)->minX(), 240. - header->width());
+ QCOMPARE(static_cast<GVAccessor*>(gridview)->maxX(), 240. - header->width());
+
+ delete canvas;
+ }
+ {
+ // Reset model
+ QQuickView *canvas = createView();
+
+ QaimModel model;
+ for (int i = 0; i < 6; i++)
+ model.addItem("Item" + QString::number(i), "");
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(testFileUrl("headerfooter.qml"));
+ qApp->processEvents();
+
+ QQuickGridView *gridview = qobject_cast<QQuickGridView*>(canvas->rootObject());
+ QTRY_VERIFY(gridview != 0);
+
+ QQuickItem *contentItem = gridview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->y(), -header->height());
+
+ QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->y(), 80.*2);
+
+ model.reset();
+
+ header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->y(), -header->height());
+
+ footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->y(), 80.*2);
+
+ delete canvas;
+ }
+}
+
void tst_QQuickGridView::resizeViewAndRepaint()
{
QQuickView *canvas = createView();
property bool rtl: false
width: 240
height: 320
+
+ model: testModel
orientation: horizontal ? ListView.Horizontal : ListView.Vertical
header: Rectangle {
delete canvas;
}
+ {
+ // Reset model
+ QQuickView *canvas = createView();
+
+ QaimModel model;
+ for (int i = 0; i < 4; i++)
+ model.addItem("Item" + QString::number(i), "");
+ QQmlContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("testModel", &model);
+
+ canvas->setSource(testFileUrl("headerfooter.qml"));
+ qApp->processEvents();
+
+ QQuickListView *listview = qobject_cast<QQuickListView*>(canvas->rootObject());
+ QTRY_VERIFY(listview != 0);
+
+ QQuickItem *contentItem = listview->contentItem();
+ QTRY_VERIFY(contentItem != 0);
+
+ QQuickItem *header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->y(), -header->height());
+
+ QQuickItem *footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->y(), 30.*4);
+
+ model.reset();
+
+ header = findItem<QQuickItem>(contentItem, "header");
+ QVERIFY(header);
+ QCOMPARE(header->y(), -header->height());
+
+ footer = findItem<QQuickItem>(contentItem, "footer");
+ QVERIFY(footer);
+ QCOMPARE(footer->y(), 30.*4);
+
+ delete canvas;
+ }
}
void tst_QQuickListView::resizeView()