Merge "[scroller] bug fix for bounce"
[framework/uifw/elementary.git] / src / lib / elm_transit.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 #define ELM_TRANSIT_CHECK_OR_RETURN(transit, ...) \
5    do { \
6       if (!transit) { \
7          CRITICAL("Elm_Transit " # transit " is NULL!"); \
8          return __VA_ARGS__; \
9       } \
10       if (!EINA_MAGIC_CHECK(transit, ELM_TRANSIT_MAGIC)) { \
11          EINA_MAGIC_FAIL(transit, ELM_TRANSIT_MAGIC); \
12          return __VA_ARGS__; \
13       } \
14       if (transit->deleted){ \
15          ERR("Elm_Transit " # transit " has already been deleted!"); \
16          return __VA_ARGS__; \
17       } \
18    } while (0)
19
20
21 /**
22  *
23  * @defgroup Transit Transit
24  * @ingroup Elementary
25  *
26  * Transit (see Warning below) is designed to set the various effects for the
27  * Evas_Object such like translation, rotation, etc. For using Effects, Create
28  * transit and insert effects which are interesting.
29  * Once effects are inserted into transit, transit will manage those effects.
30  * (ex deleting).
31  *
32  * @warning We strongly recomend to use elm_transit just when edje can not do
33  * the trick. Edje has more advantage than Elm_Transit, it has more flexibility and
34  * animations can be manipulated inside the theme.
35  */
36
37 struct _transit
38 {
39 #define ELM_TRANSIT_MAGIC 0xd27f190a
40    EINA_MAGIC;
41
42         Evas_Object *parent;
43    Elm_Animator *animator;
44    Eina_List *effect_list;
45         Elm_Transit_Tween_Mode tween_mode;
46         Evas_Object *block_rect;
47    void (*completion_op) (void *data, Elm_Transit *transit);
48    void *completion_arg;
49    Eina_Bool deleted:1;
50 };
51
52 struct _effect
53 {
54    void (*animation_op) (void *data, Elm_Animator *animator, double frame);
55    void (*begin_op) (void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt);
56    void (*end_op) (void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt);
57    void (*del_op) (void* data);
58    unsigned int shared_cnt;
59    void *user_data;
60 };
61
62 static Evas_Object *_create_block_rect(Evas_Object *parent);
63 static void _transit_animate_cb(void *data, Elm_Animator *animator, 
64                                 double frame);
65 static void _transit_fx_begin(Elm_Transit *transit);
66 static void _transit_fx_end(Elm_Transit *transit);
67 static void _transit_complete_cb(void *data);
68 static void _transit_fx_del(Elm_Effect *effect);
69
70
71 //NEW
72 static void _elm_transit_del(Elm_Transit *transit);
73
74
75 static void
76 _elm_transit_del(Elm_Transit *transit)
77 {
78         if (elm_animator_operating_get(transit->animator))
79      {
80         transit->deleted = EINA_TRUE;
81                   return;
82      }
83
84    if (transit->block_rect)
85       evas_object_del(transit->block_rect);
86
87    elm_animator_del(transit->animator);
88    elm_transit_fx_clear(transit);
89         
90         EINA_MAGIC_SET(transit, EINA_MAGIC_NONE);
91    free(transit);
92 }
93
94 static Evas_Object *
95 _create_block_rect(Evas_Object *parent)
96 {
97    Evas_Object *rect;
98
99    Evas_Coord w, h;
100
101    rect = evas_object_rectangle_add(evas_object_evas_get(parent));
102    evas_output_size_get(evas_object_evas_get(parent), &w, &h);
103    evas_object_resize(rect, w, h);
104    evas_object_color_set(rect, 0, 0, 0, 0);
105    return rect;
106 }
107
108 static void
109 _transit_animate_cb(void *data, Elm_Animator *animator, double frame)
110 {
111    Eina_List *elist;
112
113    Elm_Effect *effect;
114
115    Elm_Transit *transit = data;
116
117    EINA_LIST_FOREACH(transit->effect_list, elist, effect)
118    {
119       effect->animation_op(effect->user_data, animator, frame);
120    }
121 }
122
123 static void
124 _transit_fx_begin(Elm_Transit *transit)
125 {
126    Eina_List *elist;
127
128    Elm_Effect *effect;
129
130    Eina_Bool auto_reverse;
131
132    unsigned int repeat_cnt;
133
134    auto_reverse = elm_animator_auto_reverse_get(transit->animator);
135    repeat_cnt = elm_animator_repeat_get(transit->animator);
136
137    EINA_LIST_FOREACH(transit->effect_list, elist, effect)
138    {
139       if (effect->begin_op)
140          effect->begin_op(effect->user_data, auto_reverse, repeat_cnt);
141    }
142 }
143
144 static void
145 _transit_fx_end(Elm_Transit *transit)
146 {
147    Eina_List *elist;
148
149    Elm_Effect *effect;
150
151    Eina_Bool auto_reverse;
152
153    unsigned int repeat_cnt;
154
155    auto_reverse = elm_animator_auto_reverse_get(transit->animator);
156    repeat_cnt = elm_animator_repeat_get(transit->animator);
157
158    EINA_LIST_FOREACH(transit->effect_list, elist, effect)
159    {
160       if (effect->end_op)
161          effect->end_op(effect->user_data, auto_reverse, repeat_cnt);
162    }
163 }
164
165 static void
166 _transit_complete_cb(void *data)
167 {
168    Elm_Transit *transit = (Elm_Transit *) data;
169
170    evas_render(evas_object_evas_get(transit->parent));
171
172    _transit_fx_end(transit);
173
174    if (transit->block_rect)
175       evas_object_hide(transit->block_rect);
176
177    if (transit->completion_op)
178       transit->completion_op(transit->completion_arg, transit);
179
180    if (transit->deleted)
181      {
182         transit->deleted = EINA_FALSE;
183         elm_transit_del(transit);
184      }
185 }
186
187 static void
188 _transit_fx_del(Elm_Effect *effect)
189 {
190    if (!effect)
191       return;
192
193    --effect->shared_cnt;
194
195    if (effect->shared_cnt > 0)
196       return;
197
198    if(effect->del_op)
199            (*effect->del_op)(effect->user_data);
200
201    if (effect->user_data)
202       free(effect->user_data);
203    free(effect);
204 }
205
206 /**
207  * Set the event blocked when transit is operating.  
208  *
209  * @param[in] transit Transit object
210  * @param[in] disabled Disable or enable
211  *
212  * @ingroup Transit 
213  */
214 EAPI void
215 elm_transit_event_block_disabled_set(Elm_Transit *transit, Eina_Bool disabled)
216 {
217    ELM_TRANSIT_CHECK_OR_RETURN(transit);
218
219    if (disabled)
220      {
221         if (transit->block_rect)
222           {
223              evas_object_del(transit->block_rect);
224              transit->block_rect = NULL;
225           }
226      }
227    else
228      {
229         if (!transit->block_rect)
230           transit->block_rect = _create_block_rect(transit->parent);
231      }
232 }
233
234 /**
235  * Get the value of event blocked status.
236  *
237  * @see elm_transit_event_block_set()
238  *
239  * @param[in] transit The Transit object
240  * @return EINA_TRUE, when event block is enabled. If @p transit is NULL
241  * EINA_FALSE is returned
242  *
243  * @ingroup Transit
244  */
245 EAPI Eina_Bool
246 elm_transit_event_block_disabled_get(const Elm_Transit *transit)
247 {
248    ELM_TRANSIT_CHECK_OR_RETURN(transit, EINA_FALSE);
249    return transit->block_rect ? EINA_FALSE : EINA_TRUE;
250 }
251
252 /**
253  * Remove effect from transit.  
254  *
255  * @param[in] transit   Transit
256  * @param[in] effect Effect to be removed
257  * @return EINA_TRUE, if the effect is removed
258  * @warning If removed effect does not inserted in any transit, it will be deleted. 
259  *
260  * @ingroup Transit 
261  */
262 EAPI Eina_Bool
263 elm_transit_fx_remove(Elm_Transit *transit, Elm_Effect *effect)
264 {
265         ELM_TRANSIT_CHECK_OR_RETURN(transit, EINA_FALSE);
266
267         Eina_List *elist;
268
269    Elm_Effect *_effect;
270
271    EINA_LIST_FOREACH(transit->effect_list, elist, _effect)
272    {
273       if (_effect == effect)
274         {
275            transit->effect_list =
276               eina_list_remove(transit->effect_list, _effect);
277            _transit_fx_del(_effect);
278            return EINA_TRUE;
279         }
280    }
281    return EINA_FALSE;
282 }
283
284 /**
285  * Remove all current inserted effects. 
286  *
287  * @param[in] transit   Transit 
288  *
289  * @ingroup Transit 
290  */
291 EAPI void
292 elm_transit_fx_clear(Elm_Transit *transit)
293 {
294         ELM_TRANSIT_CHECK_OR_RETURN(transit);
295
296         Eina_List *elist;
297
298    Elm_Effect *effect;
299
300    EINA_LIST_FOREACH(transit->effect_list, elist, effect)
301    {
302       transit->effect_list = eina_list_remove(transit->effect_list, effect);
303       _transit_fx_del(effect);
304    }
305 }
306
307 /**
308  * Get the list of current inseted effects. 
309  *
310  * @param[in] transit   Transit
311  * @return Effect list 
312  *
313  * @ingroup Transit 
314  */
315 EAPI const Eina_List *
316 elm_transit_fx_get(Elm_Transit *transit)
317 {
318    ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
319
320    return transit->effect_list;
321 }
322
323 /**
324  * Set the user-callback function when the transit operation is done. 
325  *
326  * @param[in] transit   Transit
327  * @param[in] op Callback function pointer
328  * @param[in] data Callback funtion user data
329  *
330  * @ingroup Transit 
331  */
332 EAPI void
333 elm_transit_completion_callback_set(Elm_Transit *transit,
334                                     void (*op) (void *data,
335                                                 Elm_Transit *transit),
336                                     void *data)
337 {
338    ELM_TRANSIT_CHECK_OR_RETURN(transit);
339
340         transit->completion_op = op;
341    transit->completion_arg = data;
342 }
343
344
345
346
347
348 /**
349  * Delete transit. 
350  *
351  * @param[in] transit   Transit to be deleted
352  *
353  * @ingroup Transit 
354  */
355 EAPI void
356 elm_transit_del(Elm_Transit *transit)
357 {
358         ELM_TRANSIT_CHECK_OR_RETURN(transit);
359
360         _elm_transit_del(transit);
361 //      if (transit->walking) transit->deleted = EINA_TRUE;
362 //   else _elm_transit_del(transit);
363 }
364
365 /**
366  * Set the transit animation acceleration style. 
367  *
368  * @param transit       Transit
369  * @param cs Curve style(Please refer elm_animator_curve_style_set)
370  *
371  * @ingroup Transit 
372  */
373 EAPI void
374 elm_transit_curve_style_set(Elm_Transit *transit, Elm_Animator_Curve_Style cs)
375 {
376    ELM_TRANSIT_CHECK_OR_RETURN(transit);
377    elm_animator_curve_style_set(transit->animator, cs);
378 }
379
380 /**
381  * Set the transit animation acceleration type.
382  *
383  * This function sets the tween mode of the transit that can be:
384  * ELM_TRANSIT_TWEEN_MODE_LINEAR - The default mode.
385  * ELM_TRANSIT_TWEEN_MODE_SINUSOIDAL - Starts in accelerate mode and ends decelerating.
386  * ELM_TRANSIT_TWEEN_MODE_DECELERATE - The animation will be slowed over time.
387  * ELM_TRANSIT_TWEEN_MODE_ACCELERATE - The animation will accelerate over time.
388  *
389  * @param[in] transit The transit object.
390  * @param[in] tween_mode The tween type.
391  *
392  * @ingroup Transit
393  */
394 EAPI void
395 elm_transit_tween_mode_set(Elm_Transit *transit, Elm_Transit_Tween_Mode tween_mode)
396 {
397    ELM_TRANSIT_CHECK_OR_RETURN(transit);
398
399    transit->tween_mode = tween_mode;
400
401         switch(tween_mode) 
402         {
403                 case ELM_TRANSIT_TWEEN_MODE_LINEAR:
404                         elm_animator_curve_style_set(transit->animator, ELM_ANIMATOR_CURVE_LINEAR);
405                         break;
406                 case ELM_TRANSIT_TWEEN_MODE_SINUSODIAL:
407                         elm_animator_curve_style_set(transit->animator, ELM_ANIMATOR_CURVE_IN_OUT);
408                         break;
409                 case ELM_TRANSIT_TWEEN_MODE_DECELERATE:
410                         elm_animator_curve_style_set(transit->animator, ELM_ANIMATOR_CURVE_OUT);
411                         break;
412                 case ELM_TRANSIT_TWEEN_MODE_ACCELERATE:
413                         elm_animator_curve_style_set(transit->animator, ELM_ANIMATOR_CURVE_IN);
414                         break;
415                 default:
416                         break;
417         }
418
419 }
420
421 /**
422  * Get the transit animation acceleration type.
423  *
424  * @note @p transit can not be NULL
425  *
426  * @param[in] transit The transit object.
427  * @return The tween type. If @p transit is NULL
428  * ELM_TRANSIT_TWEEN_MODE_LINEAR is returned.
429  *
430  * @ingroup Transit
431  */
432 EAPI Elm_Transit_Tween_Mode
433 elm_transit_tween_mode_get(const Elm_Transit *transit)
434 {
435    ELM_TRANSIT_CHECK_OR_RETURN(transit, ELM_TRANSIT_TWEEN_MODE_LINEAR);
436
437    return transit->tween_mode;
438 }
439
440 /**
441  * Add new transit. 
442  *
443  * @param[in] parent Parent object
444  * @return transit 
445  *
446  * @ingroup Transit 
447  */
448 EAPI Elm_Transit *
449 elm_transit_add(Evas_Object *parent)
450 {
451    if (!parent) return NULL;
452
453    Elm_Transit *transit = ELM_NEW(Elm_Transit);
454
455    if (!transit) return NULL;
456
457    EINA_MAGIC_SET(transit, ELM_TRANSIT_MAGIC);
458
459    //elm_transit_tween_mode_set(transit, ELM_TRANSIT_TWEEN_MODE_LINEAR);
460
461    //transit->time.duration = duration;
462
463         //transit->time.begin = ecore_loop_time_get();
464    
465         //transit->animator = ecore_animator_add(_animator_animate_cb, transit);
466
467         transit->animator = elm_animator_add(parent);
468
469    if (!transit->animator)
470      {
471         free(transit);
472         return NULL;
473      }
474
475    transit->parent = parent;
476    elm_animator_operation_callback_set(transit->animator, _transit_animate_cb,
477                                        transit);
478    elm_animator_completion_callback_set(transit->animator, _transit_complete_cb,
479                                         transit);
480    elm_transit_event_block_disabled_set(transit, EINA_FALSE);
481 /*
482         if(parent)
483         {
484                 evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL, _transit_parent_del, 
485                                                          transit);
486         }
487 */
488    return transit;
489 }
490
491 /**
492  * Set reverse effect automatically.  
493  *
494  * @param[in] transit Transit  
495  * @param[in] reverse EINA_TRUE is reverse.
496  *
497  * @ingroup Transit 
498  */
499 EAPI void
500 elm_transit_auto_reverse_set(Elm_Transit *transit, Eina_Bool reverse)
501 {
502    ELM_TRANSIT_CHECK_OR_RETURN(transit);
503    elm_animator_auto_reverse_set(transit->animator, reverse);
504 }
505
506 /**
507  * Insert an effect into the transit. 
508  *
509  * @param[in] transit Transit
510  * @param[in] effect Effect to be inserted
511  * @return EINA_TRUE is success
512  *
513  * @ingroup Transit 
514  */
515 //EAPI void 
516 //elm_transit_effect_add(Elm_Transit *transit, void (*cb)(void *data, Elm_Transit *transit, double progress), void *data, void (*data_free_cb)(void *data, Elm_Transit *transit))
517 EAPI Eina_Bool
518 elm_transit_fx_insert(Elm_Transit *transit, Elm_Effect *effect)
519 {
520    ELM_TRANSIT_CHECK_OR_RETURN(transit, EINA_FALSE);
521         
522    Elm_Effect *_effect;
523
524    Eina_List *elist;
525
526    if (!effect) return EINA_FALSE;
527
528    EINA_LIST_FOREACH(transit->effect_list, elist, _effect)
529      {
530         if (_effect == effect)
531           return EINA_FALSE;
532      }
533
534    ++effect->shared_cnt;
535    transit->effect_list = eina_list_append(transit->effect_list, effect);
536
537    return EINA_TRUE;
538 }
539
540 /**
541  * Set the transit repeat count. Effect will be repeated by repeat count.
542  *
543  * @param[in] transit Transit 
544  * @param[in] repeat Repeat count 
545  *
546  * @ingroup Transit 
547  */
548 EAPI void
549 elm_transit_repeat_set(Elm_Transit *transit, unsigned int repeat)
550 {
551         ELM_TRANSIT_CHECK_OR_RETURN(transit);
552         elm_animator_repeat_set(transit->animator, repeat);
553 }
554
555 /**
556  * Stop the current transit, if the transit is operating. 
557  *
558  * @param[in] transit Transit 
559  *
560  * @ingroup Transit 
561  */
562 EAPI void
563 elm_transit_stop(Elm_Transit *transit)
564 {
565         ELM_TRANSIT_CHECK_OR_RETURN(transit);
566    elm_animator_stop(transit->animator);
567 }
568
569 /**
570  * Run the all the inserted effects.  
571  *
572  * @param[in] transit Transit
573  * @param[in] duration Transit time in seconds
574  *
575  * @ingroup Transit 
576  */
577 EAPI void
578 elm_transit_run(Elm_Transit *transit, double duration)
579 {
580         ELM_TRANSIT_CHECK_OR_RETURN(transit);
581    _transit_fx_begin(transit);
582    elm_animator_duration_set(transit->animator, duration);
583
584    //Block to Top
585    if (transit->block_rect)
586       evas_object_show(transit->block_rect);
587
588    elm_animator_animate(transit->animator);
589
590    //If failed to animate.  
591    if (!elm_animator_operating_get(transit->animator))
592      {
593         if (transit->block_rect)
594            evas_object_hide(transit->block_rect);
595         _transit_fx_end(transit);
596      }
597 }
598
599 /**
600  * Pause the transit
601  *
602  * @param[in]  transit Transit
603  *
604  * @ingroup Transit
605  */
606 EAPI void
607 elm_transit_pause(Elm_Transit *transit)
608 {
609         ELM_TRANSIT_CHECK_OR_RETURN(transit);
610
611         elm_animator_pause(transit->animator);
612 }
613
614 /**
615  * Resume the transit
616  *
617  * @param[in]  transit Transit
618  *
619  * @ingroup Transit
620  */
621 EAPI void
622 elm_transit_resume(Elm_Transit *transit)
623 {
624         ELM_TRANSIT_CHECK_OR_RETURN(transit);
625
626         elm_animator_resume(transit->animator);
627 }
628
629
630
631 /////////////////////////////////////////////////////////////////////////////////////
632 //Resizing FX
633 /////////////////////////////////////////////////////////////////////////////////////
634 typedef struct _resizing Elm_Fx_Resizing;
635 static void _elm_fx_resizing_op(void *data, Elm_Animator *animator, 
636                                 double frame);
637 static void _elm_fx_resizing_begin(void *data, Eina_Bool auto_reverse, 
638                                 unsigned int repeat_cnt);
639
640 struct _resizing
641 {
642    Evas_Object *obj;
643    struct _size
644    {
645       Evas_Coord w, h;
646    } from, to;
647 };
648
649 static void
650 _elm_fx_resizing_begin(void *data, Eina_Bool auto_reverse,
651                        unsigned int repeat_cnt)
652 {
653    Elm_Fx_Resizing *resizing = data;
654
655    evas_object_show(resizing->obj);
656    evas_object_resize(resizing->obj, resizing->from.w, resizing->from.h);
657 }
658
659 static void
660 _elm_fx_resizing_op(void *data, Elm_Animator *animator, double frame)
661 {
662    Evas_Coord w, h;
663
664    Elm_Fx_Resizing *resizing = data;
665
666    w = resizing->from.w + (Evas_Coord) ((float)resizing->to.w * (float)frame);
667    h = resizing->from.h + (Evas_Coord) ((float)resizing->to.h * (float)frame);
668    evas_object_resize(resizing->obj, w, h);
669 }
670
671 /**
672  * Add Resizing effect.  
673  *
674  * @param[in] obj Evas_Object that effect is applying to
675  * @param[in] from_w Object width size when effect begins
676  * @param[in] from_h Object height size when effect begins
677  * @param[in] to_w Object width size when effect ends
678  * @param[in] to_h Object height size when effect ends
679  * @return Resizing effect 
680  *
681  * @ingroup Transit 
682  */
683 EAPI Elm_Effect *
684 elm_fx_resizing_add(Evas_Object *obj, Evas_Coord from_w, Evas_Coord from_h,
685                     Evas_Coord to_w, Evas_Coord to_h)
686 {
687    Elm_Effect *effect;
688
689    Elm_Fx_Resizing *resizing;
690
691    if (!obj)
692       return NULL;
693
694    effect = calloc(1, sizeof(Elm_Effect));
695    if (!effect)
696       return NULL;
697
698    resizing = calloc(1, sizeof(Elm_Fx_Resizing));
699    if (!resizing)
700      {
701         free(effect);
702         return NULL;
703      }
704
705    resizing->obj = obj;
706    resizing->from.w = from_w;
707    resizing->from.h = from_h;
708    resizing->to.w = to_w - from_w;
709    resizing->to.h = to_h - from_h;
710
711    effect->begin_op = _elm_fx_resizing_begin;
712    effect->animation_op = _elm_fx_resizing_op;
713    effect->user_data = resizing;
714
715    return effect;
716 }
717
718 /////////////////////////////////////////////////////////////////////////////////////
719 //Translation FX
720 /////////////////////////////////////////////////////////////////////////////////////
721 typedef struct _translation Elm_Fx_Translation;
722 static void _elm_fx_translation_op(void *data, Elm_Animator *animator, 
723                                 double frame);
724 static void _elm_fx_translation_begin(void *data, Eina_Bool auto_reverse, 
725                                 unsigned int repeat_cnt);
726 static void _elm_fx_translation_end(void *data, Eina_Bool auto_reverse, 
727                                 unsigned int repeat_cnt);
728
729 struct _translation
730 {
731    Evas_Object *obj;
732    struct _point
733    {
734       Evas_Coord x, y;
735    } from, to;
736 };
737
738 static void
739 _elm_fx_translation_begin(void *data, Eina_Bool auto_reverse,
740                           unsigned int repeat_cnt)
741 {
742    Elm_Fx_Translation *translation = data;
743
744    evas_object_show(translation->obj);
745    evas_object_move(translation->obj, translation->from.x, translation->from.y);
746 }
747
748 static void
749 _elm_fx_translation_end(void *data, Eina_Bool auto_reverse,
750                         unsigned int repeat_cnt)
751 {
752    Elm_Fx_Translation *translation = data;
753
754    evas_object_move(translation->obj, translation->from.x + translation->to.x,
755                     translation->from.y + translation->to.y);
756 }
757
758 static void
759 _elm_fx_translation_op(void *data, Elm_Animator *animator, double frame)
760 {
761    Evas_Coord x, y;
762
763    Elm_Fx_Translation *translation = data;
764
765    x = translation->from.x +
766       (Evas_Coord) ((float)translation->to.x * (float)frame);
767    y = translation->from.y +
768       (Evas_Coord) ((float)translation->to.y * (float)frame);
769    evas_object_move(translation->obj, x, y);
770 }
771
772 /**
773  * Add Translation effect.  
774  *
775  * @param[in] obj Evas_Object that effect is applying to
776  * @param[in] from_x Position X when effect begins
777  * @param[in] from_y Position Y when effect begins
778  * @param[in] to_x Position X when effect ends
779  * @param[in] to_y Position Y when effect ends
780  * @return Translation effect 
781  *
782  * @ingroup Transit 
783  */
784 EAPI Elm_Effect *
785 elm_fx_translation_add(Evas_Object *obj, Evas_Coord from_x, Evas_Coord from_y,
786                        Evas_Coord to_x, Evas_Coord to_y)
787 {
788    Elm_Effect *effect;
789
790    Elm_Fx_Translation *translation;
791
792    if (!obj)
793       return NULL;
794
795    effect = calloc(1, sizeof(Elm_Effect));
796    if (!effect)
797       return NULL;
798
799    translation = calloc(1, sizeof(Elm_Fx_Translation));
800
801    if (!translation)
802      {
803         free(effect);
804         return NULL;
805      }
806
807    translation->obj = obj;
808    translation->from.x = from_x;
809    translation->from.y = from_y;
810    translation->to.x = to_x - from_x;
811    translation->to.y = to_y - from_y;
812
813    effect->begin_op = _elm_fx_translation_begin;
814    effect->end_op = _elm_fx_translation_end;
815    effect->animation_op = _elm_fx_translation_op;
816    effect->user_data = translation;
817
818    return effect;
819 }
820
821 /////////////////////////////////////////////////////////////////////////////////////
822 //Zoom FX
823 /////////////////////////////////////////////////////////////////////////////////////
824 typedef struct _zoom Elm_Fx_Zoom;
825 static void _elm_fx_zoom_op(void *data, Elm_Animator * animator, 
826                                 double frame);
827 static void _elm_fx_zoom_begin(void *data, Eina_Bool reverse, 
828                                 unsigned int repeat);
829 static void _elm_fx_zoom_end(void *data, Eina_Bool reverse, 
830                                 unsigned int repeat);
831
832 struct _zoom
833 {
834    Evas_Object *obj;
835    float from, to;
836 };
837
838 static void
839 _elm_fx_zoom_begin(void *data, Eina_Bool reverse, unsigned int repeat)
840 {
841    Elm_Fx_Zoom *zoom = data;
842
843    evas_object_show(zoom->obj);
844    _elm_fx_zoom_op(data, NULL, 0);
845 }
846
847 static void
848 _elm_fx_zoom_end(void *data, Eina_Bool reverse, unsigned int repeat)
849 {
850    Elm_Fx_Zoom *zoom = data;
851
852    evas_object_map_enable_set(zoom->obj, EINA_FALSE);
853 }
854
855 static void
856 _elm_fx_zoom_op(void *data, Elm_Animator *animator, double frame)
857 {
858    Elm_Fx_Zoom *zoom;
859
860    Evas_Map *map;
861
862    Evas_Coord x, y, w, h;
863
864    map = evas_map_new(4);
865    if (!map)
866       return;
867
868    zoom = data;
869    evas_object_geometry_get(zoom->obj, &x, &y, &w, &h);
870    evas_map_smooth_set(map, EINA_TRUE);
871    evas_map_util_points_populate_from_object_full(map, zoom->obj,
872                                                   zoom->from +
873                                                   (frame * zoom->to));
874    evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, 10000);
875    evas_object_map_set(zoom->obj, map);
876    evas_object_map_enable_set(zoom->obj, EINA_TRUE);
877    evas_map_free(map);
878 }
879
880 /**
881  * Add Zoom effect.  
882  *
883  * @param[in] obj Evas_Object that effect is applying to
884  * @param[in] from_rate Scale rate when effect begins (1 is current rate) 
885  * @param[in] to_rate Scale rate when effect ends
886  * @return Zoom effect 
887  *
888  * @ingroup Transit 
889  */
890 EAPI Elm_Effect *
891 elm_fx_zoom_add(Evas_Object *obj, float from_rate, float to_rate)
892 {
893    Elm_Effect *effect;
894
895    Elm_Fx_Zoom *zoom;
896
897    if (!obj)
898       return NULL;
899
900    effect = calloc(1, sizeof(Elm_Effect));
901    if (!effect)
902       return NULL;
903
904    zoom = calloc(1, sizeof(Elm_Fx_Zoom));
905    if (!zoom)
906      {
907         free(effect);
908         return NULL;
909      }
910
911    zoom->obj = obj;
912    zoom->from = (10000 - (from_rate * 10000)) * (1 / from_rate);
913    zoom->to = ((10000 - (to_rate * 10000)) * (1 / to_rate)) - zoom->from;
914    effect->begin_op = _elm_fx_zoom_begin;
915    effect->end_op = _elm_fx_zoom_end;
916    effect->animation_op = _elm_fx_zoom_op;
917    effect->user_data = zoom;
918
919    return effect;
920
921 }
922
923 /////////////////////////////////////////////////////////////////////////////////////
924 //Flip FX
925 /////////////////////////////////////////////////////////////////////////////////////
926 typedef struct _flip Elm_Fx_Flip;
927 static void _elm_fx_flip_op(void *data, Elm_Animator *animator, 
928                                 double frame);
929 static void _elm_fx_flip_end(void *data, Eina_Bool auto_reverse, 
930                                 unsigned int repeat_cnt);
931
932 struct _flip
933 {
934    Evas_Object *front;
935    Evas_Object *back;
936    Elm_Fx_Flip_Axis axis;
937    Eina_Bool cw:1;
938 };
939
940 static void
941 _elm_fx_flip_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
942 {
943    Elm_Fx_Flip *flip = data;
944
945    evas_object_map_enable_set(flip->front, EINA_FALSE);
946    evas_object_map_enable_set(flip->back, EINA_FALSE);
947 }
948
949 static void
950 _elm_fx_flip_op(void *data, Elm_Animator *animator, double frame)
951 {
952    Elm_Fx_Flip *flip;
953
954    Evas_Map *map;
955
956    float degree;
957
958    Evas_Object *obj;
959
960    Evas_Coord x, y, w, h;
961
962    map = evas_map_new(4);
963    if (!map)
964       return;
965
966    flip = data;
967
968    if (flip->cw)
969       degree = (float)(frame * 180);
970    else
971       degree = (float)(frame * -180);
972
973    if (degree < 90 && degree > -90)
974      {
975         obj = flip->front;
976         if(flip->back != flip->front) {
977                 evas_object_hide(flip->back);
978                 evas_object_show(flip->front);
979         }
980      }
981    else
982      {
983         obj = flip->back;
984         if(flip->back != flip->front) {
985                 evas_object_hide(flip->front);
986                 evas_object_show(flip->back);
987         }
988      }
989
990    evas_map_smooth_set(map, EINA_TRUE);
991    evas_map_util_points_populate_from_object_full(map, obj, 0);
992    evas_object_geometry_get(obj, &x, &y, &w, &h);
993    Evas_Coord half_w = (w / 2);
994
995    Evas_Coord half_h = (h / 2);
996
997    if (flip->axis == ELM_FX_FLIP_AXIS_Y)
998      {
999         if ((degree >= 90) || (degree <= -90))
1000           {
1001              evas_map_point_image_uv_set(map, 0, w, 0);
1002              evas_map_point_image_uv_set(map, 1, 0, 0);
1003              evas_map_point_image_uv_set(map, 2, 0, h);
1004              evas_map_point_image_uv_set(map, 3, w, h);
1005           }
1006         evas_map_util_3d_rotate(map, 0, degree, 0, x + half_w, y + half_h, 0);
1007      }
1008    else
1009      {
1010         if ((degree >= 90) || (degree <= -90))
1011           {
1012              evas_map_point_image_uv_set(map, 0, 0, h);
1013              evas_map_point_image_uv_set(map, 1, w, h);
1014              evas_map_point_image_uv_set(map, 2, w, 0);
1015              evas_map_point_image_uv_set(map, 3, 0, 0);
1016           }
1017         evas_map_util_3d_rotate(map, degree, 0, 0, x + half_w, y + half_h, 0);
1018      }
1019    evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, 10000);
1020    evas_object_map_enable_set(flip->front, EINA_TRUE);
1021    evas_object_map_enable_set(flip->back, EINA_TRUE);
1022    evas_object_map_set(obj, map);
1023    evas_map_free(map);
1024 }
1025
1026 /**
1027  * Add Flip effect.  
1028  *
1029  * @param[in] front Front surface object 
1030  * @param[in] back Back surface object
1031  * @param[in] axis Flipping Axis(X or Y)
1032  * @param[in] cw Flipping Direction. EINA_TRUE is clock-wise 
1033  * @return Flip effect 
1034  * 
1035  * @ingroup Transit 
1036  */
1037 EAPI Elm_Effect *
1038 elm_fx_flip_add(Evas_Object *front, Evas_Object *back, Elm_Fx_Flip_Axis axis,
1039                 Eina_Bool cw)
1040 {
1041    Elm_Effect *effect;
1042
1043    Elm_Fx_Flip *flip;
1044
1045    if ((!front) || (!back))
1046       return NULL;
1047
1048    effect = calloc(1, sizeof(Elm_Effect));
1049    if (!effect)
1050       return NULL;
1051
1052    flip = calloc(1, sizeof(Elm_Fx_Flip));
1053
1054    if (!flip)
1055      {
1056         free(effect);
1057         return NULL;
1058      }
1059
1060    flip->front = front;
1061    flip->back = back;
1062    flip->cw = cw;
1063    flip->axis = axis;
1064    effect->end_op = _elm_fx_flip_end;
1065    effect->animation_op = _elm_fx_flip_op;
1066    effect->user_data = flip;
1067
1068    return effect;
1069 }
1070
1071 /////////////////////////////////////////////////////////////////////////////////////
1072 //ResizableFlip FX
1073 /////////////////////////////////////////////////////////////////////////////////////
1074 typedef struct _resizable_flip Elm_Fx_ResizableFlip;
1075 static void _elm_fx_resizable_flip_begin(void *data, Eina_Bool reverse, 
1076                                 unsigned int repeat);
1077 static void _elm_fx_resizable_flip_end(void *data, Eina_Bool auto_reverse, 
1078                                 unsigned int repeat_cnt);
1079 static void _elm_fx_resizable_flip_op(void *data, Elm_Animator *animator,
1080                                       double frame);
1081 static void _set_image_uv_by_axis_y(Evas_Map *map, Elm_Fx_ResizableFlip *flip, 
1082                                 float degree);
1083 static void _set_image_uv_by_axis_x(Evas_Map *map, Elm_Fx_ResizableFlip *flip, 
1084                                 float degree);
1085
1086 struct _resizable_flip
1087 {
1088    Evas_Object *front;
1089    Evas_Object *back;
1090    Elm_Fx_Flip_Axis axis;
1091    struct _vector2d
1092    {
1093       float x, y;
1094    } from_pos, from_size, to_pos, to_size;
1095    Eina_Bool cw:1;
1096 };
1097
1098 static void
1099 _elm_fx_resizable_flip_begin(void *data, Eina_Bool reverse, unsigned int repeat)
1100 {
1101    Elm_Fx_ResizableFlip *resizable_flip = data;
1102
1103    evas_object_show(resizable_flip->front);
1104    _elm_fx_resizable_flip_op(data, NULL, 0);
1105 }
1106
1107 static void
1108 _elm_fx_resizable_flip_end(void *data, Eina_Bool auto_reverse,
1109                            unsigned int repeat_cnt)
1110 {
1111    Elm_Fx_ResizableFlip *resizable_flip = data;
1112
1113    evas_object_map_enable_set(resizable_flip->front, EINA_FALSE);
1114    evas_object_map_enable_set(resizable_flip->back, EINA_FALSE);
1115 }
1116
1117 static void
1118 _set_image_uv_by_axis_y(Evas_Map *map, Elm_Fx_ResizableFlip *flip,
1119                         float degree)
1120 {
1121    if ((degree >= 90) || (degree <= -90))
1122      {
1123         evas_map_point_image_uv_set(map, 0,
1124                                     (flip->from_size.x * 2) + flip->to_size.x,
1125                                     0);
1126         evas_map_point_image_uv_set(map, 1, 0, 0);
1127         evas_map_point_image_uv_set(map, 2, 0,
1128                                     (flip->from_size.y * 2) + flip->to_size.y);
1129         evas_map_point_image_uv_set(map, 3,
1130                                     (flip->from_size.x * 2) + flip->to_size.x,
1131                                     (flip->from_size.y * 2) + flip->to_size.y);
1132      }
1133    else
1134      {
1135         evas_map_point_image_uv_set(map, 0, 0, 0);
1136         evas_map_point_image_uv_set(map, 1, flip->from_size.x, 0);
1137         evas_map_point_image_uv_set(map, 2, flip->from_size.x,
1138                                     flip->from_size.y);
1139         evas_map_point_image_uv_set(map, 3, 0, flip->from_size.y);
1140      }
1141 }
1142
1143 static void
1144 _set_image_uv_by_axis_x(Evas_Map *map, Elm_Fx_ResizableFlip *flip,
1145                         float degree)
1146 {
1147    if ((degree >= 90) || (degree <= -90))
1148      {
1149         evas_map_point_image_uv_set(map, 0, 0,
1150                                     (flip->from_size.y * 2) + flip->to_size.y);
1151         evas_map_point_image_uv_set(map, 1,
1152                                     (flip->from_size.x * 2) + flip->to_size.x,
1153                                     (flip->from_size.y * 2) + flip->to_size.y);
1154         evas_map_point_image_uv_set(map, 2,
1155                                     (flip->from_size.x * 2) + flip->to_size.x,
1156                                     0);
1157         evas_map_point_image_uv_set(map, 3, 0, 0);
1158      }
1159    else
1160      {
1161         evas_map_point_image_uv_set(map, 0, 0, 0);
1162         evas_map_point_image_uv_set(map, 1, flip->from_size.x, 0);
1163         evas_map_point_image_uv_set(map, 2, flip->from_size.x,
1164                                     flip->from_size.y);
1165         evas_map_point_image_uv_set(map, 3, 0, flip->to_size.y);
1166      }
1167 }
1168
1169 static void
1170 _elm_fx_resizable_flip_op(void *data, Elm_Animator *animator, double frame)
1171 {
1172    Elm_Fx_ResizableFlip *resizable_flip;
1173
1174    Evas_Map *map;
1175
1176    float degree;
1177
1178    Evas_Object *obj;
1179
1180    float x, y, w, h;
1181
1182    Evas_Coord half_w, half_h;
1183
1184    map = evas_map_new(4);
1185    if (!map)
1186       return;
1187
1188    resizable_flip = data;
1189
1190    if (resizable_flip->cw)
1191       degree = (float)(frame * 180);
1192    else
1193       degree = (float)(frame * -180);
1194
1195    if ((degree < 90) && (degree > -90))
1196      {
1197         obj = resizable_flip->front;
1198         if(resizable_flip->back != resizable_flip->front) {
1199                 evas_object_hide(resizable_flip->back);
1200                 evas_object_show(resizable_flip->front);
1201      }
1202           }
1203    else
1204      {
1205         obj = resizable_flip->back;
1206         if(resizable_flip->back != resizable_flip->front) {
1207                 evas_object_hide(resizable_flip->front);
1208                 evas_object_show(resizable_flip->back);
1209                 }
1210     }
1211    evas_map_smooth_set(map, EINA_TRUE);
1212
1213    x = resizable_flip->from_pos.x + (resizable_flip->to_pos.x * frame);
1214    y = resizable_flip->from_pos.y + (resizable_flip->to_pos.y * frame);
1215    w = resizable_flip->from_size.x + (resizable_flip->to_size.x * frame);
1216    h = resizable_flip->from_size.y + (resizable_flip->to_size.y * frame);
1217    evas_map_point_coord_set(map, 0, x, y, 0);
1218    evas_map_point_coord_set(map, 1, x + w, y, 0);
1219    evas_map_point_coord_set(map, 2, x + w, y + h, 0);
1220    evas_map_point_coord_set(map, 3, x, y + h, 0);
1221
1222    half_w = (Evas_Coord) (w / 2);
1223    half_h = (Evas_Coord) (h / 2);
1224
1225    if (resizable_flip->axis == ELM_FX_FLIP_AXIS_Y)
1226      {
1227         _set_image_uv_by_axis_y(map, resizable_flip, degree);
1228         evas_map_util_3d_rotate(map, 0, degree, 0, x + half_w, y + half_h, 0);
1229      }
1230    else
1231      {
1232         _set_image_uv_by_axis_x(map, resizable_flip, degree);
1233         evas_map_util_3d_rotate(map, degree, 0, 0, x + half_w, y + half_h, 0);
1234      }
1235
1236    evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, 10000);
1237    evas_object_map_enable_set(resizable_flip->front, EINA_TRUE);
1238    evas_object_map_enable_set(resizable_flip->back, EINA_TRUE);
1239    evas_object_map_set(obj, map);
1240    evas_map_free(map);
1241 }
1242
1243 /**
1244  * Add ResizbleFlip effect. the size of each surface objects are interpolated automatically.
1245  *
1246  * @param[in] front Front surface object 
1247  * @param[in] back Back surface object
1248  * @param[in] axis Flipping Axis.(X or Y)  
1249  * @param[in] cw Flipping Direction. EINA_TRUE is clock-wise
1250  * @return Flip effect 
1251  *
1252  * @ingroup Transit 
1253  */
1254 EAPI Elm_Effect *
1255 elm_fx_resizable_flip_add(Evas_Object *front, Evas_Object *back,
1256                           Elm_Fx_Flip_Axis axis, Eina_Bool cw)
1257 {
1258    Elm_Fx_ResizableFlip *resizable_flip;
1259
1260    Elm_Effect *effect;
1261
1262    Evas_Coord front_x, front_y, front_w, front_h;
1263
1264    Evas_Coord back_x, back_y, back_w, back_h;
1265
1266    if (!front || !back)
1267       return NULL;
1268
1269    effect = calloc(1, sizeof(Elm_Effect));
1270    if (!effect)
1271       return NULL;
1272
1273    resizable_flip = calloc(1, sizeof(Elm_Fx_ResizableFlip));
1274
1275    if (!resizable_flip)
1276      {
1277         free(effect);
1278         return NULL;
1279      }
1280
1281    resizable_flip->front = front;
1282    resizable_flip->back = back;
1283    resizable_flip->cw = cw;
1284    resizable_flip->axis = axis;
1285
1286    evas_object_geometry_get(resizable_flip->front, &front_x, &front_y, &front_w,
1287                             &front_h);
1288    evas_object_geometry_get(resizable_flip->back, &back_x, &back_y, &back_w,
1289                             &back_h);
1290
1291    resizable_flip->from_pos.x = front_x;
1292    resizable_flip->from_pos.y = front_y;
1293    resizable_flip->to_pos.x = back_x - front_x;
1294    resizable_flip->to_pos.y = back_y - front_y;
1295
1296    resizable_flip->from_size.x = front_w;
1297    resizable_flip->from_size.y = front_h;
1298    resizable_flip->to_size.x = back_w - front_w;
1299    resizable_flip->to_size.y = back_h - front_h;
1300
1301    effect->begin_op = _elm_fx_resizable_flip_begin;
1302    effect->end_op = _elm_fx_resizable_flip_end;
1303    effect->animation_op = _elm_fx_resizable_flip_op;
1304    effect->user_data = resizable_flip;
1305
1306    return effect;
1307 }
1308
1309 /////////////////////////////////////////////////////////////////////////////////////
1310 //Wipe FX
1311 /////////////////////////////////////////////////////////////////////////////////////
1312 typedef struct _wipe Elm_Fx_Wipe;
1313 static void _elm_fx_wipe_op(void *data, Elm_Animator *animator, 
1314                                 double frame);
1315 static void _elm_fx_wipe_begin(void *data, Eina_Bool auto_repeat, 
1316                                 unsigned int repeat_cnt);
1317 static void _elm_fx_wipe_end(void *data, Eina_Bool auto_repeat, 
1318                                 unsigned int repeat_cnt);
1319 static void _elm_fx_wipe_hide(Evas_Map * map, Elm_Fx_Wipe_Dir dir, 
1320                                 float x, float y, float w, float h, float frame);
1321 static void _elm_fx_wipe_show(Evas_Map *map, Elm_Fx_Wipe_Dir dir, 
1322                                 float x, float y, float w, float h, float frame);
1323
1324 struct _wipe
1325 {
1326    Evas_Object *obj;
1327    Elm_Fx_Wipe_Type type;
1328    Elm_Fx_Wipe_Dir dir;
1329 };
1330
1331 static void
1332 _elm_fx_wipe_begin(void *data, Eina_Bool auto_repeat, unsigned int repeat_cnt)
1333 {
1334    Elm_Fx_Wipe *wipe = data;
1335
1336    evas_object_show(wipe->obj);
1337    _elm_fx_wipe_op(data, NULL, 0);
1338 }
1339
1340 static void
1341 _elm_fx_wipe_end(void *data, Eina_Bool auto_repeat, unsigned int repeat_cnt)
1342 {
1343    Elm_Fx_Wipe *wipe = data;
1344
1345    evas_object_map_enable_set(wipe->obj, EINA_FALSE);
1346 }
1347
1348 static void
1349 _elm_fx_wipe_hide(Evas_Map * map, Elm_Fx_Wipe_Dir dir, float x, float y,
1350                   float w, float h, float frame)
1351 {
1352    float w2, h2;
1353
1354    switch (dir)
1355      {
1356    case ELM_FX_WIPE_DIR_UP:
1357         w2 = (x + w);
1358         h2 = h-(h * frame);
1359         evas_map_point_image_uv_set(map, 0, 0, 0);
1360         evas_map_point_image_uv_set(map, 1, w, 0);
1361         evas_map_point_image_uv_set(map, 2, w, h2);
1362         evas_map_point_image_uv_set(map, 3, 0, h2);
1363         evas_map_point_coord_set(map, 0, x, y, 0);
1364         evas_map_point_coord_set(map, 1, w2, y, 0);
1365         evas_map_point_coord_set(map, 2, w2, y+h2, 0);
1366         evas_map_point_coord_set(map, 3, x, y+h2, 0);
1367         break;
1368         case ELM_FX_WIPE_DIR_LEFT:
1369         w2 = w - (w * frame);
1370         h2 = (y + h);
1371         evas_map_point_image_uv_set(map, 0, 0, 0);
1372         evas_map_point_image_uv_set(map, 1, w2, 0);
1373         evas_map_point_image_uv_set(map, 2, w2, h);
1374         evas_map_point_image_uv_set(map, 3, 0, h);
1375         evas_map_point_coord_set(map, 0, x, y, 0);
1376         evas_map_point_coord_set(map, 1, x + w2, y, 0);
1377         evas_map_point_coord_set(map, 2, x + w2, h2, 0);
1378         evas_map_point_coord_set(map, 3, x, h2, 0);
1379         break;
1380      case ELM_FX_WIPE_DIR_RIGHT:
1381         w2 = (w * frame);
1382         h2 = (y + h);
1383         evas_map_point_image_uv_set(map, 0, w2, 0);
1384         evas_map_point_image_uv_set(map, 1, w, 0);
1385         evas_map_point_image_uv_set(map, 2, w, h);
1386         evas_map_point_image_uv_set(map, 3, w2, h);
1387         evas_map_point_coord_set(map, 0, x + w2, y, 0);
1388         evas_map_point_coord_set(map, 1, x + w, y, 0);
1389         evas_map_point_coord_set(map, 2, x + w, h2, 0);
1390         evas_map_point_coord_set(map, 3, x + w2, h2, 0);
1391         break;
1392      case ELM_FX_WIPE_DIR_DOWN:
1393         w2 = (x + w);
1394         h2 = (h * frame);
1395         evas_map_point_image_uv_set(map, 0, 0, h2);
1396         evas_map_point_image_uv_set(map, 1, w, h2);
1397         evas_map_point_image_uv_set(map, 2, w, h);
1398         evas_map_point_image_uv_set(map, 3, 0, h);
1399         evas_map_point_coord_set(map, 0, x, y + h2, 0);
1400         evas_map_point_coord_set(map, 1, w2, y + h2, 0);
1401         evas_map_point_coord_set(map, 2, w2, y + h, 0);
1402         evas_map_point_coord_set(map, 3, x, y + h, 0);
1403         break;
1404      default:
1405         break;
1406      }
1407
1408    evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, 10000);
1409 }
1410
1411 static void
1412 _elm_fx_wipe_show(Evas_Map *map, Elm_Fx_Wipe_Dir dir, float x, float y,
1413                   float w, float h, float frame)
1414 {
1415    float w2, h2;
1416
1417    switch (dir)
1418      {
1419           case ELM_FX_WIPE_DIR_UP:
1420         w2 = (x + w);
1421         h2 = (h - (h * frame));
1422         evas_map_point_image_uv_set(map, 0, 0, h2);
1423         evas_map_point_image_uv_set(map, 1, w, h2);
1424         evas_map_point_image_uv_set(map, 2, w, h);
1425         evas_map_point_image_uv_set(map, 3, 0, h);
1426         evas_map_point_coord_set(map, 0, x, y + h2, 0);
1427         evas_map_point_coord_set(map, 1, w2, y + h2, 0);
1428         evas_map_point_coord_set(map, 2, w2, y + h, 0);
1429         evas_map_point_coord_set(map, 3, x, y + h, 0);
1430         break;
1431      case ELM_FX_WIPE_DIR_LEFT:
1432         w2 = (w - (w * frame));
1433         h2 = (y + h);
1434         evas_map_point_image_uv_set(map, 0, w2, 0);
1435         evas_map_point_image_uv_set(map, 1, w, 0);
1436         evas_map_point_image_uv_set(map, 2, w, h);
1437         evas_map_point_image_uv_set(map, 3, w2, h);
1438         evas_map_point_coord_set(map, 0, x + w2, y, 0);
1439         evas_map_point_coord_set(map, 1, x + w, y, 0);
1440         evas_map_point_coord_set(map, 2, x +w, h2, 0);
1441         evas_map_point_coord_set(map, 3, x + w2, h2, 0);
1442         break;
1443      case ELM_FX_WIPE_DIR_RIGHT:
1444         w2 = (w * frame);
1445         h2 = (y + h);
1446         evas_map_point_image_uv_set(map, 0, 0, 0);
1447         evas_map_point_image_uv_set(map, 1, w2, 0);
1448         evas_map_point_image_uv_set(map, 2, w2, h);
1449         evas_map_point_image_uv_set(map, 3, 0, h);
1450         evas_map_point_coord_set(map, 0, x, y, 0);
1451         evas_map_point_coord_set(map, 1, x + w2, y, 0);
1452         evas_map_point_coord_set(map, 2, x + w2, h2, 0);
1453         evas_map_point_coord_set(map, 3, x, h2, 0);
1454         break;
1455      case ELM_FX_WIPE_DIR_DOWN:
1456         w2 = (x + w);
1457         h2 = (h * frame);
1458         evas_map_point_image_uv_set(map, 0, 0, 0);
1459         evas_map_point_image_uv_set(map, 1, w, 0);
1460         evas_map_point_image_uv_set(map, 2, w, h2);
1461         evas_map_point_image_uv_set(map, 3, 0, h2);
1462         evas_map_point_coord_set(map, 0, x, y, 0);
1463         evas_map_point_coord_set(map, 1, w2, y, 0);
1464         evas_map_point_coord_set(map, 2, w2, y + h2, 0);
1465         evas_map_point_coord_set(map, 3, x, y + h2, 0);
1466         break;
1467      default:
1468         break;
1469      }
1470
1471    evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, 10000);
1472 }
1473
1474 static void
1475 _elm_fx_wipe_op(void *data, Elm_Animator *animator, double frame)
1476 {
1477    Elm_Fx_Wipe *wipe;
1478
1479    Evas_Map *map;
1480
1481    Evas_Coord _x, _y, _w, _h;
1482
1483    map = evas_map_new(4);
1484    if (!map)
1485       return;
1486
1487    wipe = data;
1488    evas_map_smooth_set(map, EINA_TRUE);
1489    evas_object_geometry_get(wipe->obj, &_x, &_y, &_w, &_h);
1490
1491    if (wipe->type == ELM_FX_WIPE_TYPE_SHOW)
1492       _elm_fx_wipe_show(map, wipe->dir, _x, _y, _w, _h, (float)frame);
1493    else
1494       _elm_fx_wipe_hide(map, wipe->dir, _x, _y, _w, _h, (float)frame);
1495
1496    evas_object_map_enable_set(wipe->obj, EINA_TRUE);
1497    evas_object_map_set(wipe->obj, map);
1498    evas_map_free(map);
1499 }
1500
1501 /**
1502  * Add Wipe effect.  
1503  *
1504  * @param[in] obj Evas_Object that effect is applying to
1505  * @param[in] type Wipe type. Hide or show
1506  * @param[in] dir Wipe Direction
1507  * @return Wipe effect
1508  *
1509  * @ingroup Transit 
1510  */
1511 EAPI Elm_Effect *
1512 elm_fx_wipe_add(Evas_Object *obj, Elm_Fx_Wipe_Type type, Elm_Fx_Wipe_Dir dir)
1513 {
1514    Elm_Effect *effect;
1515
1516    Elm_Fx_Wipe *wipe;
1517
1518    if (!obj)
1519       return NULL;
1520
1521    effect = calloc(1, sizeof(Elm_Effect));
1522    if (!effect)
1523       return NULL;
1524
1525    wipe = calloc(1, sizeof(Elm_Fx_Wipe));
1526    if (!wipe)
1527      {
1528         free(effect);
1529         return NULL;
1530      }
1531
1532    wipe->obj = obj;
1533    wipe->type = type;
1534    wipe->dir = dir;
1535    effect->begin_op = _elm_fx_wipe_begin;
1536    effect->end_op = _elm_fx_wipe_end;
1537    effect->animation_op = _elm_fx_wipe_op;
1538    effect->user_data = wipe;
1539
1540    return effect;
1541 }
1542
1543 /////////////////////////////////////////////////////////////////////////////////////
1544 //Color FX
1545 /////////////////////////////////////////////////////////////////////////////////////
1546 typedef struct _color Elm_Fx_Color;
1547 static void _elm_fx_color_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt);
1548 static void _elm_fx_color_op(void *data, Elm_Animator *animator, double frame);
1549
1550 struct _color
1551 {
1552    Evas_Object *obj;
1553    struct _unsigned_color
1554    {
1555       unsigned int r, g, b, a;
1556    } from;
1557    struct _signed_color
1558    {
1559       int r, g, b, a;
1560    } to;
1561 };
1562
1563 static void
1564 _elm_fx_color_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1565 {
1566    Elm_Fx_Color *color = data;
1567
1568    evas_object_show(color->obj);
1569 }
1570
1571 static void
1572 _elm_fx_color_op(void *data, Elm_Animator *animator, double frame)
1573 {
1574    Elm_Fx_Color *color;
1575
1576    unsigned int r, g, b, a;
1577
1578    color = data;
1579    r = (color->from.r + (int)((float)color->to.r * frame));
1580    g = (color->from.g + (int)((float)color->to.g * frame));
1581    b = (color->from.b + (int)((float)color->to.b * frame));
1582    a = (color->from.a + (int)((float)color->to.a * frame));
1583
1584    evas_object_color_set(color->obj, r, g, b, a);
1585 }
1586
1587 /**
1588  * Add Color effect.  
1589  *
1590  * @param[in]  obj           Evas_Object that effect is applying to
1591  * @param[in]  from_r        RGB R when effect begins
1592  * @param[in]  from_g        RGB G when effect begins 
1593  * @param[in]  from_b        RGB B when effect begins
1594  * @param[in]  from_a        RGB A when effect begins
1595  * @param[in]  to_r          RGB R when effect ends
1596  * @param[in]  to_g          RGB G when effect ends
1597  * @param[in]  to_b          RGB B when effect ends
1598  * @param[in]  to_a          RGB A when effect ends
1599  * @return               Color Effect
1600  *
1601  * @ingroup Transit 
1602  */
1603 EAPI Elm_Effect *
1604 elm_fx_color_add(Evas_Object *obj, unsigned int from_r, unsigned int from_g,
1605                  unsigned int from_b, unsigned int from_a, unsigned int to_r,
1606                  unsigned int to_g, unsigned int to_b, unsigned int to_a)
1607 {
1608    Elm_Effect *effect;
1609
1610    Elm_Fx_Color *color;
1611
1612    if (!obj)
1613       return NULL;
1614
1615    effect = calloc(1, sizeof(Elm_Effect));
1616    if (!effect)
1617       return NULL;
1618
1619    color = calloc(1, sizeof(Elm_Fx_Color));
1620    if (!color)
1621      {
1622         free(effect);
1623         return NULL;
1624      }
1625
1626    color->obj = obj;
1627    color->from.r = from_r;
1628    color->from.g = from_g;
1629    color->from.b = from_b;
1630    color->from.a = from_a;
1631    color->to.r = to_r - from_r;
1632    color->to.g = to_g - from_g;
1633    color->to.b = to_b - from_b;
1634    color->to.a = to_a - from_a;
1635
1636    effect->begin_op = _elm_fx_color_begin;
1637    effect->animation_op = _elm_fx_color_op;
1638    effect->user_data = color;
1639
1640    return effect;
1641 }
1642
1643 /////////////////////////////////////////////////////////////////////////////////////
1644 //Fade FX
1645 /////////////////////////////////////////////////////////////////////////////////////
1646 typedef struct _fade Elm_Fx_Fade;
1647 static void _elm_fx_fade_begin(void *data, Eina_Bool auto_reverse, 
1648                                 unsigned int repeat_cnt);
1649 static void _elm_fx_fade_end(void *data, Eina_Bool auto_reverse, 
1650                                 unsigned int repeat_cnt);
1651 static void _elm_fx_fade_op(void *data, Elm_Animator *animator, 
1652                                 double frame);
1653
1654 struct _fade
1655 {
1656    Evas_Object *before;
1657    Evas_Object *after;
1658    struct _signed_color before_color, after_color;
1659    int before_alpha;
1660    int after_alpha;
1661    Eina_Bool inversed:1;
1662 };
1663
1664 static void
1665 _elm_fx_fade_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1666 {
1667    Elm_Fx_Fade *fade = data;
1668
1669    fade->inversed = EINA_FALSE;
1670 }
1671
1672 static void
1673 _elm_fx_fade_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1674 {
1675    Elm_Fx_Fade *fade = data;
1676
1677    evas_object_color_set(fade->before, fade->before_color.r,
1678                          fade->before_color.g, fade->before_color.b,
1679                          fade->before_color.a);
1680    evas_object_color_set(fade->after, fade->after_color.r, fade->after_color.g,
1681                          fade->after_color.b, fade->after_color.a);
1682 }
1683
1684 static void
1685 _elm_fx_fade_op(void *data, Elm_Animator *animator, double frame)
1686 {
1687    Elm_Fx_Fade *fade;
1688
1689    float _frame;
1690
1691    fade = data;
1692
1693    if (frame < 0.5)
1694      {
1695         if (!fade->inversed)
1696           {
1697              evas_object_hide(fade->after);
1698              evas_object_show(fade->before);
1699              fade->inversed = EINA_TRUE;
1700           }
1701
1702         _frame = (1 - (frame * 2));
1703
1704         evas_object_color_set(fade->before, fade->before_color.r * _frame,
1705                               fade->before_color.g * _frame,
1706                               fade->before_color.b * _frame,
1707                               fade->before_color.a + fade->before_alpha * (1 -
1708                                                                            _frame));
1709      }
1710    else
1711      {
1712         if (fade->inversed)
1713           {
1714              evas_object_hide(fade->before);
1715              evas_object_show(fade->after);
1716              fade->inversed = EINA_FALSE;
1717           }
1718
1719         _frame = ((frame - 0.5) * 2);
1720
1721         evas_object_color_set(fade->after, fade->after_color.r * _frame,
1722                               fade->after_color.g * _frame,
1723                               fade->after_color.b * _frame,
1724                               fade->after_color.a + fade->after_alpha * (1 -
1725                                                                          _frame));
1726      }
1727
1728 }
1729
1730 /**
1731  * Add Fade effect  
1732  *
1733  * @param[in] before Evas Object before fade in 
1734  * @param[in] after Evas Object after fade out 
1735  * @return Fade effect
1736  * 
1737  * @ingroup Transit 
1738  */
1739 EAPI Elm_Effect *
1740 elm_fx_fade_add(Evas_Object *before, Evas_Object *after)
1741 {
1742    Elm_Effect *effect;
1743
1744    Elm_Fx_Fade *fade;
1745
1746    if ((!before) && (!after))
1747       return NULL;
1748
1749    effect = calloc(1, sizeof(Elm_Effect));
1750    if (!effect)
1751       return NULL;
1752
1753    fade = calloc(1, sizeof(Elm_Fx_Fade));
1754
1755    if (!fade)
1756      {
1757         free(effect);
1758         return NULL;
1759      }
1760
1761    evas_object_color_get(before, &fade->before_color.r, &fade->before_color.g,
1762                          &fade->before_color.b, &fade->before_color.a);
1763    evas_object_color_get(after, &fade->after_color.r, &fade->after_color.g,
1764                          &fade->after_color.b, &fade->after_color.a);
1765
1766    fade->before = before;
1767    fade->after = after;
1768    fade->before_alpha = (255 - fade->before_color.a);
1769    fade->after_alpha = (255 - fade->after_color.a);
1770
1771    effect->begin_op = _elm_fx_fade_begin;
1772    effect->end_op = _elm_fx_fade_end;
1773    effect->animation_op = _elm_fx_fade_op;
1774    effect->user_data = fade;
1775
1776    return effect;
1777 }
1778
1779 /////////////////////////////////////////////////////////////////////////////////////
1780 //Blend FX
1781 /////////////////////////////////////////////////////////////////////////////////////
1782 typedef struct _blend Elm_Fx_Blend;
1783 static void _elm_fx_blend_begin(void *data, Eina_Bool auto_reverse, 
1784                                 unsigned int repeat_cnt);
1785 static void _elm_fx_blend_end(void *data, Eina_Bool auto_reverse, 
1786                                 unsigned int repeat_cnt);
1787 static void _elm_fx_blend_op(void *data, Elm_Animator *animator, 
1788                                 double frame);
1789
1790 struct _blend
1791 {
1792    Evas_Object *before;
1793    Evas_Object *after;
1794    struct _signed_color from, to;
1795 };
1796
1797 static void
1798 _elm_fx_blend_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1799 {
1800    Elm_Fx_Blend *blend = data;
1801
1802    evas_object_show(blend->before);
1803 }
1804
1805 static void
1806 _elm_fx_blend_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1807 {
1808    Elm_Fx_Blend *blend = data;
1809
1810    evas_object_color_set(blend->before, blend->from.r, blend->from.g,
1811                          blend->from.b, blend->from.a);
1812    evas_object_color_set(blend->after, blend->to.r, blend->to.g, blend->to.b,
1813                          blend->to.a);
1814    if (!auto_reverse)
1815       evas_object_hide(blend->before);
1816    else
1817       evas_object_hide(blend->after);
1818 }
1819
1820 static void
1821 _elm_fx_blend_op(void *data, Elm_Animator *animator, double frame)
1822 {
1823    Elm_Fx_Blend *blend = data;
1824
1825    evas_object_show(blend->after);
1826    evas_object_color_set(blend->before, (int)(blend->from.r * (1 - frame)),
1827                          (int)(blend->from.g * (1 - frame)),
1828                          (int)(blend->from.b * (1 - frame)),
1829                          (int)(blend->from.a * (1 - frame)));
1830    evas_object_color_set(blend->after, (int)(blend->to.r * frame),
1831                          (int)(blend->to.g * frame), (int)(blend->to.b * frame),
1832                          (int)(blend->to.a * frame));
1833 }
1834
1835 /**
1836  * Add Blend effect  
1837  *
1838  * @param[in] before Evas Object before blending
1839  * @param[in] after Evas Object after blending 
1840  * @return Blend effect
1841  *
1842  * @ingroup Transit 
1843  */
1844 EAPI Elm_Effect *
1845 elm_fx_blend_add(Evas_Object *before, Evas_Object *after)
1846 {
1847    Elm_Effect *effect;
1848
1849    Elm_Fx_Blend *blend;
1850
1851    if ((!before) && (!after))
1852       return NULL;
1853
1854    effect = calloc(1, sizeof(Elm_Effect));
1855    if (!effect)
1856       return NULL;
1857
1858    blend = calloc(1, sizeof(Elm_Fx_Blend));
1859    if (!blend)
1860      {
1861         free(effect);
1862         return NULL;
1863      }
1864
1865    blend->before = before;
1866    blend->after = after;
1867    evas_object_color_get(before, &blend->from.r, &blend->from.g, &blend->from.b,
1868                          &blend->from.a);
1869    evas_object_color_get(after, &blend->to.r, &blend->to.g, &blend->to.b,
1870                          &blend->to.a);
1871
1872    effect->begin_op = _elm_fx_blend_begin;
1873    effect->end_op = _elm_fx_blend_end;
1874    effect->animation_op = _elm_fx_blend_op;
1875    effect->user_data = blend;
1876
1877    return effect;
1878 }
1879
1880 /////////////////////////////////////////////////////////////////////////////////////
1881 //Rotation FX
1882 /////////////////////////////////////////////////////////////////////////////////////
1883 typedef struct _rotation Elm_Fx_Rotation;
1884 static void _elm_fx_rotation_begin(void *data, Eina_Bool auto_reverse, 
1885                                 unsigned int repeat_cnt);
1886 static void _elm_fx_rotation_end(void *data, Eina_Bool auto_reverse, 
1887                                 unsigned int repeat_cnt);
1888 static void _elm_fx_rotation_op(void *data, Elm_Animator *animator, 
1889                                 double frame);
1890
1891 struct _rotation
1892 {
1893    Evas_Object *obj;
1894    Eina_Bool cw;
1895    float from, to;
1896 };
1897
1898 static void
1899 _elm_fx_rotation_begin(void *data, Eina_Bool auto_reverse,
1900                        unsigned int repeat_cnt)
1901 {
1902    Elm_Fx_Rotation *rotation = data;
1903
1904    evas_object_show(rotation->obj);
1905 }
1906
1907 static void
1908 _elm_fx_rotation_end(void *data, Eina_Bool auto_reverse,
1909                      unsigned int repeat_cnt)
1910 {
1911    Elm_Fx_Rotation *rotation = data;
1912
1913    evas_object_map_enable_set(rotation->obj, EINA_FALSE);
1914 }
1915
1916 static void
1917 _elm_fx_rotation_op(void *data, Elm_Animator *animator, double frame)
1918 {
1919    Elm_Fx_Rotation *rotation;
1920
1921    Evas_Map *map;
1922
1923    Evas_Coord x, y, w, h;
1924
1925    float degree;
1926
1927    float half_w, half_h;
1928
1929    map = evas_map_new(4);
1930    if (!map)
1931       return;
1932
1933    rotation = data;
1934
1935    evas_map_smooth_set(map, EINA_TRUE);
1936    evas_map_util_points_populate_from_object_full(map, rotation->obj, 0);
1937    degree = rotation->from + (float)(frame * rotation->to);
1938
1939    if (!rotation->cw)
1940       degree *= -1;
1941
1942    evas_object_geometry_get(rotation->obj, &x, &y, &w, &h);
1943
1944    half_w = (float)w *0.5;
1945
1946    half_h = (float)h *0.5;
1947
1948    evas_map_util_3d_rotate(map, 0, 0, degree, x + half_w, y + half_h, 0);
1949    evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, 10000);
1950    evas_object_map_enable_set(rotation->obj, EINA_TRUE);
1951    evas_object_map_set(rotation->obj, map);
1952    evas_map_free(map);
1953 }
1954
1955 /**
1956  * Add Rotation effect
1957  *
1958  * @param[in] obj Evas_Object that effect is applying to 
1959  * @param[in] from degree Degree when effect begins
1960  * @param[in] to_degree Degree when effect is ends
1961  * @param[in] cw Rotation direction. EINA_TRUE is clock wise
1962  * @return Rotation effect
1963  *
1964  * @ingroup Transit 
1965  */
1966 EAPI Elm_Effect *
1967 elm_fx_rotation_add(Evas_Object *obj, float from_degree, float to_degree,
1968                     Eina_Bool cw)
1969 {
1970    Elm_Effect *effect;
1971
1972    Elm_Fx_Rotation *rotation;
1973
1974    if (!obj)
1975       return NULL;
1976
1977    effect = calloc(1, sizeof(Elm_Effect));
1978    if (!effect)
1979       return NULL;
1980
1981    rotation = calloc(1, sizeof(Elm_Fx_Rotation));
1982
1983    if (!rotation)
1984      {
1985         free(effect);
1986         return NULL;
1987      }
1988
1989    rotation->obj = obj;
1990    rotation->from = from_degree;
1991    rotation->to = to_degree - from_degree;
1992    rotation->cw = cw;
1993
1994    effect->begin_op = _elm_fx_rotation_begin;
1995    effect->end_op = _elm_fx_rotation_end;
1996    effect->animation_op = _elm_fx_rotation_op;
1997    effect->user_data = rotation;
1998
1999    return effect;
2000 }
2001
2002
2003
2004
2005 /////////////////////////////////////////////////////////////////////////////////////
2006 //Rotation3d FX
2007 /////////////////////////////////////////////////////////////////////////////////////
2008 typedef struct _rotation3d Elm_Fx_Rotation3d;
2009 static void _elm_fx_rotation3d_begin(void *data, Eina_Bool auto_reverse,
2010                                 unsigned int repeat_cnt);
2011 static void _elm_fx_rotation3d_end(void *data, Eina_Bool auto_reverse,
2012                                 unsigned int repeat_cnt);
2013 static void _elm_fx_rotation3d_op(void *data, Elm_Animator *animator,
2014                                 double frame);
2015
2016 struct _rotation3d
2017 {
2018    Evas_Object *obj;
2019    float from[3];
2020    float to[3];
2021    float axis_pos[3];
2022 };
2023
2024 static void
2025 _elm_fx_rotation3d_begin(void *data, Eina_Bool auto_reverse,
2026                        unsigned int repeat_cnt)
2027 {
2028    Elm_Fx_Rotation3d *rotation = data;
2029    evas_object_show(rotation->obj);
2030 }
2031
2032 static void
2033 _elm_fx_rotation3d_end(void *data, Eina_Bool auto_reverse,
2034                      unsigned int repeat_cnt)
2035 {
2036    Elm_Fx_Rotation3d *rotation = data;
2037    evas_object_map_enable_set(rotation->obj, EINA_FALSE);
2038 }
2039
2040 static void
2041 _elm_fx_rotation3d_op(void *data, Elm_Animator *animator, double frame)
2042 {
2043    Elm_Fx_Rotation3d *rotation;
2044
2045    Evas_Map *map;
2046
2047    Evas_Coord x, y, w, h;
2048
2049    float degree[3];
2050
2051    float half_w, half_h;
2052
2053    map = evas_map_new(4);
2054    if (!map)
2055       return;
2056
2057    rotation = data;
2058
2059    evas_map_smooth_set(map, EINA_TRUE);
2060    evas_map_util_points_populate_from_object_full(map, rotation->obj, 0);
2061    degree[0] = rotation->from[0] + (float)(frame * rotation->to[0]);
2062    degree[1] = rotation->from[1] + (float)(frame * rotation->to[1]);
2063    degree[2] = rotation->from[2] + (float)(frame * rotation->to[2]);
2064
2065    evas_object_geometry_get(rotation->obj, &x, &y, &w, &h);
2066
2067    half_w = (float)w *0.5;
2068
2069    half_h = (float)h *0.5;
2070
2071    evas_map_util_3d_rotate(map, degree[0], degree[1], degree[2], rotation->axis_pos[0], rotation->axis_pos[1], rotation->axis_pos[2]);
2072    evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, 1000);
2073    evas_object_map_enable_set(rotation->obj, EINA_TRUE);
2074    evas_object_map_set(rotation->obj, map);
2075    evas_map_free(map);
2076 }
2077
2078 /**
2079  * Add Rotation3d effect
2080  *
2081  * @param[in] obj Evas_Object that effect is applying to
2082  * @param[in] from degree Degree when effect begins
2083  * @param[in] to_degree Degree when effect is ends
2084  * @param[in] axis_dir[3] rotation axis vector. it should be normalized.
2085  * @param[in] axis_pos[3] rotation axis origin position.
2086  * @param[in] cw Rotation direction. EINA_TRUE is clock wise
2087  * @return Rotation effect
2088  *
2089  * @ingroup Transit
2090  */
2091 EAPI Elm_Effect *
2092 elm_fx_rotation3d_add(Evas_Object *obj, float from_degree, float to_degree,
2093                 float* axis_dir, float* axis_pos)
2094 {
2095    Elm_Effect *effect;
2096
2097    Elm_Fx_Rotation3d *rotation;
2098
2099    if (!obj)
2100       return NULL;
2101
2102    effect = calloc(1, sizeof(Elm_Effect));
2103    if (!effect)
2104       return NULL;
2105
2106    rotation = calloc(1, sizeof(Elm_Fx_Rotation3d));
2107
2108    if (!rotation)
2109      {
2110         free(effect);
2111         return NULL;
2112      }
2113
2114    rotation->obj = obj;
2115    rotation->from[0] = from_degree * axis_dir[0];
2116    rotation->from[1] = from_degree * axis_dir[1];
2117    rotation->from[2] = from_degree * axis_dir[2];
2118    rotation->to[0] = (to_degree * axis_dir[0]) - rotation->from[0];
2119    rotation->to[1] = (to_degree * axis_dir[1]) - rotation->from[1];
2120    rotation->to[2] = (to_degree * axis_dir[2]) - rotation->from[2];
2121    rotation->axis_pos[0] = axis_pos[0];
2122    rotation->axis_pos[1] = axis_pos[1];
2123    rotation->axis_pos[2] = axis_pos[2];
2124
2125    effect->begin_op = _elm_fx_rotation3d_begin;
2126    effect->end_op = _elm_fx_rotation3d_end;
2127    effect->animation_op = _elm_fx_rotation3d_op;
2128    effect->user_data = rotation;
2129
2130    return effect;
2131 }
2132
2133
2134
2135 /////////////////////////////////////////////////////////////////////////////////////
2136 // ImageAnimation FX
2137 /////////////////////////////////////////////////////////////////////////////////////
2138 typedef struct _image_animation Elm_Fx_Image_Animation;
2139 static void _elm_fx_image_animation_begin(void *data, Eina_Bool auto_reverse,
2140                        unsigned int repeat_cnt);
2141 static void _elm_fx_image_animation_op(void *data, Elm_Animator *animator, 
2142                                 double frame);
2143 EAPI Elm_Effect *elm_fx_image_animation_add(Evas_Object *obj, const char **images, 
2144                                 unsigned int item_num);
2145
2146 struct _image_animation
2147 {
2148    Evas_Object *obj;
2149    char **images;
2150    int img_cnt;
2151 };
2152
2153
2154 static void
2155 _elm_fx_image_animation_begin(void *data, Eina_Bool auto_reverse,
2156                        unsigned int repeat_cnt)
2157 {
2158    Elm_Fx_Image_Animation *image_animation = data;
2159    evas_object_show(image_animation->obj);
2160 }
2161
2162
2163 static void
2164 _elm_fx_image_animation_op(void *data, Elm_Animator *animator, double frame)
2165 {
2166    Elm_Fx_Image_Animation *image_animation = (Elm_Fx_Image_Animation *) data;
2167
2168    elm_icon_file_set(image_animation->obj,
2169                      image_animation->images[ (int) floor(frame * (image_animation->img_cnt-1)) ], NULL);
2170 }
2171
2172 static void
2173 _elm_fx_image_animation_del(void *data)
2174 {
2175         int idx;
2176         Elm_Fx_Image_Animation *image_animation = data;
2177
2178         for(idx = 0; idx < image_animation->img_cnt; ++idx ) {
2179                 eina_stringshare_del(image_animation->images[ idx ]);
2180         }
2181
2182         free(image_animation->images);
2183 }
2184
2185 /**
2186  * Add image_animation effect.  
2187  *
2188  * @param[in] obj Icon object
2189  * @param[in] images Array of image file path. 
2190  * @param[in] img_cnt Count of image. 
2191  * @return ImageAnimation effect.
2192  *
2193  * @ingroup Transit 
2194  */
2195 EAPI Elm_Effect *
2196 elm_fx_image_animation_add(Evas_Object *obj, const char **images,
2197                           unsigned int img_cnt)
2198 {
2199    Elm_Effect *effect;
2200    Elm_Fx_Image_Animation *image_animation;
2201    int idx;
2202
2203    if ((!obj) || !images || !(*images))
2204       return NULL;
2205
2206    effect = calloc(1, sizeof(Elm_Effect));
2207    if (!effect)
2208       return NULL;
2209
2210    image_animation = calloc(1, sizeof(Elm_Fx_Image_Animation));
2211
2212    if (!image_animation)
2213      {
2214         free(effect);
2215         return NULL;
2216      }
2217
2218    image_animation->obj = obj;
2219    image_animation->images = calloc( img_cnt, sizeof(char*));
2220    for(idx = 0; idx < img_cnt; ++idx )
2221            image_animation->images[ idx ] = eina_stringshare_add( images[ idx ] );
2222
2223    image_animation->img_cnt = img_cnt;
2224
2225    effect->begin_op = _elm_fx_image_animation_begin;
2226    effect->animation_op = _elm_fx_image_animation_op;
2227    effect->del_op = _elm_fx_image_animation_del;
2228    effect->user_data = image_animation;
2229
2230    return effect;
2231 }