9#include <QtQml/qqmlinfo.h>
10#include <QtQml/qqmlengine.h>
11#include <QtQml/qqmlcomponent.h>
12#include <QtQml/qqmlincubator.h>
13#include <QtQml/private/qv4qobjectwrapper_p.h>
14#include <QtQml/private/qqmlcomponent_p.h>
15#include <QtQml/private/qqmlengine_p.h>
16#include <QtQml/private/qqmlincubator_p.h>
20#if QT_CONFIG(quick_viewtransitions)
21static QQuickStackViewAttached *attachedStackObject(QQuickStackElement *element)
23 QQuickStackViewAttached *attached = qobject_cast<QQuickStackViewAttached *>(qmlAttachedPropertiesObject<QQuickStackView>(element->item,
false));
25 QQuickStackViewAttachedPrivate::get(attached)->element = element;
42 auto privIncubator = QQmlIncubatorPrivate::get(
this);
43 if (QQmlEnginePrivate *enginePriv = privIncubator->enginePriv) {
44 element->incubate(enginePriv->v4Engine.get(), object,
45 privIncubator->requiredProperties());
54#if QT_CONFIG(quick_viewtransitions)
55 : QQuickItemViewTransitionableItem(
nullptr)
62#if QT_CONFIG(quick_viewtransitions)
64 QQuickItemPrivate::get(item)->removeItemChangeListener(
this, QQuickItemPrivate::Destroyed);
70#if QT_CONFIG(quick_viewtransitions)
71 QQuickStackViewAttached *attached = attachedStackObject(
this);
74 item->setParentItem(
nullptr);
83 if (item->parentItem() != originalParent) {
84 item->setParentItem(originalParent);
87 QQuickStackViewAttachedPrivate::get(attached)->itemParentChanged(item,
nullptr);
93 emit attached->removed();
98 QQmlEngine *engine,
const QString &str, QQuickStackView *view, QString *error)
101 if (!url.isValid()) {
102 *error = QStringLiteral(
"invalid url: ") + str;
106 if (url.isRelative())
107 url = qmlContext(view)->resolvedUrl(url);
110 element->component =
new QQmlComponent(engine, url, view);
118 QQmlComponent *component = qobject_cast<QQmlComponent *>(object);
119 QQuickItem *item = qobject_cast<QQuickItem *>(object);
120 if (!component && !item) {
121 *error = QQmlMetaType::prettyTypeName(object) + QStringLiteral(
" is not supported. Must be Item or Component.");
125 QQuickStackElement *element =
new QQuickStackElement;
126 element->component = qobject_cast<QQmlComponent *>(object);
127#if QT_CONFIG(quick_viewtransitions)
128 element->item = qobject_cast<QQuickItem *>(object);
130 element->originalParent = element->item->parentItem();
136 QQmlEngine *engine, QQuickStackView *view, QQuickStackViewArg arg)
138 QQuickStackElement *element =
new QQuickStackElement;
139#if QT_CONFIG(quick_viewtransitions)
140 element->item = arg.mItem;
142 element->originalParent = element->item->parentItem();
144 Q_ASSERT(!arg.mComponent);
145 Q_ASSERT(!arg.mUrl.isValid());
148 if (arg.mComponent) {
149 element->component = arg.mComponent;
151 Q_ASSERT(!arg.mUrl.isValid());
152 }
else if (arg.mUrl.isValid()) {
153 element->component =
new QQmlComponent(engine, arg.mUrl, view);
154 element->ownComponent =
true;
156 qFatal(
"No Item, Component or URL set on arg passed to fromStrictArg");
167 if (component->isLoading()) {
168 QObject::connect(component, &QQmlComponent::statusChanged, component,
169 [
this](QQmlComponent::Status status) {
170 if (status == QQmlComponent::Ready)
171 load(component->engine()->handle(), view);
172 else if (status == QQmlComponent::Error)
173 QQuickStackViewPrivate::get(view)->warn(component->errorString().trimmed());
178 QQmlContext *context = component->creationContext();
180 context = qmlContext(parent);
182 QQuickStackIncubator incubator(
this);
183 component->create(incubator, context);
184 if (component->isError())
185 QQuickStackViewPrivate::get(parent)->warn(component->errorString().trimmed());
187 initialize(v4,
nullptr);
195 item = qmlobject_cast<QQuickItem *>(object);
197 QQmlEngine::setObjectOwnership(item, QQmlEngine::CppOwnership);
198 item->setParent(view);
199 initialize(v4, requiredProperties);
209 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
210 if (!(widthValid = p->widthValid()))
211 item->setWidth(view->width());
212 if (!(heightValid = p->heightValid()))
213 item->setHeight(view->height());
214 item->setParentItem(view);
216 if (!properties.isUndefined()) {
217 QV4::Scope scope(v4);
218 Q_ASSERT(scope.engine);
219 QV4::ScopedValue ipv(scope, properties.value());
220 QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value());
221 QV4::ScopedValue qmlObject(scope, QV4::QObjectWrapper::wrap(scope.engine, item));
222 QQmlComponentPrivate::setInitialProperties(
223 scope.engine, qmlContext, qmlObject, ipv, requiredProperties, item,
224 component ? QQmlComponentPrivate::get(component)->creator() :
nullptr);
228 if (requiredProperties && !requiredProperties->empty()) {
230 for (
const auto &property: *requiredProperties) {
231 error += QLatin1String(
"Property %1 was marked as required but not set.\n")
232 .arg(property.propertyName);
234 QQuickStackViewPrivate::get(view)->warn(error);
237 p->addItemChangeListener(
this, QQuickItemPrivate::Destroyed);
249#if QT_CONFIG(quick_viewtransitions)
250 QQuickStackViewAttached *attached = attachedStackObject(
this);
252 emit attached->indexChanged();
262#if QT_CONFIG(quick_viewtransitions)
263 QQuickStackViewAttached *attached = attachedStackObject(
this);
265 emit attached->viewChanged();
275#if QT_CONFIG(quick_viewtransitions)
276 QQuickStackViewAttached *attached = attachedStackObject(
this);
281 case QQuickStackView::Inactive:
282 emit attached->deactivated();
284 case QQuickStackView::Deactivating:
285 emit attached->deactivating();
287 case QQuickStackView::Activating:
288 emit attached->activating();
290 case QQuickStackView::Active:
291 emit attached->activated();
298 emit attached->statusChanged();
304#if QT_CONFIG(quick_viewtransitions)
305 QQuickStackViewAttached *attached = attachedStackObject(
this);
308#if QT_CONFIG(quick_viewtransitions)
309 || (attached && QQuickStackViewAttachedPrivate::get(attached)->explicitVisible)
314 item->setVisible(visible);
317#if QT_CONFIG(quick_viewtransitions)
318void QQuickStackElement::transitionNextReposition(QQuickItemViewTransitioner *transitioner, QQuickItemViewTransitioner::TransitionType type,
bool asTarget)
321 transitioner->transitionNextReposition(
this, type, asTarget);
324bool QQuickStackElement::prepareTransition(QQuickItemViewTransitioner *transitioner,
const QRectF &viewBounds)
328 QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors;
330 if (anchors && (anchors->fill() || anchors->centerIn()))
331 qmlWarning(item) <<
"StackView has detected conflicting anchors. Transitions may not execute properly.";
335 nextTransitionToSet =
true;
336 nextTransitionFromSet =
true;
337 nextTransitionFrom += QPointF(1, 1);
338 return QQuickItemViewTransitionableItem::prepareTransition(transitioner, index, viewBounds);
343void QQuickStackElement::startTransition(QQuickItemViewTransitioner *transitioner, QQuickStackView::Status status)
347 QQuickItemViewTransitionableItem::startTransition(transitioner, index);
350void QQuickStackElement::completeTransition(QQuickTransition *quickTransition)
352 QQuickItemViewTransitionableItem::completeTransition(quickTransition);
358#if QT_CONFIG(quick_viewtransitions)
QQmlComponent * component
void itemDestroyed(QQuickItem *item) override
void initialize(QV4::ExecutionEngine *v4, RequiredProperties *requiredProperties)
void setVisible(bool visible)
void setStatus(QQuickStackView::Status status)
void incubate(QV4::ExecutionEngine *v4, QObject *object, RequiredProperties *requiredProperties)
QQuickStackIncubator(QQuickStackElement *element)
void setInitialState(QObject *object) override
Called after the object is first created, but before complex property bindings are evaluated and,...
Combined button and popup list for selecting options.