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