--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lafagnosticuifoundation/animation/src/SpriteAnimation.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,424 @@
+// Copyright (c) 2004-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 "SpriteAnimation.h"
+
+#include <w32std.h>
+#include <coecntrl.h>
+
+#include "AnimationDataProvider.h"
+#include "AnimationConfig.h"
+#include "SpriteAnimationClient.h"
+#include "AnimationEvents.h"
+#include "spriteanimationext.h"
+
+_LIT(KAnimationServerDll, "AnimationServer.dll");
+
+/**
+Two stage constructor.
+
+This creates and returns a new sprite animation.
+
+@param aDataProvider The data provider from which the animation contents will
+be obtained. The animation takes ownership of this object
+@param aPoint The starting position of the sprite in the window
+@param aWsSession A session with the window server
+@param aWindow The window in which to draw the animation
+@param aObserver An optional receiver of animation events (such as errors)
+@return The new object
+*/
+EXPORT_C CSpriteAnimation* CSpriteAnimation::NewL(CAnimationDataProvider* aDataProvider, const TPoint& aPoint, RWsSession& aWsSession, RWindow& aWindow, MAnimationObserver* aObserver)
+ {
+ return CSpriteAnimation::NewL(aDataProvider, aPoint, aWsSession, aWindow, aDataProvider->DataType(), aObserver);
+ }
+
+/**
+Two stage constructor.
+
+This is identical to the other NewL except that it allows an alternative data
+type to be specified. Unless you are trying to use a custom animator class
+the other form of constructor should be used.
+
+@param aDataProvider The data provider from which the animation contents will
+be obtained. The animation takes ownership of this object
+@param aPoint The starting position of the sprite in the window
+@param aWsSession A session with the window server
+@param aWindow The window in which to draw the animation
+@param aDataType Overrides the data type specified by the data provider
+@param aObserver An optional receiver of animation events (such as errors)
+@return The new object
+*/
+EXPORT_C CSpriteAnimation* CSpriteAnimation::NewL(CAnimationDataProvider* aDataProvider, const TPoint& aPoint, RWsSession& aWsSession, RWindow& aWindow, const TDesC8& aDataType, MAnimationObserver* aObserver)
+ {
+ CleanupStack::PushL(aDataProvider);
+ CSpriteAnimation* self = new (ELeave) CSpriteAnimation(aDataProvider, aWsSession);
+ CleanupStack::Pop(aDataProvider);
+ CleanupStack::PushL(self);
+ self->ConstructL(aPoint, aWindow, aDataType, aObserver);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+Two stage constructor.
+
+This creates and returns a new sprite animation.
+
+@param aDataProvider The data provider from which the animation contents will
+be obtained. The animation takes ownership of this object
+@param aPoint The starting position of the sprite in the window
+@param aWsSession A session with the window server
+@param aWindow The window in which to draw the animation
+@param aObserver An optional receiver of animation events (such as errors)
+@return The new object
+*/
+EXPORT_C CSpriteAnimation* CSpriteAnimation::NewL(CAnimationDataProvider* aDataProvider, const TPoint& aPoint, MAnimationObserver* aObserver, const CCoeControl* aHost)
+ {
+ return CSpriteAnimation::NewL(aDataProvider, aPoint, aDataProvider->DataType(), aObserver, aHost);
+ }
+
+/**
+Two stage constructor.
+
+This is identical to the other NewL except that it allows an alternative data
+type to be specified. Unless you are trying to use a custom animator class
+the other form of constructor should be used.
+
+@param aDataProvider The data provider from which the animation contents will
+be obtained. The animation takes ownership of this object
+@param aPoint The starting position of the sprite in the window
+@param aWsSession A session with the window server
+@param aWindow The window in which to draw the animation
+@param aDataType Overrides the data type specified by the data provider
+@param aObserver An optional receiver of animation events (such as errors)
+@return The new object
+*/
+EXPORT_C CSpriteAnimation* CSpriteAnimation::NewL(CAnimationDataProvider* aDataProvider, const TPoint& aPoint, const TDesC8& aDataType, MAnimationObserver* aObserver, const CCoeControl* aHost)
+ {
+ CleanupStack::PushL(aDataProvider);
+ CSpriteAnimation* self = new (ELeave) CSpriteAnimation(aDataProvider, aObserver, aHost);
+ CleanupStack::Pop(aDataProvider);
+ CleanupStack::PushL(self);
+ self->ConstructL(aPoint, aDataType);
+ CleanupStack::Pop(self);
+
+ return self;
+ }
+
+/** Destructor.*/
+EXPORT_C CSpriteAnimation::~CSpriteAnimation()
+ {
+ delete iDataProvider;
+ iDataProvider = NULL;
+
+ if (iWsSprite)
+ {
+ iWsSprite->Close();
+ delete iWsSprite;
+ iWsSprite = NULL;
+ }
+
+ iAnimDll.Close();
+
+ if (iClient)
+ {
+ delete iClient;
+ iClient = NULL;
+ }
+
+ if(iSpriteAnimationExt)
+ {
+ delete iSpriteAnimationExt;
+ iSpriteAnimationExt = NULL;
+ }
+
+ iObserver = NULL;
+ iWsSession = NULL;
+ iHost = NULL;
+ }
+
+EXPORT_C void CSpriteAnimation::SetHostL(const CCoeControl* aHost)
+ {
+ if (iHost)
+ {
+ Reset();
+ }
+ iHost = aHost;
+
+ if (iHost)
+ {
+ InitializeL();
+ }
+ }
+
+/** Implements CAnimation::Start.
+@param aConfig Specifies run time attributes of the animation */
+void CSpriteAnimation::Start(const TAnimationConfig& aConfig)
+ {
+ if (iFlags & EAnimationInitialized)
+ {
+ iClient->Start(aConfig);
+ iWsSession->Flush();
+ }
+ }
+
+/** Implements CAnimation::Stop.*/
+void CSpriteAnimation::Stop()
+ {
+ if (iFlags & EAnimationInitialized)
+ {
+ iClient->Stop();
+ iWsSession->Flush();
+ }
+ }
+
+/** Implements CAnimation::Pause.*/
+void CSpriteAnimation::Pause()
+ {
+ if (iFlags & EAnimationInitialized)
+ {
+ iClient->Pause();
+ iWsSession->Flush();
+ }
+ }
+
+/** Implements CAnimation::Resume.*/
+void CSpriteAnimation::Resume()
+ {
+ if (iFlags & EAnimationInitialized)
+ {
+ iClient->Resume();
+ iWsSession->Flush();
+ }
+ }
+
+/** Implements CAnimation::Hold.*/
+void CSpriteAnimation::Hold()
+ {
+ if (iFlags & EAnimationInitialized)
+ {
+ iClient->Hold();
+ iWsSession->Flush();
+ }
+ }
+
+/** Implements CAnimation::Unhold.*/
+void CSpriteAnimation::Unhold()
+ {
+ if (iFlags & EAnimationInitialized)
+ {
+ iClient->Unhold();
+ iWsSession->Flush();
+ }
+ }
+
+/** Implements CAnimation::SetPosition.
+@param aPoint The new coordinates of the animation (usually the top left corner) */
+void CSpriteAnimation::SetPosition(const TPoint& aPoint)
+ {
+ if (iFlags & EAnimationInitialized)
+ {
+ iWsSprite->SetPosition(aPoint);
+ iWsSession->Flush();
+ }
+ }
+
+/** Implements CAnimation::Size */
+EXPORT_C TSize CSpriteAnimation::Size() const
+ {
+ return (iFlags & EAnimationInitialized) ? iClient->Size() : TSize(0,0);
+ }
+
+/** Implements CAnimation::Freeze.*/
+void CSpriteAnimation::Freeze()
+ {
+ if (iFlags & EAnimationInitialized)
+ {
+ iClient->Freeze();
+ iWsSession->Flush();
+ }
+ }
+
+/** Implements CAnimation::Unfreeze.*/
+void CSpriteAnimation::Unfreeze()
+ {
+ if (iFlags & EAnimationInitialized)
+ {
+ iClient->Unfreeze();
+ iWsSession->Flush();
+ }
+ }
+
+CSpriteAnimation::CSpriteAnimation(CAnimationDataProvider* aDataProvider, MAnimationObserver* aObserver, const CCoeControl* aHost):
+ iObserver(aObserver),
+ iDataProvider(aDataProvider),
+ iHost(aHost),
+ iFlags(0)
+ {
+ }
+
+// ConstructL called by the NewL functions that take a host argument
+void CSpriteAnimation::ConstructL(const TPoint& aPoint, const TDesC8& aDataType)
+ {
+ if (iHost)
+ {
+ iSpriteAnimationExt = CSpriteAnimationExt::NewL(aPoint,aDataType);
+ InitializeL();
+ }
+ }
+
+void CSpriteAnimation::InitializeL()
+ {
+ CCoeEnv* controlEnv = iHost->ControlEnv();
+ iWsSession = &controlEnv->WsSession();
+ iWsSprite = new (ELeave) RWsSprite(*iWsSession);
+ iAnimDll = RAnimDll(*iWsSession);
+ iClient = new (ELeave) RSpriteAnimationClient(iAnimDll);
+ User::LeaveIfError(iAnimDll.Load(KAnimationServerDll()));
+ User::LeaveIfError(iWsSprite->Construct(*iHost->DrawableWindow(), iSpriteAnimationExt->iPoint, ESpriteNoChildClip|ESpriteNoShadows));
+ TSpriteMember spriteMember;
+ spriteMember.iBitmap = new (ELeave) CFbsBitmap();
+ CleanupStack::PushL(spriteMember.iBitmap);
+ TDisplayMode displayMode = controlEnv->ScreenDevice()->DisplayMode();
+ User::LeaveIfError(spriteMember.iBitmap->Create(TSize(0,0), displayMode));
+ spriteMember.iMaskBitmap = new (ELeave) CFbsBitmap();
+ CleanupStack::PushL(spriteMember.iMaskBitmap);
+ User::LeaveIfError(spriteMember.iMaskBitmap->Create(TSize(0,0), EGray256));
+ iWsSprite->AppendMember(spriteMember);
+
+ // We have a TDesC8 and we need to pass a TDesC8, but unfortunately the windows server is going
+ // to be helpful by unpackaging the one we pass to it. Packaging a variable length object seems
+ // to require jumping through one or two hoops...
+ // First, make a descriptor with a known type, instead of a reference to 'something':
+ HBufC8* data = HBufC8::NewLC(iSpriteAnimationExt->iDataType.Length());
+ *data = iSpriteAnimationExt->iDataType;
+ // Second, make another descriptor large enough to hold the first one:
+ TInt size = data->Size() + sizeof(HBufC8) - sizeof(TText8);
+ HBufC8* datadesc = HBufC8::NewLC(size);
+ datadesc->Des().Copy(static_cast<TUint8*>(static_cast<TAny*>(data)), size);
+ // Finally, pass the outer descriptor to the server:
+ iClient->ConstructL(*iWsSprite, datadesc->Des(), reinterpret_cast<TInt>(iObserver));
+
+ CleanupStack::PopAndDestroy(2, data); // the data descriptors.
+ CleanupStack::PopAndDestroy(2, spriteMember.iBitmap); //bitmap and mask
+
+ iDataProvider->SetObserver(this);
+ iDataProvider->StartL();
+
+ iFlags |= EAnimationInitialized;
+ }
+
+void CSpriteAnimation::Reset()
+ {
+ iFlags |= (~EAnimationInitialized);
+
+ iWsSession = NULL;
+
+ if (iWsSprite)
+ {
+ iWsSprite->Close();
+ delete iWsSprite;
+ iWsSprite = NULL;
+ }
+
+ iAnimDll.Close();
+
+ if (iClient)
+ {
+ iClient->Close();
+ delete iClient;
+ iClient = NULL;
+ }
+
+ if(iSpriteAnimationExt)
+ {
+ delete iSpriteAnimationExt;
+ iSpriteAnimationExt = NULL;
+ }
+ }
+
+void CSpriteAnimation::DataProviderEventL(TInt aEvent, TAny* aData, TInt aDataSize)
+ {
+ if (!(aEvent & ~EAnimationReservedEvents))
+ {
+ switch(aEvent)
+ {
+ case EAnimationDataChanged:
+ iDataProvider->StartL();
+ break;
+ case EAnimationDataProviderError:
+ if (iObserver)
+ {
+ iObserver->AnimationEvent(*this, MAnimationObserver::EDataProviderError, aData);
+ }
+ break;
+ default:
+ User::Leave(KErrNotSupported);
+ }
+ }
+ iClient->SendEventL(aEvent, aData, aDataSize);
+ }
+
+CSpriteAnimation::CSpriteAnimation(CAnimationDataProvider* aDataProvider, RWsSession& aWsSession) :
+iWsSession(&aWsSession),
+iAnimDll(aWsSession)
+ {
+ iDataProvider = aDataProvider;
+ }
+
+// ConstructL called by the NewL functions that don't take a host argument
+void CSpriteAnimation::ConstructL(const TPoint& aPoint, RWindow& aWindow, const TDesC8& aDataType, MAnimationObserver* aObserver)
+ {
+ iWsSprite = new (ELeave) RWsSprite(*iWsSession);
+ iClient = new (ELeave) RSpriteAnimationClient(iAnimDll);
+ User::LeaveIfError(iAnimDll.Load(KAnimationServerDll()));
+ User::LeaveIfError(iWsSprite->Construct(aWindow, aPoint, ESpriteNoChildClip|ESpriteNoShadows));
+ iObserver = aObserver;
+ TSpriteMember spriteMember;
+ spriteMember.iBitmap = new (ELeave) CFbsBitmap();
+ CleanupStack::PushL(spriteMember.iBitmap);
+ User::LeaveIfError(spriteMember.iBitmap->Create(TSize(0,0), aWindow.DisplayMode()));
+ spriteMember.iMaskBitmap = new (ELeave) CFbsBitmap();
+ CleanupStack::PushL(spriteMember.iMaskBitmap);
+ User::LeaveIfError(spriteMember.iMaskBitmap->Create(TSize(0,0), EGray256));
+
+ iWsSprite->AppendMember(spriteMember);
+
+ // We have a TDesC8 and we need to pass a TDesC8, but unfortunately the windows server is going
+ // to be helpful by unpackaging the one we pass to it. Packaging a variable length object seems
+ // to require jumping through one or two hoops...
+ // First, make a descriptor with a known type, instead of a reference to 'something':
+ HBufC8* data = HBufC8::NewLC(aDataType.Length());
+ *data = aDataType;
+ // Second, make another descriptor large enough to hold the first one:
+ TInt size = data->Size() + sizeof(HBufC8) - sizeof(TText8);
+ HBufC8* datadesc = HBufC8::NewLC(size);
+ datadesc->Des().Copy(static_cast<TUint8*>(static_cast<TAny*>(data)), size);
+ // Finally, pass the outer descriptor to the server:
+ iClient->ConstructL(*iWsSprite, datadesc->Des());
+
+ CleanupStack::PopAndDestroy(2, data); // the data descriptors.
+ CleanupStack::PopAndDestroy(2, spriteMember.iBitmap); //bitmap and mask
+
+ iDataProvider->SetObserver(this);
+ iDataProvider->StartL();
+ iFlags |= EAnimationInitialized;
+ }
+
+/** Reserved for future use */
+EXPORT_C void CSpriteAnimation::CSpriteAnimation_Reserved2()
+ {
+ }
+