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_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)
62 if (frame < 0.5) return _animator_curve_in(frame * 2) * 0.5;
63 else return (_animator_curve_out(frame * 2 - 1) * 0.5) + 0.5;
67 _animator_curve_in(double frame)
69 return 1 - sqrt(1 - pow(frame, 2));
73 _animator_curve_out(double frame)
75 return sqrt(1 - pow(frame - 1, 2));
79 _delete_animator(Elm_Animator *animator)
81 if (!animator->animator) return;
82 ecore_animator_del(animator->animator);
83 animator->animator = NULL;
87 _animator_animate_cb(void *data)
89 double elapsed_time, frame;
90 Elm_Animator *animator = (Elm_Animator *) data;
92 animator->cur_time = ecore_loop_time_get();
93 elapsed_time = animator->cur_time - animator->begin_time;
94 if (elapsed_time > animator->duration) elapsed_time = animator->duration;
95 frame = animator->curve_op(elapsed_time / animator->duration);
97 if (animator->auto_reverse)
99 if (!(animator->cur_repeat_cnt % 2)) frame = 1 - frame;
102 if (animator->duration > 0)
103 animator->animator_op(animator->animator_arg, animator, frame);
104 //Not end. Keep going.
105 if (elapsed_time < animator->duration) return ECORE_CALLBACK_RENEW;
107 //Repeat and reverse and time done!
108 if (!animator->cur_repeat_cnt)
110 animator->on_animating = EINA_FALSE;
111 _delete_animator(animator);
112 if (animator->completion_op)
113 animator->completion_op(animator->completion_arg);
114 return ECORE_CALLBACK_CANCEL;
118 animator->cur_repeat_cnt--;
119 animator->begin_time = ecore_loop_time_get();
121 return ECORE_CALLBACK_RENEW;
125 _animator_parent_del(void *data, Evas *evas __UNUSED__,
126 Evas_Object *obj __UNUSED__, void *event __UNUSED__)
128 elm_animator_del(data);
132 * Get the value of reverse mode.
134 * @param[in] animator Animator object
135 * @return EINA_TRUE is reverse mode
140 elm_animator_auto_reverse_get(const Elm_Animator *animator)
142 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return EINA_FALSE;
143 return animator->auto_reverse;
147 * Get the value of repeat count.
149 * @param[in] animator Animator object
150 * @return Repeat count
155 elm_animator_repeat_get(const Elm_Animator *animator)
157 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return 0;
158 return animator->repeat_cnt;
162 * Set auto reverse function.
164 * @param[in] animator Animator object
165 * @param[in] reverse Reverse or not
170 elm_animator_auto_reverse_set(Elm_Animator *animator, Eina_Bool reverse)
172 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return;
173 if (animator->auto_reverse == reverse) return;
174 animator->auto_reverse = reverse;
176 animator->repeat_cnt =
177 _animator_compute_reverse_repeat_count(animator->repeat_cnt);
179 animator->repeat_cnt =
180 _animator_compute_no_reverse_repeat_count(animator->repeat_cnt);
184 * Set the animation acceleration style.
186 * @param[in] animator Animator object
187 * @param[in] cs Curve style. Default is ELM_ANIMATOR_CURVE_LINEAR
192 elm_animator_curve_style_set(Elm_Animator *animator,
193 Elm_Animator_Curve_Style cs)
195 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return;
198 case ELM_ANIMATOR_CURVE_LINEAR:
199 animator->curve_op = _animator_curve_linear;
201 case ELM_ANIMATOR_CURVE_IN_OUT:
202 animator->curve_op = _animator_curve_in_out;
204 case ELM_ANIMATOR_CURVE_IN:
205 animator->curve_op = _animator_curve_in;
207 case ELM_ANIMATOR_CURVE_OUT:
208 animator->curve_op = _animator_curve_out;
211 animator->curve_op = _animator_curve_linear;
217 * Set the operation duration.
219 * @param[in] animator Animator object
220 * @param[in] duration Duration in second
225 elm_animator_duration_set(Elm_Animator *animator, double duration)
227 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return;
228 if (animator->on_animating) return;
229 animator->duration = duration;
233 * Set the callback function for animator operation.
234 * The range of callback function frame data is to 0 ~ 1
235 * User can refer this frame value for one's animation frame data.
236 * @param[in] animator Animator object
237 * @param[in] func Callback function pointer
238 * @param[in] data Callback function user argument
243 elm_animator_operation_callback_set(Elm_Animator *animator,
244 Elm_Animator_Operation_Cb func,
247 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return;
248 if (animator->on_animating) return;
249 animator->animator_op = func;
250 animator->animator_arg = data;
256 * @param[in] parent Parent object
257 * @return animator object
262 elm_animator_add(Evas_Object *parent)
264 Elm_Animator *animator = ELM_NEW(Elm_Animator);
265 if (!animator) return NULL;
266 animator->parent = parent;
267 animator->magic = MAGIC_OBJ_ANIMATOR;
268 elm_animator_auto_reverse_set(animator, EINA_FALSE);
269 elm_animator_curve_style_set(animator, ELM_ANIMATOR_CURVE_LINEAR);
271 evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL,
272 _animator_parent_del, animator);
278 * Get the status for the animator operation.
280 * @param[in] animator Animator object
281 * @return EINA_TRUE is animator is operating.
286 elm_animator_operating_get(const Elm_Animator *animator)
288 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return EINA_FALSE;
289 return animator->on_animating;
295 * @param[in] animator Animator object
300 elm_animator_del(Elm_Animator *animator)
302 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return;
303 _delete_animator(animator);
304 if (animator->parent)
305 evas_object_event_callback_del(animator->parent, EVAS_CALLBACK_DEL,
306 _animator_parent_del);
308 memset(animator, 0x0, sizeof(Elm_Animator));
313 * Set the callback function for the animator end.
315 * @param[in] animator Animator object
316 * @param[in] func Callback function pointer
317 * @param[in] data Callback function user argument
322 elm_animator_completion_callback_set(Elm_Animator *animator,
323 Elm_Animator_Completion_Cb func,
326 if (!animator || (animator->magic != MAGIC_OBJ_ANIMATOR)) return;
327 if (animator->on_animating) return;
328 animator->completion_op = func;
329 animator->completion_arg = data;
333 * Pause the animator.
335 * @param[in] animator Animator object
340 elm_animator_pause(Elm_Animator *animator)
342 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return;
343 if (!animator->on_animating) return;
344 ecore_animator_freeze(animator->animator);
348 * Resume the animator.
350 * @param[in] animator Animator object
355 elm_animator_resume(Elm_Animator *animator)
357 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return;
358 if (!animator->on_animating) return;
359 ecore_animator_thaw(animator->animator);
365 * @param[in] animator Animator object
370 elm_animator_stop(Elm_Animator *animator)
372 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return;
373 animator->on_animating = EINA_FALSE;
374 _delete_animator(animator);
378 * Set the animator repeat count.
380 * @param[in] animator Animator object
381 * @param[in] repeat_cnt Repeat count
386 elm_animator_repeat_set(Elm_Animator *animator, unsigned int repeat_cnt)
388 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return;
389 if (!animator->auto_reverse) animator->repeat_cnt = repeat_cnt;
391 animator->repeat_cnt = _animator_compute_reverse_repeat_count(repeat_cnt);
397 * @param[in] animator Animator object
402 elm_animator_animate(Elm_Animator *animator)
404 if ((!animator) || (animator->magic != MAGIC_OBJ_ANIMATOR)) return;
405 if (!animator->animator_op) return;
406 animator->begin_time = ecore_loop_time_get();
407 animator->cur_repeat_cnt = animator->repeat_cnt;
408 if (!animator->animator)
409 animator->animator = ecore_animator_add(_animator_animate_cb, animator);
410 if (animator->animator) animator->on_animating = EINA_TRUE;