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