4#include <QtCore/qurl.h>
5#include <QtCore/QScopeGuard>
9#include <QtQuickVectorImageGenerator/private/qquickitemgenerator_p.h>
10#include <QtQuickVectorImageGenerator/private/qquickvectorimageglobal_p.h>
11#include <QtCore/qloggingcategory.h>
13#include <private/qquicktranslate_p.h>
14#include <private/qquickanimation_p.h>
20 static const bool val = !qEnvironmentVariableIsSet(
"QT_QUICKVECTORIMAGE_USE_ITEM_GENERATOR");
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
53 Q_Q(QQuickVectorImage);
54 if (sourceFile == source)
59 emit q->sourceChanged();
64 Q_Q(QQuickVectorImage);
66 if (!q->isComponentComplete())
69 QQmlContext *ctx = qmlContext(q);
70 QUrl resolvedUrl = ctx->resolvedUrl(sourceFile);
71 QString localFile = QQmlFile::urlToLocalFileOrQrc(resolvedUrl);
73 if (localFile.isEmpty())
76 if (rootItem && !retainWhileLoading) {
77 rootItem->deleteLater();
79 emit q->generatedItemChanged();
92 if (pendingRootItem !=
nullptr) {
93 delete pendingRootItem;
94 pendingRootItem =
nullptr;
97 QQuickVectorImageGenerator::GeneratorFlags flags;
98 if (preferredRendererType == QQuickVectorImage::CurveRenderer)
99 flags.setFlag(QQuickVectorImageGenerator::CurveRenderer);
101 flags.setFlag(QQuickVectorImageGenerator::AssumeTrustedSource);
103 flags.setFlag(QQuickVectorImageGenerator::AsyncShapes);
105 flags.setFlag(QQuickVectorImageGenerator::AsynchronousLoading);
108 QQmlIncubator::IncubationMode mode =
109 asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::Synchronous;
111 if (!context || context->engine() != qmlContext(q)->engine())
112 context.reset(
new QQmlContext(qmlContext(q)->engine()));
114 incubator =
new QQuickVectorImageIncubator(mode, context.get(), q);
115 QObject::connect(incubator, &QQuickVectorImageIncubator::statusUpdated, q,
116 &QQuickVectorImage::statusChanged);
117 QObject::connect(incubator, &QQuickVectorImageIncubator::statusUpdated, q,
118 &QQuickVectorImage::updateItem);
121 QQuickItemGenerator gen(localFile, flags);
124 if (gen.errorState() == QQuickVectorImageGenerator::NoError) {
125 pendingRootItem = gen.takeRootItem();
127 qCWarning(lcQuickVectorImage) <<
"QQuickItemGenerator: failed to generate" << localFile
128 <<
"(errorState:" << gen.errorState() <<
")";
131 emit q->statusChanged();
135void QQuickVectorImage::updateItem()
137 Q_D(QQuickVectorImage);
139 QQuickItem *item =
nullptr;
140 if (d->incubator !=
nullptr) {
141 if (d->incubator->object() ==
nullptr || !d->incubator->isReady())
143 item = qobject_cast<QQuickItem *>(d->incubator->object());
144 if (item ==
nullptr) {
145 qCWarning(lcQuickVectorImage)
146 <<
"QQuickVectorImage::updateItem: Root item not a QQuickItem:"
147 << d->incubator->errors();
151 item = d->pendingRootItem;
152 d->pendingRootItem =
nullptr;
157 if (d->rootItem !=
nullptr)
158 d->rootItem->deleteLater();
160 d->rootItem =
new QQuickItem(
this);
161 d->rootItem->setParentItem(
this);
162 auto emitter = qScopeGuard([&] { emit generatedItemChanged(); });
164 if (item->width() == 0 || item->height() == 0)
167 d->rootItem->setImplicitWidth(item->width());
168 d->rootItem->setImplicitHeight(item->height());
170 item->setParent(d->rootItem);
171 item->setParentItem(d->rootItem);
173 setImplicitWidth(d->rootItem->width());
174 setImplicitHeight(d->rootItem->height());
176 updateAnimationProperties();
177 updateRootItemScale();
180 static int freezeTime = qEnvironmentVariableIntValue(
"QT_QUICKVECTORIMAGE_FREEZE");
181 if (freezeTime != 0) {
184 animations()->setPaused(
true);
185 const QList<QQuickAbstractAnimation *> anims = d->rootItem->findChildren<QQuickAbstractAnimation *>();
186 for (QQuickAbstractAnimation *anim : anims) {
187 if (anim->group() ==
nullptr)
188 anim->setCurrentTime(freezeTime);
193 d->incubator->disconnect(
this);
194 d->incubator->deleteLater();
195 d->incubator =
nullptr;
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219QQuickVectorImage::QQuickVectorImage(QQuickItem *parent)
220 : QQuickItem(*(
new QQuickVectorImagePrivate), parent)
222 setFlag(QQuickItem::ItemHasContents,
true);
224 QObject::connect(
this, &QQuickItem::widthChanged,
this, &QQuickVectorImage::updateRootItemScale);
225 QObject::connect(
this, &QQuickItem::heightChanged,
this, &QQuickVectorImage::updateRootItemScale);
226 QObject::connect(
this, &QQuickVectorImage::fillModeChanged,
this, &QQuickVectorImage::updateRootItemScale);
229QQuickVectorImage::~QQuickVectorImage()
231 Q_D(QQuickVectorImage);
234 d->incubator =
nullptr;
238
239
240
241
242
243
244
245
246QUrl QQuickVectorImage::source()
const
248 Q_D(
const QQuickVectorImage);
249 return d->sourceFile;
252void QQuickVectorImage::setSource(
const QUrl &source)
254 Q_D(QQuickVectorImage);
255 d->setSource(source);
258void QQuickVectorImage::updateRootItemScale()
260 Q_D(QQuickVectorImage);
262 if (d->rootItem ==
nullptr
263 || qFuzzyIsNull(d->rootItem->width())
264 || qFuzzyIsNull(d->rootItem->height())) {
268 auto xformProp = d->rootItem->transform();
269 QQuickScale *scaleTransform =
nullptr;
270 if (xformProp.count(&xformProp) == 0) {
271 scaleTransform =
new QQuickScale;
272 scaleTransform->setParent(d->rootItem);
273 xformProp.append(&xformProp, scaleTransform);
275 scaleTransform = qobject_cast<QQuickScale *>(xformProp.at(&xformProp, 0));
278 if (scaleTransform !=
nullptr) {
279 qreal xScale = width() / d->rootItem->width();
280 qreal yScale = height() / d->rootItem->height();
282 switch (d->fillMode) {
283 case QQuickVectorImage::NoResize:
284 xScale = yScale = 1.0;
286 case QQuickVectorImage::PreserveAspectFit:
287 xScale = yScale = qMin(xScale, yScale);
289 case QQuickVectorImage::PreserveAspectCrop:
290 xScale = yScale = qMax(xScale, yScale);
292 case QQuickVectorImage::Stretch:
297 scaleTransform->setXScale(xScale);
298 scaleTransform->setYScale(yScale);
302void QQuickVectorImage::updateAnimationProperties()
304 Q_D(QQuickVectorImage);
305 if (Q_UNLIKELY(d->rootItem ==
nullptr || d->rootItem->childItems().isEmpty()))
308 QQuickItem *childItem = d->rootItem->childItems().first();
309 if (Q_LIKELY(d->animations !=
nullptr)) {
310 childItem->setProperty(
"loops", d->animations->loops());
311 childItem->setProperty(
"paused", d->animations->paused());
315QQuickVectorImageAnimations *QQuickVectorImage::animations()
317 Q_D(QQuickVectorImage);
318 if (d->animations ==
nullptr) {
319 d->animations =
new QQuickVectorImageAnimations;
320 QQml_setParent_noEvent(d->animations,
this);
321 QObject::connect(d->animations, &QQuickVectorImageAnimations::loopsChanged,
this, &QQuickVectorImage::updateAnimationProperties);
322 QObject::connect(d->animations, &QQuickVectorImageAnimations::pausedChanged,
this, &QQuickVectorImage::updateAnimationProperties);
325 return d->animations;
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
348QQuickVectorImage::FillMode QQuickVectorImage::fillMode()
const
350 Q_D(
const QQuickVectorImage);
354void QQuickVectorImage::setFillMode(FillMode newFillMode)
356 Q_D(QQuickVectorImage);
357 if (d->fillMode == newFillMode)
359 d->fillMode = newFillMode;
360 emit fillModeChanged();
364
365
366
367
368
369
370
371
372
373
374
375
376
378QQuickVectorImage::RendererType QQuickVectorImage::preferredRendererType()
const
380 Q_D(
const QQuickVectorImage);
381 return d->preferredRendererType;
384void QQuickVectorImage::setPreferredRendererType(RendererType newPreferredRendererType)
386 Q_D(QQuickVectorImage);
387 if (d->preferredRendererType == newPreferredRendererType)
389 d->preferredRendererType = newPreferredRendererType;
391 emit preferredRendererTypeChanged();
395
396
397
398
399
400
401
402
403
404
405
406
407
408
410bool QQuickVectorImage::asynchronousShapes()
const
412 Q_D(
const QQuickVectorImage);
413 return d->m_asyncShapes;
416void QQuickVectorImage::setAsynchronousShapes(
bool asynchronous)
418 Q_D(QQuickVectorImage);
419 if (d->m_asyncShapes == asynchronous)
421 d->m_asyncShapes = asynchronous;
422 emit asynchronousShapesChanged();
426
427
428
429
430
431
432
433
434
435
436
438bool QQuickVectorImage::asynchronous()
const
440 Q_D(
const QQuickVectorImage);
441 return d->asynchronous;
444void QQuickVectorImage::setAsynchronous(
bool asynchronous)
446 Q_D(QQuickVectorImage);
447 if (d->asynchronous == asynchronous)
449 d->asynchronous = asynchronous;
450 emit asynchronousChanged();
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469bool QQuickVectorImage::retainWhileLoading()
const
471 Q_D(
const QQuickVectorImage);
472 return d->retainWhileLoading;
475void QQuickVectorImage::setRetainWhileLoading(
bool retainWhileLoading)
477 Q_D(QQuickVectorImage);
478 if (d->retainWhileLoading == retainWhileLoading)
480 d->retainWhileLoading = retainWhileLoading;
481 emit retainWhileLoadingChanged();
485
486
487
488
489
490
491
492
493
494
495QQuickVectorImage::Status QQuickVectorImage::status()
const
497 Q_D(
const QQuickVectorImage);
498 if (d->incubator ==
nullptr) {
499 if (d->rootItem ==
nullptr)
502 return Status::Ready;
505 switch (d->incubator->status()) {
506 case QQmlIncubator::Null:
508 case QQmlIncubator::Loading:
509 return Status::Loading;
510 case QQmlIncubator::Error:
511 return Status::Error;
512 case QQmlIncubator::Ready:
513 return Status::Ready;
516 return Status::Error;
520
521
522
523
524
525
526
527
528
529
530
531
532
533
535bool QQuickVectorImage::assumeTrustedSource()
const
537 Q_D(
const QQuickVectorImage);
538 return d->assumeTrustedSource;
541void QQuickVectorImage::setAssumeTrustedSource(
bool assumeTrustedSource)
543 Q_D(QQuickVectorImage);
544 if (d->assumeTrustedSource == assumeTrustedSource)
546 d->assumeTrustedSource = assumeTrustedSource;
548 emit assumeTrustedSourceChanged();
552
553
554
555
556
557
558
560QQuickItem *QQuickVectorImage::generatedItem()
const
562 Q_D(
const QQuickVectorImage);
563 return d->rootItem ? d->rootItem->childItems().value(0) :
nullptr;
566void QQuickVectorImage::componentComplete()
568 Q_D(QQuickVectorImage);
569 QQuickItem::componentComplete();
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591int QQuickVectorImageAnimations::loops()
const
596void QQuickVectorImageAnimations::setLoops(
int loops)
598 if (m_loops == loops)
604bool QQuickVectorImageAnimations::paused()
const
609void QQuickVectorImageAnimations::setPaused(
bool paused)
611 if (m_paused == paused)
614 emit pausedChanged();
617void QQuickVectorImageAnimations::restart()
619 QQuickVectorImage *parentVectorImage = qobject_cast<QQuickVectorImage *>(parent());
620 if (Q_UNLIKELY(parentVectorImage ==
nullptr)) {
621 qCWarning(lcQuickVectorImage) << Q_FUNC_INFO <<
"Parent is not a VectorImage";
625 QQuickVectorImagePrivate *d = QQuickVectorImagePrivate::get(parentVectorImage);
627 if (Q_UNLIKELY(d->rootItem ==
nullptr || d->rootItem->childItems().isEmpty()))
630 QQuickItem *childItem = d->rootItem->childItems().first();
631 QMetaObject::invokeMethod(childItem,
"restart");
636#include <moc_qquickvectorimage_p.cpp>
void setSource(const QUrl &source)
\qmlmodule QtQuick.VectorImage \title Qt Quick Vector Image QML Types
QQuickVectorImageIncubator * incubator
Combined button and popup list for selecting options.
static QT_BEGIN_NAMESPACE bool useQmlGenerator()