fixed plugin image size problem
[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
379    evas_object_size_hint_min_get(obj, &minw, &minh);
380
381    if (wd->no_scale) _els_smart_icon_scale_set(wd->img, 1.0);
382    else
383      {
384         _els_smart_icon_scale_set(wd->img, elm_widget_scale_get(obj) *
385                                   _elm_config->scale);
386         _els_smart_icon_size_get(wd->img, &w, &h);
387      }
388    if (!wd->scale_down)
389      {
390         minw = w;
391         minh = h;
392      }
393    if (!wd->scale_up)
394      {
395         maxw = w;
396         maxh = h;
397      }
398    evas_object_size_hint_min_set(obj, minw, minh);
399    evas_object_size_hint_max_set(obj, maxw, maxh);
400    wd->in_eval--;
401 }
402
403 static void
404 _mouse_up(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
405 {
406    Evas_Event_Mouse_Up *ev = event_info;
407    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
408    evas_object_smart_callback_call(data, SIG_CLICKED, event_info);
409 }
410
411 static Eina_Bool
412 _elm_icon_animate_cb(void *data)
413 {
414    Widget_Data  *wd = data;
415    Evas_Object  *img_obj;
416
417    if (!wd) return ECORE_CALLBACK_CANCEL;
418    if (!wd->anim) return ECORE_CALLBACK_CANCEL;
419
420    img_obj = _els_smart_icon_object_get(wd->img);
421    wd->cur_frame++;
422    if (wd->cur_frame > wd->frame_count)
423      wd->cur_frame = wd->cur_frame % wd->frame_count;
424    evas_object_image_animated_frame_set(img_obj, wd->cur_frame);
425
426    wd->duration = evas_object_image_animated_frame_duration_get(img_obj, wd->cur_frame, 0);
427
428    if (wd->duration > 0)
429      ecore_timer_interval_set(wd->timer, wd->duration);
430    return ECORE_CALLBACK_RENEW;
431 }
432
433 static Eina_Bool
434 _icon_standard_set(Widget_Data *wd, Evas_Object *obj, const char *name)
435 {
436    if (_elm_theme_object_icon_set(obj, wd->img, name, "default"))
437      {
438 #ifdef ELM_EFREET
439         /* TODO: elm_unneed_efreet() */
440         wd->freedesktop.use = EINA_FALSE;
441 #endif
442         return EINA_TRUE;
443      }
444    return EINA_FALSE;
445 }
446
447 static Eina_Bool
448 #ifdef ELM_EFREET
449 _icon_file_set(Widget_Data *wd, Evas_Object *obj, const char *path)
450 #else
451 _icon_file_set(Widget_Data *wd __UNUSED__, Evas_Object *obj, const char *path)
452 #endif
453 {
454    if (elm_icon_file_set(obj, path, NULL))
455      {
456 #ifdef ELM_EFREET
457         /* TODO: elm_unneed_efreet() */
458         wd->freedesktop.use = EINA_FALSE;
459 #endif
460         return EINA_TRUE;
461      }
462    return EINA_FALSE;
463 }
464
465 static Eina_Bool
466 #ifdef ELM_EFREET
467 _icon_freedesktop_set(Widget_Data *wd, Evas_Object *obj, const char *name, int size)
468 #else
469 _icon_freedesktop_set(Widget_Data *wd __UNUSED__, Evas_Object *obj __UNUSED__, const char *name __UNUSED__, int size __UNUSED__)
470 #endif
471 {
472 #ifdef ELM_EFREET
473    const char *path;
474
475    elm_need_efreet();
476    if (icon_theme == NON_EXISTING) return EINA_FALSE;
477    if (!icon_theme)
478      {
479         Efreet_Icon_Theme *theme;
480         /* TODO: Listen for EFREET_EVENT_ICON_CACHE_UPDATE */
481         theme = efreet_icon_theme_find(getenv("E_ICON_THEME"));
482         if (!theme)
483           {
484              const char **itr;
485              static const char *themes[] = {
486                   "gnome", "Human", "oxygen", "hicolor", NULL
487              };
488              for (itr = themes; *itr; itr++)
489                {
490                   theme = efreet_icon_theme_find(*itr);
491                   if (theme) break;
492                }
493           }
494
495         if (!theme)
496           {
497              icon_theme = NON_EXISTING;
498              return EINA_FALSE;
499           }
500         else
501           icon_theme = eina_stringshare_add(theme->name.internal);
502      }
503    path = efreet_icon_path_find(icon_theme, name, size);
504    wd->freedesktop.use = !!path;
505    if (wd->freedesktop.use)
506      {
507         wd->freedesktop.requested_size = size;
508         elm_icon_file_set(obj, path, NULL);
509         return EINA_TRUE;
510      }
511 #endif
512    return EINA_FALSE;
513 }
514
515 static Eina_Bool
516 _elm_icon_standard_set(Widget_Data *wd, Evas_Object *obj, const char *name, Eina_Bool *fdo)
517 {
518    char *tmp;
519    Eina_Bool ret;
520
521    /* try locating the icon using the specified lookup order */
522    switch (wd->lookup_order)
523      {
524       case ELM_ICON_LOOKUP_FDO:
525          ret = _icon_freedesktop_set(wd, obj, name, _icon_size_min_get(wd->img));
526          if (ret && fdo) *fdo = EINA_TRUE;
527          break;
528       case ELM_ICON_LOOKUP_THEME:
529          ret = _icon_standard_set(wd, obj, name);
530          break;
531       case ELM_ICON_LOOKUP_THEME_FDO:
532          ret = _icon_standard_set(wd, obj, name);
533          if (!ret)
534            {
535               ret = _icon_freedesktop_set(wd, obj, name, _icon_size_min_get(wd->img));
536               if (ret && fdo) *fdo = EINA_TRUE;
537            }
538          break;
539       case ELM_ICON_LOOKUP_FDO_THEME:
540       default:
541          ret = _icon_freedesktop_set(wd, obj, name, _icon_size_min_get(wd->img));
542          if (!ret)
543            ret = _icon_standard_set(wd, obj, name);
544          else if (fdo)
545            *fdo = EINA_TRUE;
546          break;
547      }
548
549    if (ret)
550      {
551         eina_stringshare_replace(&wd->stdicon, name);
552         if (!wd->in_eval) _sizing_eval(obj);
553         return EINA_TRUE;
554      }
555
556    if (_path_is_absolute(name))
557      return _icon_file_set(wd, obj, name);
558
559    /* if that fails, see if icon name is in the format size/name. if so,
560       try locating a fallback without the size specification */
561    if (!(tmp = strchr(name, '/'))) return EINA_FALSE;
562    ++tmp;
563    if (*tmp) return elm_icon_standard_set(obj, tmp);
564    /* give up */
565    return EINA_FALSE;
566 }
567
568 static void
569 _elm_icon_standard_resize(void *data,
570                           Evas *e __UNUSED__,
571                           Evas_Object *obj,
572                           void *event_info __UNUSED__)
573 {
574    Widget_Data *wd = data;
575    const char *refup = eina_stringshare_ref(wd->stdicon);
576    Eina_Bool fdo = EINA_FALSE;
577
578    if (!_elm_icon_standard_set(wd, obj, wd->stdicon, &fdo) || (!fdo))
579      evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE,
580                                          _elm_icon_standard_resize, wd);
581    eina_stringshare_del(refup);
582 }
583
584 #ifdef HAVE_ELEMENTARY_ETHUMB
585 static void
586 _elm_icon_thumb_resize(void *data,
587                        Evas *e __UNUSED__,
588                        Evas_Object *obj,
589                        void *event_info __UNUSED__)
590 {
591    Widget_Data *wd = data;
592
593    if (wd->thumb.file.path)
594      elm_icon_thumb_set(obj, wd->thumb.file.path, wd->thumb.file.key);
595 }
596 #endif
597
598 EAPI Evas_Object *
599 elm_icon_add(Evas_Object *parent)
600 {
601    Evas_Object *obj;
602    Evas *e;
603    Widget_Data *wd;
604
605    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
606
607    ELM_SET_WIDTYPE(widtype, "icon");
608    elm_widget_type_set(obj, "icon");
609    elm_widget_can_focus_set(obj, EINA_FALSE);
610    elm_widget_sub_object_add(parent, obj);
611    elm_widget_data_set(obj, wd);
612    elm_widget_del_hook_set(obj, _del_hook);
613    elm_widget_theme_hook_set(obj, _theme_hook);
614    elm_widget_signal_emit_hook_set(obj, _signal_emit_hook);
615    elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook);
616    elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook);
617
618    wd->lookup_order = ELM_ICON_LOOKUP_THEME_FDO;
619    wd->img = _els_smart_icon_add(e);
620    evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_UP,
621                                   _mouse_up, obj);
622    evas_object_repeat_events_set(wd->img, EINA_TRUE);
623    elm_widget_resize_object_set(obj, wd->img);
624
625    evas_object_smart_callbacks_descriptions_set(obj, _signals);
626
627 #ifdef HAVE_ELEMENTARY_ETHUMB
628    wd->thumb.request = NULL;
629 #endif
630
631    wd->smooth = EINA_TRUE;
632    wd->scale_up = EINA_TRUE;
633    wd->scale_down = EINA_TRUE;
634
635    _sizing_eval(obj);
636    return obj;
637 }
638
639 EAPI Eina_Bool
640 elm_icon_memfile_set(Evas_Object *obj, const void *img, size_t size, const char *format, const char *key)
641 {
642    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
643    Widget_Data *wd = elm_widget_data_get(obj);
644    Eina_Bool ret;
645
646    if (!wd) return EINA_FALSE;
647    EINA_SAFETY_ON_NULL_RETURN_VAL(img, EINA_FALSE);
648    EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, EINA_FALSE);
649    eina_stringshare_del(wd->stdicon);
650    wd->stdicon = NULL;
651    ret = _els_smart_icon_memfile_set(wd->img, img, size, format, key);
652    if (!wd->in_eval) _sizing_eval(obj);
653    return ret;
654 }
655
656 EAPI Eina_Bool
657 elm_icon_file_set(Evas_Object *obj, const char *file, const char *group)
658 {
659    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
660    Widget_Data *wd = elm_widget_data_get(obj);
661    Eina_Bool ret;
662
663    if (!wd) return EINA_FALSE;
664    EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
665
666 #ifdef ELM_EFREET
667    if (!wd->freedesktop.use)
668      {
669         if (wd->stdicon) eina_stringshare_del(wd->stdicon);
670         wd->stdicon = NULL;
671      }
672 #endif
673    if (eina_str_has_extension(file, ".edj"))
674      ret = _els_smart_icon_file_edje_set(wd->img, file, group);
675    else
676      ret = _els_smart_icon_file_key_set(wd->img, file, group);
677    if (!wd->in_eval) _sizing_eval(obj);
678    return ret;
679 }
680
681 EAPI void
682 elm_icon_file_get(const Evas_Object *obj, const char **file, const char **group)
683 {
684    ELM_CHECK_WIDTYPE(obj, widtype);
685    Widget_Data *wd = elm_widget_data_get(obj);
686    if (!wd) return;
687    _els_smart_icon_file_get(wd->img, file, group);
688 }
689
690 EAPI void
691 elm_icon_thumb_set(Evas_Object *obj, const char *file, const char *group)
692 {
693    ELM_CHECK_WIDTYPE(obj, widtype);
694    Widget_Data *wd = elm_widget_data_get(obj);
695    if (!wd) return;
696
697 #ifdef HAVE_ELEMENTARY_ETHUMB
698    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE,
699                                        _elm_icon_standard_resize, wd);
700    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE,
701                                        _elm_icon_thumb_resize, wd);
702
703    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
704                                   _elm_icon_thumb_resize, wd);
705
706    eina_stringshare_replace(&wd->thumb.file.path, file);
707    eina_stringshare_replace(&wd->thumb.file.key, group);
708
709    if (elm_thumb_ethumb_client_connected_get())
710      {
711         _icon_thumb_apply(wd);
712         return ;
713      }
714
715    if (!wd->thumb.eeh)
716      {
717         wd->thumb.eeh = ecore_event_handler_add(ELM_ECORE_EVENT_ETHUMB_CONNECT, _icon_thumb_apply_cb, wd);
718      }
719 #else
720    (void) obj;
721    (void) file;
722    (void) group;
723 #endif
724 }
725
726
727 EAPI Eina_Bool
728 elm_icon_animated_available_get(const Evas_Object *obj)
729 {
730    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
731    Evas_Object *img_obj ;
732    Widget_Data *wd = elm_widget_data_get(obj);
733    if (!wd) return EINA_FALSE;
734
735    img_obj = _els_smart_icon_object_get(wd->img);
736
737    return evas_object_image_animated_get(img_obj);
738 }
739
740 EAPI void
741 elm_icon_animated_set(Evas_Object *obj, Eina_Bool anim)
742 {
743    ELM_CHECK_WIDTYPE(obj, widtype);
744    Evas_Object *img_obj ;
745    Widget_Data *wd = elm_widget_data_get(obj);
746    if (!wd) return;
747    if (wd->anim == anim) return;
748
749    img_obj = _els_smart_icon_object_get(wd->img);
750    if (!evas_object_image_animated_get(img_obj)) return;
751    if (anim)
752      {
753         wd->frame_count = evas_object_image_animated_frame_count_get(img_obj);
754         wd->cur_frame = 1;
755         wd->duration = evas_object_image_animated_frame_duration_get(img_obj, wd->cur_frame, 0);
756         evas_object_image_animated_frame_set(img_obj, wd->cur_frame);
757      }
758    else
759      {
760         wd->frame_count = -1;
761         wd->cur_frame = -1;
762         wd->duration = -1;
763      }
764    wd->anim = anim;
765    return;
766 }
767
768 EAPI Eina_Bool
769 elm_icon_animated_get(const Evas_Object *obj)
770 {
771    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
772    Widget_Data *wd = elm_widget_data_get(obj);
773    if (!wd) return EINA_FALSE;
774    return wd->anim;
775 }
776
777 EAPI void
778 elm_icon_animated_play_set(Evas_Object *obj, Eina_Bool play)
779 {
780    ELM_CHECK_WIDTYPE(obj, widtype);
781    Widget_Data *wd = elm_widget_data_get(obj);
782    if (!wd) return;
783    if (!wd->anim) return;
784    if (wd->play == play) return;
785
786    if (play)
787      {
788         wd->timer = ecore_timer_add(wd->duration, _elm_icon_animate_cb, wd);
789      }
790    else
791      {
792         if (wd->timer)
793           {
794              ecore_timer_del(wd->timer);
795              wd->timer = NULL;
796           }
797      }
798    wd->play = play;
799
800 }
801
802 EAPI Eina_Bool
803 elm_icon_animated_play_get(const Evas_Object *obj)
804 {
805    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
806    Widget_Data *wd = elm_widget_data_get(obj);
807    if (!wd) return EINA_FALSE;
808    return wd->play;
809 }
810
811 EAPI Eina_Bool
812 elm_icon_standard_set(Evas_Object *obj, const char *name)
813 {
814    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
815    Widget_Data *wd = elm_widget_data_get(obj);
816    Eina_Bool fdo = EINA_FALSE;
817    Eina_Bool ret;
818
819    if ((!wd) || (!name)) return EINA_FALSE;
820
821    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_RESIZE,
822                                        _elm_icon_standard_resize, wd);
823
824    ret = _elm_icon_standard_set(wd, obj, name, &fdo);
825
826    if (fdo)
827      evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
828                                     _elm_icon_standard_resize, wd);
829
830    return ret;
831 }
832
833 EAPI const char *
834 elm_icon_standard_get(const Evas_Object *obj)
835 {
836    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
837    Widget_Data *wd = elm_widget_data_get(obj);
838    if (!wd) return NULL;
839    return wd->stdicon;
840 }
841
842 EAPI void
843 elm_icon_order_lookup_set(Evas_Object *obj, Elm_Icon_Lookup_Order order)
844 {
845    ELM_CHECK_WIDTYPE(obj, widtype);
846    Widget_Data *wd = elm_widget_data_get(obj);
847    if (wd) wd->lookup_order = order;
848 }
849
850 EAPI Elm_Icon_Lookup_Order
851 elm_icon_order_lookup_get(const Evas_Object *obj)
852 {
853    ELM_CHECK_WIDTYPE(obj, widtype) ELM_ICON_LOOKUP_THEME_FDO;
854    Widget_Data *wd = elm_widget_data_get(obj);
855    if (!wd) return ELM_ICON_LOOKUP_THEME_FDO;
856    return wd->lookup_order;
857 }
858
859 EAPI void
860 elm_icon_smooth_set(Evas_Object *obj, Eina_Bool smooth)
861 {
862    ELM_CHECK_WIDTYPE(obj, widtype);
863    Widget_Data *wd = elm_widget_data_get(obj);
864
865    if (!wd) return;
866    wd->smooth = smooth;
867    if (!wd->in_eval) _sizing_eval(obj);
868 }
869
870 EAPI Eina_Bool
871 elm_icon_smooth_get(const Evas_Object *obj)
872 {
873    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
874    Widget_Data *wd = elm_widget_data_get(obj);
875
876    if (!wd) return EINA_FALSE;
877    return wd->smooth;
878 }
879
880 EAPI void
881 elm_icon_no_scale_set(Evas_Object *obj, Eina_Bool no_scale)
882 {
883    ELM_CHECK_WIDTYPE(obj, widtype);
884    Widget_Data *wd = elm_widget_data_get(obj);
885
886    if (!wd) return;
887    wd->no_scale = no_scale;
888    if (!wd->in_eval) _sizing_eval(obj);
889 }
890
891 EAPI Eina_Bool
892 elm_icon_no_scale_get(const Evas_Object *obj)
893 {
894    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
895    Widget_Data *wd = elm_widget_data_get(obj);
896    if (!wd) return EINA_FALSE;
897    return wd->no_scale;
898 }
899
900 EAPI void
901 elm_icon_resizable_set(Evas_Object *obj, Eina_Bool size_up, Eina_Bool size_down)
902 {
903    ELM_CHECK_WIDTYPE(obj, widtype);
904    Widget_Data *wd = elm_widget_data_get(obj);
905
906    if (!wd) return;
907    wd->scale_up = size_up;
908    wd->scale_down = size_down;
909    if (!wd->in_eval) _sizing_eval(obj);
910 }
911
912 EAPI void
913 elm_icon_resizable_get(const Evas_Object *obj, Eina_Bool *size_up, Eina_Bool *size_down)
914 {
915    ELM_CHECK_WIDTYPE(obj, widtype);
916    Widget_Data *wd = elm_widget_data_get(obj);
917    if (!wd) return;
918    if (size_up) *size_up = wd->scale_up;
919    if (size_down) *size_down = wd->scale_down;
920 }
921
922 EAPI void
923 elm_icon_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside)
924 {
925    ELM_CHECK_WIDTYPE(obj, widtype);
926    Widget_Data *wd = elm_widget_data_get(obj);
927
928    if (!wd) return;
929    wd->fill_outside = fill_outside;
930    if (!wd->in_eval) _sizing_eval(obj);
931 }
932
933 EAPI void
934 elm_icon_size_get(const Evas_Object *obj, int *w, int *h)
935 {
936    ELM_CHECK_WIDTYPE(obj, widtype);
937    Widget_Data *wd = elm_widget_data_get(obj);
938
939    if (!wd) return;
940    _els_smart_icon_size_get(wd->img, w, h);
941 }
942
943 EAPI Eina_Bool
944 elm_icon_fill_outside_get(const Evas_Object *obj)
945 {
946    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
947    Widget_Data *wd = elm_widget_data_get(obj);
948
949    if (!wd) return EINA_FALSE;
950    return wd->fill_outside;
951 }
952
953 EAPI void
954 elm_icon_prescale_set(Evas_Object *obj, int size)
955 {
956    ELM_CHECK_WIDTYPE(obj, widtype);
957    Widget_Data *wd = elm_widget_data_get(obj);
958
959    if (!wd) return;
960    _els_smart_icon_scale_size_set(wd->img, size);
961 }
962
963 EAPI int
964 elm_icon_prescale_get(const Evas_Object *obj)
965 {
966    ELM_CHECK_WIDTYPE(obj, widtype) 0;
967    Widget_Data *wd = elm_widget_data_get(obj);
968
969    if (!wd) return 0;
970    return _els_smart_icon_scale_size_get(wd->img);
971 }
972
973 EAPI Evas_Object *
974 elm_icon_object_get(Evas_Object *obj)
975 {
976    ELM_CHECK_WIDTYPE(obj, widtype) 0;
977    Widget_Data *wd = elm_widget_data_get(obj);
978
979    if (!wd) return NULL;
980    return _els_smart_icon_object_get(wd->img);
981 }
982
983 EAPI void
984 elm_icon_preload_disabled_set(Evas_Object *obj, Eina_Bool disabled)
985 {
986    ELM_CHECK_WIDTYPE(obj, widtype);
987    Widget_Data *wd = elm_widget_data_get(obj);
988
989    if (!wd) return;
990    _els_smart_icon_preload_set(wd->img, !!disabled);
991 }
992
993 EAPI void
994 elm_icon_aspect_fixed_set(Evas_Object *obj, Eina_Bool fixed)
995 {
996    ELM_CHECK_WIDTYPE(obj, widtype);
997    Widget_Data *wd = elm_widget_data_get(obj);
998    if (!wd) return;
999    _els_smart_icon_aspect_fixed_set(wd->img, fixed);
1000 }
1001
1002 EAPI Eina_Bool
1003 elm_icon_aspect_fixed_get(const Evas_Object *obj)
1004 {
1005    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1006    Widget_Data *wd = elm_widget_data_get(obj);
1007    if (!wd) return EINA_FALSE;
1008    return _els_smart_icon_aspect_fixed_get(wd->img);
1009 }