aboutsummaryrefslogtreecommitdiffstats
path: root/src/controls
diff options
context:
space:
mode:
Diffstat (limited to 'src/controls')
-rw-r--r--src/controls/controls.pri2
-rw-r--r--src/controls/qquickabstractstackview.cpp565
-rw-r--r--src/controls/qquickabstractstackview_p.cpp507
-rw-r--r--src/controls/qquickabstractstackview_p.h84
-rw-r--r--src/controls/qquickabstractstackview_p_p.h158
5 files changed, 1108 insertions, 208 deletions
diff --git a/src/controls/controls.pri b/src/controls/controls.pri
index b1d2a0ea..aea9b06f 100644
--- a/src/controls/controls.pri
+++ b/src/controls/controls.pri
@@ -20,6 +20,7 @@ HEADERS += \
$$PWD/qquickabstractscrollindicator_p.h \
$$PWD/qquickabstractslider_p.h \
$$PWD/qquickabstractstackview_p.h \
+ $$PWD/qquickabstractstackview_p_p.h \
$$PWD/qquickabstractswitch_p.h \
$$PWD/qquickabstracttabbar_p.h \
$$PWD/qquickabstracttabbutton_p.h \
@@ -49,6 +50,7 @@ SOURCES += \
$$PWD/qquickabstractscrollindicator.cpp \
$$PWD/qquickabstractslider.cpp \
$$PWD/qquickabstractstackview.cpp \
+ $$PWD/qquickabstractstackview_p.cpp \
$$PWD/qquickabstractswitch.cpp \
$$PWD/qquickabstracttabbar.cpp \
$$PWD/qquickabstracttabbutton.cpp \
diff --git a/src/controls/qquickabstractstackview.cpp b/src/controls/qquickabstractstackview.cpp
index a849bd94..e5496697 100644
--- a/src/controls/qquickabstractstackview.cpp
+++ b/src/controls/qquickabstractstackview.cpp
@@ -35,7 +35,10 @@
****************************************************************************/
#include "qquickabstractstackview_p.h"
-#include "qquickabstractcontainer_p_p.h"
+#include "qquickabstractstackview_p_p.h"
+
+#include <QtQml/qjsvalue.h>
+#include <QtQml/qqmlengine.h>
QT_BEGIN_NAMESPACE
@@ -50,243 +53,407 @@ QT_BEGIN_NAMESPACE
TODO
*/
-class QQuickStackElement
+QQuickAbstractStackView::QQuickAbstractStackView(QQuickItem *parent) :
+ QQuickAbstractContainer(*(new QQuickAbstractStackViewPrivate), parent)
{
- QQuickStackElement() : ownItem(false), item(Q_NULLPTR), ownComponent(false), component(Q_NULLPTR) { }
-
-public:
- static QQuickStackElement *fromString(const QString &str, QQmlEngine *engine, QObject *parent)
- {
- QQuickStackElement *element = new QQuickStackElement;
- element->component = new QQmlComponent(engine, QUrl(str), parent);
- element->ownComponent = true;
- return element;
- }
+ setFlag(ItemIsFocusScope);
+}
- static QQuickStackElement *fromObject(QObject *object)
- {
- QQuickStackElement *element = new QQuickStackElement;
- element->component = qobject_cast<QQmlComponent *>(object);
- element->item = qobject_cast<QQuickItem *>(object);
- return element;
+QQuickAbstractStackView::~QQuickAbstractStackView()
+{
+ Q_D(QQuickAbstractStackView);
+ if (d->transitioner) {
+ d->transitioner->setChangeListener(Q_NULLPTR);
+ delete d->transitioner;
}
+ qDeleteAll(d->elements);
+}
- bool ownItem;
- QQuickItem *item;
-
- bool ownComponent;
- QQmlComponent *component;
-};
+QQuickStackAttached *QQuickAbstractStackView::qmlAttachedProperties(QObject *object)
+{
+ QQuickItem *item = qobject_cast<QQuickItem *>(object);
+ if (!item) {
+ qmlInfo(object) << "StackView must be attached to an Item";
+ return Q_NULLPTR;
+ }
+ return new QQuickStackAttached(item);
+}
-class QQuickAbstractStackViewPrivate : public QQuickAbstractContainerPrivate
+/*!
+ \qmlproperty bool QtQuickControls2::StackView::busy
+ \readonly
+ This property holds whether a transition is running.
+*/
+bool QQuickAbstractStackView::busy() const
{
- Q_DECLARE_PUBLIC(QQuickAbstractStackView)
+ Q_D(const QQuickAbstractStackView);
+ return d->transitioner && !d->transitioner->runningJobs.isEmpty();
+}
-public:
- QQuickAbstractStackViewPrivate() : busy(false), depth(0), currentItem(Q_NULLPTR) { }
+/*!
+ \qmlproperty int QtQuickControls2::StackView::depth
+ \readonly
+ This property holds the number of items currently pushed onto the stack.
+*/
+int QQuickAbstractStackView::depth() const
+{
+ Q_D(const QQuickAbstractStackView);
+ return d->elements.count();
+}
- void setBusy(bool busy);
- void setDepth(int depth);
- void setCurrentItem(QQuickItem *item);
+/*!
+ \qmlproperty Item QtQuickControls2::StackView::currentItem
+ \readonly
+ This property holds the current top-most item in the stack.
+*/
+QQuickItem *QQuickAbstractStackView::currentItem() const
+{
+ Q_D(const QQuickAbstractStackView);
+ return d->currentItem;
+}
- QList<QQuickStackElement *> createElements(const QV4::ScopedValue &value);
- QQuickItem *pushElements(const QList<QQuickStackElement *> &elements, QQuickAbstractStackView::Operation operation);
+/*!
+ \qmlmethod Item QtQuickControls2::StackView::get(index, behavior = DontLoad)
- bool busy;
- int depth;
- QVariant initialItem;
- QQuickItem *currentItem;
- QStack<QQuickStackElement *> elements;
-};
+ Supported behavior values:
+ \li StackView.DontLoad
+ \li StackView.ForceLoad
-void QQuickAbstractStackViewPrivate::setBusy(bool value)
+ TODO
+*/
+QQuickItem *QQuickAbstractStackView::get(int index, LoadBehavior behavior)
{
- Q_Q(QQuickAbstractStackView);
- if (busy != value) {
- busy = value;
- emit q->busyChanged();
+ Q_D(QQuickAbstractStackView);
+ QQuickStackElement *element = d->elements.value(index);
+ if (element) {
+ if (behavior == ForceLoad)
+ element->load(this);
+ return element->item;
}
+ return Q_NULLPTR;
}
-void QQuickAbstractStackViewPrivate::setDepth(int value)
+/*!
+ \qmlmethod Item QtQuickControls2::StackView::find(callback, behavior = DontLoad)
+
+ Supported behavior values:
+ \li StackView.DontLoad
+ \li StackView.ForceLoad
+
+ TODO
+*/
+QQuickItem *QQuickAbstractStackView::find(const QJSValue &callback, LoadBehavior behavior)
{
- Q_Q(QQuickAbstractStackView);
- if (depth != value) {
- depth = value;
- emit q->depthChanged();
+ Q_D(QQuickAbstractStackView);
+ QJSValue func(callback);
+ QQmlEngine *engine = qmlEngine(this);
+ if (!engine || !func.isCallable()) // TODO: warning?
+ return Q_NULLPTR;
+
+ for (int i = d->elements.count() - 1; i >= 0; --i) {
+ QQuickStackElement *element = d->elements.at(i);
+ if (behavior == ForceLoad)
+ element->load(this);
+ if (element->item) {
+ QJSValue rv = func.call(QJSValueList() << engine->newQObject(element->item) << i);
+ if (rv.toBool())
+ return element->item;
+ }
}
+
+ return Q_NULLPTR;
}
-void QQuickAbstractStackViewPrivate::setCurrentItem(QQuickItem *item)
+/*!
+ \qmlmethod Item QtQuickControls2::StackView::push(item, properties, operation)
+
+ TODO
+*/
+void QQuickAbstractStackView::push(QQmlV4Function *args)
{
- Q_Q(QQuickAbstractStackView);
- if (currentItem != item) {
- currentItem = item;
- emit q->currentItemChanged();
+ Q_D(QQuickAbstractStackView);
+ if (args->length() <= 0) {
+ qmlInfo(this) << "push: missing arguments";
+ args->setReturnValue(QV4::Encode::null());
+ return;
}
-}
-QList<QQuickStackElement *> QQuickAbstractStackViewPrivate::createElements(const QV4::ScopedValue &value)
-{
- Q_Q(QQuickAbstractStackView);
- QList<QQuickStackElement *> elements;
- if (QV4::String *s = value->asString()) {
- qDebug() << "### STRING:" << s->toQString();
- elements += QQuickStackElement::fromString(s->toQString(), qmlEngine(q), q);
- } else if (QV4::ArrayObject *a = value->asArrayObject()) {
- int len = a->getLength();
- qDebug() << "### ARRAY:" << len;
- for (int i = 0; i < len; ++i) {
- QV4::Scope scope(a->engine());
- QV4::ScopedValue v(scope, a->getIndexed(i));
- elements += createElements(v);
- }
- } else if (const QV4::QObjectWrapper *o =value->as<QV4::QObjectWrapper>()) {
- qDebug() << "### QOBJECT:" << o->object();
- elements += QQuickStackElement::fromObject(o->object());
+ QV4::ExecutionEngine *v4 = args->v4engine();
+ QV4::Scope scope(v4);
+
+ Operation operation = d->elements.isEmpty() ? Immediate : Transition;
+ QV4::ScopedValue lastArg(scope, (*args)[args->length() - 1]);
+ if (lastArg->isInt32())
+ operation = static_cast<Operation>(lastArg->toInt32());
+
+ QList<QQuickStackElement *> elements = d->parseElements(args);
+ if (elements.isEmpty()) {
+ qmlInfo(this) << "push: nothing to push";
+ args->setReturnValue(QV4::Encode::null());
+ return;
+ }
+
+ QQuickStackElement *exit = Q_NULLPTR;
+ if (!d->elements.isEmpty())
+ exit = d->elements.top();
+
+ if (d->pushElements(elements)) {
+ emit depthChanged();
+ QQuickStackElement *enter = d->elements.top();
+ d->pushTransition(enter, exit, boundingRect(), operation == Immediate);
+ d->setCurrentItem(enter->item);
+ }
+
+ if (d->currentItem) {
+ QV4::ScopedValue rv(scope, QV4::QObjectWrapper::wrap(v4, d->currentItem));
+ args->setReturnValue(rv->asReturnedValue());
} else {
- qDebug("### UNKNOWN");
+ args->setReturnValue(QV4::Encode::null());
}
- return elements;
}
-QQuickItem *QQuickAbstractStackViewPrivate::pushElements(const QList<QQuickStackElement *> &elems, QQuickAbstractStackView::Operation operation)
+/*!
+ \qmlmethod Item QtQuickControls2::StackView::pop(item = null, operation = Transition)
+
+ TODO
+*/
+void QQuickAbstractStackView::pop(QQmlV4Function *args)
{
- Q_Q(QQuickAbstractStackView);
- Q_UNUSED(operation); // TODO
- if (!elems.isEmpty()) {
- foreach (QQuickStackElement *elem, elems) {
- elements.push(elem);
+ Q_D(QQuickAbstractStackView);
+ int argc = args->length();
+ if (d->elements.count() <= 1 || argc > 2) {
+ if (argc > 2)
+ qmlInfo(this) << "pop: too many arguments";
+ args->setReturnValue(QV4::Encode::null());
+ return;
+ }
+
+ QQuickStackElement *exit = d->elements.pop();
+ QQuickStackElement *enter = d->elements.top();
+
+ QV4::ExecutionEngine *v4 = args->v4engine();
+ QV4::Scope scope(v4);
+
+ if (argc > 0) {
+ QV4::ScopedValue value(scope, (*args)[0]);
+ if (value->isNull()) {
+ enter = d->elements.value(0);
+ } else if (!value->isUndefined() && !value->isInt32()) {
+ enter = d->findElement(value);
+ if (!enter) {
+ qmlInfo(this) << "pop: unknown argument: " << value->toQString(); // TODO: safe?
+ args->setReturnValue(QV4::Encode::null());
+ d->elements.push(exit); // restore
+ return;
+ }
}
- emit q->depthChanged();
- // TODO: load
- return elems.last()->item;
}
- return Q_NULLPTR;
+
+ Operation operation = Transition;
+ if (argc > 0) {
+ QV4::ScopedValue lastArg(scope, (*args)[argc - 1]);
+ if (lastArg->isInt32())
+ operation = static_cast<Operation>(lastArg->toInt32());
+ }
+
+ QQuickItem *previousItem = Q_NULLPTR;
+
+ if (d->popElements(enter)) {
+ if (exit)
+ previousItem = exit->item;
+ emit depthChanged();
+ d->popTransition(enter, exit, boundingRect(), operation == Immediate);
+ d->setCurrentItem(enter->item);
+ }
+
+ if (previousItem) {
+ QV4::ScopedValue rv(scope, QV4::QObjectWrapper::wrap(v4, previousItem));
+ args->setReturnValue(rv->asReturnedValue());
+ } else {
+ args->setReturnValue(QV4::Encode::null());
+ }
}
-QQuickAbstractStackView::QQuickAbstractStackView(QQuickItem *parent) :
- QQuickAbstractContainer(*(new QQuickAbstractStackViewPrivate), parent)
+/*!
+ \qmlmethod Item QtQuickControls2::StackView::push(item, properties, operation = Transition)
+
+ TODO
+*/
+void QQuickAbstractStackView::replace(QQmlV4Function *args)
{
- setFlag(ItemIsFocusScope);
+ Q_D(QQuickAbstractStackView);
+ if (args->length() <= 0) {
+ qmlInfo(this) << "replace: missing arguments";
+ args->setReturnValue(QV4::Encode::null());
+ return;
+ }
+
+ QV4::ExecutionEngine *v4 = args->v4engine();
+ QV4::Scope scope(v4);
+
+ Operation operation = d->elements.isEmpty() ? Immediate : Transition;
+ QV4::ScopedValue lastArg(scope, (*args)[args->length() - 1]);
+ if (lastArg->isInt32())
+ operation = static_cast<Operation>(lastArg->toInt32());
+
+ QQuickStackElement *target = Q_NULLPTR;
+ QV4::ScopedValue firstArg(scope, (*args)[0]);
+ if (firstArg->isNull())
+ target = d->elements.value(0);
+ else if (!firstArg->isInt32())
+ target = d->findElement(firstArg);
+
+ QList<QQuickStackElement *> elements = d->parseElements(args, target ? 1 : 0);
+ if (elements.isEmpty()) {
+ qmlInfo(this) << "replace: nothing to push";
+ args->setReturnValue(QV4::Encode::null());
+ return;
+ }
+
+ int depth = d->elements.count();
+ QQuickStackElement* exit = Q_NULLPTR;
+ if (!d->elements.isEmpty())
+ exit = d->elements.pop();
+
+ if (d->replaceElements(target, elements)) {
+ if (depth != d->elements.count())
+ emit depthChanged();
+ QQuickStackElement *enter = d->elements.top();
+ d->replaceTransition(enter, exit, boundingRect(), operation == Immediate);
+ d->setCurrentItem(enter->item);
+ }
+
+ if (d->currentItem) {
+ QV4::ScopedValue rv(scope, QV4::QObjectWrapper::wrap(v4, d->currentItem));
+ args->setReturnValue(rv->asReturnedValue());
+ } else {
+ args->setReturnValue(QV4::Encode::null());
+ }
}
-QQuickAbstractStackView::~QQuickAbstractStackView()
+/*!
+ \qmlmethod Item QtQuickControls2::StackView::clear()
+
+ TODO
+*/
+void QQuickAbstractStackView::clear()
{
Q_D(QQuickAbstractStackView);
+ d->setCurrentItem(Q_NULLPTR);
qDeleteAll(d->elements);
+ d->elements.clear();
+ emit depthChanged();
}
/*!
- \qmlproperty bool QtQuickControls2::StackView::busy
- \readonly
- \c true if a transition is running, and \c false otherwise.
+ \qmlproperty var QtQuickControls2::StackView::initialItem
+
+ This property holds the initial item.
+
+ \sa push()
*/
-bool QQuickAbstractStackView::busy() const
+QVariant QQuickAbstractStackView::initialItem() const
{
Q_D(const QQuickAbstractStackView);
- return d->busy;
+ return d->initialItem;
}
-// TODO: remove
-void QQuickAbstractStackView::setBusy(bool busy)
+void QQuickAbstractStackView::setInitialItem(const QVariant &item)
{
Q_D(QQuickAbstractStackView);
- d->setBusy(busy);
+ d->initialItem = item;
}
/*!
- \qmlproperty int QtQuickControls2::StackView::depth
- \readonly
- The number of items currently pushed onto the stack.
+ \qmlproperty Transition QtQuickControls2::StackView::popEnter
+
+ TODO
*/
-int QQuickAbstractStackView::depth() const
+QQuickTransition *QQuickAbstractStackView::popEnter() const
{
Q_D(const QQuickAbstractStackView);
- return d->depth;
+ if (d->transitioner)
+ return d->transitioner->removeDisplacedTransition;
+ return Q_NULLPTR;
}
-// TODO: remove
-void QQuickAbstractStackView::setDepth(int depth)
+void QQuickAbstractStackView::setPopEnter(QQuickTransition *enter)
{
Q_D(QQuickAbstractStackView);
- d->setDepth(depth);
+ d->ensureTransitioner();
+ if (d->transitioner->removeDisplacedTransition != enter) {
+ d->transitioner->removeDisplacedTransition = enter;
+ emit popEnterChanged();
+ }
}
/*!
- \qmlproperty Item QtQuickControls2::StackView::currentItem
- \readonly
- The currently top-most item in the stack.
+ \qmlproperty Transition QtQuickControls2::StackView::popExit
+
+ TODO
*/
-QQuickItem *QQuickAbstractStackView::currentItem() const
+QQuickTransition *QQuickAbstractStackView::popExit() const
{
Q_D(const QQuickAbstractStackView);
- return d->currentItem;
-}
-
-// TODO: remove
-void QQuickAbstractStackView::setCurrentItem(QQuickItem *item)
-{
- Q_D(QQuickAbstractStackView);
- d->setCurrentItem(item);
+ if (d->transitioner)
+ return d->transitioner->removeTransition;
+ return Q_NULLPTR;
}
-QQuickItem *QQuickAbstractStackView::qpush(QQmlV4Function *args)
+void QQuickAbstractStackView::setPopExit(QQuickTransition *exit)
{
Q_D(QQuickAbstractStackView);
- QV4::ExecutionEngine *v4 = args->v4engine();
- QV4::Scope scope(v4);
-
- Operation operation = d->elements.isEmpty() ? Immediate : Transition;
- QList<QQuickStackElement *> elements;
- for (int i = 0; i < args->length(); ++i) {
- QV4::ScopedValue value(scope, (*args)[i]);
- if (value->isInt32())
- operation = static_cast<Operation>(value->toInt32());
- else
- elements += d->createElements(value);
+ d->ensureTransitioner();
+ if (d->transitioner->removeTransition != exit) {
+ d->transitioner->removeTransition = exit;
+ emit popExitChanged();
}
- return d->pushElements(elements, operation);
}
-QQuickItem *QQuickAbstractStackView::qpop(QQmlV4Function *args)
+/*!
+ \qmlproperty Transition QtQuickControls2::StackView::pushEnter
+
+ TODO
+*/
+QQuickTransition *QQuickAbstractStackView::pushEnter() const
{
- Q_UNUSED(args); // TODO
+ Q_D(const QQuickAbstractStackView);
+ if (d->transitioner)
+ return d->transitioner->addTransition;
return Q_NULLPTR;
}
-void QQuickAbstractStackView::qclear()
+void QQuickAbstractStackView::setPushEnter(QQuickTransition *enter)
{
- // TODO
+ Q_D(QQuickAbstractStackView);
+ d->ensureTransitioner();
+ if (d->transitioner->addTransition != enter) {
+ d->transitioner->addTransition = enter;
+ emit pushEnterChanged();
+ }
}
/*!
- \qmlproperty var QtQuickControls2::StackView::initialItem
-
- The first \l item that should be shown when the StackView is created.
- \a initialItem can take same value as the first argument to \l{StackView::push()}
- {StackView.push()}. Note that this is just a convenience for writing
- \c{Component.onCompleted: stackView.push(myInitialItem)}
-
- Examples:
+ \qmlproperty Transition QtQuickControls2::StackView::pushExit
- \list
- \li initialItem: Qt.resolvedUrl("MyItem.qml")
- \li initialItem: myItem
- \li initialItem: {"item" : Qt.resolvedUrl("MyRectangle.qml"), "properties" : {"color" : "red"}}
- \endlist
- \sa push
+ TODO
*/
-QVariant QQuickAbstractStackView::initialItem() const
+QQuickTransition *QQuickAbstractStackView::pushExit() const
{
Q_D(const QQuickAbstractStackView);
- return d->initialItem;
+ if (d->transitioner)
+ return d->transitioner->addDisplacedTransition;
+ return Q_NULLPTR;
}
-void QQuickAbstractStackView::setInitialItem(const QVariant &item)
+void QQuickAbstractStackView::setPushExit(QQuickTransition *exit)
{
Q_D(QQuickAbstractStackView);
- d->initialItem = item;
+ d->ensureTransitioner();
+ if (d->transitioner->addDisplacedTransition != exit) {
+ d->transitioner->addDisplacedTransition = exit;
+ emit pushExitChanged();
+ }
}
void QQuickAbstractStackView::componentComplete()
@@ -294,59 +461,93 @@ void QQuickAbstractStackView::componentComplete()
QQuickAbstractContainer::componentComplete();
Q_D(QQuickAbstractStackView);
+ QQuickStackElement *element = Q_NULLPTR;
if (QObject *o = d->initialItem.value<QObject *>())
- d->pushElements(QList<QQuickStackElement *>() << QQuickStackElement::fromObject(o), Immediate);
+ element = QQuickStackElement::fromObject(o, this);
else if (d->initialItem.canConvert<QString>())
- d->pushElements(QList<QQuickStackElement *>() << QQuickStackElement::fromString(d->initialItem.toString(), qmlEngine(this), this), Immediate);
+ element = QQuickStackElement::fromString(d->initialItem.toString(), this);
+ if (d->pushElement(element)) {
+ emit depthChanged();
+ d->setCurrentItem(element->item);
+ }
}
-/*!
- \qmltype Stack
- \inherits QtObject
- \instantiates QQuickStackAttached
- \inqmlmodule QtQuick.Controls
- \ingroup navigation
- \brief TODO
+void QQuickAbstractStackView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ QQuickAbstractContainer::geometryChanged(newGeometry, oldGeometry);
- TODO
-*/
+ Q_D(QQuickAbstractStackView);
+ foreach (QQuickStackElement *element, d->elements) {
+ if (element->item) {
+ QQuickItemPrivate *p = QQuickItemPrivate::get(element->item);
+ if (!p->widthValid) {
+ element->item->setWidth(newGeometry.width());
+ p->widthValid = false;
+ }
+ if (!p->heightValid) {
+ element->item->setHeight(newGeometry.height());
+ p->heightValid = false;
+ }
+ }
+ }
+}
-class QQuickStackAttachedPrivate : public QObjectPrivate
+void QQuickStackAttachedPrivate::init()
{
-public:
- QQuickStackAttachedPrivate() : status(QQuickStackAttached::Inactive) { }
-
- QQuickStackAttached::Status status;
-};
+ QQuickItem *item = qobject_cast<QQuickItem *>(parent);
+ if (item) {
+ QQuickAbstractStackView *view = qobject_cast<QQuickAbstractStackView *>(item->parentItem());
+ if (view) {
+ element = QQuickAbstractStackViewPrivate::get(view)->findElement(item);
+ if (element)
+ initialized = true;
+ }
+ }
+}
-QQuickStackAttached::QQuickStackAttached(QObject *parent) :
- QObject(*(new QQuickStackAttachedPrivate), parent)
+void QQuickStackAttachedPrivate::reset()
{
+ Q_Q(QQuickStackAttached);
+ int oldIndex = element ? element->index : -1;
+ QQuickAbstractStackView::Status oldStatus = element ? element->status : QQuickAbstractStackView::Inactive;
+
+ element = Q_NULLPTR;
+
+ if (oldIndex != -1)
+ emit q->indexChanged();
+ if (oldStatus != QQuickAbstractStackView::Inactive)
+ emit q->statusChanged();
}
-QQuickStackAttached *QQuickStackAttached::qmlAttachedProperties(QObject *object)
+QQuickStackAttached::QQuickStackAttached(QQuickItem *parent) :
+ QObject(*(new QQuickStackAttachedPrivate), parent)
{
- return new QQuickStackAttached(object);
}
/*!
- \qmlattachedproperty enumeration QtQuickControls2::Stack::status
+ \qmlattachedproperty int QtQuickControls2::StackView::index
TODO
*/
-QQuickStackAttached::Status QQuickStackAttached::status() const
+int QQuickStackAttached::index() const
{
Q_D(const QQuickStackAttached);
- return d->status;
+ if (!d->initialized)
+ const_cast<QQuickStackAttachedPrivate *>(d)->init();
+ return d->element ? d->element->index : -1;
}
-void QQuickStackAttached::setStatus(Status status)
+/*!
+ \qmlattachedproperty enumeration QtQuickControls2::StackView::status
+
+ TODO
+*/
+QQuickAbstractStackView::Status QQuickStackAttached::status() const
{
- Q_D(QQuickStackAttached);
- if (d->status != status) {
- d->status = status;
- emit statusChanged();
- }
+ Q_D(const QQuickStackAttached);
+ if (!d->initialized)
+ const_cast<QQuickStackAttachedPrivate *>(d)->init();
+ return d->element ? d->element->status : QQuickAbstractStackView::Inactive;
}
QT_END_NAMESPACE
diff --git a/src/controls/qquickabstractstackview_p.cpp b/src/controls/qquickabstractstackview_p.cpp
new file mode 100644
index 00000000..76061461
--- /dev/null
+++ b/src/controls/qquickabstractstackview_p.cpp
@@ -0,0 +1,507 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickabstractstackview_p_p.h"
+
+#include <QtQml/qqmllist.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQml/qqmlincubator.h>
+#include <QtQml/private/qqmlcomponent_p.h>
+#include <QtQuick/private/qquickanimation_p.h>
+#include <QtQuick/private/qquicktransition_p.h>
+#include <QtQuick/private/qquickitemviewtransition_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static QQuickStackAttached *attachedStackObject(QQuickItem *item)
+{
+ return qobject_cast<QQuickStackAttached *>(qmlAttachedPropertiesObject<QQuickAbstractStackView>(item, false));
+}
+
+class QQuickStackIncubator : public QQmlIncubator
+{
+public:
+ QQuickStackIncubator(QQuickStackElement *element) : QQmlIncubator(Synchronous), element(element) { }
+
+protected:
+ void setInitialState(QObject *object) Q_DECL_OVERRIDE { element->initItem(object); }
+
+private:
+ QQuickStackElement *element;
+};
+
+QQuickStackElement::QQuickStackElement() : QQuickItemViewTransitionableItem(Q_NULLPTR),
+ index(-1), removal(false), ownItem(false), ownComponent(false),
+ context(Q_NULLPTR), component(Q_NULLPTR), incubator(Q_NULLPTR), view(Q_NULLPTR),
+ status(QQuickAbstractStackView::Inactive)
+{
+}
+
+QQuickStackElement::~QQuickStackElement()
+{
+ if (item) {
+ QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed);
+
+ QQuickStackAttached *attached = attachedStackObject(item);
+ if (attached)
+ QQuickStackAttachedPrivate::get(attached)->reset();
+ }
+
+ if (ownComponent)
+ delete component;
+
+ if (ownItem && item) {
+ item->setParentItem(Q_NULLPTR);
+ item->deleteLater();
+ item = Q_NULLPTR;
+ } else if (item) {
+ item->setVisible(false);
+ item->setParentItem(originalParent);
+ }
+
+ delete context;
+ delete incubator;
+}
+
+QQuickStackElement *QQuickStackElement::fromString(const QString &str, QQuickAbstractStackView *view)
+{
+ QQuickStackElement *element = new QQuickStackElement;
+ element->component = new QQmlComponent(qmlEngine(view), QUrl(str), view);
+ element->ownComponent = true;
+ return element;
+}
+
+QQuickStackElement *QQuickStackElement::fromObject(QObject *object, QQuickAbstractStackView *view)
+{
+ QQuickStackElement *element = new QQuickStackElement;
+ element->component = qobject_cast<QQmlComponent *>(object);
+ if (!element->component) {
+ element->component = new QQmlComponent(qmlEngine(view), view);
+ element->ownComponent = true;
+ }
+ element->item = qobject_cast<QQuickItem *>(object);
+ if (element->item) {
+ element->originalParent = element->item->parentItem();
+ element->item->setParentItem(view);
+ QQuickItemPrivate::get(element->item)->addItemChangeListener(element, QQuickItemPrivate::Destroyed);
+ }
+ return element;
+}
+
+bool QQuickStackElement::load(QQuickAbstractStackView *parent)
+{
+ view = parent;
+ if (!item) {
+ ownItem = true;
+
+ QQmlContext *creationContext = component->creationContext();
+ if (!creationContext)
+ creationContext = qmlContext(parent);
+ context = new QQmlContext(creationContext);
+ context->setContextObject(parent);
+
+ delete incubator;
+ incubator = new QQuickStackIncubator(this);
+ component->create(*incubator, context);
+ }
+ initProperties();
+ return item;
+}
+
+void QQuickStackElement::initItem(QObject *object)
+{
+ item = qmlobject_cast<QQuickItem *>(object);
+ if (item) {
+ QQmlEngine::setObjectOwnership(item, QQmlEngine::CppOwnership);
+ QQuickItemPrivate *p = QQuickItemPrivate::get(item);
+ if (!p->widthValid) {
+ item->setWidth(view->width());
+ p->widthValid = false;
+ }
+ if (!p->heightValid) {
+ item->setHeight(view->height());
+ p->heightValid = false;
+ }
+ item->setParentItem(view);
+ p->addItemChangeListener(this, QQuickItemPrivate::Destroyed);
+ }
+ initProperties();
+}
+
+void QQuickStackElement::initProperties()
+{
+ if (!properties.isUndefined()) {
+ QQmlComponentPrivate *d = QQmlComponentPrivate::get(component);
+ Q_ASSERT(d && d->engine);
+ QV4::ExecutionEngine *v4 = qmlGlobal.engine();
+ Q_ASSERT(v4);
+ QV4::Scope scope(v4);
+ QV4::ScopedValue ipv(scope, properties.value());
+ d->initializeObjectWithInitialProperties(*qmlGlobal.valueRef(), ipv, item);
+ properties.clear();
+ }
+}
+
+void QQuickStackElement::setIndex(int value)
+{
+ if (index != value) {
+ index = value;
+ QQuickStackAttached *attached = attachedStackObject(item);
+ if (attached)
+ emit attached->indexChanged();
+ }
+}
+
+void QQuickStackElement::setStatus(QQuickAbstractStackView::Status value)
+{
+ if (status != value) {
+ status = value;
+ QQuickStackAttached *attached = attachedStackObject(item);
+ if (attached)
+ emit attached->statusChanged();
+ }
+}
+
+void QQuickStackElement::transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget)
+{
+ if (transitioner)
+ transitioner->transitionNextReposition(this, type, asTarget);
+}
+
+bool QQuickStackElement::prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds)
+{
+ if (transitioner) {
+ // TODO: add force argument to QQuickItemViewTransitionableItem::prepareTransition()?
+ nextTransitionToSet = true;
+ nextTransitionFromSet = true;
+ nextTransitionFrom += QPointF(1, 1);
+ return QQuickItemViewTransitionableItem::prepareTransition(transitioner, index, viewBounds);
+ }
+ return false;
+}
+
+void QQuickStackElement::startTransition(QQuickItemViewTransitioner *transitioner)
+{
+ if (transitioner)
+ QQuickItemViewTransitionableItem::startTransition(transitioner, index);
+}
+
+void QQuickStackElement::itemDestroyed(QQuickItem *)
+{
+ item = Q_NULLPTR;
+}
+
+QQuickAbstractStackViewPrivate::QQuickAbstractStackViewPrivate() : currentItem(Q_NULLPTR), transitioner(Q_NULLPTR)
+{
+}
+
+void QQuickAbstractStackViewPrivate::setCurrentItem(QQuickItem *item)
+{
+ Q_Q(QQuickAbstractStackView);
+ if (currentItem != item) {
+ currentItem = item;
+ if (item)
+ item->setVisible(true);
+ emit q->currentItemChanged();
+ }
+}
+
+static bool initProperties(QQuickStackElement *element, const QV4::Value &props, QQmlV4Function *args)
+{
+ if (props.isObject()) {
+ const QV4::QObjectWrapper *wrapper = props.as<QV4::QObjectWrapper>();
+ if (!wrapper) {
+ QV4::ExecutionEngine *v4 = args->v4engine();
+ element->properties.set(v4, props);
+ element->qmlGlobal.set(v4, args->qmlGlobal());
+ return true;
+ }
+ }
+ return false;
+}
+
+QList<QQuickStackElement *> QQuickAbstractStackViewPrivate::parseElements(QQmlV4Function *args, int from)
+{
+ QV4::ExecutionEngine *v4 = args->v4engine();
+ QV4::Scope scope(v4);
+
+ QList<QQuickStackElement *> elements;
+
+ int argc = args->length();
+ for (int i = from; i < argc; ++i) {
+ QV4::ScopedValue arg(scope, (*args)[i]);
+ if (QV4::ArrayObject *array = arg->asArrayObject()) {
+ int len = array->getLength();
+ for (int j = 0; j < len; ++j) {
+ QV4::ScopedValue value(scope, array->getIndexed(j));
+ QQuickStackElement *element = createElement(value);
+ if (element) {
+ if (j < len - 1) {
+ QV4::ScopedValue props(scope, array->getIndexed(j + 1));
+ if (initProperties(element, props, args))
+ ++j;
+ }
+ elements += element;
+ }
+ }
+ } else {
+ QQuickStackElement *element = createElement(arg);
+ if (element) {
+ if (i < argc - 1) {
+ QV4::ScopedValue props(scope, (*args)[i + 1]);
+ if (initProperties(element, props, args))
+ ++i;
+ }
+ elements += element;
+ }
+ }
+ }
+ return elements;
+}
+
+QQuickStackElement *QQuickAbstractStackViewPrivate::findElement(QQuickItem *item) const
+{
+ if (item) {
+ foreach (QQuickStackElement *e, elements) {
+ if (e->item == item)
+ return e;
+ }
+ }
+ return Q_NULLPTR;
+}
+
+QQuickStackElement *QQuickAbstractStackViewPrivate::findElement(const QV4::Value &value) const
+{
+ if (const QV4::QObjectWrapper *o = value.as<QV4::QObjectWrapper>())
+ return findElement(qobject_cast<QQuickItem *>(o->object()));
+ return Q_NULLPTR;
+}
+
+QQuickStackElement *QQuickAbstractStackViewPrivate::createElement(const QV4::Value &value)
+{
+ Q_Q(QQuickAbstractStackView);
+ if (QV4::String *s = value.asString())
+ return QQuickStackElement::fromString(s->toQString(), q);
+ if (const QV4::QObjectWrapper *o = value.as<QV4::QObjectWrapper>())
+ return QQuickStackElement::fromObject(o->object(), q);
+ return Q_NULLPTR;
+}
+
+bool QQuickAbstractStackViewPrivate::pushElements(const QList<QQuickStackElement *> &elems)
+{
+ Q_Q(QQuickAbstractStackView);
+ if (!elems.isEmpty()) {
+ foreach (QQuickStackElement *e, elems) {
+ e->setIndex(elements.count());
+ elements += e;
+ }
+ return elements.top()->load(q);
+ }
+ return false;
+}
+
+bool QQuickAbstractStackViewPrivate::pushElement(QQuickStackElement *element)
+{
+ if (element)
+ return pushElements(QList<QQuickStackElement *>() << element);
+ return false;
+}
+
+bool QQuickAbstractStackViewPrivate::popElements(QQuickStackElement *element)
+{
+ Q_Q(QQuickAbstractStackView);
+ if (elements.count() > 1) {
+ while (elements.count() > 1 && elements.top() != element) {
+ delete elements.pop();
+ if (!element)
+ break;
+ }
+ }
+ return elements.top()->load(q);
+}
+
+bool QQuickAbstractStackViewPrivate::replaceElements(QQuickStackElement *target, const QList<QQuickStackElement *> &elems)
+{
+ if (target) {
+ while (!elements.isEmpty()) {
+ QQuickStackElement* top = elements.pop();
+ delete top;
+ if (top == target)
+ break;
+ }
+ }
+ return pushElements(elems);
+}
+
+void QQuickAbstractStackViewPrivate::ensureTransitioner()
+{
+ if (!transitioner) {
+ transitioner = new QQuickItemViewTransitioner;
+ transitioner->setChangeListener(this);
+ }
+}
+
+void QQuickAbstractStackViewPrivate::popTransition(QQuickStackElement *enter, QQuickStackElement *exit, const QRectF &viewBounds, bool immediate)
+{
+ Q_Q(QQuickAbstractStackView);
+ if (exit) {
+ exit->setStatus(QQuickAbstractStackView::Deactivating);
+ exit->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, true);
+ }
+ if (enter) {
+ enter->setStatus(QQuickAbstractStackView::Activating);
+ enter->transitionNextReposition(transitioner, QQuickItemViewTransitioner::RemoveTransition, false);
+ }
+
+ if (exit && exit->prepareTransition(transitioner, viewBounds)) {
+ if (immediate)
+ completeTransition(exit, transitioner->removeTransition);
+ else
+ exit->startTransition(transitioner);
+ }
+ if (enter && enter->prepareTransition(transitioner, viewBounds)) {
+ if (immediate)
+ completeTransition(enter, transitioner->removeDisplacedTransition);
+ else
+ enter->startTransition(transitioner);
+ }
+
+ if (!immediate)
+ emit q->busyChanged();
+
+ if (transitioner)
+ transitioner->resetTargetLists();
+}
+
+void QQuickAbstractStackViewPrivate::pushTransition(QQuickStackElement *enter, QQuickStackElement *exit, const QRectF &viewBounds, bool immediate)
+{
+ Q_Q(QQuickAbstractStackView);
+ if (enter) {
+ enter->setStatus(QQuickAbstractStackView::Activating);
+ enter->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true);
+ }
+ if (exit) {
+ exit->setStatus(QQuickAbstractStackView::Deactivating);
+ exit->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, false);
+ }
+
+ if (enter && enter->prepareTransition(transitioner, viewBounds)) {
+ if (immediate)
+ completeTransition(enter, transitioner->addTransition);
+ else
+ enter->startTransition(transitioner);
+ }
+ if (exit && exit->prepareTransition(transitioner, viewBounds)) {
+ if (immediate)
+ completeTransition(exit, transitioner->addDisplacedTransition);
+ else
+ exit->startTransition(transitioner);
+ }
+
+ if (!immediate)
+ emit q->busyChanged();
+
+ if (transitioner)
+ transitioner->resetTargetLists();
+}
+
+void QQuickAbstractStackViewPrivate::replaceTransition(QQuickStackElement *enter, QQuickStackElement *exit, const QRectF &viewBounds, bool immediate)
+{
+ Q_Q(QQuickAbstractStackView);
+ if (enter) {
+ enter->setStatus(QQuickAbstractStackView::Activating);
+ enter->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true);
+ }
+ if (exit) {
+ exit->removal = true;
+ exit->setStatus(QQuickAbstractStackView::Deactivating);
+ exit->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, false);
+ }
+
+ if (enter && enter->prepareTransition(transitioner, viewBounds)) {
+ if (immediate)
+ completeTransition(enter, transitioner->addTransition);
+ else
+ enter->startTransition(transitioner);
+ }
+ if (exit && exit->prepareTransition(transitioner, viewBounds)) {
+ if (immediate)
+ completeTransition(exit, transitioner->addDisplacedTransition);
+ else
+ exit->startTransition(transitioner);
+ }
+
+ if (!immediate)
+ emit q->busyChanged();
+
+ if (transitioner)
+ transitioner->resetTargetLists();
+}
+
+void QQuickAbstractStackViewPrivate::completeTransition(QQuickStackElement *element, QQuickTransition *transition)
+{
+ if (transition) {
+ // TODO: add a proper way to complete a transition
+ QQmlListProperty<QQuickAbstractAnimation> animations = transition->animations();
+ int count = animations.count(&animations);
+ for (int i = 0; i < count; ++i) {
+ QQuickAbstractAnimation *anim = animations.at(&animations, i);
+ anim->complete();
+ }
+ viewItemTransitionFinished(element);
+ }
+}
+
+void QQuickAbstractStackViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitionableItem *transitionable)
+{
+ Q_Q(QQuickAbstractStackView);
+
+ QQuickStackElement *element = static_cast<QQuickStackElement *>(transitionable);
+ if (element->status == QQuickAbstractStackView::Activating) {
+ element->setStatus(QQuickAbstractStackView::Active);
+ } else if (element->status == QQuickAbstractStackView::Deactivating) {
+ element->setStatus(QQuickAbstractStackView::Inactive);
+ element->item->setVisible(false);
+ if (element->removal || element->isPendingRemoval())
+ delete element;
+ }
+
+ if (transitioner->runningJobs.isEmpty())
+ emit q->busyChanged();
+}
+
+QT_END_NAMESPACE
diff --git a/src/controls/qquickabstractstackview_p.h b/src/controls/qquickabstractstackview_p.h
index 5bb09464..d15a7be4 100644
--- a/src/controls/qquickabstractstackview_p.h
+++ b/src/controls/qquickabstractstackview_p.h
@@ -53,51 +53,90 @@
QT_BEGIN_NAMESPACE
class QQmlV4Function;
+class QQuickTransition;
+class QQuickStackElement;
+class QQuickStackAttached;
class QQuickAbstractStackViewPrivate;
class Q_QUICKCONTROLS_EXPORT QQuickAbstractStackView : public QQuickAbstractContainer
{
Q_OBJECT
- Q_PROPERTY(bool busy READ busy WRITE setBusy NOTIFY busyChanged FINAL) // TODO: hide setBusy
- Q_PROPERTY(int depth READ depth WRITE setDepth NOTIFY depthChanged FINAL) // TODO: hide setDepth
- Q_PROPERTY(QQuickItem *currentItem READ currentItem WRITE setCurrentItem NOTIFY currentItemChanged FINAL) // TODO: hide setCurrentItem
+ Q_PROPERTY(bool busy READ busy NOTIFY busyChanged FINAL)
+ Q_PROPERTY(int depth READ depth NOTIFY depthChanged FINAL)
+ Q_PROPERTY(QQuickItem *currentItem READ currentItem NOTIFY currentItemChanged FINAL)
Q_PROPERTY(QVariant initialItem READ initialItem WRITE setInitialItem FINAL)
+ Q_PROPERTY(QQuickTransition *popEnter READ popEnter WRITE setPopEnter NOTIFY popEnterChanged FINAL)
+ Q_PROPERTY(QQuickTransition *popExit READ popExit WRITE setPopExit NOTIFY popExitChanged FINAL)
+ Q_PROPERTY(QQuickTransition *pushEnter READ pushEnter WRITE setPushEnter NOTIFY pushEnterChanged FINAL)
+ Q_PROPERTY(QQuickTransition *pushExit READ pushExit WRITE setPushExit NOTIFY pushExitChanged FINAL)
public:
explicit QQuickAbstractStackView(QQuickItem *parent = Q_NULLPTR);
~QQuickAbstractStackView();
- bool busy() const;
- void setBusy(bool busy); // TODO: hide
+ static QQuickStackAttached *qmlAttachedProperties(QObject *object);
+ bool busy() const;
int depth() const;
- void setDepth(int depth); // TODO: hide
-
QQuickItem *currentItem() const;
- void setCurrentItem(QQuickItem *item); // TODO: hide
+
+ enum Status {
+ Inactive = 0,
+ Deactivating = 1,
+ Activating = 2,
+ Active = 3
+ };
+ Q_ENUM(Status)
QVariant initialItem() const;
void setInitialItem(const QVariant &item);
+ QQuickTransition *popEnter() const;
+ void setPopEnter(QQuickTransition *enter);
+
+ QQuickTransition *popExit() const;
+ void setPopExit(QQuickTransition *exit);
+
+ QQuickTransition *pushEnter() const;
+ void setPushEnter(QQuickTransition *enter);
+
+ QQuickTransition *pushExit() const;
+ void setPushExit(QQuickTransition *exit);
+
+ enum LoadBehavior {
+ DontLoad,
+ ForceLoad
+ };
+ Q_ENUM(LoadBehavior)
+
+ Q_INVOKABLE QQuickItem *get(int index, LoadBehavior behavior = DontLoad);
+ Q_INVOKABLE QQuickItem *find(const QJSValue &callback, LoadBehavior behavior = DontLoad);
+
enum Operation {
Transition,
Immediate
};
Q_ENUM(Operation)
- Q_INVOKABLE QQuickItem *qpush(QQmlV4Function *args);
- Q_INVOKABLE QQuickItem *qpop(QQmlV4Function *args);
+ Q_INVOKABLE void push(QQmlV4Function *args);
+ Q_INVOKABLE void pop(QQmlV4Function *args);
+ Q_INVOKABLE void replace(QQmlV4Function *args);
public Q_SLOTS:
- void qclear();
+ void clear();
Q_SIGNALS:
void busyChanged();
void depthChanged();
void currentItemChanged();
+ void popEnterChanged();
+ void popExitChanged();
+ void pushEnterChanged();
+ void pushExitChanged();
protected:
void componentComplete() Q_DECL_OVERRIDE;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(QQuickAbstractStackView)
@@ -109,25 +148,17 @@ class QQuickStackAttachedPrivate;
class Q_QUICKCONTROLS_EXPORT QQuickStackAttached : public QObject
{
Q_OBJECT
- Q_PROPERTY(Status status READ status WRITE setStatus NOTIFY statusChanged)
+ Q_PROPERTY(int index READ index NOTIFY indexChanged FINAL)
+ Q_PROPERTY(QQuickAbstractStackView::Status status READ status NOTIFY statusChanged FINAL)
public:
- explicit QQuickStackAttached(QObject *parent = Q_NULLPTR);
-
- static QQuickStackAttached *qmlAttachedProperties(QObject *object);
-
- enum Status {
- Inactive = 0,
- Deactivating = 1,
- Activating = 2,
- Active = 3
- };
- Q_ENUM(Status)
+ explicit QQuickStackAttached(QQuickItem *parent = Q_NULLPTR);
- Status status() const;
- void setStatus(Status status);
+ int index() const;
+ QQuickAbstractStackView::Status status() const;
Q_SIGNALS:
+ void indexChanged();
void statusChanged();
private:
@@ -137,6 +168,7 @@ private:
QT_END_NAMESPACE
-QML_DECLARE_TYPEINFO(QQuickStackAttached, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPEINFO(QQuickAbstractStackView, QML_HAS_ATTACHED_PROPERTIES)
+QML_DECLARE_TYPE(QQuickAbstractStackView)
#endif // QQUICKABSTRACTSTACKVIEW_P_H
diff --git a/src/controls/qquickabstractstackview_p_p.h b/src/controls/qquickabstractstackview_p_p.h
new file mode 100644
index 00000000..5cda34f9
--- /dev/null
+++ b/src/controls/qquickabstractstackview_p_p.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Quick Controls module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKABSTRACTSTACKVIEW_P_P_H
+#define QQUICKABSTRACTSTACKVIEW_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQuickControls/private/qquickabstractstackview_p.h>
+#include <QtQuickControls/private/qquickabstractcontainer_p_p.h>
+#include <QtQuick/private/qquickitemviewtransition_p.h>
+#include <QtQuick/private/qquickitemchangelistener_p.h>
+#include <QtQml/private/qv4persistent_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlContext;
+class QQmlComponent;
+class QQmlIncubator;
+
+class QQuickStackElement : public QQuickItemViewTransitionableItem, public QQuickItemChangeListener
+{
+ QQuickStackElement();
+
+public:
+ ~QQuickStackElement();
+
+ static QQuickStackElement *fromString(const QString &str, QQuickAbstractStackView *view);
+ static QQuickStackElement *fromObject(QObject *object, QQuickAbstractStackView *view);
+
+ bool load(QQuickAbstractStackView *parent);
+ void initItem(QObject *object);
+ void initProperties();
+
+ void setIndex(int index);
+ void setStatus(QQuickAbstractStackView::Status status);
+
+ void transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type, bool asTarget);
+ bool prepareTransition(QQuickItemViewTransitioner *transitioner, const QRectF &viewBounds);
+ void startTransition(QQuickItemViewTransitioner *transitioner);
+
+ void itemDestroyed(QQuickItem *item) Q_DECL_OVERRIDE;
+
+ int index;
+ bool removal;
+ bool ownItem;
+ bool ownComponent;
+ QQmlContext *context;
+ QQmlComponent *component;
+ QQmlIncubator *incubator;
+ QQuickAbstractStackView *view;
+ QPointer<QQuickItem> originalParent;
+ QQuickAbstractStackView::Status status;
+ QV4::PersistentValue properties;
+ QV4::PersistentValue qmlGlobal;
+};
+
+class QQuickAbstractStackViewPrivate : public QQuickAbstractContainerPrivate, public QQuickItemViewTransitionChangeListener
+{
+ Q_DECLARE_PUBLIC(QQuickAbstractStackView)
+
+public:
+ QQuickAbstractStackViewPrivate();
+
+ static QQuickAbstractStackViewPrivate *get(QQuickAbstractStackView *view)
+ {
+ return view->d_func();
+ }
+
+ void setCurrentItem(QQuickItem *item);
+
+ QList<QQuickStackElement *> parseElements(QQmlV4Function *args, int from = 0);
+ QQuickStackElement *findElement(QQuickItem *item) const;
+ QQuickStackElement *findElement(const QV4::Value &value) const;
+ QQuickStackElement *createElement(const QV4::Value &value);
+ bool pushElements(const QList<QQuickStackElement *> &elements);
+ bool pushElement(QQuickStackElement *element);
+ bool popElements(QQuickStackElement *element);
+ bool replaceElements(QQuickStackElement *element, const QList<QQuickStackElement *> &elements);
+
+ void ensureTransitioner();
+ void popTransition(QQuickStackElement *enter, QQuickStackElement *exit, const QRectF &viewBounds, bool immediate);
+ void pushTransition(QQuickStackElement *enter, QQuickStackElement *exit, const QRectF &viewBounds, bool immediate);
+ void replaceTransition(QQuickStackElement *enter, QQuickStackElement *exit, const QRectF &viewBounds, bool immediate);
+ void completeTransition(QQuickStackElement *element, QQuickTransition *transition);
+
+ void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item) Q_DECL_OVERRIDE;
+
+ QVariant initialItem;
+ QQuickItem *currentItem;
+ QStack<QQuickStackElement *> elements;
+ QQuickItemViewTransitioner *transitioner;
+};
+
+class QQuickStackAttachedPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickStackAttached)
+
+public:
+ QQuickStackAttachedPrivate() : initialized(false), element(Q_NULLPTR) { }
+
+ static QQuickStackAttachedPrivate *get(QQuickStackAttached *attached)
+ {
+ return attached->d_func();
+ }
+
+ void init();
+ void reset();
+
+ bool initialized;
+ QQuickStackElement *element;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKABSTRACTSTACKVIEW_P_P_H