88b32723e4d379a1825873536e9130064c091f9d
[framework/uifw/cbhm.git] / src / clipdrawer.c
1 /*
2  * Copyright (c) 2009 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * PROPRIETARY/CONFIDENTIAL
5  *
6  * This software is the confidential and proprietary information of
7  * SAMSUNG ELECTRONICS ("Confidential Information"). You agree and
8  * acknowledge that this software is owned by Samsung and you shall
9  * not disclose such Confidential Information and shall use it only
10  * in accordance with the terms of the license agreement you entered
11  * into with SAMSUNG ELECTRONICS.  SAMSUNG make no representations
12  * or warranties about the suitability of the software, either express
13  * or implied, including but not limited to the implied warranties of
14  * merchantability, fitness for a particular purpose, or non-infringement.
15  * SAMSUNG shall not be liable for any damages suffered by
16  * licensee arising out of or releated to this software.
17  */
18
19 #include "common.h"
20 #include "cbhm_main.h"
21 #include "storage.h"
22 #include "xcnphandler.h"
23 #include "clipdrawer.h"
24
25 #define DELETE_ICON_PATH "/usr/share/cbhm/icons/05_delete.png"
26 #define IM      "/usr/share/cbhm/icons/"
27 static const char *g_images_path[] = {
28         IM"cbhm_default_img.png",
29 };
30 #define N_IMAGES (1)
31
32 #define GRID_ITEM_SPACE_W 6
33 #define GRID_ITEM_SINGLE_W 185
34 #define GRID_ITEM_SINGLE_H 161
35 #define GRID_ITEM_W (GRID_ITEM_SINGLE_W+(GRID_ITEM_SPACE_W*2))
36 #define GRID_ITEM_H (GRID_ITEM_SINGLE_H)
37 #define GRID_IMAGE_LIMIT_W 91
38 #define GRID_IMAGE_LIMIT_H 113
39
40 #define ANIM_DURATION 30 // 1 seconds
41 #define ANIM_FLOPS (0.5/30)
42
43 // gic should live at gengrid callback functions
44 Elm_Gengrid_Item_Class gic;
45 static Ecore_Timer *anim_timer = NULL;
46
47 typedef struct tag_griditem
48 {
49         int itype;
50         Elm_Gengrid_Item *item;
51         const char *ipathdata;
52         Eina_Strbuf *istrdata;
53         Evas_Object *delbtn;
54         Evas_Object *ilayout;
55 } griditem_t;
56
57 const char *
58 remove_tags(const char *p)
59 {
60    char *q,*ret;
61    int i;
62    if (!p) return NULL;
63
64    q = malloc(strlen(p) + 1);
65    if (!q) return NULL;
66    ret = q;
67
68    while (*p)
69      {
70         if ((*p != '<')) *q++ = *p++;
71         else if (*p == '<')
72           {
73              if ((p[1] == 'b') && (p[2] == 'r') &&
74                  ((p[3] == ' ') || (p[3] == '/') || (p[3] == '>')))
75                *q++ = '\n';
76              while ((*p) && (*p != '>')) p++;
77              p++;
78           }
79      }
80    *q = 0;
81
82    return ret;
83 }
84
85 const char* clipdrawer_get_plain_string_from_escaped(char *escstr)
86 {
87         /* NOTE : return string should be freed */
88         return remove_tags(escstr);
89 }
90
91 static char* _get_string_for_entry(char *str)
92 {
93         if (!str)
94                 return NULL;
95
96         Eina_Strbuf *strbuf = eina_strbuf_new();
97         if (!strbuf)
98                 return strdup(str);
99         eina_strbuf_prepend(strbuf, "<font_size=18><color=#000000FF>");
100
101         char *trail = str;
102
103         while (trail && *trail)
104         {
105                 char *pretrail = trail;
106                 unsigned long length;
107                 char *temp;
108                 char *endtag;
109
110                 trail = strchr(trail, '<');
111                 if (!trail)
112                 {
113                         eina_strbuf_append(strbuf, pretrail);
114                         break;
115                 }
116                 endtag = strchr(trail, '>');
117                 if (!endtag)
118                         break;
119
120                 length = trail - pretrail;
121
122                 temp = strndup(pretrail, length);
123                 if (!temp)
124                 {
125                         trail++;
126                         continue;
127                 }
128
129                 DTRACE("temp str: %s \n", temp);
130                 eina_strbuf_append(strbuf, temp);
131                 free(temp);
132                 trail++;
133
134                 if (trail[0] == '/')
135                 {
136                         trail = endtag + 1;
137                         continue;
138                 }
139
140                 if (strncmp(trail, "br", 2) == 0)
141                 {
142                         eina_strbuf_append(strbuf, "<br>");
143                         trail = endtag + 1;
144                         continue;
145                 }
146
147                 if (strncmp(trail, "img", 3) == 0)
148                 {
149                         char *src = strstr(trail, "file://");
150                         char *src_endtag = strchr(trail, '>');
151                         if (!src || !src_endtag || src_endtag < src)
152                                 continue;
153
154                         length = src_endtag - src;
155
156                         src = strndup(src, length);
157                         if (!src)
158                         {
159                                 trail = endtag + 1;
160                                 continue;
161                         }
162                         temp = src;
163                         while(*temp)
164                         {
165                                 if (*temp == '\"' || *temp == '>')
166                                         *temp = '\0';
167                                 else
168                                         temp++;
169                         }
170
171                         eina_strbuf_append_printf(strbuf, "<item absize=66x62 href=%s></item>", src);
172                         DTRACE("src str: %s \n", src);
173                         free(src);
174                 }
175                 trail = endtag + 1;
176         }
177
178         char *ret = eina_strbuf_string_steal(strbuf);
179         eina_strbuf_free(strbuf);
180         DTRACE("result str: %s \n", ret);
181         return ret;
182 }
183
184 static void _grid_del_response_cb(void *data, Evas_Object *obj, void *event_info)
185 {
186         Elm_Gengrid_Item *it = (Elm_Gengrid_Item *)data;
187         evas_object_del(obj);
188
189         if((int)event_info == ELM_POPUP_RESPONSE_OK)
190         {
191                 struct appdata *ad = g_get_main_appdata();
192                 elm_gengrid_item_del(it);
193                 ad->hicount--;
194                 if (ad->hicount < 0)
195                 {
196                         int cnt = 0;
197                         Elm_Gengrid_Item *trail = elm_gengrid_first_item_get(ad->hig);
198                         while(trail)
199                         {
200                                 cnt++;
201                                 elm_gengrid_item_next_get(trail);
202                         }
203                         ad->hicount = cnt;
204                         DTRACE("ERR: cbhm history cnt < 0, gengrid item cnt: %d\n", cnt);
205                 }
206         }
207 }
208
209 static void _grid_click_delete(void *data, Evas_Object *obj, void *event_info)
210 {
211         struct appdata *ad = data;
212 }
213
214 static void
215 _grid_item_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
216 {
217         struct appdata *ad = g_get_main_appdata();
218
219         if (ad->anim_status != STATUS_NONE)
220                 return;
221
222         Elm_Gengrid_Item *sgobj = NULL;
223         sgobj = elm_gengrid_selected_item_get(ad->hig);
224         griditem_t *ti = NULL;
225         ti = elm_gengrid_item_data_get(sgobj);
226
227         #define EDJE_DELBTN_PART_PREFIX "delbtn"
228         if (strncmp(source, EDJE_DELBTN_PART_PREFIX, strlen(EDJE_DELBTN_PART_PREFIX)))
229         {
230                 if (!sgobj || !ti)
231                 {
232                         DTRACE("ERR: cbhm can't get the selected image\n");
233                         return;
234                 }
235
236                 elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
237
238                 if (ti->itype == GI_TEXT)
239                 {
240                         char *p = strdup(eina_strbuf_string_get(ti->istrdata));
241
242                         elm_selection_set(1, ad->hig, /*ELM_SEL_FORMAT_HTML*/0x10, p);
243                 }
244                 else //if (ti->itype == GI_IMAGE)
245                 {
246                         if (!clipdrawer_paste_textonly_get(ad))
247                         {
248                                 int len = strlen(ti->ipathdata);
249                                 char *p = malloc(len + 10);
250                                 snprintf(p,len+10, "file:///%s", ti->ipathdata);
251
252                                 elm_selection_set(/*secondary*/1, ad->hig,/*ELM_SEL_FORMAT_IMAGE*/4,p);
253                         }
254                         else
255                         {
256                                 DTRACE("ERR: cbhm image paste mode is false\n");
257                         }
258                 }
259                 return;
260         }
261
262         if (!sgobj)
263         {
264                 DTRACE("ERR: cbhm can't get the selected item\n");
265                 return;
266         }
267
268         elm_gengrid_item_selected_set(sgobj, EINA_FALSE);
269
270         Evas_Object *popup = elm_popup_add(ad->win_main);
271         elm_popup_timeout_set(popup, 5);
272         evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
273         elm_popup_desc_set(popup, "Are you sure delete this?");
274         elm_popup_buttons_add(popup, 2,
275                                                   "Yes", ELM_POPUP_RESPONSE_OK,
276                                                   "No", ELM_POPUP_RESPONSE_CANCEL,
277                                                   NULL);
278         evas_object_smart_callback_add(popup, "response", _grid_del_response_cb, sgobj);
279         evas_object_show(popup);
280 }
281
282 Evas_Object* _grid_icon_get(const void *data, Evas_Object *obj, const char *part)
283 {
284         griditem_t *ti = (griditem_t *)data;
285
286         if (!strcmp(part, "elm.swallow.icon"))
287         {
288                 if (ti->itype == GI_TEXT)
289                 {
290                         Evas_Object *layout = elm_layout_add (obj);
291                         elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
292                         edje_object_signal_callback_add(elm_layout_edje_get(layout), 
293                                                                                         "mouse,up,1", "*", _grid_item_ly_clicked, data);
294                         Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj));
295                         evas_object_resize(rect, GRID_ITEM_W, GRID_ITEM_H);
296                         evas_object_color_set(rect, 242, 233, 183, 255);
297                         evas_object_show(rect);
298                         elm_layout_content_set(layout, "elm.swallow.icon", rect);
299
300                         // FIXME: add string length check
301                         Evas_Object *ientry = elm_entry_add(obj);
302                         evas_object_size_hint_weight_set(ientry, 0, 0);
303                         Eina_Strbuf *strent = NULL;
304                         char *strdata = eina_strbuf_string_get(ti->istrdata);
305                         int i, skipflag, strcnt;
306                         
307                         strent = eina_strbuf_new();
308                         skipflag = 0;
309                         strcnt = 0;
310                         for (i = 0; i < eina_strbuf_length_get(ti->istrdata); i++)
311                         {
312                                 switch (strdata[i])
313                                 {
314                                         case '>':
315                                                 skipflag = 0;
316                                                 break;
317                                         case '<':
318                                                 skipflag = 1;
319                                                 break;
320                                         default:
321                                                 if (!skipflag)
322                                                         strcnt++;
323                                                 break;
324                                 }
325                                 if (strcnt > 100)
326                                         break;
327                         }
328                         eina_strbuf_append_n(strent, strdata, i);
329                         eina_strbuf_replace_all(strent, " absize=240x180 ", " absize=52x39 ");
330                         if (strcnt > 100)
331                                 eina_strbuf_append(strent, "...");
332                         elm_entry_scrollable_set(ientry, EINA_TRUE);
333                         char *entry_text = eina_strbuf_string_get(strent);
334                         entry_text = _get_string_for_entry(entry_text);
335                         if (entry_text)
336                         {
337                                 elm_object_text_part_set(ientry, NULL, entry_text);
338                                 free(entry_text);
339                         }
340                         elm_entry_editable_set(ientry, EINA_FALSE);
341                         elm_entry_context_menu_disabled_set(ientry, EINA_TRUE);
342                         evas_object_show(ientry);
343                         elm_layout_content_set(layout, "elm.swallow.inner", ientry);
344
345                         eina_strbuf_free(strent);
346
347                         return layout;
348                 }
349                 else// if (ti->itype == GI_IMAGE)
350                 {
351                         Evas_Object *layout = elm_layout_add (obj);
352                         elm_layout_theme_set(layout, "gengrid", "widestyle", "horizontal_layout");
353                         edje_object_signal_callback_add(elm_layout_edje_get(layout), 
354                                                                                         "mouse,up,1", "*", _grid_item_ly_clicked, data);
355
356                         Evas_Object *sicon;
357                         sicon = evas_object_image_add(evas_object_evas_get(obj));
358                         evas_object_image_load_size_set(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
359                         evas_object_image_file_set(sicon, ti->ipathdata, NULL);
360                         evas_object_image_fill_set(sicon, 0, 0, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
361                         evas_object_resize(sicon, GRID_ITEM_SINGLE_W, GRID_ITEM_SINGLE_H);
362                         elm_layout_content_set(layout, "elm.swallow.icon", sicon);
363
364                         struct appdata *ad = g_get_main_appdata();
365                         
366                         if (clipdrawer_paste_textonly_get(ad))
367                                 edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,show,dim", "elm");
368                         else
369                                 edje_object_signal_emit(elm_layout_edje_get(layout), "elm,state,hide,dim", "elm");
370
371                         ti->ilayout = layout;
372                         return layout;
373                 }
374         }
375
376         return NULL;
377 }
378
379 static void _grid_longpress(void *data, Evas_Object *obj, void *event_info)
380 {
381         struct appdata *ad = data;
382 }
383
384 static void _grid_click_paste(void *data, Evas_Object *obj, void *event_info)
385 {
386         struct appdata *ad = data;
387         if (ad->anim_status != STATUS_NONE)
388                 return;
389
390         Elm_Gengrid_Item *sgobj = NULL;
391         sgobj = elm_gengrid_selected_item_get(ad->hig);
392         griditem_t *ti = NULL;
393         ti = elm_gengrid_item_data_get(sgobj);
394 }
395
396 void _grid_del(const void *data, Evas_Object *obj)
397 {
398         griditem_t *ti = (griditem_t *)data;
399         if (ti->itype == GI_TEXT)
400                 eina_strbuf_free(ti->istrdata);
401         else
402                 eina_stringshare_del(ti->ipathdata);
403         free(ti);
404 }
405
406 char* clipdrawer_get_item_data(void *data, int pos)
407 {
408         struct appdata *ad = data;
409         griditem_t *ti = NULL;
410         griditem_t *newgi = NULL;
411         int count = 0;
412
413         if (pos < 0 || pos > ad->hicount)
414                 return NULL;
415
416         Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
417         while (item)
418         {
419                 ti = elm_gengrid_item_data_get(item);
420                 if (count == pos)
421                 {
422                         if (!ti)
423                                 break;
424                         if (ti->itype == GI_TEXT)
425                                 return (char*)eina_strbuf_string_get(ti->istrdata);
426                         else
427                                 return ti->ipathdata;
428                 }
429                 count++;
430                 item = elm_gengrid_item_next_get(item);
431         }
432
433         return NULL;
434 }
435
436 // FIXME: how to remove calling g_get_main_appdata()? 
437 //        it's mainly used at 'clipdrawer_image_item'
438 int clipdrawer_add_item(char *idata, int type)
439 {
440         struct appdata *ad = g_get_main_appdata();
441         griditem_t *newgi = NULL;
442
443         newgi = malloc(sizeof(griditem_t));
444         newgi->itype = type;
445
446         fprintf(stderr, "## add - %d : %s\n", newgi->itype, idata);
447         if (type == GI_TEXT)
448         {
449                 newgi->istrdata = eina_strbuf_new();
450                 eina_strbuf_append(newgi->istrdata, idata);
451         }
452         else //if (type == GI_IMAGE)
453         {
454                 Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
455                 griditem_t *ti = NULL;
456
457                 if (!check_regular_file(idata))
458                 {
459                         DTRACE("Error : it isn't normal file = %s\n", idata);
460                         return -1;
461                 }
462
463                 while (item)
464                 {
465                         ti = elm_gengrid_item_data_get(item);
466                         if ((ti->itype == type) && !strcmp(ti->ipathdata, idata))
467                         {
468                                 DTRACE("Error : duplicated file path = %s\n", idata);
469                                 return -1;
470                         }
471                         item = elm_gengrid_item_next_get(item);
472                 }
473                 newgi->ipathdata = eina_stringshare_add(idata);
474         }
475
476         if (ad->hicount >= HISTORY_QUEUE_MAX_ITEMS)
477         {
478                 ad->hicount--;
479                 // FIXME: add routine that is removing its elements
480                 elm_gengrid_item_del(elm_gengrid_last_item_get(ad->hig));
481         }
482
483         ad->hicount++;
484         newgi->item = elm_gengrid_item_prepend(ad->hig, &gic, newgi, NULL, NULL);
485
486         return TRUE;
487 }
488
489 static void
490 clipdrawer_ly_clicked(void *data, Evas_Object *obj, const char *emission, const char *source)
491 {
492         struct appdata *ad = data;
493
494         if (ad->anim_status != STATUS_NONE)
495                 return;
496
497         #define EDJE_CLOSE_PART_PREFIX "background/close"
498         if (!strncmp(source, EDJE_CLOSE_PART_PREFIX, strlen(EDJE_CLOSE_PART_PREFIX)))
499         {
500                 clipdrawer_lower_view(ad);
501         }
502 }
503
504 static void set_sliding_win_geometry(void *data)
505 {
506         struct appdata *ad = data;
507         Ecore_X_Window zone, xwin;
508         Evas_Coord x, y, w, h;
509         xwin = elm_win_xwindow_get(ad->win_main);
510         zone = ecore_x_e_illume_zone_get(xwin);
511         DTRACE("[CBHM] xwin:%x, zone:%x\n", xwin, zone);
512
513 //      ecore_evas_geometry_get(ecore_evas_ecore_evas_get(evas_object_evas_get(ad->win_main)), &x, &y, &w, &h);
514
515         if (ad->o_degree == 90 || ad->o_degree == 270)
516         {
517                 h = ad->anim_count * CLIPDRAWER_HEIGHT_LANDSCAPE / ANIM_DURATION;
518                 x = 0;
519                 y = ad->root_w - h;
520                 w = ad->root_h;
521         }
522         else
523         {
524                 h = ad->anim_count * CLIPDRAWER_HEIGHT / ANIM_DURATION;
525                 x = 0;
526                 y = ad->root_h - h;
527                 w = ad->root_w;
528         }
529
530         if (!h)
531                 w = 0;
532
533         DTRACE("[CBHM] change degree geometry... (%d, %d, %d x %d)\n", x, y, w, h);
534         ecore_x_e_illume_sliding_win_geometry_set(zone, x, y, w, h);
535         ecore_x_e_illume_sliding_win_state_set(zone, ad->anim_count != 0);
536 }
537
538 void set_rotation_to_clipdrawer(void *data)
539 {
540         struct appdata *ad = data;
541         int angle = ad->o_degree;
542         int x, y, w, h;
543
544         if (angle == 180) // reverse
545         {
546                 h = CLIPDRAWER_HEIGHT;
547                 x = 0;
548                 y = 0;
549                 w = ad->root_w;
550         }
551         else if (angle == 90) // right rotate
552         {
553                 h = CLIPDRAWER_HEIGHT_LANDSCAPE;
554                 x = ad->root_w - h;
555                 y = 0;
556                 w = ad->root_h;
557         }
558         else if (angle == 270) // left rotate
559         {
560                 h = CLIPDRAWER_HEIGHT_LANDSCAPE;
561                 x = 0;
562                 y = 0;
563                 w = ad->root_h;
564         }
565         else // angle == 0
566         {
567                 h = CLIPDRAWER_HEIGHT;
568                 x = 0;
569                 y = ad->root_h - h;
570                 w = ad->root_w;
571         }
572
573         evas_object_resize(ad->win_main, w, h);
574         evas_object_move(ad->win_main, x, y);
575         if (ad->anim_count == ANIM_DURATION)
576                 set_sliding_win_geometry(data);
577 }
578
579 int clipdrawer_init(void *data)
580 {
581         struct appdata *ad = data;
582         double cdy, cdw;
583
584         ad->windowshow = EINA_FALSE;
585         ad->hicount = 0;
586         ad->pastetextonly = EINA_TRUE;
587         ad->anim_status = STATUS_NONE;
588         ad->anim_count = 0;
589
590         // for elm_check
591         elm_theme_extension_add(NULL, APP_EDJ_FILE);
592
593         edje_object_signal_callback_add(elm_layout_edje_get(ad->ly_main), 
594                                                                         "mouse,up,1", "*", clipdrawer_ly_clicked, ad);
595
596         ad->hig = NULL;
597         ad->hig = elm_gengrid_add(ad->win_main);
598         elm_layout_content_set(ad->ly_main, "historyitems", ad->hig);
599         elm_gengrid_item_size_set(ad->hig, GRID_ITEM_W+2, GRID_ITEM_H);
600         elm_gengrid_align_set(ad->hig, 0.5, 0.5);
601         elm_gengrid_horizontal_set(ad->hig, EINA_TRUE);
602         elm_gengrid_bounce_set(ad->hig, EINA_TRUE, EINA_FALSE);
603         elm_gengrid_multi_select_set(ad->hig, EINA_FALSE);
604         evas_object_smart_callback_add(ad->hig, "selected", _grid_click_paste, ad);
605 //      evas_object_smart_callback_add(ad->hig, "longpressed", _grid_longpress, ad);
606         evas_object_size_hint_weight_set(ad->hig, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
607
608         elm_gengrid_clear(ad->hig);
609
610         gic.item_style = "default_grid";
611         gic.func.label_get = NULL;
612         gic.func.icon_get = _grid_icon_get;
613         gic.func.state_get = NULL;
614         gic.func.del = _grid_del;
615
616         int i;
617         griditem_t *newgi;
618
619         for (i = 0; i < N_IMAGES; i++)
620         {
621                 clipdrawer_add_item(g_images_path[0], GI_IMAGE);
622         }
623
624         clipdrawer_add_item("clipboard history", GI_TEXT);
625
626         evas_object_show (ad->hig);
627
628 // for debugging, calc history pos
629 /*
630    Evas_Coord x, y, w, h;
631    Evas_Coord vx, vy, vw, vh;
632
633    edje_object_part_geometry_get(elm_layout_edje_get(ad->ly_main),"imagehistory/list",&x,&y,&w,&h);
634    evas_object_geometry_get (ad->hig, &vx,&vy,&vw,&vh);
635    fprintf(stderr, "## x = %d, y = %d, w = %d, h = %d\n", x, y, w, h);
636    fprintf(stderr, "## vx = %d, vy = %d, vw = %d, vh = %d\n", vx, vy, vw, vh);
637 */
638
639 //      if (get_item_counts() != 0)
640 //              clipdrawer_update_contents(ad);
641
642         return 0;
643 }
644
645 int clipdrawer_create_view(void *data)
646 {
647         struct appdata *ad = data;
648
649         clipdrawer_init(ad);
650
651         // for debug
652         // at starting, showing app view
653         //clipdrawer_activate_view(ad);
654
655         return 0;
656 }
657
658 Eina_Bool _get_anim_pos(void *data, int *sp, int *ep)
659 {
660         if (!sp || !ep)
661                 return EINA_FALSE;
662
663         struct appdata *ad = data;
664         int angle = ad->o_degree;
665         int anim_start, anim_end;
666
667         if (angle == 180) // reverse
668         {
669                 anim_start = -(ad->root_h - CLIPDRAWER_HEIGHT);
670                 anim_end = 0;
671         }
672         else if (angle == 90) // right rotate
673         {
674                 anim_start = ad->root_w;
675                 anim_end = anim_start - CLIPDRAWER_HEIGHT_LANDSCAPE;
676         }
677         else if (angle == 270) // left rotate
678         {
679                 anim_start = -(ad->root_w - CLIPDRAWER_HEIGHT_LANDSCAPE);
680                 anim_end = 0;
681         }
682         else // angle == 0
683         {
684                 anim_start = ad->root_h;
685                 anim_end = anim_start - CLIPDRAWER_HEIGHT;
686         }
687
688         *sp = anim_start;
689         *ep = anim_end;
690         return EINA_TRUE;
691 }
692
693 Eina_Bool _do_anim_delta_pos(void *data, int sp, int ep, int ac, int *dp)
694 {
695         if (!dp)
696                 return EINA_FALSE;
697
698         struct appdata *ad = data;
699         int angle = ad->o_degree;
700         int delta;
701         double posprop;
702         posprop = 1.0*ac/ANIM_DURATION;
703
704         if (angle == 180) // reverse
705         {
706                 delta = (int)((ep-sp)*posprop);
707                 evas_object_move(ad->win_main, 0, sp+delta);
708         }
709         else if (angle == 90) // right rotate
710         {
711                 delta = (int)((ep-sp)*posprop);
712                 evas_object_move(ad->win_main, sp+delta, 0);
713         }
714         else if (angle == 270) // left rotate
715         {
716                 delta = (int)((ep-sp)*posprop);
717                 evas_object_move(ad->win_main, sp+delta, 0);
718         }
719         else // angle == 0
720         {
721                 delta = (int)((sp-ep)*posprop);
722                 evas_object_move(ad->win_main, 0, sp-delta);
723         }
724         
725         *dp = delta;
726
727         return EINA_TRUE;
728 }
729
730 static void stop_animation(void *data)
731 {
732         struct appdata *ad = data;
733
734         ad->anim_status = STATUS_NONE;
735         if (anim_timer)
736         {
737                 ecore_timer_del(anim_timer);
738                 anim_timer = NULL;
739         }
740
741         set_sliding_win_geometry(data);
742 }
743
744 Eina_Bool anim_pos_calc_cb(void *data)
745 {
746         struct appdata *ad = data;
747
748         int anim_start, anim_end, delta;
749
750         _get_anim_pos(ad, &anim_start, &anim_end);
751
752         if (ad->anim_status == SHOW_ANIM)
753         {
754                 if (ad->anim_count > ANIM_DURATION)
755                 {
756                         ad->anim_count = ANIM_DURATION;
757                         stop_animation(data);
758                         return EINA_FALSE;
759                 }
760                 _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta);
761                 ad->anim_count++;
762         }
763         else if (ad->anim_status == HIDE_ANIM)
764         {
765                 if (ad->anim_count < 0)
766                 {
767                         ad->anim_count = 0;
768                         evas_object_hide(ad->win_main);
769                         elm_win_lower(ad->win_main);
770                         unset_transient_for(ad);
771                         stop_animation(data);
772                         return EINA_FALSE;
773                 }
774                 _do_anim_delta_pos(ad, anim_start, anim_end, ad->anim_count, &delta);
775                 ad->anim_count--;
776         }
777         else
778         {
779                 stop_animation(data);
780                 return EINA_FALSE;
781         }
782
783         return EINA_TRUE;
784 }
785
786 Eina_Bool clipdrawer_anim_effect(void *data, anim_status_t atype)
787 {
788         struct appdata *ad = data;
789
790         if (atype == ad->anim_status)
791         {
792                 DTRACE("Warning: Animation effect is already in progress. \n");
793                 return EINA_FALSE;
794         }
795
796         ad->anim_status = atype;
797
798         if (anim_timer)
799                 ecore_timer_del(anim_timer);
800
801         anim_timer = ecore_timer_add(ANIM_FLOPS, anim_pos_calc_cb, ad);
802
803         return EINA_TRUE;
804 }
805
806 void clipdrawer_activate_view(void *data)
807 {
808         struct appdata *ad = data;
809
810         if (ad->win_main)
811         {
812                 set_transient_for(ad);
813                 ad->o_degree = get_active_window_degree(ad->active_win);
814                 elm_win_rotation_set(ad->win_main, ad->o_degree);
815                 set_rotation_to_clipdrawer(data);
816                 evas_object_show(ad->win_main);
817                 elm_win_activate(ad->win_main);
818                 if (clipdrawer_anim_effect(ad, SHOW_ANIM))
819                         ad->windowshow = EINA_TRUE;
820         }
821 }
822
823 void clipdrawer_lower_view(void *data)
824 {
825         struct appdata *ad = data;
826         
827         if (ad->win_main && ad->windowshow)
828         {
829                 if (clipdrawer_anim_effect(ad, HIDE_ANIM))
830                         ad->windowshow = EINA_FALSE;
831         }
832 }
833
834 void _change_gengrid_paste_textonly_mode(void *data)
835 {
836         struct appdata *ad = data;
837
838         griditem_t *ti = NULL;
839
840         Elm_Gengrid_Item *item = elm_gengrid_first_item_get(ad->hig);
841
842         while (item)
843         {
844                 ti = elm_gengrid_item_data_get(item);
845                 if ((ti->itype == GI_IMAGE) && (ti->ilayout))
846                 {
847                         if (clipdrawer_paste_textonly_get(ad))
848                                 edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,show,dim", "elm");
849                         else
850                                 edje_object_signal_emit(elm_layout_edje_get(ti->ilayout), "elm,state,hide,dim", "elm");
851                 }
852                 item = elm_gengrid_item_next_get(item);
853         }
854 }
855
856 void clipdrawer_paste_textonly_set(void *data, Eina_Bool textonly)
857 {
858         struct appdata *ad = data;
859         textonly = !!textonly;
860         if (ad->pastetextonly != textonly)
861                 ad->pastetextonly = textonly;
862         DTRACE("paste textonly mode = %d\n", textonly);
863
864         _change_gengrid_paste_textonly_mode(ad);
865 }
866
867 Eina_Bool clipdrawer_paste_textonly_get(void *data)
868 {
869         struct appdata *ad = data;
870         return ad->pastetextonly;
871 }