Merge branch 'master' of eunmi15.lee@165.213.180.234:/git/slp/pkgs/elementary
[framework/uifw/elementary.git] / src / lib / els_icon.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 typedef struct _Smart_Data Smart_Data;
5
6 struct _Smart_Data
7 {
8    Evas_Coord   x, y, w, h;
9    Evas_Object *obj;
10    int          size;
11    double       scale;
12    unsigned char fill_inside : 1;
13    unsigned char scale_up : 1;
14    unsigned char scale_down : 1;
15    unsigned char preloading : 1;
16    unsigned char show : 1;
17 };
18
19 /* local subsystem functions */
20 static void _smart_reconfigure(Smart_Data *sd);
21 static void _smart_init(void);
22 static void _smart_add(Evas_Object *obj);
23 static void _smart_del(Evas_Object *obj);
24 static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
25 static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
26 static void _smart_show(Evas_Object *obj);
27 static void _smart_hide(Evas_Object *obj);
28 static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
29 static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
30 static void _smart_clip_unset(Evas_Object *obj);
31
32 static void _els_smart_icon_flip_horizontal(Smart_Data *sd);
33 static void _els_smart_icon_flip_vertical(Smart_Data *sd);
34 static void _els_smart_icon_rotate_180(Smart_Data *sd);
35
36 /* local subsystem globals */
37 static Evas_Smart *_e_smart = NULL;
38
39 /* externally accessible functions */
40 Evas_Object *
41 _els_smart_icon_add(Evas *evas)
42 {
43    _smart_init();
44    return evas_object_smart_add(evas, _e_smart);
45 }
46
47 Eina_Bool
48 _els_smart_icon_file_key_set(Evas_Object *obj, const char *file, const char *key)
49 {
50    Smart_Data *sd;
51
52    sd = evas_object_smart_data_get(obj);
53    if (!sd) return EINA_FALSE;
54    /* smart code here */
55    if (sd->size != 0)
56      evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
57    evas_object_image_file_set(sd->obj, file, key);
58    sd->preloading = 1;
59    evas_object_image_preload(sd->obj, EINA_FALSE);
60    evas_object_hide(sd->obj);
61    if (evas_object_image_load_error_get(sd->obj) != EVAS_LOAD_ERROR_NONE)
62      return EINA_FALSE;
63    _smart_reconfigure(sd);
64    return EINA_TRUE;
65 }
66
67 Eina_Bool
68 _els_smart_icon_file_edje_set(Evas_Object *obj, const char *file, const char *part)
69 {
70    Smart_Data *sd;
71
72    sd = evas_object_smart_data_get(obj);
73    if (!sd) return EINA_FALSE;
74    /* smart code here */
75    if (sd->obj) evas_object_del(sd->obj);
76    sd->obj = edje_object_add(evas_object_evas_get(obj));
77    evas_object_smart_member_add(sd->obj, obj);
78    if (!edje_object_file_set(sd->obj, file, part))
79      return EINA_FALSE;
80    _smart_reconfigure(sd);
81    return EINA_TRUE;
82 }
83
84 void
85 _els_smart_icon_smooth_scale_set(Evas_Object *obj, int smooth)
86 {
87    Smart_Data *sd;
88
89    sd = evas_object_smart_data_get(obj);
90    if (!sd) return;
91    if (!strcmp(evas_object_type_get(sd->obj), "edje"))
92      return;
93    evas_object_image_smooth_scale_set(sd->obj, smooth);
94 }
95
96 Evas_Object *
97 _els_smart_icon_object_get(Evas_Object *obj)
98 {
99    Smart_Data *sd;
100    sd = evas_object_smart_data_get(obj);
101    if (!sd) return NULL;
102    return sd->obj;
103 }
104
105 void
106 _els_smart_icon_size_get(Evas_Object *obj, int *w, int *h)
107 {
108    Smart_Data *sd;
109    int tw, th;
110
111    sd = evas_object_smart_data_get(obj);
112    if (!sd) return;
113    if (!strcmp(evas_object_type_get(sd->obj), "edje"))
114      edje_object_size_min_get(sd->obj, &tw, &th);
115    else
116      evas_object_image_size_get(sd->obj, &tw, &th);
117    tw = ((double)tw) * sd->scale;
118    th = ((double)th) * sd->scale;
119    if (w) *w = tw;
120    if (h) *h = th;
121 }
122
123 void
124 _els_smart_icon_fill_inside_set(Evas_Object *obj, int fill_inside)
125 {
126    Smart_Data *sd;
127
128    sd = evas_object_smart_data_get(obj);
129    if (!sd) return;
130    if (((sd->fill_inside) && (fill_inside)) ||
131        ((!sd->fill_inside) && (!fill_inside))) return;
132    sd->fill_inside = fill_inside;
133    _smart_reconfigure(sd);
134 }
135
136 void
137 _els_smart_icon_scale_up_set(Evas_Object *obj, int scale_up)
138 {
139    Smart_Data *sd;
140
141    sd = evas_object_smart_data_get(obj);
142    if (!sd) return;
143    if (((sd->scale_up) && (scale_up)) ||
144        ((!sd->scale_up) && (!scale_up))) return;
145    sd->scale_up = scale_up;
146    _smart_reconfigure(sd);
147 }
148
149 void
150 _els_smart_icon_scale_down_set(Evas_Object *obj, int scale_down)
151 {
152    Smart_Data *sd;
153
154    sd = evas_object_smart_data_get(obj);
155    if (!sd) return;
156    if (((sd->scale_down) && (scale_down)) ||
157        ((!sd->scale_down) && (!scale_down))) return;
158    sd->scale_down = scale_down;
159    _smart_reconfigure(sd);
160 }
161
162 void
163 _els_smart_icon_scale_size_set(Evas_Object *obj, int size)
164 {
165    Smart_Data *sd;
166
167    sd = evas_object_smart_data_get(obj);
168    if (!sd) return;
169    sd->size = size;
170    if (!sd->obj) return;
171    if (!strcmp(evas_object_type_get(sd->obj), "edje"))
172      return;
173    evas_object_image_load_size_set(sd->obj, sd->size, sd->size);
174 }
175
176 void
177 _els_smart_icon_scale_set(Evas_Object *obj, double scale)
178 {
179    Smart_Data *sd;
180
181    sd = evas_object_smart_data_get(obj);
182    if (!sd) return;
183    sd->scale = scale;
184    _smart_reconfigure(sd);
185 }
186
187 void
188 _els_smart_icon_orient_set(Evas_Object *obj, Elm_Image_Orient orient)
189 {
190    Smart_Data *sd;
191    Evas_Object    *tmp;
192    unsigned int   *data, *data2, *to, *from;
193    int             x, y, w, hw, iw, ih;
194    const char     *file, *key;
195
196    sd = evas_object_smart_data_get(obj);
197    if (!sd) return;
198    if (!strcmp(evas_object_type_get(sd->obj), "edje"))
199      return;
200
201    switch (orient)
202      {
203       case ELM_IMAGE_FLIP_HORIZONTAL:
204          _els_smart_icon_flip_horizontal(sd);
205          return;
206       case ELM_IMAGE_FLIP_VERTICAL:
207          _els_smart_icon_flip_vertical(sd);
208          return;
209       case ELM_IMAGE_ROTATE_180_CW:
210          _els_smart_icon_rotate_180(sd);
211          return;
212      default:
213         return;
214      }
215
216    evas_object_image_size_get(sd->obj, &iw, &ih);
217    evas_object_image_file_get(sd->obj, &file, &key);
218    tmp = evas_object_image_add(evas_object_evas_get(sd->obj));
219    evas_object_image_file_set(tmp, file, key);
220    data2 = evas_object_image_data_get(tmp, 0);
221
222    w = ih;
223    ih = iw;
224    iw = w;
225    hw = w * ih;
226
227    evas_object_image_size_set(sd->obj, iw, ih);
228    data = evas_object_image_data_get(sd->obj, 1);
229    switch (orient)
230      {
231       case ELM_IMAGE_FLIP_TRANSPOSE:
232          to = data;
233          hw = -hw + 1;
234          break;
235       case ELM_IMAGE_FLIP_TRANSVERSE:
236          to = data + hw - 1;
237          w = -w;
238          hw = hw - 1;
239          break;
240       case ELM_IMAGE_ROTATE_90_CW:
241          to = data + w - 1;
242          hw = -hw - 1;
243          break;
244       case ELM_IMAGE_ROTATE_90_CCW:
245          to = data + hw - w;
246          w = -w;
247          hw = hw + 1;
248          break;
249       default:
250          ERR("unknown orient %d", orient);
251          evas_object_del(tmp);
252          evas_object_image_data_set(sd->obj, data); // give it back
253          return;
254      }
255    from = data2;
256    for (x = iw; --x >= 0;)
257      {
258         for (y = ih; --y >= 0;)
259           {
260              *to = *from;
261              from++;
262              to += w;
263           }
264         to += hw;
265      }
266    evas_object_del(tmp);
267    evas_object_image_data_set(sd->obj, data);
268    evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
269    _smart_reconfigure(sd);
270 }
271
272 /* local subsystem globals */
273 static void
274 _smart_reconfigure(Smart_Data *sd)
275 {
276    int iw, ih;
277    Evas_Coord x, y, w, h;
278
279    if (!sd->obj) return;
280    if (!strcmp(evas_object_type_get(sd->obj), "edje"))
281      {
282         w = sd->w;
283         h = sd->h;
284         x = sd->x;
285         y = sd->y;
286         evas_object_move(sd->obj, x, y);
287         evas_object_resize(sd->obj, w, h);
288      }
289    else
290      {
291         iw = 0;
292         ih = 0;
293         evas_object_image_size_get(sd->obj, &iw, &ih);
294
295         iw = ((double)iw) * sd->scale;
296         ih = ((double)ih) * sd->scale;
297
298         if (iw < 1) iw = 1;
299         if (ih < 1) ih = 1;
300
301         if (sd->fill_inside)
302           {
303              w = sd->w;
304              h = ((double)ih * w) / (double)iw;
305              if (h > sd->h)
306                {
307                   h = sd->h;
308                   w = ((double)iw * h) / (double)ih;
309                }
310           }
311         else
312           {
313              w = sd->w;
314              h = ((double)ih * w) / (double)iw;
315              if (h < sd->h)
316                {
317                   h = sd->h;
318                   w = ((double)iw * h) / (double)ih;
319                }
320           }
321         if (!sd->scale_up)
322           {
323              if ((w > iw) || (h > ih))
324                {
325                   w = iw;
326                   h = ih;
327                }
328           }
329         if (!sd->scale_down)
330           {
331              if ((w < iw) || (h < ih))
332                {
333                   w = iw;
334                   h = ih;
335                }
336           }
337         x = sd->x + ((sd->w - w) / 2);
338         y = sd->y + ((sd->h - h) / 2);
339         evas_object_move(sd->obj, x, y);
340         evas_object_image_fill_set(sd->obj, 0, 0, w, h);
341         evas_object_resize(sd->obj, w, h);
342      }
343 }
344
345 static void
346 _preloaded(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
347 {
348    Smart_Data *sd = data;
349
350    sd->preloading = 0;
351    if(sd->show)
352      evas_object_show(sd->obj);
353 }
354
355 static void
356 _smart_init(void)
357 {
358    if (_e_smart) return;
359      {
360         static const Evas_Smart_Class sc =
361           {
362              "e_icon",
363                EVAS_SMART_CLASS_VERSION,
364                _smart_add,
365                _smart_del,
366                _smart_move,
367                _smart_resize,
368                _smart_show,
369                _smart_hide,
370                _smart_color_set,
371                _smart_clip_set,
372                _smart_clip_unset,
373                NULL,
374                NULL,
375                NULL,
376                NULL,
377                NULL,
378                NULL,
379                NULL
380           };
381         _e_smart = evas_smart_class_new(&sc);
382      }
383 }
384
385 static void
386 _smart_add(Evas_Object *obj)
387 {
388    Smart_Data *sd;
389
390    sd = calloc(1, sizeof(Smart_Data));
391    if (!sd) return;
392    sd->obj = evas_object_image_add(evas_object_evas_get(obj));
393    evas_object_image_scale_hint_set(sd->obj, EVAS_IMAGE_SCALE_HINT_STATIC);
394    sd->x = 0;
395    sd->y = 0;
396    sd->w = 0;
397    sd->h = 0;
398    sd->fill_inside = 1;
399    sd->scale_up = 1;
400    sd->scale_down = 1;
401    sd->size = 64;
402    sd->scale = 1.0;
403    evas_object_smart_member_add(sd->obj, obj);
404    evas_object_smart_data_set(obj, sd);
405    evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_IMAGE_PRELOADED, _preloaded, sd);
406 }
407
408 static void
409 _smart_del(Evas_Object *obj)
410 {
411    Smart_Data *sd;
412
413    sd = evas_object_smart_data_get(obj);
414    if (!sd) return;
415    evas_object_del(sd->obj);
416    free(sd);
417 }
418
419 static void
420 _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
421 {
422    Smart_Data *sd;
423
424    sd = evas_object_smart_data_get(obj);
425    if (!sd) return;
426    if ((sd->x == x) && (sd->y == y)) return;
427    sd->x = x;
428    sd->y = y;
429    _smart_reconfigure(sd);
430 }
431
432 static void
433 _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
434 {
435    Smart_Data *sd;
436
437    sd = evas_object_smart_data_get(obj);
438    if (!sd) return;
439    if ((sd->w == w) && (sd->h == h)) return;
440    sd->w = w;
441    sd->h = h;
442    _smart_reconfigure(sd);
443 }
444
445 static void
446 _smart_show(Evas_Object *obj)
447 {
448    Smart_Data *sd;
449
450    sd = evas_object_smart_data_get(obj);
451    if (!sd) return;
452    sd->show = 1;
453    if(!sd->preloading)
454            evas_object_show(sd->obj);
455 }
456
457 static void
458 _smart_hide(Evas_Object *obj)
459 {
460    Smart_Data *sd;
461
462    sd = evas_object_smart_data_get(obj);
463    if (!sd) return;
464    sd->show = 0;
465    evas_object_hide(sd->obj);
466 }
467
468 static void
469 _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
470 {
471    Smart_Data *sd;
472
473    sd = evas_object_smart_data_get(obj);
474    if (!sd) return;
475    evas_object_color_set(sd->obj, r, g, b, a);
476 }
477
478 static void
479 _smart_clip_set(Evas_Object *obj, Evas_Object * clip)
480 {
481    Smart_Data *sd;
482
483    sd = evas_object_smart_data_get(obj);
484    if (!sd) return;
485    evas_object_clip_set(sd->obj, clip);
486 }
487
488 static void
489 _smart_clip_unset(Evas_Object *obj)
490 {
491    Smart_Data *sd;
492
493    sd = evas_object_smart_data_get(obj);
494    if (!sd) return;
495    evas_object_clip_unset(sd->obj);
496 }
497
498 static void
499 _els_smart_icon_flip_horizontal(Smart_Data *sd)
500 {
501    unsigned int   *data;
502    unsigned int   *p1, *p2, tmp;
503    int             x, y, iw, ih;
504
505    evas_object_image_size_get(sd->obj, &iw, &ih);
506    data = evas_object_image_data_get(sd->obj, 1);
507
508    for (y = 0; y < ih; y++)
509      {
510         p1 = data + (y * iw);
511         p2 = data + ((y + 1) * iw) - 1;
512         for (x = 0; x < (iw >> 1); x++)
513           {
514              tmp = *p1;
515              *p1 = *p2;
516              *p2 = tmp;
517              p1++;
518              p2--;
519           }
520      }
521
522    evas_object_image_data_set(sd->obj, data);
523    evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
524    _smart_reconfigure(sd);
525 }
526
527 static void
528 _els_smart_icon_flip_vertical(Smart_Data *sd)
529 {
530    unsigned int   *data;
531    unsigned int   *p1, *p2, tmp;
532    int             x, y, iw, ih;
533
534    evas_object_image_size_get(sd->obj, &iw, &ih);
535    data = evas_object_image_data_get(sd->obj, 1);
536
537    for (y = 0; y < (ih >> 1); y++)
538      {
539         p1 = data + (y * iw);
540         p2 = data + ((ih - 1 - y) * iw);
541         for (x = 0; x < iw; x++)
542           {
543              tmp = *p1;
544              *p1 = *p2;
545              *p2 = tmp;
546              p1++;
547              p2++;
548           }
549      }
550
551    evas_object_image_data_set(sd->obj, data);
552    evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
553    _smart_reconfigure(sd);
554 }
555
556 static void
557 _els_smart_icon_rotate_180(Smart_Data *sd)
558 {
559    unsigned int   *data;
560    unsigned int   *p1, *p2, tmp;
561    int             x, hw, iw, ih;
562
563    evas_object_image_size_get(sd->obj, &iw, &ih);
564    data = evas_object_image_data_get(sd->obj, 1);
565
566    hw = iw * ih;
567    x = (hw / 2);
568    p1 = data;
569    p2 = data + hw - 1;
570    for (; --x > 0;)
571      {
572         tmp = *p1;
573         *p1 = *p2;
574         *p2 = tmp;
575         p1++;
576         p2--;
577      }
578    evas_object_image_data_set(sd->obj, data);
579    evas_object_image_data_update_add(sd->obj, 0, 0, iw, ih);
580    _smart_reconfigure(sd);
581 }
582