1 #include <Elementary.h>
5 * @addtogroup Animator Animator
8 * Support normalized frame value for animation.
10 #define MAGIC_OBJ_ANIMATOR 0x40777770
15 Ecore_Animator *animator;
19 unsigned int repeat_cnt;
20 unsigned int cur_repeat_cnt;
21 double (*curve_op) (double frame);
22 void (*animator_op) (void *data, Elm_Animator *animator, double frame);
24 void (*completion_op) (void *data);
27 Eina_Bool auto_reverse:1;
28 Eina_Bool on_animating:1;
31 static double _animator_curve_linear(double frame);
32 static double _animator_curve_in_out(double frame);
33 static double _animator_curve_in(double frame);
34 static double _animator_curve_out(double frame);
35 static unsigned int _animator_compute_reverse_repeat_count(unsigned int cnt);
36 static unsigned int _animator_compute_no_reverse_repeat_count(unsigned int cnt);
37 static Eina_Bool _animator_animate_cb(void *data);
38 static void _delete_animator(Elm_Animator *animator);
39 static void _animator_parent_del(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__);
42 _animator_compute_reverse_repeat_count(unsigned int cnt)
44 return ((cnt + 1) * 2) - 1;
48 _animator_compute_no_reverse_repeat_count(unsigned int cnt)
54 _animator_curve_linear(double frame)
60 _animator_curve_in_out(double frame)
63 return _animator_curve_in(frame * 2) * 0.5;
65 return (_animator_curve_out(frame * 2 - 1) * 0.5) + 0.5;
69 _animator_curve_in(double frame)
71 return 1 - sqrt(1 - pow(frame, 2));
75 _animator_curve_out(double frame)
77 return sqrt(1 - pow(frame - 1, 2));
81 _delete_animator(Elm_Animator *animator)
83 if (animator->animator)
85 ecore_animator_del(animator->animator);
86 animator->animator = NULL;
91 _animator_animate_cb(void *data)
93 Elm_Animator *animator = (Elm_Animator *) data;
94 double elapsed_time, frame;
96 animator->cur_time = ecore_loop_time_get();
98 elapsed_time = animator->cur_time - animator->begin_time;
100 if(elapsed_time > animator->duration)
101 elapsed_time = animator->duration;
103 frame = animator->curve_op(elapsed_time / animator->duration);
106 if (animator->auto_reverse)
108 if ((animator->cur_repeat_cnt % 2) == 0)
112 if (animator->duration > 0)
113 animator->animator_op(animator->animator_arg, animator, frame);
115 //Not end. Keep going.
116 if (elapsed_time < animator->duration)
117 return ECORE_CALLBACK_RENEW;
119 //Repeat and reverse and time done!
120 if (animator->cur_repeat_cnt == 0)
122 animator->on_animating = EINA_FALSE;
123 _delete_animator(animator);
124 if (animator->completion_op)
125 animator->completion_op(animator->completion_arg);
126 return ECORE_CALLBACK_CANCEL;
130 --animator->cur_repeat_cnt;
131 animator->begin_time = ecore_loop_time_get();
133 return ECORE_CALLBACK_RENEW;
137 _animator_parent_del(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
139 Elm_Animator *animator = data;
140 elm_animator_del(data);
144 * Get the value of reverse mode.
146 * @param animator Animator object
147 * @return EINA_TRUE is reverse mode
152 elm_animator_auto_reverse_get(Elm_Animator *animator)
154 if (animator->magic != MAGIC_OBJ_ANIMATOR)
156 return animator->auto_reverse;
160 * Get the value of repeat count.
162 * @param animator Animator object
163 * @return Repeat count
168 elm_animator_repeat_get(Elm_Animator *animator)
170 if (animator->magic != MAGIC_OBJ_ANIMATOR)
172 return animator->repeat_cnt;
176 * Set auto reverse function.
178 * @param animator Animator object
179 * @param reverse Reverse or not
184 elm_animator_auto_reverse_set(Elm_Animator *animator, Eina_Bool reverse)
186 if (animator->magic != MAGIC_OBJ_ANIMATOR)
188 if (animator->auto_reverse == reverse)
190 animator->auto_reverse = reverse;
192 animator->repeat_cnt =
193 _animator_compute_reverse_repeat_count(animator->repeat_cnt);
195 animator->repeat_cnt =
196 _animator_compute_no_reverse_repeat_count(animator->repeat_cnt);
200 * Set the animation acceleration style.
202 * @param animator Animator object
203 * @param cs Curve style. Default is ELM_ANIMATOR_CURVE_LINEAR
208 elm_animator_curve_style_set(Elm_Animator *animator,
209 Elm_Animator_Curve_Style cs)
211 if (animator->magic != MAGIC_OBJ_ANIMATOR)
216 case ELM_ANIMATOR_CURVE_LINEAR:
217 animator->curve_op = _animator_curve_linear;
219 case ELM_ANIMATOR_CURVE_IN_OUT:
220 animator->curve_op = _animator_curve_in_out;
222 case ELM_ANIMATOR_CURVE_IN:
223 animator->curve_op = _animator_curve_in;
225 case ELM_ANIMATOR_CURVE_OUT:
226 animator->curve_op = _animator_curve_out;
229 animator->curve_op = _animator_curve_linear;
235 * Set the operation duration.
237 * @param animator Animator object
238 * @param duration Duration in second
243 elm_animator_duration_set(Elm_Animator *animator, double duration)
245 if (animator->magic != MAGIC_OBJ_ANIMATOR)
247 if (animator->on_animating)
249 animator->duration = duration;
253 * Set the callback function for animator operation.
254 * The range of callback function frame data is to 0 ~ 1
255 * User can refer this frame value for one's animation frame data.
256 * @param animator Animator object
257 * @param op Callback function pointer
258 * @param data Callback function user argument
263 elm_animator_operation_callback_set(Elm_Animator *animator,
264 void (*func) (void *data,
265 Elm_Animator *animator,
266 double frame), void *data)
268 if (animator->magic != MAGIC_OBJ_ANIMATOR)
270 if (animator->on_animating)
272 animator->animator_op = func;
273 animator->animator_arg = data;
279 * @param parent Parent object
280 * @return animator object
285 elm_animator_add(Evas_Object *parent)
287 Elm_Animator *animator = ELM_NEW(Elm_Animator);
292 animator->parent = parent;
293 animator->magic = MAGIC_OBJ_ANIMATOR;
295 elm_animator_auto_reverse_set(animator, EINA_FALSE);
296 elm_animator_curve_style_set(animator, ELM_ANIMATOR_CURVE_LINEAR);
299 evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL,
300 _animator_parent_del, animator);
307 * Get the status for the animator operation.
309 * @param animator Animator object
310 * @return EINA_TRUE is animator is operating.
315 elm_animator_operating_get(Elm_Animator *animator)
317 if (animator->magic != MAGIC_OBJ_ANIMATOR)
319 return animator->on_animating;
325 * @param animator Animator object
330 elm_animator_del(Elm_Animator *animator)
332 if(animator->magic != MAGIC_OBJ_ANIMATOR) {
336 _delete_animator(animator);
338 if(animator->parent) {
339 evas_object_event_callback_del(animator->parent, EVAS_CALLBACK_DEL, _animator_parent_del);
342 memset(animator, 0x0, sizeof(Elm_Animator));
347 * Set the callback function for the animator end.
349 * @param animator Animator object
350 * @param op Callback function pointer
351 * @param data Callback function user argument
356 elm_animator_completion_callback_set(Elm_Animator *animator,
357 void (*func) (void *data), void *data)
359 if (animator->magic != MAGIC_OBJ_ANIMATOR)
361 if (animator->on_animating)
363 animator->completion_op = func;
364 animator->completion_arg = data;
368 * Pause the animator.
370 * @param animator Animator object
375 elm_animator_pause(Elm_Animator *animator)
377 if (animator->magic != MAGIC_OBJ_ANIMATOR)
380 if(!animator->on_animating)
383 ecore_animator_freeze(animator->animator);
387 * Resume the animator.
389 * @param animator Animator object
394 elm_animator_resume(Elm_Animator *animator)
396 if (animator->magic != MAGIC_OBJ_ANIMATOR)
399 if(!animator->on_animating)
402 ecore_animator_thaw(animator->animator);
408 * @param animator Animator object
413 elm_animator_stop(Elm_Animator *animator)
415 if (animator->magic != MAGIC_OBJ_ANIMATOR)
417 animator->on_animating = EINA_FALSE;
418 _delete_animator(animator);
422 * Set the animator repeat count.
424 * @param animator Animator object
425 * @param repeat_cnt Repeat count
430 elm_animator_repeat_set(Elm_Animator *animator, unsigned int repeat_cnt)
432 if (animator->magic != MAGIC_OBJ_ANIMATOR)
434 if (!animator->auto_reverse)
435 animator->repeat_cnt = repeat_cnt;
437 animator->repeat_cnt = _animator_compute_reverse_repeat_count(repeat_cnt);
443 * @param animator Animator object
448 elm_animator_animate(Elm_Animator *animator)
450 if (animator->magic != MAGIC_OBJ_ANIMATOR)
452 if (!animator->animator_op)
454 animator->begin_time = ecore_loop_time_get();
455 animator->cur_repeat_cnt = animator->repeat_cnt;
456 if (!animator->animator) {
457 animator->animator = ecore_animator_add(_animator_animate_cb, animator);
459 if (animator->animator)
460 animator->on_animating = EINA_TRUE;