diff options
-rw-r--r-- | src/templates/qquickstackview.cpp | 44 | ||||
-rw-r--r-- | src/templates/qquickstackview_p.cpp | 28 | ||||
-rw-r--r-- | src/templates/qquickstackview_p.h | 1 | ||||
-rw-r--r-- | src/templates/qquickstackview_p_p.h | 8 | ||||
-rw-r--r-- | tests/auto/controls/data/tst_stackview.qml | 35 |
5 files changed, 75 insertions, 41 deletions
diff --git a/src/templates/qquickstackview.cpp b/src/templates/qquickstackview.cpp index 4439e176..1883d9d0 100644 --- a/src/templates/qquickstackview.cpp +++ b/src/templates/qquickstackview.cpp @@ -673,6 +673,7 @@ void QQuickStackView::componentComplete() if (d->pushElement(element)) { emit depthChanged(); d->setCurrentItem(element->item); + element->setStatus(QQuickStackView::Active); } } @@ -702,39 +703,40 @@ bool QQuickStackView::childMouseEventFilter(QQuickItem *, QEvent *) return true; } -void QQuickStackAttachedPrivate::init() -{ - QQuickItem *item = qobject_cast<QQuickItem *>(parent); - if (item) { - QQuickStackView *view = qobject_cast<QQuickStackView *>(item->parentItem()); - if (view) { - element = QQuickStackViewPrivate::get(view)->findElement(item); - if (element) - initialized = true; - } - } -} - -void QQuickStackAttachedPrivate::reset() +void QQuickStackAttachedPrivate::itemParentChanged(QQuickItem *item, QQuickItem *parent) { Q_Q(QQuickStackAttached); int oldIndex = element ? element->index : -1; QQuickStackView *oldView = element ? element->view : Q_NULLPTR; QQuickStackView::Status oldStatus = element ? element->status : QQuickStackView::Inactive; - element = Q_NULLPTR; + QQuickStackView *newView = qobject_cast<QQuickStackView *>(parent); + element = newView ? QQuickStackViewPrivate::get(newView)->findElement(item) : Q_NULLPTR; - if (oldIndex != -1) + int newIndex = element ? element->index : -1; + QQuickStackView::Status newStatus = element ? element->status : QQuickStackView::Inactive; + + if (oldIndex != newIndex) emit q->indexChanged(); - if (oldView) + if (oldView != newView) emit q->viewChanged(); - if (oldStatus != QQuickStackView::Inactive) + if (oldStatus != newStatus) emit q->statusChanged(); } QQuickStackAttached::QQuickStackAttached(QQuickItem *parent) : QObject(*(new QQuickStackAttachedPrivate), parent) { + Q_D(QQuickStackAttached); + QQuickItemPrivate::get(parent)->addItemChangeListener(d, QQuickItemPrivate::Parent); + d->itemParentChanged(parent, parent->parentItem()); +} + +QQuickStackAttached::~QQuickStackAttached() +{ + Q_D(QQuickStackAttached); + QQuickItem *parentItem = static_cast<QQuickItem *>(parent()); + QQuickItemPrivate::get(parentItem)->removeItemChangeListener(d, QQuickItemPrivate::Parent); } /*! @@ -745,8 +747,6 @@ QQuickStackAttached::QQuickStackAttached(QQuickItem *parent) : int QQuickStackAttached::index() const { Q_D(const QQuickStackAttached); - if (!d->initialized) - const_cast<QQuickStackAttachedPrivate *>(d)->init(); return d->element ? d->element->index : -1; } @@ -758,8 +758,6 @@ int QQuickStackAttached::index() const QQuickStackView *QQuickStackAttached::view() const { Q_D(const QQuickStackAttached); - if (!d->initialized) - const_cast<QQuickStackAttachedPrivate *>(d)->init(); return d->element ? d->element->view : Q_NULLPTR; } @@ -771,8 +769,6 @@ QQuickStackView *QQuickStackAttached::view() const QQuickStackView::Status QQuickStackAttached::status() const { Q_D(const QQuickStackAttached); - if (!d->initialized) - const_cast<QQuickStackAttachedPrivate *>(d)->init(); return d->element ? d->element->status : QQuickStackView::Inactive; } diff --git a/src/templates/qquickstackview_p.cpp b/src/templates/qquickstackview_p.cpp index 498cc44c..a66e7d21 100644 --- a/src/templates/qquickstackview_p.cpp +++ b/src/templates/qquickstackview_p.cpp @@ -48,9 +48,12 @@ QT_BEGIN_NAMESPACE -static QQuickStackAttached *attachedStackObject(QQuickItem *item) +static QQuickStackAttached *attachedStackObject(QQuickStackElement *element) { - return qobject_cast<QQuickStackAttached *>(qmlAttachedPropertiesObject<QQuickStackView>(item, false)); + QQuickStackAttached *attached = qobject_cast<QQuickStackAttached *>(qmlAttachedPropertiesObject<QQuickStackView>(element->item, false)); + if (attached) + QQuickStackAttachedPrivate::get(attached)->element = element; + return attached; } class QQuickStackIncubator : public QQmlIncubator @@ -74,14 +77,9 @@ QQuickStackElement::QQuickStackElement() : QQuickItemViewTransitionableItem(Q_NU QQuickStackElement::~QQuickStackElement() { - if (item) { + if (item) QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed); - QQuickStackAttached *attached = attachedStackObject(item); - if (attached) - QQuickStackAttachedPrivate::get(attached)->reset(); - } - if (ownComponent) delete component; @@ -91,7 +89,13 @@ QQuickStackElement::~QQuickStackElement() item = Q_NULLPTR; } else if (item) { item->setVisible(false); - item->setParentItem(originalParent); + if (item->parentItem() != originalParent) { + item->setParentItem(originalParent); + } else { + QQuickStackAttached *attached = attachedStackObject(this); + if (attached) + QQuickStackAttachedPrivate::get(attached)->itemParentChanged(item, Q_NULLPTR); + } } delete context; @@ -182,7 +186,7 @@ void QQuickStackElement::setIndex(int value) { if (index != value) { index = value; - QQuickStackAttached *attached = attachedStackObject(item); + QQuickStackAttached *attached = attachedStackObject(this); if (attached) emit attached->indexChanged(); } @@ -192,7 +196,7 @@ void QQuickStackElement::setView(QQuickStackView *value) { if (view != value) { view = value; - QQuickStackAttached *attached = attachedStackObject(item); + QQuickStackAttached *attached = attachedStackObject(this); if (attached) emit attached->viewChanged(); } @@ -202,7 +206,7 @@ void QQuickStackElement::setStatus(QQuickStackView::Status value) { if (status != value) { status = value; - QQuickStackAttached *attached = attachedStackObject(item); + QQuickStackAttached *attached = attachedStackObject(this); if (attached) emit attached->statusChanged(); } diff --git a/src/templates/qquickstackview_p.h b/src/templates/qquickstackview_p.h index a530738a..7f989faf 100644 --- a/src/templates/qquickstackview_p.h +++ b/src/templates/qquickstackview_p.h @@ -157,6 +157,7 @@ class Q_LABSTEMPLATES_EXPORT QQuickStackAttached : public QObject public: explicit QQuickStackAttached(QQuickItem *parent = Q_NULLPTR); + ~QQuickStackAttached(); int index() const; QQuickStackView *view() const; diff --git a/src/templates/qquickstackview_p_p.h b/src/templates/qquickstackview_p_p.h index 39a57a5d..5dfe7037 100644 --- a/src/templates/qquickstackview_p_p.h +++ b/src/templates/qquickstackview_p_p.h @@ -139,22 +139,20 @@ public: QQuickItemViewTransitioner *transitioner; }; -class QQuickStackAttachedPrivate : public QObjectPrivate +class QQuickStackAttachedPrivate : public QObjectPrivate, public QQuickItemChangeListener { Q_DECLARE_PUBLIC(QQuickStackAttached) public: - QQuickStackAttachedPrivate() : initialized(false), element(Q_NULLPTR) { } + QQuickStackAttachedPrivate() : element(Q_NULLPTR) { } static QQuickStackAttachedPrivate *get(QQuickStackAttached *attached) { return attached->d_func(); } - void init(); - void reset(); + void itemParentChanged(QQuickItem *item, QQuickItem *parent); - bool initialized; QQuickStackElement *element; }; diff --git a/tests/auto/controls/data/tst_stackview.qml b/tests/auto/controls/data/tst_stackview.qml index f54cd9ae..3dc6d0c9 100644 --- a/tests/auto/controls/data/tst_stackview.qml +++ b/tests/auto/controls/data/tst_stackview.qml @@ -540,4 +540,39 @@ TestCase { control.destroy() } + + Component { + id: attachedItem + Item { + property int index: StackView.index + property StackView view: StackView.view + property int status: StackView.status + } + } + + function test_attached() { + var control = stackView.createObject(testCase, {initialItem: attachedItem}) + + compare(control.get(0).index, 0) + compare(control.get(0).view, control) + compare(control.get(0).status, StackView.Active) + + control.push(attachedItem, StackView.Immediate) + + compare(control.get(0).index, 0) + compare(control.get(0).view, control) + compare(control.get(0).status, StackView.Inactive) + + compare(control.get(1).index, 1) + compare(control.get(1).view, control) + compare(control.get(1).status, StackView.Active) + + control.pop(StackView.Immediate) + + compare(control.get(0).index, 0) + compare(control.get(0).view, control) + compare(control.get(0).status, StackView.Active) + + control.destroy() + } } |