Fix StackView attached property
The attached properties weren't initialized at all for the initial item. Furthermore, the properties were initialized lazily, which made them work for imperative tests, but not correctly in bindings. Change-Id: I783c406dcf4e1cf27a6b4e6ddd43214cb06a3c7a Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
This commit is contained in:
parent
9d4c627821
commit
aa634f8642
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue