|
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "SpriteAnimation.h" |
|
17 |
|
18 #include <w32std.h> |
|
19 #include <coecntrl.h> |
|
20 |
|
21 #include "AnimationDataProvider.h" |
|
22 #include "AnimationConfig.h" |
|
23 #include "SpriteAnimationClient.h" |
|
24 #include "AnimationEvents.h" |
|
25 #include "spriteanimationext.h" |
|
26 |
|
27 _LIT(KAnimationServerDll, "AnimationServer.dll"); |
|
28 |
|
29 /** |
|
30 Two stage constructor. |
|
31 |
|
32 This creates and returns a new sprite animation. |
|
33 |
|
34 @param aDataProvider The data provider from which the animation contents will |
|
35 be obtained. The animation takes ownership of this object |
|
36 @param aPoint The starting position of the sprite in the window |
|
37 @param aWsSession A session with the window server |
|
38 @param aWindow The window in which to draw the animation |
|
39 @param aObserver An optional receiver of animation events (such as errors) |
|
40 @return The new object |
|
41 */ |
|
42 EXPORT_C CSpriteAnimation* CSpriteAnimation::NewL(CAnimationDataProvider* aDataProvider, const TPoint& aPoint, RWsSession& aWsSession, RWindow& aWindow, MAnimationObserver* aObserver) |
|
43 { |
|
44 return CSpriteAnimation::NewL(aDataProvider, aPoint, aWsSession, aWindow, aDataProvider->DataType(), aObserver); |
|
45 } |
|
46 |
|
47 /** |
|
48 Two stage constructor. |
|
49 |
|
50 This is identical to the other NewL except that it allows an alternative data |
|
51 type to be specified. Unless you are trying to use a custom animator class |
|
52 the other form of constructor should be used. |
|
53 |
|
54 @param aDataProvider The data provider from which the animation contents will |
|
55 be obtained. The animation takes ownership of this object |
|
56 @param aPoint The starting position of the sprite in the window |
|
57 @param aWsSession A session with the window server |
|
58 @param aWindow The window in which to draw the animation |
|
59 @param aDataType Overrides the data type specified by the data provider |
|
60 @param aObserver An optional receiver of animation events (such as errors) |
|
61 @return The new object |
|
62 */ |
|
63 EXPORT_C CSpriteAnimation* CSpriteAnimation::NewL(CAnimationDataProvider* aDataProvider, const TPoint& aPoint, RWsSession& aWsSession, RWindow& aWindow, const TDesC8& aDataType, MAnimationObserver* aObserver) |
|
64 { |
|
65 CleanupStack::PushL(aDataProvider); |
|
66 CSpriteAnimation* self = new (ELeave) CSpriteAnimation(aDataProvider, aWsSession); |
|
67 CleanupStack::Pop(aDataProvider); |
|
68 CleanupStack::PushL(self); |
|
69 self->ConstructL(aPoint, aWindow, aDataType, aObserver); |
|
70 CleanupStack::Pop(self); |
|
71 return self; |
|
72 } |
|
73 |
|
74 /** |
|
75 Two stage constructor. |
|
76 |
|
77 This creates and returns a new sprite animation. |
|
78 |
|
79 @param aDataProvider The data provider from which the animation contents will |
|
80 be obtained. The animation takes ownership of this object |
|
81 @param aPoint The starting position of the sprite in the window |
|
82 @param aWsSession A session with the window server |
|
83 @param aWindow The window in which to draw the animation |
|
84 @param aObserver An optional receiver of animation events (such as errors) |
|
85 @return The new object |
|
86 */ |
|
87 EXPORT_C CSpriteAnimation* CSpriteAnimation::NewL(CAnimationDataProvider* aDataProvider, const TPoint& aPoint, MAnimationObserver* aObserver, const CCoeControl* aHost) |
|
88 { |
|
89 return CSpriteAnimation::NewL(aDataProvider, aPoint, aDataProvider->DataType(), aObserver, aHost); |
|
90 } |
|
91 |
|
92 /** |
|
93 Two stage constructor. |
|
94 |
|
95 This is identical to the other NewL except that it allows an alternative data |
|
96 type to be specified. Unless you are trying to use a custom animator class |
|
97 the other form of constructor should be used. |
|
98 |
|
99 @param aDataProvider The data provider from which the animation contents will |
|
100 be obtained. The animation takes ownership of this object |
|
101 @param aPoint The starting position of the sprite in the window |
|
102 @param aWsSession A session with the window server |
|
103 @param aWindow The window in which to draw the animation |
|
104 @param aDataType Overrides the data type specified by the data provider |
|
105 @param aObserver An optional receiver of animation events (such as errors) |
|
106 @return The new object |
|
107 */ |
|
108 EXPORT_C CSpriteAnimation* CSpriteAnimation::NewL(CAnimationDataProvider* aDataProvider, const TPoint& aPoint, const TDesC8& aDataType, MAnimationObserver* aObserver, const CCoeControl* aHost) |
|
109 { |
|
110 CleanupStack::PushL(aDataProvider); |
|
111 CSpriteAnimation* self = new (ELeave) CSpriteAnimation(aDataProvider, aObserver, aHost); |
|
112 CleanupStack::Pop(aDataProvider); |
|
113 CleanupStack::PushL(self); |
|
114 self->ConstructL(aPoint, aDataType); |
|
115 CleanupStack::Pop(self); |
|
116 |
|
117 return self; |
|
118 } |
|
119 |
|
120 /** Destructor.*/ |
|
121 EXPORT_C CSpriteAnimation::~CSpriteAnimation() |
|
122 { |
|
123 delete iDataProvider; |
|
124 iDataProvider = NULL; |
|
125 |
|
126 if (iWsSprite) |
|
127 { |
|
128 iWsSprite->Close(); |
|
129 delete iWsSprite; |
|
130 iWsSprite = NULL; |
|
131 } |
|
132 |
|
133 iAnimDll.Close(); |
|
134 |
|
135 if (iClient) |
|
136 { |
|
137 delete iClient; |
|
138 iClient = NULL; |
|
139 } |
|
140 |
|
141 if(iSpriteAnimationExt) |
|
142 { |
|
143 delete iSpriteAnimationExt; |
|
144 iSpriteAnimationExt = NULL; |
|
145 } |
|
146 |
|
147 iObserver = NULL; |
|
148 iWsSession = NULL; |
|
149 iHost = NULL; |
|
150 } |
|
151 |
|
152 EXPORT_C void CSpriteAnimation::SetHostL(const CCoeControl* aHost) |
|
153 { |
|
154 if (iHost) |
|
155 { |
|
156 Reset(); |
|
157 } |
|
158 iHost = aHost; |
|
159 |
|
160 if (iHost) |
|
161 { |
|
162 InitializeL(); |
|
163 } |
|
164 } |
|
165 |
|
166 /** Implements CAnimation::Start. |
|
167 @param aConfig Specifies run time attributes of the animation */ |
|
168 void CSpriteAnimation::Start(const TAnimationConfig& aConfig) |
|
169 { |
|
170 if (iFlags & EAnimationInitialized) |
|
171 { |
|
172 iClient->Start(aConfig); |
|
173 iWsSession->Flush(); |
|
174 } |
|
175 } |
|
176 |
|
177 /** Implements CAnimation::Stop.*/ |
|
178 void CSpriteAnimation::Stop() |
|
179 { |
|
180 if (iFlags & EAnimationInitialized) |
|
181 { |
|
182 iClient->Stop(); |
|
183 iWsSession->Flush(); |
|
184 } |
|
185 } |
|
186 |
|
187 /** Implements CAnimation::Pause.*/ |
|
188 void CSpriteAnimation::Pause() |
|
189 { |
|
190 if (iFlags & EAnimationInitialized) |
|
191 { |
|
192 iClient->Pause(); |
|
193 iWsSession->Flush(); |
|
194 } |
|
195 } |
|
196 |
|
197 /** Implements CAnimation::Resume.*/ |
|
198 void CSpriteAnimation::Resume() |
|
199 { |
|
200 if (iFlags & EAnimationInitialized) |
|
201 { |
|
202 iClient->Resume(); |
|
203 iWsSession->Flush(); |
|
204 } |
|
205 } |
|
206 |
|
207 /** Implements CAnimation::Hold.*/ |
|
208 void CSpriteAnimation::Hold() |
|
209 { |
|
210 if (iFlags & EAnimationInitialized) |
|
211 { |
|
212 iClient->Hold(); |
|
213 iWsSession->Flush(); |
|
214 } |
|
215 } |
|
216 |
|
217 /** Implements CAnimation::Unhold.*/ |
|
218 void CSpriteAnimation::Unhold() |
|
219 { |
|
220 if (iFlags & EAnimationInitialized) |
|
221 { |
|
222 iClient->Unhold(); |
|
223 iWsSession->Flush(); |
|
224 } |
|
225 } |
|
226 |
|
227 /** Implements CAnimation::SetPosition. |
|
228 @param aPoint The new coordinates of the animation (usually the top left corner) */ |
|
229 void CSpriteAnimation::SetPosition(const TPoint& aPoint) |
|
230 { |
|
231 if (iFlags & EAnimationInitialized) |
|
232 { |
|
233 iWsSprite->SetPosition(aPoint); |
|
234 iWsSession->Flush(); |
|
235 } |
|
236 } |
|
237 |
|
238 /** Implements CAnimation::Size */ |
|
239 EXPORT_C TSize CSpriteAnimation::Size() const |
|
240 { |
|
241 return (iFlags & EAnimationInitialized) ? iClient->Size() : TSize(0,0); |
|
242 } |
|
243 |
|
244 /** Implements CAnimation::Freeze.*/ |
|
245 void CSpriteAnimation::Freeze() |
|
246 { |
|
247 if (iFlags & EAnimationInitialized) |
|
248 { |
|
249 iClient->Freeze(); |
|
250 iWsSession->Flush(); |
|
251 } |
|
252 } |
|
253 |
|
254 /** Implements CAnimation::Unfreeze.*/ |
|
255 void CSpriteAnimation::Unfreeze() |
|
256 { |
|
257 if (iFlags & EAnimationInitialized) |
|
258 { |
|
259 iClient->Unfreeze(); |
|
260 iWsSession->Flush(); |
|
261 } |
|
262 } |
|
263 |
|
264 CSpriteAnimation::CSpriteAnimation(CAnimationDataProvider* aDataProvider, MAnimationObserver* aObserver, const CCoeControl* aHost): |
|
265 iObserver(aObserver), |
|
266 iDataProvider(aDataProvider), |
|
267 iHost(aHost), |
|
268 iFlags(0) |
|
269 { |
|
270 } |
|
271 |
|
272 // ConstructL called by the NewL functions that take a host argument |
|
273 void CSpriteAnimation::ConstructL(const TPoint& aPoint, const TDesC8& aDataType) |
|
274 { |
|
275 if (iHost) |
|
276 { |
|
277 iSpriteAnimationExt = CSpriteAnimationExt::NewL(aPoint,aDataType); |
|
278 InitializeL(); |
|
279 } |
|
280 } |
|
281 |
|
282 void CSpriteAnimation::InitializeL() |
|
283 { |
|
284 CCoeEnv* controlEnv = iHost->ControlEnv(); |
|
285 iWsSession = &controlEnv->WsSession(); |
|
286 iWsSprite = new (ELeave) RWsSprite(*iWsSession); |
|
287 iAnimDll = RAnimDll(*iWsSession); |
|
288 iClient = new (ELeave) RSpriteAnimationClient(iAnimDll); |
|
289 User::LeaveIfError(iAnimDll.Load(KAnimationServerDll())); |
|
290 User::LeaveIfError(iWsSprite->Construct(*iHost->DrawableWindow(), iSpriteAnimationExt->iPoint, ESpriteNoChildClip|ESpriteNoShadows)); |
|
291 TSpriteMember spriteMember; |
|
292 spriteMember.iBitmap = new (ELeave) CFbsBitmap(); |
|
293 CleanupStack::PushL(spriteMember.iBitmap); |
|
294 TDisplayMode displayMode = controlEnv->ScreenDevice()->DisplayMode(); |
|
295 User::LeaveIfError(spriteMember.iBitmap->Create(TSize(0,0), displayMode)); |
|
296 spriteMember.iMaskBitmap = new (ELeave) CFbsBitmap(); |
|
297 CleanupStack::PushL(spriteMember.iMaskBitmap); |
|
298 User::LeaveIfError(spriteMember.iMaskBitmap->Create(TSize(0,0), EGray256)); |
|
299 iWsSprite->AppendMember(spriteMember); |
|
300 |
|
301 // We have a TDesC8 and we need to pass a TDesC8, but unfortunately the windows server is going |
|
302 // to be helpful by unpackaging the one we pass to it. Packaging a variable length object seems |
|
303 // to require jumping through one or two hoops... |
|
304 // First, make a descriptor with a known type, instead of a reference to 'something': |
|
305 HBufC8* data = HBufC8::NewLC(iSpriteAnimationExt->iDataType.Length()); |
|
306 *data = iSpriteAnimationExt->iDataType; |
|
307 // Second, make another descriptor large enough to hold the first one: |
|
308 TInt size = data->Size() + sizeof(HBufC8) - sizeof(TText8); |
|
309 HBufC8* datadesc = HBufC8::NewLC(size); |
|
310 datadesc->Des().Copy(static_cast<TUint8*>(static_cast<TAny*>(data)), size); |
|
311 // Finally, pass the outer descriptor to the server: |
|
312 iClient->ConstructL(*iWsSprite, datadesc->Des(), reinterpret_cast<TInt>(iObserver)); |
|
313 |
|
314 CleanupStack::PopAndDestroy(2, data); // the data descriptors. |
|
315 CleanupStack::PopAndDestroy(2, spriteMember.iBitmap); //bitmap and mask |
|
316 |
|
317 iDataProvider->SetObserver(this); |
|
318 iDataProvider->StartL(); |
|
319 |
|
320 iFlags |= EAnimationInitialized; |
|
321 } |
|
322 |
|
323 void CSpriteAnimation::Reset() |
|
324 { |
|
325 iFlags |= (~EAnimationInitialized); |
|
326 |
|
327 iWsSession = NULL; |
|
328 |
|
329 if (iWsSprite) |
|
330 { |
|
331 iWsSprite->Close(); |
|
332 delete iWsSprite; |
|
333 iWsSprite = NULL; |
|
334 } |
|
335 |
|
336 iAnimDll.Close(); |
|
337 |
|
338 if (iClient) |
|
339 { |
|
340 iClient->Close(); |
|
341 delete iClient; |
|
342 iClient = NULL; |
|
343 } |
|
344 |
|
345 if(iSpriteAnimationExt) |
|
346 { |
|
347 delete iSpriteAnimationExt; |
|
348 iSpriteAnimationExt = NULL; |
|
349 } |
|
350 } |
|
351 |
|
352 void CSpriteAnimation::DataProviderEventL(TInt aEvent, TAny* aData, TInt aDataSize) |
|
353 { |
|
354 if (!(aEvent & ~EAnimationReservedEvents)) |
|
355 { |
|
356 switch(aEvent) |
|
357 { |
|
358 case EAnimationDataChanged: |
|
359 iDataProvider->StartL(); |
|
360 break; |
|
361 case EAnimationDataProviderError: |
|
362 if (iObserver) |
|
363 { |
|
364 iObserver->AnimationEvent(*this, MAnimationObserver::EDataProviderError, aData); |
|
365 } |
|
366 break; |
|
367 default: |
|
368 User::Leave(KErrNotSupported); |
|
369 } |
|
370 } |
|
371 iClient->SendEventL(aEvent, aData, aDataSize); |
|
372 } |
|
373 |
|
374 CSpriteAnimation::CSpriteAnimation(CAnimationDataProvider* aDataProvider, RWsSession& aWsSession) : |
|
375 iWsSession(&aWsSession), |
|
376 iAnimDll(aWsSession) |
|
377 { |
|
378 iDataProvider = aDataProvider; |
|
379 } |
|
380 |
|
381 // ConstructL called by the NewL functions that don't take a host argument |
|
382 void CSpriteAnimation::ConstructL(const TPoint& aPoint, RWindow& aWindow, const TDesC8& aDataType, MAnimationObserver* aObserver) |
|
383 { |
|
384 iWsSprite = new (ELeave) RWsSprite(*iWsSession); |
|
385 iClient = new (ELeave) RSpriteAnimationClient(iAnimDll); |
|
386 User::LeaveIfError(iAnimDll.Load(KAnimationServerDll())); |
|
387 User::LeaveIfError(iWsSprite->Construct(aWindow, aPoint, ESpriteNoChildClip|ESpriteNoShadows)); |
|
388 iObserver = aObserver; |
|
389 TSpriteMember spriteMember; |
|
390 spriteMember.iBitmap = new (ELeave) CFbsBitmap(); |
|
391 CleanupStack::PushL(spriteMember.iBitmap); |
|
392 User::LeaveIfError(spriteMember.iBitmap->Create(TSize(0,0), aWindow.DisplayMode())); |
|
393 spriteMember.iMaskBitmap = new (ELeave) CFbsBitmap(); |
|
394 CleanupStack::PushL(spriteMember.iMaskBitmap); |
|
395 User::LeaveIfError(spriteMember.iMaskBitmap->Create(TSize(0,0), EGray256)); |
|
396 |
|
397 iWsSprite->AppendMember(spriteMember); |
|
398 |
|
399 // We have a TDesC8 and we need to pass a TDesC8, but unfortunately the windows server is going |
|
400 // to be helpful by unpackaging the one we pass to it. Packaging a variable length object seems |
|
401 // to require jumping through one or two hoops... |
|
402 // First, make a descriptor with a known type, instead of a reference to 'something': |
|
403 HBufC8* data = HBufC8::NewLC(aDataType.Length()); |
|
404 *data = aDataType; |
|
405 // Second, make another descriptor large enough to hold the first one: |
|
406 TInt size = data->Size() + sizeof(HBufC8) - sizeof(TText8); |
|
407 HBufC8* datadesc = HBufC8::NewLC(size); |
|
408 datadesc->Des().Copy(static_cast<TUint8*>(static_cast<TAny*>(data)), size); |
|
409 // Finally, pass the outer descriptor to the server: |
|
410 iClient->ConstructL(*iWsSprite, datadesc->Des()); |
|
411 |
|
412 CleanupStack::PopAndDestroy(2, data); // the data descriptors. |
|
413 CleanupStack::PopAndDestroy(2, spriteMember.iBitmap); //bitmap and mask |
|
414 |
|
415 iDataProvider->SetObserver(this); |
|
416 iDataProvider->StartL(); |
|
417 iFlags |= EAnimationInitialized; |
|
418 } |
|
419 |
|
420 /** Reserved for future use */ |
|
421 EXPORT_C void CSpriteAnimation::CSpriteAnimation_Reserved2() |
|
422 { |
|
423 } |
|
424 |