1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4 
5 #define EFL_ACCESS_OBJECT_PROTECTED
6 
7 #include <Elementary.h>
8 
9 #include "elm_priv.h"
10 #include "elm_widget_icon.h"
11 #include "efl_ui_widget_image.h"
12 #include "elm_icon_eo.h"
13 
14 #define NON_EXISTING (void *)-1
15 
16 #define MY_CLASS ELM_ICON_CLASS
17 #define MY_CLASS_NAME "Elm_Icon"
18 #define MY_CLASS_NAME_LEGACY "elm_icon"
19 
20 static Eina_List *_elm_icon_retry = NULL;
21 static int _icon_pending_request = 0;
22 
23 static const char SIG_THUMB_DONE[] = "thumb,done";
24 static const char SIG_THUMB_ERROR[] = "thumb,error";
25 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
26    {SIG_THUMB_DONE, ""},
27    {SIG_THUMB_ERROR, ""},
28    {NULL, NULL}
29 };
30 
31 /* FIXME: move this code to ecore */
32 #ifdef _WIN32
33 static Eina_Bool
_path_is_absolute(const char * path)34 _path_is_absolute(const char *path)
35 {
36    //TODO: Check if this works with all absolute paths in windows
37    return (isalpha(*path)) && (*(path + 1) == ':') &&
38           ((*(path + 2) == '\\') || (*(path + 2) == '/'));
39 }
40 
41 #else
42 static Eina_Bool
_path_is_absolute(const char * path)43 _path_is_absolute(const char *path)
44 {
45    return *path == '/';
46 }
47 
48 #endif
49 
50 static inline int
_icon_size_min_get(Evas_Object * icon)51 _icon_size_min_get(Evas_Object *icon)
52 {
53    int w, h;
54 
55    evas_object_geometry_get(icon, NULL, NULL, &w, &h);
56 
57    return MAX(16, MIN(w, h));
58 }
59 
60 static void
_icon_thumb_stop(Elm_Icon_Data * sd,void * ethumbd)61 _icon_thumb_stop(Elm_Icon_Data *sd,
62                  void *ethumbd)
63 {
64    if (sd->thumb.request)
65      {
66         ethumb_client_thumb_async_cancel(ethumbd, sd->thumb.request);
67         sd->thumb.request = NULL;
68         _icon_pending_request--;
69      }
70 
71    if (sd->thumb.retry)
72      {
73         _elm_icon_retry = eina_list_remove(_elm_icon_retry, sd);
74         sd->thumb.retry = EINA_FALSE;
75      }
76 }
77 
78 static Eina_Bool
_icon_thumb_display(Elm_Icon_Data * sd)79 _icon_thumb_display(Elm_Icon_Data *sd)
80 {
81    Eina_Bool ret = EINA_FALSE;
82 
83    if (sd->thumb.format == ETHUMB_THUMB_EET)
84      {
85         int prefix_size;
86         const char **ext, *ptr;
87         static const char *extensions[] =
88           {
89              ".asf", ".avi", ".bdm", ".bdmv", ".clpi", ".cpi", ".dv", ".fla",
90              ".flv", ".m1v", ".m2t", ".m2v", ".m4v", ".mkv", ".mov", ".mp2",
91              ".mp2ts", ".mp4", ".mpe", ".mpeg", ".mpg", ".mpl", ".mpls", ".mts",
92              ".mxf", ".nut", ".nuv", ".ogg", ".ogm", ".ogv", ".qt", ".rm", ".rmj",
93              ".rmm", ".rms", ".rmvb", ".rmx", ".rv", ".swf", ".ts", ".weba",
94              ".webm", ".wmv", ".3g2", ".3gp", ".3gp2", ".3gpp", ".3gpp2", ".3p2",
95              ".264",
96              NULL
97           };
98 
99         prefix_size = eina_stringshare_strlen(sd->thumb.file.path) - 4;
100         if (prefix_size >= 0)
101           {
102              ptr = sd->thumb.file.path + prefix_size;
103              for (ext = extensions; *ext; ++ext)
104                if (!strcasecmp(ptr, *ext))
105                  {
106                     sd->is_video = EINA_TRUE;
107                     break;
108                  }
109           }
110 
111         ret = elm_image_file_set
112             (sd->obj, sd->thumb.thumb.path,
113             sd->thumb.thumb.key);
114 
115         sd->is_video = EINA_FALSE;
116      }
117 
118    if (!ret)
119      ret = elm_image_file_set
120          (sd->obj, sd->thumb.thumb.path, sd->thumb.thumb.key);
121 
122    if (ret)
123      efl_event_callback_legacy_call
124        (sd->obj, ELM_ICON_EVENT_THUMB_DONE, NULL);
125    else
126      efl_event_callback_legacy_call
127        (sd->obj, ELM_ICON_EVENT_THUMB_ERROR, NULL);
128 
129    return ret;
130 }
131 
132 static Eina_Bool
_icon_thumb_retry(Elm_Icon_Data * sd)133 _icon_thumb_retry(Elm_Icon_Data *sd)
134 {
135    return _icon_thumb_display(sd);
136 }
137 
138 static void
_icon_thumb_cleanup(Ethumb_Client * ethumbd)139 _icon_thumb_cleanup(Ethumb_Client *ethumbd)
140 {
141    Eina_List *l, *ll;
142    Elm_Icon_Data *sd;
143 
144    EINA_LIST_FOREACH_SAFE(_elm_icon_retry, l, ll, sd)
145      if (_icon_thumb_retry(sd))
146        {
147           _elm_icon_retry = eina_list_remove_list(_elm_icon_retry, l);
148           sd->thumb.retry = EINA_FALSE;
149        }
150 
151    if (_icon_pending_request == 0)
152      EINA_LIST_FREE(_elm_icon_retry, sd)
153        _icon_thumb_stop(sd, ethumbd);
154 }
155 
156 static void
_icon_thumb_finish(Elm_Icon_Data * sd,Ethumb_Client * ethumbd)157 _icon_thumb_finish(Elm_Icon_Data *sd,
158                    Ethumb_Client *ethumbd)
159 {
160    const char *file = NULL, *group = NULL;
161    Eina_Bool ret = EINA_FALSE;
162 
163    elm_image_file_get(sd->obj, &file, &group);
164    file = eina_stringshare_ref(file);
165    group = eina_stringshare_ref(group);
166 
167    ret = _icon_thumb_display(sd);
168 
169    if (!ret && file)
170      {
171         if (!sd->thumb.retry)
172           {
173              _elm_icon_retry = eina_list_append(_elm_icon_retry, sd);
174              sd->thumb.retry = EINA_TRUE;
175           }
176 
177         /* Back to previous image */
178         elm_image_file_set(sd->obj, file, group);
179      }
180 
181    _icon_thumb_cleanup(ethumbd);
182 
183    eina_stringshare_del(file);
184    eina_stringshare_del(group);
185 }
186 
187 static void
_icon_thumb_done(Ethumb_Client * client,const char * thumb_path,const char * thumb_key,void * data)188 _icon_thumb_done(Ethumb_Client *client,
189                  const char *thumb_path,
190                  const char *thumb_key,
191                  void *data)
192 {
193    Elm_Icon_Data *sd = data;
194 
195    if (EINA_UNLIKELY(!sd->thumb.request))
196      {
197         ERR("Something odd happened with a thumbnail request");
198         return;
199      }
200 
201    _icon_pending_request--;
202    sd->thumb.request = NULL;
203 
204    eina_stringshare_replace(&sd->thumb.thumb.path, thumb_path);
205    eina_stringshare_replace(&sd->thumb.thumb.key, thumb_key);
206    sd->thumb.format = ethumb_client_format_get(client);
207 
208    _icon_thumb_finish(sd, client);
209 }
210 
211 static void
_icon_thumb_error(Ethumb_Client * client,void * data)212 _icon_thumb_error(Ethumb_Client *client,
213                   void *data)
214 {
215    Elm_Icon_Data *sd = data;
216 
217    if (EINA_UNLIKELY(!sd->thumb.request))
218      {
219         ERR("Something odd happened with a thumbnail request");
220         return;
221      }
222 
223    _icon_pending_request--;
224    sd->thumb.request = NULL;
225 
226    ERR("could not generate thumbnail for %s (key: %s)",
227        sd->thumb.file.path, sd->thumb.file.key);
228 
229    efl_event_callback_legacy_call(sd->obj, ELM_ICON_EVENT_THUMB_ERROR, NULL);
230 
231    _icon_thumb_cleanup(client);
232 }
233 
234 static void
_icon_thumb_apply(Elm_Icon_Data * sd)235 _icon_thumb_apply(Elm_Icon_Data *sd)
236 {
237    Ethumb_Client *ethumbd;
238    int min_size;
239 
240    ethumbd = elm_thumb_ethumb_client_get();
241 
242    _icon_thumb_stop(sd, ethumbd);
243 
244    if (!sd->thumb.file.path) return;
245 
246    _icon_pending_request++;
247    if (!ethumb_client_file_set
248          (ethumbd, sd->thumb.file.path, sd->thumb.file.key)) return;
249 
250    min_size = _icon_size_min_get(sd->obj);
251    ethumb_client_size_set(ethumbd, min_size, min_size);
252 
253    sd->thumb.request = ethumb_client_thumb_async_get
254        (ethumbd, _icon_thumb_done, _icon_thumb_error, sd);
255 }
256 
257 static Eina_Bool
_icon_thumb_apply_cb(void * data,int type EINA_UNUSED,void * ev EINA_UNUSED)258 _icon_thumb_apply_cb(void *data,
259                      int type EINA_UNUSED,
260                      void *ev EINA_UNUSED)
261 {
262    ELM_ICON_DATA_GET(data, sd);
263 
264    _icon_thumb_apply(sd);
265 
266    return ECORE_CALLBACK_RENEW;
267 }
268 
269 static Eina_Bool
_icon_freedesktop_set(Evas_Object * obj,const char * theme,const char * name,int size)270 _icon_freedesktop_set(Evas_Object *obj,
271                       const char *theme,
272                       const char *name,
273                       int size)
274 {
275    const char *path;
276 
277    ELM_ICON_DATA_GET(obj, sd);
278 
279    elm_need_efreet();
280    if (!theme)
281      theme = elm_config_icon_theme_get();
282 
283    path = efreet_icon_path_find(theme, name, size);
284    sd->freedesktop.use = !!path;
285    if (sd->freedesktop.use)
286      {
287         sd->freedesktop.requested_size = size;
288         elm_image_file_set(obj, path, NULL);
289         return EINA_TRUE;
290      }
291    return EINA_FALSE;
292 }
293 
294 static void
_edje_signal_callback(void * data,Evas_Object * obj EINA_UNUSED,const char * emission,const char * source)295 _edje_signal_callback(void *data,
296                       Evas_Object *obj EINA_UNUSED,
297                       const char *emission,
298                       const char *source)
299 {
300    Edje_Signal_Data *esd = data;
301 
302    esd->func(esd->data, esd->obj, emission, source);
303 }
304 
305 static void
_edje_signals_free(Elm_Icon_Data * sd)306 _edje_signals_free(Elm_Icon_Data *sd)
307 {
308    Edje_Signal_Data *esd;
309    Efl_Ui_Image_Data *id = efl_data_scope_get(sd->obj, EFL_UI_IMAGE_CLASS);
310 
311    EINA_LIST_FREE(sd->edje_signals, esd)
312      {
313         edje_object_signal_callback_del_full
314            (id->img, esd->emission, esd->source,
315             _edje_signal_callback, esd);
316         eina_stringshare_del(esd->emission);
317         eina_stringshare_del(esd->source);
318         free(esd);
319      }
320 }
321 
322 EOLIAN static Eina_Error
_elm_icon_efl_file_load(Eo * obj,Elm_Icon_Data * sd)323 _elm_icon_efl_file_load(Eo *obj, Elm_Icon_Data *sd)
324 {
325    Evas_Object *pclip;
326    const char *key;
327    Eina_Error err;
328 
329    if (efl_file_loaded_get(obj)) return 0;
330    err = efl_file_load(efl_super(obj, MY_CLASS));
331    if (err) return err;
332 
333    Efl_Ui_Image_Data *id = efl_data_scope_get(obj, EFL_UI_IMAGE_CLASS);
334 
335    _edje_signals_free(sd);
336 
337    if (!sd->freedesktop.use)
338      ELM_SAFE_FREE(sd->stdicon, eina_stringshare_del);
339 
340    if (!sd->is_video) return 0;
341 
342    /* parent's edje file setting path replicated here (we got .eet
343     * extension, so bypassing it) */
344    ELM_SAFE_FREE(id->prev_img, evas_object_del);
345 
346    if (!id->edje)
347      {
348         pclip = evas_object_clip_get(id->img);
349         evas_object_del(id->img);
350 
351         /* Edje object instead */
352         id->img = edje_object_add(evas_object_evas_get(obj));
353         evas_object_smart_member_add(id->img, obj);
354         if (id->show)
355           evas_object_show(id->img);
356         evas_object_clip_set(id->img, pclip);
357         id->edje = EINA_TRUE;
358      }
359    key = efl_file_key_get(obj);
360    efl_file_key_set(id->img, key);
361    err = efl_file_mmap_set(id->img, efl_file_mmap_get(obj));
362    if (!err) err = efl_file_load(id->img);
363    if (err)
364      {
365         ERR("failed to set edje file '%s', group '%s': %s", efl_file_get(id->img), key,
366             edje_load_error_str
367               (edje_object_load_error_get(id->img)));
368         return err;
369      }
370 
371    efl_gfx_entity_geometry_set(id->img, efl_gfx_entity_geometry_get(obj));
372 
373    return 0;
374 }
375 
376 EOLIAN static Eina_Error
_elm_icon_efl_ui_widget_theme_apply(Eo * obj,Elm_Icon_Data * sd)377 _elm_icon_efl_ui_widget_theme_apply(Eo *obj, Elm_Icon_Data *sd)
378 {
379    Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
380 
381    if (sd->stdicon)
382      _elm_theme_object_icon_set(obj, sd->stdicon, elm_widget_style_get(obj));
383 
384    int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
385    if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret;
386 
387    return int_ret;
388 }
389 
390 static Eina_Bool
_icon_standard_set(Evas_Object * obj,const char * name)391 _icon_standard_set(Evas_Object *obj,
392                    const char *name)
393 {
394    ELM_ICON_DATA_GET(obj, sd);
395 
396    if (_elm_theme_object_icon_set(obj, name, "default"))
397      {
398         /* TODO: elm_unneed_efreet() */
399         sd->freedesktop.use = EINA_FALSE;
400         return EINA_TRUE;
401      }
402 
403    return EINA_FALSE;
404 }
405 
406 static Eina_Bool
_icon_file_set(Elm_Icon_Data * sd,Evas_Object * obj,const char * path)407 _icon_file_set(Elm_Icon_Data *sd,
408                Evas_Object *obj,
409                const char *path)
410 {
411    if (elm_image_file_set(obj, path, NULL))
412      {
413         /* TODO: elm_unneed_efreet() */
414         sd->freedesktop.use = EINA_FALSE;
415         return EINA_TRUE;
416      }
417    return EINA_FALSE;
418 }
419 
420 static Eina_Bool
_internal_elm_icon_standard_set(Evas_Object * obj,const char * name,Eina_Bool * fdo)421 _internal_elm_icon_standard_set(Evas_Object *obj,
422                        const char *name,
423                        Eina_Bool *fdo)
424 {
425    char *tmp;
426    Eina_Bool ret = EINA_FALSE;
427 
428    ELM_ICON_DATA_GET(obj, sd);
429 
430    /* try locating the icon using the specified theme */
431    if (!strcmp(ELM_CONFIG_ICON_THEME_ELEMENTARY, elm_config_icon_theme_get()))
432      {
433         ret = _icon_standard_set(obj, name);
434         if (ret && fdo) *fdo = EINA_FALSE;
435 
436         if (!ret)
437           {
438              ret = _icon_freedesktop_set(obj, "hicolor", name, _icon_size_min_get(obj));
439              if (ret && fdo) *fdo = EINA_TRUE;
440           }
441      }
442    else
443      {
444         ret = _icon_freedesktop_set(obj, NULL, name, _icon_size_min_get(obj));
445         if (ret && fdo) *fdo = EINA_TRUE;
446      }
447 
448    if (ret)
449      {
450         eina_stringshare_replace(&sd->stdicon, name);
451         efl_canvas_group_change(obj);
452         return EINA_TRUE;
453      }
454 
455    if (_path_is_absolute(name))
456      {
457         if (fdo)
458           *fdo = EINA_FALSE;
459         return _icon_file_set(sd, obj, name);
460      }
461 
462    /* if that fails, see if icon name is in the format size/name. if so,
463       try locating a fallback without the size specification */
464    if (!(tmp = strchr(name, '/'))) return EINA_FALSE;
465    ++tmp;
466    if (*tmp) return _internal_elm_icon_standard_set(obj, tmp, fdo);
467    /* give up */
468    return EINA_FALSE;
469 }
470 
471 static void
_elm_icon_standard_resize_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)472 _elm_icon_standard_resize_cb(void *data,
473                              Evas *e EINA_UNUSED,
474                              Evas_Object *obj,
475                              void *event_info EINA_UNUSED)
476 {
477    ELM_ICON_DATA_GET(data, sd);
478    const char *refup = eina_stringshare_ref(sd->stdicon);
479    Eina_Bool fdo = EINA_FALSE;
480 
481    if (!_internal_elm_icon_standard_set(obj, sd->stdicon, &fdo) || (!fdo))
482      evas_object_event_callback_del_full
483        (obj, EVAS_CALLBACK_RESIZE, _elm_icon_standard_resize_cb, data);
484    eina_stringshare_del(refup);
485 }
486 
487 static void
_elm_icon_thumb_resize_cb(void * data,Evas * e EINA_UNUSED,Evas_Object * obj,void * event_info EINA_UNUSED)488 _elm_icon_thumb_resize_cb(void *data,
489                           Evas *e EINA_UNUSED,
490                           Evas_Object *obj,
491                           void *event_info EINA_UNUSED)
492 {
493    ELM_ICON_DATA_GET(data, sd);
494 
495    if (sd->thumb.file.path)
496      elm_icon_thumb_set(obj, sd->thumb.file.path, sd->thumb.file.key);
497 }
498 
499 EOLIAN static void
_elm_icon_efl_canvas_group_group_add(Eo * obj,Elm_Icon_Data * priv)500 _elm_icon_efl_canvas_group_group_add(Eo *obj, Elm_Icon_Data *priv)
501 {
502    efl_canvas_group_add(efl_super(obj, MY_CLASS));
503 
504    priv->thumb.request = NULL;
505 }
506 
507 EOLIAN static void
_elm_icon_efl_canvas_group_group_del(Eo * obj,Elm_Icon_Data * sd)508 _elm_icon_efl_canvas_group_group_del(Eo *obj, Elm_Icon_Data *sd)
509 {
510    eina_stringshare_del(sd->stdicon);
511 
512    if (sd->thumb.request)
513      {
514         Ethumb_Client *ethumbd = elm_thumb_ethumb_client_get();
515         if (ethumbd) _icon_thumb_stop(sd, ethumbd);
516      }
517 
518    eina_stringshare_del(sd->thumb.file.path);
519    eina_stringshare_del(sd->thumb.file.key);
520    eina_stringshare_del(sd->thumb.thumb.path);
521    eina_stringshare_del(sd->thumb.thumb.key);
522    ecore_event_handler_del(sd->thumb.eeh);
523 
524    _edje_signals_free(sd);
525 
526    efl_canvas_group_del(efl_super(obj, MY_CLASS));
527 }
528 
529 /* WARNING: to be deprecated */
530 void
_elm_icon_signal_emit(Evas_Object * obj,const char * emission,const char * source)531 _elm_icon_signal_emit(Evas_Object *obj,
532                       const char *emission,
533                       const char *source)
534 {
535 
536    Efl_Ui_Image_Data *id = efl_data_scope_get(obj, EFL_UI_IMAGE_CLASS);
537 
538    if (!id->edje) return;
539 
540    edje_object_signal_emit(id->img, emission, source);
541 }
542 
543 /* WARNING: to be deprecated */
544 void
_elm_icon_signal_callback_add(Evas_Object * obj,const char * emission,const char * source,Edje_Signal_Cb func_cb,void * data)545 _elm_icon_signal_callback_add(Evas_Object *obj,
546                               const char *emission,
547                               const char *source,
548                               Edje_Signal_Cb func_cb,
549                               void *data)
550 {
551    Edje_Signal_Data *esd;
552 
553    ELM_ICON_DATA_GET(obj, sd);
554    Efl_Ui_Image_Data *id = efl_data_scope_get(obj, EFL_UI_IMAGE_CLASS);
555 
556    if (!id->edje) return;
557 
558    esd = ELM_NEW(Edje_Signal_Data);
559    if (!esd) return;
560 
561    esd->obj = obj;
562    esd->func = func_cb;
563    esd->emission = eina_stringshare_add(emission);
564    esd->source = eina_stringshare_add(source);
565    esd->data = data;
566    sd->edje_signals =
567      eina_list_append(sd->edje_signals, esd);
568 
569    edje_object_signal_callback_add
570      (id->img, emission, source, _edje_signal_callback, esd);
571 }
572 
573 /* WARNING: to be deprecated */
574 void *
_elm_icon_signal_callback_del(Evas_Object * obj,const char * emission,const char * source,Edje_Signal_Cb func_cb)575 _elm_icon_signal_callback_del(Evas_Object *obj,
576                               const char *emission,
577                               const char *source,
578                               Edje_Signal_Cb func_cb)
579 {
580    Edje_Signal_Data *esd = NULL;
581    void *data = NULL;
582    Eina_List *l;
583 
584    ELM_ICON_DATA_GET(obj, sd);
585    Efl_Ui_Image_Data *id = efl_data_scope_get(obj, EFL_UI_IMAGE_CLASS);
586 
587    if (!id->edje) return NULL;
588 
589    EINA_LIST_FOREACH(sd->edje_signals, l, esd)
590      {
591         if ((esd->func == func_cb) && (!strcmp(esd->emission, emission)) &&
592             (!strcmp(esd->source, source)))
593           {
594              sd->edje_signals = eina_list_remove_list(sd->edje_signals, l);
595              eina_stringshare_del(esd->emission);
596              eina_stringshare_del(esd->source);
597              data = esd->data;
598 
599              edje_object_signal_callback_del_full
600                (id->img, emission, source,
601                _edje_signal_callback, esd);
602 
603              free(esd);
604 
605              return data; /* stop at 1st match */
606           }
607      }
608 
609    return data;
610 }
611 
612 EAPI Evas_Object *
elm_icon_add(Evas_Object * parent)613 elm_icon_add(Evas_Object *parent)
614 {
615    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
616    return elm_legacy_add(MY_CLASS, parent);
617 }
618 
619 EOLIAN static Eo *
_elm_icon_efl_object_constructor(Eo * obj,Elm_Icon_Data * sd)620 _elm_icon_efl_object_constructor(Eo *obj, Elm_Icon_Data *sd)
621 {
622    obj = efl_constructor(efl_super(obj, MY_CLASS));
623    sd->obj = obj;
624 
625    efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
626    evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
627    efl_access_object_role_set(obj, EFL_ACCESS_ROLE_ICON);
628 
629    return obj;
630 }
631 
632 static void
_elm_icon_class_constructor(Efl_Class * klass)633 _elm_icon_class_constructor(Efl_Class *klass)
634 {
635    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
636 }
637 
638 /* Legacy deprecated functions */
639 EAPI Eina_Bool
elm_icon_memfile_set(Evas_Object * obj,const void * img,size_t size,const char * format,const char * key)640 elm_icon_memfile_set(Evas_Object *obj,
641                      const void *img,
642                      size_t size,
643                      const char *format,
644                      const char *key)
645 {
646    ELM_ICON_CHECK(obj) EINA_FALSE;
647 
648    EINA_SAFETY_ON_NULL_RETURN_VAL(img, EINA_FALSE);
649    EINA_SAFETY_ON_TRUE_RETURN_VAL(!size, EINA_FALSE);
650 
651    ELM_ICON_DATA_GET(obj, sd);
652    ELM_SAFE_FREE(sd->stdicon, eina_stringshare_del);
653 
654    _edje_signals_free(sd);
655 
656    return elm_image_memfile_set(efl_super(obj, MY_CLASS), img, size, format, key);
657 }
658 
659 EAPI Eina_Bool
elm_icon_file_set(Evas_Object * obj,const char * file,const char * group)660 elm_icon_file_set(Evas_Object *obj,
661                   const char *file,
662                   const char *group)
663 {
664    ELM_ICON_CHECK(obj) EINA_FALSE;
665    EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
666 
667    return efl_file_simple_load(obj, file, group);
668 }
669 
670 EAPI void
elm_icon_file_get(const Evas_Object * obj,const char ** file,const char ** group)671 elm_icon_file_get(const Evas_Object *obj,
672                   const char **file,
673                   const char **group)
674 {
675    ELM_ICON_CHECK(obj);
676 
677    elm_image_file_get(obj, file, group);
678 }
679 
680 EAPI Eina_Bool
elm_icon_animated_available_get(const Evas_Object * obj)681 elm_icon_animated_available_get(const Evas_Object *obj)
682 {
683    ELM_ICON_CHECK(obj) EINA_FALSE;
684 
685    return elm_image_animated_available_get(obj);
686 }
687 
688 EAPI void
elm_icon_animated_set(Evas_Object * obj,Eina_Bool anim)689 elm_icon_animated_set(Evas_Object *obj,
690                       Eina_Bool anim)
691 {
692    ELM_ICON_CHECK(obj);
693 
694    return elm_image_animated_set(obj, anim);
695 }
696 
697 EAPI Eina_Bool
elm_icon_animated_get(const Evas_Object * obj)698 elm_icon_animated_get(const Evas_Object *obj)
699 {
700    ELM_ICON_CHECK(obj) EINA_FALSE;
701 
702    return elm_image_animated_get(obj);
703 }
704 
705 EAPI void
elm_icon_animated_play_set(Evas_Object * obj,Eina_Bool play)706 elm_icon_animated_play_set(Evas_Object *obj,
707                            Eina_Bool play)
708 {
709    ELM_ICON_CHECK(obj);
710 
711    elm_image_animated_play_set(obj, play);
712 }
713 
714 EAPI Eina_Bool
elm_icon_animated_play_get(const Evas_Object * obj)715 elm_icon_animated_play_get(const Evas_Object *obj)
716 {
717    ELM_ICON_CHECK(obj) EINA_FALSE;
718 
719    return elm_image_animated_play_get(obj);
720 }
721 
722 EAPI void
elm_icon_smooth_set(Evas_Object * obj,Eina_Bool smooth)723 elm_icon_smooth_set(Evas_Object *obj,
724                     Eina_Bool smooth)
725 {
726    ELM_ICON_CHECK(obj);
727 
728    elm_image_smooth_set(obj, smooth);
729 }
730 
731 EAPI Eina_Bool
elm_icon_smooth_get(const Evas_Object * obj)732 elm_icon_smooth_get(const Evas_Object *obj)
733 {
734    ELM_ICON_CHECK(obj) EINA_FALSE;
735 
736    return elm_image_smooth_get(obj);
737 }
738 
739 EAPI void
elm_icon_no_scale_set(Evas_Object * obj,Eina_Bool no_scale)740 elm_icon_no_scale_set(Evas_Object *obj,
741                       Eina_Bool no_scale)
742 {
743    ELM_ICON_CHECK(obj);
744 
745    elm_image_no_scale_set(obj, no_scale);
746 }
747 
748 EAPI Eina_Bool
elm_icon_no_scale_get(const Evas_Object * obj)749 elm_icon_no_scale_get(const Evas_Object *obj)
750 {
751    ELM_ICON_CHECK(obj) EINA_FALSE;
752 
753    return elm_image_no_scale_get(obj);
754 }
755 
756 EAPI void
elm_icon_resizable_set(Evas_Object * obj,Eina_Bool size_up,Eina_Bool size_down)757 elm_icon_resizable_set(Evas_Object *obj,
758                        Eina_Bool size_up,
759                        Eina_Bool size_down)
760 {
761    ELM_ICON_CHECK(obj);
762 
763    elm_image_resizable_set(obj, size_up, size_down);
764 }
765 
766 EAPI void
elm_icon_resizable_get(const Evas_Object * obj,Eina_Bool * size_up,Eina_Bool * size_down)767 elm_icon_resizable_get(const Evas_Object *obj,
768                        Eina_Bool *size_up,
769                        Eina_Bool *size_down)
770 {
771    ELM_ICON_CHECK(obj);
772 
773    elm_image_resizable_get(obj, size_up, size_down);
774 }
775 
776 EAPI void
elm_icon_fill_outside_set(Evas_Object * obj,Eina_Bool fill_outside)777 elm_icon_fill_outside_set(Evas_Object *obj,
778                           Eina_Bool fill_outside)
779 {
780    ELM_ICON_CHECK(obj);
781 
782    elm_image_fill_outside_set(obj, fill_outside);
783 }
784 
785 EAPI Eina_Bool
elm_icon_fill_outside_get(const Evas_Object * obj)786 elm_icon_fill_outside_get(const Evas_Object *obj)
787 {
788    ELM_ICON_CHECK(obj) EINA_FALSE;
789 
790    return elm_image_fill_outside_get(obj);
791 }
792 
793 EAPI void
elm_icon_size_get(const Evas_Object * obj,int * w,int * h)794 elm_icon_size_get(const Evas_Object *obj,
795                   int *w,
796                   int *h)
797 {
798    ELM_ICON_CHECK(obj);
799 
800    elm_image_object_size_get(obj, w, h);
801 }
802 
803 EAPI void
elm_icon_prescale_set(Evas_Object * obj,int size)804 elm_icon_prescale_set(Evas_Object *obj,
805                       int size)
806 {
807    ELM_ICON_CHECK(obj);
808 
809    elm_image_prescale_set(obj, size);
810 }
811 
812 EAPI int
elm_icon_prescale_get(const Evas_Object * obj)813 elm_icon_prescale_get(const Evas_Object *obj)
814 {
815    ELM_ICON_CHECK(obj) 0;
816 
817    return elm_image_prescale_get(obj);
818 }
819 
820 EAPI Evas_Object *
elm_icon_object_get(Evas_Object * obj)821 elm_icon_object_get(Evas_Object *obj)
822 {
823    ELM_ICON_CHECK(obj) 0;
824 
825    return elm_image_object_get(obj);
826 }
827 
828 EAPI void
elm_icon_preload_disabled_set(Evas_Object * obj,Eina_Bool disabled)829 elm_icon_preload_disabled_set(Evas_Object *obj,
830                               Eina_Bool disabled)
831 {
832    ELM_ICON_CHECK(obj);
833 
834    elm_image_preload_disabled_set(obj, disabled);
835 }
836 
837 EAPI void
elm_icon_aspect_fixed_set(Evas_Object * obj,Eina_Bool fixed)838 elm_icon_aspect_fixed_set(Evas_Object *obj,
839                           Eina_Bool fixed)
840 {
841    ELM_ICON_CHECK(obj);
842 
843    elm_image_aspect_fixed_set(obj, fixed);
844 }
845 
846 EAPI Eina_Bool
elm_icon_aspect_fixed_get(const Evas_Object * obj)847 elm_icon_aspect_fixed_get(const Evas_Object *obj)
848 {
849    ELM_ICON_CHECK(obj) EINA_FALSE;
850 
851    return elm_image_aspect_fixed_get(obj);
852 }
853 
854 EAPI void
elm_icon_thumb_set(Evas_Object * obj,const char * file,const char * group)855 elm_icon_thumb_set(Evas_Object *obj, const char *file, const char *group)
856 {
857    ELM_ICON_CHECK(obj);
858    ELM_ICON_DATA_GET(obj, sd);
859 
860    evas_object_event_callback_del_full
861      (obj, EVAS_CALLBACK_RESIZE, _elm_icon_standard_resize_cb, obj);
862    evas_object_event_callback_del_full
863      (obj, EVAS_CALLBACK_RESIZE, _elm_icon_thumb_resize_cb, obj);
864 
865    evas_object_event_callback_add
866      (obj, EVAS_CALLBACK_RESIZE, _elm_icon_thumb_resize_cb, obj);
867 
868    eina_stringshare_replace(&sd->thumb.file.path, file);
869    eina_stringshare_replace(&sd->thumb.file.key, group);
870 
871    if (elm_thumb_ethumb_client_connected_get())
872      {
873         _icon_thumb_apply(sd);
874         return;
875      }
876 
877    if (!sd->thumb.eeh)
878      {
879         sd->thumb.eeh = ecore_event_handler_add
880             (ELM_ECORE_EVENT_ETHUMB_CONNECT, _icon_thumb_apply_cb, obj);
881      }
882 }
883 
884 EAPI Eina_Bool
elm_icon_standard_set(Evas_Object * obj,const char * name)885 elm_icon_standard_set(Evas_Object *obj, const char *name)
886 {
887    Eina_Bool fdo = EINA_FALSE;
888 
889    ELM_ICON_CHECK(obj) EINA_FALSE;
890 
891    if (!name) return EINA_FALSE;
892 
893    evas_object_event_callback_del_full
894      (obj, EVAS_CALLBACK_RESIZE, _elm_icon_standard_resize_cb, obj);
895 
896    Eina_Bool int_ret = _internal_elm_icon_standard_set(obj, name, &fdo);
897 
898    if (fdo)
899      evas_object_event_callback_add
900        (obj, EVAS_CALLBACK_RESIZE, _elm_icon_standard_resize_cb, obj);
901 
902    return int_ret;
903 }
904 
905 EAPI const char*
elm_icon_standard_get(const Evas_Object * obj)906 elm_icon_standard_get(const Evas_Object *obj)
907 {
908    ELM_ICON_CHECK(obj) NULL;
909    ELM_ICON_DATA_GET(obj, sd);
910 
911    return sd->stdicon;
912 }
913 
914 EAPI void
elm_icon_order_lookup_set(Evas_Object * obj EINA_UNUSED,Elm_Icon_Lookup_Order order EINA_UNUSED)915 elm_icon_order_lookup_set(Evas_Object *obj EINA_UNUSED,
916                            Elm_Icon_Lookup_Order order EINA_UNUSED)
917 {
918    // this method's behaviour has been overridden by elm_config_icon_theme_set
919 }
920 
921 EAPI Elm_Icon_Lookup_Order
elm_icon_order_lookup_get(const Evas_Object * obj EINA_UNUSED)922 elm_icon_order_lookup_get(const Evas_Object *obj EINA_UNUSED)
923 {
924    return ELM_ICON_LOOKUP_FDO_THEME;
925 }
926 
927 /* Internal EO APIs and hidden overrides */
928 
929 #define ELM_ICON_EXTRA_OPS \
930    EFL_CANVAS_GROUP_ADD_DEL_OPS(elm_icon)
931 
932 #include "elm_icon_eo.c"
933