1 #include <Elementary.h>
5 * @addtogroup Animator Animator
8 * Support normalized frame value for animation.
10 #define MAGIC_OBJ_ANIMATOR 0x40777770
16 Ecore_Animator *animator;
20 unsigned int repeat_cnt;
21 unsigned int cur_repeat_cnt;
22 double (*curve_op) (double frame);
23 void (*animator_op) (void *data, Elm_Animator *animator, double frame);
25 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_out_in(double frame);
33 static double _animator_curve_in_out(double frame);
34 static double _animator_curve_in(double frame);
35 static double _animator_curve_out(double frame);
36 static unsigned int _animator_compute_reverse_repeat_count(unsigned int cnt);
37 static unsigned int _animator_compute_no_reverse_repeat_count(unsigned int cnt);
38 static Eina_Bool _animator_animate_cb(void *data);
39 static void _delete_animator(Elm_Animator *animator);
40 static void _animator_parent_del(void *data, Evas *evas __UNUSED__,
41 Evas_Object *obj __UNUSED__,
42 void *event __UNUSED__);
45 _animator_compute_reverse_repeat_count(unsigned int cnt)
47 return ((cnt + 1) * 2) - 1;
51 _animator_compute_no_reverse_repeat_count(unsigned int cnt)
57 _animator_curve_linear(double frame)
63 _animator_curve_in_out(double frame)
66 return _animator_curve_in(frame * 2) * 0.5;
68 return (_animator_curve_out(frame * 2 - 1) * 0.5) + 0.5;
72 _animator_curve_in(double frame)
74 return 1 - sqrt(1 - pow(frame, 2));
78 _animator_curve_out(double frame)
80 return sqrt(1 - pow(frame - 1, 2));
84 _delete_animator(Elm_Animator *animator)
86 if (animator->animator)
88 ecore_animator_del(animator->animator);
89 animator->animator = NULL;
94 _animator_animate_cb(void *data)
96 double elapsed_time, frame;
97 Elm_Animator *animator = (Elm_Animator *) data;
99 animator->cur_time = ecore_loop_time_get();
101 elapsed_time = animator->cur_time - animator->begin_time;
103 if (elapsed_time > animator->duration)
104 elapsed_time = animator->duration;
106 frame = animator->curve_op(elapsed_time / animator->duration);
109 if (animator->auto_reverse)
111 if (!(animator->cur_repeat_cnt % 2))
115 if (animator->duration > 0)
116 animator->animator_op(animator->animator_arg, animator, frame);
118 //Not end. Keep going.
119 if (elapsed_time < animator->duration)
120 return ECORE_CALLBACK_RENEW;
122 //Repeat and reverse and time done!
123 if (!animator->cur_repeat_cnt)
125 animator->on_animating = EINA_FALSE;
126 _delete_animator(animator);
127 if (animator->completion_op)
128 animator->completion_op(animator->completion_arg);
129 return ECORE_CALLBACK_CANCEL;
133 --animator->cur_repeat_cnt;
134 animator->begin_time = ecore_loop_time_get();
136 return ECORE_CALLBACK_RENEW;
140 _animator_parent_del(void *data, Evas *evas __UNUSED__,
141 Evas_Object *obj __UNUSED__, void *event __UNUSED__)
143 elm_animator_del(data);
147 * Get the value of reverse mode.
149 * @param[in] animator Animator object
150 * @return EINA_TRUE is reverse mode
155 elm_animator_auto_reverse_get(const Elm_Animator *animator)
157 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
159 return animator->auto_reverse;
163 * Get the value of repeat count.
165 * @param[in] animator Animator object
166 * @return Repeat count
171 elm_animator_repeat_get(const Elm_Animator *animator)
173 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
175 return animator->repeat_cnt;
179 * Set auto reverse function.
181 * @param[in] animator Animator object
182 * @param[in] reverse Reverse or not
187 elm_animator_auto_reverse_set(Elm_Animator *animator, Eina_Bool reverse)
189 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
191 if (animator->auto_reverse == reverse)
193 animator->auto_reverse = reverse;
195 animator->repeat_cnt =
196 _animator_compute_reverse_repeat_count(animator->repeat_cnt);
198 animator->repeat_cnt =
199 _animator_compute_no_reverse_repeat_count(animator->repeat_cnt);
203 * Set the animation acceleration style.
205 * @param[in] animator Animator object
206 * @param[in] cs Curve style. Default is ELM_ANIMATOR_CURVE_LINEAR
211 elm_animator_curve_style_set(Elm_Animator *animator,
212 Elm_Animator_Curve_Style cs)
214 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
219 case ELM_ANIMATOR_CURVE_LINEAR:
220 animator->curve_op = _animator_curve_linear;
222 case ELM_ANIMATOR_CURVE_IN_OUT:
223 animator->curve_op = _animator_curve_in_out;
225 case ELM_ANIMATOR_CURVE_IN:
226 animator->curve_op = _animator_curve_in;
228 case ELM_ANIMATOR_CURVE_OUT:
229 animator->curve_op = _animator_curve_out;
232 animator->curve_op = _animator_curve_linear;
238 * Set the operation duration.
240 * @param[in] animator Animator object
241 * @param[in] duration Duration in second
246 elm_animator_duration_set(Elm_Animator *animator, double duration)
248 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
250 if (animator->on_animating)
252 animator->duration = duration;
256 * Set the callback function for animator operation.
257 * The range of callback function frame data is to 0 ~ 1
258 * User can refer this frame value for one's animation frame data.
259 * @param[in] animator Animator object
260 * @param[in] func Callback function pointer
261 * @param[in] data Callback function user argument
266 elm_animator_operation_callback_set(Elm_Animator *animator,
267 void (*func) (void *data,
268 Elm_Animator * animator,
269 double frame), void *data)
271 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
273 if (animator->on_animating)
275 animator->animator_op = func;
276 animator->animator_arg = data;
282 * @param[in] parent Parent object
283 * @return animator object
288 elm_animator_add(Evas_Object *parent)
290 Elm_Animator *animator = ELM_NEW(Elm_Animator);
295 animator->parent = parent;
296 animator->magic = MAGIC_OBJ_ANIMATOR;
298 elm_animator_auto_reverse_set(animator, EINA_FALSE);
299 elm_animator_curve_style_set(animator, ELM_ANIMATOR_CURVE_LINEAR);
302 evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL,
303 _animator_parent_del, animator);
309 * Get the status for the animator operation.
311 * @param[in] animator Animator object
312 * @return EINA_TRUE is animator is operating.
317 elm_animator_operating_get(const Elm_Animator *animator)
319 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
321 return animator->on_animating;
327 * @param[in] animator Animator object
332 elm_animator_del(Elm_Animator *animator)
334 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
337 _delete_animator(animator);
339 if (animator->parent)
340 evas_object_event_callback_del(animator->parent, EVAS_CALLBACK_DEL,
341 _animator_parent_del);
343 memset(animator, 0x0, sizeof(Elm_Animator));
348 * Set the callback function for the animator end.
350 * @param[in] animator Animator object
351 * @param[in] func Callback function pointer
352 * @param[in] data Callback function user argument
357 elm_animator_completion_callback_set(Elm_Animator *animator,
358 void (*func) (void *data), void *data)
360 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
362 if (animator->on_animating)
364 animator->completion_op = func;
365 animator->completion_arg = data;
369 * Pause the animator.
371 * @param[in] animator Animator object
376 elm_animator_pause(Elm_Animator *animator)
378 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
381 if (!animator->on_animating)
384 ecore_animator_freeze(animator->animator);
388 * Resume the animator.
390 * @param[in] animator Animator object
395 elm_animator_resume(Elm_Animator *animator)
397 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
400 if (!animator->on_animating)
403 ecore_animator_thaw(animator->animator);
409 * @param[in] animator Animator object
414 elm_animator_stop(Elm_Animator *animator)
416 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
418 animator->on_animating = EINA_FALSE;
419 _delete_animator(animator);
423 * Set the animator repeat count.
425 * @param[in] animator Animator object
426 * @param[in] repeat_cnt Repeat count
431 elm_animator_repeat_set(Elm_Animator *animator, unsigned int repeat_cnt)
433 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
435 if (!animator->auto_reverse)
436 animator->repeat_cnt = repeat_cnt;
438 animator->repeat_cnt = _animator_compute_reverse_repeat_count(repeat_cnt);
444 * @param[in] animator Animator object
449 elm_animator_animate(Elm_Animator *animator)
451 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR))
453 if (!animator->animator_op)
455 animator->begin_time = ecore_loop_time_get();
456 animator->cur_repeat_cnt = animator->repeat_cnt;
457 if (!animator->animator)
458 animator->animator = ecore_animator_add(_animator_animate_cb, animator);
459 if (animator->animator)
460 animator->on_animating = EINA_TRUE;