src/hbcore/image/hbiconanimation.cpp
changeset 34 ed14f46c0e55
parent 5 627c4a0fd0e7
equal deleted inserted replaced
31:7516d6d86cf5 34:ed14f46c0e55
   159 void HbIconAnimation::setRenderSize(const QSizeF &size)
   159 void HbIconAnimation::setRenderSize(const QSizeF &size)
   160 {
   160 {
   161     mRenderSize = size;
   161     mRenderSize = size;
   162 }
   162 }
   163 
   163 
       
   164 void HbIconAnimation::setLoopCount(int loopCount)
       
   165 {
       
   166     Q_UNUSED(loopCount);
       
   167     // Nothing to do here, some subclasses may want to reimplement this in case
       
   168     // they want to offer support to the user for manually controlling the loop
       
   169     // behavior.
       
   170 }
       
   171 
       
   172 bool HbIconAnimation::loopCountSet(int *loopCount)
       
   173 {
       
   174     Q_UNUSED(loopCount);
       
   175     return false;
       
   176 }
       
   177 
   164 bool HbIconAnimation::mirrored() const
   178 bool HbIconAnimation::mirrored() const
   165 {
   179 {
   166     return mMirrored;
   180     return mMirrored;
   167 }
   181 }
   168 
   182 
   186     return mPlayMode;
   200     return mPlayMode;
   187 }
   201 }
   188 
   202 
   189 void HbIconAnimation::setPlayMode(HbIconAnimationDefinition::PlayMode playMode)
   203 void HbIconAnimation::setPlayMode(HbIconAnimationDefinition::PlayMode playMode)
   190 {
   204 {
   191     this->mPlayMode = playMode;
   205     mPlayMode = playMode;
   192 }
   206 }
   193 
   207 
   194 void HbIconAnimation::delayedEmitStarted()
   208 void HbIconAnimation::delayedEmitStarted()
   195 {
   209 {
   196     if (!mStartSignalTimer) {
   210     if (!mStartSignalTimer) {
   319 
   333 
   320     HbIconAnimation(animator, iconName),
   334     HbIconAnimation(animator, iconName),
   321     mImageRenderer(renderer),
   335     mImageRenderer(renderer),
   322     mIconFileName(iconFileName),
   336     mIconFileName(iconFileName),
   323     mType(type),
   337     mType(type),
   324     mTimerEntry(0)
   338     mTimerEntry(0),
       
   339     mDoNotResetLoopCount(false)
   325 {
   340 {
   326     // This class supports these types
   341     // This class supports these types
   327     Q_ASSERT(mType == MNG || mType == GIF);
   342     Q_ASSERT(mType == MNG || mType == GIF);
   328 
   343 
   329     // Read the first frame. QImageReader::read() must be called before
   344     // Read the first frame. QImageReader::read() must be called before
   333     // Store the first frame in the current frame pixmap
   348     // Store the first frame in the current frame pixmap
   334     mCurrentFrame = QPixmap::fromImage(img);
   349     mCurrentFrame = QPixmap::fromImage(img);
   335 
   350 
   336     // Set default size based on the first frame
   351     // Set default size based on the first frame
   337     setDefaultSize(mCurrentFrame.size());
   352     setDefaultSize(mCurrentFrame.size());
       
   353 
       
   354     // Get the loop count. -1 means infinite loop.
       
   355     mLoopCount = mImageRenderer->loopCount();
       
   356     mCustomLoopCountSet = false;
   338 
   357 
   339     // Do not start the timer or initiate any signal emission here.
   358     // Do not start the timer or initiate any signal emission here.
   340     // Do it in start() instead, since mFresh is true by default.
   359     // Do it in start() instead, since mFresh is true by default.
   341 }
   360 }
   342 
   361 
   380         // Recreate the image reader. It's slow but QImageReader::jumpToImage does not work.
   399         // Recreate the image reader. It's slow but QImageReader::jumpToImage does not work.
   381         delete mImageRenderer;
   400         delete mImageRenderer;
   382         mImageRenderer = 0;
   401         mImageRenderer = 0;
   383         mImageRenderer = new QImageReader(mIconFileName, mType == MNG ? "MNG" : "GIF");
   402         mImageRenderer = new QImageReader(mIconFileName, mType == MNG ? "MNG" : "GIF");
   384 
   403 
       
   404         if (mDoNotResetLoopCount) {
       
   405             mDoNotResetLoopCount = false;
       
   406         } else {
       
   407             // Reset the loop count.
       
   408             if (mCustomLoopCountSet) {
       
   409                 mLoopCount = mCustomLoopCount;
       
   410             } else {
       
   411                 mLoopCount = mImageRenderer->loopCount();
       
   412             }
       
   413         }
       
   414 
   385         // New image reader starts from the first frame. Handle animation update.
   415         // New image reader starts from the first frame. Handle animation update.
   386         notifyAnimationStarted();
   416         notifyAnimationStarted();
   387         handleAnimationUpdated();
   417         handleAnimationUpdated();
   388     }
   418     }
   389 }
   419 }
   406         // QImageReader::jumpToImage does not work so cannot jump to the last frame if it has not been read yet.
   436         // QImageReader::jumpToImage does not work so cannot jump to the last frame if it has not been read yet.
   407         while (true) {
   437         while (true) {
   408             QImage img = mImageRenderer->read();
   438             QImage img = mImageRenderer->read();
   409             // Reached last frame?
   439             // Reached last frame?
   410             if (!mImageRenderer->canRead()) {
   440             if (!mImageRenderer->canRead()) {
       
   441                 // Must get rid of the old pixmap first, in case of very large frames
       
   442                 // keeping both the old and new frame in memory would not succeed.
       
   443                 mCurrentFrame = QPixmap(); // This call is not superfluous.
   411                 mCurrentFrame = QPixmap::fromImage(img);
   444                 mCurrentFrame = QPixmap::fromImage(img);
   412                 mLastFrame = mCurrentFrame;
   445                 mLastFrame = mCurrentFrame;
   413                 break;
   446                 break;
   414             }
   447             }
   415         }
   448         }
   466 #endif
   499 #endif
   467         return QPixmap();
   500         return QPixmap();
   468     }
   501     }
   469 }
   502 }
   470 
   503 
       
   504 void HbIconAnimationImage::setLoopCount(int loopCount)
       
   505 {
       
   506     // By default we use whatever value QImageReader::loopCount() returned.
       
   507     // However we also offer the possibility to override it manually at any
       
   508     // time.
       
   509     mLoopCount = mCustomLoopCount = loopCount;
       
   510     mCustomLoopCountSet = true;
       
   511 }
       
   512 
       
   513 bool HbIconAnimationImage::loopCountSet(int *loopCount)
       
   514 {
       
   515     if (loopCount && mCustomLoopCountSet) {
       
   516         *loopCount = mCustomLoopCount;
       
   517     }
       
   518     return mCustomLoopCountSet;
       
   519 }
       
   520 
   471 void HbIconAnimationImage::handleAnimationUpdated()
   521 void HbIconAnimationImage::handleAnimationUpdated()
   472 {
   522 {
   473     bool finished = false;
   523     bool finished = false;
   474 
   524 
   475     // Read the new frame. QImageReader::read() must be called before
   525     // Read the new frame. QImageReader::read() must be called before
   484         mTimerEntry = HbTimer::instance()->addTimeout(mTimerInterval, this, SLOT(handleAnimationUpdated()));
   534         mTimerEntry = HbTimer::instance()->addTimeout(mTimerInterval, this, SLOT(handleAnimationUpdated()));
   485     }
   535     }
   486 
   536 
   487     // Store the new frame in the current frame pixmap
   537     // Store the new frame in the current frame pixmap
   488     if (!img.isNull()) {
   538     if (!img.isNull()) {
       
   539         // Must get rid of the old pixmap first, in case of very large frames
       
   540         // keeping both the old and new frame in memory would not succeed.
       
   541         // (with the OpenVG paint engine QPixmap will create a new QImage if
       
   542         // the pixel format is different and it will be different here...)
       
   543         mCurrentFrame = QPixmap(); // This call is not superfluous.
   489         mCurrentFrame = QPixmap::fromImage(img);
   544         mCurrentFrame = QPixmap::fromImage(img);
   490     }
   545     }
   491     // Reached the last frame. Store it so it can be used by stop().
   546     // Reached the last frame. Store it so it can be used by stop().
   492     else {
   547     else {
   493         mLastFrame = mCurrentFrame;
   548         mLastFrame = mCurrentFrame;
   500 
   555 
   501     // Inform client
   556     // Inform client
   502     emit animationUpdated();
   557     emit animationUpdated();
   503 
   558 
   504     if (finished) {
   559     if (finished) {
   505         notifyAnimationFinished();
   560         if (mLoopCount == 0) {
       
   561             notifyAnimationFinished();
       
   562         } else {
       
   563             finished = false;
       
   564             if (mLoopCount > 0) {
       
   565                 --mLoopCount;
       
   566             }
       
   567             mDoNotResetLoopCount = true;
       
   568             start();
       
   569         }
   506     }
   570     }
   507 }
   571 }
   508 
   572 
   509 HbIconAnimationFrameSet::HbIconAnimationFrameSet(
   573 HbIconAnimationFrameSet::HbIconAnimationFrameSet(
   510     HbIconAnimator *animator, const QString &iconName, const QList<FrameData> &frames) :
   574     HbIconAnimator *animator, const QString &iconName, const QList<FrameData> &frames) :
   511     HbIconAnimation(animator, iconName),
   575     HbIconAnimation(animator, iconName),
   512     mFrames(frames),
   576     mFrames(frames),
   513     mCurrentFrameIndex(0),
   577     mCurrentFrameIndex(0),
   514     mTimerEntry(0)
   578     mTimerEntry(0),
       
   579     mManualLoopingSet(false),
       
   580     mManualLooping(false)
   515 {
   581 {
   516     // Do not start the timer or initiate any signal emission here.
   582     // Do not start the timer or initiate any signal emission here.
   517     // Do it in start() instead, since mFresh is true by default.
   583     // Do it in start() instead, since mFresh is true by default.
   518 }
   584 }
   519 
   585 
   611 
   677 
   612         return pm;
   678         return pm;
   613     } else {
   679     } else {
   614         return QPixmap();
   680         return QPixmap();
   615     }
   681     }
       
   682 }
       
   683 
       
   684 void HbIconAnimationFrameSet::setLoopCount(int loopCount)
       
   685 {
       
   686     // Here we only support manually enabling/disabling infinite looping.
       
   687     // (so effectively loop count should be -1 or 0) Positive values are
       
   688     // treated as do-not-loop, i.e. zero. This is because explicit loop
       
   689     // counts are not supported by axml.
       
   690     mManualLoopingSet = true;
       
   691     mManualLooping = loopCount < 0; // -1 means loop for ever
       
   692 }
       
   693 
       
   694 bool HbIconAnimationFrameSet::loopCountSet(int *loopCount)
       
   695 {
       
   696     if (loopCount && mManualLoopingSet) {
       
   697         *loopCount = mManualLooping ? -1 : 0;
       
   698     }
       
   699     return mManualLoopingSet;
   616 }
   700 }
   617 
   701 
   618 void HbIconAnimationFrameSet::moveToNextFrame()
   702 void HbIconAnimationFrameSet::moveToNextFrame()
   619 {
   703 {
   620     if (mCurrentFrameIndex >= 0 && mCurrentFrameIndex < mFrames.count()) {
   704     if (mCurrentFrameIndex >= 0 && mCurrentFrameIndex < mFrames.count()) {
   654 
   738 
   655     // Go back to the beginning if indexing goes beyond frame count
   739     // Go back to the beginning if indexing goes beyond frame count
   656     // and looping is enabled. Change to the last valid frame and
   740     // and looping is enabled. Change to the last valid frame and
   657     // finish if looping is disabled.
   741     // finish if looping is disabled.
   658     if (mCurrentFrameIndex >= mFrames.count()) {
   742     if (mCurrentFrameIndex >= mFrames.count()) {
   659         if (playMode() == HbIconAnimationDefinition::Loop) {
   743         bool looping = playMode() == HbIconAnimationDefinition::Loop;
       
   744         if (mManualLoopingSet) {
       
   745             looping = mManualLooping;
       
   746         }
       
   747         if (looping) {
   660             mCurrentFrameIndex = 0;
   748             mCurrentFrameIndex = 0;
   661         } else {
   749         } else {
   662             finished = true;
   750             finished = true;
   663             mCurrentFrameIndex = mFrames.count() - 1;
   751             mCurrentFrameIndex = mFrames.count() - 1;
   664         }
   752         }