diff options
Diffstat (limited to 'src/quicktemplates2/qquickstackview_p.cpp')
-rw-r--r-- | src/quicktemplates2/qquickstackview_p.cpp | 394 |
1 files changed, 19 insertions, 375 deletions
diff --git a/src/quicktemplates2/qquickstackview_p.cpp b/src/quicktemplates2/qquickstackview_p.cpp index 1eaaa9a4..89b3c6e3 100644 --- a/src/quicktemplates2/qquickstackview_p.cpp +++ b/src/quicktemplates2/qquickstackview_p.cpp @@ -35,276 +35,34 @@ ****************************************************************************/ #include "qquickstackview_p_p.h" +#include "qquickstackelement_p_p.h" +#include "qquickstacktransition_p_p.h" -#include <QtQml/qqmlinfo.h> #include <QtQml/qqmllist.h> -#include <QtQml/qqmlengine.h> -#include <QtQml/qqmlcomponent.h> -#include <QtQml/qqmlincubator.h> +#include <QtQml/private/qv4qmlcontext_p.h> #include <QtQml/private/qv4qobjectwrapper_p.h> -#include <QtQml/private/qqmlcomponent_p.h> -#include <QtQml/private/qqmlengine_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(QQuickStackElement *element) +QQuickStackViewPrivate::QQuickStackViewPrivate() + : busy(false), + currentItem(nullptr), + transitioner(nullptr) { - QQuickStackAttached *attached = qobject_cast<QQuickStackAttached *>(qmlAttachedPropertiesObject<QQuickStackView>(element->item, false)); - if (attached) - QQuickStackAttachedPrivate::get(attached)->element = element; - return attached; } -class QQuickStackIncubator : public QQmlIncubator -{ -public: - QQuickStackIncubator(QQuickStackElement *element) : QQmlIncubator(Synchronous), element(element) { } - -protected: - void setInitialState(QObject *object) override { element->incubate(object); } - -private: - QQuickStackElement *element; -}; - -QQuickStackElement::QQuickStackElement() : QQuickItemViewTransitionableItem(nullptr), - index(-1), init(false), removal(false), ownItem(false), ownComponent(false), widthValid(false), heightValid(false), - context(nullptr), component(nullptr), view(nullptr), - status(QQuickStackView::Inactive) -{ -} - -QQuickStackElement::~QQuickStackElement() -{ - if (item) - QQuickItemPrivate::get(item)->removeItemChangeListener(this, QQuickItemPrivate::Destroyed); - - if (ownComponent) - delete component; - - QQuickStackAttached *attached = attachedStackObject(this); - if (item) { - if (ownItem) { - item->setParentItem(nullptr); - item->deleteLater(); - item = nullptr; - } else { - item->setVisible(false); - if (!widthValid) - item->resetWidth(); - if (!heightValid) - item->resetHeight(); - if (item->parentItem() != originalParent) { - item->setParentItem(originalParent); - } else { - if (attached) - QQuickStackAttachedPrivate::get(attached)->itemParentChanged(item, nullptr); - } - } - } - - if (attached) - emit attached->removed(); - - delete context; -} - -QQuickStackElement *QQuickStackElement::fromString(const QString &str, QQuickStackView *view) -{ - QQuickStackElement *element = new QQuickStackElement; - element->component = new QQmlComponent(qmlEngine(view), QUrl(str), view); - element->ownComponent = true; - return element; -} - -QQuickStackElement *QQuickStackElement::fromObject(QObject *object, QQuickStackView *view) -{ - Q_UNUSED(view); - QQuickStackElement *element = new QQuickStackElement; - element->component = qobject_cast<QQmlComponent *>(object); - element->item = qobject_cast<QQuickItem *>(object); - if (element->item) - element->originalParent = element->item->parentItem(); - return element; -} - -bool QQuickStackElement::load(QQuickStackView *parent) -{ - setView(parent); - if (!item) { - ownItem = true; - - if (component->isLoading()) { - QObject::connect(component, &QQmlComponent::statusChanged, [this](QQmlComponent::Status status) { - if (status == QQmlComponent::Ready) - load(view); - else if (status == QQmlComponent::Error) - qWarning() << qPrintable(component->errorString().trimmed()); - }); - return true; - } - - QQmlContext *creationContext = component->creationContext(); - if (!creationContext) - creationContext = qmlContext(parent); - context = new QQmlContext(creationContext); - context->setContextObject(parent); - - QQuickStackIncubator incubator(this); - component->create(incubator, context); - if (component->isError()) - qWarning() << qPrintable(component->errorString().trimmed()); - } else { - initialize(); - } - return item; -} - -void QQuickStackElement::incubate(QObject *object) -{ - item = qmlobject_cast<QQuickItem *>(object); - if (item) { - QQmlEngine::setObjectOwnership(item, QQmlEngine::CppOwnership); - item->setParent(view); - initialize(); - } -} - -void QQuickStackElement::initialize() -{ - if (!item || init) - return; - - QQuickItemPrivate *p = QQuickItemPrivate::get(item); - if (!(widthValid = p->widthValid)) - item->setWidth(view->width()); - if (!(heightValid = p->heightValid)) - item->setHeight(view->height()); - item->setParentItem(view); - p->addItemChangeListener(this, QQuickItemPrivate::Destroyed); - - if (!properties.isUndefined()) { - QQmlEngine *engine = qmlEngine(view); - Q_ASSERT(engine); - QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine); - Q_ASSERT(v4); - QV4::Scope scope(v4); - QV4::ScopedValue ipv(scope, properties.value()); - QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value()); - QV4::ScopedValue qmlObject(scope, QV4::QObjectWrapper::wrap(v4, item)); - QQmlComponentPrivate::setInitialProperties(v4, qmlContext, qmlObject, ipv); - properties.clear(); - } - - init = true; -} - -void QQuickStackElement::setIndex(int value) -{ - if (index == value) - return; - - index = value; - QQuickStackAttached *attached = attachedStackObject(this); - if (attached) - emit attached->indexChanged(); -} - -void QQuickStackElement::setView(QQuickStackView *value) -{ - if (view == value) - return; - - view = value; - QQuickStackAttached *attached = attachedStackObject(this); - if (attached) - emit attached->viewChanged(); -} - -void QQuickStackElement::setStatus(QQuickStackView::Status value) -{ - if (status == value) - return; - - status = value; - QQuickStackAttached *attached = attachedStackObject(this); - if (!attached) - return; - - switch (value) { - case QQuickStackView::Inactive: - emit attached->deactivated(); - break; - case QQuickStackView::Deactivating: - emit attached->deactivating(); - break; - case QQuickStackView::Activating: - emit attached->activating(); - break; - case QQuickStackView::Active: - emit attached->activated(); - break; - default: - Q_UNREACHABLE(); - break; - } - - 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) { - if (item) { - QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors; - // TODO: expose QQuickAnchorLine so we can test for other conflicting anchors - if (anchors && (anchors->fill() || anchors->centerIn())) - qmlInfo(item) << "StackView has detected conflicting anchors. Transitions may not execute properly."; - } - - // 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, QQuickStackView::Status status) -{ - setStatus(status); - if (transitioner) - QQuickItemViewTransitionableItem::startTransition(transitioner, index); -} - -void QQuickStackElement::itemDestroyed(QQuickItem *) -{ - item = nullptr; -} - -QQuickStackViewPrivate::QQuickStackViewPrivate() : busy(false), currentItem(nullptr), transitioner(nullptr) -{ -} - -void QQuickStackViewPrivate::setCurrentItem(QQuickItem *item) +void QQuickStackViewPrivate::setCurrentItem(QQuickStackElement *element) { Q_Q(QQuickStackView); + QQuickItem *item = element ? element->item : nullptr; if (currentItem == item) return; currentItem = item; - if (item) - item->setVisible(true); + if (element) + element->setVisible(true); emit q->currentItemChanged(); } @@ -450,13 +208,13 @@ void QQuickStackViewPrivate::startTransition(const QQuickStackTransition &first, if (first.element) { if (immediate || !first.element->item || !first.element->prepareTransition(transitioner, first.viewBounds)) - completeTransition(first.element, transitioner->removeTransition, first.status); + completeTransition(first.element, first.transition, first.status); else first.element->startTransition(transitioner, first.status); } if (second.element) { if (immediate || !second.element->item || !second.element->prepareTransition(transitioner, second.viewBounds)) - completeTransition(second.element, transitioner->removeDisplacedTransition, second.status); + completeTransition(second.element, second.transition, second.status); else second.element->startTransition(transitioner, second.status); } @@ -489,17 +247,18 @@ void QQuickStackViewPrivate::viewItemTransitionFinished(QQuickItemViewTransition element->setStatus(QQuickStackView::Active); } else if (element->status == QQuickStackView::Deactivating) { element->setStatus(QQuickStackView::Inactive); - if (element->item) - element->item->setVisible(false); + element->setVisible(false); if (element->removal || element->isPendingRemoval()) - removals += element; + removed += element; } if (transitioner->runningJobs.isEmpty()) { - qDeleteAll(removals); - removals.clear(); + qDeleteAll(removed); + removed.clear(); setBusy(false); } + + removing.remove(element); } void QQuickStackViewPrivate::setBusy(bool b) @@ -513,119 +272,4 @@ void QQuickStackViewPrivate::setBusy(bool b) emit q->busyChanged(); } -static QQuickStackTransition exitTransition(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) -{ - QQuickStackTransition st; - st.status = QQuickStackView::Deactivating; - st.transition = nullptr; - st.element = element; - - const QQuickItemViewTransitioner *transitioner = QQuickStackViewPrivate::get(view)->transitioner; - - switch (operation) { - case QQuickStackView::PushTransition: - st.target = false; - st.type = QQuickItemViewTransitioner::AddTransition; - st.viewBounds = QRectF(); - if (transitioner) - st.transition = transitioner->addDisplacedTransition; - break; - case QQuickStackView::ReplaceTransition: - st.target = false; - st.type = QQuickItemViewTransitioner::MoveTransition; - st.viewBounds = QRectF(); - if (transitioner) - st.transition = transitioner->moveDisplacedTransition; - break; - case QQuickStackView::PopTransition: - st.target = true; - st.type = QQuickItemViewTransitioner::RemoveTransition; - st.viewBounds = view->boundingRect(); - if (transitioner) - st.transition = transitioner->removeTransition; - break; - default: - Q_UNREACHABLE(); - break; - } - - return st; -} - -static QQuickStackTransition enterTransition(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) -{ - QQuickStackTransition st; - st.status = QQuickStackView::Activating; - st.transition = nullptr; - st.element = element; - - const QQuickItemViewTransitioner *transitioner = QQuickStackViewPrivate::get(view)->transitioner; - - switch (operation) { - case QQuickStackView::PushTransition: - st.target = true; - st.type = QQuickItemViewTransitioner::AddTransition; - st.viewBounds = view->boundingRect(); - if (transitioner) - st.transition = transitioner->addTransition; - break; - case QQuickStackView::ReplaceTransition: - st.target = true; - st.type = QQuickItemViewTransitioner::MoveTransition; - st.viewBounds = view->boundingRect(); - if (transitioner) - st.transition = transitioner->moveTransition; - break; - case QQuickStackView::PopTransition: - st.target = false; - st.type = QQuickItemViewTransitioner::RemoveTransition; - st.viewBounds = QRectF(); - if (transitioner) - st.transition = transitioner->removeDisplacedTransition; - break; - default: - Q_UNREACHABLE(); - break; - } - - return st; -} - -static QQuickStackView::Operation operationTransition(QQuickStackView::Operation operation, QQuickStackView::Operation transition) -{ - if (operation == QQuickStackView::Immediate || operation == QQuickStackView::Transition) - return transition; - return operation; -} - -QQuickStackTransition QQuickStackTransition::popExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) -{ - return exitTransition(operationTransition(operation, QQuickStackView::PopTransition), element, view); -} - -QQuickStackTransition QQuickStackTransition::popEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) -{ - return enterTransition(operationTransition(operation, QQuickStackView::PopTransition), element, view); -} - -QQuickStackTransition QQuickStackTransition::pushExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) -{ - return exitTransition(operationTransition(operation, QQuickStackView::PushTransition), element, view); -} - -QQuickStackTransition QQuickStackTransition::pushEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) -{ - return enterTransition(operationTransition(operation, QQuickStackView::PushTransition), element, view); -} - -QQuickStackTransition QQuickStackTransition::replaceExit(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) -{ - return exitTransition(operationTransition(operation, QQuickStackView::ReplaceTransition), element, view); -} - -QQuickStackTransition QQuickStackTransition::replaceEnter(QQuickStackView::Operation operation, QQuickStackElement *element, QQuickStackView *view) -{ - return enterTransition(operationTransition(operation, QQuickStackView::ReplaceTransition), element, view); -} - QT_END_NAMESPACE |