lafagnosticuifoundation/animation/src/SpriteAnimation.cpp
changeset 0 2f259fa3e83a
--- /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()
+	{
+	}
+