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