--- a/src/hbcore/image/hbiconanimation.cpp Mon Oct 04 17:49:30 2010 +0300
+++ b/src/hbcore/image/hbiconanimation.cpp Mon Oct 18 18:23:13 2010 +0300
@@ -161,6 +161,20 @@
mRenderSize = size;
}
+void HbIconAnimation::setLoopCount(int loopCount)
+{
+ Q_UNUSED(loopCount);
+ // Nothing to do here, some subclasses may want to reimplement this in case
+ // they want to offer support to the user for manually controlling the loop
+ // behavior.
+}
+
+bool HbIconAnimation::loopCountSet(int *loopCount)
+{
+ Q_UNUSED(loopCount);
+ return false;
+}
+
bool HbIconAnimation::mirrored() const
{
return mMirrored;
@@ -188,7 +202,7 @@
void HbIconAnimation::setPlayMode(HbIconAnimationDefinition::PlayMode playMode)
{
- this->mPlayMode = playMode;
+ mPlayMode = playMode;
}
void HbIconAnimation::delayedEmitStarted()
@@ -321,7 +335,8 @@
mImageRenderer(renderer),
mIconFileName(iconFileName),
mType(type),
- mTimerEntry(0)
+ mTimerEntry(0),
+ mDoNotResetLoopCount(false)
{
// This class supports these types
Q_ASSERT(mType == MNG || mType == GIF);
@@ -336,6 +351,10 @@
// Set default size based on the first frame
setDefaultSize(mCurrentFrame.size());
+ // Get the loop count. -1 means infinite loop.
+ mLoopCount = mImageRenderer->loopCount();
+ mCustomLoopCountSet = false;
+
// Do not start the timer or initiate any signal emission here.
// Do it in start() instead, since mFresh is true by default.
}
@@ -382,6 +401,17 @@
mImageRenderer = 0;
mImageRenderer = new QImageReader(mIconFileName, mType == MNG ? "MNG" : "GIF");
+ if (mDoNotResetLoopCount) {
+ mDoNotResetLoopCount = false;
+ } else {
+ // Reset the loop count.
+ if (mCustomLoopCountSet) {
+ mLoopCount = mCustomLoopCount;
+ } else {
+ mLoopCount = mImageRenderer->loopCount();
+ }
+ }
+
// New image reader starts from the first frame. Handle animation update.
notifyAnimationStarted();
handleAnimationUpdated();
@@ -408,6 +438,9 @@
QImage img = mImageRenderer->read();
// Reached last frame?
if (!mImageRenderer->canRead()) {
+ // Must get rid of the old pixmap first, in case of very large frames
+ // keeping both the old and new frame in memory would not succeed.
+ mCurrentFrame = QPixmap(); // This call is not superfluous.
mCurrentFrame = QPixmap::fromImage(img);
mLastFrame = mCurrentFrame;
break;
@@ -468,6 +501,23 @@
}
}
+void HbIconAnimationImage::setLoopCount(int loopCount)
+{
+ // By default we use whatever value QImageReader::loopCount() returned.
+ // However we also offer the possibility to override it manually at any
+ // time.
+ mLoopCount = mCustomLoopCount = loopCount;
+ mCustomLoopCountSet = true;
+}
+
+bool HbIconAnimationImage::loopCountSet(int *loopCount)
+{
+ if (loopCount && mCustomLoopCountSet) {
+ *loopCount = mCustomLoopCount;
+ }
+ return mCustomLoopCountSet;
+}
+
void HbIconAnimationImage::handleAnimationUpdated()
{
bool finished = false;
@@ -486,6 +536,11 @@
// Store the new frame in the current frame pixmap
if (!img.isNull()) {
+ // Must get rid of the old pixmap first, in case of very large frames
+ // keeping both the old and new frame in memory would not succeed.
+ // (with the OpenVG paint engine QPixmap will create a new QImage if
+ // the pixel format is different and it will be different here...)
+ mCurrentFrame = QPixmap(); // This call is not superfluous.
mCurrentFrame = QPixmap::fromImage(img);
}
// Reached the last frame. Store it so it can be used by stop().
@@ -502,7 +557,16 @@
emit animationUpdated();
if (finished) {
- notifyAnimationFinished();
+ if (mLoopCount == 0) {
+ notifyAnimationFinished();
+ } else {
+ finished = false;
+ if (mLoopCount > 0) {
+ --mLoopCount;
+ }
+ mDoNotResetLoopCount = true;
+ start();
+ }
}
}
@@ -511,7 +575,9 @@
HbIconAnimation(animator, iconName),
mFrames(frames),
mCurrentFrameIndex(0),
- mTimerEntry(0)
+ mTimerEntry(0),
+ mManualLoopingSet(false),
+ mManualLooping(false)
{
// Do not start the timer or initiate any signal emission here.
// Do it in start() instead, since mFresh is true by default.
@@ -615,6 +681,24 @@
}
}
+void HbIconAnimationFrameSet::setLoopCount(int loopCount)
+{
+ // Here we only support manually enabling/disabling infinite looping.
+ // (so effectively loop count should be -1 or 0) Positive values are
+ // treated as do-not-loop, i.e. zero. This is because explicit loop
+ // counts are not supported by axml.
+ mManualLoopingSet = true;
+ mManualLooping = loopCount < 0; // -1 means loop for ever
+}
+
+bool HbIconAnimationFrameSet::loopCountSet(int *loopCount)
+{
+ if (loopCount && mManualLoopingSet) {
+ *loopCount = mManualLooping ? -1 : 0;
+ }
+ return mManualLoopingSet;
+}
+
void HbIconAnimationFrameSet::moveToNextFrame()
{
if (mCurrentFrameIndex >= 0 && mCurrentFrameIndex < mFrames.count()) {
@@ -656,7 +740,11 @@
// and looping is enabled. Change to the last valid frame and
// finish if looping is disabled.
if (mCurrentFrameIndex >= mFrames.count()) {
- if (playMode() == HbIconAnimationDefinition::Loop) {
+ bool looping = playMode() == HbIconAnimationDefinition::Loop;
+ if (mManualLoopingSet) {
+ looping = mManualLooping;
+ }
+ if (looping) {
mCurrentFrameIndex = 0;
} else {
finished = true;