Merge "[Password]: New design based changes, a new style removed password mode contro...
[framework/uifw/elementary.git] / src / lib / elm_flip.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Flip Flip
6  * @ingroup Elementary
7  *
8  * This holds 2 content objects: one on the front and one on the back. It
9  * allows you to flip from front to back and vice-versa using various effects.
10  *
11  * Supported flip types:
12  * ELM_FLIP_ROTATE_Y_CENTER_AXIS
13  * ELM_FLIP_ROTATE_X_CENTER_AXIS
14  * ELM_FLIP_ROTATE_XZ_CENTER_AXIS
15  * ELM_FLIP_ROTATE_YZ_CENTER_AXIS
16  *
17  * Signals that you can add callbacks for are:
18  *
19  * "animate,done" - when a flip animation is finished
20  */
21
22 typedef struct _Widget_Data Widget_Data;
23
24 struct _Widget_Data
25 {
26    Ecore_Animator *animator;
27    double start, len;
28    Elm_Flip_Mode mode;
29    Evas_Object *clip;
30    struct {
31         Evas_Object *content, *clip;
32    } front, back;
33    Eina_Bool state : 1;
34 };
35
36 static const char *widtype = NULL;
37 static void _del_hook(Evas_Object *obj);
38 static void _theme_hook(Evas_Object *obj);
39 static void _sizing_eval(Evas_Object *obj);
40 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
41 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
42
43 static void _configure(Evas_Object *obj);
44
45 static const char SIG_ANIMATE_DONE[] = "animate,done";
46
47 static const Evas_Smart_Cb_Description _signals[] = {
48    {SIG_ANIMATE_DONE, ""},
49    {NULL, NULL}
50 };
51
52 static void
53 _del_hook(Evas_Object *obj)
54 {
55    Widget_Data *wd = elm_widget_data_get(obj);
56    if (!wd) return;
57    if (wd->animator) ecore_animator_del(wd->animator);
58    free(wd);
59 }
60
61 static void
62 _theme_hook(Evas_Object *obj)
63 {
64    Widget_Data *wd = elm_widget_data_get(obj);
65    if (!wd) return;
66    _sizing_eval(obj);
67 }
68
69 static Eina_Bool
70 _elm_flip_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
71 {
72    Widget_Data *wd = elm_widget_data_get(obj);
73
74    if (!wd)
75      return EINA_FALSE;
76
77    /* Try Focus cycle in subitem */
78    if (wd->state)
79      return elm_widget_focus_next_get(wd->front.content, dir, next);
80    else
81      return elm_widget_focus_next_get(wd->back.content, dir, next);
82
83 }
84
85 static void
86 _sizing_eval(Evas_Object *obj)
87 {
88    Widget_Data *wd = elm_widget_data_get(obj);
89    Evas_Coord minw = -1, minh = -1, minw2 = -1, minh2 = -1;
90    Evas_Coord maxw = -1, maxh = -1, maxw2 = -1, maxh2 = -1;
91    if (!wd) return;
92    if (wd->front.content)
93      evas_object_size_hint_min_get(wd->front.content, &minw, &minh);
94    if (wd->back.content)
95      evas_object_size_hint_min_get(wd->back.content, &minw2, &minh2);
96    if (wd->front.content)
97      evas_object_size_hint_max_get(wd->front.content, &maxw, &maxh);
98    if (wd->back.content)
99      evas_object_size_hint_max_get(wd->back.content, &maxw2, &maxh2);
100
101    if (minw2 > minw) minw = minw2;
102    if (minh2 > minh) minh = minh2;
103    if ((maxw2 >= 0) && (maxw2 < maxw)) maxw = maxw2;
104    if ((maxh2 >= 0) && (maxh2 < maxh)) maxh = maxh2;
105
106    evas_object_size_hint_min_set(obj, minw, minh);
107    evas_object_size_hint_max_set(obj, maxw, maxh);
108 }
109
110 static void
111 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
112 {
113    Widget_Data *wd = elm_widget_data_get(data);
114    if (!wd) return;
115    _sizing_eval(data);
116 }
117
118 static void
119 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
120 {
121    Widget_Data *wd = elm_widget_data_get(obj);
122    Evas_Object *sub = event_info;
123    if (!wd) return;
124    if (sub == wd->front.content)
125      {
126         evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
127                                             _changed_size_hints, obj);
128         wd->front.content = NULL;
129         evas_object_hide(wd->front.clip);
130         _sizing_eval(obj);
131      }
132    else if (sub == wd->back.content)
133      {
134         evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
135                                             _changed_size_hints, obj);
136         wd->back.content = NULL;
137         evas_object_hide(wd->back.clip);
138         _sizing_eval(obj);
139      }
140 }
141
142 static void
143 flip_show_hide(Evas_Object *obj)
144 {
145    Widget_Data *wd = elm_widget_data_get(obj);
146    if (elm_flip_front_get(obj))
147      {
148         if (wd->front.content)
149           evas_object_show(wd->front.clip);
150         else
151           evas_object_hide(wd->front.clip);
152         if (wd->back.content)
153           evas_object_hide(wd->back.clip);
154         else
155           evas_object_hide(wd->back.clip);
156      }
157    else
158      {
159         if (wd->front.content)
160           evas_object_hide(wd->front.clip);
161         else
162           evas_object_hide(wd->front.clip);
163         if (wd->back.content)
164           evas_object_show(wd->back.clip);
165         else
166           evas_object_hide(wd->back.clip);
167      }
168 }
169
170 static Eina_Bool
171 _flip(Evas_Object *obj)
172 {
173    Widget_Data *wd = elm_widget_data_get(obj);
174    double t = ecore_loop_time_get() - wd->start;
175    Evas_Coord x, y, w, h;
176    double p, deg;
177    Evas_Map *mf, *mb;
178    Evas_Coord cx, cy, px, py, foc;
179    int lx, ly, lz, lr, lg, lb, lar, lag, lab;
180    if (!wd->animator) return ECORE_CALLBACK_CANCEL;
181    t = t / wd->len;
182    if (t > 1.0) t = 1.0;
183
184    if (!wd) return ECORE_CALLBACK_CANCEL;
185
186    mf = evas_map_new(4);
187    evas_map_smooth_set(mf, 0);
188    mb = evas_map_new(4);
189    evas_map_smooth_set(mb, 0);
190
191    if (wd->front.content)
192      {
193         evas_object_geometry_get(wd->front.content, &x, &y, &w, &h);
194         evas_map_util_points_populate_from_geometry(mf, x, y, w, h, 0);
195      }
196    if (wd->back.content)
197      {
198         evas_object_geometry_get(wd->back.content, &x, &y, &w, &h);
199         evas_map_util_points_populate_from_geometry(mb, x, y, w, h, 0);
200      }
201
202    evas_object_geometry_get(obj, &x, &y, &w, &h);
203
204    cx = x + (w / 2);
205    cy = y + (h / 2);
206
207    px = x + (w / 2);
208    py = y + (h / 2);
209    foc = 2048;
210
211    lx = cx;
212    ly = cy;
213    lz = -10000;
214    lr = 255;
215    lg = 255;
216    lb = 255;
217    lar = 0;
218    lag = 0;
219    lab = 0;
220
221    switch (wd->mode)
222      {
223       case ELM_FLIP_ROTATE_Y_CENTER_AXIS:
224          p = 1.0 - t;
225          p = 1.0 - (p * p);
226          if (wd->state) deg = 180.0 * p;
227          else deg = 180 + (180.0 * p);
228          evas_map_util_3d_rotate(mf, 0.0, deg, 0.0, cx, cy, 0);
229          evas_map_util_3d_rotate(mb, 0.0, deg + 180.0, 0.0, cx, cy, 0);
230          break;
231       case ELM_FLIP_ROTATE_X_CENTER_AXIS:
232          p = 1.0 - t;
233          p = 1.0 - (p * p);
234          if (wd->state) deg = 180.0 * p;
235          else deg = 180 + (180.0 * p);
236          evas_map_util_3d_rotate(mf, deg, 0.0, 0.0, cx, cy, 0);
237          evas_map_util_3d_rotate(mb, deg + 180.0, 0.0, 0.0, cx, cy, 0);
238          break;
239       case ELM_FLIP_ROTATE_XZ_CENTER_AXIS:
240          p = 1.0 - t;
241          p = 1.0 - (p * p);
242          if (wd->state) deg = 180.0 * p;
243          else deg = 180 + (180.0 * p);
244          evas_map_util_3d_rotate(mf, deg, 0.0, deg, cx, cy, 0);
245          evas_map_util_3d_rotate(mb, deg + 180.0, 0.0, deg + 180.0, cx, cy, 0);
246          break;
247       case ELM_FLIP_ROTATE_YZ_CENTER_AXIS:
248          p = 1.0 - t;
249          p = 1.0 - (p * p);
250          if (wd->state) deg = 180.0 * p;
251          else deg = 180 + (180.0 * p);
252          evas_map_util_3d_rotate(mf, 0.0, deg, deg, cx, cy, 0);
253          evas_map_util_3d_rotate(mb, 0.0, deg + 180.0, deg + 180.0, cx, cy, 0);
254          break;
255       case ELM_FLIP_CUBE_LEFT:
256          p = 1.0 - t;
257          p = 1.0 - (p * p);
258          deg = -90.0 * p;
259          if (wd->state)
260            {
261               evas_map_util_3d_rotate(mf, 0.0, deg, 0.0, cx, cy, w / 2);
262               evas_map_util_3d_rotate(mb, 0.0, deg + 90, 0.0, cx, cy, w / 2);
263            }
264          else
265            {
266               evas_map_util_3d_rotate(mf, 0.0, deg + 90, 0.0, cx, cy, w / 2);
267               evas_map_util_3d_rotate(mb, 0.0, deg, 0.0, cx, cy, w / 2);
268            }
269          break;
270       case ELM_FLIP_CUBE_RIGHT:
271          p = 1.0 - t;
272          p = 1.0 - (p * p);
273          deg = 90.0 * p;
274          if (wd->state)
275            {
276               evas_map_util_3d_rotate(mf, 0.0, deg, 0.0, cx, cy, w / 2);
277               evas_map_util_3d_rotate(mb, 0.0, deg - 90, 0.0, cx, cy, w / 2);
278            }
279          else
280            {
281               evas_map_util_3d_rotate(mf, 0.0, deg - 90, 0.0, cx, cy, w / 2);
282               evas_map_util_3d_rotate(mb, 0.0, deg, 0.0, cx, cy, w / 2);
283            }
284          break;
285       case ELM_FLIP_CUBE_UP:
286          p = 1.0 - t;
287          p = 1.0 - (p * p);
288          deg = -90.0 * p;
289          if (wd->state)
290            {
291               evas_map_util_3d_rotate(mf, deg, 0.0, 0.0, cx, cy, h / 2);
292               evas_map_util_3d_rotate(mb, deg + 90, 0.0, 0.0, cx, cy, h / 2);
293            }
294          else
295            {
296               evas_map_util_3d_rotate(mf, deg + 90, 0.0, 0.0, cx, cy, h / 2);
297               evas_map_util_3d_rotate(mb, deg, 0.0, 0.0, cx, cy, h / 2);
298            }
299          break;
300       case ELM_FLIP_CUBE_DOWN:
301          p = 1.0 - t;
302          p = 1.0 - (p * p);
303          deg = 90.0 * p;
304          if (wd->state)
305            {
306               evas_map_util_3d_rotate(mf, deg, 0.0, 0.0, cx, cy, h / 2);
307               evas_map_util_3d_rotate(mb, deg - 90, 0.0, 0.0, cx, cy, h / 2);
308            }
309          else
310            {
311               evas_map_util_3d_rotate(mf, deg - 90, 0.0, 0.0, cx, cy, h / 2);
312               evas_map_util_3d_rotate(mb, deg, 0.0, 0.0, cx, cy, h / 2);
313            }
314          break;
315       default:
316          break;
317      }
318
319
320    if (wd->front.content)
321      {
322         evas_map_util_3d_lighting(mf, lx, ly, lz, lr, lg, lb, lar, lag, lab);
323         evas_map_util_3d_perspective(mf, px, py, 0, foc);
324         evas_object_map_set(wd->front.content, mf);
325         evas_object_map_enable_set(wd->front.content, 1);
326         if (evas_map_util_clockwise_get(mf)) evas_object_show(wd->front.clip);
327         else evas_object_hide(wd->front.clip);
328      }
329
330    if (wd->back.content)
331      {
332         evas_map_util_3d_lighting(mb, lx, ly, lz, lr, lg, lb, lar, lag, lab);
333         evas_map_util_3d_perspective(mb, px, py, 0, foc);
334         evas_object_map_set(wd->back.content, mb);
335         evas_object_map_enable_set(wd->back.content, 1);
336         if (evas_map_util_clockwise_get(mb)) evas_object_show(wd->back.clip);
337         else evas_object_hide(wd->back.clip);
338      }
339
340    evas_map_free(mf);
341    evas_map_free(mb);
342
343    if (t >= 1.0)
344      {
345         evas_object_map_enable_set(wd->front.content, 0);
346         evas_object_map_enable_set(wd->back.content, 0);
347         // FIXME: hack around evas rendering bug (only fix makes evas bitch-slow
348         evas_object_resize(wd->front.content, 0, 0);
349         evas_object_resize(wd->back.content, 0, 0);
350         evas_smart_objects_calculate(evas_object_evas_get(obj));
351         // FIXME: end hack
352         wd->animator = NULL;
353         wd->state = !wd->state;
354         _configure(obj);
355         evas_object_smart_callback_call(obj, SIG_ANIMATE_DONE, NULL);
356         return ECORE_CALLBACK_CANCEL;
357      }
358    return ECORE_CALLBACK_RENEW;
359 }
360
361 static void
362 _configure(Evas_Object *obj)
363 {
364    Widget_Data *wd = elm_widget_data_get(obj);
365    Evas_Coord x, y, w, h;
366    if (!wd) return;
367    evas_object_geometry_get(obj, &x, &y, &w, &h);
368    if (wd->front.content)
369      {
370         if (!wd->animator)
371           evas_object_move(wd->front.content, x, y);
372         evas_object_resize(wd->front.content, w, h);
373      }
374    if (wd->back.content)
375      {
376         if (!wd->animator)
377           evas_object_move(wd->back.content, x, y);
378         evas_object_resize(wd->back.content, w, h);
379      }
380    _flip(obj);
381 }
382
383 static void
384 _move(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
385 {
386    _configure(obj);
387 }
388
389 static void
390 _resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
391 {
392    _configure(obj);
393 }
394
395 static Eina_Bool
396 _animate(void *data)
397 {
398    return _flip(data);
399 }
400
401 /**
402  * Add a new flip to the parent
403  *
404  * @param parent The parent object
405  * @return The new object or NULL if it cannot be created
406  *
407  * @ingroup Flip
408  */
409 EAPI Evas_Object *
410 elm_flip_add(Evas_Object *parent)
411 {
412    Evas_Object *obj;
413    Evas *e;
414    Widget_Data *wd;
415
416    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
417
418    ELM_SET_WIDTYPE(widtype, "flip");
419    elm_widget_type_set(obj, "flip");
420    elm_widget_sub_object_add(parent, obj);
421    elm_widget_data_set(obj, wd);
422    elm_widget_del_hook_set(obj, _del_hook);
423    elm_widget_theme_hook_set(obj, _theme_hook);
424    elm_widget_focus_next_hook_set(obj, _elm_flip_focus_next_hook);
425    elm_widget_can_focus_set(obj, EINA_FALSE);
426
427    wd->clip = evas_object_rectangle_add(e);
428    evas_object_static_clip_set(wd->clip, 1);
429    evas_object_color_set(wd->clip, 255, 255, 255, 255);
430    evas_object_move(wd->clip, -49999, -49999);
431    evas_object_resize(wd->clip, 99999, 99999);
432    elm_widget_sub_object_add(obj, wd->clip);
433    evas_object_clip_set(wd->clip, evas_object_clip_get(obj));
434    evas_object_smart_member_add(wd->clip, obj);
435
436    wd->front.clip = evas_object_rectangle_add(e);
437    evas_object_static_clip_set(wd->front.clip, 1);
438    evas_object_data_set(wd->front.clip, "_elm_leaveme", obj);
439    evas_object_color_set(wd->front.clip, 255, 255, 255, 255);
440    evas_object_move(wd->front.clip, -49999, -49999);
441    evas_object_resize(wd->front.clip, 99999, 99999);
442    elm_widget_sub_object_add(obj, wd->front.clip);
443    evas_object_smart_member_add(wd->front.clip, obj);
444    evas_object_clip_set(wd->front.clip, wd->clip);
445
446    wd->back.clip = evas_object_rectangle_add(e);
447    evas_object_static_clip_set(wd->back.clip, 1);
448    evas_object_data_set(wd->back.clip, "_elm_leaveme", obj);
449    evas_object_color_set(wd->back.clip, 255, 255, 255, 255);
450    evas_object_move(wd->back.clip, -49999, -49999);
451    evas_object_resize(wd->back.clip, 99999, 99999);
452    elm_widget_sub_object_add(wd->back.clip, obj);
453    evas_object_smart_member_add(obj, wd->back.clip);
454    evas_object_clip_set(wd->back.clip, wd->clip);
455
456    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
457    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, NULL);
458    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, NULL);
459
460    evas_object_smart_callbacks_descriptions_set(obj, _signals);
461
462    wd->state = 1;
463
464    _sizing_eval(obj);
465
466    return obj;
467 }
468
469 /**
470  * Set the front content of the flip widget.
471  *
472  * Once the content object is set, a previously set one will be deleted.
473  * If you want to keep that old content object, use the
474  * elm_flip_content_front_unset() function.
475  *
476  * @param obj The flip object
477  * @param content The new front content object
478  *
479  * @ingroup Flip
480  */
481 EAPI void
482 elm_flip_content_front_set(Evas_Object *obj, Evas_Object *content)
483 {
484    ELM_CHECK_WIDTYPE(obj, widtype);
485    Widget_Data *wd = elm_widget_data_get(obj);
486    if (!wd) return;
487    if (wd->front.content == content) return;
488    if (wd->front.content) evas_object_del(wd->back.content);
489    wd->front.content = content;
490    if (content)
491      {
492         elm_widget_sub_object_add(obj, content);
493         evas_object_smart_member_add(content, obj);
494         evas_object_clip_set(content, wd->front.clip);
495         evas_object_event_callback_add(content,
496                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
497                                        _changed_size_hints, obj);
498         _sizing_eval(obj);
499      }
500    // force calc to contents are the right size before transition
501    evas_smart_objects_calculate(evas_object_evas_get(obj));
502    flip_show_hide(obj);
503    _configure(obj);
504 }
505
506 /**
507  * Set the back content of the flip widget.
508  *
509  * Once the content object is set, a previously set one will be deleted.
510  * If you want to keep that old content object, use the
511  * elm_flip_content_back_unset() function.
512  *
513  * @param obj The flip object
514  * @param content The new back content object
515  *
516  * @ingroup Flip
517  */
518 EAPI void
519 elm_flip_content_back_set(Evas_Object *obj, Evas_Object *content)
520 {
521    ELM_CHECK_WIDTYPE(obj, widtype);
522    Widget_Data *wd = elm_widget_data_get(obj);
523    if (!wd) return;
524    if (wd->back.content == content) return;
525    if (wd->back.content) evas_object_del(wd->back.content);
526    wd->back.content = content;
527    if (content)
528      {
529         elm_widget_sub_object_add(obj, content);
530         evas_object_smart_member_add(content, obj);
531         evas_object_clip_set(content, wd->back.clip);
532         evas_object_event_callback_add(content,
533                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
534                                        _changed_size_hints, obj);
535         _sizing_eval(obj);
536      }
537    // force calc to contents are the right size before transition
538    evas_smart_objects_calculate(evas_object_evas_get(obj));
539    flip_show_hide(obj);
540    _configure(obj);
541 }
542
543 /**
544  * Get the front content used for the flip
545  *
546  * Return the front content object which is set for this widget.
547  *
548  * @param obj The flip object
549  * @return The front content object that is being used
550  *
551  * @ingroup Flip
552  */
553 EAPI Evas_Object *
554 elm_flip_content_front_get(const Evas_Object *obj)
555 {
556    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
557    Widget_Data *wd = elm_widget_data_get(obj);
558    return wd->front.content;
559 }
560
561
562 /**
563  * Get the back content used for the flip
564  *
565  * Return the back content object which is set for this widget.
566  *
567  * @param obj The flip object
568  * @return The back content object that is being used
569  *
570  * @ingroup Flip
571  */
572 EAPI Evas_Object *
573 elm_flip_content_back_get(const Evas_Object *obj)
574 {
575    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
576    Widget_Data *wd = elm_widget_data_get(obj);
577    return wd->back.content;
578 }
579
580 /**
581  * Unset the front content used for the flip
582  *
583  * Unparent and return the front content object which was set for this widget.
584  *
585  * @param obj The flip object
586  * @return The front content object that was being used
587  *
588  * @ingroup Flip
589  */
590 EAPI Evas_Object *
591 elm_flip_content_front_unset(Evas_Object *obj)
592 {
593    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
594    Widget_Data *wd = elm_widget_data_get(obj);
595    if (!wd) return NULL;
596    if (!wd->front.content) return NULL;
597    Evas_Object *content = wd->front.content;
598    evas_object_clip_unset(content);
599    elm_widget_sub_object_del(obj, content);
600    evas_object_smart_member_del(content);
601    wd->front.content = NULL;
602    return content;
603 }
604
605 /**
606  * Unset the back content used for the flip
607  *
608  * Unparent and return the back content object which was set for this widget.
609  *
610  * @param obj The flip object
611  * @return The back content object that was being used
612  *
613  * @ingroup Flip
614  */
615 EAPI Evas_Object *
616 elm_flip_content_back_unset(Evas_Object *obj)
617 {
618    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
619    Widget_Data *wd = elm_widget_data_get(obj);
620    if (!wd) return NULL;
621    if (!wd->back.content) return NULL;
622    Evas_Object *content = wd->back.content;
623    evas_object_clip_unset(content);
624    elm_widget_sub_object_del(obj, content);
625    evas_object_smart_member_del(content);
626    wd->back.content = NULL;
627    return content;
628 }
629
630 /**
631  * Get flip front visibility state
632  *
633  * @param obj The flip object
634  * @return If front front is showing or not currently
635  *
636  * @ingroup Flip
637  */
638 EAPI Eina_Bool
639 elm_flip_front_get(const Evas_Object *obj)
640 {
641    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
642    Widget_Data *wd = elm_widget_data_get(obj);
643    if (!wd) return EINA_FALSE;
644    return wd->state;
645 }
646
647 /**
648  * Set flip perspective
649  *
650  * @param obj The flip object
651  * @param foc The coordinate to set the focus on
652  * @param x The X coordinate
653  * @param y The Y coordinate
654  *
655  * NOTE: This function currently does nothing.
656  *
657  * @ingroup Flip
658  */
659 EAPI void
660 elm_flip_perspective_set(Evas_Object *obj, Evas_Coord foc __UNUSED__, Evas_Coord x __UNUSED__, Evas_Coord y __UNUSED__)
661 {
662    ELM_CHECK_WIDTYPE(obj, widtype);
663    Widget_Data *wd = elm_widget_data_get(obj);
664    if (!wd) return;
665 }
666
667 /**
668  * Runs the flip animation
669  *
670  * @param obj The flip object
671  * @param mode The mode type.  Currently accepted modes are:
672  *
673  * ELM_FLIP_ROTATE_Y_CENTER_AXIS
674  * ELM_FLIP_ROTATE_X_CENTER_AXIS
675  * ELM_FLIP_ROTATE_XZ_CENTER_AXIS
676  * ELM_FLIP_ROTATE_YZ_CENTER_AXIS
677  * ELM_FLIP_CUBE_LEFT
678  * ELM_FLIP_CUBE_RIGHT
679  *
680  * FIXME: add - ELM_FLIP_CUBE_UP
681  * FIXMEL add - ELM_FLIP_CUBE_DOWN
682  *
683  * @ingroup Flip
684  */
685 EAPI void
686 elm_flip_go(Evas_Object *obj, Elm_Flip_Mode mode)
687 {
688    ELM_CHECK_WIDTYPE(obj, widtype);
689    Widget_Data *wd = elm_widget_data_get(obj);
690    if (!wd) return;
691    if (!wd->animator) wd->animator = ecore_animator_add(_animate, obj);
692    flip_show_hide(obj);
693    wd->mode = mode;
694    wd->start = ecore_loop_time_get();
695    wd->len = 0.5;
696    // force calc to contents are the right size before transition
697    evas_smart_objects_calculate(evas_object_evas_get(obj));
698    _flip(obj);
699    // FIXME: hack around evas rendering bug (only fix makes evas bitch-slow
700    evas_object_map_enable_set(wd->front.content, 0);
701    evas_object_map_enable_set(wd->back.content, 0);
702    evas_object_resize(wd->front.content, 0, 0);
703    evas_object_resize(wd->back.content, 0, 0);
704    evas_smart_objects_calculate(evas_object_evas_get(obj));
705    _configure(obj);
706    // FIXME: end hack
707 }