From f932419989ce413ccc6428980fe348540c5fe962 Mon Sep 17 00:00:00 2001 From: Leandro Pereira Date: Thu, 14 Oct 2010 22:21:43 +0000 Subject: [PATCH] [Elementary] Make it possible to lookup icons from Freedesktop in Elm_Icon. With these changes, Elm_Icon will also look up icons from the chosen Freedesktop (fd.o) icon theme. Since this might incur in some performance penalties if you're sure only theme icons will be used, icon lookup order may be specified with the elm_icon_order_lookup_set() function call; using the lookup parameter as follows: - ELM_ICON_ORDER_FDO_THEME (default) will look up first fd.o, then the theme; - ELM_ICON_ORDER_THEME_FDO will look up first the theme, then fd.o; - ELM_ICON_ORDER_FDO will look up only fd.o; and - ELM_ICON_ORDER_THEME (old behaviour) will lookup only from the theme. Elm_Icon will also try to use a different resolution image if the widget is resized and the image source is fd.o. fd.o support requires Efreet, but it should work nicely (falling back to the old behaviour) if it isn't available. SVN revision: 53433 --- src/bin/test_toolbar.c | 8 +-- src/lib/Elementary.h.in | 37 +++++++----- src/lib/elm_icon.c | 147 +++++++++++++++++++++++++++++++++++++++++++++--- src/lib/elm_toolbar.c | 3 +- 4 files changed, 169 insertions(+), 26 deletions(-) diff --git a/src/bin/test_toolbar.c b/src/bin/test_toolbar.c index 534c77e..e95404c 100644 --- a/src/bin/test_toolbar.c +++ b/src/bin/test_toolbar.c @@ -72,17 +72,17 @@ test_toolbar(void *data, Evas_Object *obj, void *event_info) ph3 = elm_photo_add(win); ph4 = elm_photo_add(win); - item = elm_toolbar_item_add(tb, "arrow_left", "Hello", tb_1, ph1); + item = elm_toolbar_item_add(tb, "document-print", "Hello", tb_1, ph1); elm_toolbar_item_disabled_set(item, EINA_TRUE); elm_toolbar_item_priority_set(item, 100); - item = elm_toolbar_item_add(tb, "arrow_right", "World", tb_2, ph1); + item = elm_toolbar_item_add(tb, "folder-new", "World", tb_2, ph1); elm_toolbar_item_priority_set(item, -100); - item = elm_toolbar_item_add(tb, "home", "H", tb_3, ph4); + item = elm_toolbar_item_add(tb, "object-rotate-right", "H", tb_3, ph4); elm_toolbar_item_priority_set(item, 150); - item = elm_toolbar_item_add(tb, "chat", "Comes", tb_4, ph4); + item = elm_toolbar_item_add(tb, "mail-send", "Comes", tb_4, ph4); elm_toolbar_item_priority_set(item, 0); item = elm_toolbar_item_add(tb, "clock", "Elementary", tb_5, ph4); diff --git a/src/lib/Elementary.h.in b/src/lib/Elementary.h.in index ea36366..74f9001 100644 --- a/src/lib/Elementary.h.in +++ b/src/lib/Elementary.h.in @@ -250,6 +250,14 @@ extern "C" { ELM_TOOLBAR_SHRINK_MENU /**< inserts a button to pop up a menu with excess items */ } Elm_Toolbar_Shrink_Mode; + typedef enum _Elm_Icon_Lookup_Order + { + ELM_ICON_LOOKUP_FDO_THEME, /**< icon look up order: freedesktop, theme */ + ELM_ICON_LOOKUP_THEME_FDO, /**< icon look up order: theme, freedesktop */ + ELM_ICON_LOOKUP_FDO, /**< icon look up order: freedesktop */ + ELM_ICON_LOOKUP_THEME /**< icon look up order: theme */ + } Elm_Icon_Lookup_Order; + /** * Called back when a widget's tooltip is activated and needs content. * @param data user-data given to elm_object_tooltip_content_cb_set() @@ -365,10 +373,10 @@ extern "C" { EAPI void elm_theme_full_flush(void); EAPI void elm_theme_all_set(const char *theme); - + EAPI Eina_List *elm_theme_name_available_list_new(void); EAPI void elm_theme_name_available_list_free(Eina_List *list); - + EAPI void elm_object_theme_set(Evas_Object *obj, Elm_Theme *th); EAPI Elm_Theme *elm_object_theme_get(Evas_Object *obj); @@ -471,14 +479,17 @@ extern "C" { /* smart callbacks called: */ - EAPI Evas_Object *elm_icon_add(Evas_Object *parent); - EAPI Eina_Bool elm_icon_file_set(Evas_Object *obj, const char *file, const char *group); - EAPI Eina_Bool elm_icon_standard_set(Evas_Object *obj, const char *name); - EAPI void elm_icon_smooth_set(Evas_Object *obj, Eina_Bool smooth); - EAPI void elm_icon_no_scale_set(Evas_Object *obj, Eina_Bool no_scale); - EAPI void elm_icon_scale_set(Evas_Object *obj, Eina_Bool scale_up, Eina_Bool scale_down); - EAPI void elm_icon_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside); - EAPI void elm_icon_prescale_set(Evas_Object *obj, int size); + EAPI Evas_Object *elm_icon_add(Evas_Object *parent); + EAPI Eina_Bool elm_icon_file_set(Evas_Object *obj, const char *file, const char *group); + EAPI Eina_Bool elm_icon_standard_set(Evas_Object *obj, const char *name); + EAPI Eina_Bool elm_icon_freedesktop_set(Evas_Object *obj, const char *name, int size); + EAPI void elm_icon_smooth_set(Evas_Object *obj, Eina_Bool smooth); + EAPI void elm_icon_no_scale_set(Evas_Object *obj, Eina_Bool no_scale); + EAPI void elm_icon_scale_set(Evas_Object *obj, Eina_Bool scale_up, Eina_Bool scale_down); + EAPI void elm_icon_fill_outside_set(Evas_Object *obj, Eina_Bool fill_outside); + EAPI void elm_icon_prescale_set(Evas_Object *obj, int size); + EAPI void elm_icon_order_lookup_set(Evas_Object *obj, Elm_Icon_Lookup_Order order); + EAPI Elm_Icon_Lookup_Order elm_icon_order_lookup_get(Evas_Object *obj); /* smart callbacks called: * "clicked" - the user clicked the icon */ @@ -1070,7 +1081,7 @@ extern "C" { EAPI void elm_bubble_corner_set(Evas_Object *obj, const char *corner); /* smart callbacks called: */ - + EAPI Evas_Object *elm_photo_add(Evas_Object *parent); EAPI Eina_Bool elm_photo_file_set(Evas_Object *obj, const char *file); EAPI void elm_photo_size_set(Evas_Object *obj, int size); @@ -1929,12 +1940,12 @@ extern "C" { /* animator */ typedef struct _Animator Elm_Animator; - typedef enum {ELM_ANIMATOR_CURVE_LINEAR, ELM_ANIMATOR_CURVE_IN_OUT, ELM_ANIMATOR_CURVE_IN, ELM_ANIMATOR_CURVE_OUT} Elm_Animator_Curve_Style; + typedef enum {ELM_ANIMATOR_CURVE_LINEAR, ELM_ANIMATOR_CURVE_IN_OUT, ELM_ANIMATOR_CURVE_IN, ELM_ANIMATOR_CURVE_OUT} Elm_Animator_Curve_Style; EAPI Elm_Animator* elm_animator_add(Evas_Object *parent); EAPI void elm_animator_del(Elm_Animator *animator); EAPI void elm_animator_duration_set(Elm_Animator *animator, double duration); - EAPI void elm_animator_operation_callback_set(Elm_Animator *animator, void (*func)(void *data, Elm_Animator *animator, double frame), void *data); + EAPI void elm_animator_operation_callback_set(Elm_Animator *animator, void (*func)(void *data, Elm_Animator *animator, double frame), void *data); EAPI void elm_animator_completion_callback_set(Elm_Animator *animator, void (*func)(void *data), void *data); EAPI void elm_animator_stop(Elm_Animator *animator); EAPI void elm_animator_repeat_set(Elm_Animator *animator, unsigned int repeat_cnt); diff --git a/src/lib/elm_icon.c b/src/lib/elm_icon.c index dde8168..b35db5f 100644 --- a/src/lib/elm_icon.c +++ b/src/lib/elm_icon.c @@ -8,9 +8,9 @@ * arrows etc.) or a custom file (PNG, JPG, EDJE etc.) used for an * icon. The Icon may scale or not and of course... support alpha * channels. - * + * * Signals that you can add callbacks for are: - * + * * clicked - This is called when a user has clicked the icon */ @@ -20,6 +20,13 @@ struct _Widget_Data { Evas_Object *img; const char *stdicon; + Elm_Icon_Lookup_Order lookup_order; +#ifdef ELM_EFREET + struct { + int requested_size; + Eina_Bool use : 1; + } freedesktop; +#endif Eina_Bool scale_up : 1; Eina_Bool scale_down : 1; Eina_Bool smooth : 1; @@ -33,6 +40,9 @@ static void _theme_hook(Evas_Object *obj); static void _sizing_eval(Evas_Object *obj); static void _mouse_up(void *data, Evas *e, Evas_Object *obj, void *event_info); +static Eina_Bool _icon_standard_set(Widget_Data *wd, Evas_Object *obj, const char *name); +static Eina_Bool _icon_freedesktop_set(Widget_Data *wd, Evas_Object *obj, const char *name, int size); + static void _del_hook(Evas_Object *obj) { @@ -62,6 +72,18 @@ _sizing_eval(Evas_Object *obj) int w, h; _els_smart_icon_size_get(wd->img, &w, &h); +#ifdef ELM_EFREET + if (wd->freedesktop.use && !((w - wd->freedesktop.requested_size) % 16)) + { + /* This icon has been set to a freedesktop icon, and the requested + appears to have a different size than the requested size, so try to + request another, higher resolution, icon. + FIXME: Find a better heuristic to determine if there should be + an icon with a different resolution. */ + if (!_icon_freedesktop_set(wd, obj, wd->stdicon, w)) + wd->freedesktop.use = EINA_TRUE; + } +#endif _els_smart_icon_scale_up_set(wd->img, wd->scale_up); _els_smart_icon_scale_down_set(wd->img, wd->scale_down); _els_smart_icon_smooth_scale_set(wd->img, wd->smooth); @@ -121,6 +143,7 @@ elm_icon_add(Evas_Object *parent) elm_widget_del_hook_set(obj, _del_hook); elm_widget_theme_hook_set(obj, _theme_hook); + wd->lookup_order = ELM_ICON_LOOKUP_FDO_THEME; wd->img = _els_smart_icon_add(e); evas_object_event_callback_add(wd->img, EVAS_CALLBACK_MOUSE_UP, _mouse_up, obj); @@ -165,6 +188,47 @@ elm_icon_file_set(Evas_Object *obj, const char *file, const char *group) return ret; } +static Eina_Bool +_icon_standard_set(Widget_Data *wd, Evas_Object *obj, const char *name) +{ + if (_elm_theme_object_icon_set(obj, wd->img, name, "default")) + { +#ifdef ELM_EFREET + wd->freedesktop.use = EINA_FALSE; +#endif + return EINA_TRUE; + } + return EINA_FALSE; +} + +static Eina_Bool +_icon_freedesktop_set(Widget_Data *wd, Evas_Object *obj, const char *name, int size) +{ +#ifdef ELM_EFREET + char *path; + + elm_need_efreet(); + path = efreet_icon_path_find(getenv("E_ICON_THEME"), name, size); + if (!path) + { + const char **itr; + static const char *themes[] = { + "default", "highcolor", "hicolor", "gnome", "Human", "oxygen", NULL + }; + for (itr = themes; !path && *itr; itr++) + path = efreet_icon_path_find(*itr, name, size); + } + if ((wd->freedesktop.use = !!path)) + { + wd->freedesktop.requested_size = size; + elm_icon_file_set(obj, path, NULL); + free(path); + return EINA_TRUE; + } +#endif + return EINA_FALSE; +} + /** * Set the theme, as standard, for a icon * @@ -180,13 +244,82 @@ elm_icon_standard_set(Evas_Object *obj, const char *name) { ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE; Widget_Data *wd = elm_widget_data_get(obj); - Eina_Bool ret; + char *tmp; + Eina_Bool ret = EINA_FALSE; if ((!wd) || (!name)) return EINA_FALSE; - eina_stringshare_replace(&wd->stdicon, name); - ret = _elm_theme_object_icon_set(obj, wd->img, name, "default"); - _sizing_eval(obj); - return ret; + + /* try locating the icon using the specified lookup order */ + switch (wd->lookup_order) + { + case ELM_ICON_LOOKUP_FDO: + ret = _icon_freedesktop_set(wd, obj, name, 48) || + _icon_freedesktop_set(wd, obj, name, 32); + break; + case ELM_ICON_LOOKUP_THEME: + ret = _icon_standard_set(wd, obj, name); + break; + case ELM_ICON_LOOKUP_THEME_FDO: + ret = _icon_standard_set(wd, obj, name) || + _icon_freedesktop_set(wd, obj, name, 48) || + _icon_freedesktop_set(wd, obj, name, 32); + break; + case ELM_ICON_LOOKUP_FDO_THEME: + default: + ret = _icon_freedesktop_set(wd, obj, name, 48) || + _icon_freedesktop_set(wd, obj, name, 32) || + _icon_standard_set(wd, obj, name); + break; + } + + if (ret) + { + eina_stringshare_replace(&wd->stdicon, name); + _sizing_eval(obj); + return EINA_TRUE; + } + + /* if that fails, see if icon name is in the format size/name. if so, + try locating a fallback without the size specification */ + if (!(tmp = strchr(name, '/'))) return EINA_FALSE; + ++tmp; + if (*tmp) return elm_icon_standard_set(obj, tmp); + + /* give up */ + return EINA_FALSE; +} + +/** + * Sets icon lookup order, used by elm_icon_standard_set(). + * + * @param obj The icon object + * @param order The icon lookup order + * + * @ingroup Icon + */ +EAPI void +elm_icon_order_lookup_set(Evas_Object *obj, Elm_Icon_Lookup_Order order) +{ + ELM_CHECK_WIDTYPE(obj, widtype); + Widget_Data *wd = elm_widget_data_get(obj); + if (wd) wd->lookup_order = order; +} + +/** + * Gets the icon lookup order. + * + * @param obj The icon object + * @return The icon lookup order + * + * @ingroup Icon + */ +EAPI Elm_Icon_Lookup_Order +elm_icon_order_lookup_get(Evas_Object *obj) +{ + ELM_CHECK_WIDTYPE(obj, widtype) ELM_ICON_LOOKUP_FDO_THEME; + Widget_Data *wd = elm_widget_data_get(obj); + if (!wd) return ELM_ICON_LOOKUP_FDO_THEME; + return wd->lookup_order; } /** diff --git a/src/lib/elm_toolbar.c b/src/lib/elm_toolbar.c index f5d89a8..35a584b 100644 --- a/src/lib/elm_toolbar.c +++ b/src/lib/elm_toolbar.c @@ -59,14 +59,13 @@ _item_icon_set(Evas_Object *icon_obj, const char *type, const char *icon) char icon_str[512]; if (!type || !*type) goto end; + if (!icon || !*icon) return EINA_FALSE; if (snprintf(icon_str, sizeof(icon_str), "%s%s", type, icon) > 0 && elm_icon_standard_set(icon_obj, icon_str)) return EINA_TRUE; - end: if (elm_icon_standard_set(icon_obj, icon)) return EINA_TRUE; - WRN("couldn't find icon definition for '%s'", icon); return EINA_FALSE; } -- 2.7.4