9#include <QtQuick/private/qsgcontext_p.h>
10#include <QtQuick/private/qquickitem_p.h>
11#include <private/qsgadaptationlayer_p.h>
12#include <private/qqmlglobal_p.h>
13#include <QtQuick/qsgnode.h>
14#include <QtQuick/qsgtexturematerial.h>
15#include <QtQuick/qsgtexture.h>
16#include <QtQuick/qquickwindow.h>
17#include <QtQml/qqmlinfo.h>
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
98
99
100
101
102
105
106
107
108
109
110
113
114
115
116
117
118
119
122
123
124
125
126
127
128
129
130
133
134
135
136
137
138
139
140
141
144
145
146
147
149
150
151
152
153
154
156
157
158
159
160
161
163
164
165
166
167
168
170
171
172
173
174
175
177
178
179
180
181
182
183
184
185
188
189
190
191
192
193
196
197
198
199
200
201
202
203
204
205
206
207
210
211
212
213
214
215
216
217
220
221
222
223
224
225
228
229
230
231
232
235
236
237
238
239
240
241
242
243
244
245
248
249
250
251
254
255
256
257
258
259
260
261
263QQuickAnimatedSprite::QQuickAnimatedSprite(QQuickItem *parent) :
264 QQuickItem(*(
new QQuickAnimatedSpritePrivate), parent)
266 Q_D(QQuickAnimatedSprite);
267 d->m_sprite =
new QQuickSprite(
this);
269 setFlag(ItemHasContents);
270 connect(
this, SIGNAL(widthChanged()),
271 this, SLOT(reset()));
272 connect(
this, SIGNAL(heightChanged()),
273 this, SLOT(reset()));
276bool QQuickAnimatedSprite::running()
const
278 Q_D(
const QQuickAnimatedSprite);
282bool QQuickAnimatedSprite::interpolate()
const
284 Q_D(
const QQuickAnimatedSprite);
285 return d->m_interpolate;
288QUrl QQuickAnimatedSprite::source()
const
290 Q_D(
const QQuickAnimatedSprite);
291 return d->m_sprite->source();
294bool QQuickAnimatedSprite::reverse()
const
296 Q_D(
const QQuickAnimatedSprite);
297 return d->m_sprite->reverse();
300bool QQuickAnimatedSprite::frameSync()
const
302 Q_D(
const QQuickAnimatedSprite);
303 return d->m_sprite->frameSync();
306int QQuickAnimatedSprite::frameCount()
const
308 Q_D(
const QQuickAnimatedSprite);
309 return d->m_sprite->frames();
312int QQuickAnimatedSprite::frameHeight()
const
314 Q_D(
const QQuickAnimatedSprite);
315 return d->m_sprite->frameHeight();
318int QQuickAnimatedSprite::frameWidth()
const
320 Q_D(
const QQuickAnimatedSprite);
321 return d->m_sprite->frameWidth();
324int QQuickAnimatedSprite::frameX()
const
326 Q_D(
const QQuickAnimatedSprite);
327 return d->m_sprite->frameX();
330int QQuickAnimatedSprite::frameY()
const
332 Q_D(
const QQuickAnimatedSprite);
333 return d->m_sprite->frameY();
336qreal QQuickAnimatedSprite::frameRate()
const
338 Q_D(
const QQuickAnimatedSprite);
339 return d->m_sprite->frameRate();
342int QQuickAnimatedSprite::frameDuration()
const
344 Q_D(
const QQuickAnimatedSprite);
345 return d->m_sprite->frameDuration();
348int QQuickAnimatedSprite::loops()
const
350 Q_D(
const QQuickAnimatedSprite);
354bool QQuickAnimatedSprite::paused()
const
356 Q_D(
const QQuickAnimatedSprite);
360int QQuickAnimatedSprite::currentFrame()
const
362 Q_D(
const QQuickAnimatedSprite);
363 return d->m_curFrame;
366QQuickAnimatedSprite::FinishBehavior QQuickAnimatedSprite::finishBehavior()
const
368 Q_D(
const QQuickAnimatedSprite);
369 return d->m_finishBehavior;
372bool QQuickAnimatedSprite::isCurrentFrameChangedConnected()
374 IS_SIGNAL_CONNECTED(
this, QQuickAnimatedSprite, currentFrameChanged, (
int));
377void QQuickAnimatedSprite::reloadImage()
379 if (!isComponentComplete())
384void QQuickAnimatedSprite::componentComplete()
386 Q_D(QQuickAnimatedSprite);
388 QQuickItem::componentComplete();
390 d->m_running =
false;
396
397
398
399
400
401
402
403
404void QQuickAnimatedSprite::start()
406 Q_D(QQuickAnimatedSprite);
410 if (!isComponentComplete())
414 d->m_timestamp.start();
415 if (d->m_spriteEngine) {
416 d->m_spriteEngine->stop(0);
417 d->m_spriteEngine->updateSprites(0);
418 d->m_spriteEngine->start(0);
420 emit currentFrameChanged(0);
421 emit runningChanged(
true);
426
427
428
429
430
431
432
433
434void QQuickAnimatedSprite::stop()
436 Q_D(QQuickAnimatedSprite);
439 d->m_running =
false;
440 if (!isComponentComplete())
442 d->m_pauseOffset = 0;
443 emit runningChanged(
false);
448
449
450
451
452void QQuickAnimatedSprite::advance(
int frames)
454 Q_D(QQuickAnimatedSprite);
458 d->m_curFrame += frames;
459 while (d->m_curFrame < 0)
460 d->m_curFrame += d->m_spriteEngine->maxFrames();
461 d->m_curFrame = d->m_curFrame % d->m_spriteEngine->maxFrames();
462 emit currentFrameChanged(d->m_curFrame);
466void QQuickAnimatedSprite::maybeUpdate()
468 QQuickItemPrivate *priv = QQuickItemPrivate::get(
this);
469 const auto &extraData = priv->extra;
470 if ((extraData.isAllocated() && extraData->effectRefCount > 0) || priv->effectiveVisible)
474void QQuickAnimatedSprite::itemChange(ItemChange change,
const ItemChangeData &value)
476 Q_D(QQuickAnimatedSprite);
477 if (change == ItemVisibleHasChanged && d->m_running && !d->m_paused)
479 QQuickItem::itemChange(change, value);
483
484
485
486
487
488
489
490void QQuickAnimatedSprite::pause()
492 Q_D(QQuickAnimatedSprite);
496 d->m_pauseOffset = d->m_timestamp.elapsed();
498 emit pausedChanged(
true);
503
504
505
506
507
508
509
510void QQuickAnimatedSprite::resume()
512 Q_D(QQuickAnimatedSprite);
516 d->m_pauseOffset = d->m_pauseOffset - d->m_timestamp.elapsed();
518 emit pausedChanged(
false);
522void QQuickAnimatedSprite::setRunning(
bool arg)
524 Q_D(QQuickAnimatedSprite);
526 if (d->m_running != arg) {
534void QQuickAnimatedSprite::setPaused(
bool arg)
536 Q_D(
const QQuickAnimatedSprite);
538 if (d->m_paused != arg) {
546void QQuickAnimatedSprite::setInterpolate(
bool arg)
548 Q_D(QQuickAnimatedSprite);
550 if (d->m_interpolate != arg) {
551 d->m_interpolate = arg;
552 Q_EMIT interpolateChanged(arg);
556void QQuickAnimatedSprite::setSource(
const QUrl &arg)
558 Q_D(QQuickAnimatedSprite);
560 if (d->m_sprite->m_source != arg) {
561 const qreal targetDevicePixelRatio = d->effectiveDevicePixelRatio();
562 d->m_sprite->setDevicePixelRatio(targetDevicePixelRatio);
563 d->m_sprite->setSource(arg);
564 Q_EMIT sourceChanged(arg);
569void QQuickAnimatedSprite::setReverse(
bool arg)
571 Q_D(QQuickAnimatedSprite);
573 if (d->m_sprite->m_reverse != arg) {
574 d->m_sprite->setReverse(arg);
575 Q_EMIT reverseChanged(arg);
579void QQuickAnimatedSprite::setFrameSync(
bool arg)
581 Q_D(QQuickAnimatedSprite);
583 if (d->m_sprite->m_frameSync != arg) {
584 d->m_sprite->setFrameSync(arg);
585 Q_EMIT frameSyncChanged(arg);
591void QQuickAnimatedSprite::setFrameCount(
int arg)
593 Q_D(QQuickAnimatedSprite);
595 if (d->m_sprite->m_frames != arg) {
596 d->m_sprite->setFrameCount(arg);
597 Q_EMIT frameCountChanged(arg);
602void QQuickAnimatedSprite::setFrameHeight(
int arg)
604 Q_D(QQuickAnimatedSprite);
606 if (d->m_sprite->m_frameHeight != arg) {
607 d->m_sprite->setFrameHeight(arg);
608 Q_EMIT frameHeightChanged(arg);
609 setImplicitHeight(frameHeight());
614void QQuickAnimatedSprite::setFrameWidth(
int arg)
616 Q_D(QQuickAnimatedSprite);
618 if (d->m_sprite->m_frameWidth != arg) {
619 d->m_sprite->setFrameWidth(arg);
620 Q_EMIT frameWidthChanged(arg);
621 setImplicitWidth(frameWidth());
626void QQuickAnimatedSprite::setFrameX(
int arg)
628 Q_D(QQuickAnimatedSprite);
630 if (d->m_sprite->m_frameX != arg) {
631 d->m_sprite->setFrameX(arg);
632 Q_EMIT frameXChanged(arg);
637void QQuickAnimatedSprite::setFrameY(
int arg)
639 Q_D(QQuickAnimatedSprite);
641 if (d->m_sprite->m_frameY != arg) {
642 d->m_sprite->setFrameY(arg);
643 Q_EMIT frameYChanged(arg);
648void QQuickAnimatedSprite::setFrameRate(qreal arg)
650 Q_D(QQuickAnimatedSprite);
652 if (d->m_sprite->m_frameRate != arg) {
653 d->m_sprite->setFrameRate(arg);
654 Q_EMIT frameRateChanged(arg);
660void QQuickAnimatedSprite::setFrameDuration(
int arg)
662 Q_D(QQuickAnimatedSprite);
664 if (d->m_sprite->m_frameDuration != arg) {
665 d->m_sprite->setFrameDuration(arg);
666 Q_EMIT frameDurationChanged(arg);
672void QQuickAnimatedSprite::resetFrameRate()
677void QQuickAnimatedSprite::resetFrameDuration()
679 setFrameDuration(-1);
682void QQuickAnimatedSprite::setLoops(
int arg)
684 Q_D(QQuickAnimatedSprite);
686 if (d->m_loops != arg) {
688 Q_EMIT loopsChanged(arg);
692void QQuickAnimatedSprite::setCurrentFrame(
int arg)
694 Q_D(QQuickAnimatedSprite);
696 if (d->m_curFrame != arg) {
698 Q_EMIT currentFrameChanged(arg);
703void QQuickAnimatedSprite::setFinishBehavior(FinishBehavior arg)
705 Q_D(QQuickAnimatedSprite);
707 if (d->m_finishBehavior != arg) {
708 d->m_finishBehavior = arg;
709 Q_EMIT finishBehaviorChanged(arg);
713void QQuickAnimatedSprite::createEngine()
715 Q_D(QQuickAnimatedSprite);
717 if (d->m_spriteEngine)
718 delete d->m_spriteEngine;
719 QList<QQuickSprite*> spriteList;
720 spriteList << d->m_sprite;
721 d->m_spriteEngine =
new QQuickSpriteEngine(QList<QQuickSprite*>(spriteList),
this);
722 d->m_spriteEngine->startAssemblingImage();
726QSGSpriteNode* QQuickAnimatedSprite::initNode()
728 Q_D(QQuickAnimatedSprite);
730 if (!d->m_spriteEngine) {
731 qmlWarning(
this) <<
"No sprite engine...";
733 }
else if (d->m_spriteEngine->status() == QQuickPixmap::Null) {
734 d->m_spriteEngine->startAssemblingImage();
737 }
else if (d->m_spriteEngine->status() == QQuickPixmap::Loading) {
742 QImage image = d->m_spriteEngine->assembledImage(d->sceneGraphRenderContext()->maxTextureSize());
754 setImplicitWidth(frameWidth());
755 setImplicitHeight(frameHeight());
757 QSGSpriteNode *node = d->sceneGraphContext()->createSpriteNode();
759 d->m_sheetSize = QSize(image.size() / image.devicePixelRatio());
760 node->setTexture(window()->createTextureFromImage(image));
761 d->m_spriteEngine->start(0);
763 node->setSourceA(QPoint(d->m_spriteEngine->spriteX(), d->m_spriteEngine->spriteY()));
764 node->setSourceB(QPoint(d->m_spriteEngine->spriteX(), d->m_spriteEngine->spriteY()));
765 node->setSpriteSize(QSize(d->m_spriteEngine->spriteWidth(), d->m_spriteEngine->spriteHeight()));
766 node->setSheetSize(d->m_sheetSize);
767 node->setSize(QSizeF(width(), height()));
771void QQuickAnimatedSprite::reset()
773 Q_D(QQuickAnimatedSprite);
774 d->m_pleaseReset =
true;
778QSGNode *QQuickAnimatedSprite::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
780 Q_D(QQuickAnimatedSprite);
782 if (d->m_pleaseReset) {
786 d->m_pleaseReset =
false;
789 QSGSpriteNode *node =
static_cast<QSGSpriteNode *>(oldNode);
794 prepareNextFrame(node);
796 if (d->m_running && !d->m_paused)
802void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node)
804 Q_D(QQuickAnimatedSprite);
806 int timeInt = d->m_timestamp.elapsed() + d->m_pauseOffset;
807 qreal time = timeInt / 1000.;
810 qreal progress = 0.0;
811 int lastFrame = d->m_curFrame;
812 if (d->m_running && !d->m_paused) {
813 const int nColumns = d->m_sheetSize.width() / d->m_spriteEngine->spriteWidth();
815 d->m_spriteEngine->updateSprites(timeInt);
818 qreal animT = d->m_spriteEngine->spriteStart()/1000.0;
819 const int frameCountInRow = d->m_spriteEngine->spriteFrames();
820 const qreal frameDuration = d->m_spriteEngine->spriteDuration() / frameCountInRow;
821 if (frameDuration > 0) {
822 qreal frame = (time - animT)/(frameDuration / 1000.0);
823 bool lastLoop = d->m_loops > 0 && d->m_curLoop == d->m_loops-1;
825 const int max = lastLoop ? frameCountInRow - 1 : frameCountInRow;
826 frame = qBound(qreal(0.0), frame, qreal(max));
828 progress = std::modf(frame,&intpart);
829 frameAt = (
int)intpart;
830 const int rowIndex = d->m_spriteEngine->spriteY()/frameHeight();
831 const int newFrame = rowIndex * nColumns + frameAt;
832 if (d->m_curFrame > newFrame)
834 d->m_curFrame = newFrame;
837 if (d->m_curFrame >= d->m_spriteEngine->maxFrames()) {
841 frameAt = d->m_curFrame % nColumns;
843 d->m_spriteEngine->advance();
846 if (d->m_loops > 0 && d->m_curLoop >= d->m_loops) {
847 if (d->m_finishBehavior == FinishAtInitialFrame)
850 frameAt = frameCount() - 1;
851 d->m_curFrame = frameAt;
852 d->m_running =
false;
853 emit runningChanged(
false);
858 frameAt = d->m_curFrame;
860 if (d->m_curFrame != lastFrame) {
861 if (isCurrentFrameChangedConnected())
862 emit currentFrameChanged(d->m_curFrame);
866 int frameCount = d->m_spriteEngine->spriteFrames();
867 bool reverse = d->m_spriteEngine->sprite()->reverse();
869 frameAt = (frameCount - 1) - frameAt;
871 int w = d->m_spriteEngine->spriteWidth();
872 int h = d->m_spriteEngine->spriteHeight();
876 int spriteY = d->m_spriteEngine->spriteY();
878 int rows = d->m_spriteEngine->maxFrames() * d->m_spriteEngine->spriteWidth() / d->m_sheetSize.width();
879 spriteY -= rows * d->m_spriteEngine->spriteHeight();
880 frameAt = (frameCount - 1) - frameAt;
883 int position = frameAt * d->m_spriteEngine->spriteWidth() + d->m_spriteEngine->spriteX();
884 int row = position / d->m_sheetSize.width();
886 x1 = (position - (row * d->m_sheetSize.width()));
887 y1 = (row * d->m_spriteEngine->spriteHeight() + spriteY);
889 x1 = d->m_spriteEngine->spriteX() + frameAt * w;
890 y1 = d->m_spriteEngine->spriteY();
903 x2 = d->m_sheetSize.width() - w;
907 int maxRowFrames = d->m_sheetSize.width() / d->m_spriteEngine->spriteWidth();
908 if (d->m_spriteEngine->maxFrames() % maxRowFrames)
909 x2 = ((d->m_spriteEngine->maxFrames() % maxRowFrames) - 1) * w;
911 y2 = d->m_sheetSize.height() - h;
915 if (frameAt < (frameCount-1)) {
921 if (y2 >= d->m_sheetSize.height())
926 node->setSourceA(QPoint(x1, y1));
927 node->setSourceB(QPoint(x2, y2));
928 node->setSpriteSize(QSize(w, h));
929 node->setTime(d->m_interpolate ? progress : 0.0);
930 node->setSize(QSizeF(width(), height()));
931 node->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);
937#include "moc_qquickanimatedsprite_p.cpp"
Combined button and popup list for selecting options.