8#include <QtQuick/private/qsgcontext_p.h>
9#include <QtQuick/private/qquickitem_p.h>
10#include <private/qsgadaptationlayer_p.h>
11#include <private/qqmlglobal_p.h>
12#include <QtQuick/qsgnode.h>
13#include <QtQuick/qsgtexturematerial.h>
14#include <QtQuick/qsgtexture.h>
15#include <QtQuick/qquickwindow.h>
16#include <QtQml/qqmlinfo.h>
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
100
101
102
103
104
105
108
109
110
111
112
113
114
117
118
119
120
121
122
123
124
125
128
129
130
131
132
133
134
135
136
139
140
141
142
144
145
146
147
148
149
151
152
153
154
155
156
158
159
160
161
162
163
165
166
167
168
169
170
172
173
174
175
176
177
178
179
180
183
184
185
186
187
188
191
192
193
194
195
196
197
198
199
200
201
202
205
206
207
208
209
210
211
212
215
216
217
218
219
220
223
224
225
226
227
230
231
232
233
234
235
236
237
238
239
240
243
244
245
246
249
250
251
252
253
254
255
256
258QQuickAnimatedSprite::QQuickAnimatedSprite(QQuickItem *parent) :
259 QQuickItem(*(
new QQuickAnimatedSpritePrivate), parent)
261 Q_D(QQuickAnimatedSprite);
262 d->m_sprite =
new QQuickSprite(
this);
264 setFlag(ItemHasContents);
265 connect(
this, SIGNAL(widthChanged()),
266 this, SLOT(reset()));
267 connect(
this, SIGNAL(heightChanged()),
268 this, SLOT(reset()));
271bool QQuickAnimatedSprite::running()
const
273 Q_D(
const QQuickAnimatedSprite);
277bool QQuickAnimatedSprite::interpolate()
const
279 Q_D(
const QQuickAnimatedSprite);
280 return d->m_interpolate;
283QUrl QQuickAnimatedSprite::source()
const
285 Q_D(
const QQuickAnimatedSprite);
286 return d->m_sprite->source();
289bool QQuickAnimatedSprite::reverse()
const
291 Q_D(
const QQuickAnimatedSprite);
292 return d->m_sprite->reverse();
295bool QQuickAnimatedSprite::frameSync()
const
297 Q_D(
const QQuickAnimatedSprite);
298 return d->m_sprite->frameSync();
301int QQuickAnimatedSprite::frameCount()
const
303 Q_D(
const QQuickAnimatedSprite);
304 return d->m_sprite->frames();
307int QQuickAnimatedSprite::frameHeight()
const
309 Q_D(
const QQuickAnimatedSprite);
310 return d->m_sprite->frameHeight();
313int QQuickAnimatedSprite::frameWidth()
const
315 Q_D(
const QQuickAnimatedSprite);
316 return d->m_sprite->frameWidth();
319int QQuickAnimatedSprite::frameX()
const
321 Q_D(
const QQuickAnimatedSprite);
322 return d->m_sprite->frameX();
325int QQuickAnimatedSprite::frameY()
const
327 Q_D(
const QQuickAnimatedSprite);
328 return d->m_sprite->frameY();
331qreal QQuickAnimatedSprite::frameRate()
const
333 Q_D(
const QQuickAnimatedSprite);
334 return d->m_sprite->frameRate();
337int QQuickAnimatedSprite::frameDuration()
const
339 Q_D(
const QQuickAnimatedSprite);
340 return d->m_sprite->frameDuration();
343int QQuickAnimatedSprite::loops()
const
345 Q_D(
const QQuickAnimatedSprite);
349bool QQuickAnimatedSprite::paused()
const
351 Q_D(
const QQuickAnimatedSprite);
355int QQuickAnimatedSprite::currentFrame()
const
357 Q_D(
const QQuickAnimatedSprite);
358 return d->m_curFrame;
361QQuickAnimatedSprite::FinishBehavior QQuickAnimatedSprite::finishBehavior()
const
363 Q_D(
const QQuickAnimatedSprite);
364 return d->m_finishBehavior;
367bool QQuickAnimatedSprite::isCurrentFrameChangedConnected()
369 IS_SIGNAL_CONNECTED(
this, QQuickAnimatedSprite, currentFrameChanged, (
int));
372void QQuickAnimatedSprite::reloadImage()
374 if (!isComponentComplete())
379void QQuickAnimatedSprite::componentComplete()
381 Q_D(QQuickAnimatedSprite);
383 QQuickItem::componentComplete();
385 d->m_running =
false;
391
392
393
394
395
396
397
398
399void QQuickAnimatedSprite::start()
401 Q_D(QQuickAnimatedSprite);
405 if (!isComponentComplete())
409 d->m_timestamp.start();
410 if (d->m_spriteEngine) {
411 d->m_spriteEngine->stop(0);
412 d->m_spriteEngine->updateSprites(0);
413 d->m_spriteEngine->start(0);
415 emit currentFrameChanged(0);
416 emit runningChanged(
true);
421
422
423
424
425
426
427
428
429void QQuickAnimatedSprite::stop()
431 Q_D(QQuickAnimatedSprite);
434 d->m_running =
false;
435 if (!isComponentComplete())
437 d->m_pauseOffset = 0;
438 emit runningChanged(
false);
443
444
445
446
447void QQuickAnimatedSprite::advance(
int frames)
449 Q_D(QQuickAnimatedSprite);
453 d->m_curFrame += frames;
454 while (d->m_curFrame < 0)
455 d->m_curFrame += d->m_spriteEngine->maxFrames();
456 d->m_curFrame = d->m_curFrame % d->m_spriteEngine->maxFrames();
457 emit currentFrameChanged(d->m_curFrame);
461void QQuickAnimatedSprite::maybeUpdate()
463 QQuickItemPrivate *priv = QQuickItemPrivate::get(
this);
464 const auto &extraData = priv->extra;
465 if ((extraData.isAllocated() && extraData->effectRefCount > 0) || priv->effectiveVisible)
469void QQuickAnimatedSprite::itemChange(ItemChange change,
const ItemChangeData &value)
471 Q_D(QQuickAnimatedSprite);
472 if (change == ItemVisibleHasChanged && d->m_running && !d->m_paused)
474 QQuickItem::itemChange(change, value);
478
479
480
481
482
483
484
485void QQuickAnimatedSprite::pause()
487 Q_D(QQuickAnimatedSprite);
491 d->m_pauseOffset = d->m_timestamp.elapsed();
493 emit pausedChanged(
true);
498
499
500
501
502
503
504
505void QQuickAnimatedSprite::resume()
507 Q_D(QQuickAnimatedSprite);
511 d->m_pauseOffset = d->m_pauseOffset - d->m_timestamp.elapsed();
513 emit pausedChanged(
false);
517void QQuickAnimatedSprite::setRunning(
bool arg)
519 Q_D(QQuickAnimatedSprite);
521 if (d->m_running != arg) {
529void QQuickAnimatedSprite::setPaused(
bool arg)
531 Q_D(
const QQuickAnimatedSprite);
533 if (d->m_paused != arg) {
541void QQuickAnimatedSprite::setInterpolate(
bool arg)
543 Q_D(QQuickAnimatedSprite);
545 if (d->m_interpolate != arg) {
546 d->m_interpolate = arg;
547 Q_EMIT interpolateChanged(arg);
551void QQuickAnimatedSprite::setSource(
const QUrl &arg)
553 Q_D(QQuickAnimatedSprite);
555 if (d->m_sprite->m_source != arg) {
556 const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio());
557 d->m_sprite->setDevicePixelRatio(targetDevicePixelRatio);
558 d->m_sprite->setSource(arg);
559 Q_EMIT sourceChanged(arg);
564void QQuickAnimatedSprite::setReverse(
bool arg)
566 Q_D(QQuickAnimatedSprite);
568 if (d->m_sprite->m_reverse != arg) {
569 d->m_sprite->setReverse(arg);
570 Q_EMIT reverseChanged(arg);
574void QQuickAnimatedSprite::setFrameSync(
bool arg)
576 Q_D(QQuickAnimatedSprite);
578 if (d->m_sprite->m_frameSync != arg) {
579 d->m_sprite->setFrameSync(arg);
580 Q_EMIT frameSyncChanged(arg);
586void QQuickAnimatedSprite::setFrameCount(
int arg)
588 Q_D(QQuickAnimatedSprite);
590 if (d->m_sprite->m_frames != arg) {
591 d->m_sprite->setFrameCount(arg);
592 Q_EMIT frameCountChanged(arg);
597void QQuickAnimatedSprite::setFrameHeight(
int arg)
599 Q_D(QQuickAnimatedSprite);
601 if (d->m_sprite->m_frameHeight != arg) {
602 d->m_sprite->setFrameHeight(arg);
603 Q_EMIT frameHeightChanged(arg);
604 setImplicitHeight(frameHeight());
609void QQuickAnimatedSprite::setFrameWidth(
int arg)
611 Q_D(QQuickAnimatedSprite);
613 if (d->m_sprite->m_frameWidth != arg) {
614 d->m_sprite->setFrameWidth(arg);
615 Q_EMIT frameWidthChanged(arg);
616 setImplicitWidth(frameWidth());
621void QQuickAnimatedSprite::setFrameX(
int arg)
623 Q_D(QQuickAnimatedSprite);
625 if (d->m_sprite->m_frameX != arg) {
626 d->m_sprite->setFrameX(arg);
627 Q_EMIT frameXChanged(arg);
632void QQuickAnimatedSprite::setFrameY(
int arg)
634 Q_D(QQuickAnimatedSprite);
636 if (d->m_sprite->m_frameY != arg) {
637 d->m_sprite->setFrameY(arg);
638 Q_EMIT frameYChanged(arg);
643void QQuickAnimatedSprite::setFrameRate(qreal arg)
645 Q_D(QQuickAnimatedSprite);
647 if (d->m_sprite->m_frameRate != arg) {
648 d->m_sprite->setFrameRate(arg);
649 Q_EMIT frameRateChanged(arg);
655void QQuickAnimatedSprite::setFrameDuration(
int arg)
657 Q_D(QQuickAnimatedSprite);
659 if (d->m_sprite->m_frameDuration != arg) {
660 d->m_sprite->setFrameDuration(arg);
661 Q_EMIT frameDurationChanged(arg);
667void QQuickAnimatedSprite::resetFrameRate()
672void QQuickAnimatedSprite::resetFrameDuration()
674 setFrameDuration(-1);
677void QQuickAnimatedSprite::setLoops(
int arg)
679 Q_D(QQuickAnimatedSprite);
681 if (d->m_loops != arg) {
683 Q_EMIT loopsChanged(arg);
687void QQuickAnimatedSprite::setCurrentFrame(
int arg)
689 Q_D(QQuickAnimatedSprite);
691 if (d->m_curFrame != arg) {
693 Q_EMIT currentFrameChanged(arg);
698void QQuickAnimatedSprite::setFinishBehavior(FinishBehavior arg)
700 Q_D(QQuickAnimatedSprite);
702 if (d->m_finishBehavior != arg) {
703 d->m_finishBehavior = arg;
704 Q_EMIT finishBehaviorChanged(arg);
708void QQuickAnimatedSprite::createEngine()
710 Q_D(QQuickAnimatedSprite);
712 if (d->m_spriteEngine)
713 delete d->m_spriteEngine;
714 QList<QQuickSprite*> spriteList;
715 spriteList << d->m_sprite;
716 d->m_spriteEngine =
new QQuickSpriteEngine(QList<QQuickSprite*>(spriteList),
this);
717 d->m_spriteEngine->startAssemblingImage();
721QSGSpriteNode* QQuickAnimatedSprite::initNode()
723 Q_D(QQuickAnimatedSprite);
725 if (!d->m_spriteEngine) {
726 qmlWarning(
this) <<
"No sprite engine...";
728 }
else if (d->m_spriteEngine->status() == QQuickPixmap::Null) {
729 d->m_spriteEngine->startAssemblingImage();
732 }
else if (d->m_spriteEngine->status() == QQuickPixmap::Loading) {
737 QImage image = d->m_spriteEngine->assembledImage(d->sceneGraphRenderContext()->maxTextureSize());
749 setImplicitWidth(frameWidth());
750 setImplicitHeight(frameHeight());
752 QSGSpriteNode *node = d->sceneGraphContext()->createSpriteNode();
754 d->m_sheetSize = QSize(image.size() / image.devicePixelRatio());
755 node->setTexture(window()->createTextureFromImage(image));
756 d->m_spriteEngine->start(0);
758 node->setSourceA(QPoint(d->m_spriteEngine->spriteX(), d->m_spriteEngine->spriteY()));
759 node->setSourceB(QPoint(d->m_spriteEngine->spriteX(), d->m_spriteEngine->spriteY()));
760 node->setSpriteSize(QSize(d->m_spriteEngine->spriteWidth(), d->m_spriteEngine->spriteHeight()));
761 node->setSheetSize(d->m_sheetSize);
762 node->setSize(QSizeF(width(), height()));
766void QQuickAnimatedSprite::reset()
768 Q_D(QQuickAnimatedSprite);
769 d->m_pleaseReset =
true;
773QSGNode *QQuickAnimatedSprite::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
775 Q_D(QQuickAnimatedSprite);
777 if (d->m_pleaseReset) {
781 d->m_pleaseReset =
false;
784 QSGSpriteNode *node =
static_cast<QSGSpriteNode *>(oldNode);
789 prepareNextFrame(node);
791 if (d->m_running && !d->m_paused)
797void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node)
799 Q_D(QQuickAnimatedSprite);
801 int timeInt = d->m_timestamp.elapsed() + d->m_pauseOffset;
802 qreal time = timeInt / 1000.;
805 qreal progress = 0.0;
806 int lastFrame = d->m_curFrame;
807 if (d->m_running && !d->m_paused) {
808 const int nColumns = d->m_sheetSize.width() / d->m_spriteEngine->spriteWidth();
810 d->m_spriteEngine->updateSprites(timeInt);
813 qreal animT = d->m_spriteEngine->spriteStart()/1000.0;
814 const int frameCountInRow = d->m_spriteEngine->spriteFrames();
815 const qreal frameDuration = d->m_spriteEngine->spriteDuration() / frameCountInRow;
816 if (frameDuration > 0) {
817 qreal frame = (time - animT)/(frameDuration / 1000.0);
818 bool lastLoop = d->m_loops > 0 && d->m_curLoop == d->m_loops-1;
820 const int max = lastLoop ? frameCountInRow - 1 : frameCountInRow;
821 frame = qBound(qreal(0.0), frame, qreal(max));
823 progress = std::modf(frame,&intpart);
824 frameAt = (
int)intpart;
825 const int rowIndex = d->m_spriteEngine->spriteY()/frameHeight();
826 const int newFrame = rowIndex * nColumns + frameAt;
827 if (d->m_curFrame > newFrame)
829 d->m_curFrame = newFrame;
832 if (d->m_curFrame >= d->m_spriteEngine->maxFrames()) {
836 frameAt = d->m_curFrame % nColumns;
838 d->m_spriteEngine->advance();
841 if (d->m_loops > 0 && d->m_curLoop >= d->m_loops) {
842 if (d->m_finishBehavior == FinishAtInitialFrame)
845 frameAt = frameCount() - 1;
846 d->m_curFrame = frameAt;
847 d->m_running =
false;
848 emit runningChanged(
false);
853 frameAt = d->m_curFrame;
855 if (d->m_curFrame != lastFrame) {
856 if (isCurrentFrameChangedConnected())
857 emit currentFrameChanged(d->m_curFrame);
861 int frameCount = d->m_spriteEngine->spriteFrames();
862 bool reverse = d->m_spriteEngine->sprite()->reverse();
864 frameAt = (frameCount - 1) - frameAt;
866 int w = d->m_spriteEngine->spriteWidth();
867 int h = d->m_spriteEngine->spriteHeight();
871 int spriteY = d->m_spriteEngine->spriteY();
873 int rows = d->m_spriteEngine->maxFrames() * d->m_spriteEngine->spriteWidth() / d->m_sheetSize.width();
874 spriteY -= rows * d->m_spriteEngine->spriteHeight();
875 frameAt = (frameCount - 1) - frameAt;
878 int position = frameAt * d->m_spriteEngine->spriteWidth() + d->m_spriteEngine->spriteX();
879 int row = position / d->m_sheetSize.width();
881 x1 = (position - (row * d->m_sheetSize.width()));
882 y1 = (row * d->m_spriteEngine->spriteHeight() + spriteY);
884 x1 = d->m_spriteEngine->spriteX() + frameAt * w;
885 y1 = d->m_spriteEngine->spriteY();
898 x2 = d->m_sheetSize.width() - w;
902 int maxRowFrames = d->m_sheetSize.width() / d->m_spriteEngine->spriteWidth();
903 if (d->m_spriteEngine->maxFrames() % maxRowFrames)
904 x2 = ((d->m_spriteEngine->maxFrames() % maxRowFrames) - 1) * w;
906 y2 = d->m_sheetSize.height() - h;
910 if (frameAt < (frameCount-1)) {
916 if (y2 >= d->m_sheetSize.height())
921 node->setSourceA(QPoint(x1, y1));
922 node->setSourceB(QPoint(x2, y2));
923 node->setSpriteSize(QSize(w, h));
924 node->setTime(d->m_interpolate ? progress : 0.0);
925 node->setSize(QSizeF(width(), height()));
926 node->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);
932#include "moc_qquickanimatedsprite_p.cpp"
Combined button and popup list for selecting options.