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