Elementary: fixed momentum value for zoom test.
[framework/uifw/elementary.git] / src / bin / test_gesture_layer3.c
1 #include <Elementary.h>
2 #ifdef HAVE_CONFIG_H
3 #include "elementary_config.h"
4 #endif
5 #ifndef ELM_LIB_QUICKLAUNCH
6
7 /* We zoom out to this value so we'll be able to use map and have a nice
8  * resolution when zooming in. */
9 #define BASE_ZOOM 0.5
10 /* The amount of zoom to do when "lifting" objects. */
11 #define LIFT_FACTOR 1.3
12 /* The base size of the shadow image. */
13 #define SHADOW_W 118
14 #define SHADOW_H 118
15 #define RAD2DEG(x) ((x) * 57.295779513)
16
17 static double zoom_momentum_animation_duration = 0.4;
18
19 struct _Photo_Object {
20      Evas_Object *ic, *shadow;
21      Evas_Object *hit;
22      Evas_Object *gl;
23
24      /* 3 transit object to implement momentum animation */
25      Elm_Transit *momentum;
26      Elm_Transit *zoom_momentum;
27      Elm_Transit *rot_momentum;
28      /* bx, by - current wanted coordinates of the photo object.
29       * bw, bh - original size of the "ic" object.
30       * dx, dy - Used to indicate the distance between the center point
31       * m_dx, m_dy - momentum delta to apply with momentum transit
32       * where we put down our fingers (when started moving the item) to
33       * the coords of the object, so we'll be able to calculate movement
34       * correctly. */
35      Evas_Coord bx, by, bw, bh, dx, dy, m_dx, m_dy;
36      /* Because gesture layer only knows the amount of rotation/zoom we do
37       * per gesture, we have to keep the current rotate/zoom factor and the
38       * one that was before we started the gesture. */
39      int base_rotate, rotate;  /* base - initial angle */
40      double r_momentum;
41      double base_zoom, zoom, zoom_dx;  /* zoom_dx used for zoom-momentum */
42      double shadow_zoom;
43 };
44 typedef struct _Photo_Object Photo_Object;
45
46
47 /* This function applies the information from the Photo_Object to the actual
48  * evas objects. Zoom/rotate factors and etc. */
49 static void
50 apply_changes(Photo_Object *po)
51 {
52    Evas_Map *map;
53
54    map = evas_map_new(4);
55    evas_map_point_coord_set(map, 0, po->bx, po->by, 0);
56    evas_map_point_coord_set(map, 1, po->bx + po->bw, po->by, 0);
57    evas_map_point_coord_set(map, 2, po->bx + po->bw, po->by + po->bh, 0);
58    evas_map_point_coord_set(map, 3, po->bx, po->by + po->bh, 0);
59    evas_map_point_image_uv_set(map, 0, 0, 0);
60    evas_map_point_image_uv_set(map, 1, po->bw, 0);
61    evas_map_point_image_uv_set(map, 2, po->bw, po->bh);
62    evas_map_point_image_uv_set(map, 3, 0, po->bh);
63    evas_map_util_rotate(map, po->rotate,
64          po->bx + po->bw / 2, po->by + po->bh /2);
65    evas_map_util_zoom(map, po->zoom, po->zoom,
66          po->bx + po->bw / 2, po->by + po->bh /2);
67    evas_object_map_enable_set(po->ic, EINA_TRUE);
68    evas_object_map_set(po->ic, map);
69
70      {
71         Evas_Map *shadow_map = evas_map_new(4);
72         evas_map_point_coord_set(shadow_map, 0, po->bx, po->by, 0);
73         evas_map_point_coord_set(shadow_map, 1, po->bx + po->bw, po->by, 0);
74         evas_map_point_coord_set(shadow_map, 2,
75               po->bx + po->bw, po->by + po->bh, 0);
76         evas_map_point_coord_set(shadow_map, 3, po->bx, po->by + po->bh, 0);
77         evas_map_point_image_uv_set(shadow_map, 0, 0, 0);
78         evas_map_point_image_uv_set(shadow_map, 1, SHADOW_W, 0);
79         evas_map_point_image_uv_set(shadow_map, 2, SHADOW_W, SHADOW_H);
80         evas_map_point_image_uv_set(shadow_map, 3, 0, SHADOW_H);
81         evas_map_util_rotate(shadow_map, po->rotate,
82               po->bx + po->bw / 2, po->by + po->bh /2);
83         evas_map_util_zoom(shadow_map, po->zoom * po->shadow_zoom,
84               po->zoom * po->shadow_zoom,
85               po->bx + (po->bw / 2), po->by + (po->bh / 2));
86         evas_object_map_enable_set(po->shadow, EINA_TRUE);
87         evas_object_map_set(po->shadow, shadow_map);
88         evas_map_free(shadow_map);
89      }
90
91    /* Update the position of the hit box */
92      {
93         Evas_Coord minx, miny, maxx, maxy;
94         int i;
95         evas_object_polygon_points_clear(po->hit);
96         evas_map_point_coord_get(map, 0, &minx, &miny, NULL);
97         maxx = minx;
98         maxy = miny;
99         evas_object_polygon_point_add(po->hit, minx, miny);
100         for (i = 1 ; i <= 3 ; i++)
101           {
102              Evas_Coord x, y;
103              evas_map_point_coord_get(map, i, &x, &y, NULL);
104              evas_object_polygon_point_add(po->hit, x, y);
105              if (x < minx)
106                 minx = x;
107              else if (x > maxx)
108                 maxx = x;
109
110              if (y < miny)
111                 miny = y;
112              else if (y > maxy)
113                 maxy = y;
114           }
115      }
116
117    evas_object_raise(po->shadow);
118    evas_object_raise(po->ic);
119    evas_object_raise(po->hit);
120    evas_map_free(map);
121 }
122
123 /* Zoom momentum animation */
124 static void
125 zoom_momentum_animation_operation(void *_po, Elm_Transit *transit __UNUSED__,
126       double progress __UNUSED__)
127 {
128    Photo_Object *po = (Photo_Object *) _po;
129    po->zoom += po->zoom_dx;
130    printf("%s po->zoom=<%f>\n",__func__, po->zoom);
131    apply_changes(po);
132 }
133
134 static void
135 zoom_momentum_animation_end(void *_po, Elm_Transit *transit __UNUSED__)
136 {
137    Photo_Object *po = (Photo_Object *) _po;
138    po->zoom_momentum = NULL;
139 }
140
141 /* Rotate momentum animation */
142 static void
143 rotate_momentum_animation_operation(void *_po, Elm_Transit *transit __UNUSED__,
144       double progress)
145 {
146    printf("%s progress=<%f>\n", __func__, progress);
147    Photo_Object *po = (Photo_Object *) _po;
148    po->rotate = po->base_rotate + RAD2DEG(po->r_momentum * progress);
149    if (po->rotate < 0)
150       po->rotate = (po->rotate % 360) + 360;
151    printf("current-angle=<%d> base-angle=<%d> momentum-angle=<%d>\n",
152          po->rotate, po->base_rotate,
153          (int) RAD2DEG(po->r_momentum * progress));
154
155    apply_changes(po);
156 }
157
158 static void
159 rotate_momentum_animation_end(void *_po, Elm_Transit *transit __UNUSED__)
160 {
161    Photo_Object *po = (Photo_Object *) _po;
162
163    po->rot_momentum = NULL;
164 }
165
166 /* Momentum animation */
167 static void
168 momentum_animation_operation(void *_po, Elm_Transit *transit __UNUSED__,
169       double progress __UNUSED__)
170 {
171    Photo_Object *po = (Photo_Object *) _po;
172    po->bx += po->m_dx;
173    po->by += po->m_dy;
174    apply_changes(po);
175 }
176
177 static void
178 pic_obj_keep_inframe(void *_po)
179 {  /* Make sure middle is in the screen, if not, fix it. */
180    /* FIXME: Use actual window sizes instead of the hardcoded
181     * values */
182    Photo_Object *po = (Photo_Object *) _po;
183
184    Evas_Coord mx, my;
185    mx = po->bx + (po->bw / 2);
186    my = po->by + (po->bh / 2);
187    if (mx < 0)
188      po->bx = 0 - (po->bw / 2);
189    else if (mx > 480)
190      po->bx = 480 - (po->bw / 2);
191
192    if (my < 0)
193      po->by = 0 - (po->bw / 2);
194    else if (my > 800)
195      po->by = 800 - (po->bh / 2);
196 }
197
198 static void
199 momentum_animation_end(void *_po, Elm_Transit *transit __UNUSED__)
200 {
201    Photo_Object *po = (Photo_Object *) _po;
202
203    pic_obj_keep_inframe(po);
204    apply_changes(po);
205
206    po->momentum = NULL;
207 }
208
209 static Evas_Event_Flags
210 rotate_start(void *_po, void *event_info)
211 {
212    Photo_Object *po = (Photo_Object *) _po;
213    Elm_Gesture_Rotate_Info *p = (Elm_Gesture_Rotate_Info *) event_info;
214    printf("rotate start <%d,%d> base=<%f> <%f>\n", p->x, p->y,
215          RAD2DEG(p->base_angle), RAD2DEG(p->angle));
216
217    /* If there's an active animator, stop it */
218    if (po->rot_momentum)
219      {
220         elm_transit_del(po->rot_momentum);
221         po->rot_momentum = NULL;
222      }
223
224    return EVAS_EVENT_FLAG_NONE;
225 }
226
227 static Evas_Event_Flags
228 rotate_move(void *_po, void *event_info)
229 {
230    Photo_Object *po = (Photo_Object *) _po;
231    Elm_Gesture_Rotate_Info *p = (Elm_Gesture_Rotate_Info *) event_info;
232    printf("rotate move <%d,%d> base=<%f> <%f> m=<%f>\n", p->x, p->y,
233          RAD2DEG(p->base_angle), RAD2DEG(p->angle), p->momentum);
234    po->rotate = po->base_rotate + (int) RAD2DEG(p->base_angle - p->angle);
235    if (po->rotate < 0)
236       po->rotate += 360;
237    apply_changes(po);
238    return EVAS_EVENT_FLAG_NONE;
239 }
240
241 static Evas_Event_Flags
242 rotate_end(void *_po, void *event_info)
243 {
244    Photo_Object *po = (Photo_Object *) _po;
245    Elm_Gesture_Rotate_Info *r_info = (Elm_Gesture_Rotate_Info *) event_info;
246    printf("rotate end <%d,%d> base=<%f> <%f> m=<%f>\n", r_info->x, r_info->y,
247          RAD2DEG(r_info->base_angle), RAD2DEG(r_info->angle), r_info->momentum);
248    po->base_rotate += (int) RAD2DEG(r_info->base_angle - r_info->angle);
249    if (po->rotate < 0)
250       po->rotate += 360;
251
252    /* Apply the rotate-momentum */
253    double tot_time = fabs(r_info->momentum) / 8;
254    po->r_momentum = r_info->momentum * tot_time - (8 * tot_time * tot_time) / 2;
255    if (po->r_momentum)
256      {
257         po->rot_momentum = elm_transit_add();
258         printf("TOM %f\n", tot_time);
259         elm_transit_duration_set(po->rot_momentum, tot_time);
260         elm_transit_effect_add(po->rot_momentum,
261               rotate_momentum_animation_operation, po,
262               rotate_momentum_animation_end);
263         elm_transit_go(po->rot_momentum);
264      }
265    return EVAS_EVENT_FLAG_NONE;
266 }
267
268 static Evas_Event_Flags
269 rotate_abort(void *_po, void *event_info)
270 {
271    Photo_Object *po = (Photo_Object *) _po;
272    Elm_Gesture_Rotate_Info *p = (Elm_Gesture_Rotate_Info *) event_info;
273    printf("rotate abort <%d,%d> base=<%f> <%f>\n", p->x, p->y,
274          RAD2DEG(p->base_angle), RAD2DEG(p->angle));
275    po->base_rotate += (int) RAD2DEG(p->base_angle - p->angle);
276    if (po->rotate < 0)
277       po->rotate += 360;
278
279    return EVAS_EVENT_FLAG_NONE;
280 }
281
282 static Evas_Event_Flags
283 zoom_start(void *_po, void *event_info)
284 {
285    Photo_Object *po = (Photo_Object *) _po;
286    Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
287    printf("zoom start <%d,%d> <%f>\n", p->x, p->y, p->zoom);
288
289    /* If there's an active animator, stop it */
290    if (po->zoom_momentum)
291      {
292         elm_transit_del(po->zoom_momentum);
293         po->zoom_momentum = NULL;
294      }
295
296    return EVAS_EVENT_FLAG_NONE;
297 }
298
299 static Evas_Event_Flags
300 zoom_move(void *_po, void *event_info)
301 {
302    Photo_Object *po = (Photo_Object *) _po;
303    Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
304    printf("zoom move <%d,%d> <%f>\n", p->x, p->y, p->zoom);
305    po->zoom = po->base_zoom * p->zoom;
306    apply_changes(po);
307    return EVAS_EVENT_FLAG_NONE;
308 }
309
310 static Evas_Event_Flags
311 zoom_end(void *_po, void *event_info)
312 {
313    Photo_Object *po = (Photo_Object *) _po;
314    Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
315    printf("zoom end/abort <%d,%d> <%f> momentum=<%f>\n", p->x, p->y,
316          p->zoom, p->momentum);
317
318    /* Apply the zoom-momentum or zoom out animator */
319    po->zoom_dx = p->momentum / (zoom_momentum_animation_duration * 1000);
320    if (po->zoom_dx)
321      {
322         po->zoom_momentum = elm_transit_add();
323         elm_transit_duration_set(po->zoom_momentum,
324               zoom_momentum_animation_duration);
325         elm_transit_effect_add(po->zoom_momentum,
326               zoom_momentum_animation_operation, po,
327               zoom_momentum_animation_end);
328         elm_transit_go(po->zoom_momentum);
329      }
330
331    return EVAS_EVENT_FLAG_NONE;
332 }
333
334 static Evas_Event_Flags
335 momentum_start(void *_po, void *event_info)
336 {
337    Photo_Object *po = (Photo_Object *) _po;
338    Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info;
339    printf("momentum_start <%d,%d>\n", p->x2, p->y2);
340
341    /* If there's an active animator, stop it */
342    if (po->momentum)
343      {
344         elm_transit_del(po->momentum);
345         po->momentum = NULL;
346      }
347
348    po->dx = p->x2 - po->bx;
349    po->dy = p->y2 - po->by;
350    apply_changes(po);
351
352    return EVAS_EVENT_FLAG_NONE;
353 }
354
355 static Evas_Event_Flags
356 momentum_move(void *_po, void *event_info)
357 {
358    Photo_Object *po = (Photo_Object *) _po;
359    Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info;
360    printf("momentum move <%d,%d>\n", p->x2, p->y2);
361
362    po->bx = p->x2 - po->dx;
363    po->by = p->y2 - po->dy;
364    apply_changes(po);
365
366    return EVAS_EVENT_FLAG_NONE;
367 }
368
369 static Evas_Event_Flags
370 momentum_end(void *_po, void *event_info)
371 {
372    Photo_Object *po = (Photo_Object *) _po;
373    Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info;
374    printf("momentum end <%d,%d> <%d,%d>\n", p->x2, p->y2, p->mx, p->my);
375    pic_obj_keep_inframe(po);
376    apply_changes(po);
377    po->m_dx = p->mx / 200;
378    po->m_dy = p->my / 200;
379
380    po->momentum = elm_transit_add();
381    elm_transit_duration_set(po->momentum, 0.5);
382    elm_transit_effect_add(po->momentum, momentum_animation_operation, po,
383          momentum_animation_end);
384    elm_transit_go(po->momentum);
385    return EVAS_EVENT_FLAG_NONE;
386 }
387
388 static Evas_Event_Flags
389 momentum_abort(void *_po, void *event_info)
390 {
391    Photo_Object *po = (Photo_Object *) _po;
392    Elm_Gesture_Momentum_Info *p = (Elm_Gesture_Momentum_Info *) event_info;
393    printf("momentum abort <%d,%d> <%d,%d>\n", p->x2, p->y2, p->mx, p->my);
394    pic_obj_keep_inframe(po);
395    apply_changes(po);
396
397    return EVAS_EVENT_FLAG_NONE;
398 }
399
400 static void
401 _win_del_req(void *data, Evas_Object *obj __UNUSED__,
402       void *event_info __UNUSED__)
403 {
404    Photo_Object **photo_array = (Photo_Object **) data;
405
406    if (!photo_array)
407       return;
408
409    /* The content of the photo object is automatically deleted when the win
410     * is deleted. */
411    for ( ; *photo_array ; photo_array++)
412       free(*photo_array);
413
414    free(data);
415 }
416
417
418 static Photo_Object *
419 photo_object_add(Evas_Object *parent, Evas_Object *ic, const char *icon,
420       Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, int angle)
421 {
422    char buf[PATH_MAX];
423    Photo_Object *po;
424    po = calloc(1, sizeof(*po));
425    po->base_zoom = po->zoom = BASE_ZOOM;
426
427    if (ic)
428      {
429         po->ic = ic;
430      }
431    else
432      {
433         po->ic = elm_icon_add(parent);
434         elm_icon_file_set(po->ic, icon, NULL);
435      }
436
437    po->bx = x;
438    po->by = y;
439    po->bw = w;
440    po->bh = h;
441
442    /* Add shadow */
443      {
444         po->shadow = elm_icon_add(po->ic);
445         snprintf(buf, sizeof(buf), "%s/images/pol_shadow.png", elm_app_data_dir_get());
446         elm_icon_file_set(po->shadow, buf, NULL);
447         evas_object_resize(po->shadow, SHADOW_W, SHADOW_H);
448         evas_object_show(po->shadow);
449      }
450
451    po->hit = evas_object_polygon_add(evas_object_evas_get(parent));
452    evas_object_precise_is_inside_set(po->hit, EINA_TRUE);
453    evas_object_repeat_events_set(po->hit, EINA_TRUE);
454    evas_object_color_set(po->hit, 0, 0, 0, 0);
455
456    evas_object_resize(po->ic, po->bw, po->bh);
457    evas_object_show(po->ic);
458
459    evas_object_show(po->hit);
460
461    po->gl = elm_gesture_layer_add(po->ic);
462    elm_gesture_layer_hold_events_set(po->gl, EINA_TRUE);
463    elm_gesture_layer_attach(po->gl, po->hit);
464
465    /* FIXME: Add a po->rotate start so we take the first angle!!!! */
466    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_MOMENTUM,
467          ELM_GESTURE_STATE_START, momentum_start, po);
468    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_MOMENTUM,
469          ELM_GESTURE_STATE_MOVE, momentum_move, po);
470    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_MOMENTUM,
471          ELM_GESTURE_STATE_END, momentum_end, po);
472    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_MOMENTUM,
473          ELM_GESTURE_STATE_ABORT, momentum_abort, po);
474
475    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ZOOM,
476          ELM_GESTURE_STATE_START, zoom_start, po);
477    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ZOOM,
478          ELM_GESTURE_STATE_MOVE, zoom_move, po);
479    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ZOOM,
480          ELM_GESTURE_STATE_END, zoom_end, po);
481    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ZOOM,
482          ELM_GESTURE_STATE_ABORT, zoom_end, po);
483
484    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ROTATE,
485          ELM_GESTURE_STATE_START, rotate_start, po);
486    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ROTATE,
487          ELM_GESTURE_STATE_MOVE, rotate_move, po);
488    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ROTATE,
489          ELM_GESTURE_STATE_END, rotate_end, po);
490    elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ROTATE,
491          ELM_GESTURE_STATE_ABORT, rotate_abort, po);
492
493    po->rotate = po->base_rotate = angle;
494    po->shadow_zoom = 1.3;
495
496    apply_changes(po);
497    return po;
498 }
499
500 void
501 test_gesture_layer3(void *data __UNUSED__, Evas_Object *obj __UNUSED__,
502       void *event_info __UNUSED__)
503 {
504    Evas_Coord w, h;
505    Evas_Object *win, *bg;
506    char buf[PATH_MAX];
507    int ind = 0;
508    Photo_Object **photo_array;
509    photo_array = calloc(sizeof(*photo_array), 4);
510
511    w = 480;
512    h = 800;
513
514    win = elm_win_add(NULL, "gesture-layer", ELM_WIN_BASIC);
515    elm_win_title_set(win, "Gesture Layer");
516    elm_win_autodel_set(win, EINA_TRUE);
517    evas_object_resize(win, w, h);
518
519    bg = elm_bg_add(win);
520    snprintf(buf, sizeof(buf), "%s/images/wood_01.jpg", elm_app_data_dir_get());
521    elm_bg_file_set(bg, buf, NULL);
522    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
523    elm_win_resize_object_add(win, bg);
524    evas_object_show(bg);
525
526    snprintf(buf, sizeof(buf), "%s/images/pol_sky.png", elm_app_data_dir_get());
527    photo_array[ind++] = photo_object_add(win, NULL, buf, 50, 200, 365, 400, 0);
528
529    photo_array[ind] = NULL;
530    evas_object_smart_callback_add(win, "delete,request", _win_del_req,
531          photo_array);
532    evas_object_show(win);
533 }
534 #endif