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