1 #include <Elementary.h>
3 #include "elementary_config.h"
5 #ifndef ELM_LIB_QUICKLAUNCH
7 /* We zoom out to this value so we'll be able to use map and have a nice
8 * resolution when zooming in. */
10 /* The amount of zoom to do when "lifting" objects. */
11 #define LIFT_FACTOR 1.3
12 /* The base size of the shadow image. */
15 #define RAD2DEG(x) ((x) * 57.295779513)
17 static double zoom_momentum_animation_duration = 0.4;
19 struct _Photo_Object {
20 Evas_Object *ic, *shadow;
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
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 */
41 double base_zoom, zoom, zoom_dx; /* zoom_dx used for zoom-momentum */
44 typedef struct _Photo_Object Photo_Object;
47 /* This function applies the information from the Photo_Object to the actual
48 * evas objects. Zoom/rotate factors and etc. */
50 apply_changes(Photo_Object *po)
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);
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);
91 /* Update the position of the hit box */
93 Evas_Coord minx, miny, maxx, maxy;
95 evas_object_polygon_points_clear(po->hit);
96 evas_map_point_coord_get(map, 0, &minx, &miny, NULL);
99 evas_object_polygon_point_add(po->hit, minx, miny);
100 for (i = 1 ; i <= 3 ; i++)
103 evas_map_point_coord_get(map, i, &x, &y, NULL);
104 evas_object_polygon_point_add(po->hit, x, y);
117 evas_object_raise(po->shadow);
118 evas_object_raise(po->ic);
119 evas_object_raise(po->hit);
123 /* Zoom momentum animation */
125 zoom_momentum_animation_operation(void *_po, Elm_Transit *transit __UNUSED__,
126 double progress __UNUSED__)
128 Photo_Object *po = (Photo_Object *) _po;
129 po->zoom += po->zoom_dx;
130 printf("%s po->zoom=<%f>\n",__func__, po->zoom);
135 zoom_momentum_animation_end(void *_po, Elm_Transit *transit __UNUSED__)
137 Photo_Object *po = (Photo_Object *) _po;
138 po->zoom_momentum = NULL;
141 /* Rotate momentum animation */
143 rotate_momentum_animation_operation(void *_po, Elm_Transit *transit __UNUSED__,
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);
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));
159 rotate_momentum_animation_end(void *_po, Elm_Transit *transit __UNUSED__)
161 Photo_Object *po = (Photo_Object *) _po;
163 po->rot_momentum = NULL;
166 /* Momentum animation */
168 momentum_animation_operation(void *_po, Elm_Transit *transit __UNUSED__,
169 double progress __UNUSED__)
171 Photo_Object *po = (Photo_Object *) _po;
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
182 Photo_Object *po = (Photo_Object *) _po;
185 mx = po->bx + (po->bw / 2);
186 my = po->by + (po->bh / 2);
188 po->bx = 0 - (po->bw / 2);
190 po->bx = 480 - (po->bw / 2);
193 po->by = 0 - (po->bw / 2);
195 po->by = 800 - (po->bh / 2);
199 momentum_animation_end(void *_po, Elm_Transit *transit __UNUSED__)
201 Photo_Object *po = (Photo_Object *) _po;
203 pic_obj_keep_inframe(po);
209 static Evas_Event_Flags
210 rotate_start(void *_po, void *event_info)
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));
217 /* If there's an active animator, stop it */
218 if (po->rot_momentum)
220 elm_transit_del(po->rot_momentum);
221 po->rot_momentum = NULL;
224 return EVAS_EVENT_FLAG_NONE;
227 static Evas_Event_Flags
228 rotate_move(void *_po, void *event_info)
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);
238 return EVAS_EVENT_FLAG_NONE;
241 static Evas_Event_Flags
242 rotate_end(void *_po, void *event_info)
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);
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;
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);
265 return EVAS_EVENT_FLAG_NONE;
268 static Evas_Event_Flags
269 rotate_abort(void *_po, void *event_info)
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);
279 return EVAS_EVENT_FLAG_NONE;
282 static Evas_Event_Flags
283 zoom_start(void *_po, void *event_info)
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);
289 /* If there's an active animator, stop it */
290 if (po->zoom_momentum)
292 elm_transit_del(po->zoom_momentum);
293 po->zoom_momentum = NULL;
296 return EVAS_EVENT_FLAG_NONE;
299 static Evas_Event_Flags
300 zoom_move(void *_po, void *event_info)
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;
307 return EVAS_EVENT_FLAG_NONE;
310 static Evas_Event_Flags
311 zoom_end(void *_po, void *event_info)
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);
318 /* Apply the zoom-momentum or zoom out animator */
319 po->zoom_dx = p->zoom / (zoom_momentum_animation_duration * 1000);
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);
331 return EVAS_EVENT_FLAG_NONE;
334 static Evas_Event_Flags
335 momentum_start(void *_po, void *event_info)
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);
341 /* If there's an active animator, stop it */
344 elm_transit_del(po->momentum);
348 po->dx = p->x2 - po->bx;
349 po->dy = p->y2 - po->by;
352 return EVAS_EVENT_FLAG_NONE;
355 static Evas_Event_Flags
356 momentum_move(void *_po, void *event_info)
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);
362 po->bx = p->x2 - po->dx;
363 po->by = p->y2 - po->dy;
366 return EVAS_EVENT_FLAG_NONE;
369 static Evas_Event_Flags
370 momentum_end(void *_po, void *event_info)
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);
377 po->m_dx = p->mx / 200;
378 po->m_dy = p->my / 200;
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;
388 static Evas_Event_Flags
389 momentum_abort(void *_po, void *event_info)
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);
397 return EVAS_EVENT_FLAG_NONE;
401 _win_del_req(void *data, Evas_Object *obj __UNUSED__,
402 void *event_info __UNUSED__)
404 Photo_Object **photo_array = (Photo_Object **) data;
409 /* The content of the photo object is automatically deleted when the win
411 for ( ; *photo_array ; photo_array++)
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)
424 po = calloc(1, sizeof(*po));
425 po->base_zoom = po->zoom = BASE_ZOOM;
433 po->ic = elm_icon_add(parent);
434 elm_icon_file_set(po->ic, icon, NULL);
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);
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);
456 evas_object_resize(po->ic, po->bw, po->bh);
457 evas_object_show(po->ic);
459 evas_object_show(po->hit);
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);
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);
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);
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);
493 po->rotate = po->base_rotate = angle;
494 po->shadow_zoom = 1.3;
501 test_gesture_layer3(void *data __UNUSED__, Evas_Object *obj __UNUSED__,
502 void *event_info __UNUSED__)
505 Evas_Object *win, *bg;
508 Photo_Object **photo_array;
509 photo_array = calloc(sizeof(*photo_array), 4);
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);
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);
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);
529 photo_array[ind] = NULL;
530 evas_object_smart_callback_add(win, "delete,request", _win_del_req,
532 evas_object_show(win);