14 * Description: |
14 * Description: |
15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 |
18 |
|
19 |
19 #include <AknUtils.h> |
20 #include <AknUtils.h> |
20 #include <AknsUtils.h> |
21 #include <AknsUtils.h> |
21 #include <AknIconUtils.h> |
22 #include <AknIconUtils.h> |
22 #include <bautils.h> |
23 #include <bautils.h> |
23 |
24 |
24 #include "AknSmileyImage.h" |
25 #include "AknSmileyImage.h" |
25 |
26 |
26 const TInt KFrameMaxInterval = 3*1000*1000; // 3s |
27 const TInt KFrameMaxInterval = 3*1000*1000; // 30s |
27 const TInt KFrameMonitorStep = 5; // monitor once per 5 call, for increase performence |
28 const TInt KFrameMonitorStep = 5; // monitor once per 5 call, for increase performence |
28 const TInt KMaxSameFrameRepeat = 6; // 5 * 6, animation whose frame keep the same for 6 times call back, it will be stopped |
29 const TInt KMaxSameFrameRepeat = 6; // 5 * 6, animation frame keep same for 6 times will be stopped |
29 |
30 |
30 #define DELZ(ptr) {delete (ptr); (ptr)=NULL;} |
31 #define DELZ(ptr) {delete (ptr); (ptr)=NULL;} |
31 |
32 |
32 |
33 |
33 /////////////////////////////////////////////////////////////////////////////////////////////// |
34 /////////////////////////////////////////////////////////////////////////////////////////////// |
61 CleanupStack::PopAndDestroy(2); |
62 CleanupStack::PopAndDestroy(2); |
62 } |
63 } |
63 |
64 |
64 TBool BmpUtils::BitmpIsSame(const CFbsBitmap* aDesBmp, const CFbsBitmap* aSrcBmp) |
65 TBool BmpUtils::BitmpIsSame(const CFbsBitmap* aDesBmp, const CFbsBitmap* aSrcBmp) |
65 { |
66 { |
66 if(!aDesBmp || !aSrcBmp) return EFalse; |
67 if(!aDesBmp || !aSrcBmp) return FALSE; |
67 |
68 |
68 if(aDesBmp->SizeInPixels() == aSrcBmp->SizeInPixels()) |
69 if(aDesBmp->SizeInPixels() == aSrcBmp->SizeInPixels()) |
69 { |
70 { |
70 TSize size(aSrcBmp->SizeInPixels()); |
71 TSize size(aSrcBmp->SizeInPixels()); |
71 TInt scanLineLength = CFbsBitmap::ScanLineLength(size.iWidth, aSrcBmp->DisplayMode()); |
72 TInt scanLineLength = CFbsBitmap::ScanLineLength(size.iWidth, aSrcBmp->DisplayMode()); |
72 TInt length = scanLineLength*size.iHeight; |
73 TInt length = scanLineLength*size.iHeight; |
73 |
74 |
74 aDesBmp->BeginDataAccess(); |
75 aDesBmp->BeginDataAccess(); |
75 aSrcBmp->BeginDataAccess(); |
76 aSrcBmp->BeginDataAccess(); |
76 TInt result = Mem::Compare((TUint8*)aDesBmp->DataAddress(), length, (TUint8*)aSrcBmp->DataAddress(), length); |
77 TInt result = Mem::Compare((TUint8*)aDesBmp->DataAddress(), length, (TUint8*)aSrcBmp->DataAddress(), length); |
77 aSrcBmp->EndDataAccess(ETrue); |
78 aSrcBmp->EndDataAccess(TRUE); |
78 aDesBmp->EndDataAccess(ETrue); |
79 aDesBmp->EndDataAccess(TRUE); |
79 |
80 |
80 if(result == KErrNone) return ETrue; |
81 if(result == KErrNone) return TRUE; |
81 } |
82 } |
82 |
83 |
83 return EFalse; |
84 return FALSE; |
84 } |
85 } |
85 |
86 |
86 |
87 |
87 /////////////////////////////////////////////////////////////////////////////////////////////// |
88 /////////////////////////////////////////////////////////////////////////////////////////////// |
88 // SmileyUtils |
89 // SmileyUtils |
118 iFrameSnap = new (ELeave) CFbsBitmap; |
119 iFrameSnap = new (ELeave) CFbsBitmap; |
119 iAsynchronousTaskTimer = CPeriodic::NewL(CActive::EPriorityStandard); |
120 iAsynchronousTaskTimer = CPeriodic::NewL(CActive::EPriorityStandard); |
120 } |
121 } |
121 |
122 |
122 CSmileyImage::CSmileyImage(const TAknsItemID& aSkinImage, TInt aPkgImage, TBool aIsAnimation, MSmileyImageObserver* aObserver) : |
123 CSmileyImage::CSmileyImage(const TAknsItemID& aSkinImage, TInt aPkgImage, TBool aIsAnimation, MSmileyImageObserver* aObserver) : |
123 iImageMifPkgItemId(aPkgImage), |
124 iImagePkgItem(aPkgImage), |
124 iIsAnimation(aIsAnimation), |
125 iIsAnimation(aIsAnimation), |
125 iImageObserver(aObserver) |
126 iImageObserver(aObserver) |
126 { |
127 { |
127 iImageSkinItemId.Set(aSkinImage); |
128 iImageSkinItem.Set(aSkinImage); |
128 } |
129 } |
129 |
130 |
130 CSmileyImage::~CSmileyImage() |
131 CSmileyImage::~CSmileyImage() |
131 { |
132 { |
132 DoRelease(); |
133 DoRelease(); |
185 return iFrameMask; |
177 return iFrameMask; |
186 } |
178 } |
187 |
179 |
188 void CSmileyImage::BitmapChanged(CFbsBitmap* aBitmap) |
180 void CSmileyImage::BitmapChanged(CFbsBitmap* aBitmap) |
189 { |
181 { |
190 iReadyToDraw = ETrue; // animation is ready |
182 iReadyToDraw = TRUE; // animation is ready |
191 |
183 |
192 if(iImageObserver) iImageObserver->BitmapChanged(this, aBitmap); |
184 if(iImageObserver) iImageObserver->BitmapChanged(this, aBitmap); |
193 |
185 |
194 TRAP_IGNORE(MonitorAnimationEndedL()); |
186 TRAP_IGNORE(MonitorAnimationEndedL()); |
|
187 } |
|
188 |
|
189 void CSmileyImage::DoLoadL() |
|
190 { |
|
191 StopAnyAsynchronousTask(); |
|
192 |
|
193 if(iFrame) return; |
|
194 |
|
195 TFileName smileyMifName; |
|
196 SmileyUtils::GetCustomizableResPath(smileyMifName, KSmileyMif); |
|
197 if(iImageSkinItem.iMinor > 0) |
|
198 { |
|
199 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
200 TRAPD(err, AknsUtils::CreateColorIconL(skin, iImageSkinItem, |
|
201 KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG19, |
|
202 iFrame, iFrameMask, |
|
203 smileyMifName, iImagePkgItem, iImagePkgItem, |
|
204 AKN_LAF_COLOR(215))); |
|
205 } |
|
206 else |
|
207 { |
|
208 TRAPD(err, AknIconUtils::CreateIconL(iFrame, iFrameMask, smileyMifName, iImagePkgItem, iImagePkgItem)); |
|
209 } |
|
210 |
|
211 if(iIsAnimation) // the first frame of animation svg is blank without correct content |
|
212 { |
|
213 iReadyToDraw = FALSE; |
|
214 AknIconUtils::SetObserver(iFrame, this); |
|
215 |
|
216 StopAnimationAsynchronousL(KFrameMaxInterval); |
|
217 } |
|
218 else // the first frame of static svg has correct content |
|
219 { |
|
220 iReadyToDraw = TRUE; |
|
221 if(iImageObserver) iImageObserver->BitmapChanged(this, iFrame); |
|
222 } |
|
223 |
|
224 AknIconUtils::SetSize(iFrame, iSize); |
|
225 } |
|
226 |
|
227 void CSmileyImage::DoRelease() |
|
228 { |
|
229 StopAnyAsynchronousTask(); |
|
230 |
|
231 if(!iFrame) return; |
|
232 |
|
233 DELZ(iFrame); |
|
234 DELZ(iFrameMask); |
|
235 iFrameSnap->Reset(); |
|
236 |
|
237 iReadyToDraw = FALSE; |
|
238 } |
|
239 |
|
240 void CSmileyImage::StopAnyAsynchronousTask() |
|
241 { |
|
242 iAsynchronousTaskTimer->Cancel(); |
195 } |
243 } |
196 |
244 |
197 void CSmileyImage::MonitorAnimationEndedL() |
245 void CSmileyImage::MonitorAnimationEndedL() |
198 { |
246 { |
199 // for animation doesn't call back |
247 // for animation doesn't call back |
201 |
249 |
202 // for reduce the times of animation monitor |
250 // for reduce the times of animation monitor |
203 iFrameCounter++; |
251 iFrameCounter++; |
204 if(iFrameCounter % KFrameMonitorStep) return; |
252 if(iFrameCounter % KFrameMonitorStep) return; |
205 |
253 |
206 // for not call back any more |
|
207 StopAnimationAsynchronousL(KFrameMaxInterval); |
|
208 |
|
209 // monitor the end of animation clip, replay or stop animation if ended |
254 // monitor the end of animation clip, replay or stop animation if ended |
210 if(BmpUtils::BitmpIsSame(iFrameSnap, iFrame)) |
255 if(BmpUtils::BitmpIsSame(iFrameSnap, iFrame)) |
211 { |
256 { |
212 iSameFrameCounter++; |
257 iSameFrameCounter++; |
213 if(iSameFrameCounter > KMaxSameFrameRepeat) |
258 if(iSameFrameCounter > KMaxSameFrameRepeat) |
214 { |
259 { |
215 StopAnimationAsynchronousL(); // can not stop animation synchronously |
260 StopAnimationAsynchronousL(); |
216 } |
261 } |
217 } |
262 } |
218 else |
263 else |
219 { |
264 { |
220 iSameFrameCounter = 0; |
265 iSameFrameCounter = 0; |
221 BmpUtils::CopyBitmpL(iFrameSnap, iFrame); |
266 BmpUtils::CopyBitmpL(iFrameSnap, iFrame); |
222 } |
267 } |
223 } |
268 } |
224 |
269 |
225 void CSmileyImage::DoLoadL() |
270 void CSmileyImage::HandleAnimationEndedL() |
226 { |
|
227 StopAsynchronousTaskTimer(); |
|
228 |
|
229 if(iFrame) return; |
|
230 |
|
231 TFileName smileyMifName; |
|
232 SmileyUtils::GetCustomizableResPath(smileyMifName, KSmileyMif); |
|
233 |
|
234 if(iImageSkinItemId.iMinor > 0) |
|
235 { |
|
236 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
237 TRAP_IGNORE(AknsUtils::CreateColorIconL(skin, iImageSkinItemId, |
|
238 KAknsIIDQsnTextColors,EAknsCIQsnTextColorsCG19, |
|
239 iFrame,iFrameMask, |
|
240 smileyMifName, iImageMifPkgItemId,iImageMifPkgItemId, |
|
241 AKN_LAF_COLOR(215))); |
|
242 } |
|
243 else |
|
244 { |
|
245 TRAP_IGNORE(AknIconUtils::CreateIconL(iFrame,iFrameMask,smileyMifName,iImageMifPkgItemId,iImageMifPkgItemId)); |
|
246 } |
|
247 |
|
248 if(iIsAnimation) // the first frame of animation svg is blank without correct content |
|
249 { |
|
250 iReadyToDraw = EFalse; |
|
251 AknIconUtils::SetObserver(iFrame, this); |
|
252 StopAnimationAsynchronousL(KFrameMaxInterval); // monitor for no callback |
|
253 } |
|
254 else // the first frame of static svg has correct content |
|
255 { |
|
256 iReadyToDraw = ETrue; |
|
257 if(iImageObserver) iImageObserver->BitmapChanged(this, iFrame); |
|
258 } |
|
259 |
|
260 AknIconUtils::SetSize(iFrame, iSize); |
|
261 } |
|
262 |
|
263 void CSmileyImage::DoRelease() |
|
264 { |
|
265 StopAsynchronousTaskTimer(); |
|
266 |
|
267 if(!iFrame) return; |
|
268 |
|
269 DELZ(iFrame); |
|
270 DELZ(iFrameMask); |
|
271 iFrameSnap->Reset(); |
|
272 |
|
273 iReadyToDraw = EFalse; |
|
274 } |
|
275 |
|
276 void CSmileyImage::DoHandleEndedL() |
|
277 { |
271 { |
278 DoRelease(); |
272 DoRelease(); |
279 |
273 |
280 if(iRepeatCount != 0) |
274 if(iRepeatCount != 0) |
281 { |
275 { |
282 iRepeatCount--; |
276 iRepeatCount--; |
283 DoLoadL(); |
277 DoLoadL(); |
284 } |
278 } |
285 } |
279 } |
286 |
280 |
287 void CSmileyImage::StopAsynchronousTaskTimer() |
281 void CSmileyImage::StartLoadAsynchronousL(TInt aRepeat, TInt aDelayMicroSeconds) |
288 { |
282 { |
|
283 iRepeatCount = aRepeat; |
|
284 |
289 iAsynchronousTaskTimer->Cancel(); |
285 iAsynchronousTaskTimer->Cancel(); |
290 } |
|
291 |
|
292 void CSmileyImage::StartLoadAsynchronousL(TInt aDelayMicroSeconds) |
|
293 { |
|
294 StopAsynchronousTaskTimer(); |
|
295 iAsynchronousTaskTimer->Start(aDelayMicroSeconds, 1, TCallBack(StartLoadAsynchronousCallBackL,this)); |
286 iAsynchronousTaskTimer->Start(aDelayMicroSeconds, 1, TCallBack(StartLoadAsynchronousCallBackL,this)); |
296 } |
287 } |
297 |
288 |
298 TInt CSmileyImage::StartLoadAsynchronousCallBackL(TAny* aPtr) |
289 TInt CSmileyImage::StartLoadAsynchronousCallBackL(TAny* aPtr) |
299 { |
290 { |
300 CSmileyImage* self = (CSmileyImage*)aPtr; |
291 CSmileyImage* self = (CSmileyImage*)aPtr; |
301 self->StopAsynchronousTaskTimer(); |
292 self->StopAnyAsynchronousTask(); |
302 self->DoLoadL(); |
293 self->DoLoadL(); |
303 return KErrNone; |
294 return KErrNone; |
304 } |
295 } |
305 |
296 |
306 void CSmileyImage::StopAnimationAsynchronousL(TInt aDelayMicroSeconds) |
297 void CSmileyImage::StopAnimationAsynchronousL(TInt aDelayMicroSeconds) |
307 { |
298 { |
308 StopAsynchronousTaskTimer(); |
299 iAsynchronousTaskTimer->Cancel(); |
309 iAsynchronousTaskTimer->Start(aDelayMicroSeconds, 1, TCallBack(StopAnimationAsynchronousCallBackL,this)); |
300 iAsynchronousTaskTimer->Start(aDelayMicroSeconds, 1, TCallBack(StopAnimationAsynchronousCallBackL,this)); |
310 } |
301 } |
311 |
302 |
312 TInt CSmileyImage::StopAnimationAsynchronousCallBackL(TAny* aPtr) |
303 TInt CSmileyImage::StopAnimationAsynchronousCallBackL(TAny* aPtr) |
313 { |
304 { |
314 CSmileyImage* self = (CSmileyImage*)aPtr; |
305 CSmileyImage* self = (CSmileyImage*)aPtr; |
315 self->StopAsynchronousTaskTimer(); |
306 self->StopAnyAsynchronousTask(); |
316 self->DoHandleEndedL(); |
307 self->HandleAnimationEndedL(); |
317 return KErrNone; |
308 return KErrNone; |
318 } |
309 } |
319 |
310 |
320 |
311 |
321 // end of file |
312 // end of file |