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_out_animation_duration = 0.4;
19 struct _Photo_Object {
20 Evas_Object *ic, *shadow;
23 Elm_Animator *zoom_out;
24 /* bx, by - current wanted coordinates of the photo object.
25 * bw, bh - original size of the "ic" object.
26 * dx, dy - Used to indicate the distance between the center point
27 * where we put down our fingers (when started moving the item) to
28 * the coords of the object, so we'll be able to calculate movement
30 Evas_Coord bx, by, bw, bh, dx, dy;
31 /* Because gesture layer only knows the amount of rotation/zoom we do
32 * per gesture, we have to keep the current rotate/zoom factor and the
33 * one that was before we started the gesture. */
34 int base_rotate, rotate;
35 double base_zoom, zoom;
38 typedef struct _Photo_Object Photo_Object;
41 /* This function applies the information from the Photo_Object to the actual
42 * evas objects. Zoom/rotate factors and etc. */
44 apply_changes(Photo_Object *po)
48 map = evas_map_new(4);
49 evas_map_point_coord_set(map, 0, po->bx, po->by, 0);
50 evas_map_point_coord_set(map, 1, po->bx + po->bw, po->by, 0);
51 evas_map_point_coord_set(map, 2, po->bx + po->bw, po->by + po->bh, 0);
52 evas_map_point_coord_set(map, 3, po->bx, po->by + po->bh, 0);
53 evas_map_point_image_uv_set(map, 0, 0, 0);
54 evas_map_point_image_uv_set(map, 1, po->bw, 0);
55 evas_map_point_image_uv_set(map, 2, po->bw, po->bh);
56 evas_map_point_image_uv_set(map, 3, 0, po->bh);
57 evas_map_util_rotate(map, po->rotate,
58 po->bx + po->bw / 2, po->by + po->bh /2);
59 evas_map_util_zoom(map, po->zoom, po->zoom,
60 po->bx + po->bw / 2, po->by + po->bh /2);
61 evas_object_map_enable_set(po->ic, EINA_TRUE);
62 evas_object_map_set(po->ic, map);
65 Evas_Map *shadow_map = evas_map_new(4);
66 evas_map_point_coord_set(shadow_map, 0, po->bx, po->by, 0);
67 evas_map_point_coord_set(shadow_map, 1, po->bx + po->bw, po->by, 0);
68 evas_map_point_coord_set(shadow_map, 2, po->bx + po->bw, po->by + po->bh, 0);
69 evas_map_point_coord_set(shadow_map, 3, po->bx, po->by + po->bh, 0);
70 evas_map_point_image_uv_set(shadow_map, 0, 0, 0);
71 evas_map_point_image_uv_set(shadow_map, 1, SHADOW_W, 0);
72 evas_map_point_image_uv_set(shadow_map, 2, SHADOW_W, SHADOW_H);
73 evas_map_point_image_uv_set(shadow_map, 3, 0, SHADOW_H);
74 evas_map_util_rotate(shadow_map, po->rotate,
75 po->bx + po->bw / 2, po->by + po->bh /2);
76 evas_map_util_zoom(shadow_map, po->zoom * po->shadow_zoom,
77 po->zoom * po->shadow_zoom,
78 po->bx + (po->bw / 2), po->by + (po->bh / 2));
79 evas_object_map_enable_set(po->shadow, EINA_TRUE);
80 evas_object_map_set(po->shadow, shadow_map);
81 evas_map_free(shadow_map);
84 /* Update the position of the hit box */
86 Evas_Coord minx, miny, maxx, maxy;
88 evas_object_polygon_points_clear(po->hit);
89 evas_map_point_coord_get(map, 0, &minx, &miny, NULL);
92 evas_object_polygon_point_add(po->hit, minx, miny);
93 for (i = 1 ; i <= 3 ; i++)
96 evas_map_point_coord_get(map, i, &x, &y, NULL);
97 evas_object_polygon_point_add(po->hit, x, y);
110 evas_object_raise(po->shadow);
111 evas_object_raise(po->ic);
112 evas_object_raise(po->hit);
116 /* Zoom out animation */
118 zoom_out_animation_operation(void *_po, Elm_Animator *animator __UNUSED__,
121 Photo_Object *po = (Photo_Object *) _po;
122 po->zoom = BASE_ZOOM + ((po->base_zoom - BASE_ZOOM) * (1.0 - frame));
127 zoom_out_animation_end(void *_po)
129 Photo_Object *po = (Photo_Object *) _po;
131 po->base_zoom = po->zoom = BASE_ZOOM;
134 elm_animator_del(po->zoom_out);
138 static Evas_Event_Flags
139 rotate_move(void *_po, void *event_info)
141 Photo_Object *po = (Photo_Object *) _po;
142 Elm_Gesture_Rotate_Info *p = (Elm_Gesture_Rotate_Info *) event_info;
143 printf("rotate move <%d,%d> base=<%f> <%f>\n", p->x, p->y, RAD2DEG(p->base_angle), RAD2DEG(p->angle));
144 po->rotate = po->base_rotate + (int) RAD2DEG(p->base_angle - p->angle);
148 return EVAS_EVENT_FLAG_NONE;
151 static Evas_Event_Flags
152 rotate_end(void *_po, void *event_info)
154 Photo_Object *po = (Photo_Object *) _po;
155 Elm_Gesture_Rotate_Info *p = (Elm_Gesture_Rotate_Info *) event_info;
156 printf("rotate end/abort <%d,%d> base=<%f> <%f>\n", p->x, p->y, RAD2DEG(p->base_angle), RAD2DEG(p->angle));
157 po->base_rotate += (int) RAD2DEG(p->base_angle - p->angle);
160 return EVAS_EVENT_FLAG_NONE;
163 static Evas_Event_Flags
164 zoom_start(void *_po, void *event_info)
166 Photo_Object *po = (Photo_Object *) _po;
167 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
168 printf("zoom start <%d,%d> <%f>\n", p->x, p->y, p->zoom);
170 /* If there's an active animator, stop it */
173 elm_animator_del(po->zoom_out);
178 po->dx = p->x - po->bx;
179 po->dy = p->y - po->by;
180 /* Give it a "lift" effect right from the start */
181 po->base_zoom = BASE_ZOOM * LIFT_FACTOR;
182 po->zoom = po->base_zoom;
183 po->shadow_zoom = 1.7;
186 return EVAS_EVENT_FLAG_NONE;
189 static Evas_Event_Flags
190 zoom_move(void *_po, void *event_info)
192 Photo_Object *po = (Photo_Object *) _po;
193 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
194 printf("zoom move <%d,%d> <%f>\n", p->x, p->y, p->zoom);
195 po->zoom = po->base_zoom * p->zoom;
196 po->bx = p->x - po->dx;
197 po->by = p->y - po->dy;
199 return EVAS_EVENT_FLAG_NONE;
202 static Evas_Event_Flags
203 zoom_end(void *_po, void *event_info)
205 Photo_Object *po = (Photo_Object *) _po;
206 Elm_Gesture_Zoom_Info *p = (Elm_Gesture_Zoom_Info *) event_info;
207 printf("zoom end/abort <%d,%d> <%f>\n", p->x, p->y, p->zoom);
209 /* Make sure middle is in the screen, if not, fix it. */
211 /* FIXME: Use actual window sizes instead of the hardcoded
214 mx = po->bx + (po->bw / 2);
215 my = po->by + (po->bh / 2);
217 po->bx = 0 - (po->bw / 2);
219 po->bx = 480 - (po->bw / 2);
222 po->by = 0 - (po->bw / 2);
224 po->by = 800 - (po->bh / 2);
227 /* Apply the zoom out animator */
228 po->shadow_zoom = 1.3;
229 po->base_zoom = po->zoom;
230 po->zoom_out = elm_animator_add(po->ic);
231 elm_animator_duration_set(po->zoom_out, zoom_out_animation_duration);
232 elm_animator_curve_style_set(po->zoom_out, ELM_ANIMATOR_CURVE_LINEAR);
233 elm_animator_operation_callback_set(po->zoom_out,
234 zoom_out_animation_operation, po);
235 elm_animator_completion_callback_set(po->zoom_out,
236 zoom_out_animation_end, po);
237 elm_animator_animate(po->zoom_out);
238 return EVAS_EVENT_FLAG_NONE;
242 photo_object_add(Evas_Object *parent, Evas_Object *ic, const char *icon, Evas_Coord x,
243 Evas_Coord y, Evas_Coord w, Evas_Coord h, int angle)
246 po = calloc(1, sizeof(*po));
247 po->base_zoom = po->zoom = BASE_ZOOM;
255 po->ic = elm_icon_add(parent);
256 elm_icon_file_set(po->ic, icon, NULL);
266 po->shadow = elm_icon_add(po->ic);
267 elm_icon_file_set(po->shadow, PACKAGE_DATA_DIR "/images/pol_shadow.png", NULL);
268 evas_object_resize(po->shadow, SHADOW_W, SHADOW_H);
269 evas_object_show(po->shadow);
272 po->hit = evas_object_polygon_add(evas_object_evas_get(parent));
273 evas_object_precise_is_inside_set(po->hit, EINA_TRUE);
274 evas_object_repeat_events_set(po->hit, EINA_TRUE);
275 evas_object_color_set(po->hit, 0, 0, 0, 0);
277 evas_object_resize(po->ic, po->bw, po->bh);
278 evas_object_show(po->ic);
280 evas_object_show(po->hit);
282 po->gl = elm_gesture_layer_add(po->ic);
283 elm_gesture_layer_hold_events_set(po->gl, EINA_TRUE);
284 elm_gesture_layer_attach(po->gl, po->hit);
286 /* FIXME: Add a po->rotate start so we take the first angle!!!! */
287 elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_MOVE, rotate_move, po);
288 elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_END, rotate_end, po);
289 elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ROTATE, ELM_GESTURE_STATE_ABORT, rotate_end, po);
290 elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_START, zoom_start, po);
291 elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_MOVE, zoom_move, po);
292 elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_END, zoom_end, po);
293 elm_gesture_layer_cb_set(po->gl, ELM_GESTURE_ZOOM, ELM_GESTURE_STATE_ABORT, zoom_end, po);
295 po->rotate = po->base_rotate = angle;
296 po->shadow_zoom = 1.3;
303 test_gesture_layer(void *data __UNUSED__, Evas_Object *obj __UNUSED__,
304 void *event_info __UNUSED__)
307 Evas_Object *win, *bg;
312 win = elm_win_add(NULL, "gesture-layer", ELM_WIN_BASIC);
313 elm_win_title_set(win, "Gesture Layer");
314 elm_win_autodel_set(win, EINA_TRUE);
315 evas_object_resize(win, w, h);
317 bg = elm_bg_add(win);
318 elm_bg_file_set(bg, PACKAGE_DATA_DIR "/images/wood_01.jpg", NULL);
319 elm_win_resize_object_add(win, bg);
320 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
321 evas_object_show(bg);
324 photo_object_add(win, NULL, PACKAGE_DATA_DIR "/images/pol_sky.png", 200, 200, 365, 400, 0);
325 photo_object_add(win, NULL, PACKAGE_DATA_DIR "/images/pol_twofish.png", 40, 300, 365, 400, 45);
327 Evas_Object *en = elm_entry_add(win);
328 elm_entry_entry_set(en, "You can use whatever object you want, "
329 "even entries like this.");
330 elm_entry_line_wrap_set(en, ELM_WRAP_MIXED);
332 Evas_Object *postit = elm_layout_add(win);
333 elm_layout_file_set(postit, PACKAGE_DATA_DIR "/objects/postit_ent.edj", "main");
334 elm_layout_content_set(postit, "ent", en);
336 photo_object_add(win, postit, NULL, 50, 50, 382, 400, 355);
338 evas_object_show(win);