diff options
-rw-r--r-- | src/quick/items/qquickanimatedsprite.cpp | 92 | ||||
-rw-r--r-- | src/quick/items/qquickanimatedsprite_p.h | 10 | ||||
-rw-r--r-- | tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp | 22 |
3 files changed, 71 insertions, 53 deletions
diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp index 5f77c6461f..d7f3f4f83b 100644 --- a/src/quick/items/qquickanimatedsprite.cpp +++ b/src/quick/items/qquickanimatedsprite.cpp @@ -310,8 +310,6 @@ struct AnimatedSpriteVertices { //TODO: Implicitly size element to size of sprite QQuickAnimatedSprite::QQuickAnimatedSprite(QQuickItem *parent) : QQuickItem(parent) - , m_node(0) - , m_material(0) , m_sprite(new QQuickSprite(this)) , m_spriteEngine(0) , m_curFrame(0) @@ -325,9 +323,9 @@ QQuickAnimatedSprite::QQuickAnimatedSprite(QQuickItem *parent) : { setFlag(ItemHasContents); connect(this, SIGNAL(widthChanged()), - this, SLOT(sizeVertices())); + this, SLOT(reset())); connect(this, SIGNAL(heightChanged()), - this, SLOT(sizeVertices())); + this, SLOT(reset())); } bool QQuickAnimatedSprite::isCurrentFrameChangedConnected() @@ -455,12 +453,9 @@ static QSGGeometry::AttributeSet AnimatedSprite_AttributeSet = AnimatedSprite_Attributes }; -void QQuickAnimatedSprite::sizeVertices() +void QQuickAnimatedSprite::sizeVertices(QSGGeometryNode *node) { - if (!m_node) - return; - - AnimatedSpriteVertices *p = (AnimatedSpriteVertices *) m_node->geometry()->vertexData(); + AnimatedSpriteVertices *p = (AnimatedSpriteVertices *) node->geometry()->vertexData(); p->v1.x = 0; p->v1.y = 0; @@ -488,21 +483,21 @@ QSGGeometryNode* QQuickAnimatedSprite::buildNode() return 0; } - m_material = new QQuickAnimatedSpriteMaterial(); + QQuickAnimatedSpriteMaterial *material = new QQuickAnimatedSpriteMaterial(); QImage image = m_spriteEngine->assembledImage(); //Engine prints errors if there are any if (image.isNull()) return 0; m_sheetSize = QSizeF(image.size()); - m_material->texture = window()->createTextureFromImage(image); + material->texture = window()->createTextureFromImage(image); m_spriteEngine->start(0); - m_material->animT = 0; - m_material->animX1 = m_spriteEngine->spriteX() / m_sheetSize.width(); - m_material->animY1 = m_spriteEngine->spriteY() / m_sheetSize.height(); - m_material->animX2 = m_material->animX1; - m_material->animY2 = m_material->animY1; - m_material->animW = m_spriteEngine->spriteWidth() / m_sheetSize.width(); - m_material->animH = m_spriteEngine->spriteHeight() / m_sheetSize.height(); + material->animT = 0; + material->animX1 = m_spriteEngine->spriteX() / m_sheetSize.width(); + material->animY1 = m_spriteEngine->spriteY() / m_sheetSize.height(); + material->animX2 = material->animX1; + material->animY2 = material->animY1; + material->animW = m_spriteEngine->spriteWidth() / m_sheetSize.width(); + material->animH = m_spriteEngine->spriteHeight() / m_sheetSize.height(); int vCount = 4; int iCount = 6; @@ -511,7 +506,7 @@ QSGGeometryNode* QQuickAnimatedSprite::buildNode() AnimatedSpriteVertices *p = (AnimatedSpriteVertices *) g->vertexData(); - QRectF texRect = m_material->texture->normalizedTextureSubRect(); + QRectF texRect = material->texture->normalizedTextureSubRect(); p->v1.tx = texRect.topLeft().x(); p->v1.ty = texRect.topLeft().y(); @@ -534,51 +529,51 @@ QSGGeometryNode* QQuickAnimatedSprite::buildNode() indices[5] = 2; - m_node = new QSGGeometryNode(); - m_node->setGeometry(g); - m_node->setMaterial(m_material); - m_node->setFlag(QSGGeometryNode::OwnsMaterial); - m_node->setFlag(QSGGeometryNode::OwnsGeometry); - sizeVertices(); - return m_node; + QSGGeometryNode *node = new QSGGeometryNode(); + node->setGeometry(g); + node->setMaterial(material); + node->setFlag(QSGGeometryNode::OwnsMaterial); + node->setFlag(QSGGeometryNode::OwnsGeometry); + sizeVertices(node); + return node; } void QQuickAnimatedSprite::reset() { m_pleaseReset = true; + update(); } -QSGNode *QQuickAnimatedSprite::updatePaintNode(QSGNode *, UpdatePaintNodeData *) +QSGNode *QQuickAnimatedSprite::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { if (m_pleaseReset) { - delete m_node; + delete oldNode; - m_node = 0; - m_material = 0; + oldNode = 0; m_pleaseReset = false; } - prepareNextFrame(); + QSGGeometryNode *node = static_cast<QSGGeometryNode *>(oldNode); + if (!node) + node = buildNode(); + + if (node) + prepareNextFrame(node); if (m_running) { if (!m_paused) update(); - if (m_node) { - m_node->markDirty(QSGNode::DirtyMaterial); + if (node) { + node->markDirty(QSGNode::DirtyMaterial); } } - return m_node; + return node; } -void QQuickAnimatedSprite::prepareNextFrame() +void QQuickAnimatedSprite::prepareNextFrame(QSGGeometryNode *node) { - if (m_node == 0) - m_node = buildNode(); - if (m_node == 0) //error creating node - return; - int timeInt = m_timestamp.elapsed() + m_pauseOffset; qreal time = timeInt / 1000.; @@ -694,14 +689,15 @@ void QQuickAnimatedSprite::prepareNextFrame() } } - m_material->animX1 = x1; - m_material->animY1 = y1; - m_material->animX2 = x2; - m_material->animY2 = y2; - m_material->animW = w; - m_material->animH = h; - m_material->animT = m_interpolate ? progress : 0.0; - m_material->texture->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest); + QQuickAnimatedSpriteMaterial *material = static_cast<QQuickAnimatedSpriteMaterial *>(node->material()); + material->animX1 = x1; + material->animY1 = y1; + material->animX2 = x2; + material->animY2 = y2; + material->animW = w; + material->animH = h; + material->animT = m_interpolate ? progress : 0.0; + material->texture->setFiltering(smooth() ? QSGTexture::Linear : QSGTexture::Nearest); } QT_END_NAMESPACE diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h index ffaddefb47..5b181640f9 100644 --- a/src/quick/items/qquickanimatedsprite_p.h +++ b/src/quick/items/qquickanimatedsprite_p.h @@ -351,19 +351,19 @@ public Q_SLOTS: private Q_SLOTS: void createEngine(); - void sizeVertices(); + void sizeVertices(QSGGeometryNode *node); -protected: +protected Q_SLOTS: void reset(); + +protected: void componentComplete() Q_DECL_OVERRIDE; QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE; private: bool isCurrentFrameChangedConnected(); - void prepareNextFrame(); + void prepareNextFrame(QSGGeometryNode *node); void reloadImage(); QSGGeometryNode* buildNode(); - QSGGeometryNode *m_node; - QQuickAnimatedSpriteMaterial *m_material; QQuickSprite* m_sprite; QQuickSpriteEngine* m_spriteEngine; QElapsedTimer m_timestamp; diff --git a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp index c9e1a43414..3cb7ff511f 100644 --- a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp +++ b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp @@ -35,6 +35,7 @@ #include <QtQuick/qquickview.h> #include <private/qabstractanimation_p.h> #include <private/qquickanimatedsprite_p.h> +#include <private/qquickitem_p.h> #include <QtGui/qpainter.h> #include <QtGui/qopenglcontext.h> #include <QtGui/qopenglfunctions.h> @@ -53,6 +54,7 @@ private slots: void test_frameChangedSignal(); void test_largeAnimation_data(); void test_largeAnimation(); + void test_reparenting(); }; void tst_qquickanimatedsprite::initTestCase() @@ -268,6 +270,26 @@ void tst_qquickanimatedsprite::test_largeAnimation() delete window; } +void tst_qquickanimatedsprite::test_reparenting() +{ + QQuickView window; + window.setSource(testFileUrl("basic.qml")); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + QVERIFY(window.rootObject()); + QQuickAnimatedSprite* sprite = window.rootObject()->findChild<QQuickAnimatedSprite*>("sprite"); + QVERIFY(sprite); + + QTRY_VERIFY(sprite->running()); + sprite->setParentItem(0); + + sprite->setParentItem(window.rootObject()); + // don't crash (QTBUG-51162) + sprite->polish(); + QTRY_COMPARE(QQuickItemPrivate::get(sprite)->polishScheduled, true); + QTRY_COMPARE(QQuickItemPrivate::get(sprite)->polishScheduled, false); +} QTEST_MAIN(tst_qquickanimatedsprite) |