From 0da1b076bf4e33f239ebe9dc4d8f5363ee24110b Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 27 May 2010 14:30:23 +1000 Subject: If a pathview delegate changes size, reposition center on path Task-number: QTBUG-11006 --- .../graphicsitems/qdeclarativepathview.cpp | 15 ++++++++++++++ .../graphicsitems/qdeclarativepathview_p.h | 1 + .../graphicsitems/qdeclarativepathview_p_p.h | 24 ++++++++++++++++++---- .../qdeclarativepathview/data/pathview0.qml | 6 ++++-- .../tst_qdeclarativepathview.cpp | 6 ++++++ 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 207cc25..3a69f44 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -110,6 +110,8 @@ QDeclarativeItem *QDeclarativePathViewPrivate::getItem(int modelIndex) att->setOnPath(true); } item->setParentItem(q); + QDeclarativeItemPrivate *itemPrivate = static_cast(QGraphicsItemPrivate::get(item)); + itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); } requestedIndex = -1; return item; @@ -121,6 +123,8 @@ void QDeclarativePathViewPrivate::releaseItem(QDeclarativeItem *item) return; if (QDeclarativePathViewAttached *att = attached(item)) att->setOnPath(false); + QDeclarativeItemPrivate *itemPrivate = static_cast(QGraphicsItemPrivate::get(item)); + itemPrivate->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry); model->release(item); } @@ -1084,6 +1088,16 @@ bool QDeclarativePathView::sceneEventFilter(QGraphicsItem *i, QEvent *e) return QDeclarativeItem::sceneEventFilter(i, e); } +bool QDeclarativePathView::event(QEvent *event) +{ + if (event->type() == QEvent::User) { + refill(); + return true; + } + + return QDeclarativeItem::event(event); +} + void QDeclarativePathView::componentComplete() { Q_D(QDeclarativePathView); @@ -1103,6 +1117,7 @@ void QDeclarativePathView::refill() if (!d->isValid() || !isComponentComplete()) return; + d->layoutScheduled = false; bool currentVisible = false; // first move existing items and remove items off path diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p.h index 349a01c..8a6f53f 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview_p.h +++ b/src/declarative/graphicsitems/qdeclarativepathview_p.h @@ -161,6 +161,7 @@ protected: void mouseReleaseEvent(QGraphicsSceneMouseEvent *); bool sendMouseEvent(QGraphicsSceneMouseEvent *event); bool sceneEventFilter(QGraphicsItem *, QEvent *); + bool event(QEvent *event); void componentComplete(); private Q_SLOTS: diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h index 303486f..3abb2f4 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h @@ -68,7 +68,7 @@ QT_BEGIN_NAMESPACE class QDeclarativeOpenMetaObjectType; class QDeclarativePathViewAttached; -class QDeclarativePathViewPrivate : public QDeclarativeItemPrivate +class QDeclarativePathViewPrivate : public QDeclarativeItemPrivate, public QDeclarativeItemChangeListener { Q_DECLARE_PUBLIC(QDeclarativePathView) @@ -77,7 +77,8 @@ public: : path(0), currentIndex(0), currentItemOffset(0.0), startPc(0), lastDist(0) , lastElapsed(0), mappedRange(1.0) , stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true) - , autoHighlight(true), highlightUp(false), dragMargin(0), deceleration(100) + , autoHighlight(true), highlightUp(false), layoutScheduled(false) + , dragMargin(0), deceleration(100) , moveOffset(this, &QDeclarativePathViewPrivate::setOffset) , firstIndex(-1), pathItems(-1), requestedIndex(-1) , moveReason(Other), attType(0), highlightComponent(0), highlightItem(0) @@ -89,8 +90,7 @@ public: { } - void init() - { + void init() { Q_Q(QDeclarativePathView); offset = 0; q->setAcceptedMouseButtons(Qt::LeftButton); @@ -99,6 +99,21 @@ public: q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked())); } + void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { + if ((newGeometry.size() != oldGeometry.size()) + && (!highlightItem || item != highlightItem)) { + scheduleLayout(); + } + } + + void scheduleLayout() { + Q_Q(QDeclarativePathView); + if (!layoutScheduled) { + layoutScheduled = true; + QCoreApplication::postEvent(q, new QEvent(QEvent::User), Qt::HighEventPriority); + } + } + QDeclarativeItem *getItem(int modelIndex); void releaseItem(QDeclarativeItem *item); QDeclarativePathViewAttached *attached(QDeclarativeItem *item); @@ -138,6 +153,7 @@ public: bool haveHighlightRange : 1; bool autoHighlight : 1; bool highlightUp : 1; + bool layoutScheduled : 1; QTime lastPosTime; QPointF lastPos; qreal dragMargin; diff --git a/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml b/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml index a3afd38..8956205 100644 --- a/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml +++ b/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml @@ -4,6 +4,8 @@ Rectangle { id: root property int currentA: -1 property int currentB: -1 + property real delegateWidth: 60 + property real delegateHeight: 20 width: 240 height: 320 color: "#ffffff" @@ -13,8 +15,8 @@ Rectangle { Rectangle { id: wrapper objectName: "wrapper" - height: 20 - width: 60 + height: root.delegateHeight + width: root.delegateWidth color: PathView.isCurrentItem ? "lightsteelblue" : "white" border.color: "black" Text { diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp index f32a6c7..dffc7ac 100644 --- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp +++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp @@ -445,6 +445,12 @@ void tst_QDeclarativePathView::pathMoved() pathview->setOffset(0.0); QCOMPARE(firstItem->pos() + offset, start); + // Change delegate size + canvas->rootObject()->setProperty("delegateWidth", 30); + QCOMPARE(firstItem->width(), 30.0); + offset.setX(firstItem->width()/2); + QTRY_COMPARE(firstItem->pos() + offset, start); + delete canvas; } -- cgit v0.12