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 187
16 #define GRID_ITEM_SINGLE_H 151
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;
28 typedef struct tag_griditem
31 Elm_Gengrid_Item *item;
32 const char *ipathdata;
33 Eina_Strbuf *istrdata;
39 int clipdrawer_update_contents(void *data)
41 struct appdata *ad = data;
45 for (i = 0; i < HISTORY_QUEUE_MAX_ITEMS; i++)
47 pos = get_current_history_position() - i;
49 pos = pos+HISTORY_QUEUE_MAX_ITEMS;
51 if (get_item_contents_by_pos(pos) != NULL && strlen(get_item_contents_by_pos(pos)) > 0)
53 unesc = clipdrawer_get_plain_string_from_escaped(get_item_contents_by_pos(pos));
54 unesc = unesc ? unesc : "";
55 elm_list_item_append(ad->txtlist, unesc, NULL, NULL, NULL, ad);
60 /* FIXME : sometimes when list update, screen isn't updated */
65 const char* clipdrawer_get_plain_string_from_escaped(char *escstr)
67 /* TODO : is it should be here? besides, remove dependency for entry */
68 /* NOTE : return string should be freed */
69 return elm_entry_markup_to_utf8(escstr);
72 static void _grid_del_response_cb(void *data, Evas_Object *obj, void *event_info)
74 Elm_Gengrid_Item *it = (Elm_Gengrid_Item *)data;
77 if((int)event_info == ELM_POPUP_RESPONSE_OK)
78 elm_gengrid_item_del(it);
81 static void _grid_click_delete(void *data, Evas_Object *obj, void *event_info)
83 struct appdata *ad = data;
87 _grid_item_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
89 struct appdata *ad = g_get_main_appdata();
91 if (ad->anim_status != STATUS_NONE)
94 Elm_Gengrid_Item *sgobj = NULL;
95 sgobj = elm_gengrid_selected_item_get(ad->hig);
96 griditem_t *ti = NULL;
97 ti = elm_gengrid_item_data_get(sgobj);
99 #define EDJE_DELBTN_PART_PREFIX "delbtn"
100 if (strncmp(source, EDJE_DELBTN_PART_PREFIX, strlen(EDJE_DELBTN_PART_PREFIX)))
104 DTRACE("ERR: cbhm can't get the selected image\n");
108 elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
110 if (ti->itype == GI_TEXT)
112 char *p = strdup(eina_strbuf_string_get(ti->istrdata));
114 elm_selection_set(1, obj, /*ELM_SEL_FORMAT_TEXT*/1, p);
116 else //if (ti->itype == GI_IMAGE)
118 if (!clipdrawer_paste_textonly_get(ad))
120 int len = strlen(ti->ipathdata);
121 char *p = malloc(len + 10);
122 snprintf(p,len+10, "file:///%s", ti->ipathdata);
124 elm_selection_set(/*secondary*/1,obj,/*ELM_SEL_FORMAT_IMAGE*/4,p);
128 DTRACE("ERR: cbhm image paste mode is false\n");
137 DTRACE("ERR: cbhm can't get the selected item\n");
141 elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
143 Evas_Object *popup = elm_popup_add(ad->win_main);
144 elm_popup_timeout_set(popup, 5);
145 evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
146 elm_popup_desc_set(popup, "Are you sure delete this?");
147 elm_popup_buttons_add(popup, 2,
148 "Yes", ELM_POPUP_RESPONSE_OK,
149 "No", ELM_POPUP_RESPONSE_CANCEL,
151 evas_object_smart_callback_add(popup, "response", _grid_del_response_cb, sgobj);
152 evas_object_show(popup);
155 Evas_Object* _grid_icon_get(const void *data, Evas_Object *obj, const char *part)
157 griditem_t *ti = (griditem_t *)data;
159 if (!strcmp(part, "elm.swallow.icon"))
161 if (ti->itype == GI_TEXT)
163 Evas_Object *layout = elm_layout_add (obj);
164 elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
165 edje_object_signal_callback_add(elm_layout_edje_get(layout),
166 "mouse,up,1", "*", _grid_item_ly_clicked, data);
167 Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj));
168 evas_object_resize(rect, GRID_ITEM_W, GRID_ITEM_H);
169 evas_object_color_set(rect, 242, 233, 183, 255);
170 evas_object_show(rect);
171 elm_layout_content_set(layout, "elm.swallow.icon", rect);
173 // FIXME: add string length check
174 Evas_Object *ientry = elm_scrolled_entry_add(obj);
175 evas_object_size_hint_weight_set(ientry, 0, 0);
176 Eina_Strbuf *strent = NULL;
177 char *strdata = eina_strbuf_string_get(ti->istrdata);
178 int i, skipflag, strcnt;
180 strent = eina_strbuf_new();
183 for (i = 0; i < eina_strbuf_length_get(ti->istrdata); i++)
201 eina_strbuf_append_n(strent, strdata, i);
202 // eina_strbuf_append(strent, strdata);
203 eina_strbuf_replace_all(strent, " absize=240x180 ", " absize=52x39 ");
205 eina_strbuf_append(strent, "...");
207 elm_scrolled_entry_entry_set(ientry, eina_strbuf_string_get(strent));
208 elm_scrolled_entry_editable_set(ientry, EINA_FALSE);
209 elm_scrolled_entry_context_menu_disabled_set(ientry, EINA_TRUE);
210 evas_object_show(ientry);
211 elm_layout_content_set(layout, "elm.swallow.inner", ientry);
213 eina_strbuf_free(strent);
217 else// if (ti->itype == GI_IMAGE)
219 Evas_Object *layout = elm_layout_add (obj);
220 elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
221 edje_object_signal_callback_add(elm_layout_edje_get(layout),
222 "mouse,up,1", "*", _grid_item_ly_clicked, data);
225 sicon = evas_object_image_add(evas_object_evas_get(obj));
226 evas_object_image_load_size_set(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
227 evas_object_image_file_set(sicon, ti->ipathdata, NULL);
228 evas_object_image_fill_set(sicon, 0, 0, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
229 evas_object_resize(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
230 elm_layout_content_set(layout, "elm.swallow.icon", sicon);
232 struct appdata *ad = g_get_main_appdata();
234 if (!clipdrawer_paste_textonly_get(ad))
236 edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,hide,delbtn", "elm");
237 Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj));
238 evas_object_color_set(rect, 0, 0, 0, 200);
239 evas_object_show(rect);
240 elm_layout_content_set(layout, "elm.swallow.cover", rect);
243 ti->ilayout = layout;
247 Evas_Object *icon = elm_icon_add(obj);
248 elm_icon_file_set(icon, ti->ipathdata, NULL);
249 evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
250 evas_object_show(icon);
260 my_ee = ecore_evas_buffer_new(GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
261 my_e = ecore_evas_get(my_ee);
263 bgrect = evas_object_rectangle_add(my_e);
264 evas_object_color_set(bgrect, 255, 255, 255, 255);
265 evas_object_resize(bgrect, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
266 evas_object_move(bgrect, 0, 0);
267 evas_object_show(bgrect);
269 #define BORDER_SIZE 1
270 fgimg = evas_object_image_add(my_e);
271 evas_object_image_load_size_set(fgimg, GRID_ITEM_SINGLE_W-BORDER_SIZE*2, GRID_ITEM_SINGLE_H-BORDER_SIZE*2);
272 evas_object_image_file_set(fgimg, ti->ipathdata, NULL);
273 evas_object_image_fill_set(fgimg, 0, 0, GRID_ITEM_SINGLE_W-BORDER_SIZE*2, GRID_ITEM_SINGLE_H-BORDER_SIZE*2);
274 evas_object_image_filled_set(fgimg, 1);
276 evas_object_image_size_get(fgimg, &x, &y);
277 //fprintf(stderr, "## img x = %d, y = %d\n", x, y);
278 evas_object_resize(fgimg, GRID_ITEM_SINGLE_W-BORDER_SIZE*2, GRID_ITEM_SINGLE_H-BORDER_SIZE*2);
279 evas_object_move(fgimg, BORDER_SIZE, BORDER_SIZE);
280 evas_object_show(fgimg);
282 icon = evas_object_image_add(evas_object_evas_get(obj));
284 evas_object_image_data_set(icon, NULL);
285 evas_object_image_size_set(icon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
286 evas_object_image_fill_set(icon, 0, 0, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
287 evas_object_image_filled_set(icon, EINA_TRUE);
288 evas_object_image_data_copy_set(icon, (int *)ecore_evas_buffer_pixels_get(my_ee));
289 evas_object_image_data_update_add(icon, 0, 0, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
291 evas_object_del(bgrect);
292 evas_object_del(fgimg);
293 ecore_evas_free(my_ee);
302 else if (!strcmp(part, "elm.swallow.end"))
304 ti->delbtn = elm_check_add(obj);
305 elm_object_style_set(ti->delbtn, "extended/itemcheck");
306 //evas_object_propagate_events_set(ti->delbtn, 0);
307 elm_check_state_set(ti->delbtn, tcm);
308 evas_object_smart_callback_add(ti->delbtn, "changed", _grid_item_check_changed, data);
309 evas_object_show(ti->delbtn);
317 static void _grid_longpress(void *data, Evas_Object *obj, void *event_info)
319 struct appdata *ad = data;
320 clipdrawer_change_mode(ad);
323 static void _grid_click_paste(void *data, Evas_Object *obj, void *event_info)
325 struct appdata *ad = data;
326 if (ad->anim_status != STATUS_NONE)
329 Elm_Gengrid_Item *sgobj = NULL;
330 sgobj = elm_gengrid_selected_item_get(ad->hig);
331 griditem_t *ti = NULL;
332 ti = elm_gengrid_item_data_get(sgobj);
334 fprintf(stderr, "## grid_click_paste = 0x%x\n", event_info);
337 void _grid_del(const void *data, Evas_Object *obj)
339 griditem_t *ti = (griditem_t *)data;
340 if (ti->itype == GI_TEXT)
341 eina_strbuf_free(ti->istrdata);
343 eina_stringshare_del(ti->ipathdata);
347 // FIXME: how to remove calling g_get_main_appdata()?
348 // it's mainly used at 'clipdrawer_image_item'
349 int clipdrawer_add_item(char *idata, int type)
351 struct appdata *ad = g_get_main_appdata();
352 griditem_t *newgi = NULL;
354 newgi = malloc(sizeof(griditem_t));
357 fprintf(stderr, "## add - %d : %s\n", newgi->itype, idata);
360 newgi->istrdata = eina_strbuf_new();
361 eina_strbuf_append(newgi->istrdata, idata);
363 else //if (type == GI_IMAGE)
365 Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
366 griditem_t *ti = NULL;
368 if (!check_regular_file(idata))
370 DTRACE("Error : it isn't normal file = %s\n", idata);
376 ti = elm_gengrid_item_data_get(item);
377 if ((ti->itype == type) && !strcmp(ti->ipathdata, idata))
379 DTRACE("Error : duplicated file path = %s\n", idata);
382 item = elm_gengrid_item_next_get(item);
385 newgi->ipathdata = eina_stringshare_add(idata);
388 if (ad->hicount >= HISTORY_QUEUE_MAX_ITEMS)
391 // FIXME: add routine that is removing its elements
392 elm_gengrid_item_del(elm_gengrid_last_item_get(ad->hig));
396 newgi->item = elm_gengrid_item_prepend(ad->hig, &gic, newgi, NULL, NULL);
402 clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
404 struct appdata *ad = data;
406 if (ad->anim_status != STATUS_NONE)
409 #define EDJE_CLOSE_PART_PREFIX "background/close"
410 if (!strncmp(source, EDJE_CLOSE_PART_PREFIX, strlen(EDJE_CLOSE_PART_PREFIX)))
412 clipdrawer_lower_view(ad);
416 int clipdrawer_init(void *data)
418 struct appdata *ad = data;
421 ad->windowshow = EINA_FALSE;
423 ad->pastetextonly = EINA_TRUE;
424 ad->anim_status = STATUS_NONE;
427 elm_theme_extension_add(NULL, APP_EDJ_FILE);
429 cdy = (1.0*CLIPDRAWER_HEIGHT/SCREEN_HEIGHT)*ad->root_h;
430 cdw = (1.0*CLIPDRAWER_POS_Y/SCREEN_HEIGHT)*ad->root_h;
432 evas_object_resize(ad->win_main, ad->root_w, (int)cdy);
433 evas_object_move(ad->win_main, CLIPDRAWER_POS_X, (int)cdw);
434 evas_object_resize(ad->ly_main, ad->root_w, (int)cdy);
435 evas_object_move(ad->ly_main, CLIPDRAWER_POS_X, (int)cdw);
437 edje_object_signal_callback_add(elm_layout_edje_get(ad->ly_main),
438 "mouse,up,1", "*", clipdrawer_ly_clicked, ad);
441 ad->hig = elm_gengrid_add(ad->win_main);
442 elm_layout_content_set(ad->ly_main, "historyitems", ad->hig);
443 elm_gengrid_item_size_set(ad->hig, GRID_ITEM_W+2, GRID_ITEM_H);
444 elm_gengrid_align_set(ad->hig, 0.5, 0.5);
445 elm_gengrid_horizontal_set(ad->hig, EINA_TRUE);
446 elm_gengrid_bounce_set(ad->hig, EINA_TRUE, EINA_FALSE);
447 elm_gengrid_multi_select_set(ad->hig, EINA_FALSE);
448 evas_object_smart_callback_add(ad->hig, "selected", _grid_click_paste, ad);
449 // evas_object_smart_callback_add(ad->hig, "longpressed", _grid_longpress, ad);
450 evas_object_size_hint_weight_set(ad->hig, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
452 elm_gengrid_clear(ad->hig);
454 gic.item_style = "default_grid";
455 gic.func.label_get = NULL;
456 gic.func.icon_get = _grid_icon_get;
457 gic.func.state_get = NULL;
458 gic.func.del = _grid_del;
463 for (i = 0; i < N_IMAGES; i++)
465 clipdrawer_add_item(g_images_path[0], GI_IMAGE);
468 clipdrawer_add_item("clipboard history", GI_TEXT);
470 evas_object_show (ad->hig);
472 // for debugging, calc history pos
474 Evas_Coord x, y, w, h;
475 Evas_Coord vx, vy, vw, vh;
477 edje_object_part_geometry_get(elm_layout_edje_get(ad->ly_main),"imagehistory/list",&x,&y,&w,&h);
478 evas_object_geometry_get (ad->hig, &vx,&vy,&vw,&vh);
479 fprintf(stderr, "## x = %d, y = %d, w = %d, h = %d\n", x, y, w, h);
480 fprintf(stderr, "## vx = %d, vy = %d, vw = %d, vh = %d\n", vx, vy, vw, vh);
483 // if (get_item_counts() != 0)
484 // clipdrawer_update_contents(ad);
489 int clipdrawer_create_view(void *data)
491 struct appdata *ad = data;
496 // at starting, showing app view
497 // clipdrawer_activate_view(ad);
499 // clipdrawer_anim_show_effect(ad);
504 Ecore_Timer *tm_anim;
506 Eina_Bool anim_pos_calc_cb(void *data)
508 struct appdata *ad = data;
510 static int anim_count = 0;
511 int anim_starty, anim_endy, deltay;
514 switch (ad->anim_status)
517 anim_starty = (int)((1.0*CLIPDRAWER_HEIGHT/SCREEN_HEIGHT)*ad->root_h);
518 anim_endy = ad->root_h;
519 anim_starty = anim_endy - anim_starty;
522 anim_starty = ad->root_h;
523 anim_endy = (int)((1.0*CLIPDRAWER_HEIGHT/SCREEN_HEIGHT)*ad->root_h);
524 anim_endy = anim_starty-anim_endy;
530 if (anim_count > ANIM_DURATION)
533 if (ad->anim_status == HIDE_ANIM)
535 evas_object_hide(ad->win_main);
536 elm_win_lower(ad->win_main);
537 unset_transient_for(ad);
539 ad->anim_status = STATUS_NONE;
543 posprop = 1.0*anim_count/ANIM_DURATION;
544 switch (ad->anim_status)
547 deltay = (int)((anim_endy-anim_starty)*posprop);
548 evas_object_move(ad->win_main, 0, anim_starty+deltay);
549 //fprintf(stderr, "## cur pos y = %d\n", anim_starty+deltay);
552 deltay = (int)((anim_starty-anim_endy)*posprop);
553 evas_object_move(ad->win_main, 0, anim_starty-deltay);
554 //fprintf(stderr, "## cur pos y = %d\n", anim_starty-deltay);
564 void clipdrawer_anim_effect(void *data, anim_status_t atype)
566 struct appdata *ad = data;
568 if (ad->anim_status != STATUS_NONE)
570 DTRACE("ERR: another animation is showing\n");
574 ad->anim_status = atype;
575 ecore_timer_add(ANIM_FLOPS, anim_pos_calc_cb, ad);
578 void clipdrawer_activate_view(void *data)
580 struct appdata *ad = data;
584 set_transient_for(ad);
585 evas_object_show(ad->win_main);
586 clipdrawer_anim_effect(ad, SHOW_ANIM);
587 elm_win_activate(ad->win_main);
588 ad->windowshow = EINA_TRUE;
592 void clipdrawer_lower_view(void *data)
594 struct appdata *ad = data;
596 if (ad->win_main && ad->windowshow)
598 clipdrawer_anim_effect(ad, HIDE_ANIM);
599 ad->windowshow = EINA_FALSE;
603 void _change_gengrid_paste_textonly_mode(void *data)
605 struct appdata *ad = data;
607 fprintf(stderr, "## _change_gengrid_paste_textonly_mode = %d\n", clipdrawer_paste_textonly_get(ad));
609 Elm_Gengrid_Item *item;
610 griditem_t *ti = NULL;
612 if (clipdrawer_paste_textonly_get(ad))
613 { // textonly paste mode
614 Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
618 ti = elm_gengrid_item_data_get(item);
619 if ((ti->itype == GI_IMAGE) && (ti->ilayout))
621 fprintf(stderr, "## sig to hide delbtn\n");
623 edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,hide,delbtn", "elm");
624 Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(ad->hig));
625 evas_object_color_set(rect, 0, 0, 0, 200);
626 evas_object_show(rect);
627 elm_layout_content_set(ti->ilayout, "elm.swallow.cover", rect);
629 item = elm_gengrid_item_next_get(item);
633 { // text+image paste mode
634 Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
638 ti = elm_gengrid_item_data_get(item);
639 fprintf(stderr, "## itype = %d\n", ti->itype);
640 fprintf(stderr, "## ilayout = 0x%x\n", ti->ilayout);
641 if ((ti->itype == GI_IMAGE) && (ti->ilayout))
643 fprintf(stderr, "## sig to show delbtn\n");
645 edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,show,delbtn", "elm");
646 Evas_Object *rect = elm_layout_content_unset(ti->ilayout, "elm.swallow.cover");
647 evas_object_hide(rect);
648 evas_object_del(rect);
650 item = elm_gengrid_item_next_get(item);
655 void clipdrawer_paste_textonly_set(void *data, Eina_Bool textonly)
657 struct appdata *ad = data;
658 textonly = !!textonly;
659 if (ad->pastetextonly != textonly)
660 ad->pastetextonly = textonly;
661 DTRACE("paste textonly mode = %d\n", textonly);
663 _change_gengrid_paste_textonly_mode(ad);
666 Eina_Bool clipdrawer_paste_textonly_get(void *data)
668 struct appdata *ad = data;
669 return ad->pastetextonly;