4 #include "xcnphandler.h"
5 #include "clipdrawer.h"
7 #define DELETE_ICON_PATH "/usr/share/cbhm/icons/05_delete.png"
8 #define IM "/usr/share/cbhm/icons/"
9 static const char *g_images_path[] = {
10 IM"cbhm_default_img.png",
14 #define GRID_ITEM_SPACE_W 6
15 #define GRID_ITEM_SINGLE_W 185
16 #define GRID_ITEM_SINGLE_H 161
17 #define GRID_ITEM_W (GRID_ITEM_SINGLE_W+(GRID_ITEM_SPACE_W*2))
18 #define GRID_ITEM_H (GRID_ITEM_SINGLE_H)
19 #define GRID_IMAGE_LIMIT_W 91
20 #define GRID_IMAGE_LIMIT_H 113
22 #define ANIM_DURATION 30 // 1 seconds
23 #define ANIM_FLOPS (0.5/30)
25 // gic should live at gengrid callback functions
26 Elm_Gengrid_Item_Class gic;
27 static Ecore_Timer *anim_timer = NULL;
29 typedef struct tag_griditem
32 Elm_Gengrid_Item *item;
33 const char *ipathdata;
34 Eina_Strbuf *istrdata;
39 const char* clipdrawer_get_plain_string_from_escaped(char *escstr)
41 /* TODO : is it should be here? besides, remove dependency for entry */
42 /* NOTE : return string should be freed */
43 return elm_entry_markup_to_utf8(escstr);
46 static void _grid_del_response_cb(void *data, Evas_Object *obj, void *event_info)
48 Elm_Gengrid_Item *it = (Elm_Gengrid_Item *)data;
51 if((int)event_info == ELM_POPUP_RESPONSE_OK)
53 struct appdata *ad = g_get_main_appdata();
54 elm_gengrid_item_del(it);
59 Elm_Gengrid_Item *trail = elm_gengrid_first_item_get(ad->hig);
63 elm_gengrid_item_next_get(trail);
66 DTRACE("ERR: cbhm history cnt < 0, gengrid item cnt: %d\n", cnt);
71 static void _grid_click_delete(void *data, Evas_Object *obj, void *event_info)
73 struct appdata *ad = data;
77 _grid_item_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
79 struct appdata *ad = g_get_main_appdata();
81 if (ad->anim_status != STATUS_NONE)
84 Elm_Gengrid_Item *sgobj = NULL;
85 sgobj = elm_gengrid_selected_item_get(ad->hig);
86 griditem_t *ti = NULL;
87 ti = elm_gengrid_item_data_get(sgobj);
89 #define EDJE_DELBTN_PART_PREFIX "delbtn"
90 if (strncmp(source, EDJE_DELBTN_PART_PREFIX, strlen(EDJE_DELBTN_PART_PREFIX)))
94 DTRACE("ERR: cbhm can't get the selected image\n");
98 elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
100 if (ti->itype == GI_TEXT)
102 char *p = strdup(eina_strbuf_string_get(ti->istrdata));
104 elm_selection_set(1, obj, /*ELM_SEL_FORMAT_TEXT*/1, p);
106 else //if (ti->itype == GI_IMAGE)
108 if (!clipdrawer_paste_textonly_get(ad))
110 int len = strlen(ti->ipathdata);
111 char *p = malloc(len + 10);
112 snprintf(p,len+10, "file:///%s", ti->ipathdata);
114 elm_selection_set(/*secondary*/1,obj,/*ELM_SEL_FORMAT_IMAGE*/4,p);
118 DTRACE("ERR: cbhm image paste mode is false\n");
127 DTRACE("ERR: cbhm can't get the selected item\n");
131 elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
133 Evas_Object *popup = elm_popup_add(ad->win_main);
134 elm_popup_timeout_set(popup, 5);
135 evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
136 elm_popup_desc_set(popup, "Are you sure delete this?");
137 elm_popup_buttons_add(popup, 2,
138 "Yes", ELM_POPUP_RESPONSE_OK,
139 "No", ELM_POPUP_RESPONSE_CANCEL,
141 evas_object_smart_callback_add(popup, "response", _grid_del_response_cb, sgobj);
142 evas_object_show(popup);
145 Evas_Object* _grid_icon_get(const void *data, Evas_Object *obj, const char *part)
147 griditem_t *ti = (griditem_t *)data;
149 if (!strcmp(part, "elm.swallow.icon"))
151 if (ti->itype == GI_TEXT)
153 Evas_Object *layout = elm_layout_add (obj);
154 elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
155 edje_object_signal_callback_add(elm_layout_edje_get(layout),
156 "mouse,up,1", "*", _grid_item_ly_clicked, data);
157 Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj));
158 evas_object_resize(rect, GRID_ITEM_W, GRID_ITEM_H);
159 evas_object_color_set(rect, 242, 233, 183, 255);
160 evas_object_show(rect);
161 elm_layout_content_set(layout, "elm.swallow.icon", rect);
163 // FIXME: add string length check
164 Evas_Object *ientry = elm_scrolled_entry_add(obj);
165 evas_object_size_hint_weight_set(ientry, 0, 0);
166 Eina_Strbuf *strent = NULL;
167 char *strdata = eina_strbuf_string_get(ti->istrdata);
168 int i, skipflag, strcnt;
170 strent = eina_strbuf_new();
173 for (i = 0; i < eina_strbuf_length_get(ti->istrdata); i++)
191 eina_strbuf_append_n(strent, strdata, i);
192 eina_strbuf_replace_all(strent, " absize=240x180 ", " absize=52x39 ");
194 eina_strbuf_append(strent, "...");
195 eina_strbuf_prepend(strent, "<font_size=18>");
197 elm_scrolled_entry_entry_set(ientry, eina_strbuf_string_get(strent));
198 elm_scrolled_entry_editable_set(ientry, EINA_FALSE);
199 elm_scrolled_entry_context_menu_disabled_set(ientry, EINA_TRUE);
200 evas_object_show(ientry);
201 elm_layout_content_set(layout, "elm.swallow.inner", ientry);
203 eina_strbuf_free(strent);
207 else// if (ti->itype == GI_IMAGE)
209 Evas_Object *layout = elm_layout_add (obj);
210 elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
211 edje_object_signal_callback_add(elm_layout_edje_get(layout),
212 "mouse,up,1", "*", _grid_item_ly_clicked, data);
215 sicon = evas_object_image_add(evas_object_evas_get(obj));
216 evas_object_image_load_size_set(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
217 evas_object_image_file_set(sicon, ti->ipathdata, NULL);
218 evas_object_image_fill_set(sicon, 0, 0, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
219 evas_object_resize(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
220 elm_layout_content_set(layout, "elm.swallow.icon", sicon);
222 struct appdata *ad = g_get_main_appdata();
224 if (!clipdrawer_paste_textonly_get(ad))
226 edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,hide,delbtn", "elm");
227 Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj));
228 evas_object_color_set(rect, 0, 0, 0, 200);
229 evas_object_show(rect);
230 elm_layout_content_set(layout, "elm.swallow.cover", rect);
233 ti->ilayout = layout;
241 static void _grid_longpress(void *data, Evas_Object *obj, void *event_info)
243 struct appdata *ad = data;
246 static void _grid_click_paste(void *data, Evas_Object *obj, void *event_info)
248 struct appdata *ad = data;
249 if (ad->anim_status != STATUS_NONE)
252 Elm_Gengrid_Item *sgobj = NULL;
253 sgobj = elm_gengrid_selected_item_get(ad->hig);
254 griditem_t *ti = NULL;
255 ti = elm_gengrid_item_data_get(sgobj);
258 void _grid_del(const void *data, Evas_Object *obj)
260 griditem_t *ti = (griditem_t *)data;
261 if (ti->itype == GI_TEXT)
262 eina_strbuf_free(ti->istrdata);
264 eina_stringshare_del(ti->ipathdata);
268 char* clipdrawer_get_item_data(void *data, int pos)
270 struct appdata *ad = data;
271 griditem_t *ti = NULL;
272 griditem_t *newgi = NULL;
275 if (pos < 0 || pos > ad->hicount)
278 Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
281 ti = elm_gengrid_item_data_get(item);
286 if (ti->itype == GI_TEXT)
287 return (char*)eina_strbuf_string_get(ti->istrdata);
289 return ti->ipathdata;
292 item = elm_gengrid_item_next_get(item);
298 // FIXME: how to remove calling g_get_main_appdata()?
299 // it's mainly used at 'clipdrawer_image_item'
300 int clipdrawer_add_item(char *idata, int type)
302 struct appdata *ad = g_get_main_appdata();
303 griditem_t *newgi = NULL;
305 newgi = malloc(sizeof(griditem_t));
308 fprintf(stderr, "## add - %d : %s\n", newgi->itype, idata);
311 newgi->istrdata = eina_strbuf_new();
312 eina_strbuf_append(newgi->istrdata, idata);
314 else //if (type == GI_IMAGE)
316 Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
317 griditem_t *ti = NULL;
319 if (!check_regular_file(idata))
321 DTRACE("Error : it isn't normal file = %s\n", idata);
327 ti = elm_gengrid_item_data_get(item);
328 if ((ti->itype == type) && !strcmp(ti->ipathdata, idata))
330 DTRACE("Error : duplicated file path = %s\n", idata);
333 item = elm_gengrid_item_next_get(item);
335 newgi->ipathdata = eina_stringshare_add(idata);
338 if (ad->hicount >= HISTORY_QUEUE_MAX_ITEMS)
341 // FIXME: add routine that is removing its elements
342 elm_gengrid_item_del(elm_gengrid_last_item_get(ad->hig));
346 newgi->item = elm_gengrid_item_prepend(ad->hig, &gic, newgi, NULL, NULL);
352 clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
354 struct appdata *ad = data;
356 if (ad->anim_status != STATUS_NONE)
359 #define EDJE_CLOSE_PART_PREFIX "background/close"
360 if (!strncmp(source, EDJE_CLOSE_PART_PREFIX, strlen(EDJE_CLOSE_PART_PREFIX)))
362 clipdrawer_lower_view(ad);
366 void set_rotation_to_clipdrawer(void *data, int angle)
368 struct appdata *ad = data;
372 if (angle == 180) // reverse
374 wh = (1.0*CLIPDRAWER_HEIGHT/SCREEN_HEIGHT)*ad->root_h;
377 wposx = CLIPDRAWER_POS_X;
379 else if (angle == 90) // right rotate
381 wh = (1.0*CLIPDRAWER_HEIGHT_LANDSCAPE/SCREEN_WIDTH)*ad->root_w;
382 wy = (1.0*CLIPDRAWER_POS_X/SCREEN_WIDTH)*ad->root_w;
384 wposx = CLIPDRAWER_WIDTH-CLIPDRAWER_HEIGHT_LANDSCAPE;
386 else if (angle == -90) // left rotate
388 wh = (1.0*CLIPDRAWER_HEIGHT_LANDSCAPE/SCREEN_WIDTH)*ad->root_w;
389 wy = (1.0*CLIPDRAWER_POS_X/SCREEN_WIDTH)*ad->root_w;
391 wposx = CLIPDRAWER_POS_X;
395 wh = (1.0*CLIPDRAWER_HEIGHT/SCREEN_HEIGHT)*ad->root_h;
396 wy = (1.0*CLIPDRAWER_POS_Y/SCREEN_HEIGHT)*ad->root_h;
398 wposx = CLIPDRAWER_POS_X;
401 evas_object_resize(ad->win_main, wwidth, (int)wh);
402 evas_object_move(ad->win_main, wposx, (int)wy);
405 int clipdrawer_init(void *data)
407 struct appdata *ad = data;
410 ad->windowshow = EINA_FALSE;
412 ad->pastetextonly = EINA_TRUE;
413 ad->anim_status = STATUS_NONE;
417 elm_theme_extension_add(NULL, APP_EDJ_FILE);
419 set_rotation_to_clipdrawer(ad, get_rotation_degree());
421 edje_object_signal_callback_add(elm_layout_edje_get(ad->ly_main),
422 "mouse,up,1", "*", clipdrawer_ly_clicked, ad);
425 ad->hig = elm_gengrid_add(ad->win_main);
426 elm_layout_content_set(ad->ly_main, "historyitems", ad->hig);
427 elm_gengrid_item_size_set(ad->hig, GRID_ITEM_W+2, GRID_ITEM_H);
428 elm_gengrid_align_set(ad->hig, 0.5, 0.5);
429 elm_gengrid_horizontal_set(ad->hig, EINA_TRUE);
430 elm_gengrid_bounce_set(ad->hig, EINA_TRUE, EINA_FALSE);
431 elm_gengrid_multi_select_set(ad->hig, EINA_FALSE);
432 evas_object_smart_callback_add(ad->hig, "selected", _grid_click_paste, ad);
433 // evas_object_smart_callback_add(ad->hig, "longpressed", _grid_longpress, ad);
434 evas_object_size_hint_weight_set(ad->hig, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
436 elm_gengrid_clear(ad->hig);
438 gic.item_style = "default_grid";
439 gic.func.label_get = NULL;
440 gic.func.icon_get = _grid_icon_get;
441 gic.func.state_get = NULL;
442 gic.func.del = _grid_del;
447 for (i = 0; i < N_IMAGES; i++)
449 clipdrawer_add_item(g_images_path[0], GI_IMAGE);
452 clipdrawer_add_item("clipboard history", GI_TEXT);
454 evas_object_show (ad->hig);
456 // for debugging, calc history pos
458 Evas_Coord x, y, w, h;
459 Evas_Coord vx, vy, vw, vh;
461 edje_object_part_geometry_get(elm_layout_edje_get(ad->ly_main),"imagehistory/list",&x,&y,&w,&h);
462 evas_object_geometry_get (ad->hig, &vx,&vy,&vw,&vh);
463 fprintf(stderr, "## x = %d, y = %d, w = %d, h = %d\n", x, y, w, h);
464 fprintf(stderr, "## vx = %d, vy = %d, vw = %d, vh = %d\n", vx, vy, vw, vh);
467 // if (get_item_counts() != 0)
468 // clipdrawer_update_contents(ad);
473 int clipdrawer_create_view(void *data)
475 struct appdata *ad = data;
480 // at starting, showing app view
481 //clipdrawer_activate_view(ad);
486 Eina_Bool _get_anim_pos(void *data, int *sp, int *ep)
491 struct appdata *ad = data;
492 int angle = get_rotation_degree();
493 int anim_start, anim_end, delta;
495 if (angle == 180) // reverse
497 anim_start = (int)(((double)CLIPDRAWER_HEIGHT/SCREEN_HEIGHT)*ad->root_h);
498 anim_start = ad->root_h - anim_start;
499 anim_start = -anim_start;
502 else if (angle == 90) // right rotate
504 anim_start = ad->root_w;
505 anim_end = (int)(((double)CLIPDRAWER_HEIGHT_LANDSCAPE/SCREEN_WIDTH)*ad->root_w);
506 anim_end = anim_start-anim_end;
508 else if (angle == -90) // left rotate
510 anim_start = (int)(((double)CLIPDRAWER_HEIGHT_LANDSCAPE/SCREEN_WIDTH)*ad->root_w);
511 anim_start = ad->root_w-anim_start;
512 anim_start = -anim_start;
517 anim_start = ad->root_h;
518 anim_end = (int)(((double)CLIPDRAWER_HEIGHT/SCREEN_HEIGHT)*ad->root_h);
519 anim_end = anim_start-anim_end;
527 Eina_Bool _do_anim_delta_pos(void *data, int sp, int ep, int ac, int *dp)
532 struct appdata *ad = data;
533 int angle = get_rotation_degree();
536 posprop = 1.0*ac/ANIM_DURATION;
538 if (angle == 180) // reverse
540 delta = (int)((ep-sp)*posprop);
541 evas_object_move(ad->win_main, 0, sp+delta);
543 else if (angle == 90) // right rotate
545 delta = (int)((ep-sp)*posprop);
546 evas_object_move(ad->win_main, sp+delta, 0);
548 else if (angle == -90) // left rotate
550 delta = (int)((ep-sp)*posprop);
551 evas_object_move(ad->win_main, sp+delta, 0);
555 delta = (int)((sp-ep)*posprop);
556 evas_object_move(ad->win_main, 0, sp-delta);
564 static void stop_animation(void *data)
566 struct appdata *ad = data;
568 ad->anim_status = STATUS_NONE;
571 ecore_timer_del(anim_timer);
576 Eina_Bool anim_pos_calc_cb(void *data)
578 struct appdata *ad = data;
580 int anim_start, anim_end, delta;
582 _get_anim_pos(ad, &anim_start, &anim_end);
584 if (ad->anim_status == SHOW_ANIM)
586 if (ad->anim_count > ANIM_DURATION)
588 ad->anim_count = ANIM_DURATION;
589 stop_animation(data);
592 _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta);
595 else if (ad->anim_status == HIDE_ANIM)
597 if (ad->anim_count < 0)
600 evas_object_hide(ad->win_main);
601 elm_win_lower(ad->win_main);
602 unset_transient_for(ad);
603 stop_animation(data);
606 _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta);
611 stop_animation(data);
618 Eina_Bool clipdrawer_anim_effect(void *data, anim_status_t atype)
620 struct appdata *ad = data;
622 if (atype == ad->anim_status)
624 DTRACE("Warning: Animation effect is already in progress. \n");
628 ad->anim_status = atype;
631 ecore_timer_del(anim_timer);
633 anim_timer = ecore_timer_add(ANIM_FLOPS, anim_pos_calc_cb, ad);
638 void clipdrawer_activate_view(void *data)
640 struct appdata *ad = data;
644 set_transient_for(ad);
645 evas_object_show(ad->win_main);
646 elm_win_activate(ad->win_main);
647 if (clipdrawer_anim_effect(ad, SHOW_ANIM))
648 ad->windowshow = EINA_TRUE;
652 void clipdrawer_lower_view(void *data)
654 struct appdata *ad = data;
656 if (ad->win_main && ad->windowshow)
658 if (clipdrawer_anim_effect(ad, HIDE_ANIM))
659 ad->windowshow = EINA_FALSE;
663 void _change_gengrid_paste_textonly_mode(void *data)
665 struct appdata *ad = data;
667 Elm_Gengrid_Item *item;
668 griditem_t *ti = NULL;
670 if (clipdrawer_paste_textonly_get(ad))
671 { // textonly paste mode
672 Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
676 ti = elm_gengrid_item_data_get(item);
677 if ((ti->itype == GI_IMAGE) && (ti->ilayout))
679 edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,hide,delbtn", "elm");
680 Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(ad->hig));
681 evas_object_color_set(rect, 0, 0, 0, 200);
682 evas_object_show(rect);
683 elm_layout_content_set(ti->ilayout, "elm.swallow.cover", rect);
685 item = elm_gengrid_item_next_get(item);
689 { // text+image paste mode
690 Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
694 ti = elm_gengrid_item_data_get(item);
695 if ((ti->itype == GI_IMAGE) && (ti->ilayout))
697 edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,show,delbtn", "elm");
698 Evas_Object *rect = elm_layout_content_unset(ti->ilayout, "elm.swallow.cover");
699 evas_object_hide(rect);
700 evas_object_del(rect);
702 item = elm_gengrid_item_next_get(item);
707 void clipdrawer_paste_textonly_set(void *data, Eina_Bool textonly)
709 struct appdata *ad = data;
710 textonly = !!textonly;
711 if (ad->pastetextonly != textonly)
712 ad->pastetextonly = textonly;
713 DTRACE("paste textonly mode = %d\n", textonly);
715 _change_gengrid_paste_textonly_mode(ad);
718 Eina_Bool clipdrawer_paste_textonly_get(void *data)
720 struct appdata *ad = data;
721 return ad->pastetextonly;