EFL migration revision 67547
[framework/uifw/elementary.git] / tests / 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())
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 EAPI Eina_Bool
721 elm_icon_animated_available_get(const Evas_Object *obj)
722 {
723    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
724    Evas_Object *img_obj ;
725    Widget_Data *wd = elm_widget_data_get(obj);
726    if (!wd) return EINA_FALSE;
727
728    img_obj = _els_smart_icon_object_get(wd->img);
729
730    return evas_object_image_animated_get(img_obj);
731 }
732
733 EAPI void
734 elm_icon_animated_set(Evas_Object *obj, Eina_Bool anim)
735 {
736    ELM_CHECK_WIDTYPE(obj, widtype);
737    Evas_Object *img_obj ;
738    Widget_Data *wd = elm_widget_data_get(obj);
739    if (!wd) return;
740    if (wd->anim == anim) return;
741
742    img_obj = _els_smart_icon_object_get(wd->img);
743    if (!evas_object_image_animated_get(img_obj)) return;
744    if (anim)
745      {
746         wd->frame_count = evas_object_image_animated_frame_count_get(img_obj);
747         wd->cur_frame = 1;
748         wd->duration = evas_object_image_animated_frame_duration_get(img_obj, wd->cur_frame, 0);
749         evas_object_image_animated_frame_set(img_obj, wd->cur_frame);
750      }
751    else
752      {
753         wd->frame_count = -1;
754         wd->cur_frame = -1;
755         wd->duration = -1;
756      }
757    wd->anim = anim;
758    return;
759 }
760
761 EAPI Eina_Bool
762 elm_icon_animated_get(const Evas_Object *obj)
763 {
764    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
765    Widget_Data *wd = elm_widget_data_get(obj);
766    if (!wd) return EINA_FALSE;
767    return wd->anim;
768 }
769
770 EAPI void
771 elm_icon_animated_play_set(Evas_Object *obj, Eina_Bool play)
772 {
773    ELM_CHECK_WIDTYPE(obj, widtype);
774    Widget_Data *wd = elm_widget_data_get(obj);
775    if (!wd) return;
776    if (!wd->anim) return;
777    if (wd->play == play) return;
778
779    if (play)
780      {
781         wd->timer = ecore_timer_add(wd->duration, _elm_icon_animate_cb, wd);
782      }
783    else
784      {
785         if (wd->timer)
786           {
787              ecore_timer_del(wd->timer);
788              wd->timer = NULL;
789           }
790      }
791    wd->play = play;
792
793 }
794
795 EAPI Eina_Bool
796 elm_icon_animated_play_get(const Evas_Object *obj)
797 {
798    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
799    Widget_Data *wd = elm_widget_data_get(obj);
800    if (!wd) return EINA_FALSE;
801    return wd->play;
802 }
803
804 EAPI Eina_Bool
805 elm_icon_standard_set(Evas_Object *obj, const char *name)
806 {
807    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
808    Widget_Data *wd = elm_widget_data_get(obj);
809    Eina_Bool fdo = EINA_FALSE;
810    Eina_Bool ret;
811
812    if ((!wd) || (!name)) return EINA_FALSE;
813
814    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE,
815                                        _elm_icon_standard_resize, wd);
816
817    ret = _elm_icon_standard_set(wd, obj, name, &fdo);
818
819    if (fdo)
820      evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
821                                     _elm_icon_standard_resize, wd);
822
823    return ret;
824 }
825
826 EAPI const char *
827 elm_icon_standard_get(const Evas_Object *obj)
828 {
829    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
830    Widget_Data *wd = elm_widget_data_get(obj);
831    if (!wd) return NULL;
832    return wd->stdicon;
833 }
834
835 EAPI void
836 elm_icon_order_lookup_set(Evas_Object *obj, Elm_Icon_Lookup_Order order)
837 {
838    ELM_CHECK_WIDTYPE(obj, widtype);
839    Widget_Data *wd = elm_widget_data_get(obj);
840    if (wd) wd->lookup_order = order;
841 }
842
843 EAPI Elm_Icon_Lookup_Order
844 elm_icon_order_lookup_get(const Evas_Object *obj)
845 {
846    ELM_CHECK_WIDTYPE(obj, widtype) ELM_ICON_LOOKUP_THEME_FDO;
847    Widget_Data *wd = elm_widget_data_get(obj);
848    if (!wd) return ELM_ICON_LOOKUP_THEME_FDO;
849    return wd->lookup_order;
850 }
851
852 EAPI void
853 elm_icon_smooth_set(Evas_Object *obj, Eina_Bool smooth)
854 {
855    ELM_CHECK_WIDTYPE(obj, widtype);
856    Widget_Data *wd = elm_widget_data_get(obj);
857
858    if (!wd) return;
859    wd->smooth = smooth;
860    if (!wd->in_eval) _sizing_eval(obj);
861 }
862
863 EAPI Eina_Bool
864 elm_icon_smooth_get(const Evas_Object *obj)
865 {
866    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
867    Widget_Data *wd = elm_widget_data_get(obj);
868
869    if (!wd) return EINA_FALSE;
870    return wd->smooth;
871 }
872
873 EAPI void
874 elm_icon_no_scale_set(Evas_Object *obj, Eina_Bool no_scale)
875 {
876    ELM_CHECK_WIDTYPE(obj, widtype);
877    Widget_Data *wd = elm_widget_data_get(obj);
878
879    if (!wd) return;
880    wd->no_scale = no_scale;
881    if (!wd->in_eval) _sizing_eval(obj);
882 }
883
884 EAPI Eina_Bool
885 elm_icon_no_scale_get(const Evas_Object *obj)
886 {
887    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
888    Widget_Data *wd = elm_widget_data_get(obj);
889    if (!wd) return EINA_FALSE;
890    return wd->no_scale;
891 }
892
893 EAPI void
894 elm_icon_scale_set(Evas_Object *obj, Eina_Bool scale_up, Eina_Bool scale_down)
895 {
896    ELM_CHECK_WIDTYPE(obj, widtype);
897    Widget_Data *wd = elm_widget_data_get(obj);
898
899    if (!wd) return;
900    wd->scale_up = scale_up;
901    wd->scale_down = scale_down;
902    if (!wd->in_eval) _sizing_eval(obj);
903 }
904
905 EAPI void
906 elm_icon_scale_get(const Evas_Object *obj, Eina_Bool *scale_up, Eina_Bool *scale_down)
907 {
908    ELM_CHECK_WIDTYPE(obj, widtype);
909    Widget_Data *wd = elm_widget_data_get(obj);
910    if (!wd) return;
911    if (scale_up) *scale_up = wd->scale_up;
912    if (scale_down) *scale_down = wd->scale_down;
913 }
914
915 EAPI void
916 elm_icon_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside)
917 {
918    ELM_CHECK_WIDTYPE(obj, widtype);
919    Widget_Data *wd = elm_widget_data_get(obj);
920
921    if (!wd) return;
922    wd->fill_outside = fill_outside;
923    if (!wd->in_eval) _sizing_eval(obj);
924 }
925
926 EAPI void
927 elm_icon_size_get(const Evas_Object *obj, int *w, int *h)
928 {
929    ELM_CHECK_WIDTYPE(obj, widtype);
930    Widget_Data *wd = elm_widget_data_get(obj);
931
932    if (!wd) return;
933    _els_smart_icon_size_get(wd->img, w, h);
934 }
935
936 EAPI Eina_Bool
937 elm_icon_fill_outside_get(const Evas_Object *obj)
938 {
939    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
940    Widget_Data *wd = elm_widget_data_get(obj);
941
942    if (!wd) return EINA_FALSE;
943    return wd->fill_outside;
944 }
945
946 EAPI void
947 elm_icon_prescale_set(Evas_Object *obj, int size)
948 {
949    ELM_CHECK_WIDTYPE(obj, widtype);
950    Widget_Data *wd = elm_widget_data_get(obj);
951
952    if (!wd) return;
953    _els_smart_icon_scale_size_set(wd->img, size);
954 }
955
956 EAPI int
957 elm_icon_prescale_get(const Evas_Object *obj)
958 {
959    ELM_CHECK_WIDTYPE(obj, widtype) 0;
960    Widget_Data *wd = elm_widget_data_get(obj);
961
962    if (!wd) return 0;
963    return _els_smart_icon_scale_size_get(wd->img);
964 }
965
966 EAPI Evas_Object *
967 elm_icon_object_get(Evas_Object *obj)
968 {
969    ELM_CHECK_WIDTYPE(obj, widtype) 0;
970    Widget_Data *wd = elm_widget_data_get(obj);
971
972    if (!wd) return NULL;
973    return _els_smart_icon_object_get(wd->img);
974 }
975
976 EAPI void
977 elm_icon_preload_set(Evas_Object *obj, Eina_Bool disable)
978 {
979    ELM_CHECK_WIDTYPE(obj, widtype);
980    Widget_Data *wd = elm_widget_data_get(obj);
981
982    if (!wd) return;
983    _els_smart_icon_preload_set(wd->img, disable);
984 }