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); \
19 #define ELM_ANIMATOR_MAGIC 0x40777770
23 Ecore_Animator *animator;
27 unsigned int repeat_cnt;
28 unsigned int cur_repeat_cnt;
29 void (*animator_op) (void *data, Elm_Animator *animator, double frame);
31 void (*completion_op) (void *data);
33 Elm_Animator_Curve_Style curve_style;
34 Eina_Bool auto_reverse:1;
35 Eina_Bool on_animating:1;
38 static double _animator_curve_linear(double frame);
39 static double _animator_curve_in_out(double frame);
40 static double _animator_curve_in(double frame);
41 static double _animator_curve_out(double frame);
42 static unsigned int _animator_compute_reverse_repeat_count(unsigned int cnt);
43 static unsigned int _animator_compute_no_reverse_repeat_count(unsigned int cnt);
44 static Eina_Bool _animator_animate_cb(void *data);
45 static void _delete_animator(Elm_Animator *animator);
46 static void _animator_parent_del(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__);
49 _animator_compute_reverse_repeat_count(unsigned int cnt)
51 return ((cnt + 1) * 2) - 1;
55 _animator_compute_no_reverse_repeat_count(unsigned int cnt)
61 _animator_curve_linear(double frame)
67 _animator_curve_in_out(double frame)
69 if (frame < 0.5) return _animator_curve_in(frame * 2) * 0.5;
70 else return (_animator_curve_out(frame * 2 - 1) * 0.5) + 0.5;
74 _animator_curve_in(double frame)
76 return 1 - sqrt(1 - pow(frame, 2));
80 _animator_curve_out(double frame)
82 return sqrt(1 - pow(frame - 1, 2));
86 _delete_animator(Elm_Animator *animator)
88 if (!animator->animator) return;
89 ecore_animator_del(animator->animator);
90 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();
100 elapsed_time = animator->cur_time - animator->begin_time;
101 if (elapsed_time > animator->duration) elapsed_time = animator->duration;
103 //Compute current frame
104 switch (animator->curve_style)
106 case ELM_ANIMATOR_CURVE_IN_OUT:
107 frame = _animator_curve_in_out(elapsed_time / animator->duration);
109 case ELM_ANIMATOR_CURVE_IN:
110 frame = _animator_curve_in(elapsed_time / animator->duration);
112 case ELM_ANIMATOR_CURVE_OUT:
113 frame = _animator_curve_out(elapsed_time / animator->duration);
116 frame = _animator_curve_linear(elapsed_time / animator->duration);
121 if (animator->auto_reverse)
123 if (!(animator->cur_repeat_cnt % 2)) frame = 1 - frame;
126 if (animator->duration > 0)
127 animator->animator_op(animator->animator_arg, animator, frame);
128 //Not end. Keep going.
129 if (elapsed_time < animator->duration) return ECORE_CALLBACK_RENEW;
131 //Repeat and reverse and time done!
132 if (!animator->cur_repeat_cnt)
134 animator->on_animating = EINA_FALSE;
135 _delete_animator(animator);
136 if (animator->completion_op)
137 animator->completion_op(animator->completion_arg);
138 return ECORE_CALLBACK_CANCEL;
142 animator->cur_repeat_cnt--;
143 animator->begin_time = ecore_loop_time_get();
145 return ECORE_CALLBACK_RENEW;
149 _animator_parent_del(void *data, Evas *evas __UNUSED__,
150 Evas_Object *obj __UNUSED__, void *event __UNUSED__)
152 elm_animator_del(data);
156 elm_animator_auto_reverse_get(const Elm_Animator *animator)
158 ELM_ANIMATOR_CHECK_OR_RETURN(animator, EINA_FALSE);
159 return animator->auto_reverse;
163 elm_animator_repeat_get(const Elm_Animator *animator)
165 ELM_ANIMATOR_CHECK_OR_RETURN(animator, 0);
166 return animator->repeat_cnt;
169 EAPI Elm_Animator_Curve_Style
170 elm_animator_curve_style_get(const Elm_Animator *animator)
172 ELM_ANIMATOR_CHECK_OR_RETURN(animator, ELM_ANIMATOR_CURVE_LINEAR);
173 return animator->curve_style;
177 elm_animator_auto_reverse_set(Elm_Animator *animator, Eina_Bool reverse)
179 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
180 if (animator->auto_reverse == reverse) return;
181 animator->auto_reverse = reverse;
183 animator->repeat_cnt =
184 _animator_compute_reverse_repeat_count(animator->repeat_cnt);
186 animator->repeat_cnt =
187 _animator_compute_no_reverse_repeat_count(animator->repeat_cnt);
191 elm_animator_curve_style_set(Elm_Animator *animator,
192 Elm_Animator_Curve_Style cs)
194 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
195 animator->curve_style = cs;
198 elm_animator_duration_set(Elm_Animator *animator, double duration)
200 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
201 if (animator->on_animating) return;
202 animator->duration = duration;
206 elm_animator_operation_callback_set(Elm_Animator *animator,
207 Elm_Animator_Operation_Cb func,
210 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
211 if (animator->on_animating) return;
212 animator->animator_op = func;
213 animator->animator_arg = data;
217 elm_animator_add(Evas_Object *parent)
219 Elm_Animator *animator = ELM_NEW(Elm_Animator);
220 if (!animator) return NULL;
221 EINA_MAGIC_SET(animator, ELM_ANIMATOR_MAGIC);
222 animator->parent = parent;
223 elm_animator_auto_reverse_set(animator, EINA_FALSE);
224 elm_animator_curve_style_set(animator, ELM_ANIMATOR_CURVE_LINEAR);
226 evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL,
227 _animator_parent_del, animator);
232 elm_animator_operating_get(const Elm_Animator *animator)
234 ELM_ANIMATOR_CHECK_OR_RETURN(animator, EINA_FALSE);
235 return animator->on_animating;
239 elm_animator_del(Elm_Animator *animator)
241 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
242 _delete_animator(animator);
243 if (animator->parent)
244 evas_object_event_callback_del(animator->parent, EVAS_CALLBACK_DEL,
245 _animator_parent_del);
247 EINA_MAGIC_SET(animator, EINA_MAGIC_NONE);
252 elm_animator_completion_callback_set(Elm_Animator *animator,
253 Elm_Animator_Completion_Cb func,
256 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
257 if (animator->on_animating) return;
258 animator->completion_op = func;
259 animator->completion_arg = data;
263 elm_animator_pause(Elm_Animator *animator)
265 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
266 if (!animator->on_animating) return;
267 ecore_animator_freeze(animator->animator);
271 elm_animator_resume(Elm_Animator *animator)
273 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
274 if (!animator->on_animating) return;
275 ecore_animator_thaw(animator->animator);
279 elm_animator_stop(Elm_Animator *animator)
281 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
282 animator->on_animating = EINA_FALSE;
283 _delete_animator(animator);
287 elm_animator_repeat_set(Elm_Animator *animator, unsigned int repeat_cnt)
289 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
290 if (!animator->auto_reverse) animator->repeat_cnt = repeat_cnt;
292 animator->repeat_cnt = _animator_compute_reverse_repeat_count(repeat_cnt);
296 elm_animator_animate(Elm_Animator *animator)
298 ELM_ANIMATOR_CHECK_OR_RETURN(animator);
299 if (!animator->animator_op) return;
300 animator->begin_time = ecore_loop_time_get();
301 animator->cur_repeat_cnt = animator->repeat_cnt;
302 if (!animator->animator)
303 animator->animator = ecore_animator_add(_animator_animate_cb, animator);
304 if (animator->animator) animator->on_animating = EINA_TRUE;