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