Initialize Tizen 2.3
[framework/uifw/elementary.git] / wearable / src / lib / elm_icon.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "elm_widget_icon.h"
4
5 #ifdef ELM_EFREET
6 #define NON_EXISTING (void *)-1
7 static const char *icon_theme = NULL;
8 #endif
9
10 EAPI const char ELM_ICON_SMART_NAME[] = "elm_icon";
11
12 #ifdef HAVE_ELEMENTARY_ETHUMB
13 static Eina_List *_elm_icon_retry = NULL;
14 static int _icon_pending_request = 0;
15 #endif
16
17 static const char SIG_THUMB_DONE[] = "thumb,done";
18 static const char SIG_THUMB_ERROR[] = "thumb,error";
19 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
20    {SIG_THUMB_DONE, ""},
21    {SIG_THUMB_ERROR, ""},
22    {NULL, NULL}
23 };
24
25 EVAS_SMART_SUBCLASS_NEW
26   (ELM_ICON_SMART_NAME, _elm_icon, Elm_Icon_Smart_Class,
27   Elm_Image_Smart_Class, elm_image_smart_class_get, _smart_callbacks);
28
29 /* FIXME: move this code to ecore */
30 #ifdef _WIN32
31 static Eina_Bool
32 _path_is_absolute(const char *path)
33 {
34    //TODO: Check if this works with all absolute paths in windows
35    return (isalpha(*path)) && (*(path + 1) == ':') &&
36           ((*(path + 2) == '\\') || (*(path + 2) == '/'));
37 }
38
39 #else
40 static Eina_Bool
41 _path_is_absolute(const char *path)
42 {
43    return *path == '/';
44 }
45
46 #endif
47
48 static inline int
49 _icon_size_min_get(Evas_Object *icon)
50 {
51    int size;
52
53    elm_image_object_size_get(icon, &size, NULL);
54
55    return (size < 16) ? 16 : size;
56 }
57
58 #ifdef HAVE_ELEMENTARY_ETHUMB
59 static void
60 _icon_thumb_stop(Elm_Icon_Smart_Data *sd,
61                  void *ethumbd)
62 {
63    if (sd->thumb.request)
64      {
65         ethumb_client_thumb_async_cancel(ethumbd, sd->thumb.request);
66         sd->thumb.request = NULL;
67         _icon_pending_request--;
68      }
69
70    if (sd->thumb.retry)
71      {
72         _elm_icon_retry = eina_list_remove(_elm_icon_retry, sd);
73         sd->thumb.retry = EINA_FALSE;
74      }
75 }
76
77 static Eina_Bool
78 _icon_thumb_display(Elm_Icon_Smart_Data *sd)
79 {
80    Eina_Bool ret = EINA_FALSE;
81
82    if (sd->thumb.format == ETHUMB_THUMB_EET)
83      {
84         int prefix_size;
85         const char **ext, *ptr;
86         static const char *extensions[] =
87         {
88            ".avi", ".mp4", ".ogv", ".mov", ".mpg", ".wmv", NULL
89         };
90
91         prefix_size = eina_stringshare_strlen(sd->thumb.file.path) - 4;
92         if (prefix_size >= 0)
93           {
94              ptr = sd->thumb.file.path + prefix_size;
95              for (ext = extensions; *ext; ++ext)
96                if (!strcasecmp(ptr, *ext))
97                  {
98                     sd->is_video = EINA_TRUE;
99                     break;
100                  }
101           }
102
103         ret = elm_image_file_set
104             (ELM_WIDGET_DATA(sd)->obj, sd->thumb.thumb.path,
105             sd->thumb.thumb.key);
106
107         sd->is_video = EINA_FALSE;
108      }
109
110    if (!ret)
111      ret = elm_image_file_set
112          (ELM_WIDGET_DATA(sd)->obj, sd->thumb.thumb.path, sd->thumb.thumb.key);
113
114    if (ret)
115      evas_object_smart_callback_call
116        (ELM_WIDGET_DATA(sd)->obj, SIG_THUMB_DONE, NULL);
117    else
118      evas_object_smart_callback_call
119        (ELM_WIDGET_DATA(sd)->obj, SIG_THUMB_ERROR, NULL);
120
121    return ret;
122 }
123
124 static Eina_Bool
125 _icon_thumb_retry(Elm_Icon_Smart_Data *sd)
126 {
127    return _icon_thumb_display(sd);
128 }
129
130 static void
131 _icon_thumb_cleanup(Ethumb_Client *ethumbd)
132 {
133    Eina_List *l, *ll;
134    Elm_Icon_Smart_Data *sd;
135
136    EINA_LIST_FOREACH_SAFE(_elm_icon_retry, l, ll, sd)
137      if (_icon_thumb_retry(sd))
138        {
139           _elm_icon_retry = eina_list_remove_list(_elm_icon_retry, l);
140           sd->thumb.retry = EINA_FALSE;
141        }
142
143    if (_icon_pending_request == 0)
144      EINA_LIST_FREE (_elm_icon_retry, sd)
145        _icon_thumb_stop(sd, ethumbd);
146 }
147
148 static void
149 _icon_thumb_finish(Elm_Icon_Smart_Data *sd,
150                    Ethumb_Client *ethumbd)
151 {
152    const char *file = NULL, *group = NULL;
153    Eina_Bool ret;
154
155    elm_image_file_get(ELM_WIDGET_DATA(sd)->obj, &file, &group);
156    file = eina_stringshare_ref(file);
157    group = eina_stringshare_ref(group);
158
159    ret = _icon_thumb_display(sd);
160
161    if (!ret && file)
162      {
163         if (!sd->thumb.retry)
164           {
165              _elm_icon_retry = eina_list_append(_elm_icon_retry, sd);
166              sd->thumb.retry = EINA_TRUE;
167           }
168
169         /* Back to previous image */
170         elm_image_file_set(ELM_WIDGET_DATA(sd)->obj, file, group);
171      }
172
173    _icon_thumb_cleanup(ethumbd);
174
175    eina_stringshare_del(file);
176    eina_stringshare_del(group);
177 }
178
179 static void
180 _icon_thumb_done(Ethumb_Client *client,
181                  const char *thumb_path,
182                  const char *thumb_key,
183                  void *data)
184 {
185    Elm_Icon_Smart_Data *sd = data;
186
187    if (EINA_UNLIKELY(!sd->thumb.request))
188      {
189         ERR("Something odd happened with a thumbnail request");
190         return;
191      }
192
193    _icon_pending_request--;
194    sd->thumb.request = NULL;
195
196    eina_stringshare_replace(&sd->thumb.thumb.path, thumb_path);
197    eina_stringshare_replace(&sd->thumb.thumb.key, thumb_key);
198    sd->thumb.format = ethumb_client_format_get(client);
199
200    _icon_thumb_finish(sd, client);
201 }
202
203 static void
204 _icon_thumb_error(Ethumb_Client *client,
205                   void *data)
206 {
207    Elm_Icon_Smart_Data *sd = data;
208
209    if (EINA_UNLIKELY(!sd->thumb.request))
210      {
211         ERR("Something odd happened with a thumbnail request");
212         return;
213      }
214
215    _icon_pending_request--;
216    sd->thumb.request = NULL;
217
218    ERR("could not generate thumbnail for %s (key: %s)",
219        sd->thumb.file.path, sd->thumb.file.key);
220
221    evas_object_smart_callback_call(ELM_WIDGET_DATA(sd)->obj, SIG_THUMB_ERROR, NULL);
222
223    _icon_thumb_cleanup(client);
224 }
225
226 static void
227 _icon_thumb_apply(Elm_Icon_Smart_Data *sd)
228 {
229    Ethumb_Client *ethumbd;
230    int min_size;
231
232    ethumbd = elm_thumb_ethumb_client_get();
233
234    _icon_thumb_stop(sd, ethumbd);
235
236    if (!sd->thumb.file.path) return;
237
238    _icon_pending_request++;
239    if (!ethumb_client_file_set
240          (ethumbd, sd->thumb.file.path, sd->thumb.file.key)) return;
241
242    min_size = _icon_size_min_get(ELM_WIDGET_DATA(sd)->obj);
243    ethumb_client_size_set(ethumbd, min_size, min_size);
244
245    sd->thumb.request = ethumb_client_thumb_async_get
246        (ethumbd, _icon_thumb_done, _icon_thumb_error, sd);
247 }
248
249 static Eina_Bool
250 _icon_thumb_apply_cb(void *data,
251                      int type __UNUSED__,
252                      void *ev __UNUSED__)
253 {
254    Elm_Icon_Smart_Data *sd = data;
255
256    _icon_thumb_apply(sd);
257
258    return ECORE_CALLBACK_RENEW;
259 }
260
261 #endif
262
263 static Eina_Bool
264 #ifdef ELM_EFREET
265 _icon_freedesktop_set(Evas_Object *obj,
266                       const char *name,
267                       int size)
268 #else
269 _icon_freedesktop_set(Evas_Object * obj __UNUSED__,
270                       const char *name __UNUSED__,
271                       int size __UNUSED__)
272 #endif
273 {
274 #ifdef ELM_EFREET
275    const char *path;
276
277    ELM_ICON_DATA_GET(obj, sd);
278
279    elm_need_efreet();
280
281    if (icon_theme == NON_EXISTING) return EINA_FALSE;
282
283    if (!icon_theme)
284      {
285         Efreet_Icon_Theme *theme;
286         /* TODO: Listen for EFREET_EVENT_ICON_CACHE_UPDATE */
287         theme = efreet_icon_theme_find(getenv("E_ICON_THEME"));
288         if (!theme)
289           {
290              const char **itr;
291              static const char *themes[] = {
292                 "gnome", "Human", "oxygen", "hicolor", NULL
293              };
294              for (itr = themes; *itr; itr++)
295                {
296                   theme = efreet_icon_theme_find(*itr);
297                   if (theme) break;
298                }
299           }
300
301         if (!theme)
302           {
303              icon_theme = NON_EXISTING;
304              return EINA_FALSE;
305           }
306         else
307           icon_theme = eina_stringshare_add(theme->name.internal);
308      }
309    path = efreet_icon_path_find(icon_theme, name, size);
310    sd->freedesktop.use = !!path;
311    if (sd->freedesktop.use)
312      {
313         sd->freedesktop.requested_size = size;
314         elm_image_file_set(obj, path, NULL);
315         return EINA_TRUE;
316      }
317 #endif
318    return EINA_FALSE;
319 }
320
321 static void
322 _elm_icon_smart_sizing_eval(Evas_Object *obj)
323 {
324    int w, h;
325
326    ELM_ICON_DATA_GET(obj, sd);
327
328    if (sd->in_eval) return;
329
330    sd->in_eval++;
331    elm_image_object_size_get(obj, &w, &h);
332
333 #ifdef ELM_EFREET
334    if (sd->freedesktop.use && sd->stdicon)
335      {
336         int size;
337         /* This icon has been set to a freedesktop icon, and the requested
338            appears to have a different size than the requested size, so try to
339            request another, higher resolution, icon.
340            FIXME: Find a better heuristic to determine if there should be
341            an icon with a different resolution. */
342         size = ((w / 16) + 1) * 16;
343         _icon_freedesktop_set(obj, sd->stdicon, size);
344      }
345 #endif
346
347    _elm_icon_parent_sc->sizing_eval(obj);
348
349    sd->in_eval--;
350 }
351
352 static void
353 _edje_signal_callback(void *data,
354                       Evas_Object *obj __UNUSED__,
355                       const char *emission,
356                       const char *source)
357 {
358    Edje_Signal_Data *esd = data;
359
360    esd->func(esd->data, esd->obj, emission, source);
361 }
362
363 static void
364 _edje_signals_free(Elm_Icon_Smart_Data *sd)
365 {
366    Edje_Signal_Data *esd;
367
368    EINA_LIST_FREE (sd->edje_signals, esd)
369      {
370         edje_object_signal_callback_del_full
371            (ELM_IMAGE_DATA(sd)->img, esd->emission, esd->source,
372             _edje_signal_callback, esd);
373         eina_stringshare_del(esd->emission);
374         eina_stringshare_del(esd->source);
375         free(esd);
376      }
377 }
378
379 static Eina_Bool
380 _elm_icon_smart_file_set(Evas_Object *obj,
381                          const char *file,
382                          const char *key)
383 {
384    Evas_Object *pclip;
385
386    ELM_ICON_DATA_GET(obj, sd);
387
388    EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
389
390    _edje_signals_free(sd);
391
392 #ifdef ELM_EFREET
393    if (!sd->freedesktop.use)
394      {
395         if (sd->stdicon) eina_stringshare_del(sd->stdicon);
396         sd->stdicon = NULL;
397      }
398 #endif
399
400    if (!sd->is_video) return _elm_icon_parent_sc->file_set(obj, file, key);
401
402    /* parent's edje file setting path replicated here (we got .eet
403     * extension, so bypassing it) */
404    if (ELM_IMAGE_DATA(sd)->prev_img)
405      evas_object_del(ELM_IMAGE_DATA(sd)->prev_img);
406    ELM_IMAGE_DATA(sd)->prev_img = NULL;
407
408    if (!ELM_IMAGE_DATA(sd)->edje)
409      {
410         pclip = evas_object_clip_get(ELM_IMAGE_DATA(sd)->img);
411         if (ELM_IMAGE_DATA(sd)->img) evas_object_del(ELM_IMAGE_DATA(sd)->img);
412
413         /* Edje object instead */
414         ELM_IMAGE_DATA(sd)->img = edje_object_add(evas_object_evas_get(obj));
415         evas_object_smart_member_add(ELM_IMAGE_DATA(sd)->img, obj);
416         if (ELM_IMAGE_DATA(sd)->show)
417           evas_object_show(ELM_IMAGE_DATA(sd)->img);
418         evas_object_clip_set(ELM_IMAGE_DATA(sd)->img, pclip);
419      }
420
421    ELM_IMAGE_DATA(sd)->edje = EINA_TRUE;
422    if (!edje_object_file_set(ELM_IMAGE_DATA(sd)->img, file, key))
423      {
424         ERR("failed to set edje file '%s', group '%s': %s", file, key,
425             edje_load_error_str
426               (edje_object_load_error_get(ELM_IMAGE_DATA(sd)->img)));
427         return EINA_FALSE;
428      }
429
430    evas_object_move(ELM_IMAGE_DATA(sd)->img, ELM_IMAGE_DATA(sd)->img_x,
431                     ELM_IMAGE_DATA(sd)->img_y);
432    evas_object_resize(ELM_IMAGE_DATA(sd)->img, ELM_IMAGE_DATA(sd)->img_w,
433                       ELM_IMAGE_DATA(sd)->img_h);
434
435    return EINA_TRUE;
436 }
437
438 static Eina_Bool
439 _elm_icon_smart_memfile_set(Evas_Object *obj,
440                             const void *img,
441                             size_t size,
442                             const char *format,
443                             const char *key)
444 {
445    ELM_ICON_DATA_GET(obj, sd);
446
447    Eina_Bool ret;
448
449    EINA_SAFETY_ON_NULL_RETURN_VAL(img, EINA_FALSE);
450    EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, EINA_FALSE);
451    eina_stringshare_del(sd->stdicon);
452    sd->stdicon = NULL;
453
454    _edje_signals_free(sd);
455
456    ret = _elm_icon_parent_sc->memfile_set(obj, img, size, format, key);
457
458    return ret;
459 }
460
461 static Eina_Bool
462 _elm_icon_smart_theme(Evas_Object *obj)
463 {
464    ELM_ICON_DATA_GET(obj, sd);
465
466    if (sd->stdicon)
467      _elm_theme_object_icon_set(obj, sd->stdicon, elm_widget_style_get(obj));
468
469    if (!ELM_WIDGET_CLASS(_elm_icon_parent_sc)->theme(obj))
470      return EINA_FALSE;
471
472    return EINA_TRUE;
473 }
474
475 static Eina_Bool
476 _icon_standard_set(Evas_Object *obj,
477                    const char *name)
478 {
479    ELM_ICON_DATA_GET(obj, sd);
480
481    if (_elm_theme_object_icon_set(obj, name, "default"))
482      {
483 #ifdef ELM_EFREET
484         /* TODO: elm_unneed_efreet() */
485         sd->freedesktop.use = EINA_FALSE;
486 #endif
487         return EINA_TRUE;
488      }
489
490    return EINA_FALSE;
491 }
492
493 static Eina_Bool
494 #ifdef ELM_EFREET
495 _icon_file_set(Elm_Icon_Smart_Data *sd,
496                Evas_Object *obj,
497                const char *path)
498 #else
499 _icon_file_set(Elm_Icon_Smart_Data * sd __UNUSED__,
500                Evas_Object * obj,
501                const char *path)
502 #endif
503 {
504    if (elm_image_file_set(obj, path, NULL))
505      {
506 #ifdef ELM_EFREET
507         /* TODO: elm_unneed_efreet() */
508         sd->freedesktop.use = EINA_FALSE;
509 #endif
510         return EINA_TRUE;
511      }
512    return EINA_FALSE;
513 }
514
515 static Eina_Bool
516 _elm_icon_standard_set(Evas_Object *obj,
517                        const char *name,
518                        Eina_Bool *fdo)
519 {
520    char *tmp;
521    Eina_Bool ret;
522
523    ELM_ICON_DATA_GET(obj, sd);
524
525    /* try locating the icon using the specified lookup order */
526    switch (sd->lookup_order)
527      {
528       case ELM_ICON_LOOKUP_FDO:
529         ret = _icon_freedesktop_set(obj, name, _icon_size_min_get(obj));
530         if (ret && fdo) *fdo = EINA_TRUE;
531         break;
532
533       case ELM_ICON_LOOKUP_THEME:
534         ret = _icon_standard_set(obj, name);
535         break;
536
537       case ELM_ICON_LOOKUP_THEME_FDO:
538         ret = _icon_standard_set(obj, name);
539         if (!ret)
540           {
541              ret = _icon_freedesktop_set(obj, name, _icon_size_min_get(obj));
542              if (ret && fdo) *fdo = EINA_TRUE;
543           }
544         break;
545
546       case ELM_ICON_LOOKUP_FDO_THEME:
547       default:
548         ret = _icon_freedesktop_set(obj, name, _icon_size_min_get(obj));
549         if (!ret)
550           ret = _icon_standard_set(obj, name);
551         else if (fdo)
552           *fdo = EINA_TRUE;
553         break;
554      }
555
556    if (ret)
557      {
558         eina_stringshare_replace(&sd->stdicon, name);
559         _elm_icon_smart_sizing_eval(obj);
560         return EINA_TRUE;
561      }
562
563    if (_path_is_absolute(name))
564      return _icon_file_set(sd, obj, name);
565
566    /* if that fails, see if icon name is in the format size/name. if so,
567       try locating a fallback without the size specification */
568    if (!(tmp = strchr(name, '/'))) return EINA_FALSE;
569    ++tmp;
570    if (*tmp) return elm_icon_standard_set(obj, tmp);
571    /* give up */
572    return EINA_FALSE;
573 }
574
575 static void
576 _elm_icon_standard_resize_cb(void *data,
577                              Evas *e __UNUSED__,
578                              Evas_Object *obj,
579                              void *event_info __UNUSED__)
580 {
581    Elm_Icon_Smart_Data *sd = data;
582    const char *refup = eina_stringshare_ref(sd->stdicon);
583    Eina_Bool fdo = EINA_FALSE;
584
585    if (!_elm_icon_standard_set(obj, sd->stdicon, &fdo) || (!fdo))
586      evas_object_event_callback_del_full
587        (obj, EVAS_CALLBACK_RESIZE, _elm_icon_standard_resize_cb, sd);
588    eina_stringshare_del(refup);
589 }
590
591 #ifdef HAVE_ELEMENTARY_ETHUMB
592 static void
593 _elm_icon_thumb_resize_cb(void *data,
594                           Evas *e __UNUSED__,
595                           Evas_Object *obj,
596                           void *event_info __UNUSED__)
597 {
598    Elm_Icon_Smart_Data *sd = data;
599
600    if (sd->thumb.file.path)
601      elm_icon_thumb_set(obj, sd->thumb.file.path, sd->thumb.file.key);
602 }
603
604 #endif
605
606 static void
607 _elm_icon_smart_add(Evas_Object *obj)
608 {
609    EVAS_SMART_DATA_ALLOC(obj, Elm_Icon_Smart_Data);
610
611    ELM_WIDGET_CLASS(_elm_icon_parent_sc)->base.add(obj);
612
613    priv->lookup_order = ELM_ICON_LOOKUP_THEME_FDO;
614
615 #ifdef HAVE_ELEMENTARY_ETHUMB
616    priv->thumb.request = NULL;
617 #endif
618 }
619
620 static void
621 _elm_icon_smart_del(Evas_Object *obj)
622 {
623 #ifdef HAVE_ELEMENTARY_ETHUMB
624    Ethumb_Client *ethumbd;
625 #endif
626
627    ELM_ICON_DATA_GET(obj, sd);
628
629    if (sd->stdicon) eina_stringshare_del(sd->stdicon);
630
631 #ifdef HAVE_ELEMENTARY_ETHUMB
632    ethumbd = elm_thumb_ethumb_client_get();
633    _icon_thumb_stop(sd, ethumbd);
634
635    eina_stringshare_del(sd->thumb.file.path);
636    eina_stringshare_del(sd->thumb.file.key);
637    eina_stringshare_del(sd->thumb.thumb.path);
638    eina_stringshare_del(sd->thumb.thumb.key);
639
640    if (sd->thumb.eeh)
641      ecore_event_handler_del(sd->thumb.eeh);
642 #endif
643
644    _edje_signals_free(sd);
645
646    ELM_WIDGET_CLASS(_elm_icon_parent_sc)->base.del(obj);
647 }
648
649 /* WARNING: to be deprecated */
650 void
651 _elm_icon_signal_emit(Evas_Object *obj,
652                       const char *emission,
653                       const char *source)
654 {
655    ELM_ICON_DATA_GET(obj, sd);
656
657    if (!ELM_IMAGE_DATA(sd)->edje) return;
658
659    edje_object_signal_emit(ELM_IMAGE_DATA(sd)->img, emission, source);
660 }
661
662 /* WARNING: to be deprecated */
663 void
664 _elm_icon_signal_callback_add(Evas_Object *obj,
665                               const char *emission,
666                               const char *source,
667                               Edje_Signal_Cb func_cb,
668                               void *data)
669 {
670    Edje_Signal_Data *esd;
671
672    ELM_ICON_DATA_GET(obj, sd);
673
674    if (!ELM_IMAGE_DATA(sd)->edje) return;
675
676    esd = ELM_NEW(Edje_Signal_Data);
677    if (!esd) return;
678
679    esd->obj = obj;
680    esd->func = func_cb;
681    esd->emission = eina_stringshare_add(emission);
682    esd->source = eina_stringshare_add(source);
683    esd->data = data;
684    sd->edje_signals =
685      eina_list_append(sd->edje_signals, esd);
686
687    edje_object_signal_callback_add
688      (ELM_IMAGE_DATA(sd)->img, emission, source, _edje_signal_callback, esd);
689 }
690
691 /* WARNING: to be deprecated */
692 void *
693 _elm_icon_signal_callback_del(Evas_Object *obj,
694                               const char *emission,
695                               const char *source,
696                               Edje_Signal_Cb func_cb)
697 {
698    Edje_Signal_Data *esd = NULL;
699    void *data = NULL;
700    Eina_List *l;
701
702    ELM_ICON_DATA_GET(obj, sd);
703
704    if (!ELM_IMAGE_DATA(sd)->edje) return NULL;
705
706    EINA_LIST_FOREACH(sd->edje_signals, l, esd)
707      {
708         if ((esd->func == func_cb) && (!strcmp(esd->emission, emission)) &&
709             (!strcmp(esd->source, source)))
710           {
711              sd->edje_signals = eina_list_remove_list(sd->edje_signals, l);
712              eina_stringshare_del(esd->emission);
713              eina_stringshare_del(esd->source);
714              data = esd->data;
715
716              edje_object_signal_callback_del_full
717                (ELM_IMAGE_DATA(sd)->img, emission, source,
718                _edje_signal_callback, esd);
719              free(esd);
720              return data; /* stop at 1st match */
721           }
722      }
723
724    return data;
725 }
726
727 static void
728 _elm_icon_smart_set_user(Elm_Icon_Smart_Class *sc)
729 {
730    ELM_WIDGET_CLASS(sc)->base.add = _elm_icon_smart_add;
731    ELM_WIDGET_CLASS(sc)->base.del = _elm_icon_smart_del;
732
733    ELM_WIDGET_CLASS(sc)->theme = _elm_icon_smart_theme;
734
735    ELM_IMAGE_CLASS(sc)->file_set = _elm_icon_smart_file_set;
736    ELM_IMAGE_CLASS(sc)->memfile_set = _elm_icon_smart_memfile_set;
737    ELM_IMAGE_CLASS(sc)->sizing_eval = _elm_icon_smart_sizing_eval;
738 }
739
740 EAPI const Elm_Icon_Smart_Class *
741 elm_icon_smart_class_get(void)
742 {
743    static Elm_Icon_Smart_Class _sc =
744      ELM_ICON_SMART_CLASS_INIT_NAME_VERSION(ELM_ICON_SMART_NAME);
745    static const Elm_Icon_Smart_Class *class = NULL;
746    Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
747
748    if (class) return class;
749
750    _elm_icon_smart_set(&_sc);
751    esc->callbacks = _smart_callbacks;
752    class = &_sc;
753
754    return class;
755 }
756
757 EAPI Evas_Object *
758 elm_icon_add(Evas_Object *parent)
759 {
760    Evas_Object *obj;
761
762    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
763
764    obj = elm_widget_add(_elm_icon_smart_class_new(), parent);
765    if (!obj) return NULL;
766
767    if (!elm_widget_sub_object_add(parent, obj))
768      ERR("could not add %p as sub object of %p", obj, parent);
769
770    //Tizen Only: This should be removed when eo is applied.
771    ELM_WIDGET_DATA_GET(obj, sd);
772    sd->on_create = EINA_FALSE;
773
774    return obj;
775 }
776
777 EAPI Eina_Bool
778 elm_icon_memfile_set(Evas_Object *obj,
779                      const void *img,
780                      size_t size,
781                      const char *format,
782                      const char *key)
783 {
784    ELM_ICON_CHECK(obj) EINA_FALSE;
785
786    return elm_image_memfile_set(obj, img, size, format, key);
787 }
788
789 EAPI Eina_Bool
790 elm_icon_file_set(Evas_Object *obj,
791                   const char *file,
792                   const char *group)
793 {
794    ELM_ICON_CHECK(obj) EINA_FALSE;
795
796    return elm_image_file_set(obj, file, group);
797 }
798
799 EAPI void
800 elm_icon_file_get(const Evas_Object *obj,
801                   const char **file,
802                   const char **group)
803 {
804    ELM_ICON_CHECK(obj);
805
806    elm_image_file_get(obj, file, group);
807 }
808
809 EAPI void
810 elm_icon_thumb_set(Evas_Object *obj,
811                    const char *file,
812                    const char *group)
813 {
814    ELM_ICON_CHECK(obj);
815
816 #ifdef HAVE_ELEMENTARY_ETHUMB
817    ELM_ICON_DATA_GET(obj, sd);
818
819    evas_object_event_callback_del_full
820      (obj, EVAS_CALLBACK_RESIZE, _elm_icon_standard_resize_cb, sd);
821    evas_object_event_callback_del_full
822      (obj, EVAS_CALLBACK_RESIZE, _elm_icon_thumb_resize_cb, sd);
823
824    evas_object_event_callback_add
825      (obj, EVAS_CALLBACK_RESIZE, _elm_icon_thumb_resize_cb, sd);
826
827    eina_stringshare_replace(&sd->thumb.file.path, file);
828    eina_stringshare_replace(&sd->thumb.file.key, group);
829
830    if (elm_thumb_ethumb_client_connected_get())
831      {
832         _icon_thumb_apply(sd);
833         return;
834      }
835
836    if (!sd->thumb.eeh)
837      {
838         sd->thumb.eeh = ecore_event_handler_add
839             (ELM_ECORE_EVENT_ETHUMB_CONNECT, _icon_thumb_apply_cb, sd);
840      }
841 #else
842    (void)obj;
843    (void)file;
844    (void)group;
845 #endif
846 }
847
848 EAPI Eina_Bool
849 elm_icon_animated_available_get(const Evas_Object *obj)
850 {
851    ELM_ICON_CHECK(obj) EINA_FALSE;
852
853    return elm_image_animated_available_get(obj);
854 }
855
856 EAPI void
857 elm_icon_animated_set(Evas_Object *obj,
858                       Eina_Bool anim)
859 {
860    ELM_ICON_CHECK(obj);
861
862    return elm_image_animated_set(obj, anim);
863 }
864
865 EAPI Eina_Bool
866 elm_icon_animated_get(const Evas_Object *obj)
867 {
868    ELM_ICON_CHECK(obj) EINA_FALSE;
869
870    return elm_image_animated_get(obj);
871 }
872
873 EAPI void
874 elm_icon_animated_play_set(Evas_Object *obj,
875                            Eina_Bool play)
876 {
877    ELM_ICON_CHECK(obj);
878
879    elm_image_animated_play_set(obj, play);
880 }
881
882 EAPI Eina_Bool
883 elm_icon_animated_play_get(const Evas_Object *obj)
884 {
885    ELM_ICON_CHECK(obj) EINA_FALSE;
886
887    return elm_image_animated_play_get(obj);
888 }
889
890 EAPI Eina_Bool
891 elm_icon_standard_set(Evas_Object *obj,
892                       const char *name)
893 {
894    ELM_ICON_CHECK(obj) EINA_FALSE;
895    ELM_ICON_DATA_GET(obj, sd);
896
897    Eina_Bool fdo = EINA_FALSE;
898    Eina_Bool ret;
899
900    if (!name) return EINA_FALSE;
901
902    evas_object_event_callback_del_full
903      (obj, EVAS_CALLBACK_RESIZE, _elm_icon_standard_resize_cb, sd);
904
905    ret = _elm_icon_standard_set(obj, name, &fdo);
906
907    if (fdo)
908      evas_object_event_callback_add
909        (obj, EVAS_CALLBACK_RESIZE, _elm_icon_standard_resize_cb, sd);
910
911    return ret;
912 }
913
914 EAPI const char *
915 elm_icon_standard_get(const Evas_Object *obj)
916 {
917    ELM_ICON_CHECK(obj) NULL;
918    ELM_ICON_DATA_GET(obj, sd);
919
920    return sd->stdicon;
921 }
922
923 EAPI void
924 elm_icon_order_lookup_set(Evas_Object *obj,
925                           Elm_Icon_Lookup_Order order)
926 {
927    ELM_ICON_CHECK(obj);
928    ELM_ICON_DATA_GET(obj, sd);
929
930    sd->lookup_order = order;
931 }
932
933 EAPI Elm_Icon_Lookup_Order
934 elm_icon_order_lookup_get(const Evas_Object *obj)
935 {
936    ELM_ICON_CHECK(obj) ELM_ICON_LOOKUP_THEME_FDO;
937    ELM_ICON_DATA_GET(obj, sd);
938
939    return sd->lookup_order;
940 }
941
942 EAPI void
943 elm_icon_smooth_set(Evas_Object *obj,
944                     Eina_Bool smooth)
945 {
946    ELM_ICON_CHECK(obj);
947
948    elm_image_smooth_set(obj, smooth);
949 }
950
951 EAPI Eina_Bool
952 elm_icon_smooth_get(const Evas_Object *obj)
953 {
954    ELM_ICON_CHECK(obj) EINA_FALSE;
955
956    return elm_image_smooth_get(obj);
957 }
958
959 EAPI void
960 elm_icon_no_scale_set(Evas_Object *obj,
961                       Eina_Bool no_scale)
962 {
963    ELM_ICON_CHECK(obj);
964
965    elm_image_no_scale_set(obj, no_scale);
966 }
967
968 EAPI Eina_Bool
969 elm_icon_no_scale_get(const Evas_Object *obj)
970 {
971    ELM_ICON_CHECK(obj) EINA_FALSE;
972
973    return elm_image_no_scale_get(obj);
974 }
975
976 EAPI void
977 elm_icon_resizable_set(Evas_Object *obj,
978                        Eina_Bool size_up,
979                        Eina_Bool size_down)
980 {
981    ELM_ICON_CHECK(obj);
982
983    elm_image_resizable_set(obj, size_up, size_down);
984 }
985
986 EAPI void
987 elm_icon_resizable_get(const Evas_Object *obj,
988                        Eina_Bool *size_up,
989                        Eina_Bool *size_down)
990 {
991    ELM_ICON_CHECK(obj);
992
993    elm_image_resizable_get(obj, size_up, size_down);
994 }
995
996 EAPI void
997 elm_icon_fill_outside_set(Evas_Object *obj,
998                           Eina_Bool fill_outside)
999 {
1000    ELM_ICON_CHECK(obj);
1001
1002    elm_image_fill_outside_set(obj, fill_outside);
1003 }
1004
1005 EAPI Eina_Bool
1006 elm_icon_fill_outside_get(const Evas_Object *obj)
1007 {
1008    ELM_ICON_CHECK(obj) EINA_FALSE;
1009
1010    return elm_image_fill_outside_get(obj);
1011 }
1012
1013 EAPI void
1014 elm_icon_size_get(const Evas_Object *obj,
1015                   int *w,
1016                   int *h)
1017 {
1018    ELM_ICON_CHECK(obj);
1019
1020    elm_image_object_size_get(obj, w, h);
1021 }
1022
1023 EAPI void
1024 elm_icon_prescale_set(Evas_Object *obj,
1025                       int size)
1026 {
1027    ELM_ICON_CHECK(obj);
1028
1029    elm_image_prescale_set(obj, size);
1030 }
1031
1032 EAPI int
1033 elm_icon_prescale_get(const Evas_Object *obj)
1034 {
1035    ELM_ICON_CHECK(obj) 0;
1036
1037    return elm_image_prescale_get(obj);
1038 }
1039
1040 EAPI Evas_Object *
1041 elm_icon_object_get(Evas_Object *obj)
1042 {
1043    ELM_ICON_CHECK(obj) 0;
1044
1045    return elm_image_object_get(obj);
1046 }
1047
1048 EAPI void
1049 elm_icon_preload_disabled_set(Evas_Object *obj,
1050                               Eina_Bool disabled)
1051 {
1052    ELM_ICON_CHECK(obj);
1053
1054    elm_image_preload_disabled_set(obj, disabled);
1055 }
1056
1057 EAPI void
1058 elm_icon_aspect_fixed_set(Evas_Object *obj,
1059                           Eina_Bool fixed)
1060 {
1061    ELM_ICON_CHECK(obj);
1062
1063    elm_image_aspect_fixed_set(obj, fixed);
1064 }
1065
1066 EAPI Eina_Bool
1067 elm_icon_aspect_fixed_get(const Evas_Object *obj)
1068 {
1069    ELM_ICON_CHECK(obj) EINA_FALSE;
1070
1071    return elm_image_aspect_fixed_get(obj);
1072 }