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);
209 return animator->curve_style;
213 * Set auto reverse function.
215 * @param[in] animator Animator object
216 * @param[in] reverse Reverse or not
221 elm_animator_auto_reverse_set(Elm_Animator *animator, Eina_Bool reverse)
223 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
224 if (animator->auto_reverse == reverse) return;
225 animator->auto_reverse = reverse;
227 animator->repeat_cnt =
228 _animator_compute_reverse_repeat_count(animator->repeat_cnt);
230 animator->repeat_cnt =
231 _animator_compute_no_reverse_repeat_count(animator->repeat_cnt);
235 * Set the animation acceleration style.
237 * @param[in] animator Animator object
238 * @param[in] cs Curve style. Default is ELM_ANIMATOR_CURVE_LINEAR
243 elm_animator_curve_style_set(Elm_Animator *animator,
244 Elm_Animator_Curve_Style cs)
246 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
247 animator->curve_style = cs;
251 * Set the operation duration.
253 * @param[in] animator Animator object
254 * @param[in] duration Duration in second
259 elm_animator_duration_set(Elm_Animator *animator, double duration)
261 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
262 if (animator->on_animating) return;
263 animator->duration = duration;
267 * Set the callback function for animator operation.
268 * The range of callback function frame data is to 0 ~ 1
269 * User can refer this frame value for one's animation frame data.
270 * @param[in] animator Animator object
271 * @param[in] func Callback function pointer
272 * @param[in] data Callback function user argument
277 elm_animator_operation_callback_set(Elm_Animator *animator,
278 Elm_Animator_Operation_Cb func,
281 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
282 if (animator->on_animating) return;
283 animator->animator_op = func;
284 animator->animator_arg = data;
290 * @param[in] parent Parent object
291 * @return animator object
296 elm_animator_add(Evas_Object *parent)
298 Elm_Animator *animator = ELM_NEW(Elm_Animator);
299 if (!animator) return NULL;
300 EINA_MAGIC_SET(animator, ELM_ANIMATOR_MAGIC);
301 animator->parent = parent;
302 elm_animator_auto_reverse_set(animator, EINA_FALSE);
303 elm_animator_curve_style_set(animator, ELM_ANIMATOR_CURVE_LINEAR);
305 evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL,
306 _animator_parent_del, animator);
311 * Get the status for the animator operation.
313 * @param[in] animator Animator object
314 * @return EINA_TRUE is animator is operating.
319 elm_animator_operating_get(const Elm_Animator *animator)
321 ELM_ANIMATOR_CHECK_OR_RETURN(animator, EINA_FALSE);
322 return animator->on_animating;
328 * @param[in] animator Animator object
333 elm_animator_del(Elm_Animator *animator)
335 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
336 _delete_animator(animator);
337 if (animator->parent)
338 evas_object_event_callback_del(animator->parent, EVAS_CALLBACK_DEL,
339 _animator_parent_del);
341 EINA_MAGIC_SET(animator, EINA_MAGIC_NONE);
346 * Set the callback function for the animator end.
348 * @param[in] animator Animator object
349 * @param[in] func Callback function pointe
350 * @param[in] data Callback function user argument
355 elm_animator_completion_callback_set(Elm_Animator *animator,
356 Elm_Animator_Completion_Cb func,
359 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
360 if (animator->on_animating) return;
361 animator->completion_op = func;
362 animator->completion_arg = data;
366 * Pause the animator.
368 * @param[in] animator Animator object
373 elm_animator_pause(Elm_Animator *animator)
375 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
376 if (!animator->on_animating) return;
377 ecore_animator_freeze(animator->animator);
381 * Resume the animator.
383 * @param[in] animator Animator object
388 elm_animator_resume(Elm_Animator *animator)
390 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
391 if (!animator->on_animating) return;
392 ecore_animator_thaw(animator->animator);
398 * @param[in] animator Animator object
403 elm_animator_stop(Elm_Animator *animator)
405 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
406 animator->on_animating = EINA_FALSE;
407 _delete_animator(animator);
411 * Set the animator repeat count.
413 * @param[in] animator Animator object
414 * @param[in] repeat_cnt Repeat count
419 elm_animator_repeat_set(Elm_Animator *animator, unsigned int repeat_cnt)
421 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
422 if (!animator->auto_reverse) animator->repeat_cnt = repeat_cnt;
424 animator->repeat_cnt = _animator_compute_reverse_repeat_count(repeat_cnt);
430 * @param[in] animator Animator object
435 elm_animator_animate(Elm_Animator *animator)
437 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
438 if (!animator->animator_op) return;
439 animator->begin_time = ecore_loop_time_get();
440 animator->cur_repeat_cnt = animator->repeat_cnt;
441 if (!animator->animator)
442 animator->animator = ecore_animator_add(_animator_animate_cb, animator);
443 if (animator->animator) animator->on_animating = EINA_TRUE;