Merge branch 'master' of 165.213.180.234:/git/slp/pkgs/elementary
[framework/uifw/elementary.git] / src / lib / elm_transit.c
1 #include <Elementary.h>
2
3 /**
4  *
5  * @defgroup Transit Transit
6  * @ingroup Elementary
7  *
8  * Transit 
9 */
10 struct _transit 
11 {
12         Evas_Object             *parent;
13         Elm_Animator    *animator;
14         Eina_List               *effect_list;
15         Evas_Object             *block_rect;
16         void                            (*completion_op)(void *, Elm_Transit *);
17         void                            *completion_arg;
18         Eina_Bool               reserved_del:1;
19 };
20
21 struct _effect 
22 {
23         void  (*animation_op)(void *, Elm_Animator *, double);
24         void  (*begin_op)(void *, Eina_Bool, unsigned int);
25         void  (*end_op)( void *, Eina_Bool, unsigned int);
26         unsigned int shared_cnt;
27         void  *user_data;
28 };
29
30 static Evas_Object *_create_block_rect(Evas_Object *parent)
31 {
32         Evas_Object* rect;      
33         Evas_Coord w, h;
34
35         rect = evas_object_rectangle_add(evas_object_evas_get(parent));
36         evas_output_size_get(evas_object_evas_get(parent), &w, &h);
37         evas_object_resize(rect, w, h); 
38         evas_object_color_set(rect, 0, 0, 0, 0);
39         return rect;
40 }
41
42 static void _transit_animate_cb(void *data, Elm_Animator *animator, double frame)
43 {
44         Eina_List *elist;
45         Elm_Effect *effect;
46         Elm_Transit *transit = data;
47
48         EINA_LIST_FOREACH(transit->effect_list, elist, effect) 
49         {
50                 effect->animation_op(effect->user_data, animator, frame);
51         }
52 }
53
54 static void _transit_fx_begin(Elm_Transit *transit)
55 {
56         Eina_List *elist;
57         Elm_Effect *effect;
58         Eina_Bool auto_reverse;
59         unsigned int repeat_cnt;
60
61         auto_reverse = elm_animator_auto_reverse_get(transit->animator);
62         repeat_cnt  = elm_animator_repeat_get(transit->animator); 
63
64         EINA_LIST_FOREACH(transit->effect_list, elist, effect) 
65         {
66                 if(effect->begin_op) 
67                         effect->begin_op(effect->user_data, auto_reverse, repeat_cnt);
68         }
69 }
70
71 static void _transit_fx_end(Elm_Transit *transit)
72 {
73         Eina_List *elist;
74         Elm_Effect *effect;
75         Eina_Bool auto_reverse;
76         unsigned int repeat_cnt;
77
78         auto_reverse = elm_animator_auto_reverse_get(transit->animator);
79         repeat_cnt = elm_animator_repeat_get(transit->animator); 
80
81         EINA_LIST_FOREACH(transit->effect_list, elist, effect) 
82         {
83                 if(effect->end_op) 
84                         effect->end_op(effect->user_data, auto_reverse, repeat_cnt);
85         }
86 }
87
88 static void _transit_complete_cb(void *data)
89 {
90         Elm_Transit *transit = (Elm_Transit *) data;            
91
92         evas_render(evas_object_evas_get(transit->parent));
93
94         _transit_fx_end(transit);
95
96         if(transit->block_rect) 
97                 evas_object_hide(transit->block_rect);
98
99         if(transit->completion_op) 
100                 transit->completion_op(transit->completion_arg, transit);
101
102         if(transit->reserved_del)
103         {
104                 transit->reserved_del = EINA_FALSE;
105                 elm_transit_del(transit);
106         }
107 }
108
109 static void _transit_fx_del(Elm_Effect *effect)
110 {
111         if(!effect) return;
112         
113         --effect->shared_cnt;
114
115         if(effect->shared_cnt > 0) return;
116         if(effect->user_data) free(effect->user_data);
117         free(effect);
118 }
119
120 /**
121  * @ingroup Transit 
122  *
123  * Set the event block when the transit is operating.  
124  *
125  * @param transit       Transit object
126  * @param disable       Disable or enable
127  */
128 EAPI void elm_transit_event_block_disabled_set(Elm_Transit *transit, Eina_Bool disable)
129 {
130         if(!transit) return;
131
132         if(disable) 
133         {
134                 if(transit->block_rect) 
135                 {
136                         evas_object_del(transit->block_rect);
137                         transit->block_rect = NULL;
138                 }
139         }else 
140         {
141                 if(transit->block_rect == NULL) 
142                         transit->block_rect = _create_block_rect(transit->parent);
143         }
144 }
145
146 /**
147  * @ingroup Transit 
148  *
149  * Get the event block setting status.  
150  *
151  * @param  transit      Transit object
152  * @return              EINA_TRUE when the event block is disabled
153  */
154 EAPI Eina_Bool elm_transit_event_block_disabled_get(Elm_Transit *transit)
155 {
156         if(!transit) return EINA_FALSE;
157         return transit->block_rect ? EINA_TRUE : EINA_FALSE;
158 }
159
160 /**
161  * @ingroup Transit 
162  *
163  * Remove effect from transit.  
164  *
165  * @param  transit      Transit object
166  * @param  effect       effect that should be removed
167  * @return  EINA_TRUE, if the effect is removed
168  * @warning  If the effect is not inserted in any transit, it will be deleted
169  */
170 EAPI Eina_Bool elm_transit_fx_remove(Elm_Transit *transit, Elm_Effect *effect)
171 {
172         Eina_List *elist;
173         Elm_Effect *_effect;
174
175         if(!transit) return EINA_FALSE;
176
177         EINA_LIST_FOREACH(transit->effect_list, elist, _effect) 
178         {
179                 if(_effect == effect) 
180                 {
181                         transit->effect_list = eina_list_remove(transit->effect_list, _effect);
182                         _transit_fx_del(_effect);       
183                         return EINA_TRUE;
184                 }
185         }
186         return EINA_FALSE;
187 }
188
189 /**
190  * @ingroup Transit 
191  *
192  * Remove all current inseted effects. 
193  *
194  * @param  transit      Transit object 
195  */
196 EAPI void elm_transit_fx_clear(Elm_Transit *transit)
197 {
198         Eina_List *elist;
199         Elm_Effect *effect;
200
201         if(!transit) return;
202
203         EINA_LIST_FOREACH(transit->effect_list, elist, effect) 
204         {
205                 transit->effect_list = eina_list_remove(transit->effect_list, effect);
206                 _transit_fx_del(effect);        
207         }
208 }
209
210 /**
211  * @ingroup Transit 
212  *
213  * Remove all current inseted effects. 
214  *
215  * @param  transit      Transit object 
216  * @return              Effect list 
217  */
218 EAPI const Eina_List *elm_transit_fx_get(Elm_Transit *transit)
219 {
220         if(!transit) return NULL;
221         return transit->effect_list;
222 }
223
224 /**
225  * @ingroup Transit 
226  *
227  * Set the user-callback function when the transit is done. 
228  *
229  * @param  transit      Transit object
230  * @param  op           Callback function pointer
231  * @param  data         Callback funtion user argument
232  */
233 EAPI void elm_transit_completion_callback_set(Elm_Transit *transit, void (*op)(void *data, Elm_Transit* transit), void *data)
234 {
235         if(!transit) return;
236         transit->completion_op = op;
237         transit->completion_arg = data;
238 }
239
240 /**
241  * @ingroup Transit 
242  *
243  * Delete transit object. 
244  *
245  * @param  transit      Transit object
246  */
247 EAPI void elm_transit_del(Elm_Transit *transit)
248 {
249         if(!transit) return;
250         if(elm_animator_operating_get(transit->animator)) 
251         {
252                 transit->reserved_del = EINA_TRUE;
253                 return ;
254         }
255
256         if(transit->block_rect) 
257                 evas_object_del( transit->block_rect );
258
259         elm_animator_del(transit->animator);
260         elm_transit_fx_clear(transit);
261
262         free(transit);
263 }
264
265
266
267 /**
268  * @ingroup Transit 
269  *
270  * Set the animation acceleration style. 
271  *
272  * @param  transit      Transit object
273  * @param  cs           Curve style
274  */
275 EAPI void elm_transit_curve_style_set(Elm_Transit* transit, Elm_Animator_Curve_Style cs)
276 {
277         if(!transit) return;
278         elm_animator_curve_style_set(transit->animator, cs);
279 }
280
281
282
283
284 /**
285  * @ingroup Transit 
286  *
287  * Add a new transit. 
288  *
289  * @param  parent       Given canvas of parent object will be blocked
290  * @return              Transit object 
291  */
292 EAPI Elm_Transit *elm_transit_add(Evas_Object *parent) 
293 {
294         Elm_Transit *transit = calloc(1, sizeof(Elm_Transit)); 
295
296         if(!transit) return NULL;
297
298         transit->animator = elm_animator_add(parent);
299
300         if(!transit->animator) 
301         { 
302                 free(transit);
303                 return NULL;
304         }
305
306         transit->parent = parent;
307         elm_animator_operation_callback_set(transit->animator, _transit_animate_cb, transit);
308         elm_animator_completion_callback_set(transit->animator, _transit_complete_cb, transit);
309         elm_transit_event_block_disabled_set(transit, EINA_FALSE);
310
311         return transit;
312 }
313
314 /**
315  * @ingroup Transit 
316  *
317  * Set auto reverse function.  
318  *
319  * @param  transit       Transit object  
320  * @param  reverse       Reverse or not
321  */
322 EAPI void elm_transit_auto_reverse_set(Elm_Transit *transit, Eina_Bool reverse)
323 {
324         if(!transit) return;
325         elm_animator_auto_reverse_set(transit->animator, reverse);
326 }
327
328 /**
329  * @ingroup Transit 
330  *
331  * Insert an effect in given transit. 
332  *
333  * @param  transit       Transit object.  
334  * @param  effect        Effect
335  * @return               EINA_TRUE is success
336  */
337 EAPI Eina_Bool elm_transit_fx_insert(Elm_Transit *transit, Elm_Effect *effect)
338 {
339         Eina_List *elist;
340         Elm_Effect *_effect;
341
342         if(!transit) return EINA_FALSE;
343
344         EINA_LIST_FOREACH(transit->effect_list, elist, _effect) 
345         {
346                 if(_effect == effect) return EINA_FALSE;
347         }
348
349         ++effect->shared_cnt;
350         transit->effect_list = eina_list_append(transit->effect_list, effect);
351
352         return EINA_TRUE;
353 }
354
355 /**
356  * @ingroup Transit 
357  *
358  * Set the transit repeat count. Effect will be repeated by repeat count.
359  *
360  * @param  transit       Transit object 
361  * @param  repeat        Repeat count 
362  */
363 EAPI void elm_transit_repeat_set(Elm_Transit *transit, unsigned int repeat)
364 {
365         if(!transit) return;
366         elm_animator_repeat_set(transit->animator, repeat);     
367 }
368
369 /**
370  * @ingroup Transit 
371  *
372  * Stop the current transit effect if transit is operating. 
373  *
374  * @param  transit       Transit object 
375  */
376 EAPI void elm_transit_stop(Elm_Transit *transit)
377 {
378         if(!transit) return;
379         elm_animator_stop(transit->animator);
380 }
381
382 /**
383  * @ingroup Transit 
384  *
385  * Run the all the inserted effects.  
386  *
387  * @param  transit       Transit object 
388  * @param  duration      Transit time in second
389  */
390 EAPI void elm_transit_run(Elm_Transit *transit, double duration)
391 {
392         if(!transit) return;
393         _transit_fx_begin(transit);
394         elm_animator_duration_set(transit->animator, duration);
395
396         //Block to Top
397         if(transit->block_rect) 
398                 evas_object_show(transit->block_rect);
399
400         elm_animator_animate(transit->animator);        
401
402         //If failed to animate.  
403         if(!elm_animator_operating_get(transit->animator)) 
404         {
405                 if(transit->block_rect) 
406                         evas_object_hide(transit->block_rect);
407                 _transit_fx_end(transit);       
408         }
409 }
410
411 /////////////////////////////////////////////////////////////////////////////////////
412 //Resizing FX
413 /////////////////////////////////////////////////////////////////////////////////////
414 typedef struct _resizing Elm_Fx_Resizing;
415 static void _elm_fx_resizing_op(void *data, Elm_Animator *animator, double frame);
416
417 struct _resizing 
418 {
419         Evas_Object *obj;
420         struct _size 
421         { 
422                  Evas_Coord w, h;
423         }from, to;
424 };
425
426 static void _elm_fx_resizing_begin(void* data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
427 {
428         Elm_Fx_Resizing *resizing = data;
429         evas_object_show(resizing->obj);
430         evas_object_resize(resizing->obj, resizing->from.w, resizing->from.h);
431 }
432
433 static void _elm_fx_resizing_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
434 {
435         Elm_Fx_Resizing *resizing = data;
436         evas_object_move(resizing->obj, resizing->from.w + resizing->to.w, resizing->from.h + resizing->to.h);
437 }
438
439 static void _elm_fx_resizing_op(void *data, Elm_Animator *animator, double frame)
440 {
441         Evas_Coord w, h;
442         Elm_Fx_Resizing *resizing = data;
443         w = resizing->from.w + (Evas_Coord)((float) resizing->to.h * (float) frame);
444         h = resizing->from.h + (Evas_Coord)((float) resizing->to.w * (float) frame);
445         evas_object_resize(resizing->obj, w, h);
446 }
447
448 /**
449  * @ingroup Transit 
450  *
451  * Add resizing effect.  
452  *
453  * @param  obj           Evas_Object that effect is applying to
454  * @param  from_w        Width size when effect begin
455  * @param  from_h        Height size whene effect begin
456  * @param  to_w          Width size to be 
457  * @param  to_h          Height size to be
458  * @return               Resizing effect 
459  */
460 EAPI Elm_Effect *elm_fx_resizing_add(Evas_Object* obj, Evas_Coord from_w, Evas_Coord from_h, Evas_Coord to_w, Evas_Coord to_h)
461 {
462         Elm_Effect *effect; 
463         Elm_Fx_Resizing *resizing;
464         if(!obj) return NULL;
465
466         effect = calloc(1, sizeof(Elm_Effect));
467         if(!effect) return NULL;
468         
469         resizing = calloc(1, sizeof(Elm_Fx_Resizing));
470         if(!resizing) 
471         {
472                 free(effect);
473                 return NULL;
474         }
475
476         resizing->obj = obj;
477         resizing->from.w = from_w;
478         resizing->from.h = from_h;
479         resizing->to.w = to_w - from_w;
480         resizing->to.h = to_h - from_h;
481         
482         effect->begin_op = _elm_fx_resizing_begin;
483         effect->animation_op = _elm_fx_resizing_op;
484         effect->user_data = resizing;
485
486         return effect;
487 }
488
489 /////////////////////////////////////////////////////////////////////////////////////
490 //Translation FX
491 /////////////////////////////////////////////////////////////////////////////////////
492 typedef struct _translation Elm_Fx_Translation;
493 static void _elm_fx_translation_op(void *data, Elm_Animator *animator, double frame);
494
495 struct _translation 
496 {
497         Evas_Object *obj;
498         struct _point 
499         { 
500                  Evas_Coord x, y;
501         }from, to;
502 };
503
504 static void _elm_fx_translation_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
505 {
506         Elm_Fx_Translation *translation = data;
507         evas_object_show(translation->obj);
508         evas_object_move(translation->obj, translation->from.x, translation->from.y);
509 }
510
511 static void _elm_fx_translation_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
512 {
513         Elm_Fx_Translation *translation = data;
514         evas_object_move(translation->obj, translation->from.x + translation->to.x, translation->from.y + translation->to.y);
515 }
516
517 static void _elm_fx_translation_op(void *data, Elm_Animator *animator, double frame)
518 {
519         Evas_Coord x, y;
520         Elm_Fx_Translation *translation = data;
521         x = translation->from.x + (Evas_Coord)((float) translation->to.x * (float) frame);
522         y = translation->from.y + (Evas_Coord)((float) translation->to.y * (float) frame);
523         evas_object_move(translation->obj, x, y);
524 }
525
526 /**
527  * @ingroup Transit 
528  *
529  * Add translation effect.  
530  *
531  * @param  obj           Evas_Object that effect is applying to
532  * @param  from_x        Position X when effect begin
533  * @param  from_y        Position Y whene effect begin
534  * @param  to_x          Position X to be 
535  * @param  to_y          Position Y to be
536  * @return               Translation effect 
537  */
538 EAPI Elm_Effect *elm_fx_translation_add(Evas_Object *obj, Evas_Coord from_x, Evas_Coord from_y, Evas_Coord to_x, Evas_Coord to_y)
539 {
540         Elm_Effect *effect;
541         Elm_Fx_Translation *translation;
542                   
543         if(!obj) return NULL;
544         
545         effect = calloc(1, sizeof(Elm_Effect));
546         if(!effect) return NULL;
547         
548         translation = calloc(1, sizeof(Elm_Fx_Translation));
549
550         if(!translation) 
551         {
552                 free(effect);
553                 return NULL;
554         }
555
556         translation->obj = obj;
557         translation->from.x = from_x;
558         translation->from.y = from_y;
559         translation->to.x = to_x - from_x;
560         translation->to.y = to_y - from_y;
561         
562         effect->begin_op = _elm_fx_translation_begin;
563         effect->end_op = _elm_fx_translation_end;
564         effect->animation_op = _elm_fx_translation_op;
565         effect->user_data = translation;
566
567         return effect;
568 }
569
570 /////////////////////////////////////////////////////////////////////////////////////
571 //Zoom FX
572 /////////////////////////////////////////////////////////////////////////////////////
573 typedef struct _zoom Elm_Fx_Zoom;
574 static void _elm_fx_zoom_op(void *data, Elm_Animator *animator, double frame);
575 struct _zoom 
576 {
577         Evas_Object *obj;
578         float from, to;
579 };
580
581 static void _elm_fx_zoom_begin(void *data, Eina_Bool reverse, unsigned int repeat)
582 {
583         Elm_Fx_Zoom *zoom = data;
584         evas_object_show(zoom->obj);
585         _elm_fx_zoom_op(data, NULL, 0);
586 }
587
588 static void _elm_fx_zoom_end(void *data, Eina_Bool reverse, unsigned int repeat)
589 {
590         Elm_Fx_Zoom *zoom = data;
591         evas_object_map_enable_set(zoom->obj, EINA_FALSE);
592 }
593
594 static void _elm_fx_zoom_op(void *data, Elm_Animator *animator, double frame)
595 {
596         Elm_Fx_Zoom *zoom;
597         Evas_Map *map;
598         Evas_Coord x, y, w, h;
599
600         map = evas_map_new(4);
601         if(!map) return ;
602
603         zoom = data;
604         evas_object_geometry_get(zoom->obj, &x, &y, &w, &h);
605         evas_map_smooth_set(map, EINA_TRUE);
606         evas_map_util_points_populate_from_object_full(map, zoom->obj, zoom->from + (frame * zoom->to));
607         evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, 10000);
608         evas_object_map_set(zoom->obj, map);
609         evas_object_map_enable_set(zoom->obj, EINA_TRUE);
610         evas_map_free(map);
611 }
612
613 /**
614  * @ingroup Transit 
615  *
616  * Add Zoom effect.  
617  *
618  * @param  obj           Evas_Object that effect is applying to
619  * @param  from_rate     Scale rate when the effect begin (1 is current rate) 
620  * @param  to_rate       Scale rate to be 
621  * @return               Zoom effect 
622  */
623 EAPI Elm_Effect *elm_fx_zoom_add(Evas_Object *obj, float from_rate, float to_rate)
624 {
625         Elm_Effect *effect;
626         Elm_Fx_Zoom *zoom;
627
628         if(!obj) return NULL;
629
630         effect = calloc(1, sizeof(Elm_Effect));
631         if(!effect) return NULL;
632         
633         zoom = calloc(1, sizeof(Elm_Fx_Zoom));
634         if(!zoom) 
635         {
636                 free(effect);
637                 return NULL;
638         }
639
640         zoom->obj = obj;
641         zoom->from = (10000 - (from_rate * 10000)) * (1 / from_rate);
642         zoom->to = ((10000 - (to_rate * 10000)) * (1 / to_rate)) - zoom->from;
643         effect->begin_op = _elm_fx_zoom_begin;
644         effect->end_op = _elm_fx_zoom_end;
645         effect->animation_op = _elm_fx_zoom_op;
646         effect->user_data = zoom;
647
648         return effect;
649
650 }
651
652 /////////////////////////////////////////////////////////////////////////////////////
653 //Flip FX
654 /////////////////////////////////////////////////////////////////////////////////////
655 typedef struct _flip Elm_Fx_Flip;
656
657 struct _flip 
658 {
659         Evas_Object      *front;
660         Evas_Object      *back;
661         Elm_Fx_Flip_Axis  axis;                 
662         Eina_Bool         cw : 1;
663 };
664
665 static void _elm_fx_flip_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
666 {
667         Elm_Fx_Flip *flip = data;
668         evas_object_map_enable_set(flip->front, EINA_FALSE);
669         evas_object_map_enable_set(flip->back, EINA_FALSE);
670 }
671
672 static void _elm_fx_flip_op(void *data, Elm_Animator *animator, double frame)
673 {
674         Elm_Fx_Flip *flip;
675         Evas_Map *map;
676         float degree;
677         Evas_Object* obj;
678         Evas_Coord x, y, w, h;
679
680         map = evas_map_new(4);
681         if(!map) return ;
682
683         flip = data;
684         
685         if(flip->cw) degree = (float) (frame * 180);
686         else degree = (float) (frame * -180);
687         
688         if(degree < 90 && degree > -90) 
689         {
690                 obj = flip->front;
691                 evas_object_hide(flip->back);
692                 evas_object_show(flip->front);
693         }
694         else 
695         {
696                 obj = flip->back;
697                 evas_object_hide(flip->front);
698                 evas_object_show(flip->back);
699         }
700         
701         evas_map_smooth_set(map, EINA_TRUE);
702         evas_map_util_points_populate_from_object_full(map, obj, 0);
703         evas_object_geometry_get(obj, &x, &y, &w, &h);
704         Evas_Coord half_w =(w / 2);
705         Evas_Coord half_h =(h / 2);
706
707         if(flip->axis == ELM_FX_FLIP_AXIS_Y) 
708         {
709                 if((degree >= 90)||(degree <= -90))
710                 {
711                         evas_map_point_image_uv_set(map, 0, w, 0);
712                         evas_map_point_image_uv_set(map, 1, 0, 0);
713                         evas_map_point_image_uv_set(map, 2, 0, h);
714                         evas_map_point_image_uv_set(map, 3, w, h);
715                 }
716                 evas_map_util_3d_rotate(map, 0, degree, 0, x + half_w, y + half_h, 0);
717         }else {
718                 if((degree >= 90)||(degree <= -90)) 
719                 {
720                         evas_map_point_image_uv_set(map, 0, 0, h);
721                         evas_map_point_image_uv_set(map, 1, w, h);
722                         evas_map_point_image_uv_set(map, 2, w, 0);
723                         evas_map_point_image_uv_set(map, 3, 0, 0);
724                 }
725                 evas_map_util_3d_rotate(map, degree, 0, 0, x + half_w, y + half_h, 0);
726         }
727         evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, 10000);
728         evas_object_map_enable_set(flip->front, EINA_TRUE);
729         evas_object_map_enable_set(flip->back, EINA_TRUE);
730         evas_object_map_set(obj, map);
731         evas_map_free(map);
732 }
733
734 /**
735  * @ingroup Transit 
736  *
737  * Add Flip effect.  
738  *
739  * @param  front         Front surface object 
740  * @param  back          Back surface object
741  * @param  axis          Flipping Axis. X or Y  
742  * @param  cw            Flipping Direction. EINA_TRUE is clock-wise 
743  * @return               Flip effect 
744  */
745 EAPI Elm_Effect *elm_fx_flip_add(Evas_Object *front, Evas_Object *back, Elm_Fx_Flip_Axis axis, Eina_Bool cw)
746 {
747         Elm_Effect* effect;
748         Elm_Fx_Flip *flip;
749
750         if((!front)||(!back)) return NULL;
751
752         effect = calloc(1, sizeof(Elm_Effect));
753         if(!effect) return NULL;
754         
755         flip = calloc(1, sizeof(Elm_Fx_Flip));
756
757         if(!flip) 
758         {
759                 free(effect);
760                 return NULL;
761         }
762
763         flip->front = front;
764         flip->back = back;
765         flip->cw = cw;
766         flip->axis = axis;
767         effect->end_op = _elm_fx_flip_end;
768         effect->animation_op = _elm_fx_flip_op;
769         effect->user_data = flip;
770
771         return effect;
772 }
773
774 /////////////////////////////////////////////////////////////////////////////////////
775 //ResizableFlip FX
776 /////////////////////////////////////////////////////////////////////////////////////
777 typedef struct _resizable_flip Elm_Fx_ResizableFlip;
778 static void _elm_fx_resizable_flip_op(void *data, Elm_Animator *animator, double frame);
779
780 struct _resizable_flip 
781 {
782         Evas_Object      *front;
783         Evas_Object      *back;
784         Elm_Fx_Flip_Axis  axis;         
785         struct _vector2d 
786         {
787                 float x, y;
788         } from_pos, from_size, to_pos, to_size;
789         Eina_Bool         cw : 1;
790 };
791
792 static void _elm_fx_resizable_flip_begin(void *data, Eina_Bool reverse, unsigned int repeat)
793 {
794         Elm_Fx_ResizableFlip *resizable_flip = data;
795         evas_object_show(resizable_flip->front);
796         _elm_fx_resizable_flip_op(data, NULL, 0);
797 }
798
799 static void _elm_fx_resizable_flip_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
800 {
801         Elm_Fx_ResizableFlip *resizable_flip = data;
802         evas_object_map_enable_set(resizable_flip->front, EINA_FALSE);
803         evas_object_map_enable_set(resizable_flip->back, EINA_FALSE);
804 }
805
806 static void _set_image_uv_by_axis_y(Evas_Map *map, Elm_Fx_ResizableFlip *flip, float degree)
807 {
808         if((degree >= 90)||(degree <= -90)) 
809         {
810                 evas_map_point_image_uv_set(map, 0, (flip->from_size.x * 2) + flip->to_size.x, 0);
811                 evas_map_point_image_uv_set(map, 1, 0, 0);
812                 evas_map_point_image_uv_set(map, 2, 0, (flip->from_size.y * 2) + flip->to_size.y);
813                 evas_map_point_image_uv_set(map, 3, (flip->from_size.x * 2) + flip->to_size.x, (flip->from_size.y * 2) + flip->to_size.y);
814         }
815         else 
816         {
817                 evas_map_point_image_uv_set(map, 0, 0, 0);
818                 evas_map_point_image_uv_set(map, 1, flip->from_size.x, 0);
819                 evas_map_point_image_uv_set(map, 2, flip->from_size.x, flip->from_size.y);
820                 evas_map_point_image_uv_set(map, 3, 0, flip->to_size.y);
821         }
822 }
823
824 static void _set_image_uv_by_axis_x(Evas_Map *map, Elm_Fx_ResizableFlip *flip, float degree)
825 {
826         if((degree >= 90)||(degree <= -90)) 
827         {
828                 evas_map_point_image_uv_set(map, 0, 0, (flip->from_size.y * 2) + flip->to_size.y);
829                 evas_map_point_image_uv_set(map, 1, (flip->from_size.x * 2) + flip->to_size.x, (flip->from_size.y * 2) + flip->to_size.y);
830                 evas_map_point_image_uv_set(map, 2, (flip->from_size.x * 2) + flip->to_size.x, 0);
831                 evas_map_point_image_uv_set(map, 3, 0, 0);
832         }else 
833         {
834                 evas_map_point_image_uv_set(map, 0, 0, 0);
835                 evas_map_point_image_uv_set(map, 1, flip->from_size.x, 0);
836                 evas_map_point_image_uv_set(map, 2, flip->from_size.x, flip->from_size.y);
837                 evas_map_point_image_uv_set(map, 3, 0, flip->to_size.y);
838         }
839 }
840
841 static void _elm_fx_resizable_flip_op(void *data, Elm_Animator *animator, double frame)
842 {
843         Elm_Fx_ResizableFlip *resizable_flip;
844         Evas_Map *map;
845         float degree;
846         Evas_Object* obj;
847         float x, y, w, h;
848         Evas_Coord half_w, half_h;
849
850         map = evas_map_new(4);
851         if(!map) return;
852
853         resizable_flip = data;
854
855         if(resizable_flip->cw) degree = (float) (frame * 180);
856         else degree = (float) (frame * -180);
857         
858         if((degree < 90) && (degree > -90)) 
859         {
860                 obj = resizable_flip->front;
861                 evas_object_hide(resizable_flip->back);
862                 evas_object_show(resizable_flip->front);
863         }
864         else 
865         {
866                 obj = resizable_flip->back;
867                 evas_object_hide(resizable_flip->front);
868                 evas_object_show(resizable_flip->back);
869         }
870         
871         evas_map_smooth_set(map, EINA_TRUE);
872
873         x = resizable_flip->from_pos.x + (resizable_flip->to_pos.x * frame); 
874         y = resizable_flip->from_pos.y + (resizable_flip->to_pos.y * frame);
875         w = resizable_flip->from_size.x + (resizable_flip->to_size.x * frame);
876         h = resizable_flip->from_size.y + (resizable_flip->to_size.y * frame);
877         evas_map_point_coord_set(map, 0, x, y, 0); 
878         evas_map_point_coord_set(map, 1, x + w, y, 0);
879         evas_map_point_coord_set(map, 2, x + w, y + h, 0);
880         evas_map_point_coord_set(map, 3, x, y + h, 0);
881
882         half_w = (Evas_Coord) (w / 2);
883         half_h = (Evas_Coord) (h / 2);
884
885         if(resizable_flip->axis == ELM_FX_FLIP_AXIS_Y) 
886         {
887                 _set_image_uv_by_axis_y(map, resizable_flip, degree);
888                 evas_map_util_3d_rotate(map, 0, degree, 0, x + half_w, y + half_h, 0);
889         }
890         else 
891         {
892                 _set_image_uv_by_axis_x(map, resizable_flip, degree);
893                 evas_map_util_3d_rotate(map, degree, 0, 0, x + half_w, y + half_h, 0);
894         }
895
896         evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, 10000);
897         evas_object_map_enable_set(resizable_flip->front, EINA_TRUE);
898         evas_object_map_enable_set(resizable_flip->back, EINA_TRUE);
899         evas_object_map_set(obj, map);
900         evas_map_free(map);
901 }
902
903 /**
904  * @ingroup Transit 
905  *
906  * Add ResizbleFlip effect.  
907  *
908  * @param  front         Front surface object 
909  * @param  back          Back surface object
910  * @param  axis          Flipping Axis. X or Y  
911  * @param  cw            Flipping Direction. EINA_TRUE is clock-wise
912  * @return               Flip effect 
913  */
914 EAPI Elm_Effect *elm_fx_resizable_flip_add(Evas_Object *front, Evas_Object *back, Elm_Fx_Flip_Axis axis, Eina_Bool cw)
915 {
916         Elm_Fx_ResizableFlip *resizable_flip;
917         Elm_Effect *effect;
918         Evas_Coord front_x, front_y, front_w, front_h;
919         Evas_Coord back_x, back_y, back_w, back_h;
920
921         if(!front||!back) return NULL;
922
923         effect = calloc(1, sizeof(Elm_Effect));
924         if(!effect) return NULL;
925         
926         resizable_flip = calloc(1, sizeof(Elm_Fx_ResizableFlip));
927         
928         if(!resizable_flip) 
929         {
930                 free(effect);
931                 return NULL;
932         }
933
934         resizable_flip->front = front;
935         resizable_flip->back = back;
936         resizable_flip->cw = cw;
937         resizable_flip->axis = axis;
938         
939         evas_object_geometry_get( resizable_flip->front, &front_x, &front_y, &front_w, &front_h );
940         evas_object_geometry_get( resizable_flip->back, &back_x, &back_y, &back_w, &back_h );
941
942         resizable_flip->from_pos.x = front_x;
943         resizable_flip->from_pos.y = front_y;
944         resizable_flip->to_pos.x = back_x - front_x;
945         resizable_flip->to_pos.y = back_y - front_y;
946
947         resizable_flip->from_size.x = front_w;
948         resizable_flip->from_size.y = front_h;
949         resizable_flip->to_size.x = back_w - front_w;
950         resizable_flip->to_size.y = back_h - front_h;
951
952         effect->begin_op = _elm_fx_resizable_flip_begin;
953         effect->end_op = _elm_fx_resizable_flip_end;
954         effect->animation_op = _elm_fx_resizable_flip_op;
955         effect->user_data = resizable_flip;
956
957         return effect;
958 }
959
960 /////////////////////////////////////////////////////////////////////////////////////
961 //Wipe FX
962 /////////////////////////////////////////////////////////////////////////////////////
963 typedef struct _wipe Elm_Fx_Wipe;
964 static void _elm_fx_wipe_op(void *data, Elm_Animator *animator, double frame);
965
966 struct _wipe 
967 {
968         Evas_Object *obj;
969         Elm_Fx_Wipe_Type type;
970         Elm_Fx_Wipe_Dir dir;
971 };
972
973 static void _elm_fx_wipe_begin(void *data, Eina_Bool auto_repeat, unsigned int repeat_cnt) 
974 {
975         Elm_Fx_Wipe *wipe = data;
976         evas_object_show(wipe->obj);
977         _elm_fx_wipe_op(data, NULL, 0);
978 }
979
980 static void _elm_fx_wipe_end(void *data, Eina_Bool auto_repeat, unsigned int repeat_cnt) 
981 {
982         Elm_Fx_Wipe *wipe = data;
983         evas_object_map_enable_set(wipe->obj, EINA_FALSE);
984 }
985
986 static void _elm_fx_wipe_hide(Evas_Map *map, Elm_Fx_Wipe_Dir dir, float x, float y, float w, float h, float frame)
987 {
988         float w2, h2;
989
990         switch(dir) 
991         {
992                 case ELM_FX_WIPE_DIR_LEFT:                      
993                         w2 = w - (w * frame);
994                         h2 = (y + h);
995                         evas_map_point_image_uv_set(map, 0, 0, 0);
996                         evas_map_point_image_uv_set(map, 1, w2, 0);
997                         evas_map_point_image_uv_set(map, 2, w2, h);
998                         evas_map_point_image_uv_set(map, 3, 0, h);
999                         evas_map_point_coord_set(map, 0, x, y, 0);
1000                         evas_map_point_coord_set(map, 1, x + w2, y, 0);
1001                         evas_map_point_coord_set(map, 2, x + w2, h2, 0);
1002                         evas_map_point_coord_set(map, 3, x, h2, 0);
1003                         break;
1004                 case ELM_FX_WIPE_DIR_RIGHT:
1005                         w2 = (w * frame);
1006                         h2 = (y + h);
1007                         evas_map_point_image_uv_set(map, 0, w2, 0);
1008                         evas_map_point_image_uv_set(map, 1, w, 0);
1009                         evas_map_point_image_uv_set(map, 2, w, h);
1010                         evas_map_point_image_uv_set(map, 3, w2, h);
1011                         evas_map_point_coord_set(map, 0, x + w2, y, 0);
1012                         evas_map_point_coord_set(map, 1, x + w, y, 0);
1013                         evas_map_point_coord_set(map, 2, x + w, h2, 0);
1014                         evas_map_point_coord_set(map, 3, x + w2, h2, 0);
1015                         break;
1016                 case ELM_FX_WIPE_DIR_UP:
1017                         w2 = (x + w);
1018                         h2 = h - (h * frame);
1019                         evas_map_point_image_uv_set(map, 0, 0, 0);
1020                         evas_map_point_image_uv_set(map, 1, w, 0);
1021                         evas_map_point_image_uv_set(map, 2, w, h2);
1022                         evas_map_point_image_uv_set(map, 3, 0, h2);
1023                         evas_map_point_coord_set(map, 0, x, y, 0);
1024                         evas_map_point_coord_set(map, 1, w2, y, 0);
1025                         evas_map_point_coord_set(map, 2, w2,  h2, 0);
1026                         evas_map_point_coord_set(map, 3, x, h2, 0);
1027                         break;
1028                 case ELM_FX_WIPE_DIR_DOWN:
1029                         w2 = (x + w);
1030                         h2 = (h * frame);
1031                         evas_map_point_image_uv_set(map, 0, 0, h2);
1032                         evas_map_point_image_uv_set(map, 1, w, h2);
1033                         evas_map_point_image_uv_set(map, 2, w, h);
1034                         evas_map_point_image_uv_set(map, 3, 0, h);
1035                         evas_map_point_coord_set(map, 0, x, y + h2, 0);
1036                         evas_map_point_coord_set(map, 1, w2, y + h2, 0 );
1037                         evas_map_point_coord_set(map, 2, w2, y + h, 0);
1038                         evas_map_point_coord_set(map, 3, x, y + h, 0);
1039                         break;
1040                 default:
1041                         break;
1042         }
1043
1044         evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, 10000);
1045 }
1046
1047
1048 static void _elm_fx_wipe_show(Evas_Map *map, Elm_Fx_Wipe_Dir dir, float x, float y, float w, float h, float frame)
1049 {
1050         float w2, h2;
1051
1052         switch( dir ) 
1053         {
1054                 case ELM_FX_WIPE_DIR_LEFT:                      
1055                         w2 = (w - (w * frame));
1056                         h2 = (y + h);
1057                         evas_map_point_image_uv_set(map, 0, w2, 0);
1058                         evas_map_point_image_uv_set(map, 1, w, 0);
1059                         evas_map_point_image_uv_set(map, 2, w, h);
1060                         evas_map_point_image_uv_set(map, 3, w2, h);
1061                         evas_map_point_coord_set(map, 0, x + w2, y, 0);
1062                         evas_map_point_coord_set(map, 1, w, y, 0);
1063                         evas_map_point_coord_set(map, 2, w, h2, 0);
1064                         evas_map_point_coord_set(map, 3, x + w2, h2, 0);
1065                         break;
1066                 case ELM_FX_WIPE_DIR_RIGHT:
1067                         w2 = (w * frame);
1068                         h2 = (y + h);
1069                         evas_map_point_image_uv_set(map, 0, 0, 0);
1070                         evas_map_point_image_uv_set(map, 1, w2, 0);
1071                         evas_map_point_image_uv_set(map, 2, w2, h);
1072                         evas_map_point_image_uv_set(map, 3, 0, h);
1073                         evas_map_point_coord_set(map, 0, x, y, 0);
1074                         evas_map_point_coord_set(map, 1, x + w2, y, 0);
1075                         evas_map_point_coord_set(map, 2, x + w2, h2, 0);
1076                         evas_map_point_coord_set(map, 3, x, h2, 0);
1077                         break;
1078                 case ELM_FX_WIPE_DIR_UP:
1079                         w2 = (x + w);
1080                         h2 = (h - (h * frame));
1081                         evas_map_point_image_uv_set(map, 0, 0, h2);
1082                         evas_map_point_image_uv_set(map, 1, w, h2);
1083                         evas_map_point_image_uv_set(map, 2, w, h);
1084                         evas_map_point_image_uv_set(map, 3, 0, h);
1085                         evas_map_point_coord_set(map, 0, x, y + h2, 0);
1086                         evas_map_point_coord_set(map, 1, w2, y + h2, 0);
1087                         evas_map_point_coord_set(map, 2, w2, y + h, 0);
1088                         evas_map_point_coord_set(map, 3, x, y + h, 0);
1089                         break;
1090                 case ELM_FX_WIPE_DIR_DOWN:
1091                         w2 = (x + w);
1092                         h2 = (h * frame);
1093                         evas_map_point_image_uv_set(map, 0, 0, 0);
1094                         evas_map_point_image_uv_set(map, 1, w, 0);
1095                         evas_map_point_image_uv_set(map, 2, w, h2);
1096                         evas_map_point_image_uv_set(map, 3, 0, h2);
1097                         evas_map_point_coord_set(map, 0, x, y, 0);
1098                         evas_map_point_coord_set(map, 1, w2, y, 0);
1099                         evas_map_point_coord_set(map, 2, w2, y + h2, 0);
1100                         evas_map_point_coord_set(map, 3, x, y + h2, 0);
1101                         break;
1102                 default:
1103                         break;
1104         }
1105
1106         evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, 10000);
1107 }
1108
1109 static void _elm_fx_wipe_op(void *data, Elm_Animator *animator, double frame)
1110 {
1111         Elm_Fx_Wipe *wipe;
1112         Evas_Map *map;
1113         Evas_Coord _x, _y, _w, _h;
1114
1115         map = evas_map_new(4);
1116         if(!map) return;
1117
1118         wipe = data;
1119         evas_map_smooth_set(map, EINA_TRUE);
1120         evas_object_geometry_get(wipe->obj, &_x, &_y, &_w, &_h);
1121
1122         if(wipe->type == ELM_FX_WIPE_TYPE_SHOW)  
1123                 _elm_fx_wipe_show(map, wipe->dir, _x, _y, _w, _h, (float) frame);
1124         else 
1125                 _elm_fx_wipe_hide(map, wipe->dir, _x, _y, _w, _h, (float) frame);
1126         
1127         evas_object_map_enable_set(wipe->obj, EINA_TRUE);
1128         evas_object_map_set(wipe->obj, map);
1129         evas_map_free(map);
1130 }
1131
1132 /**
1133  * @ingroup Transit 
1134  *
1135  * Add Wipe effect.  
1136  *
1137  * @param  obj           Evas_Object that effect is applying to
1138  * @param  type          Wipe type. Hide or show
1139  * @param  dir           Wipe Direction
1140  * @return               Wipe Effect
1141  */
1142 EAPI Elm_Effect *elm_fx_wipe_add(Evas_Object *obj, Elm_Fx_Wipe_Type type, Elm_Fx_Wipe_Dir dir)
1143 {
1144         Elm_Effect *effect;
1145         Elm_Fx_Wipe *wipe;
1146
1147         if(!obj) return NULL;
1148                   
1149         effect = calloc(1, sizeof(Elm_Effect));
1150         if(!effect) return NULL; 
1151         
1152         wipe = calloc(1, sizeof(Elm_Fx_Wipe));
1153         if(!wipe) {
1154                 free(effect);
1155                 return NULL;
1156         }
1157
1158         wipe->obj = obj;
1159         wipe->type = type;
1160         wipe->dir = dir;
1161         effect->begin_op = _elm_fx_wipe_begin;
1162         effect->end_op = _elm_fx_wipe_end;
1163         effect->animation_op = _elm_fx_wipe_op;
1164         effect->user_data = wipe;
1165
1166         return effect;
1167 }
1168
1169 /////////////////////////////////////////////////////////////////////////////////////
1170 //Color FX
1171 /////////////////////////////////////////////////////////////////////////////////////
1172 typedef struct _color Elm_Fx_Color;
1173
1174 struct _color 
1175 {
1176         Evas_Object *obj;
1177         struct _unsigned_color 
1178         {
1179                 unsigned int r, g, b, a;
1180         }from;
1181         struct _signed_color 
1182         {
1183                 int r, g, b, a;
1184         } to;
1185 };
1186
1187 static void _elm_fx_color_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1188 {
1189         Elm_Fx_Color *color = data;
1190         evas_object_show(color->obj);
1191 }
1192
1193 static void _elm_fx_color_op(void *data, Elm_Animator *animator, double frame)
1194 {
1195         Elm_Fx_Color *color;
1196         unsigned int r, g, b, a;
1197         color = data;
1198         r = (color->from.r + (int) ( (float) color->to.r * frame ));
1199         g = (color->from.g + (int) ( (float) color->to.g * frame ));
1200         b = (color->from.b + (int) ( (float) color->to.b * frame ));
1201         a = (color->from.a + (int) ( (float) color->to.a * frame ));
1202
1203         evas_object_color_set(color->obj, r, g, b, a);
1204 }
1205
1206 /**
1207  * @ingroup Transit 
1208  *
1209  * Add Color effect.  
1210  *
1211  * @param  obj           Evas_Object that effect is applying to
1212  * @param  from_r        RGB R when the effect begins
1213  * @param  from_g        RGB G when the effect begins 
1214  * @param  from_b        RGB B when the effect begins
1215  * @param  from_a        RGB A when the effect begins
1216  * @param  to_r          RGB R to be
1217  * @param  to_g          RGB G to be 
1218  * @param  to_b          RGB B to be
1219  * @param  to_a          RGB A to be 
1220  * @return               Color Effect
1221  */
1222 EAPI Elm_Effect* elm_fx_color_add(Evas_Object *obj, unsigned int from_r, unsigned int from_g, unsigned int from_b, unsigned int from_a, unsigned int to_r, unsigned int to_g, unsigned int to_b, unsigned int to_a)
1223 {
1224         Elm_Effect *effect;
1225         Elm_Fx_Color *color;
1226         if(!obj) return NULL;
1227                   
1228         effect = calloc(1, sizeof(Elm_Effect));
1229         if(!effect) return NULL; 
1230         
1231         color = calloc(1, sizeof(Elm_Fx_Color));
1232         if(!color) 
1233         {
1234                 free(effect);
1235                 return NULL;
1236         }
1237
1238         color->obj = obj;
1239         color->from.r = from_r;
1240         color->from.g = from_g;
1241         color->from.b = from_b;
1242         color->from.a = from_a;
1243         color->to.r = to_r - from_r;
1244         color->to.g = to_g - from_g;
1245         color->to.b = to_b - from_b;
1246         color->to.a = to_a - from_a;
1247
1248         effect->begin_op = _elm_fx_color_begin;
1249         effect->animation_op = _elm_fx_color_op;
1250         effect->user_data = color;
1251         
1252         return effect;
1253 }
1254
1255 /////////////////////////////////////////////////////////////////////////////////////
1256 //Fade FX
1257 /////////////////////////////////////////////////////////////////////////////////////
1258 typedef struct _fade Elm_Fx_Fade;
1259
1260 struct _fade 
1261 {
1262         Evas_Object *before;
1263         Evas_Object *after;
1264         struct _signed_color before_color, after_color;
1265         int before_alpha;
1266         int after_alpha;
1267         Eina_Bool inversed : 1;
1268 };
1269
1270 static void _elm_fx_fade_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1271 {
1272         Elm_Fx_Fade *fade = data;
1273         fade->inversed = EINA_FALSE;
1274 }
1275
1276 static void _elm_fx_fade_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1277 {
1278         Elm_Fx_Fade *fade = data;
1279         evas_object_color_set(fade->before, fade->before_color.r, fade->before_color.g, fade->before_color.b,   fade->before_color.a);
1280         evas_object_color_set(fade->after, fade->after_color.r, fade->after_color.g, fade->after_color.b, fade->after_color.a);
1281 }
1282
1283 static void _elm_fx_fade_op(void *data, Elm_Animator *animator, double frame)
1284 {
1285         Elm_Fx_Fade *fade;
1286         float _frame;
1287
1288         fade = data;
1289         
1290         if(frame < 0.5) 
1291         {
1292                 if(!fade->inversed) 
1293                 {
1294                         evas_object_hide(fade->after);
1295                         evas_object_show(fade->before);
1296                         fade->inversed = EINA_TRUE; 
1297                 }
1298
1299                 _frame = (1 - (frame * 2));
1300                 
1301                 evas_object_color_set( fade->before, fade->before_color.r * _frame, fade->before_color.g * _frame, fade->before_color.b * _frame, fade->before_color.a + fade->before_alpha * (1-_frame));
1302         }else 
1303         {
1304                 if(fade->inversed) 
1305                 {
1306                         evas_object_hide(fade->before);
1307                         evas_object_show(fade->after);
1308                         fade->inversed = EINA_FALSE; 
1309                 }
1310
1311                 _frame = ((frame - 0.5) * 2);
1312                         
1313                 evas_object_color_set(fade->after, fade->after_color.r * _frame, fade->after_color.g * _frame, fade->after_color.b * _frame, fade->after_color.a + fade->after_alpha * (1 -_frame));
1314         }
1315
1316 }
1317
1318
1319 /**
1320  * @ingroup Transit 
1321  *
1322  * Add Fade Effect  
1323  *
1324  * @param  before        Evas Object before fade in 
1325  * @param  after         Evas Object after fade out 
1326  * @return               Fade Effect
1327  */
1328 EAPI Elm_Effect *elm_fx_fade_add(Evas_Object *before, Evas_Object *after)
1329 {
1330         Elm_Effect *effect;
1331         Elm_Fx_Fade *fade;
1332                         
1333         if((!before) && (!after)) return NULL;
1334         
1335         effect = calloc(1, sizeof(Elm_Effect));
1336         if(!effect) return NULL; 
1337         
1338         fade = calloc(1, sizeof(Elm_Fx_Fade));
1339
1340         if(!fade) 
1341         { 
1342                 free(effect);
1343                 return NULL;
1344         }
1345
1346         evas_object_color_get(before, &fade->before_color.r, &fade->before_color.g, &fade->before_color.b, &fade->before_color.a);
1347         evas_object_color_get(after, &fade->after_color.r, &fade->after_color.g, &fade->after_color.b, &fade->after_color.a);
1348
1349         fade->before = before;
1350         fade->after = after;
1351         fade->before_alpha = (255 - fade->before_color.a);
1352         fade->after_alpha = (255 - fade->after_color.a);
1353
1354         effect->begin_op = _elm_fx_fade_begin;
1355         effect->end_op = _elm_fx_fade_end;
1356         effect->animation_op = _elm_fx_fade_op;
1357         effect->user_data = fade;
1358         
1359         return effect;
1360 }
1361
1362 /////////////////////////////////////////////////////////////////////////////////////
1363 //Blend FX
1364 /////////////////////////////////////////////////////////////////////////////////////
1365 typedef struct _blend Elm_Fx_Blend;
1366
1367 struct _blend 
1368 {
1369         Evas_Object *before;
1370         Evas_Object *after;
1371         struct _signed_color from, to;
1372 };
1373
1374 static void _elm_fx_blend_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1375 {
1376         Elm_Fx_Blend *blend = data;
1377         evas_object_show(blend->before);
1378 }
1379
1380 static void _elm_fx_blend_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1381 {
1382         Elm_Fx_Blend *blend = data;
1383         evas_object_color_set(blend->before, blend->from.r, blend->from.g, blend->from.b, blend->from.a);
1384         evas_object_color_set(blend->after, blend->to.r, blend->to.g, blend->to.b, blend->to.a);
1385         if(!auto_reverse) 
1386                 evas_object_hide(blend->before);
1387         else 
1388                 evas_object_hide(blend->after);
1389 }
1390
1391 static void _elm_fx_blend_op(void *data, Elm_Animator *animator, double frame)
1392 {
1393         Elm_Fx_Blend *blend = data;
1394         evas_object_show(blend->after);
1395         evas_object_color_set(blend->before, (int) (blend->from.r * (1 - frame)), (int) (blend->from.g * (1 - frame)), (int) (blend->from.b * (1 - frame)), (int) (blend->from.a * (1 - frame)));
1396         evas_object_color_set(blend->after,     (int) (blend->to.r * frame), (int) (blend->to.g * frame), (int) (blend->to.b * frame), (int) (blend->to.a * frame));
1397 }
1398
1399 /**
1400  * @ingroup Transit 
1401  *
1402  * Add Blend Effect  
1403  *
1404  * @param  before        Evas Object before blending
1405  * @param  after         Evas Object after blending 
1406  * @return               Blend Effect
1407  */
1408 EAPI Elm_Effect *elm_fx_blend_add(Evas_Object *before, Evas_Object *after)
1409 {
1410         Elm_Effect *effect;
1411         Elm_Fx_Blend *blend;
1412
1413         if((!before) && (!after)) return NULL;
1414
1415         effect = calloc(1, sizeof(Elm_Effect));
1416         if(!effect) return NULL; 
1417         
1418         blend = calloc(1, sizeof(Elm_Fx_Blend));
1419         if(!blend) 
1420         {
1421                 free( effect );
1422                 return NULL;
1423         }
1424
1425         blend->before = before;
1426         blend->after = after;
1427         evas_object_color_get(before, &blend->from.r, &blend->from.g, &blend->from.b, &blend->from.a);
1428         evas_object_color_get(after, &blend->to.r, &blend->to.g, &blend->to.b, &blend->to.a);
1429         
1430         effect->begin_op = _elm_fx_blend_begin;
1431         effect->end_op = _elm_fx_blend_end;
1432         effect->animation_op = _elm_fx_blend_op;
1433         effect->user_data = blend;
1434
1435         return effect;
1436 }
1437
1438 /////////////////////////////////////////////////////////////////////////////////////
1439 //Rotation FX
1440 /////////////////////////////////////////////////////////////////////////////////////
1441 typedef struct _rotation Elm_Fx_Rotation;
1442
1443 struct _rotation 
1444 {
1445         Evas_Object     *obj;
1446         Eina_Bool         cw;
1447         float from, to;
1448 };
1449
1450 static void _elm_fx_rotation_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1451 {
1452         Elm_Fx_Rotation *rotation = data;
1453         evas_object_show(rotation->obj);
1454 }
1455
1456 static void _elm_fx_rotation_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
1457 {
1458         Elm_Fx_Rotation *rotation = data;
1459         evas_object_map_enable_set(rotation->obj, EINA_FALSE);
1460 }
1461
1462 static void _elm_fx_rotation_op(void *data, Elm_Animator *animator, double frame)
1463 {
1464         Elm_Fx_Rotation *rotation;
1465         Evas_Map* map;
1466         Evas_Coord x, y, w, h;
1467         float degree;
1468         float half_w, half_h;
1469
1470         map = evas_map_new(4);
1471         if(!map) return;
1472
1473         rotation = data;
1474
1475         evas_map_smooth_set(map, EINA_TRUE);
1476         evas_map_util_points_populate_from_object_full(map, rotation->obj, 0);
1477         degree = rotation->from + (float) (frame * rotation->to);
1478         
1479         if(!rotation->cw) degree *= -1;
1480
1481         evas_object_geometry_get(rotation->obj, &x, &y, &w, &h);
1482
1483         half_w = (float) w * 0.5;
1484         half_h = (float) h * 0.5;
1485
1486         evas_map_util_3d_rotate(map, 0, 0, degree, x + half_w, y + half_h, 0);
1487         evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, 10000);
1488         evas_object_map_enable_set(rotation->obj, EINA_TRUE);
1489         evas_object_map_set(rotation->obj, map);
1490         evas_map_free(map);
1491 }
1492
1493 /**
1494  * @ingroup Transit 
1495  *
1496  * Add Rotation Effect
1497  *
1498  * @param  obj           Evas_Object that effect is applying to 
1499  * @param  from degree   Degree when effect begins
1500  * @param  to_degree     Degree when effect is done
1501  * @param  cw            Rotation Direction. EINA_TRUE is clock wise 
1502  * @return               Rotation effect
1503  */
1504 EAPI Elm_Effect *elm_fx_rotation_add(Evas_Object *obj, float from_degree, float to_degree, Eina_Bool cw)
1505 {
1506         Elm_Effect *effect;
1507         Elm_Fx_Rotation *rotation;
1508
1509         if(!obj) return NULL;
1510
1511         effect = calloc(1, sizeof(Elm_Effect));
1512         if(!effect) return NULL;
1513         
1514         rotation = calloc(1, sizeof(Elm_Fx_Rotation));
1515
1516         if(!rotation) 
1517         {
1518                 free(effect);
1519                 return NULL;
1520         }
1521
1522         rotation->obj = obj;
1523         rotation->from = from_degree;
1524         rotation->to = to_degree - from_degree;
1525         rotation->cw = cw;
1526
1527         effect->begin_op = _elm_fx_rotation_begin;
1528         effect->end_op = _elm_fx_rotation_end;
1529         effect->animation_op = _elm_fx_rotation_op;
1530         effect->user_data = rotation;
1531
1532         return effect;
1533 }
1534
1535
1536
1537 /////////////////////////////////////////////////////////////////////////////////////
1538 // ImageAnimation FX
1539 /////////////////////////////////////////////////////////////////////////////////////
1540 typedef struct _image_animation Elm_Fx_Image_Animation;
1541
1542 struct _image_animation 
1543 {
1544         Evas_Object *icon;
1545         char** images;
1546         int count;
1547         int item_num;
1548 };
1549
1550 static void _elm_fx_imageanimation_op(void *data, Elm_Animator *animator, double frame)
1551 {
1552         Elm_Fx_Image_Animation *image_animation = (Elm_Fx_Image_Animation *) data;
1553         if(!image_animation->icon) return;
1554         image_animation->count = floor(frame * image_animation->item_num);
1555         elm_icon_file_set(image_animation->icon, image_animation->images[image_animation->count], NULL);
1556 }
1557
1558 /**
1559  * @ingroup Transit 
1560  *
1561  * Add ImageAnimation effect.  
1562  *
1563  * @param  images        Images for animation.
1564  * @return               ImageAnimation Effect.
1565  */
1566 EAPI Elm_Effect *elm_fx_imageanimation_add(Evas_Object *icon, const char** images, unsigned int item_num)
1567 {
1568         Elm_Effect *effect;
1569         Elm_Fx_Image_Animation *image_animation;
1570
1571         if(!images || !(*images)) return NULL;
1572
1573         effect = calloc(1, sizeof(Elm_Effect));
1574         if(!effect) return NULL;
1575
1576         image_animation = calloc(1, sizeof(Elm_Fx_Image_Animation));
1577
1578         if(!image_animation) 
1579         {
1580                 free(effect);
1581                 return NULL;
1582         }
1583
1584         image_animation->icon = icon;
1585         image_animation->images = (char**) images;
1586         image_animation->count = 0;
1587         image_animation->item_num = item_num;
1588
1589         effect->animation_op = _elm_fx_imageanimation_op;
1590         effect->user_data = image_animation;
1591
1592         return effect;
1593 }
1594