1 #include <Elementary.h>
4 #define ELM_ANIMATOR_CHECK_OR_RETURN(animator, ...) \
7 CRITICAL("Elm_Animator " # animator " is NULL!"); \
10 if (!EINA_MAGIC_CHECK(animator, ELM_ANIMATOR_MAGIC)) { \
11 EINA_MAGIC_FAIL(animator, ELM_ANIMATOR_MAGIC); \
18 * @addtogroup Animator Animator
21 * elm_animator is designed to provides animation frame.
22 * It is somewhat different with any others widgets however elm_animator
23 * might useful when your GUIs have animation.
24 * Basically, it computes normalized frame value for animation,
25 * provides additional functions to adjust this also.
31 #define ELM_ANIMATOR_MAGIC 0x40777770
35 Ecore_Animator *animator;
39 unsigned int repeat_cnt;
40 unsigned int cur_repeat_cnt;
41 void (*animator_op) (void *data, Elm_Animator *animator, double frame);
43 void (*completion_op) (void *data);
45 Elm_Animator_Curve_Style curve_style;
46 Eina_Bool auto_reverse:1;
47 Eina_Bool on_animating:1;
50 static double _animator_curve_linear(double frame);
51 static double _animator_curve_in_out(double frame);
52 static double _animator_curve_in(double frame);
53 static double _animator_curve_out(double frame);
54 static unsigned int _animator_compute_reverse_repeat_count(unsigned int cnt);
55 static unsigned int _animator_compute_no_reverse_repeat_count(unsigned int cnt);
56 static Eina_Bool _animator_animate_cb(void *data);
57 static void _delete_animator(Elm_Animator *animator);
58 static void _animator_parent_del(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__);
61 _animator_compute_reverse_repeat_count(unsigned int cnt)
63 return ((cnt + 1) * 2) - 1;
67 _animator_compute_no_reverse_repeat_count(unsigned int cnt)
73 _animator_curve_linear(double frame)
79 _animator_curve_in_out(double frame)
81 if (frame < 0.5) return _animator_curve_in(frame * 2) * 0.5;
82 else return (_animator_curve_out(frame * 2 - 1) * 0.5) + 0.5;
86 _animator_curve_in(double frame)
88 return 1 - sqrt(1 - pow(frame, 2));
92 _animator_curve_out(double frame)
94 return sqrt(1 - pow(frame - 1, 2));
98 _delete_animator(Elm_Animator *animator)
100 if (!animator->animator) return;
101 ecore_animator_del(animator->animator);
102 animator->animator = NULL;
106 _animator_animate_cb(void *data)
108 double elapsed_time, frame;
109 Elm_Animator *animator = (Elm_Animator *) data;
111 animator->cur_time = ecore_loop_time_get();
112 elapsed_time = animator->cur_time - animator->begin_time;
113 if (elapsed_time > animator->duration) elapsed_time = animator->duration;
115 //Compute current frame
116 switch (animator->curve_style)
118 case ELM_ANIMATOR_CURVE_IN_OUT:
119 frame = _animator_curve_in_out(elapsed_time / animator->duration);
121 case ELM_ANIMATOR_CURVE_IN:
122 frame = _animator_curve_in(elapsed_time / animator->duration);
124 case ELM_ANIMATOR_CURVE_OUT:
125 frame = _animator_curve_out(elapsed_time / animator->duration);
128 frame = _animator_curve_linear(elapsed_time / animator->duration);
133 if (animator->auto_reverse)
135 if (!(animator->cur_repeat_cnt % 2)) frame = 1 - frame;
138 if (animator->duration > 0)
139 animator->animator_op(animator->animator_arg, animator, frame);
140 //Not end. Keep going.
141 if (elapsed_time < animator->duration) return ECORE_CALLBACK_RENEW;
143 //Repeat and reverse and time done!
144 if (!animator->cur_repeat_cnt)
146 animator->on_animating = EINA_FALSE;
147 _delete_animator(animator);
148 if (animator->completion_op)
149 animator->completion_op(animator->completion_arg);
150 return ECORE_CALLBACK_CANCEL;
154 animator->cur_repeat_cnt--;
155 animator->begin_time = ecore_loop_time_get();
157 return ECORE_CALLBACK_RENEW;
161 _animator_parent_del(void *data, Evas *evas __UNUSED__,
162 Evas_Object *obj __UNUSED__, void *event __UNUSED__)
164 elm_animator_del(data);
168 * Get the value of reverse mode.
170 * @param[in] animator Animator object
171 * @return EINA_TRUE is reverse mode
176 elm_animator_auto_reverse_get(const Elm_Animator *animator)
178 ELM_ANIMATOR_CHECK_OR_RETURN(animator, EINA_FALSE);
179 return animator->auto_reverse;
183 * Get the value of repeat count.
185 * @param[in] animator Animator object
186 * @return Repeat count
191 elm_animator_repeat_get(const Elm_Animator *animator)
193 ELM_ANIMATOR_CHECK_OR_RETURN(animator, 0);
194 return animator->repeat_cnt;
198 * Set the animation acceleration style.
200 * @param[in] animator Animator object
201 * @param[in] cs Curve style. Default is ELM_ANIMATOR_CURVE_LINEAR
205 EAPI Elm_Animator_Curve_Style
206 elm_animator_curve_style_get(const Elm_Animator *animator)
208 ELM_ANIMATOR_CHECK_OR_RETURN(animator, ELM_ANIMATOR_CURVE_LINEAR);
210 return animator->curve_style;
214 * Set auto reverse function.
216 * @param[in] animator Animator object
217 * @param[in] reverse Reverse or not
222 elm_animator_auto_reverse_set(Elm_Animator *animator, Eina_Bool reverse)
224 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
225 if (animator->auto_reverse == reverse) return;
226 animator->auto_reverse = reverse;
228 animator->repeat_cnt =
229 _animator_compute_reverse_repeat_count(animator->repeat_cnt);
231 animator->repeat_cnt =
232 _animator_compute_no_reverse_repeat_count(animator->repeat_cnt);
236 * Set the animation acceleration style.
238 * @param[in] animator Animator object
239 * @param[in] cs Curve style. Default is ELM_ANIMATOR_CURVE_LINEAR
244 elm_animator_curve_style_set(Elm_Animator *animator,
245 Elm_Animator_Curve_Style cs)
247 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
249 animator->curve_style = cs;
253 * Set the operation duration.
255 * @param[in] animator Animator object
256 * @param[in] duration Duration in second
261 elm_animator_duration_set(Elm_Animator *animator, double duration)
263 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
264 if (animator->on_animating) return;
265 animator->duration = duration;
269 * Set the callback function for animator operation.
270 * The range of callback function frame data is to 0 ~ 1
271 * User can refer this frame value for one's animation frame data.
272 * @param[in] animator Animator object
273 * @param[in] func Callback function pointer
274 * @param[in] data Callback function user argument
279 elm_animator_operation_callback_set(Elm_Animator *animator,
280 Elm_Animator_Operation_Cb func,
283 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
284 if (animator->on_animating) return;
285 animator->animator_op = func;
286 animator->animator_arg = data;
292 * @param[in] parent Parent object
293 * @return animator object
298 elm_animator_add(Evas_Object *parent)
300 Elm_Animator *animator = ELM_NEW(Elm_Animator);
301 if (!animator) return NULL;
302 EINA_MAGIC_SET(animator, ELM_ANIMATOR_MAGIC);
303 animator->parent = parent;
304 elm_animator_auto_reverse_set(animator, EINA_FALSE);
305 elm_animator_curve_style_set(animator, ELM_ANIMATOR_CURVE_LINEAR);
307 evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL,
308 _animator_parent_del, animator);
313 * Get the status for the animator operation.
315 * @param[in] animator Animator object
316 * @return EINA_TRUE is animator is operating.
321 elm_animator_operating_get(const Elm_Animator *animator)
323 ELM_ANIMATOR_CHECK_OR_RETURN(animator, EINA_FALSE);
324 return animator->on_animating;
330 * @param[in] animator Animator object
335 elm_animator_del(Elm_Animator *animator)
337 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
338 _delete_animator(animator);
339 if (animator->parent)
340 evas_object_event_callback_del(animator->parent, EVAS_CALLBACK_DEL,
341 _animator_parent_del);
343 EINA_MAGIC_SET(animator, EINA_MAGIC_NONE);
348 * Set the callback function for the animator end.
350 * @param[in] animator Animator object
351 * @param[in] func Callback function pointe
352 * @param[in] data Callback function user argument
357 elm_animator_completion_callback_set(Elm_Animator *animator,
358 Elm_Animator_Completion_Cb func,
361 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
362 if (animator->on_animating) return;
363 animator->completion_op = func;
364 animator->completion_arg = data;
368 * Pause the animator.
370 * @param[in] animator Animator object
375 elm_animator_pause(Elm_Animator *animator)
377 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
378 if (!animator->on_animating) return;
379 ecore_animator_freeze(animator->animator);
383 * Resume the animator.
385 * @param[in] animator Animator object
390 elm_animator_resume(Elm_Animator *animator)
392 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
393 if (!animator->on_animating) return;
394 ecore_animator_thaw(animator->animator);
400 * @param[in] animator Animator object
405 elm_animator_stop(Elm_Animator *animator)
407 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
408 animator->on_animating = EINA_FALSE;
409 _delete_animator(animator);
413 * Set the animator repeat count.
415 * @param[in] animator Animator object
416 * @param[in] repeat_cnt Repeat count
421 elm_animator_repeat_set(Elm_Animator *animator, unsigned int repeat_cnt)
423 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
424 if (!animator->auto_reverse) animator->repeat_cnt = repeat_cnt;
426 animator->repeat_cnt = _animator_compute_reverse_repeat_count(repeat_cnt);
432 * @param[in] animator Animator object
437 elm_animator_animate(Elm_Animator *animator)
439 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
440 if (!animator->animator_op) return;
441 animator->begin_time = ecore_loop_time_get();
442 animator->cur_repeat_cnt = animator->repeat_cnt;
443 if (!animator->animator)
444 animator->animator = ecore_animator_add(_animator_animate_cb, animator);
445 if (animator->animator) animator->on_animating = EINA_TRUE;