Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / animations / FUiAnimDimensionAnimation.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 /**
19  * @file                FUiAnimDimensionAnimation.cpp
20  * @brief               This file contains implementation of DimensionAnimation class
21  *
22  * This file contains implementation of DimensionAnimation class.
23  */
24
25 #include <new>
26
27 #include <FBaseColHashMapT.h>
28 #include <FUiAnimDimensionAnimation.h>
29 #include <FBaseSysLog.h>
30
31 #include "FUiAnim_DimensionAnimationImpl.h"
32 #include "FUiAnim_AnimationBaseImpl.h"
33
34
35 using namespace Tizen::Base;
36 using namespace Tizen::Graphics;
37 using namespace Tizen::Ui::Animations;
38 using namespace Tizen::Base::Collection;
39
40
41 namespace Tizen { namespace Ui { namespace Animations
42 {
43
44 DimensionAnimation::DimensionAnimation(void)
45         : _pDimensionAnimationImpl(null)
46 {
47 }
48
49 DimensionAnimation::DimensionAnimation(const Dimension& startValue, const Dimension& endValue, long duration, AnimationInterpolatorType interpolator)
50         : AnimationBase(duration, interpolator)
51         , _pDimensionAnimationImpl(null)
52 {
53         result r = GetLastResult();
54         SysTryReturnVoidResult(NID_UI_ANIM, (_pAnimationBaseImpl), r, "[%s] Propagating.", GetErrorMessage(r));
55
56         SysTryReturnVoidResult(NID_UI_ANIM, (startValue.height >= 0 && startValue.width >= 0 && endValue.height >= 0 && endValue.width >= 0),
57                                                         E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument(s) is used. startValue = (%d, %d), endValue = (%d, %d)", startValue.width, startValue.height, endValue.width, endValue.height);
58
59         _pDimensionAnimationImpl = new (std::nothrow) _DimensionAnimationImpl(this);
60         if (_pDimensionAnimationImpl == null)
61         {
62                 SysLogException(NID_UI_ANIM, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory Allocation failed.");
63
64                 delete _pAnimationBaseImpl;
65                 _pAnimationBaseImpl = null;
66
67                 return;
68         }
69
70         _pDimensionAnimationImpl->startValue = startValue;
71         _pDimensionAnimationImpl->endValue = endValue;
72 }
73
74 DimensionAnimation::~DimensionAnimation(void)
75 {
76         delete _pDimensionAnimationImpl;
77         _pDimensionAnimationImpl = null;
78 }
79
80 DimensionAnimation::DimensionAnimation(const DimensionAnimation& dimensionAnimation)
81         : AnimationBase(dimensionAnimation)
82         , _pDimensionAnimationImpl(null)
83 {
84         result r = GetLastResult();
85         SysTryReturnVoidResult(NID_UI_ANIM, (_pAnimationBaseImpl), r, "[%s] Propagating.", GetErrorMessage(r));
86
87         _pDimensionAnimationImpl = new (std::nothrow) _DimensionAnimationImpl(this);
88         SysTryCatch(NID_UI_ANIM, (_pDimensionAnimationImpl != null), , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
89
90         dimensionAnimation.GetAnchor(_pDimensionAnimationImpl->anchorX, _pDimensionAnimationImpl->anchorY);
91
92         r = _pDimensionAnimationImpl->CopyDimensionAnimationValue(dimensionAnimation);
93         SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Failed to copy dimension animation.");
94
95         return;
96
97 CATCH:
98         delete _pAnimationBaseImpl;
99         _pAnimationBaseImpl = null;
100         delete _pDimensionAnimationImpl;
101         _pDimensionAnimationImpl = null;
102 }
103
104 DimensionAnimation&
105 DimensionAnimation::operator =(const DimensionAnimation& rhs)
106 {
107         ClearLastResult();
108
109         if ((&rhs) != this)
110         {
111                 result r = E_SUCCESS;
112
113                 AnimationBase::operator =(rhs);
114
115                 rhs.GetAnchor(_pDimensionAnimationImpl->anchorX, _pDimensionAnimationImpl->anchorY);
116
117                 r = _pDimensionAnimationImpl->CopyDimensionAnimationValue(rhs);
118                 SysTryReturn(NID_UI_ANIM, (r == E_SUCCESS), *this, E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Failed to copy dimension animation.");
119         }
120
121         return *this;
122 }
123
124 bool
125 DimensionAnimation::operator ==(const DimensionAnimation& dimensionAnimation) const
126 {
127         result r = E_SUCCESS;
128
129         if (_pAnimationBaseImpl->keyFrameList.GetCount() != dimensionAnimation._pAnimationBaseImpl->keyFrameList.GetCount())
130         {
131                 return false;
132         }
133
134         ArrayListT< long >* pKeyList1 = null;
135         ArrayListT< long >* pKeyList2 = null;
136         ICollectionT< long >* pKeyN = _pAnimationBaseImpl->keyFrameList.GetKeysN();
137         ICollectionT< long >* pKeyN1 = dimensionAnimation._pAnimationBaseImpl->keyFrameList.GetKeysN();
138
139         if (_pAnimationBaseImpl->keyFrameList.GetCount() != 0)
140         {
141                 pKeyList1 = new (std::nothrow) ArrayListT< long >;
142                 SysTryCatch(NID_UI_ANIM, (!(pKeyList1 == null || pKeyN == null)), , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
143
144                 r = pKeyList1->Construct(*pKeyN);
145                 SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , E_SYSTEM, "[E_SYSTEM] Failed to construct key list.");
146
147                 pKeyList2 = new (std::nothrow) ArrayListT< long >;
148                 SysTryCatch(NID_UI_ANIM, !(pKeyList2 == null || pKeyN1 == null), , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
149
150                 r = pKeyList2->Construct(*pKeyN1);
151                 SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , E_SYSTEM, "[E_SYSTEM] Failed to construct key list.");
152
153                 ComparerT< long > comparer;
154
155                 r = pKeyList1->Sort(comparer);
156                 SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Failed to sort key list.");
157
158                 r = pKeyList2->Sort(comparer);
159                 SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), , E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Failed to sort key list.");
160
161                 long time1 = 0;
162                 long time2 = 0;
163                 Object* pObjValue1 = null;
164                 Object* pObjValue2 = null;
165
166                 for (int index = 0; index < _pAnimationBaseImpl->keyFrameList.GetCount(); index++)
167                 {
168                         pKeyList1->GetAt(index, time1);
169                         pKeyList2->GetAt(index, time2);
170                         if (time1 != time2)
171                         {
172                                 goto CATCH;
173                         }
174                         _pAnimationBaseImpl->keyFrameList.GetValue(time1, pObjValue1);
175                         dimensionAnimation._pAnimationBaseImpl->keyFrameList.GetValue(time2, pObjValue2);
176                         if ((!pObjValue1) && (!pObjValue2))
177                         {
178                                 continue;
179                         }
180                         else if ((!pObjValue1) || (!pObjValue2))
181                         {
182                                 goto CATCH;
183                         }
184                         Dimension* pDimValue1 = dynamic_cast< Dimension* >(pObjValue1);
185                         if (pDimValue1 == null)
186                         {
187                                 goto CATCH;
188                         }
189
190                         Dimension* pDimValue2 = dynamic_cast< Dimension* >(pObjValue2);
191                         if (pDimValue2 == null)
192                         {
193                                 goto CATCH;
194                         }
195                         if (!(pDimValue1->Equals(*pDimValue2)))
196                         {
197                                 goto CATCH;
198                         }
199
200                 }
201
202                 delete pKeyList1;
203                 delete pKeyList2;
204         }
205
206         delete pKeyN;
207         delete pKeyN1;
208
209         if (!((_pDimensionAnimationImpl->startValue).Equals(dimensionAnimation._pDimensionAnimationImpl->startValue)) ||
210                 !((_pDimensionAnimationImpl->endValue).Equals(dimensionAnimation._pDimensionAnimationImpl->endValue)))
211         {
212                 return false;
213         }
214
215         if (((Float::Compare(_pDimensionAnimationImpl->anchorX, dimensionAnimation._pDimensionAnimationImpl->anchorX)) != 0) &&
216                 ((Float::Compare(_pDimensionAnimationImpl->anchorY, dimensionAnimation._pDimensionAnimationImpl->anchorY)) != 0))
217         {
218                 return false;
219         }
220
221         return _pAnimationBaseImpl->CompareTimingValues(dimensionAnimation);
222
223 CATCH:
224         delete pKeyN;
225         delete pKeyN1;
226         delete pKeyList1;
227         delete pKeyList2;
228
229         return false;
230 }
231
232 bool
233 DimensionAnimation::operator !=(const DimensionAnimation& rhs) const
234 {
235         return !(*this == rhs);
236 }
237
238 bool
239 DimensionAnimation::Equals(const Object& obj) const
240 {
241         const DimensionAnimation* pDimAnim = dynamic_cast< const DimensionAnimation* >(&obj);
242         if (pDimAnim == null)
243         {
244                 return false;
245         }
246
247         return (*this == *pDimAnim);
248 }
249
250 int
251 DimensionAnimation::GetHashCode(void) const
252 {
253         return (((int) GetRepeatCount()) + ((int) GetOffset()) + ((int) GetDuration()) + ((int) GetDelay()));
254 }
255
256 result
257 DimensionAnimation::SetAnchor(float anchorX, float anchorY)
258 {
259         SysTryReturnResult(NID_UI_ANIM, (anchorX >= 0.0 && anchorX <= 1.0 && anchorY >= 0.0 && anchorY <= 1.0), E_INVALID_ARG, "Invalid argument(s) is used. anchorX = %f, anchorY = %f.", anchorX, anchorY);
260
261         _pDimensionAnimationImpl->anchorX = anchorX;
262         _pDimensionAnimationImpl->anchorY = anchorY;
263
264         return E_SUCCESS;
265 }
266
267 void
268 DimensionAnimation::GetAnchor(float& anchorX, float& anchorY) const
269 {
270         anchorX = _pDimensionAnimationImpl->anchorX;
271         anchorY = _pDimensionAnimationImpl->anchorY;
272
273         return;
274 }
275
276 result
277 DimensionAnimation::GetAnimatedValue(long currentTime, Dimension& animatedValue) const
278 {
279         SysTryReturnResult(NID_UI_ANIM, (currentTime >= 0 && currentTime <= GetDuration()), E_INVALID_ARG, "Invalid argument(s) is used. currentTime = %ld", currentTime);
280
281         float actualProgress = _pAnimationBaseImpl->GetActualProgressValue(currentTime);
282         SysTryReturnResult(NID_UI_ANIM, (actualProgress >= 0.0f && actualProgress <= 1.0f), E_SYSTEM, "A system error has been occurred. Failed to calculate progress.");
283
284         return _pDimensionAnimationImpl->GetAnimatedValue(actualProgress, animatedValue);
285 }
286
287 result
288 DimensionAnimation::AddKeyFrame(long time, const Dimension& value)
289 {
290         SysTryReturnResult(NID_UI_ANIM, (time > 0 && time != _pAnimationBaseImpl->duration), E_INVALID_ARG, "Invalid argument(s) is used. time = %ld", time);
291
292         result r = E_SUCCESS;
293         Dimension* pDimObj = null;
294
295         if (time > _pAnimationBaseImpl->duration)
296         {
297                 pDimObj = new (std::nothrow) Dimension(_pDimensionAnimationImpl->endValue);
298                 SysTryReturnResult(NID_UI_ANIM, (pDimObj), E_OUT_OF_MEMORY, "Memory allocation failed.");
299                 r = _pAnimationBaseImpl->keyFrameList.Add(_pAnimationBaseImpl->duration, dynamic_cast< Object* >(pDimObj));
300                 SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Failed to add to key frame list.");
301
302                 _pAnimationBaseImpl->duration = time;
303                 _pDimensionAnimationImpl->endValue = value;
304         }
305         else
306         {
307                 pDimObj = new (std::nothrow) Dimension(value);
308                 SysTryReturnResult(NID_UI_ANIM, (pDimObj), E_OUT_OF_MEMORY, "Memory allocation failed.");
309                 Object* pKeyValue = null;
310                 _pAnimationBaseImpl->keyFrameList.GetValue(time, pKeyValue);
311                 if (pKeyValue)
312                 {
313                         _pAnimationBaseImpl->keyFrameList.Remove(time);  //If a key-value pair with the current key already exists, then remove the already existing entry
314                         delete pKeyValue;
315                         pKeyValue = null;
316                 }
317                 r = _pAnimationBaseImpl->keyFrameList.Add(time, dynamic_cast< Object* >(pDimObj));
318                 SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Failed to add to key frame list.");
319         }
320
321         return r;
322 CATCH:
323         delete pDimObj;
324         pDimObj = null;
325         return r;
326 }
327
328 result
329 DimensionAnimation::GetKeyFrameAt(int index, long& time, Dimension& value) const
330 {
331         SysTryReturnResult(NID_UI_ANIM, (index >= 0 && index < _pAnimationBaseImpl->keyFrameList.GetCount()),
332                                                 E_OUT_OF_RANGE, "[E_OUT_OF_RANGE] Index (%d) is out of range.", index);
333
334         result r = E_SUCCESS;
335         Object* pObjValue = null;
336         Dimension* pDimValue = null;
337         ComparerT< long > comparer;
338
339         ArrayListT< long >* pKeyList = new (std::nothrow) ArrayListT< long >;
340         ICollectionT< long >* pKeyN = _pAnimationBaseImpl->keyFrameList.GetKeysN();
341
342         SysTryCatch(NID_UI_ANIM, (pKeyList != null && pKeyN != null), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
343
344         r = pKeyList->Construct(*pKeyN);
345         SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to construct key list.");
346         SysTryCatch(NID_UI_ANIM, !(pKeyList->GetCount() <= 0), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Key list count is invalid.");
347
348         r = pKeyList->Sort(comparer);
349         SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Failed to sort key list.");
350
351         r = pKeyList->GetAt(index, time);
352         SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Failed to get the time from list.");
353
354         r = _pAnimationBaseImpl->keyFrameList.GetValue(time, pObjValue);
355         SysTryCatch(NID_UI_ANIM, (r == E_SUCCESS), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Failed to get key value.");
356         SysTryCatch(NID_UI_ANIM, (pObjValue != null), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] A system error has been occurred. Failed to get key frame.");
357
358         pDimValue = dynamic_cast< Dimension* >(pObjValue);
359         if (pDimValue)
360         {
361                 value = *pDimValue;
362         }
363
364         //fall through
365
366 CATCH:
367         delete pKeyN;
368         delete pKeyList;
369
370         return r;
371 }
372
373 result
374 DimensionAnimation::RemoveKeyFrame(long time)
375 {
376         return _pAnimationBaseImpl->RemoveKeyFrame(time);
377 }
378
379 result
380 DimensionAnimation::RemoveKeyFrameAt(int index)
381 {
382         return _pAnimationBaseImpl->RemoveKeyFrameAt(index);
383 }
384
385 result
386 DimensionAnimation::RemoveAllKeyFrames(void)
387 {
388         return _pAnimationBaseImpl->RemoveAllKeyFrames();
389 }
390
391 result
392 DimensionAnimation::SetStartValue(const Dimension& startValue)
393 {
394         SysTryReturnResult(NID_UI_ANIM, (startValue.width >= 0 && startValue.height >= 0), E_INVALID_ARG, "Invalid argument(s) is used. startValue = (%d, %d)", startValue.width, startValue.height);
395
396         _pDimensionAnimationImpl->startValue = startValue;
397
398         return E_SUCCESS;
399 }
400
401 result
402 DimensionAnimation::SetEndValue(const Dimension& endValue)
403 {
404         SysTryReturnResult(NID_UI_ANIM, (endValue.width >= 0 && endValue.height >= 0), E_INVALID_ARG, "Invalid argument(s) is used. endValue = (%d, %d)", endValue.width, endValue.height);
405
406         _pDimensionAnimationImpl->endValue = endValue;
407
408         return E_SUCCESS;
409 }
410
411 Dimension
412 DimensionAnimation::GetStartValue(void) const
413 {
414         return _pDimensionAnimationImpl->startValue;
415 }
416
417 Dimension
418 DimensionAnimation::GetEndValue(void) const
419 {
420         return _pDimensionAnimationImpl->endValue;
421 }
422
423 AnimationType
424 DimensionAnimation::GetType(void) const
425 {
426         return ANIMATION_TYPE_DIMENSION_ANIMATION;
427 }
428
429
430 }}}             // Tizen::Ui::Animations
431