[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
This commit is contained in:
Leandro Pereira 2010-10-14 22:21:43 +00:00
parent 8c518f2dae
commit c563ef2370
4 changed files with 169 additions and 26 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
/**

View File

@ -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;
}