9#include <QtQuick/private/qsgcontext_p.h>
10#include <private/qsgadaptationlayer_p.h>
11#include <QtQuick/qsgnode.h>
12#include <QtQuick/qsgtexturematerial.h>
13#include <QtQuick/qsgtexture.h>
14#include <QtQuick/qquickwindow.h>
15#include <QtQml/qqmlinfo.h>
24
25
26
27
28
29
30
31
32
33
34
35
36
38
39
40
41
42
43
45
46
47
48
49
50
51
53
54
55
56
58
59
60
61
62
63
64
65
66
67
68
69
71
72
73
74
76
77
78
79
82QQuickSpriteSequence::QQuickSpriteSequence(QQuickItem *parent) :
83 QQuickItem(*(
new QQuickSpriteSequencePrivate), parent)
85 setFlag(ItemHasContents);
86 connect(
this, SIGNAL(runningChanged(
bool)),
87 this, SLOT(update()));
90void QQuickSpriteSequence::jumpTo(
const QString &sprite)
92 Q_D(QQuickSpriteSequence);
93 if (!d->m_spriteEngine)
95 d->m_spriteEngine->setGoal(d->m_spriteEngine->stateIndex(sprite), 0,
true);
98void QQuickSpriteSequence::setGoalSprite(
const QString &sprite)
100 Q_D(QQuickSpriteSequence);
101 if (d->m_goalState != sprite){
102 d->m_goalState = sprite;
103 emit goalSpriteChanged(sprite);
104 if (d->m_spriteEngine)
105 d->m_spriteEngine->setGoal(d->m_spriteEngine->stateIndex(sprite));
109void QQuickSpriteSequence::setRunning(
bool arg)
111 Q_D(QQuickSpriteSequence);
112 if (d->m_running != arg) {
114 Q_EMIT runningChanged(arg);
118void QQuickSpriteSequence::setInterpolate(
bool arg)
120 Q_D(QQuickSpriteSequence);
121 if (d->m_interpolate != arg) {
122 d->m_interpolate = arg;
123 Q_EMIT interpolateChanged(arg);
127QQmlListProperty<QQuickSprite> QQuickSpriteSequence::sprites()
129 Q_D(QQuickSpriteSequence);
130 return QQmlListProperty<QQuickSprite>(
this, &d->m_sprites,
131 spriteAppend, spriteCount, spriteAt,
132 spriteClear, spriteReplace, spriteRemoveLast);
135bool QQuickSpriteSequence::running()
const
137 Q_D(
const QQuickSpriteSequence);
141bool QQuickSpriteSequence::interpolate()
const
143 Q_D(
const QQuickSpriteSequence);
144 return d->m_interpolate;
147QString QQuickSpriteSequence::goalSprite()
const
149 Q_D(
const QQuickSpriteSequence);
150 return d->m_goalState;
153QString QQuickSpriteSequence::currentSprite()
const
155 Q_D(
const QQuickSpriteSequence);
156 return d->m_curState;
159void QQuickSpriteSequence::createEngine()
161 Q_D(QQuickSpriteSequence);
163 if (d->m_spriteEngine)
164 delete d->m_spriteEngine;
165 if (d->m_sprites.size()) {
166 d->m_spriteEngine =
new QQuickSpriteEngine(d->m_sprites,
this);
167 if (!d->m_goalState.isEmpty())
168 d->m_spriteEngine->setGoal(d->m_spriteEngine->stateIndex(d->m_goalState));
170 d->m_spriteEngine =
nullptr;
175QSGSpriteNode *QQuickSpriteSequence::initNode()
177 Q_D(QQuickSpriteSequence);
179 if (!d->m_spriteEngine) {
180 qmlWarning(
this) <<
"No sprite engine...";
182 }
else if (d->m_spriteEngine->status() == QQuickPixmap::Null) {
183 d->m_spriteEngine->startAssemblingImage();
186 }
else if (d->m_spriteEngine->status() == QQuickPixmap::Loading) {
191 QImage image = d->m_spriteEngine->assembledImage(d->sceneGraphRenderContext()->maxTextureSize());
195 QSGSpriteNode *node = d->sceneGraphContext()->createSpriteNode();
197 d->m_sheetSize = QSize(image.size() / image.devicePixelRatio());
198 node->setTexture(window()->createTextureFromImage(image));
199 d->m_spriteEngine->start(0);
201 node->setSourceA(QPoint(d->m_spriteEngine->spriteX(), d->m_spriteEngine->spriteY()));
202 node->setSourceB(QPoint(d->m_spriteEngine->spriteX(), d->m_spriteEngine->spriteY()));
203 node->setSpriteSize(QSize(d->m_spriteEngine->spriteWidth(), d->m_spriteEngine->spriteHeight()));
204 node->setSheetSize(d->m_sheetSize);
205 node->setSize(QSizeF(width(), height()));
207 d->m_curState = d->m_spriteEngine->state(d->m_spriteEngine->curState())->name();
208 emit currentSpriteChanged(d->m_curState);
209 d->m_timestamp.start();
213void QQuickSpriteSequence::reset()
215 Q_D(QQuickSpriteSequence);
216 d->m_pleaseReset =
true;
219QSGNode *QQuickSpriteSequence::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
221 Q_D(QQuickSpriteSequence);
223 if (d->m_pleaseReset) {
227 d->m_pleaseReset =
false;
230 QSGSpriteNode *node =
static_cast<QSGSpriteNode *>(oldNode);
235 prepareNextFrame(node);
244void QQuickSpriteSequence::prepareNextFrame(QSGSpriteNode *node)
246 Q_D(QQuickSpriteSequence);
248 uint timeInt = d->m_timestamp.elapsed();
249 qreal time = timeInt / 1000.;
252 d->m_spriteEngine->updateSprites(timeInt);
253 if (d->m_curStateIdx != d->m_spriteEngine->curState()) {
254 d->m_curStateIdx = d->m_spriteEngine->curState();
255 d->m_curState = d->m_spriteEngine->state(d->m_spriteEngine->curState())->name();
256 emit currentSpriteChanged(d->m_curState);
261 qreal animT = d->m_spriteEngine->spriteStart()/1000.0;
262 qreal frameCount = d->m_spriteEngine->spriteFrames();
263 qreal frameDuration = d->m_spriteEngine->spriteDuration()/frameCount;
266 if (frameDuration > 0) {
267 qreal frame = (time - animT)/(frameDuration / 1000.0);
268 frame = qBound(qreal(0.0), frame, frameCount - qreal(1.0));
269 progress = std::modf(frame,&frameAt);
272 if (d->m_curFrame >= frameCount){
274 d->m_spriteEngine->advance();
276 frameAt = d->m_curFrame;
279 if (d->m_spriteEngine->sprite()->reverse())
280 frameAt = (d->m_spriteEngine->spriteFrames() - 1) - frameAt;
281 int y = d->m_spriteEngine->spriteY();
282 int w = d->m_spriteEngine->spriteWidth();
283 int h = d->m_spriteEngine->spriteHeight();
284 int x1 = d->m_spriteEngine->spriteX();
287 if (frameAt < (frameCount-1))
290 node->setSourceA(QPoint(x1, y));
291 node->setSourceB(QPoint(x2, y));
292 node->setSpriteSize(QSize(w, h));
293 node->setTime(d->m_interpolate ? progress : 0.0);
294 node->setSize(QSizeF(width(), height()));
295 node->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest);
301#include "moc_qquickspritesequence_p.cpp"