1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #define EFL_ACCESS_OBJECT_PROTECTED
6 #define EFL_PART_PROTECTED
7
8 #include <Elementary.h>
9 #include "elm_priv.h"
10 #include "efl_ui_widget_flip.h"
11 #include "elm_widget_container.h"
12
13 #include "efl_ui_flip_part.eo.h"
14 #include "elm_part_helper.h"
15
16 #define MY_CLASS EFL_UI_FLIP_CLASS
17 #define MY_CLASS_NAME "Efl.Ui.Flip"
18
19 static const char SIG_ANIMATE_BEGIN[] = "animate,begin";
20 static const char SIG_ANIMATE_DONE[] = "animate,done";
21 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
22 {SIG_ANIMATE_BEGIN, ""},
23 {SIG_ANIMATE_DONE, ""},
24 {NULL, NULL}
25 };
26
27 static Eina_Bool _flip(Evas_Object *obj);
28
29 static void _update_front_back(Eo *obj, Efl_Ui_Flip_Data *sd);
30
31 static void
_slice_free(Slice * sl)32 _slice_free(Slice *sl)
33 {
34 evas_object_del(sl->obj);
35 free(sl);
36 }
37
38 static void
_state_slices_clear(Efl_Ui_Flip_Data * sd)39 _state_slices_clear(Efl_Ui_Flip_Data *sd)
40 {
41 int i, j, num;
42
43 if (sd->slices)
44 {
45 num = 0;
46 for (j = 0; j < sd->slices_h; j++)
47 {
48 for (i = 0; i < sd->slices_w; i++)
49 {
50 if (sd->slices[num]) _slice_free(sd->slices[num]);
51 if (sd->slices2[num]) _slice_free(sd->slices2[num]);
52 num++;
53 }
54 }
55
56 free(sd->slices);
57 free(sd->slices2);
58 sd->slices = NULL;
59 sd->slices2 = NULL;
60 }
61
62 sd->slices_w = 0;
63 sd->slices_h = 0;
64 }
65
66 static void
_sizing_eval(Evas_Object * obj)67 _sizing_eval(Evas_Object *obj)
68 {
69 Evas_Coord minw = -1, minh = -1, minw2 = -1, minh2 = -1;
70 int fingx = 0, fingy = 0;
71 Eina_Size2D max = EINA_SIZE2D(-1, -1), max2 = EINA_SIZE2D(-1, -1);
72
73 EFL_UI_FLIP_DATA_GET(obj, sd);
74
75 if (sd->front.content)
76 evas_object_size_hint_combined_min_get(sd->front.content, &minw, &minh);
77 if (sd->back.content)
78 evas_object_size_hint_combined_min_get(sd->back.content, &minw2, &minh2);
79 if (sd->front.content)
80 max = efl_gfx_hint_size_combined_max_get(sd->front.content);
81 if (sd->back.content)
82 max2 = efl_gfx_hint_size_combined_max_get(sd->back.content);
83
84 if (minw2 > minw) minw = minw2;
85 if (minh2 > minh) minh = minh2;
86 if ((max2.w >= 0) && (max2.w < max.w)) max.w = max2.w;
87 if ((max2.h >= 0) && (max2.h < max.h)) max.h = max2.h;
88
89 if (sd->dir_enabled[ELM_FLIP_DIRECTION_UP]) fingy++;
90 if (sd->dir_enabled[ELM_FLIP_DIRECTION_DOWN]) fingy++;
91 if (sd->dir_enabled[ELM_FLIP_DIRECTION_LEFT]) fingx++;
92 if (sd->dir_enabled[ELM_FLIP_DIRECTION_RIGHT]) fingx++;
93
94 elm_coords_finger_size_adjust(fingx, &minw, fingy, &minh);
95
96 efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
97 efl_gfx_hint_size_restricted_max_set(obj, max);
98 }
99
100 EOLIAN static Eina_Error
_efl_ui_flip_efl_ui_widget_theme_apply(Eo * obj,Efl_Ui_Flip_Data * sd EINA_UNUSED)101 _efl_ui_flip_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Flip_Data *sd EINA_UNUSED)
102 {
103 Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
104 int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
105 if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
106
107 _sizing_eval(obj);
108
109 return int_ret;
110 }
111
112 static void
_changed_size_hints_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)113 _changed_size_hints_cb(void *data,
114 Evas *e EINA_UNUSED,
115 Evas_Object *obj EINA_UNUSED,
116 void *event_info EINA_UNUSED)
117 {
118 _sizing_eval(data);
119 }
120
121 EOLIAN static Eina_Bool
_efl_ui_flip_efl_ui_widget_widget_sub_object_add(Eo * obj,Efl_Ui_Flip_Data * _pd EINA_UNUSED,Evas_Object * sobj)122 _efl_ui_flip_efl_ui_widget_widget_sub_object_add(Eo *obj, Efl_Ui_Flip_Data *_pd EINA_UNUSED, Evas_Object *sobj)
123 {
124 Eina_Bool int_ret = EINA_FALSE;
125
126 if (evas_object_data_get(sobj, "elm-parent") == obj)
127 return EINA_TRUE;
128
129 int_ret = elm_widget_sub_object_add(efl_super(obj, MY_CLASS), sobj);
130 if (!int_ret) return EINA_FALSE;
131
132 evas_object_data_set(sobj, "_elm_leaveme", sobj);
133 evas_object_smart_member_add(sobj, obj);
134 evas_object_event_callback_add
135 (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints_cb, obj);
136 evas_object_lower(sobj);
137
138 return EINA_TRUE;
139 }
140
141 EOLIAN static Eina_Bool
_efl_ui_flip_efl_ui_widget_widget_sub_object_del(Eo * obj,Efl_Ui_Flip_Data * sd,Evas_Object * sobj)142 _efl_ui_flip_efl_ui_widget_widget_sub_object_del(Eo *obj, Efl_Ui_Flip_Data *sd, Evas_Object *sobj)
143 {
144 Eina_Bool int_ret = EINA_FALSE;
145
146
147 int_ret = elm_widget_sub_object_del(efl_super(obj, MY_CLASS), sobj);
148 if (!int_ret) return EINA_FALSE;
149
150 if (sobj == sd->front.content)
151 {
152 evas_object_data_del(sobj, "_elm_leaveme");
153 sd->front.content = NULL;
154 evas_object_hide(sd->front.clip);
155 }
156 else if (sobj == sd->back.content)
157 {
158 evas_object_data_del(sobj, "_elm_leaveme");
159 sd->back.content = NULL;
160 evas_object_hide(sd->back.clip);
161 }
162
163 evas_object_smart_member_del(sobj);
164 evas_object_clip_unset(sobj);
165
166 evas_object_event_callback_del_full
167 (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints_cb, obj);
168 _sizing_eval(obj);
169
170 return EINA_TRUE;
171 }
172
173 static Slice *
_slice_new(Evas_Object * container_obj,Evas_Object * obj)174 _slice_new(Evas_Object *container_obj,
175 Evas_Object *obj)
176 {
177 Slice *sl;
178
179 sl = calloc(1, sizeof(Slice));
180 if (!sl) return NULL;
181
182 sl->obj = evas_object_image_add(evas_object_evas_get(obj));
183
184 evas_object_smart_member_add(sl->obj, container_obj);
185
186 evas_object_image_smooth_scale_set(sl->obj, EINA_FALSE);
187 evas_object_pass_events_set(sl->obj, EINA_TRUE);
188 evas_object_image_source_set(sl->obj, obj);
189
190 return sl;
191 }
192
193 static void
_slice_apply(Efl_Ui_Flip_Data * sd,Slice * sl,Evas_Coord x EINA_UNUSED,Evas_Coord y EINA_UNUSED,Evas_Coord w,Evas_Coord h EINA_UNUSED,Evas_Coord ox,Evas_Coord oy,Evas_Coord ow,Evas_Coord oh)194 _slice_apply(Efl_Ui_Flip_Data *sd,
195 Slice *sl,
196 Evas_Coord x EINA_UNUSED,
197 Evas_Coord y EINA_UNUSED,
198 Evas_Coord w,
199 Evas_Coord h EINA_UNUSED,
200 Evas_Coord ox,
201 Evas_Coord oy,
202 Evas_Coord ow,
203 Evas_Coord oh)
204 {
205 static Evas_Map *m = NULL;
206 int i;
207
208 if (!m) m = evas_map_new(4);
209 if (!m) return;
210
211 evas_map_smooth_set(m, EINA_FALSE);
212 for (i = 0; i < 4; i++)
213 {
214 evas_map_point_color_set(m, i, 255, 255, 255, 255);
215 if (sd->dir == ELM_FLIP_DIRECTION_LEFT)
216 {
217 int p[4] = { 0, 1, 2, 3 };
218 evas_map_point_coord_set(m, i, ox + sl->x[p[i]], oy + sl->y[p[i]],
219 sl->z[p[i]]);
220 evas_map_point_image_uv_set(m, i, sl->u[p[i]], sl->v[p[i]]);
221 }
222 else if (sd->dir == ELM_FLIP_DIRECTION_RIGHT)
223 {
224 int p[4] = { 1, 0, 3, 2 };
225 evas_map_point_coord_set(m, i, ox + (w - sl->x[p[i]]),
226 oy + sl->y[p[i]], sl->z[p[i]]);
227 evas_map_point_image_uv_set(m, i, ow - sl->u[p[i]], sl->v[p[i]]);
228 }
229 else if (sd->dir == ELM_FLIP_DIRECTION_UP)
230 {
231 int p[4] = { 1, 0, 3, 2 };
232 evas_map_point_coord_set(m, i, ox + sl->y[p[i]], oy + sl->x[p[i]],
233 sl->z[p[i]]);
234 evas_map_point_image_uv_set(m, i, sl->v[p[i]], sl->u[p[i]]);
235 }
236 else /* if (sd->dir == 3) will be this anyway */
237 {
238 int p[4] = { 0, 1, 2, 3 };
239 evas_map_point_coord_set(m, i, ox + sl->y[p[i]],
240 oy + (w - sl->x[p[i]]), sl->z[p[i]]);
241 evas_map_point_image_uv_set(m, i, sl->v[p[i]], oh - sl->u[p[i]]);
242 }
243 }
244
245 evas_object_map_enable_set(sl->obj, EINA_TRUE);
246 evas_object_image_fill_set(sl->obj, 0, 0, ow, oh);
247 evas_object_map_set(sl->obj, m);
248 }
249
250 static void
_slice_3d(Efl_Ui_Flip_Data * sd EINA_UNUSED,Slice * sl,Evas_Coord x,Evas_Coord y,Evas_Coord w,Evas_Coord h)251 _slice_3d(Efl_Ui_Flip_Data *sd EINA_UNUSED,
252 Slice *sl,
253 Evas_Coord x,
254 Evas_Coord y,
255 Evas_Coord w,
256 Evas_Coord h)
257 {
258 Evas_Map *m = evas_map_dup(evas_object_map_get(sl->obj));
259 int i;
260
261 if (!m) return;
262
263 // vanishing point is center of page, and focal dist is 1024
264 evas_map_util_3d_perspective(m, x + (w / 2), y + (h / 2), 0, 1024);
265 for (i = 0; i < 4; i++)
266 {
267 Evas_Coord xx, yy;
268 evas_map_point_coord_get(m, i, &xx, &yy, NULL);
269 evas_map_point_coord_set(m, i, xx, yy, 0);
270 }
271
272 if (evas_map_util_clockwise_get(m)) evas_object_show(sl->obj);
273 else evas_object_hide(sl->obj);
274
275 evas_object_map_set(sl->obj, m);
276 evas_map_free(m);
277 }
278
279 static void
_slice_light(Efl_Ui_Flip_Data * sd EINA_UNUSED,Slice * sl,Evas_Coord x,Evas_Coord y,Evas_Coord w,Evas_Coord h)280 _slice_light(Efl_Ui_Flip_Data *sd EINA_UNUSED,
281 Slice *sl,
282 Evas_Coord x,
283 Evas_Coord y,
284 Evas_Coord w,
285 Evas_Coord h)
286 {
287 Evas_Map *m = (Evas_Map *)evas_object_map_get(sl->obj);
288 int i;
289
290 if (!m) return;
291
292 evas_map_util_3d_lighting(m,
293 /* light position
294 * (centered over page 10 * h toward camera) */
295 x + (w / 2), y + (h / 2), -10000,
296 255, 255, 255, // light color
297 0, 0, 0); // ambient minimum
298
299 // multiply brightness by 1.2 to make lightish bits all white so we don't
300 // add shading where we could otherwise be pure white
301 for (i = 0; i < 4; i++)
302 {
303 int r, g, b, a;
304
305 evas_map_point_color_get(m, i, &r, &g, &b, &a);
306 r = (double)r * 1.2; if (r > 255) r = 255;
307 g = (double)g * 1.2; if (g > 255) g = 255;
308 b = (double)b * 1.2; if (b > 255) b = 255;
309 evas_map_point_color_set(m, i, r, g, b, a);
310 }
311
312 evas_object_map_set(sl->obj, m);
313 }
314
315 static void
_slice_xyz(Efl_Ui_Flip_Data * sd EINA_UNUSED,Slice * sl,double xx1,double yy1,double zz1,double xx2,double yy2,double zz2,double xx3,double yy3,double zz3,double xx4,double yy4,double zz4)316 _slice_xyz(Efl_Ui_Flip_Data *sd EINA_UNUSED,
317 Slice *sl,
318 double xx1,
319 double yy1,
320 double zz1,
321 double xx2,
322 double yy2,
323 double zz2,
324 double xx3,
325 double yy3,
326 double zz3,
327 double xx4,
328 double yy4,
329 double zz4)
330 {
331 sl->x[0] = xx1; sl->y[0] = yy1; sl->z[0] = zz1;
332 sl->x[1] = xx2; sl->y[1] = yy2; sl->z[1] = zz2;
333 sl->x[2] = xx3; sl->y[2] = yy3; sl->z[2] = zz3;
334 sl->x[3] = xx4; sl->y[3] = yy4; sl->z[3] = zz4;
335 }
336
337 static void
_slice_uv(Efl_Ui_Flip_Data * sd EINA_UNUSED,Slice * sl,double u1,double v1,double u2,double v2,double u3,double v3,double u4,double v4)338 _slice_uv(Efl_Ui_Flip_Data *sd EINA_UNUSED,
339 Slice *sl,
340 double u1,
341 double v1,
342 double u2,
343 double v2,
344 double u3,
345 double v3,
346 double u4,
347 double v4)
348 {
349 sl->u[0] = u1; sl->v[0] = v1;
350 sl->u[1] = u2; sl->v[1] = v2;
351 sl->u[2] = u3; sl->v[2] = v3;
352 sl->u[3] = u4; sl->v[3] = v4;
353 }
354
355 static void
_deform_point(Vertex2 * vi,Vertex3 * vo,double rho,double theta,double A)356 _deform_point(Vertex2 *vi,
357 Vertex3 *vo,
358 double rho,
359 double theta,
360 double A)
361 {
362 // ^Y
363 // |
364 // | X
365 // +---->
366 // theta == cone angle (0 -> PI/2)
367 // A == distance of cone apex from origin
368 // rho == angle of cone from vertical axis (...-PI/2 to PI/2...)
369 Vertex3 v1;
370 double d, r, b;
371
372 d = sqrt((vi->x * vi->x) + pow(vi->y - A, 2));
373 r = d * sin(theta);
374 b = asin(vi->x / d) / sin(theta);
375
376 v1.x = r * sin(b);
377 v1.y = d + A - (r * (1 - cos(b)) * sin(theta));
378 v1.z = r * (1 - cos(b)) * cos(theta);
379
380 vo->x = (v1.x * cos(rho)) - (v1.z * sin(rho));
381 vo->y = v1.y;
382 vo->z = (v1.x * sin(rho)) + (v1.z * cos(rho));
383 }
384
385 static void
_interp_point(Vertex3 * vi1,Vertex3 * vi2,Vertex3 * vo,double v)386 _interp_point(Vertex3 *vi1,
387 Vertex3 *vi2,
388 Vertex3 *vo,
389 double v)
390 {
391 vo->x = (v * vi2->x) + ((1.0 - v) * vi1->x);
392 vo->y = (v * vi2->y) + ((1.0 - v) * vi1->y);
393 vo->z = (v * vi2->z) + ((1.0 - v) * vi1->z);
394 }
395
396 static int
_slice_obj_color_sum(Slice * s,int p,int * r,int * g,int * b,int * a)397 _slice_obj_color_sum(Slice *s,
398 int p,
399 int *r,
400 int *g,
401 int *b,
402 int *a)
403 {
404 Evas_Map *m;
405 int rr = 0, gg = 0, bb = 0, aa = 0;
406
407 if (!s) return 0;
408
409 m = (Evas_Map *)evas_object_map_get(s->obj);
410 if (!m) return 0;
411
412 evas_map_point_color_get(m, p, &rr, &gg, &bb, &aa);
413 *r += rr; *g += gg; *b += bb; *a += aa;
414
415 return 1;
416 }
417
418 static void
_slice_obj_color_set(Slice * s,int p,int r,int g,int b,int a)419 _slice_obj_color_set(Slice *s,
420 int p,
421 int r,
422 int g,
423 int b,
424 int a)
425 {
426 Evas_Map *m;
427
428 if (!s) return;
429
430 m = (Evas_Map *)evas_object_map_get(s->obj);
431 if (!m) return;
432
433 evas_map_point_color_set(m, p, r, g, b, a);
434 evas_object_map_set(s->obj, m);
435 }
436
437 static void
_slice_obj_vert_color_merge(Slice * s1,int p1,Slice * s2,int p2,Slice * s3,int p3,Slice * s4,int p4)438 _slice_obj_vert_color_merge(Slice *s1,
439 int p1,
440 Slice *s2,
441 int p2,
442 Slice *s3,
443 int p3,
444 Slice *s4,
445 int p4)
446 {
447 int r = 0, g = 0, b = 0, a = 0, n = 0;
448
449 n += _slice_obj_color_sum(s1, p1, &r, &g, &b, &a);
450 n += _slice_obj_color_sum(s2, p2, &r, &g, &b, &a);
451 n += _slice_obj_color_sum(s3, p3, &r, &g, &b, &a);
452 n += _slice_obj_color_sum(s4, p4, &r, &g, &b, &a);
453
454 if (n < 1) return;
455 r /= n; g /= n; b /= n; a /= n;
456
457 _slice_obj_color_set(s1, p1, r, g, b, a);
458 _slice_obj_color_set(s2, p2, r, g, b, a);
459 _slice_obj_color_set(s3, p3, r, g, b, a);
460 _slice_obj_color_set(s4, p4, r, g, b, a);
461 }
462
463 static int
_state_update(Evas_Object * obj)464 _state_update(Evas_Object *obj)
465 {
466 Efl_Ui_Flip_Data *sd = efl_data_scope_get(obj, MY_CLASS);
467 Slice *sl;
468 Vertex3 *tvo, *tvol;
469 Evas_Object *front, *back;
470 int i, j, num, nn, jump, num2;
471 double b, minv = 0.0, minva, mgrad;
472 Evas_Coord xx1, yy1, xx2, yy2, mx, my;
473 Evas_Coord x, y, w, h, ox, oy, ow, oh;
474 int gx, gy, gszw, gszh, gw, gh, col, row, nw, nh;
475 double rho, A, theta, perc, n, rhol, Al, thetal;
476
477 sd->backflip = EINA_TRUE;
478 if (sd->state)
479 {
480 front = sd->front.content;
481 back = sd->front.content;
482 }
483 else
484 {
485 front = sd->back.content;
486 back = sd->back.content;
487 }
488
489 evas_object_geometry_get(obj, &x, &y, &w, &h);
490 ox = x; oy = y; ow = w; oh = h;
491 xx1 = sd->down_x;
492 yy1 = sd->down_y;
493 xx2 = sd->x;
494 yy2 = sd->y;
495
496 if (sd->dir == ELM_FLIP_DIRECTION_LEFT)
497 {
498 // no nothing. left drag is standard
499 }
500 else if (sd->dir == ELM_FLIP_DIRECTION_RIGHT)
501 {
502 xx1 = (w - 1) - xx1;
503 xx2 = (w - 1) - xx2;
504 }
505 else if (sd->dir == ELM_FLIP_DIRECTION_UP)
506 {
507 Evas_Coord tmp;
508
509 tmp = xx1; xx1 = yy1; yy1 = tmp;
510 tmp = xx2; xx2 = yy2; yy2 = tmp;
511 tmp = w; w = h; h = tmp;
512 }
513 else /* if (sd->dir == 3) will be this anyway */
514 {
515 Evas_Coord tmp;
516
517 tmp = xx1; xx1 = yy1; yy1 = tmp;
518 tmp = xx2; xx2 = yy2; yy2 = tmp;
519 tmp = w; w = h; h = tmp;
520 xx1 = (w - 1) - xx1;
521 xx2 = (w - 1) - xx2;
522 }
523
524 if (xx2 >= xx1) xx2 = xx1 - 1;
525 mx = (xx1 + xx2) / 2;
526 my = (yy1 + yy2) / 2;
527
528 if (mx < 0) mx = 0;
529 else if (mx >= w)
530 mx = w - 1;
531 if (my < 0) my = 0;
532 else if (my >= h)
533 my = h - 1;
534
535 mgrad = (double)(yy1 - yy2) / (double)(xx1 - xx2);
536
537 if (mx < 1) mx = 1; // quick hack to keep curl line visible
538
539 if (EINA_DBL_EQ(mgrad, 0.0)) // special horizontal case
540 mgrad = 0.001; // quick dirty hack for now
541 // else
542 {
543 minv = 1.0 / mgrad;
544 // y = (m * x) + b
545 b = my + (minv * mx);
546 }
547 if ((b >= -5) && (b <= (h + 5)))
548 {
549 if (minv > 0.0) // clamp to h
550 {
551 minv = (double)(h + 5 - my) / (double)(mx);
552 b = my + (minv * mx);
553 }
554 else // clamp to 0
555 {
556 minv = (double)(-5 - my) / (double)(mx);
557 b = my + (minv * mx);
558 }
559 }
560
561 perc = (double)xx2 / (double)xx1;
562 if (perc < 0.0) perc = 0.0;
563 else if (perc > 1.0)
564 perc = 1.0;
565
566 minva = atan(minv) / (M_PI / 2);
567 if (minva < 0.0) minva = -minva;
568
569 // A = apex of cone
570 if (b <= 0) A = b;
571 else A = h - b;
572 if (A < -(h * 20)) A = -h * 20;
573 //--//
574 Al = -5;
575
576 // rho = is how much the page is turned
577 n = 1.0 - perc;
578 n = 1.0 - cos(n * M_PI / 2.0);
579 n = n * n;
580 rho = -(n * M_PI);
581 //--//
582 rhol = -(n * M_PI);
583
584 // theta == curliness (how much page curls in on itself
585 n = sin((1.0 - perc) * M_PI);
586 n = n * 1.2;
587 theta = 7.86 + n;
588 //--//
589 n = sin((1.0 - perc) * M_PI);
590 n = 1.0 - n;
591 n = n * n;
592 n = 1.0 - n;
593 thetal = 7.86 + n;
594
595 nw = 16;
596 nh = 16;
597 gszw = w / nw;
598 gszh = h / nh;
599 if (gszw < 4) gszw = 4;
600 if (gszh < 4) gszh = 4;
601
602 nw = (w + gszw - 1) / gszw;
603 nh = (h + gszh - 1) / gszh;
604 if ((sd->slices_w != nw) || (sd->slices_h != nh)) _state_slices_clear(sd);
605 sd->slices_w = nw;
606 sd->slices_h = nh;
607 if (!sd->slices)
608 {
609 sd->slices = calloc(sd->slices_w * sd->slices_h, sizeof(Slice *));
610 if (!sd->slices) return 0;
611 sd->slices2 = calloc(sd->slices_w * sd->slices_h, sizeof(Slice *));
612 if (!sd->slices2)
613 {
614 ELM_SAFE_FREE(sd->slices, free);
615 return 0;
616 }
617 }
618
619 num = (sd->slices_w + 1) * (sd->slices_h + 1);
620
621 tvo = alloca(sizeof(Vertex3) * num);
622 tvol = alloca(sizeof(Vertex3) * (sd->slices_w + 1));
623
624 for (col = 0, gx = 0; gx <= (w + gszw - 1); gx += gszw, col++)
625 {
626 Vertex2 vil;
627
628 vil.x = gx;
629 vil.y = h - ((gx * h) / (w + gszw - 1));
630 _deform_point(&vil, &(tvol[col]), rhol, thetal, Al);
631 }
632
633 n = minva * sin(perc * M_PI);
634 n = n * n;
635
636 num = 0;
637 for (col = 0, gx = 0; gx <= (w + gszw - 1); gx += gszw, col++)
638 {
639 for (gy = 0; gy <= (h + gszh - 1); gy += gszh)
640 {
641 Vertex2 vi;
642 Vertex3 vo, tvo1;
643
644 if (gx > w) vi.x = w;
645 else vi.x = gx;
646 if (gy > h) vi.y = h;
647 else vi.y = gy;
648 _deform_point(&vi, &vo, rho, theta, A);
649 tvo1 = tvol[col];
650 if (gy > h) tvo1.y = h;
651 else tvo1.y = gy;
652 _interp_point(&vo, &tvo1, &(tvo[num]), n);
653 num++;
654 }
655 }
656
657 jump = sd->slices_h + 1;
658 for (col = 0, gx = 0; gx < w; gx += gszw, col++)
659 {
660 num = sd->slices_h * col;
661 num2 = jump * col;
662
663 gw = gszw;
664 if ((gx + gw) > w) gw = w - gx;
665
666 for (row = 0, gy = 0; gy < h; gy += gszh, row++)
667 {
668 Vertex3 vo[4];
669
670 memset(vo, 0, sizeof (vo));
671
672 if (b > 0) nn = num + sd->slices_h - row - 1;
673 else nn = num + row;
674
675 gh = gszh;
676 if ((gy + gh) > h) gh = h - gy;
677
678 vo[0] = tvo[num2 + row];
679 vo[1] = tvo[num2 + row + jump];
680 vo[2] = tvo[num2 + row + jump + 1];
681 vo[3] = tvo[num2 + row + 1];
682
683 #define SWP(a, b) \
684 do { \
685 typeof(a)vt; \
686 vt = (a); \
687 (a) = (b); \
688 (b) = vt; \
689 } while (0)
690
691 if (b > 0)
692 {
693 SWP(vo[0], vo[3]);
694 SWP(vo[1], vo[2]);
695 vo[0].y = h - vo[0].y;
696 vo[1].y = h - vo[1].y;
697 vo[2].y = h - vo[2].y;
698 vo[3].y = h - vo[3].y;
699 }
700
701 // FRONT
702 sl = sd->slices[nn];
703 if (!sl)
704 {
705 sl = _slice_new(obj, front);
706 if (!sl) return 0;
707 sd->slices[nn] = sl;
708 }
709 _slice_xyz(sd, sl,
710 vo[0].x, vo[0].y, vo[0].z,
711 vo[1].x, vo[1].y, vo[1].z,
712 vo[2].x, vo[2].y, vo[2].z,
713 vo[3].x, vo[3].y, vo[3].z);
714 if (b <= 0)
715 _slice_uv(sd, sl,
716 gx, gy, gx + gw, gy, gx + gw, gy + gh, gx, gy + gh);
717 else
718 _slice_uv(sd, sl,
719 gx, h - (gy + gh), gx + gw, h - (gy + gh), gx + gw,
720 h - gy, gx, h - gy);
721
722 // BACK
723 sl = sd->slices2[nn];
724 if (!sl)
725 {
726 sl = _slice_new(obj, back);
727 if (!sl) return 0;
728 sd->slices2[nn] = sl;
729 }
730
731 _slice_xyz(sd, sl,
732 vo[1].x, vo[1].y, vo[1].z,
733 vo[0].x, vo[0].y, vo[0].z,
734 vo[3].x, vo[3].y, vo[3].z,
735 vo[2].x, vo[2].y, vo[2].z);
736 if (sd->backflip)
737 {
738 if (b <= 0)
739 _slice_uv(sd, sl, gx + gw, gy, gx, gy, gx, gy + gh, gx + gw,
740 gy + gh);
741 else
742 _slice_uv(sd, sl, gx + gw, h - (gy + gh), gx, h - (gy + gh),
743 gx, h - gy, gx + gw, h - gy);
744 }
745 else
746 {
747 if (b <= 0)
748 _slice_uv(sd, sl, w - (gx + gw), gy, w - (gx), gy, w - (gx),
749 gy + gh, w - (gx + gw), gy + gh);
750 else
751 _slice_uv(sd, sl, w - (gx + gw), h - (gy + gh), w - (gx),
752 h - (gy + gh), w - (gx), h - gy, w - (gx + gw),
753 h - gy);
754 }
755 }
756 }
757
758 for (num = 0; num < sd->slices_h * sd->slices_w; num++)
759 {
760 _slice_apply(sd, sd->slices[num], x, y, w, h, ox, oy, ow, oh);
761 _slice_apply(sd, sd->slices2[num], x, y, w, h, ox, oy, ow, oh);
762 _slice_light(sd, sd->slices[num], ox, oy, ow, oh);
763 _slice_light(sd, sd->slices2[num], ox, oy, ow, oh);
764 }
765
766 for (i = 0; i <= sd->slices_w; i++)
767 {
768 num = i * sd->slices_h;
769 for (j = 0; j <= sd->slices_h; j++)
770 {
771 Slice *s[4] = { NULL }, *s2[4] = { NULL };
772
773 if ((i > 0) && (j > 0))
774 s[0] = sd->slices[num - 1 - sd->slices_h],
775 s2[0] = sd->slices2[num - 1 - sd->slices_h];
776 if ((i < sd->slices_w) && (j > 0))
777 s[1] = sd->slices[num - 1],
778 s2[1] = sd->slices2[num - 1];
779 if ((i > 0) && (j < sd->slices_h))
780 s[2] = sd->slices[num - sd->slices_h],
781 s2[2] = sd->slices2[num - sd->slices_h];
782 if ((i < sd->slices_w) && (j < sd->slices_h))
783 s[3] = sd->slices[num],
784 s2[3] = sd->slices2[num];
785 switch (sd->dir)
786 {
787 case ELM_FLIP_DIRECTION_LEFT:
788 _slice_obj_vert_color_merge
789 (s[0], 2, s[1], 3, s[2], 1, s[3], 0);
790 _slice_obj_vert_color_merge
791 (s2[0], 3, s2[1], 2, s2[2], 0, s2[3], 1);
792 break;
793
794 case ELM_FLIP_DIRECTION_RIGHT:
795 _slice_obj_vert_color_merge
796 (s[0], 3, s[1], 2, s[2], 0, s[3], 1);
797 _slice_obj_vert_color_merge
798 (s2[0], 2, s2[1], 3, s2[2], 1, s2[3], 0);
799 break;
800
801 case ELM_FLIP_DIRECTION_UP:
802 _slice_obj_vert_color_merge
803 (s[0], 3, s[1], 2, s[2], 0, s[3], 1);
804 _slice_obj_vert_color_merge
805 (s2[0], 2, s2[1], 3, s2[2], 1, s2[3], 0);
806 break;
807
808 default:
809 _slice_obj_vert_color_merge
810 (s[0], 2, s[1], 3, s[2], 1, s[3], 0);
811 _slice_obj_vert_color_merge
812 (s2[0], 3, s2[1], 2, s2[2], 0, s2[3], 1);
813 }
814 num++;
815 }
816 }
817
818 for (num = 0; num < sd->slices_h * sd->slices_w; num++)
819 {
820 _slice_3d(sd, sd->slices[num], ox, oy, ow, oh);
821 _slice_3d(sd, sd->slices2[num], ox, oy, ow, oh);
822 }
823
824 return 1;
825 }
826
827 static void
_cross_fade_update(Evas_Object * obj,double t)828 _cross_fade_update(Evas_Object *obj, double t)
829 {
830 int ca, cb;
831 Evas_Object *aclip, *bclip;
832 Eina_Bool front;
833 double s;
834 EFL_UI_FLIP_DATA_GET(obj, sd);
835 front = sd->next_state;
836
837 s = sin(t * M_PI_2); // fade in sinusoidally
838 t = s * s;
839 ca = 255 * t;
840 if (ca < 0) ca = 0;
841 if (ca > 255) ca = 255;
842
843 cb = sqrt(255 * 255 - ca * ca);
844 if (cb < 0) cb = 0;
845 if (cb > 255) cb = 255;
846
847 if (front)
848 {
849 aclip = sd->front.clip;
850 bclip = sd->back.clip;
851 }
852 else
853 {
854 aclip = sd->back.clip;
855 bclip = sd->front.clip;
856 }
857
858 evas_object_color_set(aclip, ca, ca, ca, ca);
859 evas_object_color_set(bclip, cb, cb, cb, cb);
860 }
861
862 static void
_state_end(Efl_Ui_Flip_Data * sd)863 _state_end(Efl_Ui_Flip_Data *sd)
864 {
865 _state_slices_clear(sd);
866 }
867
868 static void
_flip_show_hide(Evas_Object * obj)869 _flip_show_hide(Evas_Object *obj)
870 {
871 EFL_UI_FLIP_DATA_GET(obj, sd);
872 if (elm_flip_front_visible_get(obj))
873 {
874 if (sd->pageflip)
875 {
876 if (sd->front.content)
877 {
878 evas_object_move(sd->front.content, 4999, 4999);
879 evas_object_show(sd->front.clip);
880 }
881 else
882 evas_object_hide(sd->front.clip);
883 if (sd->back.content)
884 evas_object_show(sd->back.clip);
885 else
886 evas_object_hide(sd->back.clip);
887 }
888 else
889 {
890 if (sd->front.content)
891 evas_object_show(sd->front.clip);
892 else
893 evas_object_hide(sd->front.clip);
894 evas_object_hide(sd->back.clip);
895 }
896 }
897 else
898 {
899 if (sd->pageflip)
900 {
901 if (sd->front.content)
902 evas_object_show(sd->front.clip);
903 else
904 evas_object_hide(sd->front.clip);
905 if (sd->back.content)
906 {
907 evas_object_move(sd->back.content, 4999, 4999);
908 evas_object_show(sd->back.clip);
909 }
910 else
911 evas_object_hide(sd->back.clip);
912 }
913 else
914 {
915 evas_object_hide(sd->front.clip);
916 if (sd->back.content)
917 evas_object_show(sd->back.clip);
918 else
919 evas_object_hide(sd->back.clip);
920 }
921 }
922 }
923
924 static void
_map_uv_set(Evas_Object * obj,Evas_Map * map)925 _map_uv_set(Evas_Object *obj, Evas_Map *map)
926 {
927 Evas_Coord x, y, w, h;
928
929 // FIXME: only handles filled obj
930 if (efl_isa(obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS) &&
931 !evas_object_image_source_get(obj))
932 {
933 int iw, ih;
934 evas_object_image_size_get(obj, &iw, &ih);
935 evas_object_geometry_get(obj, &x, &y, &w, &h);
936 evas_map_util_points_populate_from_geometry(map, x, y, w, h, 0);
937 evas_map_point_image_uv_set(map, 0, 0, 0);
938 evas_map_point_image_uv_set(map, 1, iw, 0);
939 evas_map_point_image_uv_set(map, 2, iw, ih);
940 evas_map_point_image_uv_set(map, 3, 0, ih);
941 }
942 else
943 {
944 evas_object_geometry_get(obj, &x, &y, &w, &h);
945 evas_map_util_points_populate_from_geometry(map, x, y, w, h, 0);
946 }
947 }
948
949 static void
_flip_do(Evas_Object * obj,double t,Elm_Flip_Mode mode,int lin,int rev)950 _flip_do(Evas_Object *obj,
951 double t,
952 Elm_Flip_Mode mode,
953 int lin,
954 int rev)
955 {
956 double p, deg, pp;
957 Evas_Map *mf, *mb;
958 Evas_Coord x, y, w, h;
959 Evas_Coord cx, cy, px, py, foc;
960 int lx, ly, lz, lr, lg, lb, lar, lag, lab;
961
962 EFL_UI_FLIP_DATA_GET(obj, sd);
963
964 mf = evas_map_new(4);
965 evas_map_smooth_set(mf, EINA_FALSE);
966 mb = evas_map_new(4);
967 evas_map_smooth_set(mb, EINA_FALSE);
968
969 if (sd->front.content)
970 _map_uv_set(sd->front.content, mf);
971 if (sd->back.content)
972 _map_uv_set(sd->back.content, mb);
973
974 evas_object_geometry_get(obj, &x, &y, &w, &h);
975
976 cx = x + (w / 2);
977 cy = y + (h / 2);
978
979 px = x + (w / 2);
980 py = y + (h / 2);
981 foc = 2048;
982
983 lx = cx;
984 ly = cy;
985 lz = -10000;
986 lr = 255;
987 lg = 255;
988 lb = 255;
989 lar = 0;
990 lag = 0;
991 lab = 0;
992
993 switch (mode)
994 {
995 case ELM_FLIP_ROTATE_Y_CENTER_AXIS:
996 p = 1.0 - t;
997 pp = p;
998 if (!lin) pp = (p * p);
999 p = 1.0 - pp;
1000 if (sd->state) deg = 180.0 * p;
1001 else deg = 180 + (180.0 * p);
1002 if (rev) deg = -deg;
1003 evas_map_util_3d_rotate(mf, 0.0, deg, 0.0, cx, cy, 0);
1004 evas_map_util_3d_rotate(mb, 0.0, 180 + deg, 0.0, cx, cy, 0);
1005 break;
1006
1007 case ELM_FLIP_ROTATE_X_CENTER_AXIS:
1008 p = 1.0 - t;
1009 pp = p;
1010 if (!lin) pp = (p * p);
1011 p = 1.0 - pp;
1012 if (sd->state) deg = 180.0 * p;
1013 else deg = 180 + (180.0 * p);
1014 if (rev) deg = -deg;
1015 evas_map_util_3d_rotate(mf, deg, 0.0, 0.0, cx, cy, 0);
1016 evas_map_util_3d_rotate(mb, 180.0 + deg, 0.0, 0.0, cx, cy, 0);
1017 break;
1018
1019 case ELM_FLIP_ROTATE_XZ_CENTER_AXIS:
1020 p = 1.0 - t;
1021 pp = p;
1022 if (!lin) pp = (p * p);
1023 p = 1.0 - pp;
1024 if (sd->state) deg = 180.0 * p;
1025 else deg = 180 + (180.0 * p);
1026 if (rev) deg = -deg;
1027 evas_map_util_3d_rotate(mf, deg, 0.0, deg, cx, cy, 0);
1028 evas_map_util_3d_rotate(mb, 180 + deg, 0.0, 180 + deg, cx, cy, 0);
1029 break;
1030
1031 case ELM_FLIP_ROTATE_YZ_CENTER_AXIS:
1032 p = 1.0 - t;
1033 pp = p;
1034 if (!lin) pp = (p * p);
1035 p = 1.0 - pp;
1036 if (sd->state) deg = 180.0 * p;
1037 else deg = 180 + (180.0 * p);
1038 if (rev) deg = -deg;
1039 evas_map_util_3d_rotate(mf, 0.0, deg, deg, cx, cy, 0);
1040 evas_map_util_3d_rotate(mb, 0.0, 180.0 + deg, 180.0 + deg, cx, cy, 0);
1041 break;
1042
1043 case ELM_FLIP_CUBE_LEFT:
1044 p = 1.0 - t;
1045 pp = p;
1046 if (!lin) pp = (p * p);
1047 p = 1.0 - pp;
1048 deg = -90.0 * p;
1049 if (sd->state)
1050 {
1051 evas_map_util_3d_rotate(mf, 0.0, deg, 0.0, cx, cy, w / 2);
1052 evas_map_util_3d_rotate(mb, 0.0, deg + 90, 0.0, cx, cy, w / 2);
1053 }
1054 else
1055 {
1056 evas_map_util_3d_rotate(mf, 0.0, deg + 90, 0.0, cx, cy, w / 2);
1057 evas_map_util_3d_rotate(mb, 0.0, deg, 0.0, cx, cy, w / 2);
1058 }
1059 break;
1060
1061 case ELM_FLIP_CUBE_RIGHT:
1062 p = 1.0 - t;
1063 pp = p;
1064 if (!lin) pp = (p * p);
1065 p = 1.0 - pp;
1066 deg = 90.0 * p;
1067 if (sd->state)
1068 {
1069 evas_map_util_3d_rotate(mf, 0.0, deg, 0.0, cx, cy, w / 2);
1070 evas_map_util_3d_rotate(mb, 0.0, deg - 90, 0.0, cx, cy, w / 2);
1071 }
1072 else
1073 {
1074 evas_map_util_3d_rotate(mf, 0.0, deg - 90, 0.0, cx, cy, w / 2);
1075 evas_map_util_3d_rotate(mb, 0.0, deg, 0.0, cx, cy, w / 2);
1076 }
1077 break;
1078
1079 case ELM_FLIP_CUBE_UP:
1080 p = 1.0 - t;
1081 pp = p;
1082 if (!lin) pp = (p * p);
1083 p = 1.0 - pp;
1084 deg = -90.0 * p;
1085 if (sd->state)
1086 {
1087 evas_map_util_3d_rotate(mf, deg, 0.0, 0.0, cx, cy, h / 2);
1088 evas_map_util_3d_rotate(mb, deg + 90, 0.0, 0.0, cx, cy, h / 2);
1089 }
1090 else
1091 {
1092 evas_map_util_3d_rotate(mf, deg + 90, 0.0, 0.0, cx, cy, h / 2);
1093 evas_map_util_3d_rotate(mb, deg, 0.0, 0.0, cx, cy, h / 2);
1094 }
1095 break;
1096
1097 case ELM_FLIP_CUBE_DOWN:
1098 p = 1.0 - t;
1099 pp = p;
1100 if (!lin) pp = (p * p);
1101 p = 1.0 - pp;
1102 deg = 90.0 * p;
1103 if (sd->state)
1104 {
1105 evas_map_util_3d_rotate(mf, deg, 0.0, 0.0, cx, cy, h / 2);
1106 evas_map_util_3d_rotate(mb, deg - 90, 0.0, 0.0, cx, cy, h / 2);
1107 }
1108 else
1109 {
1110 evas_map_util_3d_rotate(mf, deg - 90, 0.0, 0.0, cx, cy, h / 2);
1111 evas_map_util_3d_rotate(mb, deg, 0.0, 0.0, cx, cy, h / 2);
1112 }
1113 break;
1114
1115 case ELM_FLIP_PAGE_LEFT:
1116 break;
1117
1118 case ELM_FLIP_PAGE_RIGHT:
1119 break;
1120
1121 case ELM_FLIP_PAGE_UP:
1122 break;
1123
1124 case ELM_FLIP_PAGE_DOWN:
1125 break;
1126
1127 default:
1128 break;
1129 }
1130
1131 if (sd->front.content)
1132 {
1133 evas_map_util_3d_lighting(mf, lx, ly, lz, lr, lg, lb, lar, lag, lab);
1134 evas_map_util_3d_perspective(mf, px, py, 0, foc);
1135 evas_object_map_set(sd->front.content, mf);
1136 evas_object_map_enable_set(sd->front.content, EINA_TRUE);
1137 if (evas_map_util_clockwise_get(mf)) evas_object_show(sd->front.clip);
1138 else evas_object_hide(sd->front.clip);
1139 }
1140
1141 if (sd->back.content)
1142 {
1143 evas_map_util_3d_lighting(mb, lx, ly, lz, lr, lg, lb, lar, lag, lab);
1144 evas_map_util_3d_perspective(mb, px, py, 0, foc);
1145 evas_object_map_set(sd->back.content, mb);
1146 evas_object_map_enable_set(sd->back.content, EINA_TRUE);
1147 if (evas_map_util_clockwise_get(mb)) evas_object_show(sd->back.clip);
1148 else evas_object_hide(sd->back.clip);
1149 }
1150
1151 evas_map_free(mf);
1152 evas_map_free(mb);
1153 }
1154
1155 static void
_show_hide(Evas_Object * obj)1156 _show_hide(Evas_Object *obj)
1157 {
1158 EFL_UI_FLIP_DATA_GET(obj, sd);
1159 Evas_Coord x, y, w, h;
1160 if (!sd) return;
1161
1162 evas_object_geometry_get(obj, &x, &y, &w, &h);
1163 if (sd->front.content)
1164 {
1165 if ((sd->pageflip) && (sd->state))
1166 {
1167 evas_object_move(sd->front.content, 4999, 4999);
1168 }
1169 else
1170 {
1171 if (!sd->animator)
1172 evas_object_move(sd->front.content, x, y);
1173 }
1174 evas_object_resize(sd->front.content, w, h);
1175 }
1176 if (sd->back.content)
1177 {
1178 if ((sd->pageflip) && (!sd->state))
1179 {
1180 evas_object_move(sd->back.content, 4999, 4999);
1181 }
1182 else
1183 {
1184 if (!sd->animator)
1185 evas_object_move(sd->back.content, x, y);
1186 }
1187 evas_object_resize(sd->back.content, w, h);
1188 }
1189 }
1190
1191 static void
_configure(Evas_Object * obj)1192 _configure(Evas_Object *obj)
1193 {
1194 Evas_Coord x, y, w, h;
1195 Evas_Coord fsize;
1196
1197 EFL_UI_FLIP_DATA_GET(obj, sd);
1198 _show_hide(obj);
1199 evas_object_geometry_get(obj, &x, &y, &w, &h);
1200 // FIXME: manual flip wont get fixed
1201 if (sd->animator) _flip(obj);
1202
1203 if (sd->event[0])
1204 {
1205 fsize = (double)w * sd->dir_hitsize[0];
1206 elm_coords_finger_size_adjust(0, NULL, 1, &fsize);
1207 evas_object_geometry_set(sd->event[0], x, y, w, fsize);
1208 }
1209 if (sd->event[1])
1210 {
1211 fsize = (double)w * sd->dir_hitsize[1];
1212 elm_coords_finger_size_adjust(0, NULL, 1, &fsize);
1213 evas_object_geometry_set(sd->event[1], x, y + h - fsize, w, fsize);
1214 }
1215 if (sd->event[2])
1216 {
1217 fsize = (double)h * sd->dir_hitsize[2];
1218 elm_coords_finger_size_adjust(1, &fsize, 0, NULL);
1219 evas_object_geometry_set(sd->event[2], x, y, fsize, h);
1220 }
1221 if (sd->event[3])
1222 {
1223 fsize = (double)h * sd->dir_hitsize[3];
1224 elm_coords_finger_size_adjust(1, &fsize, 0, NULL);
1225 evas_object_geometry_set(sd->event[3], x + w - fsize, y, fsize, h);
1226 }
1227 }
1228
1229 static Eina_Bool
_flip(Evas_Object * obj)1230 _flip(Evas_Object *obj)
1231 {
1232 double t;
1233 Evas_Coord w, h;
1234
1235 EFL_UI_FLIP_DATA_GET(obj, sd);
1236
1237 t = ecore_loop_time_get() - sd->start;
1238
1239 if (!sd->animator) return ECORE_CALLBACK_CANCEL;
1240
1241 t = t / sd->len;
1242 if (t > 1.0) t = 1.0;
1243 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1244 if (!sd->manual)
1245 {
1246 if (sd->mode == ELM_FLIP_PAGE_LEFT)
1247 {
1248 sd->dir = ELM_FLIP_DIRECTION_LEFT;
1249 sd->started = EINA_TRUE;
1250 sd->pageflip = EINA_TRUE;
1251 sd->down_x = w - 1;
1252 sd->down_y = h / 2;
1253 sd->x = (1.0 - t) * sd->down_x;
1254 sd->y = sd->down_y;
1255 _flip_show_hide(obj);
1256 _state_update(obj);
1257 }
1258 else if (sd->mode == ELM_FLIP_PAGE_RIGHT)
1259 {
1260 sd->dir = ELM_FLIP_DIRECTION_RIGHT;
1261 sd->started = EINA_TRUE;
1262 sd->pageflip = EINA_TRUE;
1263 sd->down_x = 0;
1264 sd->down_y = h / 2;
1265 sd->x = (t) * w;
1266 sd->y = sd->down_y;
1267 _flip_show_hide(obj);
1268 _state_update(obj);
1269 }
1270 else if (sd->mode == ELM_FLIP_PAGE_UP)
1271 {
1272 sd->dir = ELM_FLIP_DIRECTION_UP;
1273 sd->started = EINA_TRUE;
1274 sd->pageflip = EINA_TRUE;
1275 sd->down_x = w / 2;
1276 sd->down_y = h - 1;
1277 sd->x = sd->down_x;
1278 sd->y = (1.0 - t) * sd->down_y;
1279 _flip_show_hide(obj);
1280 _state_update(obj);
1281 }
1282 else if (sd->mode == ELM_FLIP_PAGE_DOWN)
1283 {
1284 sd->dir = ELM_FLIP_DIRECTION_DOWN;
1285 sd->started = EINA_TRUE;
1286 sd->pageflip = EINA_TRUE;
1287 sd->down_x = w / 2;
1288 sd->down_y = 0;
1289 sd->x = sd->down_x;
1290 sd->y = (t) * h;
1291 _flip_show_hide(obj);
1292 _state_update(obj);
1293 }
1294 else if (sd->mode == ELM_FLIP_CROSS_FADE)
1295 {
1296 sd->dir = 0;
1297 sd->started = EINA_TRUE;
1298 sd->pageflip = EINA_FALSE;
1299 _cross_fade_update(obj, t);
1300 }
1301 else
1302 _flip_do(obj, t, sd->mode, 0, 0);
1303 }
1304
1305 if (t >= 1.0)
1306 {
1307 #if 0 // this breaks manual flipping. :/
1308 if (sd->state == sd->next_state)
1309 {
1310 /* it was flipped while flipping, do it again */
1311 sd->start = ecore_loop_time_get();
1312 sd->state = !sd->next_state;
1313 return ECORE_CALLBACK_RENEW;
1314 }
1315 #endif
1316 sd->pageflip = EINA_FALSE;
1317 _state_end(sd);
1318 evas_object_map_enable_set(sd->front.content, EINA_FALSE);
1319 evas_object_map_enable_set(sd->back.content, EINA_FALSE);
1320 // FIXME: hack around evas rendering bug (only fix makes evas bitch-slow
1321 evas_object_resize(sd->front.content, 0, 0);
1322 evas_object_resize(sd->back.content, 0, 0);
1323 evas_smart_objects_calculate(evas_object_evas_get(obj));
1324 // FIXME: end hack
1325 sd->animator = NULL;
1326 if (((sd->manual) && (sd->finish)) || (!sd->manual))
1327 sd->state = sd->next_state;
1328 _configure(obj);
1329 _flip_show_hide(obj);
1330
1331 if (sd->mode == ELM_FLIP_CROSS_FADE)
1332 {
1333 // Make the content fully opaque again
1334 evas_object_color_set(sd->front.clip, 255, 255, 255, 255);
1335 evas_object_color_set(sd->back.clip, 255, 255, 255, 255);
1336 }
1337
1338 efl_event_callback_legacy_call(obj, EFL_UI_FLIP_EVENT_ANIMATE_DONE, NULL);
1339
1340 // update the new front and back object.
1341 _update_front_back(obj, sd);
1342
1343 return ECORE_CALLBACK_CANCEL;
1344 }
1345
1346 return ECORE_CALLBACK_RENEW;
1347 }
1348
1349 /* we have to have move/resize info up-to-date on those events. it
1350 * happens that smarts callbacks on them happen before we have the new
1351 * values, so using event callbacks instead */
1352 static void
_on_move(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)1353 _on_move(void *data EINA_UNUSED,
1354 Evas *e EINA_UNUSED,
1355 Evas_Object *obj,
1356 void *event_info EINA_UNUSED)
1357 {
1358 _configure(obj);
1359 }
1360
1361 static void
_on_resize(void * data EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)1362 _on_resize(void *data EINA_UNUSED,
1363 Evas *e EINA_UNUSED,
1364 Evas_Object *obj,
1365 void *event_info EINA_UNUSED)
1366 {
1367 _configure(obj);
1368 }
1369
1370 static Eina_Bool
_animate(void * data)1371 _animate(void *data)
1372 {
1373 return _flip(data);
1374 }
1375
1376 static double
_pos_get(Evas_Object * obj,Efl_Ui_Flip_Data * sd,int * rev,Elm_Flip_Mode * m)1377 _pos_get(Evas_Object *obj,
1378 Efl_Ui_Flip_Data *sd,
1379 int *rev,
1380 Elm_Flip_Mode *m)
1381 {
1382 Evas_Coord x, y, w, h;
1383 double t = 1.0;
1384
1385 evas_object_geometry_get(obj, &x, &y, &w, &h);
1386 switch (sd->intmode)
1387 {
1388 case EFL_UI_FLIP_INTERACTION_ROTATE:
1389 case EFL_UI_FLIP_INTERACTION_CUBE:
1390 {
1391 if (sd->dir == ELM_FLIP_DIRECTION_LEFT)
1392 {
1393 if (sd->down_x > 0)
1394 t = 1.0 - ((double)sd->x / (double)sd->down_x);
1395 *rev = 1;
1396 }
1397 else if (sd->dir == ELM_FLIP_DIRECTION_RIGHT)
1398 {
1399 if (sd->down_x < w)
1400 t = 1.0 - ((double)(w - sd->x) / (double)(w - sd->down_x));
1401 }
1402 else if (sd->dir == ELM_FLIP_DIRECTION_UP)
1403 {
1404 if (sd->down_y > 0)
1405 t = 1.0 - ((double)sd->y / (double)sd->down_y);
1406 }
1407 else if (sd->dir == ELM_FLIP_DIRECTION_DOWN)
1408 {
1409 if (sd->down_y < h)
1410 t = 1.0 - ((double)(h - sd->y) / (double)(h - sd->down_y));
1411 *rev = 1;
1412 }
1413
1414 if (t < 0.0) t = 0.0;
1415 else if (t > 1.0)
1416 t = 1.0;
1417
1418 if ((sd->dir == ELM_FLIP_DIRECTION_LEFT) ||
1419 (sd->dir == ELM_FLIP_DIRECTION_RIGHT))
1420 {
1421 if (sd->intmode == EFL_UI_FLIP_INTERACTION_ROTATE)
1422 *m = ELM_FLIP_ROTATE_Y_CENTER_AXIS;
1423 else if (sd->intmode == EFL_UI_FLIP_INTERACTION_CUBE)
1424 {
1425 if (*rev)
1426 *m = ELM_FLIP_CUBE_LEFT;
1427 else
1428 *m = ELM_FLIP_CUBE_RIGHT;
1429 }
1430 }
1431 else
1432 {
1433 if (sd->intmode == EFL_UI_FLIP_INTERACTION_ROTATE)
1434 *m = ELM_FLIP_ROTATE_X_CENTER_AXIS;
1435 else if (sd->intmode == EFL_UI_FLIP_INTERACTION_CUBE)
1436 {
1437 if (*rev)
1438 *m = ELM_FLIP_CUBE_UP;
1439 else
1440 *m = ELM_FLIP_CUBE_DOWN;
1441 }
1442 }
1443 }
1444
1445 default:
1446 break;
1447 }
1448 return t;
1449 }
1450
1451 static Eina_Bool
_event_anim(void * data,double pos)1452 _event_anim(void *data,
1453 double pos)
1454 {
1455 Efl_Ui_Flip_Data *sd = data;
1456 double p;
1457
1458 p = ecore_animator_pos_map(pos, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
1459 if (sd->finish)
1460 {
1461 if (sd->dir == ELM_FLIP_DIRECTION_LEFT)
1462 sd->x = sd->ox * (1.0 - p);
1463 else if (sd->dir == ELM_FLIP_DIRECTION_RIGHT)
1464 sd->x = sd->ox + ((sd->w - sd->ox) * p);
1465 else if (sd->dir == ELM_FLIP_DIRECTION_UP)
1466 sd->y = sd->oy * (1.0 - p);
1467 else if (sd->dir == ELM_FLIP_DIRECTION_DOWN)
1468 sd->y = sd->oy + ((sd->h - sd->oy) * p);
1469 }
1470 else
1471 {
1472 if (sd->dir == ELM_FLIP_DIRECTION_LEFT)
1473 sd->x = sd->ox + ((sd->w - sd->ox) * p);
1474 else if (sd->dir == ELM_FLIP_DIRECTION_RIGHT)
1475 sd->x = sd->ox * (1.0 - p);
1476 else if (sd->dir == ELM_FLIP_DIRECTION_UP)
1477 sd->y = sd->oy + ((sd->h - sd->oy) * p);
1478 else if (sd->dir == ELM_FLIP_DIRECTION_DOWN)
1479 sd->y = sd->oy * (1.0 - p);
1480 }
1481 switch (sd->intmode)
1482 {
1483 case EFL_UI_FLIP_INTERACTION_NONE:
1484 break;
1485
1486 case EFL_UI_FLIP_INTERACTION_ROTATE:
1487 case EFL_UI_FLIP_INTERACTION_CUBE:
1488 {
1489 Elm_Flip_Mode m = ELM_FLIP_ROTATE_X_CENTER_AXIS;
1490 int rev = 0;
1491 p = _pos_get(sd->obj, sd, &rev, &m);
1492 _flip_do(sd->obj, p, m, 1, rev);
1493 }
1494 break;
1495
1496 case EFL_UI_FLIP_INTERACTION_PAGE:
1497 sd->pageflip = EINA_TRUE;
1498 _configure(sd->obj);
1499 _state_update(sd->obj);
1500 break;
1501
1502 default:
1503 break;
1504 }
1505 if (pos < 1.0) return ECORE_CALLBACK_RENEW;
1506
1507 sd->pageflip = EINA_FALSE;
1508 _state_end(sd);
1509 evas_object_map_enable_set(sd->front.content, EINA_FALSE);
1510 evas_object_map_enable_set(sd->back.content, EINA_FALSE);
1511 // FIXME: hack around evas rendering bug (only fix makes evas bitch-slow
1512 evas_object_resize(sd->front.content, 0, 0);
1513 evas_object_resize(sd->back.content, 0, 0);
1514 evas_smart_objects_calculate
1515 (evas_object_evas_get(sd->obj));
1516 // FIXME: end hack
1517 sd->animator = NULL;
1518 if (sd->finish) sd->state = sd->next_state;
1519 _flip_show_hide(sd->obj);
1520 _configure(sd->obj);
1521 sd->animator = NULL;
1522 efl_event_callback_legacy_call
1523 (sd->obj, EFL_UI_FLIP_EVENT_ANIMATE_DONE, NULL);
1524
1525 return ECORE_CALLBACK_CANCEL;
1526 }
1527
1528 static void
_update_job(void * data)1529 _update_job(void *data)
1530 {
1531 Elm_Flip_Mode m = ELM_FLIP_ROTATE_X_CENTER_AXIS;
1532 Evas_Object *obj = data;
1533 Efl_Ui_Flip_Data *sd = efl_data_scope_get(obj, MY_CLASS);
1534 int rev = 0;
1535 double p;
1536
1537 sd->job = NULL;
1538 switch (sd->intmode)
1539 {
1540 case EFL_UI_FLIP_INTERACTION_ROTATE:
1541 case EFL_UI_FLIP_INTERACTION_CUBE:
1542 p = _pos_get(obj, sd, &rev, &m);
1543 _flip_do(obj, p, m, 1, rev);
1544 break;
1545
1546 case EFL_UI_FLIP_INTERACTION_PAGE:
1547 sd->pageflip = EINA_TRUE;
1548 _configure(obj);
1549 _state_update(obj);
1550 break;
1551
1552 default:
1553 break;
1554 }
1555 }
1556
1557 static void
_down_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1558 _down_cb(void *data,
1559 Evas *e EINA_UNUSED,
1560 Evas_Object *obj EINA_UNUSED,
1561 void *event_info)
1562 {
1563 Evas_Event_Mouse_Down *ev = event_info;
1564 Evas_Object *fl = data;
1565 Evas_Coord x, y, w, h;
1566
1567 EFL_UI_FLIP_DATA_GET(fl, sd);
1568
1569 if (ev->button != 1) return;
1570 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1571 ELM_SAFE_FREE(sd->animator, ecore_animator_del);
1572 sd->mouse_down = EINA_TRUE;
1573 sd->started = EINA_FALSE;
1574 evas_object_geometry_get(data, &x, &y, &w, &h);
1575 sd->x = ev->canvas.x - x;
1576 sd->y = ev->canvas.y - y;
1577 sd->w = w;
1578 sd->h = h;
1579 sd->down_x = sd->x;
1580 sd->down_y = sd->y;
1581 }
1582
1583 static void
_up_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1584 _up_cb(void *data,
1585 Evas *e EINA_UNUSED,
1586 Evas_Object *obj EINA_UNUSED,
1587 void *event_info)
1588 {
1589 Evas_Event_Mouse_Up *ev = event_info;
1590 Evas_Object *fl = data;
1591 Evas_Coord x, y, w, h;
1592 double tm = 0.5;
1593
1594 EFL_UI_FLIP_DATA_GET(fl, sd);
1595
1596 if (ev->button != 1) return;
1597 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1598 sd->mouse_down = EINA_FALSE;
1599 if (!sd->started) return;
1600 evas_object_geometry_get(data, &x, &y, &w, &h);
1601 sd->x = ev->canvas.x - x;
1602 sd->y = ev->canvas.y - y;
1603 sd->w = w;
1604 sd->h = h;
1605 sd->ox = sd->x;
1606 sd->oy = sd->y;
1607 ELM_SAFE_FREE(sd->job, ecore_job_del);
1608 sd->finish = EINA_FALSE;
1609 if (sd->dir == ELM_FLIP_DIRECTION_LEFT)
1610 {
1611 tm = (double)sd->x / (double)sd->w;
1612 if (sd->x < (sd->w / 2)) sd->finish = EINA_TRUE;
1613 }
1614 else if (sd->dir == ELM_FLIP_DIRECTION_RIGHT)
1615 {
1616 if (sd->x > (sd->w / 2)) sd->finish = EINA_TRUE;
1617 tm = 1.0 - ((double)sd->x / (double)sd->w);
1618 }
1619 else if (sd->dir == ELM_FLIP_DIRECTION_UP)
1620 {
1621 if (sd->y < (sd->h / 2)) sd->finish = EINA_TRUE;
1622 tm = (double)sd->y / (double)sd->h;
1623 }
1624 else if (sd->dir == ELM_FLIP_DIRECTION_DOWN)
1625 {
1626 if (sd->y > (sd->h / 2)) sd->finish = EINA_TRUE;
1627 tm = 1.0 - ((double)sd->y / (double)sd->h);
1628 }
1629 if (tm < 0.01) tm = 0.01;
1630 else if (tm > 0.99) tm = 0.99;
1631 if (!sd->finish) tm = 1.0 - tm;
1632 else sd->next_state = !sd->state;
1633 tm *= 1.0; // FIXME: config for anim time
1634 ecore_animator_del(sd->animator);
1635 sd->animator = ecore_evas_animator_timeline_add(fl, tm, _event_anim, sd);
1636 sd->len = tm;
1637 sd->start = ecore_loop_time_get();
1638 sd->manual = EINA_TRUE;
1639 _event_anim(sd, 0.0);
1640 }
1641
1642 static void
_move_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)1643 _move_cb(void *data,
1644 Evas *e EINA_UNUSED,
1645 Evas_Object *obj EINA_UNUSED,
1646 void *event_info)
1647 {
1648 Evas_Event_Mouse_Move *ev = event_info;
1649 Evas_Object *fl = data;
1650 Evas_Coord x, y, w, h;
1651
1652 EFL_UI_FLIP_DATA_GET(fl, sd);
1653 if (!sd->mouse_down) return;
1654 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1655 evas_object_geometry_get(data, &x, &y, &w, &h);
1656 sd->x = ev->cur.canvas.x - x;
1657 sd->y = ev->cur.canvas.y - y;
1658 sd->w = w;
1659 sd->h = h;
1660 if (!sd->started)
1661 {
1662 Evas_Coord dx, dy;
1663
1664 dx = sd->x - sd->down_x;
1665 dy = sd->y - sd->down_y;
1666 if (((dx * dx) + (dy * dy)) >
1667 (_elm_config->finger_size * _elm_config->finger_size / 4))
1668 {
1669 if ((sd->x > (w / 2)) &&
1670 (dx < 0) && (abs(dx) > abs(dy)))
1671 {
1672 sd->dir = ELM_FLIP_DIRECTION_LEFT;
1673 if (!sd->dir_enabled[ELM_FLIP_DIRECTION_LEFT]) return;
1674 }
1675 else if ((sd->x < (w / 2)) && (dx >= 0) &&
1676 (abs(dx) > abs(dy)))
1677 {
1678 sd->dir = ELM_FLIP_DIRECTION_RIGHT;
1679 if (!sd->dir_enabled[ELM_FLIP_DIRECTION_RIGHT]) return;
1680 }
1681 else if ((sd->y > (h / 2)) && (dy < 0) && (abs(dy) >= abs(dx)))
1682 {
1683 sd->dir = ELM_FLIP_DIRECTION_UP;
1684 if (!sd->dir_enabled[ELM_FLIP_DIRECTION_UP]) return;
1685 }
1686 else if ((sd->y < (h / 2)) && (dy >= 0) && (abs(dy) >= abs(dx)))
1687 {
1688 sd->dir = ELM_FLIP_DIRECTION_DOWN;
1689 if (!sd->dir_enabled[ELM_FLIP_DIRECTION_DOWN]) return;
1690 }
1691 else return;
1692
1693 sd->started = EINA_TRUE;
1694 if (sd->intmode == EFL_UI_FLIP_INTERACTION_PAGE)
1695 sd->pageflip = EINA_TRUE;
1696 _flip_show_hide(data);
1697 evas_smart_objects_calculate(evas_object_evas_get(data));
1698 _flip(data);
1699 // FIXME: hack around evas rendering bug (only fix makes
1700 // evas bitch-slow)
1701 evas_object_map_enable_set(sd->front.content, EINA_FALSE);
1702 evas_object_map_enable_set(sd->back.content, EINA_FALSE);
1703 // FIXME: XXX why does this bork interactive flip??
1704 // evas_object_resize(sd->front.content, 0, 0);
1705 // evas_object_resize(sd->back.content, 0, 0);
1706 evas_smart_objects_calculate(evas_object_evas_get(data));
1707 _configure(fl);
1708 // FIXME: end hack
1709 efl_event_callback_legacy_call(fl, EFL_UI_FLIP_EVENT_ANIMATE_BEGIN, NULL);
1710 }
1711 else return;
1712 }
1713
1714 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1715 ecore_job_del(sd->job);
1716 sd->job = ecore_job_add(_update_job, fl);
1717 }
1718
1719 static Eina_Bool
_flip_content_set(Evas_Object * obj,Evas_Object * content,Eina_Bool front)1720 _flip_content_set(Evas_Object *obj,
1721 Evas_Object *content,
1722 Eina_Bool front)
1723 {
1724 int i;
1725 Evas_Object **cont;
1726
1727 EFL_UI_FLIP_DATA_GET(obj, sd);
1728
1729 cont = front ? &(sd->front.content) : &(sd->back.content);
1730
1731 if (*cont == content) return EINA_TRUE;
1732
1733 evas_object_del(*cont);
1734 *cont = content;
1735
1736 if (content)
1737 {
1738 elm_widget_sub_object_add(obj, content);
1739 //evas_object_smart_member_add(content, obj);
1740 evas_object_clip_set
1741 (content, front ? sd->front.clip : sd->back.clip);
1742 if (efl_isa(content, EFL_UI_WIDGET_CLASS) && sd->state != front)
1743 elm_widget_tree_unfocusable_set(content, EINA_TRUE);
1744 }
1745
1746 // force calc to contents are the right size before transition
1747 evas_smart_objects_calculate(evas_object_evas_get(obj));
1748 //evas_object_smart_calculate(obj);
1749 _flip_show_hide(obj);
1750 _configure(obj);
1751 _sizing_eval(obj);
1752
1753 if (sd->intmode != EFL_UI_FLIP_INTERACTION_NONE)
1754 {
1755 for (i = 0; i < 4; i++)
1756 evas_object_raise(sd->event[i]);
1757 }
1758
1759 return EINA_TRUE;
1760 }
1761
1762 static Evas_Object *
_flip_content_unset(Evas_Object * obj,Eina_Bool front)1763 _flip_content_unset(Evas_Object *obj,
1764 Eina_Bool front)
1765 {
1766 Evas_Object *content;
1767 Evas_Object **cont;
1768
1769 EFL_UI_FLIP_DATA_GET(obj, sd);
1770
1771 cont = front ? &(sd->front.content) : &(sd->back.content);
1772
1773 if (!*cont) return NULL;
1774
1775 content = *cont;
1776 _elm_widget_sub_object_redirect_to_top(obj, content);
1777
1778 return content;
1779 }
1780
1781 static Eina_Bool
_efl_ui_flip_content_set(Eo * obj,Efl_Ui_Flip_Data * _pd EINA_UNUSED,const char * part,Evas_Object * content)1782 _efl_ui_flip_content_set(Eo *obj, Efl_Ui_Flip_Data *_pd EINA_UNUSED, const char *part, Evas_Object *content)
1783 {
1784 if (!part || !strcmp(part, "front"))
1785 return _flip_content_set(obj, content, EINA_TRUE);
1786 else if (!strcmp(part, "back"))
1787 return _flip_content_set(obj, content, EINA_FALSE);
1788 return EINA_FALSE;
1789 }
1790
1791 static Evas_Object*
_efl_ui_flip_content_get(Eo * obj EINA_UNUSED,Efl_Ui_Flip_Data * sd,const char * part)1792 _efl_ui_flip_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Flip_Data *sd, const char *part)
1793 {
1794 if (!part || !strcmp(part, "front"))
1795 return sd->front.content;
1796 else if (!strcmp(part, "back"))
1797 return sd->back.content;
1798 return NULL;
1799 }
1800
1801 static Evas_Object*
_efl_ui_flip_content_unset(Eo * obj EINA_UNUSED,Efl_Ui_Flip_Data * _pd EINA_UNUSED,const char * part)1802 _efl_ui_flip_content_unset(Eo *obj EINA_UNUSED, Efl_Ui_Flip_Data *_pd EINA_UNUSED, const char *part)
1803 {
1804 if (!part || !strcmp(part, "front"))
1805 return _flip_content_unset(obj, EINA_TRUE);
1806 else if (!strcmp(part, "back"))
1807 return _flip_content_unset(obj, EINA_FALSE);
1808 return NULL;
1809 }
1810
1811 EOLIAN static void
_efl_ui_flip_efl_canvas_group_group_add(Eo * obj,Efl_Ui_Flip_Data * priv)1812 _efl_ui_flip_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Flip_Data *priv)
1813 {
1814 efl_canvas_group_add(efl_super(obj, MY_CLASS));
1815
1816 priv->clip = evas_object_rectangle_add(evas_object_evas_get(obj));
1817 evas_object_static_clip_set(priv->clip, EINA_TRUE);
1818 evas_object_geometry_set(priv->clip, -49999, -49999, 99999, 99999);
1819 evas_object_smart_member_add(priv->clip, obj);
1820
1821 priv->front.clip = evas_object_rectangle_add(evas_object_evas_get(obj));
1822 evas_object_static_clip_set(priv->front.clip, EINA_TRUE);
1823 evas_object_data_set(priv->front.clip, "_elm_leaveme", obj);
1824 evas_object_geometry_set(priv->front.clip, -49999, -49999, 99999, 99999);
1825 evas_object_smart_member_add(priv->front.clip, obj);
1826 evas_object_clip_set(priv->front.clip, priv->clip);
1827
1828 priv->back.clip = evas_object_rectangle_add(evas_object_evas_get(obj));
1829 evas_object_static_clip_set(priv->back.clip, EINA_TRUE);
1830 evas_object_data_set(priv->back.clip, "_elm_leaveme", obj);
1831 evas_object_geometry_set(priv->back.clip, -49999, -49999, 99999, 99999);
1832 evas_object_smart_member_add(priv->back.clip, obj);
1833 evas_object_clip_set(priv->back.clip, priv->clip);
1834
1835 evas_object_event_callback_add
1836 (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints_cb, obj);
1837
1838 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _on_resize, NULL);
1839 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _on_move, NULL);
1840
1841 priv->state = EINA_TRUE;
1842 priv->next_state = EINA_TRUE;
1843 priv->intmode = EFL_UI_FLIP_INTERACTION_NONE;
1844
1845 elm_widget_can_focus_set(obj, EINA_FALSE);
1846 }
1847
1848 EOLIAN static void
_efl_ui_flip_efl_canvas_group_group_del(Eo * obj,Efl_Ui_Flip_Data * sd)1849 _efl_ui_flip_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Flip_Data *sd)
1850 {
1851 ecore_animator_del(sd->animator);
1852 _state_slices_clear(sd);
1853
1854 efl_canvas_group_del(efl_super(obj, MY_CLASS));
1855 }
1856
1857 EOLIAN static Eo *
_efl_ui_flip_efl_object_constructor(Eo * obj,Efl_Ui_Flip_Data * sd)1858 _efl_ui_flip_efl_object_constructor(Eo *obj, Efl_Ui_Flip_Data *sd)
1859 {
1860 obj = efl_constructor(efl_super(obj, MY_CLASS));
1861 sd->obj = obj;
1862
1863 evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
1864 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_PAGE_TAB_LIST);
1865
1866 return obj;
1867 }
1868
1869 EOLIAN static Eina_Bool
_efl_ui_flip_front_visible_get(const Eo * obj EINA_UNUSED,Efl_Ui_Flip_Data * sd)1870 _efl_ui_flip_front_visible_get(const Eo *obj EINA_UNUSED, Efl_Ui_Flip_Data *sd)
1871 {
1872 return sd->state;
1873 }
1874
1875 EAPI void
elm_flip_perspective_set(Evas_Object * obj,Evas_Coord foc EINA_UNUSED,Evas_Coord x EINA_UNUSED,Evas_Coord y EINA_UNUSED)1876 elm_flip_perspective_set(Evas_Object *obj,
1877 Evas_Coord foc EINA_UNUSED,
1878 Evas_Coord x EINA_UNUSED,
1879 Evas_Coord y EINA_UNUSED)
1880 {
1881 EFL_UI_FLIP_CHECK(obj);
1882 }
1883
1884 // FIXME: add ambient and lighting control
1885
1886 static void
_internal_elm_flip_go_to(Evas_Object * obj,Efl_Ui_Flip_Data * sd,Eina_Bool front,Elm_Flip_Mode mode)1887 _internal_elm_flip_go_to(Evas_Object *obj,
1888 Efl_Ui_Flip_Data *sd,
1889 Eina_Bool front,
1890 Elm_Flip_Mode mode)
1891 {
1892 if (!sd->animator) sd->animator = ecore_evas_animator_add(obj, _animate, obj);
1893
1894 sd->mode = mode;
1895 sd->start = ecore_loop_time_get();
1896 sd->next_state = front;
1897 sd->len = 0.5; // FIXME: make config val
1898 sd->manual = EINA_FALSE;
1899 if ((sd->mode == ELM_FLIP_PAGE_LEFT) ||
1900 (sd->mode == ELM_FLIP_PAGE_RIGHT) ||
1901 (sd->mode == ELM_FLIP_PAGE_UP) ||
1902 (sd->mode == ELM_FLIP_PAGE_DOWN))
1903 sd->pageflip = EINA_TRUE;
1904 // force calc to contents are the right size before transition
1905 evas_smart_objects_calculate(evas_object_evas_get(obj));
1906
1907 if (sd->mode == ELM_FLIP_CROSS_FADE)
1908 {
1909 // Convention: a is fading in, b is fading out
1910 Evas_Object *a, *b;
1911 if (front)
1912 {
1913 a = sd->front.content;
1914 b = sd->back.content;
1915 }
1916 else
1917 {
1918 a = sd->back.content;
1919 b = sd->front.content;
1920 }
1921
1922 // Stack fade-in content on top of fade-out content
1923 if (a && b) evas_object_stack_above(a, b);
1924
1925 evas_object_show(sd->front.clip);
1926 evas_object_show(sd->back.clip);
1927 }
1928 else
1929 {
1930 _flip_show_hide(obj);
1931 }
1932
1933 _flip(obj);
1934 // FIXME: hack around evas rendering bug (only fix makes evas bitch-slow)
1935 evas_object_map_enable_set(sd->front.content, EINA_FALSE);
1936 evas_object_map_enable_set(sd->back.content, EINA_FALSE);
1937 evas_object_resize(sd->front.content, 0, 0);
1938 evas_object_resize(sd->back.content, 0, 0);
1939 evas_smart_objects_calculate(evas_object_evas_get(obj));
1940 _configure(obj);
1941 // FIXME: end hack
1942
1943 efl_event_callback_legacy_call(obj, EFL_UI_FLIP_EVENT_ANIMATE_BEGIN, NULL);
1944
1945 // set focus to the content object when flip go to is called
1946 if (elm_object_focus_get(obj))
1947 {
1948 if (front) elm_object_focus_set(sd->front.content, EINA_TRUE);
1949 else elm_object_focus_set(sd->back.content, EINA_TRUE);
1950 }
1951
1952 if (sd->front.content && efl_isa(sd->front.content, EFL_UI_WIDGET_CLASS))
1953 elm_widget_tree_unfocusable_set(sd->front.content, !front);
1954 if (sd->back.content && efl_isa(sd->back.content, EFL_UI_WIDGET_CLASS))
1955 elm_widget_tree_unfocusable_set(sd->back.content, front);
1956
1957
1958 }
1959
1960 EOLIAN static void
_efl_ui_flip_go_to(Eo * obj,Efl_Ui_Flip_Data * sd,Eina_Bool front,Efl_Ui_Flip_Mode mode)1961 _efl_ui_flip_go_to(Eo *obj, Efl_Ui_Flip_Data *sd, Eina_Bool front, Efl_Ui_Flip_Mode mode)
1962 {
1963 if (sd->next_state == front) return;
1964
1965 _internal_elm_flip_go_to(obj, sd, front, (Elm_Flip_Mode)mode);
1966 }
1967
1968 EOLIAN static void
_efl_ui_flip_go(Eo * obj,Efl_Ui_Flip_Data * sd,Efl_Ui_Flip_Mode mode)1969 _efl_ui_flip_go(Eo *obj, Efl_Ui_Flip_Data *sd, Efl_Ui_Flip_Mode mode)
1970 {
1971 _internal_elm_flip_go_to(obj, sd, !sd->state, (Elm_Flip_Mode)mode);
1972 }
1973
1974 static void
_event_rect_create(Eo * obj,Efl_Ui_Flip_Data * sd,int i)1975 _event_rect_create(Eo *obj, Efl_Ui_Flip_Data *sd, int i)
1976 {
1977 Evas_Object *clip;
1978 Evas *e;
1979
1980 if (sd->event[i]) return;
1981
1982 e = evas_object_evas_get(obj);
1983 sd->event[i] = evas_object_rectangle_add(e);
1984
1985 clip = evas_object_clip_get(obj);
1986 evas_object_data_set(sd->event[i], "_elm_leaveme", obj);
1987 evas_object_clip_set(sd->event[i], clip);
1988 evas_object_color_set(sd->event[i], 0, 0, 0, 0);
1989 evas_object_show(sd->event[i]);
1990 evas_object_smart_member_add(sd->event[i], obj);
1991 evas_object_event_callback_add
1992 (sd->event[i], EVAS_CALLBACK_MOUSE_DOWN, _down_cb, obj);
1993 evas_object_event_callback_add
1994 (sd->event[i], EVAS_CALLBACK_MOUSE_UP, _up_cb, obj);
1995 evas_object_event_callback_add
1996 (sd->event[i], EVAS_CALLBACK_MOUSE_MOVE, _move_cb, obj);
1997 }
1998
1999 EOLIAN static void
_efl_ui_flip_interaction_set(Eo * obj,Efl_Ui_Flip_Data * sd,Efl_Ui_Flip_Interaction mode)2000 _efl_ui_flip_interaction_set(Eo *obj, Efl_Ui_Flip_Data *sd, Efl_Ui_Flip_Interaction mode)
2001 {
2002 int i;
2003
2004
2005 if (sd->intmode == mode) return;
2006 sd->intmode = mode;
2007
2008 for (i = 0; i < 4; i++)
2009 {
2010 if (sd->intmode == EFL_UI_FLIP_INTERACTION_NONE)
2011 ELM_SAFE_FREE(sd->event[i], evas_object_del);
2012 else if (sd->dir_enabled[i])
2013 {
2014 int area = (i & 0x2) | (i ^ 0x1);
2015 if (sd->dir_hitsize[area] >= 0.0)
2016 _event_rect_create(obj, sd, area);
2017 }
2018 }
2019
2020 _sizing_eval(obj);
2021 _configure(obj);
2022 }
2023
2024 EOLIAN static Efl_Ui_Flip_Interaction
_efl_ui_flip_interaction_get(const Eo * obj EINA_UNUSED,Efl_Ui_Flip_Data * sd)2025 _efl_ui_flip_interaction_get(const Eo *obj EINA_UNUSED, Efl_Ui_Flip_Data *sd)
2026 {
2027 return sd->intmode;
2028 }
2029
2030 static Efl_Ui_Layout_Orientation
_flip_dir_to_efl_ui_dir(Elm_Flip_Direction dir)2031 _flip_dir_to_efl_ui_dir(Elm_Flip_Direction dir)
2032 {
2033 switch (dir)
2034 {
2035 case ELM_FLIP_DIRECTION_RIGHT: return EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL;
2036 case ELM_FLIP_DIRECTION_DOWN: return EFL_UI_LAYOUT_ORIENTATION_VERTICAL | EFL_UI_LAYOUT_ORIENTATION_INVERTED;
2037 case ELM_FLIP_DIRECTION_LEFT: return EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL | EFL_UI_LAYOUT_ORIENTATION_INVERTED;
2038 case ELM_FLIP_DIRECTION_UP: return EFL_UI_LAYOUT_ORIENTATION_VERTICAL;
2039 }
2040 ERR("Invalid value for Elm_Flip_Direction: %d", (int) dir);
2041 return EFL_UI_LAYOUT_ORIENTATION_DEFAULT;
2042 }
2043
2044 static Elm_Flip_Direction
_efl_ui_dir_to_flip_dir(Efl_Ui_Layout_Orientation dir)2045 _efl_ui_dir_to_flip_dir(Efl_Ui_Layout_Orientation dir)
2046 {
2047 switch ((int)dir) // The cast silences warnings about missing enum values and non-existing case labels
2048 {
2049 case EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL:
2050 return ELM_FLIP_DIRECTION_RIGHT;
2051 case EFL_UI_LAYOUT_ORIENTATION_VERTICAL | EFL_UI_LAYOUT_ORIENTATION_INVERTED:
2052 return ELM_FLIP_DIRECTION_DOWN;
2053 case EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL | EFL_UI_LAYOUT_ORIENTATION_INVERTED:
2054 return ELM_FLIP_DIRECTION_LEFT;
2055 case EFL_UI_LAYOUT_ORIENTATION_VERTICAL:
2056 case EFL_UI_LAYOUT_ORIENTATION_DEFAULT:
2057 return ELM_FLIP_DIRECTION_UP;
2058 }
2059 ERR("Invalid value for Efl_Ui_Layout_Orientation: %d", (int) dir);
2060 return ELM_FLIP_DIRECTION_UP;
2061 }
2062
2063 EOLIAN static void
_efl_ui_flip_interaction_direction_enabled_set(Eo * obj,Efl_Ui_Flip_Data * sd,Efl_Ui_Layout_Orientation dir,Eina_Bool enabled)2064 _efl_ui_flip_interaction_direction_enabled_set(Eo *obj, Efl_Ui_Flip_Data *sd, Efl_Ui_Layout_Orientation dir, Eina_Bool enabled)
2065 {
2066 int i = _efl_ui_dir_to_flip_dir(dir);
2067 int area;
2068
2069 enabled = !!enabled;
2070 if (sd->dir_enabled[i] == enabled) return;
2071 sd->dir_enabled[i] = enabled;
2072 if (sd->intmode == EFL_UI_FLIP_INTERACTION_NONE) return;
2073
2074 area = (i & 0x2) | (i ^ 0x1); // up <-> down, left <-> right
2075 if (enabled && (sd->dir_hitsize[area] >= 0.0))
2076 _event_rect_create(obj, sd, area);
2077 else if (!enabled && (sd->dir_hitsize[area] <= 0.0))
2078 // Delete this hit area as it has the default hitsize (0)
2079 ELM_SAFE_FREE(sd->event[area], evas_object_del);
2080
2081 _sizing_eval(obj);
2082 _configure(obj);
2083 }
2084
2085 EOLIAN static Eina_Bool
_efl_ui_flip_interaction_direction_enabled_get(Eo * obj EINA_UNUSED,Efl_Ui_Flip_Data * sd,Efl_Ui_Layout_Orientation dir)2086 _efl_ui_flip_interaction_direction_enabled_get(Eo *obj EINA_UNUSED, Efl_Ui_Flip_Data *sd, Efl_Ui_Layout_Orientation dir)
2087 {
2088 return sd->dir_enabled[_efl_ui_dir_to_flip_dir(dir)];
2089 }
2090
2091 EOLIAN static void
_efl_ui_flip_interaction_direction_hitsize_set(Eo * obj,Efl_Ui_Flip_Data * sd,Efl_Ui_Layout_Orientation dir,double hitsize)2092 _efl_ui_flip_interaction_direction_hitsize_set(Eo *obj, Efl_Ui_Flip_Data *sd, Efl_Ui_Layout_Orientation dir, double hitsize)
2093 {
2094 int i = _efl_ui_dir_to_flip_dir(dir);
2095
2096
2097 if (hitsize < 0.0)
2098 hitsize = -1.0;
2099 else if (hitsize > 1.0)
2100 hitsize = 1.0;
2101
2102 if (EINA_DBL_EQ(sd->dir_hitsize[i], hitsize)) return;
2103 sd->dir_hitsize[i] = hitsize;
2104
2105 if (hitsize >= 0.0)
2106 _event_rect_create(obj, sd, i);
2107 else
2108 ELM_SAFE_FREE(sd->event[i], evas_object_del);
2109
2110 _sizing_eval(obj);
2111 _configure(obj);
2112 }
2113
2114 static void
_update_front_back(Eo * obj,Efl_Ui_Flip_Data * pd)2115 _update_front_back(Eo *obj, Efl_Ui_Flip_Data *pd)
2116 {
2117 int count, index;
2118 Efl_Gfx_Entity *content;
2119
2120 count = eina_list_count(pd->content_list);
2121 if (count <= 2) return;
2122
2123 // update the next state object
2124 content = _flip_content_unset(obj, !pd->state);
2125 evas_object_hide(content);
2126 content = pd->state ? pd->front.content : pd->back.content;
2127 index = eina_list_data_idx(pd->content_list, content);
2128 index = (index == count-1) ? 0 : index + 1;
2129 content = eina_list_nth(pd->content_list, index);
2130 evas_object_show(content);
2131 _flip_content_set(obj, content, !pd->state);
2132 }
2133
2134 static void
_content_added(Eo * obj,Efl_Ui_Flip_Data * pd,Efl_Gfx_Entity * content)2135 _content_added(Eo *obj, Efl_Ui_Flip_Data *pd, Efl_Gfx_Entity *content)
2136 {
2137 elm_widget_sub_object_add(obj, content);
2138
2139 if (!pd->front.content)
2140 {
2141 _flip_content_set(obj, content, EINA_TRUE);
2142 return;
2143 }
2144 if (!pd->back.content)
2145 {
2146 _flip_content_set(obj, content, EINA_FALSE);
2147 return;
2148 }
2149 }
2150
2151 static void
_content_removed(Eo * obj,Efl_Ui_Flip_Data * pd,Efl_Gfx_Entity * content)2152 _content_removed(Eo *obj, Efl_Ui_Flip_Data *pd, Efl_Gfx_Entity *content)
2153 {
2154 Efl_Gfx_Entity *back_face, *cur_face, *face;
2155 int index, count;
2156 Eina_Bool state;
2157
2158 elm_widget_sub_object_del(obj, content);
2159 // if its not the front or back object just return.
2160 if ((pd->front.content != content) ||
2161 (pd->back.content != content))
2162 return;
2163
2164 cur_face = pd->state ? pd->front.content : pd->back.content;
2165 back_face = pd->state ? pd->back.content : pd->front.content;
2166
2167 if (cur_face == content)
2168 {
2169 face = back_face;
2170 state = EINA_TRUE;
2171 }
2172 else
2173 {
2174 face = cur_face;
2175 state = EINA_FALSE;
2176 }
2177
2178 _flip_content_unset(obj, state);
2179
2180 count = eina_list_count(pd->content_list);
2181 if (count == 1) return;
2182
2183 _flip_content_unset(obj, state);
2184 index = eina_list_data_idx(pd->content_list, face);
2185 index = (index == count-1) ? 0 : index + 1;
2186 _flip_content_set(obj, eina_list_nth(pd->content_list, index), state);
2187 }
2188
2189 EOLIAN static double
_efl_ui_flip_interaction_direction_hitsize_get(Eo * obj EINA_UNUSED,Efl_Ui_Flip_Data * sd,Efl_Ui_Layout_Orientation dir)2190 _efl_ui_flip_interaction_direction_hitsize_get(Eo *obj EINA_UNUSED, Efl_Ui_Flip_Data *sd, Efl_Ui_Layout_Orientation dir)
2191 {
2192 int i = _efl_ui_dir_to_flip_dir(dir);
2193
2194 return sd->dir_hitsize[i];
2195 }
2196
2197 EOLIAN static Eina_Iterator *
_efl_ui_flip_efl_container_content_iterate(Eo * obj EINA_UNUSED,Efl_Ui_Flip_Data * pd)2198 _efl_ui_flip_efl_container_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_Flip_Data *pd)
2199 {
2200 return eina_list_iterator_new(pd->content_list);
2201 }
2202
2203 EOLIAN static int
_efl_ui_flip_efl_container_content_count(Eo * obj EINA_UNUSED,Efl_Ui_Flip_Data * pd)2204 _efl_ui_flip_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Flip_Data *pd)
2205 {
2206 return eina_list_count(pd->content_list);
2207 }
2208
2209 EOLIAN static Eina_Bool
_efl_ui_flip_efl_pack_unpack(Eo * obj,Efl_Ui_Flip_Data * pd,Efl_Gfx_Entity * subobj)2210 _efl_ui_flip_efl_pack_unpack(Eo *obj, Efl_Ui_Flip_Data *pd, Efl_Gfx_Entity *subobj)
2211 {
2212 pd->content_list = eina_list_remove(pd->content_list, subobj);
2213 pd->content_list = eina_list_remove(pd->content_list, subobj);
2214 _content_removed(obj, pd, subobj);
2215 return EINA_TRUE;
2216 }
2217
2218 EOLIAN static Eina_Bool
_efl_ui_flip_efl_pack_pack(Eo * obj,Efl_Ui_Flip_Data * pd,Efl_Gfx_Entity * subobj)2219 _efl_ui_flip_efl_pack_pack(Eo *obj, Efl_Ui_Flip_Data *pd, Efl_Gfx_Entity *subobj)
2220 {
2221 pd->content_list = eina_list_remove(pd->content_list, subobj);
2222 pd->content_list = eina_list_append(pd->content_list, subobj);
2223 _content_added(obj, pd, subobj);
2224 return EINA_TRUE;
2225 }
2226
2227 EOLIAN static Eina_Bool
_efl_ui_flip_efl_pack_linear_pack_begin(Eo * obj,Efl_Ui_Flip_Data * pd,Efl_Gfx_Entity * subobj)2228 _efl_ui_flip_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_Flip_Data *pd, Efl_Gfx_Entity *subobj)
2229 {
2230 pd->content_list = eina_list_remove(pd->content_list, subobj);
2231 pd->content_list = eina_list_prepend(pd->content_list, subobj);
2232 _content_added(obj, pd, subobj);
2233
2234 return EINA_TRUE;
2235 }
2236
2237 EOLIAN static Eina_Bool
_efl_ui_flip_efl_pack_linear_pack_end(Eo * obj,Efl_Ui_Flip_Data * pd,Efl_Gfx_Entity * subobj)2238 _efl_ui_flip_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_Flip_Data *pd, Efl_Gfx_Entity *subobj)
2239 {
2240 pd->content_list = eina_list_remove(pd->content_list, subobj);
2241 pd->content_list = eina_list_append(pd->content_list, subobj);
2242 _content_added(obj, pd, subobj);
2243 return EINA_TRUE;
2244 }
2245
2246 EOLIAN static Eina_Bool
_efl_ui_flip_efl_pack_linear_pack_before(Eo * obj,Efl_Ui_Flip_Data * pd,Efl_Gfx_Entity * subobj,const Efl_Gfx_Entity * existing)2247 _efl_ui_flip_efl_pack_linear_pack_before(Eo *obj, Efl_Ui_Flip_Data *pd, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing)
2248 {
2249 pd->content_list = eina_list_remove(pd->content_list, subobj);
2250 pd->content_list = eina_list_prepend_relative(pd->content_list, subobj, existing);
2251 _content_added(obj, pd, subobj);
2252 return EINA_TRUE;
2253 }
2254
2255 EOLIAN static Eina_Bool
_efl_ui_flip_efl_pack_linear_pack_after(Eo * obj,Efl_Ui_Flip_Data * pd,Efl_Gfx_Entity * subobj,const Efl_Gfx_Entity * existing)2256 _efl_ui_flip_efl_pack_linear_pack_after(Eo *obj, Efl_Ui_Flip_Data *pd, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing)
2257 {
2258 pd->content_list = eina_list_remove(pd->content_list, subobj);
2259 pd->content_list = eina_list_append_relative(pd->content_list, subobj, existing);
2260 _content_added(obj, pd, subobj);
2261 return EINA_TRUE;
2262 }
2263
2264 EOLIAN static Eina_Bool
_efl_ui_flip_efl_pack_linear_pack_at(Eo * obj,Efl_Ui_Flip_Data * pd,Efl_Gfx_Entity * subobj,int index)2265 _efl_ui_flip_efl_pack_linear_pack_at(Eo *obj, Efl_Ui_Flip_Data *pd, Efl_Gfx_Entity *subobj, int index)
2266 {
2267 Efl_Gfx_Entity *existing = NULL;
2268 existing = eina_list_nth(pd->content_list, index);
2269 pd->content_list = eina_list_remove(pd->content_list, subobj);
2270 pd->content_list = eina_list_prepend_relative(pd->content_list, subobj, existing);
2271 _content_added(obj, pd, subobj);
2272 return EINA_TRUE;
2273 }
2274
2275 EOLIAN static Efl_Gfx_Entity *
_efl_ui_flip_efl_pack_linear_pack_content_get(Eo * obj EINA_UNUSED,Efl_Ui_Flip_Data * pd,int index)2276 _efl_ui_flip_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Flip_Data *pd, int index)
2277 {
2278 return eina_list_nth(pd->content_list, index);
2279 }
2280
2281 EOLIAN static Efl_Gfx_Entity *
_efl_ui_flip_efl_pack_linear_pack_unpack_at(Eo * obj,Efl_Ui_Flip_Data * pd,int index)2282 _efl_ui_flip_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Flip_Data *pd, int index)
2283 {
2284 Efl_Gfx_Entity *content = eina_list_nth(pd->content_list ,index);
2285
2286 pd->content_list = eina_list_remove(pd->content_list, content);
2287 _content_removed(obj, pd, content);
2288 return content;
2289 }
2290
2291 EOLIAN static int
_efl_ui_flip_efl_pack_linear_pack_index_get(Eo * obj EINA_UNUSED,Efl_Ui_Flip_Data * pd,const Efl_Gfx_Entity * subobj)2292 _efl_ui_flip_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Flip_Data *pd, const Efl_Gfx_Entity *subobj)
2293 {
2294 return eina_list_data_idx(pd->content_list, (void *)subobj);
2295 }
2296
2297 EAPI void
elm_flip_interaction_direction_hitsize_set(Efl_Ui_Flip * obj,Elm_Flip_Direction dir,double hitsize)2298 elm_flip_interaction_direction_hitsize_set(Efl_Ui_Flip *obj, Elm_Flip_Direction dir, double hitsize)
2299 {
2300 Efl_Ui_Layout_Orientation uidir = _flip_dir_to_efl_ui_dir(dir);
2301 efl_ui_flip_interaction_direction_hitsize_set(obj, uidir, hitsize);
2302 }
2303
2304 EAPI double
elm_flip_interaction_direction_hitsize_get(Efl_Ui_Flip * obj,Elm_Flip_Direction dir)2305 elm_flip_interaction_direction_hitsize_get(Efl_Ui_Flip *obj, Elm_Flip_Direction dir)
2306 {
2307 Efl_Ui_Layout_Orientation uidir = _flip_dir_to_efl_ui_dir(dir);
2308 return efl_ui_flip_interaction_direction_hitsize_get(obj, uidir);
2309 }
2310
2311 EOAPI void
elm_flip_interaction_direction_enabled_set(Efl_Ui_Flip * obj,Elm_Flip_Direction dir,Eina_Bool enabled)2312 elm_flip_interaction_direction_enabled_set(Efl_Ui_Flip *obj, Elm_Flip_Direction dir, Eina_Bool enabled)
2313 {
2314 Efl_Ui_Layout_Orientation uidir = _flip_dir_to_efl_ui_dir(dir);
2315 efl_ui_flip_interaction_direction_enabled_set(obj, uidir, enabled);
2316 }
2317
2318 EOAPI Eina_Bool
elm_flip_interaction_direction_enabled_get(Efl_Ui_Flip * obj,Elm_Flip_Direction dir)2319 elm_flip_interaction_direction_enabled_get(Efl_Ui_Flip *obj, Elm_Flip_Direction dir)
2320 {
2321 Efl_Ui_Layout_Orientation uidir = _flip_dir_to_efl_ui_dir(dir);
2322 return efl_ui_flip_interaction_direction_enabled_get(obj, uidir);
2323 }
2324
2325 /* Efl.Part begin */
2326
2327 static Eina_Bool
_part_is_efl_ui_flip_entry_part(const Eo * obj EINA_UNUSED,const char * part)2328 _part_is_efl_ui_flip_entry_part(const Eo *obj EINA_UNUSED, const char *part)
2329 {
2330 return ((eina_streq(part, "front")) || (eina_streq(part, "back")));
2331 }
2332
ELM_PART_OVERRIDE_PARTIAL(efl_ui_flip,EFL_UI_FLIP,Efl_Ui_Flip_Data,_part_is_efl_ui_flip_entry_part)2333 ELM_PART_OVERRIDE_PARTIAL(efl_ui_flip, EFL_UI_FLIP, Efl_Ui_Flip_Data, _part_is_efl_ui_flip_entry_part)
2334 ELM_PART_OVERRIDE_CONTENT_SET(efl_ui_flip, EFL_UI_FLIP, Efl_Ui_Flip_Data)
2335 ELM_PART_OVERRIDE_CONTENT_GET(efl_ui_flip, EFL_UI_FLIP, Efl_Ui_Flip_Data)
2336 ELM_PART_OVERRIDE_CONTENT_UNSET(efl_ui_flip, EFL_UI_FLIP, Efl_Ui_Flip_Data)
2337 ELM_PART_CONTENT_DEFAULT_GET(efl_ui_flip, "front")
2338 #include "efl_ui_flip_part.eo.c"
2339
2340 /* Efl.Part end */
2341
2342 /* Internal EO APIs and hidden overrides */
2343
2344 #define EFL_UI_FLIP_EXTRA_OPS \
2345 ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_flip), \
2346 EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_flip)
2347
2348 #include "efl_ui_flip.eo.c"
2349 #include "efl_ui_flip_eo.legacy.c"
2350
2351 #include "efl_ui_flip_legacy_eo.h"
2352
2353 #define MY_CLASS_NAME_LEGACY "elm_flip"
2354
2355 static void
2356 _efl_ui_flip_legacy_class_constructor(Efl_Class *klass)
2357 {
2358 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
2359 }
2360
2361 EOLIAN static Eo *
_efl_ui_flip_legacy_efl_object_constructor(Eo * obj,void * pd EINA_UNUSED)2362 _efl_ui_flip_legacy_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
2363 {
2364 obj = efl_constructor(efl_super(obj, EFL_UI_FLIP_LEGACY_CLASS));
2365 efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
2366 return obj;
2367 }
2368
2369 EAPI Evas_Object *
elm_flip_add(Evas_Object * parent)2370 elm_flip_add(Evas_Object *parent)
2371 {
2372 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
2373 return elm_legacy_add(EFL_UI_FLIP_LEGACY_CLASS, parent);
2374 }
2375
2376 #include "efl_ui_flip_legacy_eo.c"
2377