screen capture by clientmessage, replace imagelist icon to evas obj
[framework/uifw/cbhm.git] / src / clipdrawer.c
1 #include "common.h"
2 #include "cbhm_main.h"
3 #include "storage.h"
4 #include "xcnphandler.h"
5 #include "clipdrawer.h"
6
7 #define DELETE_ICON_PATH "/usr/share/icon/cbhm/05_delete.png"
8 #define IM      "/usr/share/icon/cbhm/"
9 static const char *g_images_path[] = {
10         IM"cbhm_default_img.png",
11 /*
12         IM"2_photo.jpg",
13         IM"3_photo.jpg",
14         IM"4_photo.jpg",
15         IM"5_photo.jpg",
16         IM"6_photo.jpg",
17 */
18 };
19 #define N_IMAGES (1)
20
21 #define GRID_ITEM_SIZE 100
22
23 // 0 - select mode, 1 - delete mode
24 static int g_clipdrawer_mode = 0;
25 // gic should live at gengrid callback functions
26 Elm_Gengrid_Item_Class gic;
27
28 typedef struct tag_gridimgitem
29 {
30         Elm_Gengrid_Item *item;
31         const char *path;
32         Evas_Object *delbtn;
33 } gridimgitem_t;
34
35 static int toggle_clipdrawer_mode()
36 {
37         g_clipdrawer_mode = !g_clipdrawer_mode;
38         return g_clipdrawer_mode;
39 }
40
41 static int get_clipdrawer_mode()
42 {
43         return g_clipdrawer_mode;
44 }
45
46 static void _list_longpress(void *data, Evas_Object *obj, void *event_info)
47 {
48         struct appdata *ad = data;
49
50         clipdrawer_change_mode(ad);
51 }
52
53 static void _list_click_paste(void *data, Evas_Object *obj, void *event_info)
54 {
55         struct appdata *ad = data;
56     Elm_List_Item *it = (Elm_List_Item *) elm_list_selected_item_get(obj);
57         if (it == NULL)
58                 return;
59
60     elm_list_item_selected_set(it, 0);
61
62         char *p = NULL;
63         int cplen;
64
65         char *cpdata = NULL;
66         cpdata = elm_list_item_label_get(it);
67         if (cpdata == NULL)
68                 return;
69         cplen = strlen(cpdata);
70         p = malloc(cplen + 1);
71         snprintf(p, cplen+1, "%s", cpdata);
72         elm_selection_set(1, obj, /*ELM_SEL_FORMAT_TEXT*/1, p);
73 //      elm_selection_set(1, obj, /*ELM_SEL_FORMAT_MARKUP*/2, p);
74
75 //      clipdrawer_lower_view(ad);
76 }
77
78 static void _list_del_response_cb(void *data, Evas_Object *obj, void *event_info)
79 {
80         Elm_List_Item *it = (Elm_List_Item *)data;
81         evas_object_del(obj);
82
83         if((int)event_info == ELM_POPUP_RESPONSE_OK)
84                 elm_list_item_del(it);
85 }
86
87 static void _list_click_delete(void *data, Evas_Object *obj, void *event_info)
88 {
89         struct appdata *ad = data;
90     Elm_List_Item *it = (Elm_List_Item *) elm_list_selected_item_get(obj);
91         if (it == NULL)
92                 return;
93
94     elm_list_item_selected_set(it, 0);
95
96         Evas_Object *popup = elm_popup_add(ad->win_main);
97         elm_popup_timeout_set(popup, 3);
98         evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
99         elm_popup_desc_set(popup, "Are you sure delete this?");
100         elm_popup_buttons_add(popup, 2,
101                                                   "Yes", ELM_POPUP_RESPONSE_OK,
102                                                   "No", ELM_POPUP_RESPONSE_CANCEL,
103                                                   NULL);
104         evas_object_smart_callback_add(popup, "response", _list_del_response_cb, it);
105         evas_object_show(popup);
106
107 //      char *slabel = NULL;
108 //      slabel = elm_list_item_label_get(it);
109 }
110
111 int clipdrawer_update_contents(void *data)
112 {
113         struct appdata *ad = data;
114         int i, pos;
115
116         // if delete mode, then back to normal mode
117 //      if (get_clipdrawer_mode())
118 //              clipdrawer_change_mode(ad);
119
120         elm_list_clear(ad->txtlist);
121         for (i = 0; i < HISTORY_QUEUE_MAX_TXT_ITEMS; i++)
122         {
123                 pos = get_current_history_position()+i;
124                 if (pos > HISTORY_QUEUE_MAX_TXT_ITEMS-1)
125                         pos = pos-HISTORY_QUEUE_MAX_TXT_ITEMS;
126                 if (get_item_contents_by_pos(pos) != NULL && strlen(get_item_contents_by_pos(pos)) > 0)
127                 {
128                         elm_list_item_append(ad->txtlist, get_item_contents_by_pos(pos), NULL, NULL, NULL, ad);
129                 }
130         }
131         elm_list_go(ad->txtlist);
132
133         /* FIXME : sometimes when list update, screen isn't updated */
134
135         return 0;
136 }
137
138 const char* clipdrawer_get_plain_string_from_escaped(char *escstr)
139 {
140         /* TODO : is it should be here? besides, remove dependency for entry */
141         /* NOTE : return string should be freed */
142         return elm_entry_markup_to_utf8(escstr);
143 }
144
145 Evas_Object* _grid_icon_get(const void *data, Evas_Object *obj, const char *part)
146 {
147         int delete_mode = get_clipdrawer_mode();
148         gridimgitem_t *ti = (gridimgitem_t *)data;
149         if (!strcmp(part, "elm.swallow.icon"))
150         {
151 /*
152                 Evas_Object *icon = elm_icon_add(obj);
153                 elm_icon_file_set(icon, ti->path, NULL);
154                 evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
155                 evas_object_show(icon);
156 */
157                 Ecore_Evas *my_ee;
158                 Evas *my_e;
159                 Evas_Object *fgimg;
160                 Evas_Object *bgrect;
161                 Evas_Object *delbtn;
162                 Evas_Object *icon;
163                 my_ee = ecore_evas_buffer_new(GRID_ITEM_SIZE, GRID_ITEM_SIZE);
164                 my_e = ecore_evas_get(my_ee);
165
166                 bgrect = evas_object_rectangle_add(my_e);
167                 evas_object_color_set(bgrect, 119, 116, 100, 255);
168                 evas_object_resize(bgrect, GRID_ITEM_SIZE, GRID_ITEM_SIZE);
169                 evas_object_move(bgrect, 0, 0);
170                 evas_object_show(bgrect);
171
172                 #define BORDER_SIZE 10
173                 fgimg = evas_object_image_add(my_e);
174                 evas_object_image_load_size_set(fgimg, GRID_ITEM_SIZE-BORDER_SIZE*2, GRID_ITEM_SIZE-BORDER_SIZE*2);
175                 evas_object_image_file_set(fgimg, ti->path, NULL);
176                 evas_object_image_fill_set(fgimg, 0, 0, GRID_ITEM_SIZE-BORDER_SIZE*2, GRID_ITEM_SIZE-BORDER_SIZE*2);
177                 evas_object_image_filled_set(fgimg, 1);
178                 evas_object_resize(fgimg, GRID_ITEM_SIZE-BORDER_SIZE*2, GRID_ITEM_SIZE-BORDER_SIZE*2);
179                 evas_object_move(fgimg, BORDER_SIZE, BORDER_SIZE);
180                 evas_object_show(fgimg);
181
182 /*
183                 if (delete_mode)
184                 {
185                         delbtn = evas_object_image_add(my_e);
186                         evas_object_image_load_size_set(delbtn, 33, 33);
187                         evas_object_image_file_set(delbtn, DELETE_ICON_PATH, NULL);
188                         evas_object_image_fill_set(delbtn, 0, 0, 33, 33);
189                         evas_object_image_filled_set(delbtn, 1);
190                         evas_object_resize(delbtn, 33, 33);
191                         evas_object_move(delbtn, 55, 38);
192                         evas_object_show(delbtn);
193                 }
194 */
195         
196                 icon = evas_object_image_add(evas_object_evas_get(obj));
197
198                 evas_object_image_data_set(icon, NULL);
199                 evas_object_image_size_set(icon, GRID_ITEM_SIZE, GRID_ITEM_SIZE);
200                 evas_object_image_fill_set(icon, 0, 0, GRID_ITEM_SIZE, GRID_ITEM_SIZE);
201                 evas_object_image_filled_set(icon, EINA_TRUE);
202                 evas_object_image_data_copy_set(icon, (int *)ecore_evas_buffer_pixels_get(my_ee));
203                 evas_object_image_data_update_add(icon, 0, 0, GRID_ITEM_SIZE, GRID_ITEM_SIZE);
204
205                 evas_object_del(bgrect);
206                 evas_object_del(fgimg);
207                 if (delete_mode)
208                         evas_object_del(delbtn);
209                 ecore_evas_free(my_ee);
210
211                 return icon;
212         }
213         else if (!strcmp(part, "elm.swallow.end") && delete_mode)
214         {
215                 ti->delbtn = elm_check_add(obj);
216                 elm_object_style_set(ti->delbtn, "extended/imagegrid");
217                 elm_check_state_set(ti->delbtn, 1);
218                 evas_object_show(ti->delbtn);
219                 return ti->delbtn;
220         }
221            
222         return NULL;
223 }
224
225 static void _grid_longpress(void *data, Evas_Object *obj, void *event_info)
226 {
227         struct appdata *ad = data;
228         clipdrawer_change_mode(ad);
229 }
230
231
232 static void _grid_click_paste(void *data, Evas_Object *obj, void *event_info)
233 {
234         struct appdata *ad = data;
235         char *file, *p;
236         int len;
237         Elm_Gengrid_Item *sgobj = NULL;
238         sgobj = elm_gengrid_selected_item_get(ad->imggrid);
239         gridimgitem_t *ti = NULL;
240         ti = elm_gengrid_item_data_get(sgobj);
241
242         if (!sgobj || !ti)
243         {
244                 DTRACE("ERR: cbhm can't get the selected image\n");
245                 return;
246         }
247         len = strlen(ti->path);
248         p = malloc(len + 10);
249         snprintf(p,len+10, "file:///%s", ti->path);
250
251         elm_selection_set(/*secondary*/1,obj,/*ELM_SEL_FORMAT_IMAGE*/4,p);
252
253 //      clipdrawer_lower_view(ad);
254
255         elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
256 }
257
258 static void _grid_del_response_cb(void *data, Evas_Object *obj, void *event_info)
259 {
260         Elm_Gengrid_Item *it = (Elm_Gengrid_Item *)data;
261         evas_object_del(obj);
262
263         if((int)event_info == ELM_POPUP_RESPONSE_OK)
264                 elm_gengrid_item_del(it);
265 }
266
267 static void _grid_click_delete(void *data, Evas_Object *obj, void *event_info)
268 {
269         struct appdata *ad = data;
270         Elm_Gengrid_Item *sgobj = NULL;
271         sgobj = elm_gengrid_selected_item_get(ad->imggrid);
272         gridimgitem_t *ti = NULL;
273         ti = elm_gengrid_item_data_get(sgobj);
274
275         if (!sgobj || !ti)
276         {
277                 DTRACE("ERR: cbhm can't get the clicked del image\n");
278                 return;
279         }
280
281         Evas_Object *popup = elm_popup_add(ad->win_main);
282         elm_popup_timeout_set(popup, 3);
283         evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
284         elm_popup_desc_set(popup, "Are you sure delete this?");
285         elm_popup_buttons_add(popup, 2,
286                                                   "Yes", ELM_POPUP_RESPONSE_OK,
287                                                   "No", ELM_POPUP_RESPONSE_CANCEL,
288                                                   NULL);
289         evas_object_smart_callback_add(popup, "response", _grid_del_response_cb, sgobj);
290         evas_object_show(popup);
291 }
292
293 void _grid_del(const void *data, Evas_Object *obj)
294 {
295         gridimgitem_t *ti = (gridimgitem_t *)data;
296         eina_stringshare_del(ti->path);
297         free(ti);
298 }
299
300 int clipdrawer_refresh_imghistory_item(void *data, int delete_mode)
301 {
302         struct appdata *ad = data;
303         Eina_List *oldlist = NULL;
304         const Eina_List *l;
305         Elm_Gengrid_Item *lgrid;
306         gridimgitem_t *lgitem;
307         Evas_Object *ngg;
308         Evas_Object *oldgg;
309         
310         oldlist = elm_gengrid_items_get(ad->imggrid);
311         elm_layout_content_unset(ad->ly_main, "imagehistory/list");
312         ngg = elm_gengrid_add(ad->win_main);
313         elm_layout_content_set(ad->ly_main, "imagehistory/list", ngg);
314         oldgg = ad->imggrid;
315         ad->imggrid = ngg;
316         elm_gengrid_item_size_set(ad->imggrid, GRID_ITEM_SIZE, GRID_ITEM_SIZE+3);
317         elm_gengrid_align_set(ad->imggrid, 0.0, 0.0);
318         elm_gengrid_horizontal_set(ad->imggrid, EINA_TRUE);
319         elm_gengrid_bounce_set(ad->imggrid, EINA_TRUE, EINA_FALSE);
320         elm_gengrid_multi_select_set(ad->imggrid, EINA_FALSE);
321         if (delete_mode)
322                 evas_object_smart_callback_add(ad->imggrid, "selected", _grid_click_delete, ad);
323         else
324                 evas_object_smart_callback_add(ad->imggrid, "selected", _grid_click_paste, ad);
325         evas_object_smart_callback_add(ad->imggrid, "longpressed", _grid_longpress, ad);
326         evas_object_size_hint_weight_set(ad->imggrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
327
328         gic.item_style = "default_grid";
329         gic.func.label_get = NULL;
330         gic.func.icon_get = _grid_icon_get;
331         gic.func.state_get = NULL;
332         gic.func.del = _grid_del;
333
334         EINA_LIST_REVERSE_FOREACH(oldlist, l, lgrid)
335         {
336                 lgitem = elm_gengrid_item_data_get(lgrid);
337                 clipdrawer_add_image_item(lgitem->path);
338         }
339
340         evas_object_show (ad->imggrid);
341
342         elm_gengrid_clear(oldgg);
343         evas_object_hide(oldgg);
344         evas_object_del(oldgg);
345
346         return 0;
347 }
348
349 int clipdrawer_refresh_txthistory_item(void *data, int delete_mode)
350 {
351         struct appdata *ad = data;
352         Eina_List *oldlist = NULL;
353         const Eina_List *l;
354         Elm_List_Item *litem;
355         const char *ltext;
356         Evas_Object *ntl = NULL;
357 //      Evas_Object *ci = NULL;
358
359         oldlist = elm_list_items_get(ad->txtlist);
360         elm_layout_content_unset(ad->ly_main, "texthistory/list");
361         ntl = elm_list_add(ad->win_main);
362         elm_layout_content_set(ad->ly_main, "texthistory/list", ntl);
363         elm_object_style_set(ntl, "extended/historylist");
364
365         EINA_LIST_FOREACH(oldlist, l, litem)
366         {
367                 ltext = elm_list_item_label_get(litem);
368                 if (delete_mode)
369                 {
370                         Evas_Object *ci = elm_icon_add(ad->win_main);
371                         elm_icon_file_set(ci, DELETE_ICON_PATH, NULL);
372                         evas_object_size_hint_min_set(ci, 33 * elm_scale_get(), 33 * elm_scale_get());
373 //                      evas_object_size_hint_aspect_set(ci, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
374                         evas_object_show(ci);
375                         elm_list_item_append(ntl, ltext, NULL, ci, NULL, ad);
376                 }
377                 else
378                 {
379                         elm_list_item_append(ntl, ltext, NULL, NULL, NULL, ad);
380                 }
381         }
382
383         elm_list_clear(ad->txtlist);
384         evas_object_hide(ad->txtlist);
385         evas_object_del(ad->txtlist);
386
387         ad->txtlist = ntl;
388         evas_object_size_hint_weight_set(ad->txtlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
389         if (delete_mode)
390                 evas_object_smart_callback_add(ad->txtlist, "selected", _list_click_delete, ad);
391         else
392                 evas_object_smart_callback_add(ad->txtlist, "selected", _list_click_paste, ad);
393         evas_object_smart_callback_add(ad->txtlist, "longpressed", _list_longpress, ad);
394
395         elm_list_go(ad->txtlist);
396
397         return 0;
398 }
399
400 int clipdrawer_change_mode(void *data)
401 {
402         struct appdata *ad = data;
403
404         toggle_clipdrawer_mode();
405
406         DTRACE("clipdrawer delete mode = %d\n", get_clipdrawer_mode());
407
408         clipdrawer_refresh_imghistory_item(ad, get_clipdrawer_mode());
409         clipdrawer_refresh_txthistory_item(ad, get_clipdrawer_mode());
410
411         return 0;
412 }
413
414 // FIXME: how to remove calling g_get_main_appdata()? 
415 //        it's mainly used at 'clipdrawer_add_image_item'
416 int clipdrawer_add_image_item(char *imagepath)
417 {
418         struct appdata *ad = g_get_main_appdata();
419         gridimgitem_t *newgenimg = NULL;
420         char* filepath = NULL;
421         Eina_List *igl = NULL;
422         unsigned int igl_counter = 0;
423
424         // if delete mode, then back to normal mode
425 //      if (get_clipdrawer_mode())
426 //              clipdrawer_change_mode(ad);
427
428         if (!check_regular_file(imagepath))
429         {
430                 DTRACE("Error : it isn't normal file = %s\n", imagepath);
431                 return -1;
432         }
433
434         igl = elm_gengrid_items_get(ad->imggrid);
435         igl_counter = eina_list_count(igl);
436
437         Eina_List *l;
438         Elm_Gengrid_Item *item;
439         gridimgitem_t *ti = NULL;
440
441         EINA_LIST_FOREACH(igl, l, item)
442         {
443                 ti = elm_gengrid_item_data_get(item);
444                 if (!strcmp(ti->path, imagepath))
445                 {
446                         DTRACE("Error : duplicated file path = %s\n", imagepath);
447                         return -1;
448                 }
449         }
450
451         if (igl_counter >= HISTORY_QUEUE_MAX_IMG_ITEMS)
452         {
453                 elm_gengrid_item_del(eina_list_data_get(eina_list_last(igl)));
454         }
455
456         newgenimg = malloc(sizeof(gridimgitem_t));
457         newgenimg->path = eina_stringshare_add(imagepath);
458         newgenimg->item = elm_gengrid_item_prepend(ad->imggrid, &gic, newgenimg, NULL, NULL);
459
460         return TRUE;
461 }
462
463 static void
464 clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
465 {
466         struct appdata *ad = data;
467
468         #define EDJE_CLOSE_PART_PREFIX "closebutton/"
469         if (!strncmp(source, EDJE_CLOSE_PART_PREFIX, strlen(EDJE_CLOSE_PART_PREFIX)))
470         {
471                 clipdrawer_lower_view(ad);
472         }
473 }
474
475 int clipdrawer_init(void *data)
476 {
477         struct appdata *ad = data;
478         double cdy, cdw;
479
480         // for elm_check, elm_list
481         elm_theme_extension_add(NULL, APP_EDJ_FILE);
482
483         cdy = (1.0*CLIPDRAWER_HEIGHT/SCREEN_HEIGHT)*ad->root_h;
484         cdw = (1.0*CLIPDRAWER_POS_Y/SCREEN_HEIGHT)*ad->root_h;
485
486         evas_object_resize(ad->win_main, ad->root_w, (int)cdy);
487         evas_object_move(ad->win_main, CLIPDRAWER_POS_X, (int)cdw);
488         evas_object_resize(ad->ly_main, ad->root_w, (int)cdy);
489         evas_object_move(ad->ly_main, CLIPDRAWER_POS_X, (int)cdw);
490
491         edje_object_signal_callback_add(elm_layout_edje_get(ad->ly_main), "mouse,up,1", "*", clipdrawer_ly_clicked, ad);
492
493         ad->imggrid = NULL;
494         ad->imggrid = elm_gengrid_add(ad->win_main);
495         elm_layout_content_set(ad->ly_main, "imagehistory/list", ad->imggrid);
496         elm_gengrid_item_size_set(ad->imggrid, GRID_ITEM_SIZE, GRID_ITEM_SIZE+3);
497         elm_gengrid_align_set(ad->imggrid, 0.0, 0.0);
498         elm_gengrid_horizontal_set(ad->imggrid, EINA_TRUE);
499         elm_gengrid_bounce_set(ad->imggrid, EINA_TRUE, EINA_FALSE);
500         elm_gengrid_multi_select_set(ad->imggrid, EINA_FALSE);
501         evas_object_smart_callback_add(ad->imggrid, "selected", _grid_click_paste, ad);
502         evas_object_smart_callback_add(ad->imggrid, "longpressed", _grid_longpress, ad);
503         evas_object_size_hint_weight_set(ad->imggrid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
504
505         elm_gengrid_clear(ad->imggrid);
506
507         gic.item_style = "default_grid";
508         gic.func.label_get = NULL;
509         gic.func.icon_get = _grid_icon_get;
510         gic.func.state_get = NULL;
511         gic.func.del = _grid_del;
512
513         int i;
514         gridimgitem_t *newgenimg;
515
516         for (i = 0; i < N_IMAGES; i++)
517         {
518                 clipdrawer_add_image_item(g_images_path[i]);
519         }
520
521         evas_object_show (ad->imggrid);
522
523 // for debugging, calc image history pos
524 /*
525    Evas_Coord x, y, w, h;
526    Evas_Coord vx, vy, vw, vh;
527
528    edje_object_part_geometry_get(elm_layout_edje_get(ad->ly_main),"imagehistory/list",&x,&y,&w,&h);
529    evas_object_geometry_get (ad->imggrid, &vx,&vy,&vw,&vh);
530    fprintf(stderr, "## x = %d, y = %d, w = %d, h = %d\n", x, y, w, h);
531    fprintf(stderr, "## vx = %d, vy = %d, vw = %d, vh = %d\n", vx, vy, vw, vh);
532 */
533
534         ad->txtlist = elm_list_add(ad->win_main);
535         elm_layout_content_set(ad->ly_main, "texthistory/list", ad->txtlist);
536         elm_object_style_set(ad->txtlist, "extended/historylist");
537         evas_object_size_hint_weight_set(ad->txtlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
538         evas_object_smart_callback_add(ad->txtlist, "selected", _list_click_paste, ad);
539         evas_object_smart_callback_add(ad->txtlist, "longpressed", _list_longpress, ad);
540         elm_list_item_append(ad->txtlist, "default", NULL, NULL, NULL, ad);
541
542         elm_list_go(ad->txtlist);
543
544         if (get_item_counts() != 0)
545                 clipdrawer_update_contents(ad);
546
547         return 0;
548 }
549
550 int clipdrawer_create_view(void *data)
551 {
552         struct appdata *ad = data;
553
554         clipdrawer_init(ad);
555
556         // for debug
557         // at starting, showing app view
558         // clipdrawer_activate_view(ad);
559
560         return 0;
561 }
562
563 void clipdrawer_activate_view(void *data)
564 {
565         struct appdata *ad = data;
566         
567         if (ad->win_main)
568         {
569                 evas_object_show(ad->win_main);
570                 elm_win_activate(ad->win_main);
571         }
572 }
573
574 void clipdrawer_lower_view(void *data)
575 {
576         struct appdata *ad = data;
577         
578         if (ad->win_main)
579         {
580                 evas_object_hide(ad->win_main);
581                 elm_win_lower(ad->win_main);
582
583                 // if delete mode, then back to normal mode
584                 if (get_clipdrawer_mode())
585                         clipdrawer_change_mode(ad);
586         }
587 }