--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lafagnosticuifoundation/bmpanimation/src/bmpansrv.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,1026 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "bmpansrv.h"
+
+
+const TInt KAnimationGranularity = 5;
+
+// times
+const TInt KMilliToMicroSecondsFactor = 1000;
+
+
+//
+// CBitmapAnimFrameData
+//
+
+/**
+ Creates a new empty frame object.
+
+@return A pointer to the new empty frame object.
+*/
+CBitmapAnimFrameData* CBitmapAnimFrameData::NewL()
+ {
+ CBitmapAnimFrameData* self = CBitmapAnimFrameData::NewLC();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+ Constructs a new bitmap animation frame data object,and puts a pointer to it onto the cleanup stack.
+
+@return A pointer to the new empty frame data object or NULL if the disk is full.
+*/
+CBitmapAnimFrameData* CBitmapAnimFrameData::NewLC()
+ {
+ CBitmapAnimFrameData* self = new (ELeave) CBitmapAnimFrameData;
+ CleanupStack::PushL(self);
+ return self;
+ }
+
+
+/**
+ Empty default constructor.
+ */
+CBitmapAnimFrameData::CBitmapAnimFrameData()
+ {
+ }
+
+/**
+ Frees resources owned by the object prior to deletion.
+*/
+CBitmapAnimFrameData::~CBitmapAnimFrameData()
+ {
+ if( iBitmap && (iBitmap != iMaskBitmap) )
+ {
+ delete iBitmap;
+ }
+
+ if( iMaskBitmap )
+ {
+ delete iMaskBitmap;
+ }
+
+ }
+
+
+/**
+ Initialization of CBitmapAnimFrameData data members to NULL.
+*/
+void CBitmapAnimFrameData::InitialiseMembers()
+ {
+ if( iBitmap && (iBitmap != iMaskBitmap) )
+ {
+ delete iBitmap;
+ iBitmap = NULL;
+ }
+
+ if( iMaskBitmap )
+ {
+ delete iMaskBitmap;
+ iMaskBitmap = NULL;
+ iBitmap = NULL;
+ }
+
+
+ iPosition.SetXY( 0, 0 );
+ iInterval = 0;
+ }
+
+
+/**
+ Creates bitmaps if they are not created earlier.
+*/
+void CBitmapAnimFrameData::CheckAndCreateBitmapsL()
+ {
+ if (iBitmap == NULL)
+ {
+ iBitmap = new(ELeave) CFbsBitmap();
+ }
+ if (iMaskBitmap == NULL)
+ {
+ iMaskBitmap = new(ELeave) CFbsBitmap();
+ }
+ }
+
+
+/**
+ Un-packs the frame data arguments, aFrameDataArg, and uses this information to fill the frame
+ data with two bitmaps, a position and a time interval.
+*/
+void CBitmapAnimFrameData::FillFrameDataL( const TFrameData& aFrameDataArg )
+ {
+// Create the icon by using the bitmap handles
+ if ( aFrameDataArg.iBitmapHandle ) // Null member of sequence, time is only valid field in member data
+ {
+ iBitmap = new(ELeave) CFbsBitmap();
+ User::LeaveIfError(iBitmap->Duplicate(aFrameDataArg.iBitmapHandle));
+ if (aFrameDataArg.iMaskBitmapHandle)
+ {
+ iMaskBitmap = new(ELeave) CFbsBitmap();
+ User::LeaveIfError(iMaskBitmap->Duplicate(aFrameDataArg.iMaskBitmapHandle));
+ }
+
+ iPosition = aFrameDataArg.iPosition;
+ iInterval = (TTimeIntervalMicroSeconds32) ( aFrameDataArg.iIntervalInMilliSeconds * KMilliToMicroSecondsFactor );
+ }
+ else
+ {
+ InitialiseMembers();
+ }
+
+ }
+
+
+
+/**
+ class CBitmapAnim
+*/
+
+/**
+ Constructs a new bitmap animation object.
+*/
+CBitmapAnim::CBitmapAnim() :
+ iBitmapAnimFrameDataArray(KAnimationGranularity),
+ iFlags(ENoBitmapWindowRestoring),
+ iIndex(-1),
+ iNumberOfCycles(-1),
+ iPosition(0,0)
+ {
+ }
+
+
+
+/**
+ Frees resources owned by the object prior to deletion.
+*/
+CBitmapAnim::~CBitmapAnim()
+ {
+ StopAnimation();
+ delete iAnimTimer;
+ delete iFlashTimer;
+ iBitmapAnimFrameDataArray.ResetAndDestroy();
+ iBitmapAnimFrameDataArray.Close();
+ delete iBackgroundFrame;
+ }
+
+
+
+/**
+ Creates a new empty bitmap animation object.
+
+@return A pointer to the new empty bitmap animation object.
+*/
+CBitmapAnim* CBitmapAnim::NewL()
+ {
+ CBitmapAnim* self = new (ELeave) CBitmapAnim();
+ return self;
+ }
+
+
+
+/**
+ Pure virtual function from CAnim it creates the animation timer object.
+*/
+void CBitmapAnim::ConstructL(TAny* /*aArgs*/, TBool /*aHasFocus*/)
+ {
+ iAnimTimer = CBitmapAnimTimer::NewL(this);
+ }
+
+void CBitmapAnim::Animate(TDateTime* /*aDateTime*/)
+ {
+ }
+
+
+
+/**
+ Stops animation and resets animation frame data array.
+*/
+void CBitmapAnim::ResetFrameArray()
+ {
+ StopAnimation();
+ iBitmapAnimFrameDataArray.ResetAndDestroy();
+ }
+
+
+/**
+ Appends a new frame, aFrame, to the frame array.
+*/
+void CBitmapAnim::AppendFrameL(const TFrameData& aFrameDataArg)
+ {
+ CBitmapAnimFrameData* dataFrame = CBitmapAnimFrameData::NewLC();
+ dataFrame->FillFrameDataL(aFrameDataArg);
+ User::LeaveIfError(iBitmapAnimFrameDataArray.Append(dataFrame));
+ CleanupStack::Pop(dataFrame);
+ }
+
+
+/**
+ Pure virtual function from CAnim.
+*/
+void CBitmapAnim::Command(TInt aOpcode, TAny* aArgs)
+ {
+ switch (aOpcode)
+ {
+ case EBitmapAnimCommandClearDataFrames:
+ ClearFrameData();
+ break;
+ case EBitmapAnimCommandSetFlash:
+ SetFlash(*(TBmpAnimAttributes*)aArgs);
+ break;
+ case EBitmapAnimCommandSetFrameIndex:
+ SetIndexFrame(*(SBitmapAnimIndexFrame*)aArgs);
+ break;
+ case EBitmapAnimCommandSetFrameInterval:
+ SetFrameInterval(*(TBmpAnimAttributes*)aArgs);
+ break;
+ case EBitmapAnimCommandSetNumberOfCycles:
+ SetNumberOfCycles(*(SBitmapAnimNumberOfCycles*)aArgs);
+ break;
+ case EBitmapAnimCommandSetPlayMode:
+ SetPlayMode(*(TBmpAnimAttributes*)aArgs);
+ break;
+ case EBitmapAnimCommandSetPosition:
+ SetPosition(*(SBitmapAnimNewPosition*)aArgs);
+ break;
+ }
+ }
+
+
+
+/**
+ Pure virtual function from CAnim it handles the command received by the relative client.
+ aOpcode determines the action that has to be taken while aArgs contains the information
+ packed by the client. It returns KErrNone if no problem has occurred.
+*/
+TInt CBitmapAnim::CommandReplyL(TInt aOpcode, TAny* aArgs)
+ {
+ TInt error = KErrNone;
+ switch (aOpcode)
+ {
+ case EBitmapAnimCommandClearDataFrames:
+ ClearFrameData();
+ break;
+ case EBitmapAnimCommandStartAnimation:
+ StartAnimationL();
+ break;
+ case EBitmapAnimCommandStopAnimation:
+ StopAnimation();
+ break;
+ case EBitmapAnimCommandSetBackgroundFrame:
+ SetBackgroundFrameL(*(TFrameData*)aArgs);
+ break;
+ case EBitmapAnimCommandSetDataFrame:
+ AppendFrameL(*(TFrameData*)aArgs);
+ break;
+ case EBitmapAnimCommandSetFlash:
+ SetFlash(*(TBmpAnimAttributes*)aArgs);
+ break;
+ case EBitmapAnimCommandSetFrameIndex:
+ error = SetIndexFrame(*(SBitmapAnimIndexFrame*)aArgs);
+ break;
+ case EBitmapAnimCommandSetFrameInterval:
+ SetFrameInterval(*(TBmpAnimAttributes*)aArgs);
+ break;
+ case EBitmapAnimCommandSetNumberOfCycles:
+ SetNumberOfCycles(*(SBitmapAnimNumberOfCycles*)aArgs);
+ break;
+ case EBitmapAnimCommandSetPlayMode:
+ SetPlayMode(*(TBmpAnimAttributes*)aArgs);
+ break;
+ case EBitmapAnimCommandSetPosition:
+ SetPosition(*(SBitmapAnimNewPosition*)aArgs);
+ break;
+ case EBitmapAnimCommandStartAnimationAndKeepLastFrame:
+ iFlags |= EDisplayLastFrameWhenFinished;
+ StartAnimationL();
+ break;
+ case EBitmapAnimCommandResetFrameArray:
+ ResetFrameArray();
+ break;
+ default:
+ error = KErrNotSupported;
+ }
+ return error;
+ }
+
+
+
+/**
+ Clears Frame data by stopping animation and resetting frame data array.
+*/
+void CBitmapAnim::ClearFrameData()
+ {
+ StopAnimation();
+ iBitmapAnimFrameDataArray.ResetAndDestroy();
+ iIndex = -1;
+ }
+
+
+
+/**
+ Pure virtual function from MAnimationTimer it is used to draw the next frame. It first updates
+ the index frame, checks if the frame is displayable and if so it draws the frame otherwise it
+ stops the animation.
+*/
+void CBitmapAnim::DisplayNextFrameL()
+ {
+ if (!IsRunning())
+ {
+ return;
+ }
+
+ const TInt previousIndex = iIndex;
+ UpdateCurrentIndex();
+
+ if (IsFrameDisplayable())
+ {
+ if (!IsFrozen())
+ {
+ DisplayFrame(previousIndex);
+ }
+ }
+ else
+ {
+ iIndex = previousIndex;
+ StopAnimation();
+ }
+ }
+
+/**
+ Draws the current frame in a particular position.
+ */
+void CBitmapAnim::DrawBitmap(TInt /*aPreviousIndex*/, TBool aRedraw)
+ {
+ __ASSERT_ALWAYS((iIndex>=0 && iIndex < Count()), Panic(EAnimationServerPanicIndexOutOfRange));
+ CBitmapAnimFrameData* frameData = iBitmapAnimFrameDataArray[iIndex];
+
+ if (frameData->iBitmap)
+ {
+ if (!aRedraw)
+ {
+ iWindowFunctions->ActivateGc();
+ }
+
+ const TPoint framePosition = frameData->iPosition + iPosition;
+
+ RenderFrameBackground(iIndex);
+
+ if (frameData->iMaskBitmap)
+ {
+ iGc->BitBltMasked(framePosition, frameData->iBitmap, frameData->iBitmap->SizeInPixels(), frameData->iMaskBitmap, ETrue);
+ }
+ else
+ {
+ iGc->BitBlt(framePosition, frameData->iBitmap);
+ }
+
+ MAnimFreeTimerWindowFunctions* windowFunctions = WindowFunctions();
+
+ if (!aRedraw)
+ {
+ windowFunctions->DeactivateGc();
+ }
+
+ windowFunctions->Update();
+ }
+ }
+
+/**
+ Sets the next call-back of the timer and draws the new frame.
+ */
+void CBitmapAnim::DisplayFrame(TInt aPreviousIndex)
+ {
+ TTimeIntervalMicroSeconds32 time = iBitmapAnimFrameDataArray[iIndex]->iInterval;
+ if (time.Int() < 0)
+ {
+ time = iFrameInterval;
+ }
+
+ // Limits frame interval time
+ const TTimeIntervalMicroSeconds32 KAnimationMinimumFrameInterval = 30 * KMilliToMicroSecondsFactor;
+
+ __ASSERT_DEBUG(time >= KAnimationMinimumFrameInterval, RDebug::Print(_L("CBitmapAnim: frame interval was %d reset to %d."), time.Int(), KAnimationMinimumFrameInterval.Int()));
+ time = Max(time, KAnimationMinimumFrameInterval);
+ iAnimTimer->Cancel();
+ iAnimTimer->After(time);
+
+ DrawBitmap(aPreviousIndex);
+ }
+
+
+
+/**
+ Flashes and draws the current frame.
+
+@param aFlash ETrue for the animation to flash, otherwise EFalse.
+*/
+void CBitmapAnim::FlashFrame(TBool aFlash)
+ {
+ const TTimeIntervalMicroSeconds32 KFlashInterval = 1000;
+
+ if (aFlash)
+ {
+ iFlags |= EFlashing;
+ }
+ else
+ {
+ iFlags &= ~EFlashing;
+ }
+
+ iFlashTimer->After(KFlashInterval);
+
+ DrawBitmap();
+ }
+
+
+
+/**
+ Notifies change of focus.
+Overridden from virtual method CWindowAnim::FocusChanged(TBool aState).
+
+@param aState Indicates whether the focus has or has not changed.
+@see CWindowAnim::FocusChanged(TBool aState)
+*/
+void CBitmapAnim::FocusChanged(TBool aState)
+ {
+ if (aState)
+ {
+ iFlags &= ~EFrozen;
+ if (IsRunning())
+ {
+ TRAP_IGNORE(DisplayNextFrameL());
+ }
+ }
+ else
+ {
+ iFlags |= EFrozen;
+ }
+ }
+
+
+
+/** Handles raw events.
+Overridden from virtual method MEventHandler::OfferRawEvent().
+This function does not handle the incoming events.
+
+@param aRawEvent The raw event to be processed
+@return ETrue if the raw event is handled by this function, EFalse if the function
+chooses not to process it.
+@see MEventHandler
+*/
+TBool CBitmapAnim::OfferRawEvent(const TRawEvent& /*aRawEvent*/)
+ {
+ return EFalse;
+ }
+
+
+
+/**
+ Redraws the current animation frame and the background bitmap.
+Overridden from virtual method CWindowAnim::Redraw().
+
+@see CWindowAnim
+*/
+void CBitmapAnim::Redraw()
+ {
+ TWindowInfo parameter;
+ WindowFunctions()->Parameters(parameter);
+ const TRegion* redrawRegion;
+ const TRegion* redrawShadowRegion;
+ parameter.GetRedrawRegionAndRedrawShadowRegion(redrawRegion, redrawShadowRegion);
+
+ // redraw the current animation frame if needed
+ if (IsFrameDisplayable())
+ {
+ // redraw frame unless we're absolutely sure it doesn't need doing
+ TRect currentFrameScreenRect = CalcFrameRect(iIndex);
+ currentFrameScreenRect.Move(parameter.iScreenPos.iTl);
+ if (FrameNeedsRedrawing(redrawRegion, currentFrameScreenRect) || FrameNeedsRedrawing(redrawShadowRegion, currentFrameScreenRect))
+ {
+ DrawBitmap(-1, ETrue);
+ }
+ }
+ }
+
+
+/**
+ Resets the animation to be in a valid state every time a stop request occurs.
+*/
+void CBitmapAnim::ResetAnimation()
+ {
+ iIndex = -1;
+ iNumberOfCycles = -1;
+ iFlags &= ~(ERunning|EPlayForwards|EPlayBackwards);
+ iFlags |= ENoBitmapWindowRestoring;
+ }
+
+
+/**
+ Sets the background frame by using the information from aFrameDataArg. This will overwrite the
+ existing background frame.
+*/
+void CBitmapAnim::SetBackgroundFrameL(TFrameData aFrameDataArg)
+ {
+ if (iBackgroundFrame)
+ {
+ delete iBackgroundFrame;
+ iBackgroundFrame = NULL;
+ }
+
+ iBackgroundFrame = CBitmapAnimFrameData::NewL();
+ iBackgroundFrame->FillFrameDataL(aFrameDataArg);
+ iBackgroundFrame->CheckAndCreateBitmapsL();
+ }
+
+
+
+/**
+ Sets and un-sets the flash flag according to aFlash value. It can be called at any time after
+ the animation has been set, and it has an immediate effect.
+*/
+void CBitmapAnim::SetFlash(TBmpAnimAttributes aFlash)
+ {
+ if (aFlash.iFlash)
+ {
+ iFlags |= EFlash;
+ }
+ else
+ {
+ iFlags &= ~EFlash;
+ }
+ }
+
+
+
+/**
+ Sets the frame interval of the animation to aFrameInterval. It has an immediate effect.
+*/
+void CBitmapAnim::SetFrameInterval(TBmpAnimAttributes aFrameInterval)
+ {
+ __ASSERT_ALWAYS(aFrameInterval.iFrameIntervalInMilliSeconds >= 0, Panic(EAnimationServerPanicFrameIntervalNegative));
+ iFrameInterval = (aFrameInterval.iFrameIntervalInMilliSeconds * KMilliToMicroSecondsFactor);
+ }
+
+
+
+/**
+ Changes the index frame of the animation to be aIndexFrame and it has an immediate effect.
+*/
+TInt CBitmapAnim::SetIndexFrame(SBitmapAnimIndexFrame aIndexFrame)
+ {
+ TInt error = KErrNone;
+ TInt backupFlags = iFlags;
+ TInt oldNumberOfCycles = iNumberOfCycles;
+ StopAnimation();
+ iIndex = aIndexFrame.iIndex;
+// Restore previous state.
+ iNumberOfCycles = oldNumberOfCycles;
+ iFlags = backupFlags;
+
+ if (IsFrameDisplayable())
+ {
+ DisplayFrame();
+ iFlags &= ~ENoBitmapWindowRestoring;
+ }
+ else
+ {
+ error = KErrOverflow;
+ }
+ return error;
+ }
+
+
+/**
+ Sets the number of times that all the frames have to be displayed. It has an immediate effect.
+*/
+void CBitmapAnim::SetNumberOfCycles(SBitmapAnimNumberOfCycles aNumberOfCycles)
+ {
+ TInt value = aNumberOfCycles.iCycles;
+
+ if (value == 0)
+ {
+ value = 1;
+ }
+
+ iNumberOfCycles = value;
+ }
+
+
+
+/**
+ Sets the play mode of the animation to aPlayMode. It has an immediate effect.
+*/
+void CBitmapAnim::SetPlayMode(TBmpAnimAttributes aPlayMode)
+ {
+
+ TBool isRunning = IsRunning();
+
+ if( isRunning )
+ {
+ StopAnimation();
+ }
+
+ // EPlay = xx0x
+ iFlags &= ~( EPlayModeBounce | EPlayModeCycle );
+
+ CBitmapAnimClientData::TPlayMode mode = aPlayMode.iPlayMode;
+
+ switch (mode)
+ {
+ case CBitmapAnimClientData::EPlay:
+ break;
+
+ case CBitmapAnimClientData::ECycle:
+ iFlags |= EPlayModeCycle;
+ break;
+
+ case CBitmapAnimClientData::EBounce:
+ iFlags |= EPlayModeBounce;
+ break;
+
+ default:
+ break;
+ }
+
+
+ if( isRunning )
+ {
+ TRAP_IGNORE( StartAnimationL() );
+ }
+
+ }
+
+
+
+/**
+ Sets the position of the animation control to aNewPosition.
+ aNewPosition is relative to the origin of the control's window
+*/
+void CBitmapAnim::SetPosition(SBitmapAnimNewPosition aNewPosition)
+ {
+ ClearFrameNow(iIndex);
+ iPosition.iX = aNewPosition.iPosition.iX;
+ iPosition.iY = aNewPosition.iPosition.iY;
+ if (IsRunning())
+ {
+ DrawBitmap();
+ }
+ }
+
+
+
+/**
+ Starts the animation routine.
+*/
+void CBitmapAnim::StartAnimationL()
+ {
+ if (iFunctions->WindowExtension())
+ {
+ TWindowConfig windowConfig;
+ iFunctions->WindowExtension()->WindowConfig(windowConfig);
+ iWindowConfig = windowConfig.iFlags;
+ }
+ if (!IsRunning() && (Count() > 0) )
+ {
+ iFlags |= EPlayForwards;
+ iFlags |= ERunning;
+ DisplayNextFrameL();
+ iFlags &= ~ENoBitmapWindowRestoring;
+ }
+ }
+
+
+
+/**
+ Stops the animation by removing the last frame from the window and replacing the old contents.
+*/
+void CBitmapAnim::StopAnimation()
+ {
+ if (IsRunning())
+ {
+ if (!(iFlags & EDisplayLastFrameWhenFinished))
+ {
+ ClearFrameNow(iIndex);
+ }
+
+ ResetAnimation();
+ }
+ if (iAnimTimer && iAnimTimer->IsActive())
+ {
+ iAnimTimer->Cancel();
+ }
+ }
+
+
+
+/**
+ Calculates and finds frame's rectangle, relative to animation position.
+
+@param aIndex index value of the frame in frame data array.
+@return frame's rectangle.
+*/
+TRect CBitmapAnim::CalcFrameRect( TInt aIndex )
+ {
+ TRect rect;
+
+ CBitmapAnimFrameData* frameData = iBitmapAnimFrameDataArray[aIndex];
+
+ if ( (aIndex >= 0) && frameData && frameData->iBitmap )
+ {
+ TSize frameSize = frameData->iBitmap->SizeInPixels();
+ TPoint framePosition = frameData->iPosition;
+ framePosition += iPosition;
+ rect.SetRect(framePosition, frameSize);
+ }
+
+
+ return rect;
+ }
+
+/**
+Renders the background associated with the specified frame index.
+
+@param aIndex Index of frame to render background for.
+*/
+void CBitmapAnim::RenderFrameBackground(TInt aIndex)
+ {
+ if ((aIndex >= 0) && !(iFlags&ENoBitmapWindowRestoring) && iBackgroundFrame && iBackgroundFrame->iBitmap)
+ {
+ TRect frameRectOnWindow = CalcFrameRect(aIndex);
+ TPoint framePosition = frameRectOnWindow.iTl;
+ frameRectOnWindow.Move(-iPosition);
+ iGc->BitBlt(framePosition, iBackgroundFrame->iBitmap, frameRectOnWindow);
+ }
+ }
+
+/**
+ Clears the frame by calling ClearFrame function.
+ Uses CFreeTimerWindowAnim timer functions which supports animations with their own timers.
+
+@param aIndex index value of the frame in frame data array.
+@see CFreeTimerWindowAnim
+*/
+void CBitmapAnim::ClearFrameNow(TInt /*aIndex*/)
+ {
+ iWindowFunctions->ActivateGc();
+ MAnimFreeTimerWindowFunctions* windowFunctions = WindowFunctions();
+ windowFunctions->DeactivateGc();
+ windowFunctions->Update();
+ }
+
+/**
+ Updates the index indicating which frame should be displayed. The index value will be set
+ to -1 when the animation routine is completed.
+*/
+void CBitmapAnim::UpdateCurrentIndex()
+ {
+ const TInt lastIndexFrame = iBitmapAnimFrameDataArray.Count() - 1;
+ if (iIndex == lastIndexFrame)
+ {
+ if (--iNumberOfCycles == 0)
+ {
+ iIndex = -1;
+ return;
+ }
+
+
+ if (iFlags&EPlayModeBounce)
+ {
+ iIndex--;
+
+ if (iIndex < 0)
+ {
+ iIndex = 0;
+ }
+
+ iFlags &= ~EPlayForwards;
+ iFlags |= EPlayBackwards;
+ }
+ else if (iFlags&EPlayModeCycle)
+ {
+ iIndex = 0;
+ }
+ else
+ {
+ iIndex = -1;
+ }
+ }
+ else if (iIndex == 0)
+ {
+ if (iFlags&EPlayModeBounce)
+ {
+ if (--iNumberOfCycles == 0)
+ {
+ iIndex = -1;
+ return;
+ }
+
+ iIndex ++;
+ iFlags &= ~EPlayBackwards;
+ iFlags |= EPlayForwards;
+ }
+ else if (iFlags&EPlayForwards)
+ {
+ iIndex ++;
+ }
+ else
+ {
+ iIndex = -1;
+ }
+ }
+ else
+ if (iFlags&EPlayForwards)
+ {
+ iIndex++;
+ }
+ else
+ {
+ iIndex--;
+ }
+ }
+
+/**
+ returns true if there is any chance the frame needs to be redrawn, false otherwise
+*/
+TBool CBitmapAnim::FrameNeedsRedrawing(const TRegion* aRedrawRegion, TRect aFrameScreenRect)
+ {
+ // if the region is NULL, empty or doesn't intersect the frame rect,
+ // assume we don't need to redraw the frame
+ TBool ret = aRedrawRegion!=NULL;
+ if (aRedrawRegion)
+ {
+ if (!aRedrawRegion->CheckError())
+ {
+ if (aRedrawRegion->IsEmpty())
+ {
+ ret = EFalse;
+ }
+ else
+ {
+ RRegionBuf<10> frameRegion;
+ frameRegion.Copy(*aRedrawRegion);
+ frameRegion.ClipRect(aFrameScreenRect);
+ if (frameRegion.IsEmpty()) // TRegion::IsEmpty only returns true if the region contains no error
+ {
+ ret = EFalse;
+ }
+ frameRegion.Close();
+ }
+ }
+ }
+ return ret;
+ }
+
+
+
+//
+// CBitmapAnimTimer class
+//
+
+/**
+ Constructs a new bitmap animation timer object,and adds the specified active object to the current active scheduler.
+
+@param aObserver a pointer to MBitmapAnimTimerObserver
+*/
+CBitmapAnimTimer::CBitmapAnimTimer(MBitmapAnimTimerObserver* aObserver)
+ :CTimer(EPriorityStandard),
+ iAnimate(aObserver)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+
+
+/**
+ Frees resources owned by the object prior to deletion.
+*/
+CBitmapAnimTimer::~CBitmapAnimTimer()
+ {
+ }
+
+
+
+/**
+ Creates a new bitmap animation timer object.
+
+@param aObserver A pointer to the MBitmapAnimTimerObserver
+@return A pointer to the new bitmap animation timer object.
+*/
+CBitmapAnimTimer* CBitmapAnimTimer::NewL(MBitmapAnimTimerObserver* aObserver)
+ {
+ CBitmapAnimTimer* timer=new(ELeave) CBitmapAnimTimer(aObserver);
+ CleanupStack::PushL(timer);
+ timer->ConstructL();
+ CleanupStack::Pop();
+ return timer;
+ }
+
+
+
+/**
+ Completes construction of the bitmap animation timer object and
+ constructs a new asynchronous timer.
+*/
+void CBitmapAnimTimer::ConstructL()
+ {
+ CTimer::ConstructL();
+ }
+
+
+
+/**
+ Handles an active object's request completion event.
+ Invokes the function to draw the next frame
+*/
+void CBitmapAnimTimer::RunL()
+ {
+ iAnimate->DisplayNextFrameL();
+ }
+
+
+
+//
+// CBitmapAnimFlashTimer class
+//
+
+/**
+ Constructs a new bitmap animation flash timer object,and adds the specified active object to the current active scheduler.
+
+@param aObserver a pointer to MBitmapAnimFlashTimerObserver
+*/
+CBitmapAnimFlashTimer::CBitmapAnimFlashTimer(MBitmapAnimFlashTimerObserver* aObserver)
+ :CTimer(EPriorityStandard),
+ iAnimate(aObserver),
+ iFlash(EFalse)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+
+
+/**
+ Frees resources owned by the object prior to deletion.
+*/
+CBitmapAnimFlashTimer::~CBitmapAnimFlashTimer()
+ {
+ }
+
+
+
+/**
+ Creates a new bitmap animation flash timer object.
+
+@param aObserver A pointer to the MBitmapAnimFlashTimerObserver
+@return A pointer to the new bitmap animation flash timer object.
+*/
+CBitmapAnimFlashTimer* CBitmapAnimFlashTimer::NewL(MBitmapAnimFlashTimerObserver* aObserver)
+ {
+ CBitmapAnimFlashTimer* timer=new(ELeave) CBitmapAnimFlashTimer(aObserver);
+ CleanupStack::PushL(timer);
+ timer->ConstructL();
+ CleanupStack::Pop();
+ return timer;
+ }
+
+
+
+/**
+ Completes construction of the CBitmapAnimFlashTimer object and
+ constructs a new asynchronous timer.
+*/
+void CBitmapAnimFlashTimer::ConstructL()
+ {
+ CTimer::ConstructL();
+ }
+
+
+
+void CBitmapAnimFlashTimer::DoCancel()
+ {
+ }
+
+
+
+/**
+ Handles an active object's request completion event.
+ Invokes the function to flash the animation frame and draw the bitmap.
+*/
+void CBitmapAnimFlashTimer::RunL()
+ {
+ iFlash = ~iFlash;
+ iAnimate->FlashFrame(iFlash);
+ }
+