aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2012-01-18 10:32:33 +1000
committerQt by Nokia <qt-info@nokia.com>2012-01-27 06:17:51 +0100
commit15c00d747e24dae3b2681e6af07cfba3bdb6f74c (patch)
tree3b79f3fed858ac0a7e7568d79c93f8454b3c0e13 /src
parent3a03373ad29ee3f66878e008eb7f56156cbbd06f (diff)
Update Sprite API
Added the following properties frameSync (replaces duration: -1) frameRate frameRateVariation frameDuration frameDurationVariation frameX (not yet implemented) frameY (not yet implemented) reverse (not yet implemented) Started the process of duration meaning animation duration instead of frameDuration, but some grace period is being allowed for the transition Change-Id: I0771a55d1708ba999483f76796f0323043b8a4db Reviewed-by: Alan Alpert <alan.alpert@nokia.com> Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquicksprite.cpp123
-rw-r--r--src/quick/items/qquicksprite_p.h173
-rw-r--r--src/quick/items/qquickspriteengine.cpp30
-rw-r--r--src/quick/items/qquickspriteengine_p.h60
4 files changed, 315 insertions, 71 deletions
diff --git a/src/quick/items/qquicksprite.cpp b/src/quick/items/qquicksprite.cpp
index 4c7dafafbb..8b5369d3f6 100644
--- a/src/quick/items/qquicksprite.cpp
+++ b/src/quick/items/qquicksprite.cpp
@@ -53,13 +53,59 @@ QT_BEGIN_NAMESPACE
/*!
\qmlproperty int QtQuick2::Sprite::duration
- Time between frames. Use -1 to indicate one sprite frame per rendered frame.
+ Duration of the animation. Values below 0 are invalid.
+
+ If frameRate is valid then it will be used to calculate the duration of the frames.
+ If not, and frameDuration is valid, then frameDuration will be used. Otherwise duration is used.
*/
/*!
\qmlproperty int QtQuick2::Sprite::durationVariation
- The time between frames can vary by up to this amount. Variation will never decrease the time
- between frames to less than 0.
+ The duration of the animation can vary by up to this amount. Variation will never decrease the
+ length of the animation to less than 0.
+
+ durationVariation will only take effect if duration is
+ used to calculate the duration of frames.
+
+ Default is 0.
+*/
+
+/*!
+ \qmlproperty qreal QtQuick2::Sprite::frameRate
+
+ Frames per second to show in the animation. Values below 0 are invalid.
+
+ If frameRate is valid then it will be used to calculate the duration of the frames.
+ If not, and frameDuration is valid , then frameDuration will be used. Otherwise duration is used.
+*/
+/*!
+ \qmlproperty qreal QtQuick2::Sprite::frameRateVariation
+
+ The frame rate between animations can vary by up to this amount. Variation will never decrease the
+ length of the animation to less than 0.
+
+ frameRateVariation will only take effect if frameRate is
+ used to calculate the duration of frames.
+
+ Default is 0.
+*/
+
+/*!
+ \qmlproperty int QtQuick2::Sprite::frameDuration
+
+ Duration of each frame of the animation. Values below 0 are invalid.
+
+ If frameRate is valid then it will be used to calculate the duration of the frames.
+ If not, and frameDuration is valid, then frameDuration will be used. Otherwise duration is used.
+*/
+/*!
+ \qmlproperty int QtQuick2::Sprite::frameDurationVariation
+
+ The duration of a frame in the animation can vary by up to this amount. Variation will never decrease the
+ length of the animation to less than 0.
+
+ frameDurationVariation will only take effect if frameDuration is
+ used to calculate the duration of frames.
Default is 0.
*/
@@ -99,22 +145,87 @@ QT_BEGIN_NAMESPACE
Width of a single frame in this sprite.
*/
/*!
+ \qmlproperty int QtQuick2::Sprite::frameX
+
+ The X coordinate in the image file of the first frame of the sprite.
+*/
+/*!
+ \qmlproperty int QtQuick2::Sprite::frameY
+
+ The Y coordinate in the image file of the first frame of the sprite.
+*/
+/*!
\qmlproperty url QtQuick2::Sprite::source
The image source for the animation.
If frameHeight and frameWidth are not specified, it is assumed to be a single long row of square frames.
Otherwise, it can be multiple contiguous rows or rectangluar frames, when one row runs out the next will be used.
+
+ If frameX and frameY are specified, the row of frames will be taken with that x/y coordinate as the upper left corner.
+*/
+
+/*!
+ \qmlproperty bool QtQuick2::Sprite::reverse
+
+ If true, then the animation will be played in reverse.
+
+ Default is false.
*/
-QQuickSprite::QQuickSprite(QObject *parent) :
- QQuickStochasticState(parent)
+/*!
+ \qmlproperty bool QtQuick2::Sprite::frameSync
+
+ If true, then the animation will have no duration. Instead, the animation will advance
+ one frame each time a frame is rendered to the screen. This syncronizes it with the painting
+ rate as opposed to elapsed time.
+
+ If frameSync is set to true, it overrides all of duration, frameRate and frameDuration.
+
+ Default is false.
+*/
+
+static const int unsetDuration = -2;//-1 means perframe for duration
+QQuickSprite::QQuickSprite(QObject *parent)
+ : QQuickStochasticState(parent)
, m_generatedCount(0)
, m_framesPerRow(0)
+ , m_rowY(0)
+ , m_reverse(false)
, m_frameHeight(0)
, m_frameWidth(0)
- , m_rowY(0)
+ , m_frames(1)
+ , m_frameX(0)
+ , m_frameY(0)
+ , m_frameRate(unsetDuration)
+ , m_frameRateVariation(0)
+ , m_frameDuration(unsetDuration)
+ , m_frameDurationVariation(0)
+ , m_frameSync(false)
+{
+}
+
+int QQuickSprite::variedDuration() const //Deals with precedence when multiple durations are set
{
+ if (m_frameSync)
+ return 0;
+
+ if (m_frameRate != unsetDuration) {
+ qreal fpms = (m_frameRate
+ + (m_frameRateVariation * ((qreal)qrand()/RAND_MAX) * 2)
+ - m_frameRateVariation) / 1000.0;
+ return qMax(qreal(0.0) , m_frames / fpms);
+ } else if (m_frameDuration != unsetDuration) {
+ int mspf = m_frameDuration
+ + (m_frameDurationVariation * ((qreal)qrand()/RAND_MAX) * 2)
+ - m_frameDurationVariation;
+ return qMax(0, m_frames * mspf);
+ }
+ qWarning() << "Sprite::duration is changing meaning to the full animation duration.";
+ qWarning() << "Use Sprite::frameDuration for the old meaning, of per frame duration.";
+ qWarning() << "As an interim measure, duration/durationVariation means the same as frameDuration/frameDurationVariation, and you'll get this warning spewed out everywhere to movtivate you.";
+ //Note that the spammyness is due to this being the best location to detect, but also called once each animation loop
+ return QQuickStochasticState::variedDuration() * m_frames;
}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h
index e8a033caa8..6aab74f8dd 100644
--- a/src/quick/items/qquicksprite_p.h
+++ b/src/quick/items/qquicksprite_p.h
@@ -56,10 +56,20 @@ class QQuickSprite : public QQuickStochasticState
{
Q_OBJECT
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(bool reverse READ reverse WRITE setReverse NOTIFY reverseChanged)
+ Q_PROPERTY(bool frameSync READ frameSync WRITE setFrameSync NOTIFY frameSyncChanged)
+ Q_PROPERTY(int frames READ frames WRITE setFrames NOTIFY framesChanged)
//If frame height or width is not specified, it is assumed to be a single long row of square frames.
//Otherwise, it can be multiple contiguous rows, when one row runs out the next will be used.
Q_PROPERTY(int frameHeight READ frameHeight WRITE setFrameHeight NOTIFY frameHeightChanged)
Q_PROPERTY(int frameWidth READ frameWidth WRITE setFrameWidth NOTIFY frameWidthChanged)
+ Q_PROPERTY(int frameX READ frameX WRITE setFrameX NOTIFY frameXChanged)
+ Q_PROPERTY(int frameY READ frameY WRITE setFrameY NOTIFY frameYChanged)
+ //Precedence order: frameRate, frameDuration, duration
+ Q_PROPERTY(qreal frameRate READ frameRate WRITE setFrameRate NOTIFY frameRateChanged RESET resetFrameRate)
+ Q_PROPERTY(qreal frameRateVariation READ frameRateVariation WRITE setFrameRateVariation NOTIFY frameRateVariationChanged)
+ Q_PROPERTY(int frameDuration READ frameDuration WRITE setFrameDuration NOTIFY frameDurationChanged RESET resetFrameDuration)
+ Q_PROPERTY(int frameDurationVariation READ frameDurationVariation WRITE setFrameDurationVariation NOTIFY frameDurationVariationChanged)
public:
explicit QQuickSprite(QObject *parent = 0);
@@ -80,6 +90,63 @@ public:
}
+ bool reverse() const
+ {
+ return m_reverse;
+ }
+
+ int frames() const
+ {
+ return m_frames;
+ }
+
+ int frameX() const
+ {
+ return m_frameX;
+ }
+
+ int frameY() const
+ {
+ return m_frameY;
+ }
+
+ void resetFrameRate()
+ {
+ setFrameRate(-1);
+ }
+
+ qreal frameRate() const
+ {
+ return m_frameRate;
+ }
+
+ qreal frameRateVariation() const
+ {
+ return m_frameRateVariation;
+ }
+
+ void resetFrameDuration()
+ {
+ setFrameDuration(-1);
+ }
+
+ int frameDuration() const
+ {
+ return m_frameDuration;
+ }
+
+ int frameDurationVariation() const
+ {
+ return m_frameDurationVariation;
+ }
+
+ int variedDuration() const;
+
+ bool frameSync() const
+ {
+ return m_frameSync;
+ }
+
signals:
void sourceChanged(QUrl arg);
@@ -88,6 +155,24 @@ signals:
void frameWidthChanged(int arg);
+ void reverseChanged(bool arg);
+
+ void framesChanged(int arg);
+
+ void frameXChanged(int arg);
+
+ void frameYChanged(int arg);
+
+ void frameRateChanged(qreal arg);
+
+ void frameRateVariationChanged(qreal arg);
+
+ void frameDurationChanged(int arg);
+
+ void frameDurationVariationChanged(int arg);
+
+ void frameSyncChanged(bool arg);
+
public slots:
void setSource(QUrl arg)
@@ -115,17 +200,99 @@ public slots:
}
+ void setReverse(bool arg)
+ {
+ if (m_reverse != arg) {
+ m_reverse = arg;
+ emit reverseChanged(arg);
+ }
+ }
+
+ void setFrames(int arg)
+ {
+ if (m_frames != arg) {
+ m_frames = arg;
+ emit framesChanged(arg);
+ }
+ }
+
+ void setFrameX(int arg)
+ {
+ if (m_frameX != arg) {
+ m_frameX = arg;
+ emit frameXChanged(arg);
+ }
+ }
+
+ void setFrameY(int arg)
+ {
+ if (m_frameY != arg) {
+ m_frameY = arg;
+ emit frameYChanged(arg);
+ }
+ }
+
+ void setFrameRate(qreal arg)
+ {
+ if (m_frameRate != arg) {
+ m_frameRate = arg;
+ emit frameRateChanged(arg);
+ }
+ }
+
+ void setFrameRateVariation(qreal arg)
+ {
+ if (m_frameRateVariation != arg) {
+ m_frameRateVariation = arg;
+ emit frameRateVariationChanged(arg);
+ }
+ }
+
+ void setFrameDuration(int arg)
+ {
+ if (m_frameDuration != arg) {
+ m_frameDuration = arg;
+ emit frameDurationChanged(arg);
+ }
+ }
+
+ void setFrameDurationVariation(int arg)
+ {
+ if (m_frameDurationVariation != arg) {
+ m_frameDurationVariation = arg;
+ emit frameDurationVariationChanged(arg);
+ }
+ }
+
+ void setFrameSync(bool arg)
+ {
+ if (m_frameSync != arg) {
+ m_frameSync = arg;
+ emit frameSyncChanged(arg);
+ }
+ }
+
private:
- friend class QSGImageParticle;
+ friend class QQuickImageParticle;
+ friend class QQuickSpriteImage;
friend class QQuickSpriteEngine;
friend class QQuickStochasticEngine;
int m_generatedCount;
int m_framesPerRow;
+ int m_rowY;
+
QUrl m_source;
+ bool m_reverse;
int m_frameHeight;
int m_frameWidth;
- int m_rowY;
-
+ int m_frames;
+ int m_frameX;
+ int m_frameY;
+ qreal m_frameRate;
+ qreal m_frameRateVariation;
+ int m_frameDuration;
+ int m_frameDurationVariation;
+ bool m_frameSync;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index 38be93f1ce..470aa6d160 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -139,12 +139,12 @@ int QQuickSpriteEngine::spriteState(int sprite)
if (!m_sprites[state]->m_generatedCount)
return state;
int extra;
- if (m_sprites[state]->duration() < 0) {
+ if (m_sprites[state]->frameSync()) {
extra = m_startTimes[sprite];
} else {
if (!m_duration[sprite])
return state;
- int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
+ int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
}
return state + extra;
@@ -157,7 +157,7 @@ int QQuickSpriteEngine::spriteStart(int sprite)
int state = m_things[sprite];
if (!m_sprites[state]->m_generatedCount)
return m_startTimes[sprite];
- int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
+ int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
return m_startTimes[sprite] + extra*rowDuration;
}
@@ -168,12 +168,12 @@ int QQuickSpriteEngine::spriteFrames(int sprite)
if (!m_sprites[state]->m_generatedCount)
return m_sprites[state]->frames();
int extra;
- if (m_sprites[state]->duration() < 0) {
+ if (m_sprites[state]->frameSync()) {
extra = m_startTimes[sprite];
} else {
if (!m_duration[sprite])
return state;
- int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
+ int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
}
if (extra == m_sprites[state]->m_generatedCount - 1)//last state
@@ -188,11 +188,11 @@ int QQuickSpriteEngine::spriteDuration(int sprite)//Full duration, not per frame
return m_duration[sprite];
int state = m_things[sprite];
if (!m_sprites[state]->m_generatedCount)
- return m_duration[sprite] * m_sprites[state]->frames();
- int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
+ return m_duration[sprite];
+ int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
int extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
if (extra == m_sprites[state]->m_generatedCount - 1)//last state
- return (m_duration[sprite] * m_sprites[state]->frames()) % rowDuration;
+ return m_duration[sprite] % rowDuration;
else
return rowDuration;
}
@@ -203,12 +203,12 @@ int QQuickSpriteEngine::spriteY(int sprite)
if (!m_sprites[state]->m_generatedCount)
return m_sprites[state]->m_rowY;
int extra;
- if (m_sprites[state]->duration() < 0) {
+ if (m_sprites[state]->frameSync()) {
extra = m_startTimes[sprite];
} else {
if (!m_duration[sprite])
return state;
- int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow;
+ int rowDuration = m_duration[sprite] * m_sprites[state]->m_framesPerRow / m_sprites[state]->m_frames;
extra = (m_timeOffset - m_startTimes[sprite])/rowDuration;
}
return m_sprites[state]->m_rowY + m_sprites[state]->m_frameHeight * extra;
@@ -397,7 +397,7 @@ void QQuickStochasticEngine::restart(int index)
m_startTimes[index] = m_timeOffset;
if (m_addAdvance)
m_startTimes[index] += m_advanceTime.elapsed();
- int time = m_duration[index] * m_states[m_things[index]]->frames() + m_startTimes[index];
+ int time = m_duration[index] + m_startTimes[index];
for (int i=0; i<m_stateUpdates.count(); i++)
m_stateUpdates[i].second.removeAll(index);
if (m_duration[index] >= 0)
@@ -406,7 +406,7 @@ void QQuickStochasticEngine::restart(int index)
void QQuickSpriteEngine::restart(int index) //Reimplemented to recognize and handle pseudostates
{
- if (m_sprites[m_things[index]]->duration() < 0) {//Manually advanced
+ if (m_sprites[m_things[index]]->frameSync()) {//Manually advanced
m_startTimes[index] = 0;
} else {
m_startTimes[index] = m_timeOffset;
@@ -436,7 +436,7 @@ void QQuickSpriteEngine::advance(int idx) //Reimplemented to recognize and handl
if (idx >= m_things.count())
return;//TODO: Proper fix(because this has happened and I just ignored it)
if (m_duration[idx] == 0) {
- if (m_sprites[m_things[idx]]->duration() < 0) {
+ if (m_sprites[m_things[idx]]->frameSync()) {
//Manually called, advance inner substate count
m_startTimes[idx]++;
if (m_startTimes[idx] < m_sprites[m_things[idx]]->m_generatedCount) {
@@ -446,8 +446,8 @@ void QQuickSpriteEngine::advance(int idx) //Reimplemented to recognize and handl
}
}
//just go past the pseudostate logic
- } else if (m_startTimes[idx] + m_duration[idx] * m_states[m_things[idx]]->frames()
- > m_timeOffset + (m_addAdvance ? m_advanceTime.elapsed() : 0)) {
+ } else if (m_startTimes[idx] + m_duration[idx]
+ > int(m_timeOffset + (m_addAdvance ? m_advanceTime.elapsed() : 0))) {
//only a pseduostate ended
emit stateChanged(idx);
addToUpdateList(m_timeOffset + spriteDuration(idx), idx);
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index 48ef6c305e..7a147a2e88 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -56,20 +56,17 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QQuickSprite;
-class Q_AUTOTEST_EXPORT QQuickStochasticState : public QObject //For internal use
+class Q_AUTOTEST_EXPORT QQuickStochasticState : public QObject //Currently for internal use only - Sprite and ParticleGroup
{
Q_OBJECT
Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
- Q_PROPERTY(int durationVariation READ durationVariance WRITE setDurationVariance NOTIFY durationVarianceChanged)
+ Q_PROPERTY(int durationVariation READ durationVariation WRITE setDurationVariation NOTIFY durationVariationChanged)
Q_PROPERTY(QVariantMap to READ to WRITE setTo NOTIFY toChanged)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
- Q_PROPERTY(qreal speedModifiesDuration READ speedModifer WRITE setSpeedModifier NOTIFY speedModifierChanged)
- Q_PROPERTY(int frames READ frames WRITE setFrames NOTIFY framesChanged)
public:
QQuickStochasticState(QObject* parent = 0)
: QObject(parent)
- , m_frames(1)
, m_duration(1000)
{
}
@@ -89,27 +86,17 @@ public:
return m_to;
}
- qreal speedModifer() const
+ int durationVariation() const
{
- return m_speedModifier;
+ return m_durationVariation;
}
- int durationVariance() const
- {
- return m_durationVariance;
- }
-
- int variedDuration() const
+ virtual int variedDuration() const
{
return qMax(qreal(0.0) , m_duration
- + (m_durationVariance * ((qreal)qrand()/RAND_MAX) * 2)
- - m_durationVariance);
- }
-
- int frames() const
- {
- return m_frames;
+ + (m_durationVariation * ((qreal)qrand()/RAND_MAX) * 2)
+ - m_durationVariation);
}
signals:
@@ -119,12 +106,9 @@ signals:
void toChanged(QVariantMap arg);
- void speedModifierChanged(qreal arg);
-
- void durationVarianceChanged(int arg);
+ void durationVariationChanged(int arg);
void entered();//### Just playing around - don't expect full state API
- void framesChanged(int arg);
public slots:
void setDuration(int arg)
@@ -151,37 +135,19 @@ public slots:
}
}
- void setSpeedModifier(qreal arg)
- {
- if (m_speedModifier != arg) {
- m_speedModifier = arg;
- emit speedModifierChanged(arg);
- }
- }
-
- void setDurationVariance(int arg)
- {
- if (m_durationVariance != arg) {
- m_durationVariance = arg;
- emit durationVarianceChanged(arg);
- }
- }
-
- void setFrames(int arg)
+ void setDurationVariation(int arg)
{
- if (m_frames != arg) {
- m_frames = arg;
- emit framesChanged(arg);
+ if (m_durationVariation != arg) {
+ m_durationVariation = arg;
+ emit durationVariationChanged(arg);
}
}
private:
QString m_name;
- int m_frames;
QVariantMap m_to;
int m_duration;
- qreal m_speedModifier;
- int m_durationVariance;
+ int m_durationVariation;
friend class QQuickStochasticEngine;
};