tizen 2.3 release
[framework/uifw/elementary.git] / src / bin / test_dnd.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4 #include <Elementary.h>
5
6 static const char *img[9] =
7 {
8    "panel_01.jpg",
9    "plant_01.jpg",
10    "rock_01.jpg",
11    "rock_02.jpg",
12    "sky_01.jpg",
13    "sky_02.jpg",
14    "sky_03.jpg",
15    "sky_04.jpg",
16    "wood_01.jpg",
17 };
18
19 struct _anim_icon_st
20 {
21    int start_x;
22    int start_y;
23    Evas_Object *o;
24 };
25 typedef struct _anim_icon_st anim_icon_st;
26
27 struct _drag_anim_st
28 {
29    Evas_Object *icwin;
30    Evas *e;
31    Evas_Coord mdx;     /* Mouse-down x */
32    Evas_Coord mdy;     /* Mouse-down y */
33    Eina_List *icons;   /* List of icons to animate (anim_icon_st) */
34    Ecore_Timer *tm;
35    Ecore_Animator *ea;
36    Evas_Object *gl;
37 };
38 typedef struct _drag_anim_st drag_anim_st;
39
40 #define DRAG_TIMEOUT 0.3
41 #define ANIM_TIME 0.5
42
43 static Eina_Bool _5s_cancel = EINA_FALSE;
44 static Ecore_Timer *_5s_timeout = NULL;
45
46 static int
47 _item_ptr_cmp(const void *d1, const void *d2)
48 {
49    return (d1 - d2);
50 }
51
52 static Elm_Genlist_Item_Class *itc1;
53 static Elm_Gengrid_Item_Class *gic;
54
55 static char *
56 gl_text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *part EINA_UNUSED)
57 {
58    return strdup(data);
59 }
60
61 static Evas_Object *
62 gl_content_get(void *data, Evas_Object *obj, const char *part)
63 {
64    if (!strcmp(part, "elm.swallow.icon"))
65      {
66         Evas_Object *icon = elm_icon_add(obj);
67         elm_image_file_set(icon, data, NULL);
68         evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
69         evas_object_show(icon);
70         return icon;
71      }
72    return NULL;
73 }
74
75 static void
76 _win_del(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
77 {
78    printf("<%s> <%d> will del <%p>\n", __func__, __LINE__, data);
79    elm_drop_item_container_del(data);
80    elm_drag_item_container_del(data);
81
82    if (gic) elm_gengrid_item_class_free(gic);
83    gic = NULL;
84    if (itc1) elm_genlist_item_class_free(itc1);
85    itc1 = NULL;
86 }
87
88 static Elm_Object_Item *
89 _gl_item_getcb(Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *xposret EINA_UNUSED, int *yposret)
90 {  /* This function returns pointer to item under (x,y) coords */
91    printf("<%s> <%d> obj=<%p>\n", __func__, __LINE__, obj);
92    Elm_Object_Item *gli;
93    gli = elm_genlist_at_xy_item_get(obj, x, y, yposret);
94    if (gli)
95      printf("over <%s>, gli=<%p> yposret %i\n",
96            (char *)elm_object_item_data_get(gli), gli, *yposret);
97    else
98      printf("over none, yposret %i\n", *yposret);
99    return gli;
100 }
101
102 static Elm_Object_Item *
103 _grid_item_getcb(Evas_Object *obj, Evas_Coord x, Evas_Coord y, int *xposret, int *yposret)
104 {  /* This function returns pointer to item under (x,y) coords */
105    printf("<%s> <%d> obj=<%p>\n", __func__, __LINE__, obj);
106    Elm_Object_Item *item;
107    item = elm_gengrid_at_xy_item_get(obj, x, y, xposret, yposret);
108    if (item)
109      printf("over <%s>, item=<%p> xposret %i yposret %i\n",
110            (char *)elm_object_item_data_get(item), item, *xposret, *yposret);
111    else
112      printf("over none, xposret %i yposret %i\n", *xposret, *yposret);
113    return item;
114 }
115
116 static Eina_Bool
117 _gl_dropcb(void *data EINA_UNUSED, Evas_Object *obj, Elm_Object_Item *it, Elm_Selection_Data *ev, int xposret EINA_UNUSED, int yposret)
118 {  /* This function is called when data is dropped on the genlist */
119    printf("<%s> <%d> str=<%s>\n", __func__, __LINE__, (char *) ev->data);
120    if (!ev->data)
121      return EINA_FALSE;
122
123    char *p = ev->data;
124    p = strchr(p, '#');
125    while(p)
126      {
127         p++;
128         char *p2 = strchr(p, '#');
129         if (p2)
130           {
131              *p2 = '\0';
132              printf("Item %s\n", p);
133              switch(yposret)
134                {
135                 case -1:  /* Dropped on top-part of the it item */
136                      {
137                         elm_genlist_item_insert_before(obj,
138                               itc1, strdup(p), NULL, it,
139                               ELM_GENLIST_ITEM_NONE,
140                               NULL, NULL);
141                         break;
142                      }
143                 case  0:  /* Dropped on center of the it item      */
144                 case  1:  /* Dropped on botton-part of the it item */
145                      {
146                         if (!it) it = elm_genlist_last_item_get(obj);
147                         if (it) it = elm_genlist_item_insert_after(obj,
148                               itc1, strdup(p), NULL, it,
149                               ELM_GENLIST_ITEM_NONE,
150                               NULL, NULL);
151                         else
152                            it = elm_genlist_item_append(obj,
153                                  itc1, strdup(p), NULL,
154                                  ELM_GENLIST_ITEM_NONE,
155                                  NULL, NULL);
156                         break;
157                      }
158                 default:
159                    return EINA_FALSE;
160                }
161              p = p2;
162           }
163         else p = NULL;
164      }
165
166    return EINA_TRUE;
167 }
168
169 static Eina_Bool
170 _grid_dropcb(void *data EINA_UNUSED, Evas_Object *obj, Elm_Object_Item *it, Elm_Selection_Data *ev, int xposret EINA_UNUSED, int yposret EINA_UNUSED)
171 {  /* This function is called when data is dropped on the genlist */
172    printf("<%s> <%d> str=<%s>\n", __func__, __LINE__, (char *) ev->data);
173    if (!ev->data)
174      return EINA_FALSE;
175
176    char *p = ev->data;
177    p = strchr(p, '#');
178    while(p)
179      {
180         p++;
181         char *p2 = strchr(p, '#');
182         if (p2)
183           {
184              *p2 = '\0';
185              printf("Item %s\n", p);
186              if (!it) it = elm_gengrid_last_item_get(obj);
187              if (it) it = elm_gengrid_item_insert_after(obj, gic, strdup(p), it, NULL, NULL);
188              else it = elm_gengrid_item_append(obj, gic, strdup(p), NULL, NULL);
189              p = p2;
190           }
191         else p = NULL;
192      }
193
194    return EINA_TRUE;
195 }
196
197 static void _gl_obj_mouse_move( void *data, Evas *e, Evas_Object *obj, void *event_info);
198 static void _gl_obj_mouse_up( void *data, Evas *e, Evas_Object *obj, void *event_info);
199
200 static void
201 anim_st_free(drag_anim_st *anim_st)
202 {  /* Stops and free mem of ongoing animation */
203    printf("<%s> <%d>\n", __func__, __LINE__);
204    if (anim_st)
205      {
206         evas_object_event_callback_del_full
207            (anim_st->gl, EVAS_CALLBACK_MOUSE_MOVE, _gl_obj_mouse_move, anim_st);
208         evas_object_event_callback_del_full
209            (anim_st->gl, EVAS_CALLBACK_MOUSE_UP, _gl_obj_mouse_up, anim_st);
210         if (anim_st->tm)
211           {
212              ecore_timer_del(anim_st->tm);
213              anim_st->tm = NULL;
214           }
215
216         if (anim_st->ea)
217           {
218              ecore_animator_del(anim_st->ea);
219              anim_st->ea = NULL;
220           }
221
222         anim_icon_st *st;
223
224         EINA_LIST_FREE(anim_st->icons, st)
225           {
226              evas_object_hide(st->o);
227              evas_object_del(st->o);
228              free(st);
229           }
230
231         free(anim_st);
232      }
233 }
234
235 static Eina_Bool
236 _drag_anim_play(void *data, double pos)
237 {  /* Impl of the animation of icons, called on frame time */
238    drag_anim_st *anim_st = data;
239    printf("<%s> <%d>\n", __func__, __LINE__);
240    Eina_List *l;
241    anim_icon_st *st;
242
243    if (anim_st)
244      {
245         if (pos > 0.99)
246           {
247              anim_st->ea = NULL;  /* Avoid deleting on mouse up */
248
249              EINA_LIST_FOREACH(anim_st->icons, l, st)
250                 evas_object_hide(st->o);   /* Hide animated icons */
251              anim_st_free(anim_st);
252              return ECORE_CALLBACK_CANCEL;
253           }
254
255         EINA_LIST_FOREACH(anim_st->icons, l, st)
256           {
257              int x, y, w, h;
258              Evas_Coord xm, ym;
259              evas_object_geometry_get(st->o, NULL, NULL, &w, &h);
260              evas_pointer_canvas_xy_get(anim_st->e, &xm, &ym);
261              x = st->start_x + (pos * (xm - (st->start_x + (w/2))));
262              y = st->start_y + (pos * (ym - (st->start_y + (h/2))));
263              evas_object_move(st->o, x, y);
264           }
265
266         return ECORE_CALLBACK_RENEW;
267      }
268
269    return ECORE_CALLBACK_CANCEL;
270 }
271
272 static Eina_Bool
273 _gl_anim_start(void *data)
274 {  /* Start icons animation before actually drag-starts */
275    drag_anim_st *anim_st = data;
276    printf("<%s> <%d>\n", __func__, __LINE__);
277    int yposret = 0;
278
279    Eina_List *l;
280    Eina_List *items = eina_list_clone(elm_genlist_selected_items_get(anim_st->gl));
281    Elm_Object_Item *gli = elm_genlist_at_xy_item_get(anim_st->gl,
282          anim_st->mdx, anim_st->mdy, &yposret);
283    if (gli)
284      {  /* Add the item mouse is over to the list if NOT seleced */
285         void *p = eina_list_search_unsorted(items, _item_ptr_cmp, gli);
286         if (!p)
287           items = eina_list_append(items, gli);
288      }
289
290    EINA_LIST_FOREACH(items, l, gli)
291      {  /* Now add icons to animation window */
292         Evas_Object *o = elm_object_item_part_content_get(gli,
293               "elm.swallow.icon");
294
295         if (o)
296           {
297              int w, h;
298              const char *f;
299              const char *g;
300              anim_icon_st *st = calloc(1, sizeof(*st));
301              elm_image_file_get(o, &f, &g);
302              Evas_Object *ic = elm_icon_add(anim_st->gl);
303              elm_image_file_set(ic, f, g);
304              evas_object_geometry_get(o, &st->start_x, &st->start_y, &w, &h);
305              evas_object_size_hint_align_set(ic,
306                    EVAS_HINT_FILL, EVAS_HINT_FILL);
307              evas_object_size_hint_weight_set(ic,
308                    EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
309
310              evas_object_move(ic, st->start_x, st->start_y);
311              evas_object_resize(ic, w, h);
312              evas_object_show(ic);
313
314              st->o = ic;
315              anim_st->icons = eina_list_append(anim_st->icons, st);
316           }
317      }
318
319    eina_list_free(items);
320
321    anim_st->tm = NULL;
322    anim_st->ea = ecore_animator_timeline_add(DRAG_TIMEOUT,
323          _drag_anim_play, anim_st);
324
325    return ECORE_CALLBACK_CANCEL;
326 }
327
328 static void
329 _gl_obj_mouse_up(
330    void *data,
331    Evas *e EINA_UNUSED,
332    Evas_Object *obj EINA_UNUSED,
333    void *event_info EINA_UNUSED)
334 {  /* Cancel any drag waiting to start on timeout */
335    drag_anim_st *anim_st = data;
336    anim_st_free(anim_st);
337 }
338
339 static void
340 _gl_obj_mouse_move(
341    void *data,
342    Evas *e EINA_UNUSED,
343    Evas_Object *obj EINA_UNUSED,
344    void *event_info)
345 {  /* Cancel any drag waiting to start on timeout */
346
347    if (((Evas_Event_Mouse_Move *)event_info)->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
348      {
349         drag_anim_st *anim_st = data;
350         anim_st_free(anim_st);
351      }
352 }
353
354 static void
355 _gl_obj_mouse_down(
356    void *data,
357    Evas *e EINA_UNUSED,
358    Evas_Object *obj EINA_UNUSED,
359    void *event_info)
360 {  /* Launch a timer to start drag animation */
361    Evas_Event_Mouse_Down *ev = event_info;
362    drag_anim_st *anim_st = calloc(1, sizeof(*anim_st));
363    anim_st->e = e;
364    anim_st->mdx = ev->canvas.x;
365    anim_st->mdy = ev->canvas.y;
366    anim_st->gl = data;
367    anim_st->tm = ecore_timer_add(DRAG_TIMEOUT, _gl_anim_start, anim_st);
368    evas_object_event_callback_add(data, EVAS_CALLBACK_MOUSE_UP,
369          _gl_obj_mouse_up, anim_st);
370    evas_object_event_callback_add(data, EVAS_CALLBACK_MOUSE_MOVE,
371          _gl_obj_mouse_move, anim_st);
372 }
373 /* END   - Handling drag start animation */
374
375 static void
376 _gl_dragdone(void *data, Evas_Object *obj EINA_UNUSED, Eina_Bool doaccept)
377 {
378    printf("<%s> <%d> data=<%p> doaccept=<%d>\n",
379          __func__, __LINE__, data, doaccept);
380
381    Elm_Object_Item *it;
382    Eina_List *l;
383
384    if (_5s_cancel)
385      {
386         ecore_timer_del(_5s_timeout);
387         _5s_timeout = NULL;
388      }
389
390    if (doaccept)
391      {  /* Remove items dragged out (accepted by target) */
392         EINA_LIST_FOREACH(data, l, it)
393            elm_object_item_del(it);
394      }
395
396    eina_list_free(data);
397    return;
398 }
399
400 static Eina_Bool
401 _5s_timeout_gone(void *data)
402 {
403    printf("Cancel DnD\n");
404    elm_drag_cancel(data);
405    _5s_timeout = NULL;
406    return ECORE_CALLBACK_CANCEL;
407 }
408
409 static Evas_Object *
410 _gl_createicon(void *data, Evas_Object *win, Evas_Coord *xoff, Evas_Coord *yoff)
411 {
412    printf("<%s> <%d>\n", __func__, __LINE__);
413    Evas_Object *icon = NULL;
414    Evas_Object *o = elm_object_item_part_content_get(data, "elm.swallow.icon");
415
416    if (o)
417      {
418         int xm, ym, w = 30, h = 30;
419         const char *f;
420         const char *g;
421         elm_image_file_get(o, &f, &g);
422         evas_pointer_canvas_xy_get(evas_object_evas_get(o), &xm, &ym);
423         if (xoff) *xoff = xm - (w/2);
424         if (yoff) *yoff = ym - (h/2);
425         icon = elm_icon_add(win);
426         elm_image_file_set(icon, f, g);
427         evas_object_size_hint_align_set(icon,
428               EVAS_HINT_FILL, EVAS_HINT_FILL);
429         evas_object_size_hint_weight_set(icon,
430               EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
431         if (xoff && yoff) evas_object_move(icon, *xoff, *yoff);
432         evas_object_resize(icon, w, h);
433      }
434
435    return icon;
436 }
437
438 static Eina_List *
439 _gl_icons_get(void *data)
440 {  /* Start icons animation before actually drag-starts */
441    printf("<%s> <%d>\n", __func__, __LINE__);
442    int yposret = 0;
443
444    Eina_List *l;
445
446    Eina_List *icons = NULL;
447
448    Evas_Coord xm, ym;
449    evas_pointer_canvas_xy_get(evas_object_evas_get(data), &xm, &ym);
450    Eina_List *items = eina_list_clone(elm_genlist_selected_items_get(data));
451    Elm_Object_Item *gli = elm_genlist_at_xy_item_get(data,
452          xm, ym, &yposret);
453    if (gli)
454      {  /* Add the item mouse is over to the list if NOT seleced */
455         void *p = eina_list_search_unsorted(items, _item_ptr_cmp, gli);
456         if (!p)
457           items = eina_list_append(items, gli);
458      }
459
460    EINA_LIST_FOREACH(items, l, gli)
461      {  /* Now add icons to animation window */
462         Evas_Object *o = elm_object_item_part_content_get(gli,
463               "elm.swallow.icon");
464
465         if (o)
466           {
467              int x, y, w, h;
468              const char *f, *g;
469              elm_image_file_get(o, &f, &g);
470              Evas_Object *ic = elm_icon_add(data);
471              elm_image_file_set(ic, f, g);
472              evas_object_geometry_get(o, &x, &y, &w, &h);
473              evas_object_size_hint_align_set(ic,
474                    EVAS_HINT_FILL, EVAS_HINT_FILL);
475              evas_object_size_hint_weight_set(ic,
476                    EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
477
478              evas_object_move(ic, x, y);
479              evas_object_resize(ic, w, h);
480              evas_object_show(ic);
481
482              icons =  eina_list_append(icons, ic);
483           }
484      }
485
486    eina_list_free(items);
487    return icons;
488 }
489
490 static const char *
491 _gl_get_drag_data(Evas_Object *obj, Elm_Object_Item *it, Eina_List **items)
492 {  /* Construct a string of dragged info, user frees returned string */
493    const char *drag_data = NULL;
494    printf("<%s> <%d>\n", __func__, __LINE__);
495
496    *items = eina_list_clone(elm_genlist_selected_items_get(obj));
497    if (it)
498      {  /* Add the item mouse is over to the list if NOT seleced */
499         void *p = eina_list_search_unsorted(*items, _item_ptr_cmp, it);
500         if (!p)
501           *items = eina_list_append(*items, it);
502      }
503
504    if (*items)
505      {  /* Now we can actually compose string to send and start dragging */
506         Eina_List *l;
507         const char *t;
508         unsigned int len = 0;
509
510         EINA_LIST_FOREACH(*items, l, it)
511           {
512              t = (char *)elm_object_item_data_get(it);
513              if (t)
514                len += strlen(t);
515           }
516
517         drag_data = malloc(len + eina_list_count(*items) * 2 + 8);
518         strcpy((char *) drag_data, "file://");
519
520         EINA_LIST_FOREACH(*items, l, it)
521           {
522              t = (char *)elm_object_item_data_get(it);
523              if (t)
524                {
525                   strcat((char *) drag_data, "#");
526                   strcat((char *) drag_data, t);
527                }
528           }
529         strcat((char *) drag_data, "#");
530
531         printf("<%s> <%d> Sending <%s>\n", __func__, __LINE__, drag_data);
532      }
533
534    return drag_data;
535 }
536
537 static const char *
538 _grid_get_drag_data(Evas_Object *obj, Elm_Object_Item *it, Eina_List **items)
539 {  /* Construct a string of dragged info, user frees returned string */
540    const char *drag_data = NULL;
541    printf("<%s> <%d>\n", __func__, __LINE__);
542
543    *items = eina_list_clone(elm_gengrid_selected_items_get(obj));
544    if (it)
545      {  /* Add the item mouse is over to the list if NOT seleced */
546         void *p = eina_list_search_unsorted(*items, _item_ptr_cmp, it);
547         if (!p)
548           *items = eina_list_append(*items, it);
549      }
550
551    if (*items)
552      {  /* Now we can actually compose string to send and start dragging */
553         Eina_List *l;
554         const char *t;
555         unsigned int len = 0;
556
557         EINA_LIST_FOREACH(*items, l, it)
558           {
559              t = (char *)elm_object_item_data_get(it);
560              if (t)
561                len += strlen(t);
562           }
563
564         drag_data = malloc(len + eina_list_count(*items) * 2 + 8);
565         strcpy((char *) drag_data, "file://");
566
567         EINA_LIST_FOREACH(*items, l, it)
568           {
569              t = (char *)elm_object_item_data_get(it);
570              if (t)
571                {
572                   strcat((char *) drag_data, "#");
573                   strcat((char *) drag_data, t);
574                }
575           }
576         strcat((char *) drag_data, "#");
577
578         printf("<%s> <%d> Sending <%s>\n", __func__, __LINE__, drag_data);
579      }
580
581    return drag_data;
582 }
583
584 static Eina_Bool
585 _gl_dnd_default_anim_data_getcb(Evas_Object *obj,  /* The genlist object */
586       Elm_Object_Item *it,
587       Elm_Drag_User_Info *info)
588 {  /* This called before starting to drag, mouse-down was on it */
589    info->format = ELM_SEL_FORMAT_TARGETS;
590    info->createicon = _gl_createicon;
591    info->createdata = it;
592    info->icons = _gl_icons_get(obj);
593    info->dragdone = _gl_dragdone;
594
595    /* Now, collect data to send for drop from ALL selected items */
596    /* Save list pointer to remove items after drop and free list on done */
597    info->data = _gl_get_drag_data(obj, it, (Eina_List **) &info->donecbdata);
598    printf("%s - data = %s\n", __FUNCTION__, info->data);
599    info->acceptdata = info->donecbdata;
600
601    if (info->data)
602      return EINA_TRUE;
603    else
604      return EINA_FALSE;
605 }
606
607 static Eina_Bool
608 _gl_data_getcb(Evas_Object *obj,  /* The genlist object */
609       Elm_Object_Item *it,
610       Elm_Drag_User_Info *info)
611 {  /* This called before starting to drag, mouse-down was on it */
612    info->format = ELM_SEL_FORMAT_TARGETS;
613    info->createicon = _gl_createicon;
614    info->createdata = it;
615    info->dragdone = _gl_dragdone;
616
617    /* Now, collect data to send for drop from ALL selected items */
618    /* Save list pointer to remove items after drop and free list on done */
619    info->data = _gl_get_drag_data(obj, it, (Eina_List **) &info->donecbdata);
620    info->acceptdata = info->donecbdata;
621
622    if (info->data)
623      return EINA_TRUE;
624    else
625      return EINA_FALSE;
626 }
627
628 static Eina_List *
629 _grid_icons_get(void *data)
630 {  /* Start icons animation before actually drag-starts */
631    printf("<%s> <%d>\n", __func__, __LINE__);
632
633    Eina_List *l;
634
635    Eina_List *icons = NULL;
636
637    Evas_Coord xm, ym;
638    evas_pointer_canvas_xy_get(evas_object_evas_get(data), &xm, &ym);
639    Eina_List *items = eina_list_clone(elm_gengrid_selected_items_get(data));
640    Elm_Object_Item *gli = elm_gengrid_at_xy_item_get(data,
641          xm, ym, NULL, NULL);
642    if (gli)
643      {  /* Add the item mouse is over to the list if NOT seleced */
644         void *p = eina_list_search_unsorted(items, _item_ptr_cmp, gli);
645         if (!p)
646           items = eina_list_append(items, gli);
647      }
648
649    EINA_LIST_FOREACH(items, l, gli)
650      {  /* Now add icons to animation window */
651         Evas_Object *o = elm_object_item_part_content_get(gli,
652               "elm.swallow.icon");
653
654         if (o)
655           {
656              int x, y, w, h;
657              const char *f, *g;
658              elm_image_file_get(o, &f, &g);
659              Evas_Object *ic = elm_icon_add(data);
660              elm_image_file_set(ic, f, g);
661              evas_object_geometry_get(o, &x, &y, &w, &h);
662              evas_object_size_hint_align_set(ic,
663                    EVAS_HINT_FILL, EVAS_HINT_FILL);
664              evas_object_size_hint_weight_set(ic,
665                    EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
666
667              evas_object_move(ic, x, y);
668              evas_object_resize(ic, w, h);
669              evas_object_show(ic);
670
671              icons =  eina_list_append(icons, ic);
672           }
673      }
674
675    eina_list_free(items);
676    return icons;
677 }
678
679 static void
680 _gl_dragstart(void *data EINA_UNUSED, Evas_Object *obj)
681 {
682    printf("<%s> <%d>\n", __func__, __LINE__);
683    if (_5s_cancel)
684      _5s_timeout = ecore_timer_add(5.0, _5s_timeout_gone, obj);
685 }
686
687 static Eina_Bool
688 _grid_data_getcb(Evas_Object *obj,  /* The genlist object */
689       Elm_Object_Item *it,
690       Elm_Drag_User_Info *info)
691 {  /* This called before starting to drag, mouse-down was on it */
692    info->format = ELM_SEL_FORMAT_TARGETS;
693    info->createicon = _gl_createicon;
694    info->createdata = it;
695    info->dragstart = _gl_dragstart;
696    info->icons = _grid_icons_get(obj);
697    info->dragdone = _gl_dragdone;
698
699    /* Now, collect data to send for drop from ALL selected items */
700    /* Save list pointer to remove items after drop and free list on done */
701    info->data = _grid_get_drag_data(obj, it, (Eina_List **) &info->donecbdata);
702    printf("%s - data = %s\n", __FUNCTION__, info->data);
703    info->acceptdata = info->donecbdata;
704
705    if (info->data)
706      return EINA_TRUE;
707    else
708      return EINA_FALSE;
709 }
710
711 void
712 test_dnd_genlist_default_anim(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
713 {
714    char buf[PATH_MAX];
715    Evas_Object *win, *gl, *bxx;
716    int i, j;
717
718    win = elm_win_util_standard_add("dnd-genlist-default-anim", "DnD-Genlist-Default-Anim");
719    elm_win_autodel_set(win, EINA_TRUE);
720
721    bxx = elm_box_add(win);
722    elm_box_horizontal_set(bxx, EINA_TRUE);
723    evas_object_size_hint_weight_set(bxx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
724    elm_win_resize_object_add(win, bxx);
725    evas_object_show(bxx);
726
727    itc1 = elm_genlist_item_class_new();
728    itc1->item_style     = "default";
729    itc1->func.text_get = gl_text_get;
730    itc1->func.content_get  = gl_content_get;
731    itc1->func.del       = NULL;
732
733    for (j = 0; j < 2; j++)
734      {
735         gl = elm_genlist_add(win);
736
737         /* START Drag and Drop handling */
738         evas_object_smart_callback_add(win, "delete,request", _win_del, gl);
739         elm_genlist_multi_select_set(gl, EINA_TRUE); /* We allow multi drag */
740         elm_drop_item_container_add(gl,
741               ELM_SEL_FORMAT_TARGETS,
742               _gl_item_getcb,
743               NULL, NULL,
744               NULL, NULL,
745               NULL, NULL,
746               _gl_dropcb, NULL);
747
748         elm_drag_item_container_add(gl, ANIM_TIME, DRAG_TIMEOUT,
749               _gl_item_getcb, _gl_dnd_default_anim_data_getcb);
750
751         // FIXME: This causes genlist to resize the horiz axis very slowly :(
752         // Reenable this and resize the window horizontally, then try to resize it back
753         //elm_genlist_mode_set(gl, ELM_LIST_LIMIT);
754         evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
755         evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
756         elm_box_pack_end(bxx, gl);
757         evas_object_show(gl);
758
759         for (i = 0; i < 20; i++)
760           {
761              snprintf(buf, sizeof(buf), "%s/images/%s", elm_app_data_dir_get(), img[(i % 9)]);
762              const char *path = eina_stringshare_add(buf);
763              elm_genlist_item_append(gl, itc1, path, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
764           }
765      }
766
767    evas_object_resize(win, 680, 800);
768    evas_object_show(win);
769 }
770
771 void
772 test_dnd_genlist_user_anim(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
773 {
774    char buf[PATH_MAX];
775    Evas_Object *win, *gl, *bxx;
776    int i, j;
777
778    win = elm_win_util_standard_add("dnd-genlist-user-anim", "DnD-Genlist-User-Anim");
779    elm_win_autodel_set(win, EINA_TRUE);
780
781    bxx = elm_box_add(win);
782    elm_box_horizontal_set(bxx, EINA_TRUE);
783    evas_object_size_hint_weight_set(bxx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
784    elm_win_resize_object_add(win, bxx);
785    evas_object_show(bxx);
786
787    itc1 = elm_genlist_item_class_new();
788    itc1->item_style     = "default";
789    itc1->func.text_get = gl_text_get;
790    itc1->func.content_get  = gl_content_get;
791    itc1->func.del       = NULL;
792
793    for (j = 0; j < 2; j++)
794      {
795         gl = elm_genlist_add(win);
796
797         /* START Drag and Drop handling */
798         evas_object_smart_callback_add(win, "delete,request", _win_del, gl);
799         elm_genlist_multi_select_set(gl, EINA_TRUE); /* We allow multi drag */
800         elm_drop_item_container_add(gl,
801               ELM_SEL_FORMAT_TARGETS,
802               _gl_item_getcb,
803               NULL, NULL,
804               NULL, NULL,
805               NULL, NULL,
806               _gl_dropcb, NULL);
807
808         elm_drag_item_container_add(gl, ANIM_TIME, DRAG_TIMEOUT,
809               _gl_item_getcb, _gl_data_getcb);
810
811         /* We add mouse-down, up callbacks to start/stop drag animation */
812         evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_DOWN,
813               _gl_obj_mouse_down, gl);
814         /* END Drag and Drop handling */
815
816         // FIXME: This causes genlist to resize the horiz axis very slowly :(
817         // Reenable this and resize the window horizontally, then try to resize it back
818         //elm_genlist_mode_set(gl, ELM_LIST_LIMIT);
819         evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
820         evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
821         elm_box_pack_end(bxx, gl);
822         evas_object_show(gl);
823
824         for (i = 0; i < 20; i++)
825           {
826              snprintf(buf, sizeof(buf), "%s/images/%s", elm_app_data_dir_get(), img[(i % 9)]);
827              const char *path = eina_stringshare_add(buf);
828              elm_genlist_item_append(gl, itc1, path, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
829           }
830      }
831
832    evas_object_resize(win, 680, 800);
833    evas_object_show(win);
834 }
835
836 void
837 test_dnd_genlist_gengrid(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
838 {
839    char buf[PATH_MAX];
840    Evas_Object *win, *bxx;
841    int i;
842
843    win = elm_win_util_standard_add("dnd-genlist-gengrid", "DnD-Genlist-Gengrid");
844    elm_win_autodel_set(win, EINA_TRUE);
845
846    bxx = elm_box_add(win);
847    elm_box_horizontal_set(bxx, EINA_TRUE);
848    evas_object_size_hint_weight_set(bxx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
849    elm_win_resize_object_add(win, bxx);
850    evas_object_show(bxx);
851
852      {
853         itc1 = elm_genlist_item_class_new();
854         itc1->item_style     = "default";
855         itc1->func.text_get = gl_text_get;
856         itc1->func.content_get  = gl_content_get;
857         itc1->func.del       = NULL;
858
859         Evas_Object *gl = elm_genlist_add(win);
860         evas_object_smart_callback_add(win, "delete,request", _win_del, gl);
861
862         /* START Drag and Drop handling */
863         elm_genlist_multi_select_set(gl, EINA_TRUE); /* We allow multi drag */
864         elm_drop_item_container_add(gl, ELM_SEL_FORMAT_TARGETS, _gl_item_getcb, NULL, NULL,
865               NULL, NULL, NULL, NULL, _gl_dropcb, NULL);
866
867         elm_drag_item_container_add(gl, ANIM_TIME, DRAG_TIMEOUT,
868               _gl_item_getcb, _gl_dnd_default_anim_data_getcb);
869         /* END Drag and Drop handling */
870
871         // FIXME: This causes genlist to resize the horiz axis very slowly :(
872         // Reenable this and resize the window horizontally, then try to resize it back
873         //elm_genlist_mode_set(gl, ELM_LIST_LIMIT);
874         evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
875         evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
876         elm_box_pack_end(bxx, gl);
877         evas_object_show(gl);
878
879         for (i = 0; i < 20; i++)
880           {
881              snprintf(buf, sizeof(buf), "%s/images/%s", elm_app_data_dir_get(), img[(i % 9)]);
882              const char *path = eina_stringshare_add(buf);
883              elm_genlist_item_append(gl, itc1, path, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
884           }
885      }
886
887      {
888         Evas_Object *grid = elm_gengrid_add(win);
889         evas_object_smart_callback_add(win, "delete,request", _win_del, grid);
890         elm_gengrid_item_size_set(grid,
891               elm_config_scale_get() * 150,
892               elm_config_scale_get() * 150);
893         elm_gengrid_horizontal_set(grid, EINA_FALSE);
894         elm_gengrid_reorder_mode_set(grid, EINA_FALSE);
895         elm_gengrid_multi_select_set(grid, EINA_TRUE); /* We allow multi drag */
896         evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
897         evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
898
899         gic = elm_gengrid_item_class_new();
900         gic->item_style = "default";
901         gic->func.text_get = gl_text_get;
902         gic->func.content_get = gl_content_get;
903
904         elm_drop_item_container_add(grid, ELM_SEL_FORMAT_TARGETS, _grid_item_getcb, NULL, NULL,
905               NULL, NULL, NULL, NULL, _grid_dropcb, NULL);
906
907         elm_drag_item_container_add(grid, ANIM_TIME, DRAG_TIMEOUT,
908               _grid_item_getcb, _grid_data_getcb);
909         for (i = 0; i < 20; i++)
910           {
911              snprintf(buf, sizeof(buf), "%s/images/%s", elm_app_data_dir_get(), img[(i % 9)]);
912              const char *path = eina_stringshare_add(buf);
913              elm_gengrid_item_append(grid, gic, path, NULL, NULL);
914           }
915         elm_box_pack_end(bxx, grid);
916         evas_object_show(grid);
917      }
918
919    evas_object_resize(win, 680, 800);
920    evas_object_show(win);
921 }
922
923 static Eina_Bool _drop_box_button_new_cb(void *data, Evas_Object *obj, Elm_Selection_Data *ev)
924 {
925    Evas_Object *win = data;
926    char *p = strchr(ev->data, '#');
927    while(p)
928      {
929         p++;
930         char *p2 = strchr(p, '#');
931         if (p2)
932           {
933              *p2 = '\0';
934              Evas_Object *ic = elm_icon_add(win);
935              elm_image_file_set(ic, p, NULL);
936              evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
937              Evas_Object *bt = elm_button_add(win);
938              elm_object_text_set(bt, "Dropped button");
939              elm_object_part_content_set(bt, "icon", ic);
940              elm_box_pack_end(obj, bt);
941              evas_object_show(bt);
942              evas_object_show(ic);
943              p = p2;
944           }
945         else p = NULL;
946      }
947    return EINA_TRUE;
948 }
949
950 void _enter_but_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED)
951 {
952    printf("Entered %s - drop it here and I will never print this line anymore.\n", __FUNCTION__);
953 }
954
955 static Eina_Bool _drop_but_icon_change_cb(void *data, Evas_Object *obj, Elm_Selection_Data *ev)
956 {
957    Evas_Object *win = data;
958    Evas_Object *ic = elm_icon_add(win);
959    char *p = strchr(ev->data, '#');
960    if (!p) return EINA_FALSE;
961    p++;
962    char *p2 = strchr(p, '#');
963    if (!p2) return EINA_FALSE;
964    *p2 = '\0';
965    elm_image_file_set(ic, p, NULL);
966    evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
967    evas_object_del(elm_object_part_content_get(obj, "icon"));
968    elm_object_part_content_set(obj, "icon", ic);
969    evas_object_show(ic);
970    return EINA_TRUE;
971 }
972
973 /* Callback used to test multi-callbacks feature */
974 static Eina_Bool _drop_but_cb_remove_cb(void *data EINA_UNUSED, Evas_Object *obj, Elm_Selection_Data *ev EINA_UNUSED)
975 {
976    printf("Second callback called - removing it\n");
977    elm_drop_target_del(obj, ELM_SEL_FORMAT_TARGETS, _enter_but_cb, NULL, NULL, NULL, NULL, NULL, _drop_but_cb_remove_cb, NULL);
978    return EINA_TRUE;
979 }
980
981 static Eina_Bool _drop_bg_change_cb(void *data EINA_UNUSED, Evas_Object *obj, Elm_Selection_Data *ev)
982 {
983    char *p = strchr(ev->data, '#');
984    if (!p) return EINA_FALSE;
985    p++;
986    char *p2 = strchr(p, '#');
987    if (!p2) return EINA_FALSE;
988    *p2 = '\0';
989    elm_bg_file_set(obj, p, NULL);
990    return EINA_TRUE;
991 }
992
993 static void
994 _5s_cancel_ck_changed(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
995 {
996    _5s_cancel = elm_check_state_get(obj);
997 }
998
999 void
1000 test_dnd_multi_features(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1001 {
1002    char buf[PATH_MAX];
1003    Evas_Object *win, *bxx, *bg;
1004    int i;
1005
1006    win = elm_win_util_standard_add("dnd-multi-features", "DnD-Multi Features");
1007    elm_win_autodel_set(win, EINA_TRUE);
1008
1009    bg = elm_bg_add(win);
1010    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1011    elm_drop_target_add(bg, ELM_SEL_FORMAT_TARGETS, NULL, NULL, NULL, NULL, NULL, NULL, _drop_bg_change_cb, NULL);
1012    elm_win_resize_object_add(win, bg);
1013
1014    /* And show the background. */
1015    evas_object_show(bg);
1016    bxx = elm_box_add(win);
1017    elm_box_horizontal_set(bxx, EINA_TRUE);
1018    evas_object_size_hint_weight_set(bxx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1019    elm_win_resize_object_add(win, bxx);
1020    evas_object_show(bxx);
1021
1022      {
1023         Evas_Object *grid = elm_gengrid_add(bxx);
1024         evas_object_smart_callback_add(win, "delete,request", _win_del, grid);
1025         elm_gengrid_item_size_set(grid,
1026               elm_config_scale_get() * 100,
1027               elm_config_scale_get() * 100);
1028         elm_gengrid_horizontal_set(grid, EINA_FALSE);
1029         elm_gengrid_reorder_mode_set(grid, EINA_FALSE);
1030         elm_gengrid_multi_select_set(grid, EINA_TRUE); /* We allow multi drag */
1031         evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1032         evas_object_size_hint_align_set(grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
1033
1034         gic = elm_gengrid_item_class_new();
1035         gic->item_style = "default";
1036         gic->func.text_get = gl_text_get;
1037         gic->func.content_get = gl_content_get;
1038
1039         elm_drag_item_container_add(grid, ANIM_TIME, DRAG_TIMEOUT,
1040               _grid_item_getcb, _grid_data_getcb);
1041         for (i = 0; i < 10; i++)
1042           {
1043              snprintf(buf, sizeof(buf), "%s/images/%s", elm_app_data_dir_get(), img[(i % 9)]);
1044              const char *path = eina_stringshare_add(buf);
1045              Elm_Object_Item *item = elm_gengrid_item_append(grid, gic, path, NULL, NULL);
1046              elm_object_item_part_text_set(item, "elm.text", path);
1047           }
1048         elm_box_pack_end(bxx, grid);
1049         evas_object_show(grid);
1050      }
1051
1052      {
1053         Evas_Object *ic, *bt;
1054         Evas_Object *vert_box = elm_box_add(bxx);
1055         evas_object_size_hint_weight_set(vert_box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1056         elm_box_pack_end(bxx, vert_box);
1057         evas_object_show(vert_box);
1058         elm_drop_target_add(vert_box, ELM_SEL_FORMAT_TARGETS, NULL, NULL, NULL, NULL, NULL, NULL, _drop_box_button_new_cb, win);
1059
1060         _5s_cancel = EINA_FALSE;
1061         Evas_Object *ck = elm_check_add(vert_box);
1062         elm_object_style_set(ck, "toggle");
1063         elm_object_text_set(ck, "Cancel after 5s:");
1064         elm_check_state_set(ck, _5s_cancel);
1065         evas_object_smart_callback_add(ck, "changed", _5s_cancel_ck_changed, NULL);
1066         elm_box_pack_end(vert_box, ck);
1067         evas_object_show(ck);
1068
1069         ic = elm_icon_add(win);
1070         snprintf(buf, sizeof(buf), "%s/images/logo_small.png", elm_app_data_dir_get());
1071         elm_image_file_set(ic, buf, NULL);
1072         evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
1073         bt = elm_button_add(win);
1074         elm_object_text_set(bt, "Multi-callbacks check");
1075         elm_drop_target_add(bt, ELM_SEL_FORMAT_TARGETS, NULL, NULL, NULL, NULL, NULL, NULL, _drop_but_icon_change_cb, win);
1076         elm_drop_target_add(bt, ELM_SEL_FORMAT_TARGETS, _enter_but_cb, NULL, NULL, NULL, NULL, NULL, _drop_but_cb_remove_cb, NULL);
1077         elm_object_part_content_set(bt, "icon", ic);
1078         elm_box_pack_end(vert_box, bt);
1079         evas_object_show(bt);
1080         evas_object_show(ic);
1081
1082         ic = elm_icon_add(win);
1083         snprintf(buf, sizeof(buf), "%s/images/logo_small.png", elm_app_data_dir_get());
1084         elm_image_file_set(ic, buf, NULL);
1085         evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
1086         bt = elm_button_add(win);
1087         elm_object_text_set(bt, "Drop into me to change my icon");
1088         elm_drop_target_add(bt, ELM_SEL_FORMAT_TARGETS, NULL, NULL, NULL, NULL, NULL, NULL, _drop_but_icon_change_cb, win);
1089         elm_object_part_content_set(bt, "icon", ic);
1090         elm_box_pack_end(vert_box, bt);
1091         evas_object_show(bt);
1092         evas_object_show(ic);
1093
1094         ic = elm_icon_add(win);
1095         snprintf(buf, sizeof(buf), "%s/images/logo_small.png", elm_app_data_dir_get());
1096         elm_image_file_set(ic, buf, NULL);
1097         evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
1098         bt = elm_button_add(win);
1099         elm_object_text_set(bt, "No action on drop");
1100         elm_object_part_content_set(bt, "icon", ic);
1101         elm_box_pack_end(vert_box, bt);
1102         evas_object_show(bt);
1103         evas_object_show(ic);
1104      }
1105    evas_object_resize(win, 680, 800);
1106    evas_object_show(win);
1107 }
1108