Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / controls / FUiCtrl_AnimationPresenter.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file                FUiCtrl_AnimationPresenter.cpp
19  * @brief               This is the implementation file for the _AnimationPresenter class.
20  */
21
22 #include <FBaseErrorDefine.h>
23 #include <FBaseSysLog.h>
24 #include "FUiCtrl_AnimationPresenter.h"
25 #include "FUiCtrl_Animation.h"
26 #include "FUiCtrl_AnimationModel.h"
27
28 using namespace Tizen::Graphics;
29 using namespace Tizen::Base::Runtime;
30 using namespace Tizen::Base::Collection;
31 using namespace Tizen::Base;
32
33 namespace Tizen { namespace Ui { namespace Controls
34 {
35
36 _AnimationPresenter::_AnimationPresenter(void)
37         : __pAnimation(null)
38         , __pAnimationModel(null)
39         , __pTimer(null)
40         , __pCurrentFrame(null)
41         , __isTimerRunning(false)
42         , __pVisualElement(null)
43 {
44 }
45
46 _AnimationPresenter::~_AnimationPresenter(void)
47 {
48         Dispose();
49 }
50
51 _AnimationPresenter*
52 _AnimationPresenter::CreateInstanceN(const _Animation& animation)
53 {
54         result r = E_SUCCESS;
55
56         _AnimationPresenter* pAnimationPresenter = new (std::nothrow) _AnimationPresenter();
57         SysTryReturn(NID_UI_CTRL, pAnimationPresenter != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
58
59         r = pAnimationPresenter->Initialize(animation);
60
61         if (r != E_SUCCESS)
62         {
63                 SysLogException(NID_UI_CTRL, r, "Failed to initialize the Animation Presenter.");
64
65                 delete pAnimationPresenter;
66                 pAnimationPresenter = null;
67
68                 return null;
69         }
70
71         return pAnimationPresenter;
72 }
73
74 result
75 _AnimationPresenter::Initialize(const _Animation& animation)
76 {
77         result r = E_SUCCESS;
78
79         __pAnimation = const_cast <_Animation*>(&animation);
80         SysTryReturnResult(NID_UI_CTRL, __pAnimation != null, E_SYSTEM, "A system error has occurred. Animation control core is null.");
81
82         __pAnimationModel = new (std::nothrow) _AnimationModel();
83         SysTryCatch(NID_UI_CTRL, __pAnimationModel != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
84
85         __pTimer = new (std::nothrow) Timer();
86         SysTryCatch(NID_UI_CTRL, __pTimer != null, , E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to create a new timer.");
87
88         r = __pTimer->Construct(*__pAnimation);
89         SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[E_SYSTEM] A system error has occurred. Failed to construct the timer.");
90
91         __pVisualElement = __pAnimation->GetVisualElement();
92         SysTryCatch(NID_UI_CTRL, __pVisualElement != null, , E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get the root visual element");
93
94         return r;
95
96 CATCH:
97         Dispose();
98         return r;
99 }
100
101 bool
102 _AnimationPresenter::IsTimerExpired(Timer& timer)
103 {
104         bool isTimerExpired = false;
105
106         __isTimerRunning = false;
107         SysTryReturn(NID_UI_CTRL, __pAnimationModel->GetAnimationStatus() == ANIMATION_PLAYING, false, E_SYSTEM,
108                                 "[E_SYSTEM] A system error has occurred. Animation is in ANIMATION_PLAYING state.");
109
110         AnimationFrame* pNextFrame = GetNextFrame();
111         SysTryReturn(NID_UI_CTRL, pNextFrame != null, false, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get the next animation frame.");
112
113         if (__pAnimationModel->GetCurrentRepeatedCount() < __pAnimationModel->GetRepeatCount())
114         {
115                 if (timer.Start(pNextFrame->GetDuration()) == E_SUCCESS)
116                 {
117                         __isTimerRunning = true;
118                 }
119                 else
120                 {
121                         __pAnimationModel->SetAnimationStatus(ANIMATION_PAUSED);
122                 }
123                 isTimerExpired = false;
124         }
125         else
126         {
127                 __pAnimationModel->SetCurrentRepeatedCount(0);
128
129                 __pAnimationModel->SetAnimationStatus(ANIMATION_STOPPED);
130                 isTimerExpired = true;
131         }
132
133         result r = Draw();
134         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
135
136         return isTimerExpired;
137 }
138
139 void
140 _AnimationPresenter::SetImageCount(int imageCount)
141 {
142         __pAnimationModel->SetImageCount(imageCount);
143
144         return;
145 }
146
147 result
148 _AnimationPresenter::SetAnimationFrames(const IList* pAnimationFrames)
149 {
150         SysTryReturnResult(NID_UI_CTRL, pAnimationFrames != null, E_SYSTEM, "A system error has occurred. AnimationFrame list is null");
151
152         __pCurrentFrame = pAnimationFrames->GetEnumeratorN();
153         SysTryReturnResult(NID_UI_CTRL, __pCurrentFrame != null, E_SYSTEM, "A system error has occurred. Failed to get the AnimationFrame list.");
154
155         return E_SUCCESS;
156 }
157
158 void
159 _AnimationPresenter::SetRepeatCount(int count)
160 {
161         __pAnimationModel->SetRepeatCount(count);
162
163         return;
164 }
165
166 int
167 _AnimationPresenter::GetRepeatCount(void) const
168 {
169         return __pAnimationModel->GetRepeatCount();
170 }
171
172 int
173 _AnimationPresenter::GetCurrentRepeatedCount(void) const
174 {
175         return __pAnimationModel->GetCurrentRepeatedCount();
176 }
177
178 int
179 _AnimationPresenter::GetImageCount(void) const
180 {
181         return __pAnimationModel->GetImageCount();
182 }
183
184 result
185 _AnimationPresenter::Play(void)
186 {
187         result r = E_SUCCESS;
188
189         if (__isTimerRunning == true)
190         {
191                 return E_SUCCESS;
192         }
193
194         if (__pAnimationModel->GetAnimationStatus() != ANIMATION_PAUSED)
195         {
196                 __pAnimationModel->SetCurrentRepeatedCount(0);
197         }
198
199         AnimationFrame* pFrame = dynamic_cast <AnimationFrame*>(__pCurrentFrame->GetCurrent());
200
201         if (pFrame == null)
202         {
203                 pFrame = GetNextFrame();
204                 SysTryReturnResult(NID_UI_CTRL, pFrame != null, E_SYSTEM, "A system error has occurred. Failed to get the next AnimationFrame.");
205
206                 r = Draw();
207                 SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
208         }
209
210         r = __pTimer->Start(pFrame->GetDuration());
211         SysTryReturnResult(NID_UI_CTRL, r == E_SUCCESS, r, "A system error has occurred. Failed to start the timer");
212
213         __isTimerRunning = true;
214         __pAnimationModel->SetAnimationStatus(ANIMATION_PLAYING);
215
216         return r;
217 }
218
219 result
220 _AnimationPresenter::Stop(void)
221 {
222         if (__isTimerRunning == true)
223         {
224                 if (__pTimer != null)
225                 {
226                         __pTimer->Cancel();
227                 }
228                 __isTimerRunning = false;
229         }
230
231         __pAnimationModel->SetCurrentRepeatedCount(0);
232         __pCurrentFrame->Reset();
233         __pAnimationModel->SetAnimationStatus(ANIMATION_STOPPED);
234
235         result r = Draw();
236         SysTryReturn(NID_UI_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
237
238         return E_SUCCESS;
239 }
240
241 result
242 _AnimationPresenter::Pause(void)
243 {
244         SysTryReturnResult(NID_UI_CTRL, __isTimerRunning == true, E_SYSTEM, "A system error has occurred. Timer is not in running state.");
245
246         if (__pTimer != null)
247         {
248                 __pTimer->Cancel();
249         }
250         __isTimerRunning = false;
251
252         __pAnimationModel->SetAnimationStatus(ANIMATION_PAUSED);
253
254         return E_SUCCESS;
255 }
256
257 AnimationStatus
258 _AnimationPresenter::GetStatus(void) const
259 {
260         return __pAnimationModel->GetAnimationStatus();
261 }
262
263 AnimationFrame*
264 _AnimationPresenter::GetCurrentFrame(void) const
265 {
266         AnimationFrame* pFrame = dynamic_cast <AnimationFrame*>(__pCurrentFrame->GetCurrent());
267
268         if (pFrame != null)
269         {
270                 return pFrame;
271         }
272
273         int imageCount = __pAnimationModel->GetImageCount();
274         for (int index = 0; index < imageCount; index++)
275         {
276                 if (__pCurrentFrame->MoveNext() == E_OUT_OF_RANGE)
277                 {
278                         __pCurrentFrame->Reset();
279                 }
280
281                 pFrame = dynamic_cast <AnimationFrame*>(__pCurrentFrame->GetCurrent());
282
283                 if (pFrame != null)
284                 {
285                         break;
286                 }
287         }
288
289         return pFrame;
290 }
291
292 AnimationFrame*
293 _AnimationPresenter::GetNextFrame(void) const
294 {
295         AnimationFrame* pNextFrame = null;
296
297         int imageCount = __pAnimationModel->GetImageCount();
298         for (int index = 0; index < imageCount; index++)
299         {
300                 if (__pCurrentFrame->MoveNext() == E_SUCCESS)
301                 {
302                         pNextFrame = dynamic_cast <AnimationFrame*>(__pCurrentFrame->GetCurrent());
303
304                         if (pNextFrame != null)
305                         {
306                                 break;
307                         }
308                 }
309                 else
310                 {
311                         __pCurrentFrame->Reset();
312                         int currentRepeatedCount = __pAnimationModel->GetCurrentRepeatedCount();
313                         __pAnimationModel->SetCurrentRepeatedCount(++currentRepeatedCount);
314                 }
315         }
316
317         return pNextFrame;
318 }
319
320 result
321 _AnimationPresenter::Dispose(void)
322 {
323         __pAnimation = null;
324
325         delete __pCurrentFrame;
326         __pCurrentFrame = null;
327
328         if (__pTimer != null && __isTimerRunning == true)
329         {
330                 __pTimer->Cancel();
331         }
332
333         delete __pTimer;
334         __pTimer = null;
335
336         delete __pAnimationModel;
337         __pAnimationModel = null;
338
339         __pVisualElement = null;
340
341         return E_SUCCESS;
342 }
343
344 result
345 _AnimationPresenter::Draw(void)
346 {
347         result r = E_SUCCESS;
348
349         Rectangle bounds = __pAnimation->GetBounds();
350         Color bgColor = __pAnimation->GetBackgroundColor();
351         Canvas* pCanvas = null;
352         AnimationFrame* pFrame = null;
353         Bitmap* pBitmap = null;
354
355         pFrame = GetCurrentFrame();
356         SysTryCatch(NID_UI_CTRL, pFrame != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A system error has occurred. Failed to get the current animation frame.");
357
358         pBitmap = const_cast <Bitmap*>(pFrame->GetFrame());
359
360         if (pBitmap != null)
361         {
362                 pCanvas = __pAnimation->GetCanvasN();
363
364                 SysTryReturnResult(NID_UI_CTRL, pCanvas != null, E_SYSTEM, "A system error has occurred. Failed to get the animation canvas.");
365
366                 pCanvas->SetBackgroundColor(Color());
367                 pCanvas->Clear();
368
369                 if (pBitmap->IsNinePatchedBitmap())
370                 {
371                         r = pCanvas->DrawNinePatchedBitmap(bounds, *pBitmap);
372                 }
373                 else
374                 {
375                         r = pCanvas->DrawBitmap(Rectangle(0, 0, bounds.width, bounds.height), *pBitmap);
376                 }
377
378                 SysTryCatch(NID_UI_CTRL, r == E_SUCCESS, , r, "[%s] Failed to draw the bitmap", GetErrorMessage(r));
379         }
380
381 CATCH:
382         delete pCanvas;
383         pCanvas = null;
384
385         return r;
386 }
387
388 }}} // Tizen::Ui::Controls