diff -r 000000000000 -r 2f259fa3e83a lafagnosticuifoundation/animation/src/SpriteAnimation.cpp --- /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 +#include + +#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(static_cast(data)), size); + // Finally, pass the outer descriptor to the server: + iClient->ConstructL(*iWsSprite, datadesc->Des(), reinterpret_cast(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(static_cast(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() + { + } +