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