Add APIs for floating mode (app-in-app)
[framework/uifw/elementary.git] / src / lib / els_icon.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "els_icon.h"
4
5 #ifdef _WIN32
6 # define FMT_SIZE_T "%Iu"
7 #else
8 # define FMT_SIZE_T "%zu"
9 #endif
10
11 typedef struct _Smart_Data Smart_Data;
12
13 struct _Smart_Data
14 {
15    Evas_Coord   x, y, w, h;
16    Evas_Object *obj;
17    Evas_Object *prev;
18    int          size;
19    double       scale;
20    Eina_Bool fill_inside : 1;
21    Eina_Bool scale_up : 1;
22    Eina_Bool scale_down : 1;
23    Eina_Bool preloading : 1;
24    Eina_Bool show : 1;
25    Eina_Bool edit : 1;
26    Eina_Bool edje : 1;
27    Eina_Bool aspect_fixed: 1;
28    Elm_Image_Orient orient;
29 };
30
31 /* local subsystem functions */
32 static void _smart_reconfigure(Smart_Data *sd);
33 static void _smart_init(void);
34 static void _smart_add(Evas_Object *obj);
35 static void _smart_del(Evas_Object *obj);
36 static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
37 static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
38 static void _smart_show(Evas_Object *obj);
39 static void _smart_hide(Evas_Object *obj);
40 static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
41 static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
42 static void _smart_clip_unset(Evas_Object *obj);
43
44 static void _els_smart_icon_flip_horizontal(Smart_Data *sd);
45 static void _els_smart_icon_flip_vertical(Smart_Data *sd);
46 static void _els_smart_icon_rotate_180(Smart_Data *sd);
47 static Eina_Bool _els_smart_icon_dropcb(void *,Evas_Object *, Elm_Selection_Data *);
48
49 /* local subsystem globals */
50 static Evas_Smart *_e_smart = NULL;
51
52 /* externally accessible functions */
53 Evas_Object *
54 _els_smart_icon_add(Evas *evas)
55 {
56    _smart_init();
57    return evas_object_smart_add(evas, _e_smart);
58 }
59
60 static void
61 _preloaded(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event __UNUSED__)
62 {
63    Smart_Data *sd = data;
64
65    sd->preloading = EINA_FALSE;
66    if (obj == sd->obj)
67      {
68         if (sd->show)
69           evas_object_show(sd->obj);
70      }
71    if (sd->prev) evas_object_del(sd->prev);
72    sd->prev = NULL;
73 }
74
75 static void
76 _els_smart_icon_file_helper(Evas_Object *obj)
77 {
78    Smart_Data *sd;
79    Evas_Object *pclip;
80
81    sd = evas_object_smart_data_get(obj);
82    /* smart code here */
83    /* NOTE: Do not merge upstream for the if (sd->edje) { } statements
84       But wonder whether the edje resource icons have no problem. */
85    if (!sd->edje) goto out;
86
87    if (sd->prev) evas_object_del(sd->prev);
88    pclip = evas_object_clip_get(sd->obj);
89    if (sd->obj) sd->prev = sd->obj;
90    sd->obj = evas_object_image_add(evas_object_evas_get(obj));
91    evas_object_image_load_orientation_set(sd->obj, EINA_TRUE);
92    evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
93                                   _preloaded, sd);
94    evas_object_smart_member_add(sd->obj, obj);
95    if (sd->prev) evas_object_smart_member_add(sd->prev, obj);
96    evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
97    evas_object_clip_set(sd->obj, pclip);
98
99    sd->edje = EINA_FALSE;
100 out:
101
102    if (!sd->size)
103      evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
104 }
105
106 Eina_Bool
107 _els_smart_icon_memfile_set(Evas_Object *obj, const void *img, size_t size, const char *format, const char *key)
108 {
109    Smart_Data *sd;
110
111    sd = evas_object_smart_data_get(obj);
112    if (!sd) return EINA_FALSE;
113    _els_smart_icon_file_helper(obj);
114
115    evas_object_image_memfile_set(sd->obj, (void*)img, size, (char*)format, (char*)key);
116    sd->preloading = EINA_TRUE;
117    sd->show = EINA_TRUE;
118    evas_object_hide(sd->obj);
119    evas_object_image_preload(sd->obj, EINA_FALSE);
120    if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
121      {
122         ERR("Things are going bad for some random " FMT_SIZE_T " byte chunk of memory (%p)", size, sd->obj);
123         return EINA_FALSE;
124      }
125    _smart_reconfigure(sd);
126    return EINA_TRUE;
127 }
128
129 Eina_Bool
130 _els_smart_icon_file_key_set(Evas_Object *obj, const char *file, const char *key)
131 {
132    Smart_Data *sd;
133
134    sd = evas_object_smart_data_get(obj);
135    if (!sd) return EINA_FALSE;
136    _els_smart_icon_file_helper(obj);
137
138    evas_object_image_file_set(sd->obj, file, key);
139    // NOTE: Do not merge upstream for sd->preloading.
140    sd->preloading = EINA_FALSE; // by default preload off by seok.j.jeong
141    sd->show = EINA_TRUE;
142    // NOTE: Do not merge upstream for sd->preloading.
143    if (sd->preloading)
144      evas_object_image_preload(sd->obj, EINA_FALSE);
145    // NOTE: Do not merge upstream for sd->preloading.
146    if (sd->preloading) // sd->preloading can be changed by above function. so add "if (sd->preloading)" as below
147      evas_object_hide(sd->obj);
148    if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
149      {
150         ERR("Things are going bad for '%s' (%p)", file, sd->obj);
151         return EINA_FALSE;
152      }
153    _smart_reconfigure(sd);
154    return EINA_TRUE;
155 }
156
157 void
158 _els_smart_icon_preload_set(Evas_Object *obj, Eina_Bool disable)
159 {
160    Smart_Data *sd;
161
162    sd = evas_object_smart_data_get(obj);
163    if ((!sd) || sd->edje) return;
164    evas_object_image_preload(sd->obj, disable);
165    sd->preloading = !disable;
166 }
167
168 Eina_Bool
169 _els_smart_icon_file_edje_set(Evas_Object *obj, const char *file, const char *part)
170 {
171    Smart_Data *sd;
172    Evas_Object *pclip;
173
174    sd = evas_object_smart_data_get(obj);
175    if (!sd) return EINA_FALSE;
176    /* smart code here */
177    if (sd->prev) evas_object_del(sd->prev);
178    sd->prev = NULL;
179
180    if (!sd->edje)
181      {
182         pclip = evas_object_clip_get(sd->obj);
183         if (sd->obj) evas_object_del(sd->obj);
184         sd->obj = edje_object_add(evas_object_evas_get(obj));
185         evas_object_smart_member_add(sd->obj, obj);
186         if (sd->show) evas_object_show(sd->obj);
187         evas_object_clip_set(sd->obj, pclip);
188      }
189    sd->edje = EINA_TRUE;
190    if (!edje_object_file_set(sd->obj, file, part))
191      return EINA_FALSE;
192    _smart_reconfigure(sd);
193    return EINA_TRUE;
194 }
195
196 void
197 _els_smart_icon_file_get(const Evas_Object *obj, const char **file, const char **key)
198 {
199    Smart_Data *sd = evas_object_smart_data_get(obj);
200    if (!sd) return;
201    if (sd->edje)
202      edje_object_file_get(sd->obj, file, key);
203    else
204      evas_object_image_file_get(sd->obj, file, key);
205 }
206
207 void
208 _els_smart_icon_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth)
209 {
210    Smart_Data *sd = evas_object_smart_data_get(obj);
211    if (!sd) return;
212    if (sd->edje)
213      return;
214    evas_object_image_smooth_scale_set(sd->obj, smooth);
215 }
216
217 Eina_Bool
218 _els_smart_icon_smooth_scale_get(const Evas_Object *obj)
219 {
220    Smart_Data *sd = evas_object_smart_data_get(obj);
221    if (!sd) return EINA_FALSE;
222    if (sd->edje)
223      return EINA_FALSE;
224    return evas_object_image_smooth_scale_get(sd->obj);
225 }
226
227 Evas_Object *
228 _els_smart_icon_object_get(const Evas_Object *obj)
229 {
230    Smart_Data *sd = evas_object_smart_data_get(obj);
231    if (!sd) return NULL;
232    return sd->obj;
233 }
234
235 void
236 _els_smart_icon_size_get(const Evas_Object *obj, int *w, int *h)
237 {
238    Smart_Data *sd;
239    int tw, th;
240    int cw, ch;
241    const char *type;
242
243    sd = evas_object_smart_data_get(obj);
244    if (!sd) return;
245    type = evas_object_type_get(sd->obj);
246    if (!type) return;
247    if (!strcmp(type, "edje"))
248      edje_object_size_min_get(sd->obj, &tw, &th);
249    else
250      evas_object_image_size_get(sd->obj, &tw, &th);
251    evas_object_geometry_get(sd->obj, NULL, NULL, &cw, &ch);
252    tw = tw > cw ? tw : cw;
253    th = th > ch ? th : ch;
254    tw = ((double)tw) * sd->scale;
255    th = ((double)th) * sd->scale;
256    if (w) *w = tw;
257    if (h) *h = th;
258 }
259
260 void
261 _els_smart_icon_fill_inside_set(Evas_Object *obj, Eina_Bool fill_inside)
262 {
263    Smart_Data *sd;
264
265    sd = evas_object_smart_data_get(obj);
266    if (!sd) return;
267    if (((sd->fill_inside) && (fill_inside)) ||
268        ((!sd->fill_inside) && (!fill_inside))) return;
269    sd->fill_inside = fill_inside;
270    _smart_reconfigure(sd);
271 }
272
273 Eina_Bool
274 _els_smart_icon_fill_inside_get(const Evas_Object *obj)
275 {
276    Smart_Data *sd = evas_object_smart_data_get(obj);
277    if (!sd) return EINA_FALSE;
278    return sd->fill_inside;
279 }
280
281 void
282 _els_smart_icon_scale_up_set(Evas_Object *obj, Eina_Bool scale_up)
283 {
284    Smart_Data *sd;
285
286    sd = evas_object_smart_data_get(obj);
287    if (!sd) return;
288    if (((sd->scale_up) && (scale_up)) ||
289        ((!sd->scale_up) && (!scale_up))) return;
290    sd->scale_up = scale_up;
291    _smart_reconfigure(sd);
292 }
293
294 Eina_Bool
295 _els_smart_icon_scale_up_get(const Evas_Object *obj)
296 {
297    Smart_Data *sd; sd = evas_object_smart_data_get(obj);
298    if (!sd) return EINA_FALSE;
299    return sd->scale_up;
300 }
301
302 void
303 _els_smart_icon_scale_down_set(Evas_Object *obj, Eina_Bool scale_down)
304 {
305    Smart_Data *sd;
306
307    sd = evas_object_smart_data_get(obj);
308    if (!sd) return;
309    if (((sd->scale_down) && (scale_down)) ||
310        ((!sd->scale_down) && (!scale_down))) return;
311    sd->scale_down = scale_down;
312    _smart_reconfigure(sd);
313 }
314
315 Eina_Bool
316 _els_smart_icon_scale_down_get(const Evas_Object *obj)
317 {
318    Smart_Data *sd; sd = evas_object_smart_data_get(obj);
319    if (!sd) return EINA_FALSE;
320    return sd->scale_up;
321 }
322
323 void
324 _els_smart_icon_scale_size_set(Evas_Object *obj, int size)
325 {
326    Smart_Data *sd;
327
328    sd = evas_object_smart_data_get(obj);
329    if (!sd) return;
330    sd->size = size;
331    if (!sd->obj) return;
332    if (sd->edje)
333      return;
334    evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
335 }
336
337 int
338 _els_smart_icon_scale_size_get(const Evas_Object *obj)
339 {
340    Smart_Data *sd; sd = evas_object_smart_data_get(obj);
341    if (!sd) return 0;
342    return sd->size;
343 }
344
345 void
346 _els_smart_icon_scale_set(Evas_Object *obj, double scale)
347 {
348    Smart_Data *sd = evas_object_smart_data_get(obj);
349    if (!sd) return;
350    sd->scale = scale;
351    _smart_reconfigure(sd);
352 }
353
354 double
355 _els_smart_icon_scale_get(const Evas_Object *obj)
356 {
357    Smart_Data *sd; sd = evas_object_smart_data_get(obj);
358    if (!sd) return 0.0;
359    return sd->scale;
360 }
361
362 void
363 _els_smart_icon_orient_set(Evas_Object *obj, Elm_Image_Orient orient)
364 {
365    Smart_Data   *sd;
366    unsigned int *data, *data2 = NULL, *to, *from;
367    int           x, y, w, hw, iw, ih;
368
369    sd = evas_object_smart_data_get(obj);
370    if (!sd) return;
371    if (sd->edje)
372      return;
373
374    switch (orient)
375      {
376       case ELM_IMAGE_FLIP_HORIZONTAL:
377          _els_smart_icon_flip_horizontal(sd);
378          return;
379       case ELM_IMAGE_FLIP_VERTICAL:
380          _els_smart_icon_flip_vertical(sd);
381          return;
382       case ELM_IMAGE_ROTATE_180:
383          _els_smart_icon_rotate_180(sd);
384          return;
385       default:
386          break;
387      }
388
389    evas_object_image_size_get(sd->obj, &iw, &ih);
390    /* we need separate destination memory if we want to rotate 90 or 270 degree */
391    evas_object_image_data_copy_set(sd->obj, data2);
392    if (!data2) return;
393
394    w = ih;
395    ih = iw;
396    iw = w;
397    hw = w * ih;
398
399    evas_object_image_size_set(sd->obj, iw, ih);
400    data = evas_object_image_data_get(sd->obj, EINA_TRUE);
401
402    switch (orient)
403      {
404       case ELM_IMAGE_FLIP_TRANSPOSE:
405          to = data;
406          hw = -hw + 1;
407          break;
408       case ELM_IMAGE_FLIP_TRANSVERSE:
409          to = data + hw - 1;
410          w = -w;
411          hw = hw - 1;
412          break;
413       case ELM_IMAGE_ROTATE_90:
414          to = data + w - 1;
415          hw = -hw - 1;
416          break;
417       case ELM_IMAGE_ROTATE_270:
418          to = data + hw - w;
419          w = -w;
420          hw = hw + 1;
421          break;
422       default:
423          ERR("unknown orient %d", orient);
424          evas_object_image_data_set(sd->obj, data); // give it back
425          if (data2) free(data2);
426          return;
427      }
428    from = data2;
429    for (x = iw; --x >= 0;)
430      {
431         for (y = ih; --y >= 0;)
432           {
433              *to = *from;
434              from++;
435              to += w;
436           }
437         to += hw;
438      }
439    sd->orient = orient;
440    if (data2) free(data2);
441    evas_object_image_data_set(sd->obj, data);
442    evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
443    _smart_reconfigure(sd);
444 }
445
446 Elm_Image_Orient
447 _els_smart_icon_orient_get(const Evas_Object *obj)
448 {
449    Smart_Data *sd; sd = evas_object_smart_data_get(obj);
450    if (!sd) return 0;
451    return sd->orient;
452 }
453
454 /**
455  * Turns on editing through drag and drop and copy and paste.
456  */
457 void
458 _els_smart_icon_edit_set(Evas_Object *obj, Eina_Bool edit, Evas_Object *parent)
459 {
460    Smart_Data   *sd = evas_object_smart_data_get(obj);
461    if (!sd) return;
462
463    if (sd->edje)
464      {
465         printf("No editing edje objects yet (ever)\n");
466         return;
467      }
468
469    /* Unfortunately eina bool is not a bool, but a char */
470    if (edit == sd->edit) return;
471
472    sd->edit = edit;
473
474    if (sd->edit)
475      elm_drop_target_add(obj, ELM_SEL_FORMAT_IMAGE, _els_smart_icon_dropcb,
476                          parent);
477    else
478      elm_drop_target_del(obj);
479 }
480
481 Eina_Bool
482 _els_smart_icon_edit_get(const Evas_Object *obj)
483 {
484    Smart_Data *sd; sd = evas_object_smart_data_get(obj);
485    if (!sd) return EINA_FALSE;
486    return sd->edit;
487 }
488
489 Evas_Object *
490 _els_smart_icon_edje_get(Evas_Object *obj)
491 {
492    Smart_Data *sd = evas_object_smart_data_get(obj);
493    if (!sd) return NULL;
494    if (!sd->edje) return NULL;
495    return sd->obj;
496 }
497
498 void
499 _els_smart_icon_aspect_fixed_set(Evas_Object *obj, Eina_Bool fixed)
500 {
501    Smart_Data *sd;
502
503    sd = evas_object_smart_data_get(obj);
504    if (!sd) return;
505
506    fixed = !!fixed;
507    if (sd->aspect_fixed == fixed) return;
508    sd->aspect_fixed = fixed;
509    _smart_reconfigure(sd);
510 }
511
512 Eina_Bool
513 _els_smart_icon_aspect_fixed_get(const Evas_Object *obj)
514 {
515    Smart_Data *sd;
516
517    sd = evas_object_smart_data_get(obj);
518    if (!sd) return EINA_FALSE;
519    return sd->aspect_fixed;
520 }
521
522 /* local subsystem globals */
523 static void
524 _smart_reconfigure(Smart_Data *sd)
525 {
526    Evas_Coord x, y, w, h;
527    const char *type;
528
529    if (!sd->obj) return;
530
531    w = sd->w;
532    h = sd->h;
533
534    type = evas_object_type_get(sd->obj);
535    if (!type) return;
536    if (!strcmp(type, "edje"))
537      {
538         x = sd->x;
539         y = sd->y;
540         evas_object_move(sd->obj, x, y);
541         evas_object_resize(sd->obj, w, h);
542      }
543    else
544      {
545         int iw = 0, ih = 0;
546         double alignh = 0.5, alignv = 0.5;
547         Evas_Object *parent;
548
549         evas_object_image_size_get(sd->obj, &iw, &ih);
550
551         iw = ((double)iw) * sd->scale;
552         ih = ((double)ih) * sd->scale;
553
554         if (iw < 1) iw = 1;
555         if (ih < 1) ih = 1;
556
557         if (sd->aspect_fixed)
558           {
559              h = ((double)ih * w) / (double)iw;
560              if (sd->fill_inside)
561                {
562                   if (h > sd->h)
563                     {
564                        h = sd->h;
565                        w = ((double)iw * h) / (double)ih;
566                     }
567                }
568              else
569                {
570                   if (h < sd->h)
571                     {
572                        h = sd->h;
573                        w = ((double)iw * h) / (double)ih;
574                     }
575                }
576           }
577         if (!sd->scale_up)
578           {
579              if (w > iw) w = iw;
580              if (h > ih) h = ih;
581           }
582         if (!sd->scale_down)
583           {
584              if (w < iw) w = iw;
585              if (h < ih) h = ih;
586           }
587         parent = elm_widget_parent_widget_get(sd->obj);
588         if (parent)
589           evas_object_size_hint_align_get(parent, &alignh, &alignv);
590         if (alignh == EVAS_HINT_FILL) alignh = 0.5;
591         if (alignv == EVAS_HINT_FILL) alignv = 0.5;
592         x = sd->x + ((sd->w - w) * alignh);
593         y = sd->y + ((sd->h - h) * alignv);
594         evas_object_move(sd->obj, x, y);
595         evas_object_image_fill_set(sd->obj, 0, 0, w, h);
596         evas_object_resize(sd->obj, w, h);
597      }
598 }
599
600 static void
601 _smart_init(void)
602 {
603    if (_e_smart) return;
604      {
605         static const Evas_Smart_Class sc =
606           {
607              "e_icon",
608              EVAS_SMART_CLASS_VERSION,
609              _smart_add,
610              _smart_del,
611              _smart_move,
612              _smart_resize,
613              _smart_show,
614              _smart_hide,
615              _smart_color_set,
616              _smart_clip_set,
617              _smart_clip_unset,
618              NULL,
619              NULL,
620              NULL,
621              NULL,
622              NULL,
623              NULL,
624              NULL
625           };
626         _e_smart = evas_smart_class_new(&sc);
627      }
628 }
629
630 static void
631 _smart_add(Evas_Object *obj)
632 {
633    Smart_Data *sd;
634
635    sd = calloc(1, sizeof(Smart_Data));
636    if (!sd) return;
637    sd->obj = evas_object_image_add(evas_object_evas_get(obj));
638    sd->prev = NULL;
639    evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
640    sd->x = 0;
641    sd->y = 0;
642    sd->w = 0;
643    sd->h = 0;
644    sd->fill_inside = EINA_TRUE;
645    sd->scale_up = EINA_TRUE;
646    sd->scale_down = EINA_TRUE;
647    sd->aspect_fixed = EINA_TRUE;
648    sd->size = 64;
649    sd->scale = 1.0;
650    evas_object_smart_member_add(sd->obj, obj);
651    evas_object_smart_data_set(obj, sd);
652    evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED,
653                                   _preloaded, sd);
654 }
655
656 static void
657 _smart_del(Evas_Object *obj)
658 {
659    Smart_Data *sd;
660
661    sd = evas_object_smart_data_get(obj);
662    if (!sd) return;
663    evas_object_del(sd->obj);
664    if (sd->prev) evas_object_del(sd->prev);
665    free(sd);
666 }
667
668 static void
669 _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
670 {
671    Smart_Data *sd;
672
673    sd = evas_object_smart_data_get(obj);
674    if (!sd) return;
675    if ((sd->x == x) && (sd->y == y)) return;
676    sd->x = x;
677    sd->y = y;
678    _smart_reconfigure(sd);
679 }
680
681 static void
682 _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
683 {
684    Smart_Data *sd;
685
686    sd = evas_object_smart_data_get(obj);
687    if (!sd) return;
688    if ((sd->w == w) && (sd->h == h)) return;
689    sd->w = w;
690    sd->h = h;
691    _smart_reconfigure(sd);
692 }
693
694 static void
695 _smart_show(Evas_Object *obj)
696 {
697    Smart_Data *sd;
698
699    sd = evas_object_smart_data_get(obj);
700    if (!sd) return;
701    sd->show = EINA_TRUE;
702    if (!sd->preloading)
703      {
704         evas_object_show(sd->obj);
705         if (sd->prev) evas_object_del(sd->prev);
706         sd->prev = NULL;
707      }
708 }
709
710 static void
711 _smart_hide(Evas_Object *obj)
712 {
713    Smart_Data *sd;
714
715    sd = evas_object_smart_data_get(obj);
716    if (!sd) return;
717    sd->show = EINA_FALSE;
718    evas_object_hide(sd->obj);
719    if (sd->prev) evas_object_del(sd->prev);
720    sd->prev = NULL;
721 }
722
723 static void
724 _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
725 {
726    Smart_Data *sd;
727
728    sd = evas_object_smart_data_get(obj);
729    if (!sd) return;
730    evas_object_color_set(sd->obj, r, g, b, a);
731    if (sd->prev) evas_object_color_set(sd->prev, r, g, b, a);
732 }
733
734 static void
735 _smart_clip_set(Evas_Object *obj, Evas_Object * clip)
736 {
737    Smart_Data *sd;
738
739    sd = evas_object_smart_data_get(obj);
740    if (!sd) return;
741    evas_object_clip_set(sd->obj, clip);
742    if (sd->prev) evas_object_clip_set(sd->prev, clip);
743 }
744
745 static void
746 _smart_clip_unset(Evas_Object *obj)
747 {
748    Smart_Data *sd;
749
750    sd = evas_object_smart_data_get(obj);
751    if (!sd) return;
752    evas_object_clip_unset(sd->obj);
753    if (sd->prev) evas_object_clip_unset(sd->prev);
754 }
755
756 static void
757 _els_smart_icon_flip_horizontal(Smart_Data *sd)
758 {
759    unsigned int   *data;
760    unsigned int   *p1, *p2, tmp;
761    int             x, y, iw, ih;
762
763    evas_object_image_size_get(sd->obj, &iw, &ih);
764    data = evas_object_image_data_get(sd->obj, EINA_TRUE);
765
766    for (y = 0; y < ih; y++)
767      {
768         p1 = data + (y * iw);
769         p2 = data + ((y + 1) * iw) - 1;
770         for (x = 0; x < (iw >> 1); x++)
771           {
772              tmp = *p1;
773              *p1 = *p2;
774              *p2 = tmp;
775              p1++;
776              p2--;
777           }
778      }
779
780    evas_object_image_data_set(sd->obj, data);
781    evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
782    _smart_reconfigure(sd);
783 }
784
785 static void
786 _els_smart_icon_flip_vertical(Smart_Data *sd)
787 {
788    unsigned int   *data;
789    unsigned int   *p1, *p2, tmp;
790    int             x, y, iw, ih;
791
792    evas_object_image_size_get(sd->obj, &iw, &ih);
793    data = evas_object_image_data_get(sd->obj, EINA_TRUE);
794
795    for (y = 0; y < (ih >> 1); y++)
796      {
797         p1 = data + (y * iw);
798         p2 = data + ((ih - 1 - y) * iw);
799         for (x = 0; x < iw; x++)
800           {
801              tmp = *p1;
802              *p1 = *p2;
803              *p2 = tmp;
804              p1++;
805              p2++;
806           }
807      }
808
809    evas_object_image_data_set(sd->obj, data);
810    evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
811    _smart_reconfigure(sd);
812 }
813
814 static void
815 _els_smart_icon_rotate_180(Smart_Data *sd)
816 {
817    unsigned int   *data;
818    unsigned int   *p1, *p2, tmp;
819    int             x, hw, iw, ih;
820
821    evas_object_image_size_get(sd->obj, &iw, &ih);
822    data = evas_object_image_data_get(sd->obj, 1);
823
824    hw = iw * ih;
825    x = (hw / 2);
826    p1 = data;
827    p2 = data + hw - 1;
828    for (; --x > 0;)
829      {
830         tmp = *p1;
831         *p1 = *p2;
832         *p2 = tmp;
833         p1++;
834         p2--;
835      }
836    evas_object_image_data_set(sd->obj, data);
837    evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
838    _smart_reconfigure(sd);
839 }
840
841 static Eina_Bool
842 _els_smart_icon_dropcb(void *elmobj,Evas_Object *obj, Elm_Selection_Data *drop)
843 {
844    _els_smart_icon_file_key_set(obj, drop->data, NULL);
845    evas_object_smart_callback_call(elmobj, "drop", drop->data);
846
847    return EINA_TRUE;
848 }
849 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/