2008-09-29 23:58:56 -07:00
|
|
|
#include <Elementary.h>
|
|
|
|
#include "elm_priv.h"
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
static Elm_Theme theme_default =
|
|
|
|
{
|
2011-09-11 18:05:07 -07:00
|
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1
|
2010-05-11 18:03:46 -07:00
|
|
|
};
|
|
|
|
|
2009-01-13 01:20:53 -08:00
|
|
|
static Eina_List *themes = NULL;
|
2010-05-11 18:03:46 -07:00
|
|
|
|
|
|
|
static void
|
|
|
|
_elm_theme_clear(Elm_Theme *th)
|
|
|
|
{
|
|
|
|
const char *p;
|
|
|
|
EINA_LIST_FREE(th->themes, p)
|
|
|
|
eina_stringshare_del(p);
|
|
|
|
EINA_LIST_FREE(th->overlay, p)
|
|
|
|
eina_stringshare_del(p);
|
|
|
|
EINA_LIST_FREE(th->extension, p)
|
|
|
|
eina_stringshare_del(p);
|
|
|
|
if (th->cache)
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
eina_hash_free(th->cache);
|
|
|
|
th->cache = NULL;
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
2011-09-11 18:05:07 -07:00
|
|
|
if (th->cache_data)
|
|
|
|
{
|
|
|
|
eina_hash_free(th->cache_data);
|
|
|
|
th->cache_data = NULL;
|
|
|
|
}
|
2010-05-11 18:03:46 -07:00
|
|
|
if (th->theme)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(th->theme);
|
|
|
|
th->theme = NULL;
|
|
|
|
}
|
2011-04-01 04:20:18 -07:00
|
|
|
if (th->ref_theme)
|
|
|
|
{
|
|
|
|
th->ref_theme->referrers =
|
|
|
|
eina_list_remove(th->ref_theme->referrers, th);
|
|
|
|
elm_theme_free(th->ref_theme);
|
|
|
|
th->ref_theme = NULL;
|
|
|
|
}
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
2009-01-13 01:20:53 -08:00
|
|
|
|
2009-02-23 00:40:58 -08:00
|
|
|
static const char *
|
2010-05-11 18:03:46 -07:00
|
|
|
_elm_theme_find_try(Elm_Theme *th, const char *f, const char *group)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
|
|
|
const char *file;
|
2009-07-06 23:46:51 -07:00
|
|
|
|
2009-02-23 00:40:58 -08:00
|
|
|
if (edje_file_group_exists(f, group))
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
file = eina_stringshare_add(f);
|
|
|
|
if (file)
|
|
|
|
{
|
|
|
|
eina_hash_add(th->cache, group, file);
|
|
|
|
return file;
|
|
|
|
}
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
2010-05-11 18:03:46 -07:00
|
|
|
_elm_theme_theme_element_try(Elm_Theme *th, const char *home, const char *f, const char *group)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
const char *file = NULL;
|
2009-07-06 23:46:51 -07:00
|
|
|
|
2009-10-27 12:32:50 -07:00
|
|
|
if ((f[0] == '/') || ((f[0] == '.') && (f[1] == '/')) ||
|
2010-03-19 11:24:58 -07:00
|
|
|
((f[0] == '.') && (f[1] == '.') && (f[2] == '/')) ||
|
2010-10-22 14:41:22 -07:00
|
|
|
((isalpha(f[0])) && (f[1] == ':')))
|
2010-05-11 18:03:46 -07:00
|
|
|
return _elm_theme_find_try(th, f, group);
|
2009-02-23 00:40:58 -08:00
|
|
|
else if (((f[0] == '~') && (f[1] == '/')))
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
snprintf(buf, sizeof(buf), "%s/%s", home, f + 2);
|
|
|
|
return _elm_theme_find_try(th, buf, group);
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
2012-01-19 09:12:15 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%s/"ELEMENTARY_BASE_DIR"/themes/%s.edj", home, f);
|
2010-05-11 18:03:46 -07:00
|
|
|
file = _elm_theme_find_try(th, buf, group);
|
2009-02-23 00:40:58 -08:00
|
|
|
if (file) return file;
|
|
|
|
snprintf(buf, sizeof(buf), "%s/themes/%s.edj", _elm_data_dir, f);
|
2010-05-11 18:03:46 -07:00
|
|
|
file = _elm_theme_find_try(th, buf, group);
|
2009-04-22 20:51:50 -07:00
|
|
|
return file;
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
|
|
|
|
2009-01-13 01:20:53 -08:00
|
|
|
static const char *
|
2010-05-11 18:03:46 -07:00
|
|
|
_elm_theme_group_file_find(Elm_Theme *th, const char *group)
|
2009-01-13 01:20:53 -08:00
|
|
|
{
|
2009-02-25 11:50:45 -08:00
|
|
|
const Eina_List *l;
|
|
|
|
const char *f;
|
2009-01-13 01:20:53 -08:00
|
|
|
static const char *home = NULL;
|
2010-05-11 18:03:46 -07:00
|
|
|
const char *file = eina_hash_find(th->cache, group);
|
2009-10-27 12:32:50 -07:00
|
|
|
|
2009-01-13 01:20:53 -08:00
|
|
|
if (file) return file;
|
|
|
|
if (!home)
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
home = getenv("HOME");
|
|
|
|
if (!home) home = "";
|
2009-01-13 01:20:53 -08:00
|
|
|
}
|
2010-05-11 18:03:46 -07:00
|
|
|
EINA_LIST_FOREACH(th->overlay, l, f)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
file = _elm_theme_theme_element_try(th, home, f, group);
|
|
|
|
if (file) return file;
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
2010-05-11 18:03:46 -07:00
|
|
|
EINA_LIST_FOREACH(th->themes, l, f)
|
2009-01-13 01:20:53 -08:00
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
file = _elm_theme_theme_element_try(th, home, f, group);
|
|
|
|
if (file) return file;
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
2010-05-11 18:03:46 -07:00
|
|
|
EINA_LIST_FOREACH(th->extension, l, f)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
file = _elm_theme_theme_element_try(th, home, f, group);
|
|
|
|
if (file) return file;
|
2009-01-13 01:20:53 -08:00
|
|
|
}
|
2010-11-05 01:37:31 -07:00
|
|
|
if (th->ref_theme) return _elm_theme_group_file_find(th->ref_theme, group);
|
2009-01-13 01:20:53 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-09-11 18:05:07 -07:00
|
|
|
static const char *
|
|
|
|
_elm_theme_find_data_try(Elm_Theme *th, const char *f, const char *key)
|
|
|
|
{
|
|
|
|
char *data;
|
|
|
|
const char *t;
|
|
|
|
|
|
|
|
data = edje_file_data_get(f, key);
|
|
|
|
t = eina_stringshare_add(data);
|
|
|
|
free(data);
|
|
|
|
if (t)
|
|
|
|
{
|
|
|
|
eina_hash_add(th->cache, key, t);
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
_elm_theme_theme_data_try(Elm_Theme *th, const char *home, const char *f, const char *key)
|
|
|
|
{
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
const char *data = NULL;
|
|
|
|
|
|
|
|
if ((f[0] == '/') || ((f[0] == '.') && (f[1] == '/')) ||
|
|
|
|
((f[0] == '.') && (f[1] == '.') && (f[2] == '/')) ||
|
|
|
|
((isalpha(f[0])) && (f[1] == ':')))
|
|
|
|
return _elm_theme_find_data_try(th, f, key);
|
|
|
|
else if (((f[0] == '~') && (f[1] == '/')))
|
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "%s/%s", home, f + 2);
|
|
|
|
return _elm_theme_find_try(th, buf, key);
|
|
|
|
}
|
2012-01-19 09:12:15 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%s/"ELEMENTARY_BASE_DIR"/themes/%s.edj", home, f);
|
2011-09-11 18:05:07 -07:00
|
|
|
data = _elm_theme_find_data_try(th, buf, key);
|
|
|
|
if (data) return data;
|
|
|
|
snprintf(buf, sizeof(buf), "%s/themes/%s.edj", _elm_data_dir, f);
|
|
|
|
data = _elm_theme_find_data_try(th, buf, key);
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
_elm_theme_data_find(Elm_Theme *th, const char *key)
|
|
|
|
{
|
|
|
|
const Eina_List *l;
|
|
|
|
const char *f;
|
|
|
|
static const char *home = NULL;
|
|
|
|
const char *data = eina_hash_find(th->cache_data, key);
|
|
|
|
|
|
|
|
if (data) return data;
|
|
|
|
if (!home)
|
|
|
|
{
|
|
|
|
home = getenv("HOME");
|
|
|
|
if (!home) home = "";
|
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(th->overlay, l, f)
|
|
|
|
{
|
|
|
|
data = _elm_theme_theme_data_try(th, home, f, key);
|
|
|
|
if (data) return data;
|
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(th->themes, l, f)
|
|
|
|
{
|
|
|
|
data = _elm_theme_theme_data_try(th, home, f, key);
|
|
|
|
if (data) return data;
|
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(th->extension, l, f)
|
|
|
|
{
|
|
|
|
data = _elm_theme_theme_data_try(th, home, f, key);
|
|
|
|
if (data) return data;
|
|
|
|
}
|
|
|
|
if (th->ref_theme) return _elm_theme_data_find(th->ref_theme, key);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-05-09 03:46:14 -07:00
|
|
|
static void _elm_theme_idler_clean(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__);
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_elm_theme_reload_idler(void *data)
|
|
|
|
{
|
|
|
|
Evas_Object *elm = data;
|
|
|
|
|
|
|
|
elm_widget_theme(elm);
|
|
|
|
evas_object_data_del(elm, "elm-theme-reload-idler");
|
|
|
|
evas_object_event_callback_del(elm, EVAS_CALLBACK_DEL, _elm_theme_idler_clean);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_elm_theme_idler_clean(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
|
|
|
|
{
|
|
|
|
Ecore_Idler *idler;
|
|
|
|
|
|
|
|
idler = evas_object_data_get(obj, "elm-theme-reload-idler");
|
|
|
|
if (idler) ecore_idler_del(idler);
|
|
|
|
evas_object_data_del(obj, "elm-theme-reload-idler");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_elm_theme_reload(void *data __UNUSED__, Evas_Object *obj,
|
|
|
|
const char *emission __UNUSED__, const char *source __UNUSED__)
|
|
|
|
{
|
|
|
|
Evas_Object *elm;
|
|
|
|
|
|
|
|
elm = evas_object_data_get(obj, "elm-parent");
|
|
|
|
if (elm)
|
|
|
|
{
|
|
|
|
evas_object_event_callback_add(elm, EVAS_CALLBACK_DEL, _elm_theme_idler_clean, NULL);
|
|
|
|
evas_object_data_set(elm, "elm-theme-reload-idler", ecore_idler_add(_elm_theme_reload_idler, elm));
|
|
|
|
}
|
2013-02-19 00:22:15 -08:00
|
|
|
}
|
2012-05-09 03:46:14 -07:00
|
|
|
|
2013-02-19 00:22:15 -08:00
|
|
|
int
|
|
|
|
_elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style, Eina_Bool orient_on, int orient_mode)
|
2010-05-11 18:03:46 -07:00
|
|
|
{
|
|
|
|
Elm_Theme *th = NULL;
|
2012-05-09 03:46:14 -07:00
|
|
|
void *test;
|
2013-02-19 00:22:15 -08:00
|
|
|
int ret;
|
2012-05-09 03:46:14 -07:00
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
if (parent) th = elm_widget_theme_get(parent);
|
2013-02-19 00:22:15 -08:00
|
|
|
ret = _elm_theme_set(th, o, clas, group, style, orient_on, orient_mode);
|
|
|
|
if (ret == -1) return -1;
|
2013-02-17 21:15:17 -08:00
|
|
|
|
2012-05-09 03:46:14 -07:00
|
|
|
test = evas_object_data_get(o, "edje,theme,watcher");
|
|
|
|
if (!test)
|
|
|
|
{
|
2013-02-17 21:15:17 -08:00
|
|
|
edje_object_signal_callback_add(o, "edje,change,file", "edje",
|
|
|
|
_elm_theme_reload, NULL);
|
2012-05-09 03:46:14 -07:00
|
|
|
evas_object_data_set(o, "edje,theme,watcher", (void*) -1);
|
|
|
|
}
|
2013-02-19 00:22:15 -08:00
|
|
|
return ret;
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
2012-05-25 12:53:59 -07:00
|
|
|
/* only issued by elm_icon.c */
|
2010-10-21 11:58:37 -07:00
|
|
|
Eina_Bool
|
2012-05-25 12:53:59 -07:00
|
|
|
_elm_theme_object_icon_set(Evas_Object *o,
|
|
|
|
const char *group,
|
|
|
|
const char *style)
|
2010-05-11 18:03:46 -07:00
|
|
|
{
|
2012-05-25 12:53:59 -07:00
|
|
|
Elm_Theme *th = elm_widget_theme_get(o);
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
return _elm_theme_icon_set(th, o, group, style);
|
|
|
|
}
|
|
|
|
|
2013-02-19 00:22:15 -08:00
|
|
|
int
|
|
|
|
_elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *group, const char *style, Eina_Bool orient_on, int orient_mode)
|
2010-05-11 18:03:46 -07:00
|
|
|
{
|
|
|
|
const char *file;
|
|
|
|
char buf2[1024];
|
|
|
|
|
2013-02-19 00:22:15 -08:00
|
|
|
if ((!clas) || (!group) || (!style)) return -1;
|
2010-05-11 18:03:46 -07:00
|
|
|
if (!th) th = &(theme_default);
|
2013-02-19 00:22:15 -08:00
|
|
|
|
|
|
|
//First Try. Apply orient mode.
|
|
|
|
if (orient_mode > 0)
|
|
|
|
{
|
|
|
|
snprintf(buf2, sizeof(buf2), "elm/%s/%s/%d/%s", clas, group,
|
|
|
|
orient_mode, style);
|
|
|
|
file = _elm_theme_group_file_find(th, buf2);
|
|
|
|
if (file)
|
|
|
|
{
|
|
|
|
if (edje_object_file_set(o, file, buf2)) return orient_mode;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DBG("could not set theme group '%s' from file '%s': %s",
|
|
|
|
buf2, file,
|
|
|
|
edje_load_error_str(edje_object_load_error_get(o)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (orient_on && evas_object_data_get(o, "edje,theme,watcher"))
|
|
|
|
return orient_mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Second Try. Use the default group.
|
2010-05-11 18:03:46 -07:00
|
|
|
snprintf(buf2, sizeof(buf2), "elm/%s/%s/%s", clas, group, style);
|
|
|
|
file = _elm_theme_group_file_find(th, buf2);
|
|
|
|
if (file)
|
|
|
|
{
|
2013-02-19 00:22:15 -08:00
|
|
|
if (edje_object_file_set(o, file, buf2)) return 0;
|
2010-09-26 16:27:18 -07:00
|
|
|
else
|
2013-02-19 00:22:15 -08:00
|
|
|
{
|
|
|
|
DBG("could not set theme group '%s' from file '%s': %s",
|
|
|
|
buf2, file, edje_load_error_str(edje_object_load_error_get(o)));
|
|
|
|
}
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
2013-02-19 00:22:15 -08:00
|
|
|
|
|
|
|
//Third Try. Use the elementary default theme.
|
2010-05-11 18:03:46 -07:00
|
|
|
snprintf(buf2, sizeof(buf2), "elm/%s/%s/default", clas, group);
|
|
|
|
file = _elm_theme_group_file_find(th, buf2);
|
2013-02-19 00:22:15 -08:00
|
|
|
if (!file) return -1;
|
|
|
|
if (edje_object_file_set(o, file, buf2)) return 0;
|
|
|
|
DBG("could not set theme group '%s' from file '%s': %s",
|
|
|
|
buf2, file, edje_load_error_str(edje_object_load_error_get(o)));
|
|
|
|
|
|
|
|
return -1;
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
2010-10-21 11:58:37 -07:00
|
|
|
Eina_Bool
|
2012-05-25 12:53:59 -07:00
|
|
|
_elm_theme_icon_set(Elm_Theme *th,
|
|
|
|
Evas_Object *o,
|
|
|
|
const char *group,
|
|
|
|
const char *style)
|
2010-05-11 18:03:46 -07:00
|
|
|
{
|
|
|
|
const char *file;
|
|
|
|
char buf2[1024];
|
|
|
|
int w, h;
|
|
|
|
|
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
snprintf(buf2, sizeof(buf2), "elm/icon/%s/%s", group, style);
|
|
|
|
file = _elm_theme_group_file_find(th, buf2);
|
|
|
|
if (file)
|
|
|
|
{
|
2012-05-28 14:50:11 -07:00
|
|
|
elm_image_file_set(o, file, buf2);
|
|
|
|
elm_image_object_size_get(o, &w, &h);
|
2011-04-01 04:20:18 -07:00
|
|
|
if (w > 0) return EINA_TRUE;
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
snprintf(buf2, sizeof(buf2), "elm/icon/%s/default", group);
|
|
|
|
file = _elm_theme_group_file_find(th, buf2);
|
2012-05-25 12:53:59 -07:00
|
|
|
|
2010-10-21 11:58:37 -07:00
|
|
|
if (!file) return EINA_FALSE;
|
2012-05-25 12:53:59 -07:00
|
|
|
|
2012-05-28 14:50:11 -07:00
|
|
|
elm_image_file_set(o, file, buf2);
|
|
|
|
elm_image_object_size_get(o, &w, &h);
|
2012-05-25 12:53:59 -07:00
|
|
|
|
|
|
|
return w > 0;
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
2010-10-21 11:58:37 -07:00
|
|
|
Eina_Bool
|
2010-05-11 18:03:46 -07:00
|
|
|
_elm_theme_parse(Elm_Theme *th, const char *theme)
|
|
|
|
{
|
|
|
|
Eina_List *names = NULL;
|
|
|
|
const char *p, *pe;
|
|
|
|
|
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
if (theme)
|
|
|
|
{
|
2012-09-25 01:04:17 -07:00
|
|
|
Eina_Strbuf *buf;
|
|
|
|
|
|
|
|
buf = eina_strbuf_new();
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
p = theme;
|
|
|
|
pe = p;
|
|
|
|
for (;;)
|
|
|
|
{
|
2012-09-25 01:04:17 -07:00
|
|
|
if ((pe[0] == '\\') && (pe[1] == ':'))
|
|
|
|
{
|
|
|
|
eina_strbuf_append_char(buf, ':');
|
|
|
|
pe += 2;
|
|
|
|
}
|
|
|
|
else if ((*pe == ':') || (!*pe))
|
2010-05-11 18:03:46 -07:00
|
|
|
{ // p -> pe == 'name:'
|
|
|
|
if (pe > p)
|
|
|
|
{
|
2012-09-25 01:04:17 -07:00
|
|
|
const char *nn;
|
|
|
|
|
|
|
|
nn = eina_stringshare_add(eina_strbuf_string_get(buf));
|
|
|
|
if (nn) names = eina_list_append(names, nn);
|
|
|
|
eina_strbuf_reset(buf);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
2010-10-22 14:41:27 -07:00
|
|
|
if (!*pe) break;
|
2010-05-11 18:03:46 -07:00
|
|
|
p = pe + 1;
|
|
|
|
pe = p;
|
|
|
|
}
|
|
|
|
else
|
2012-09-25 01:04:17 -07:00
|
|
|
{
|
|
|
|
eina_strbuf_append_char(buf, *pe);
|
|
|
|
pe++;
|
|
|
|
}
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
2012-09-25 01:04:17 -07:00
|
|
|
|
|
|
|
eina_strbuf_free(buf);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
p = eina_list_data_get(eina_list_last(names));
|
|
|
|
if ((!p) || ((p) && (strcmp(p, "default"))))
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
p = eina_stringshare_add("default");
|
|
|
|
if (p) names = eina_list_append(names, p);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
if (th->cache) eina_hash_free(th->cache);
|
|
|
|
th->cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
|
2011-09-11 18:05:07 -07:00
|
|
|
if (th->cache_data) eina_hash_free(th->cache_data);
|
|
|
|
th->cache_data = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
|
2010-05-11 18:03:46 -07:00
|
|
|
|
|
|
|
EINA_LIST_FREE(th->themes, p) eina_stringshare_del(p);
|
|
|
|
|
|
|
|
th->themes = names;
|
2010-10-21 11:58:37 -07:00
|
|
|
return EINA_TRUE;
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_elm_theme_shutdown(void)
|
|
|
|
{
|
|
|
|
_elm_theme_clear(&(theme_default));
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Elm_Theme *
|
|
|
|
elm_theme_new(void)
|
|
|
|
{
|
|
|
|
Elm_Theme *th = calloc(1, sizeof(Elm_Theme));
|
|
|
|
if (!th) return NULL;
|
|
|
|
th->ref = 1;
|
|
|
|
th->themes = eina_list_append(th->themes, eina_stringshare_add("default"));
|
|
|
|
themes = eina_list_append(themes, th);
|
|
|
|
return th;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_theme_free(Elm_Theme *th)
|
|
|
|
{
|
2010-12-03 06:08:33 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(th);
|
2010-05-11 18:03:46 -07:00
|
|
|
th->ref--;
|
|
|
|
if (th->ref < 1)
|
|
|
|
{
|
|
|
|
_elm_theme_clear(th);
|
|
|
|
themes = eina_list_remove(themes, th);
|
|
|
|
free(th);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-05 01:37:31 -07:00
|
|
|
EAPI void
|
|
|
|
elm_theme_copy(Elm_Theme *th, Elm_Theme *thdst)
|
|
|
|
{
|
|
|
|
const Eina_List *l;
|
|
|
|
const char *f;
|
2011-04-01 04:20:18 -07:00
|
|
|
|
2010-11-05 01:37:31 -07:00
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
if (!thdst) thdst = &(theme_default);
|
|
|
|
_elm_theme_clear(thdst);
|
|
|
|
if (th->ref_theme)
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
thdst->ref_theme = th->ref_theme;
|
|
|
|
thdst->ref_theme->referrers =
|
|
|
|
eina_list_append(thdst->ref_theme->referrers, thdst);
|
|
|
|
thdst->ref_theme->ref++;
|
2010-11-05 01:37:31 -07:00
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(th->overlay, l, f)
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
const char *s = eina_stringshare_add(f);
|
|
|
|
if (s) thdst->overlay = eina_list_append(thdst->overlay, s);
|
2010-11-05 01:37:31 -07:00
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(th->themes, l, f)
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
const char *s = eina_stringshare_add(f);
|
|
|
|
if (s) thdst->themes = eina_list_append(thdst->themes, s);
|
2010-11-05 01:37:31 -07:00
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(th->extension, l, f)
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
const char *s = eina_stringshare_add(f);
|
|
|
|
if (s) thdst->extension = eina_list_append(thdst->extension, s);
|
2010-11-05 01:37:31 -07:00
|
|
|
}
|
|
|
|
if (th->theme) thdst->theme = eina_stringshare_add(th->theme);
|
|
|
|
elm_theme_flush(thdst);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_theme_ref_set(Elm_Theme *th, Elm_Theme *thref)
|
|
|
|
{
|
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
if (!thref) thref = &(theme_default);
|
|
|
|
if (th->ref_theme == thref) return;
|
|
|
|
_elm_theme_clear(th);
|
|
|
|
if (thref)
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
thref->referrers = eina_list_append(thref->referrers, th);
|
|
|
|
thref->ref++;
|
2010-11-05 01:37:31 -07:00
|
|
|
}
|
|
|
|
th->ref_theme = thref;
|
|
|
|
elm_theme_flush(th);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Elm_Theme *
|
|
|
|
elm_theme_ref_get(Elm_Theme *th)
|
|
|
|
{
|
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
return th->ref_theme;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Elm_Theme *
|
|
|
|
elm_theme_default_get(void)
|
|
|
|
{
|
|
|
|
return &theme_default;
|
|
|
|
}
|
|
|
|
|
2009-02-23 00:40:58 -08:00
|
|
|
EAPI void
|
2010-05-11 18:03:46 -07:00
|
|
|
elm_theme_overlay_add(Elm_Theme *th, const char *item)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
|
|
|
const char *f = eina_stringshare_add(item);
|
2009-10-27 12:32:50 -07:00
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
if (f) th->overlay = eina_list_prepend(th->overlay, f);
|
|
|
|
elm_theme_flush(th);
|
2009-10-23 07:42:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2010-05-11 18:03:46 -07:00
|
|
|
elm_theme_overlay_del(Elm_Theme *th, const char *item)
|
2009-10-23 07:42:39 -07:00
|
|
|
{
|
|
|
|
const Eina_List *l;
|
2009-10-23 22:05:38 -07:00
|
|
|
const char *f, *s;
|
2009-10-27 12:32:50 -07:00
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
if (!th) th = &(theme_default);
|
2009-10-23 22:05:38 -07:00
|
|
|
s = eina_stringshare_add(item);
|
2010-05-11 18:03:46 -07:00
|
|
|
EINA_LIST_FOREACH(th->overlay, l, f)
|
2011-04-01 04:20:18 -07:00
|
|
|
if (f == s)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(f);
|
|
|
|
th->overlay = eina_list_remove_list(th->overlay, (Eina_List *)l);
|
|
|
|
break;
|
|
|
|
}
|
2009-10-23 22:05:38 -07:00
|
|
|
eina_stringshare_del(s);
|
2010-05-11 18:03:46 -07:00
|
|
|
elm_theme_flush(th);
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
|
|
|
|
2012-03-05 13:48:32 -08:00
|
|
|
EAPI const Eina_List *
|
2012-03-05 16:19:31 -08:00
|
|
|
elm_theme_overlay_list_get(const Elm_Theme *th)
|
2012-03-05 13:48:32 -08:00
|
|
|
{
|
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
return th->overlay;
|
|
|
|
}
|
|
|
|
|
2009-02-23 00:40:58 -08:00
|
|
|
EAPI void
|
2010-05-11 18:03:46 -07:00
|
|
|
elm_theme_extension_add(Elm_Theme *th, const char *item)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
|
|
|
const char *f = eina_stringshare_add(item);
|
2009-10-27 12:32:50 -07:00
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
if (f) th->extension = eina_list_append(th->extension, f);
|
|
|
|
elm_theme_flush(th);
|
2009-10-23 07:42:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2010-05-11 18:03:46 -07:00
|
|
|
elm_theme_extension_del(Elm_Theme *th, const char *item)
|
2009-10-23 07:42:39 -07:00
|
|
|
{
|
|
|
|
const Eina_List *l;
|
2009-10-23 22:05:38 -07:00
|
|
|
const char *f, *s;
|
2009-10-27 12:32:50 -07:00
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
if (!th) th = &(theme_default);
|
2009-10-23 22:05:38 -07:00
|
|
|
s = eina_stringshare_add(item);
|
2010-05-11 18:03:46 -07:00
|
|
|
EINA_LIST_FOREACH(th->extension, l, f)
|
2011-04-01 04:20:18 -07:00
|
|
|
if (f == s)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(f);
|
|
|
|
th->extension = eina_list_remove_list(th->extension, (Eina_List *)l);
|
|
|
|
break;
|
|
|
|
}
|
2009-10-23 22:05:38 -07:00
|
|
|
eina_stringshare_del(s);
|
2010-05-11 18:03:46 -07:00
|
|
|
elm_theme_flush(th);
|
|
|
|
}
|
|
|
|
|
2012-03-05 13:48:32 -08:00
|
|
|
EAPI const Eina_List *
|
2012-03-05 16:19:31 -08:00
|
|
|
elm_theme_extension_list_get(const Elm_Theme *th)
|
2012-03-05 13:48:32 -08:00
|
|
|
{
|
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
return th->extension;
|
|
|
|
}
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
EAPI void
|
|
|
|
elm_theme_set(Elm_Theme *th, const char *theme)
|
|
|
|
{
|
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
_elm_theme_parse(th, theme);
|
|
|
|
if (th->theme)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(th->theme);
|
|
|
|
th->theme = NULL;
|
|
|
|
}
|
|
|
|
elm_theme_flush(th);
|
2012-03-05 04:39:22 -08:00
|
|
|
if (th == &(theme_default))
|
|
|
|
eina_stringshare_replace(&_elm_config->theme, theme);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
elm_theme_get(Elm_Theme *th)
|
|
|
|
{
|
2010-09-23 22:11:33 -07:00
|
|
|
if (!th) th = &(theme_default);
|
2010-05-11 18:03:46 -07:00
|
|
|
if (!th->theme)
|
|
|
|
{
|
2012-09-25 01:04:17 -07:00
|
|
|
Eina_Strbuf *buf;
|
2010-05-11 18:03:46 -07:00
|
|
|
Eina_List *l;
|
|
|
|
const char *f;
|
2010-10-25 07:34:22 -07:00
|
|
|
|
2012-09-25 01:04:17 -07:00
|
|
|
buf = eina_strbuf_new();
|
2010-05-11 18:03:46 -07:00
|
|
|
EINA_LIST_FOREACH(th->themes, l, f)
|
|
|
|
{
|
2012-09-25 01:04:17 -07:00
|
|
|
while (*f)
|
|
|
|
{
|
|
|
|
if (*f == ':')
|
|
|
|
eina_strbuf_append_char(buf, '\\');
|
|
|
|
eina_strbuf_append_char(buf, *f);
|
|
|
|
|
|
|
|
f++;
|
|
|
|
}
|
|
|
|
if (l->next) eina_strbuf_append_char(buf, ':');
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
2012-09-25 01:04:17 -07:00
|
|
|
th->theme = eina_stringshare_add(eina_strbuf_string_get(buf));
|
|
|
|
eina_strbuf_free(buf);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
return th->theme;
|
2009-10-23 07:42:39 -07:00
|
|
|
}
|
|
|
|
|
2010-09-23 22:11:33 -07:00
|
|
|
EAPI const Eina_List *
|
2010-10-25 07:34:22 -07:00
|
|
|
elm_theme_list_get(const Elm_Theme *th)
|
2010-09-23 22:11:33 -07:00
|
|
|
{
|
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
return th->themes;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI char *
|
|
|
|
elm_theme_list_item_path_get(const char *f, Eina_Bool *in_search_path)
|
|
|
|
{
|
|
|
|
static const char *home = NULL;
|
|
|
|
char buf[PATH_MAX];
|
2011-04-01 04:20:18 -07:00
|
|
|
|
2010-09-23 22:11:33 -07:00
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
if (in_search_path) *in_search_path = EINA_FALSE;
|
|
|
|
return NULL;
|
|
|
|
}
|
2011-04-01 04:20:18 -07:00
|
|
|
|
2010-09-23 22:11:33 -07:00
|
|
|
if (!home)
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
home = getenv("HOME");
|
|
|
|
if (!home) home = "";
|
2010-09-23 22:11:33 -07:00
|
|
|
}
|
2011-04-01 04:20:18 -07:00
|
|
|
|
2010-09-23 22:11:33 -07:00
|
|
|
if ((f[0] == '/') || ((f[0] == '.') && (f[1] == '/')) ||
|
|
|
|
((f[0] == '.') && (f[1] == '.') && (f[2] == '/')) ||
|
2010-10-22 14:41:22 -07:00
|
|
|
((isalpha(f[0])) && (f[1] == ':')))
|
2010-09-23 22:11:33 -07:00
|
|
|
{
|
|
|
|
if (in_search_path) *in_search_path = EINA_FALSE;
|
|
|
|
return strdup(f);
|
|
|
|
}
|
|
|
|
else if (((f[0] == '~') && (f[1] == '/')))
|
|
|
|
{
|
|
|
|
if (in_search_path) *in_search_path = EINA_FALSE;
|
2011-04-01 04:20:18 -07:00
|
|
|
snprintf(buf, sizeof(buf), "%s/%s", home, f + 2);
|
2010-09-23 22:11:33 -07:00
|
|
|
return strdup(buf);
|
|
|
|
}
|
2012-01-19 09:12:15 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%s/"ELEMENTARY_BASE_DIR"/themes/%s.edj", home, f);
|
2010-09-23 22:11:33 -07:00
|
|
|
if (ecore_file_exists(buf))
|
|
|
|
{
|
|
|
|
if (in_search_path) *in_search_path = EINA_TRUE;
|
|
|
|
return strdup(buf);
|
|
|
|
}
|
2011-04-01 04:20:18 -07:00
|
|
|
|
2010-09-23 22:11:33 -07:00
|
|
|
snprintf(buf, sizeof(buf), "%s/themes/%s.edj", _elm_data_dir, f);
|
|
|
|
if (ecore_file_exists(buf))
|
|
|
|
{
|
|
|
|
if (in_search_path) *in_search_path = EINA_TRUE;
|
|
|
|
return strdup(buf);
|
|
|
|
}
|
2011-04-01 04:20:18 -07:00
|
|
|
|
2010-09-23 22:11:33 -07:00
|
|
|
if (in_search_path) *in_search_path = EINA_FALSE;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2009-10-23 07:42:39 -07:00
|
|
|
EAPI void
|
2010-05-11 18:03:46 -07:00
|
|
|
elm_theme_flush(Elm_Theme *th)
|
2009-10-23 07:42:39 -07:00
|
|
|
{
|
2010-05-11 18:03:46 -07:00
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
if (th->cache) eina_hash_free(th->cache);
|
|
|
|
th->cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
|
2011-09-11 18:05:07 -07:00
|
|
|
if (th->cache_data) eina_hash_free(th->cache_data);
|
|
|
|
th->cache_data = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
|
2010-11-05 01:37:31 -07:00
|
|
|
_elm_win_rescale(th, EINA_TRUE);
|
2011-10-05 15:18:22 -07:00
|
|
|
_elm_ews_wm_rescale(th, EINA_TRUE);
|
2010-11-05 01:37:31 -07:00
|
|
|
if (th->referrers)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Elm_Theme *th2;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(th->referrers, l, th2) elm_theme_flush(th2);
|
|
|
|
}
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
EAPI void
|
|
|
|
elm_theme_full_flush(void)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
Elm_Theme *th;
|
2011-04-01 04:20:18 -07:00
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
EINA_LIST_FOREACH(themes, l, th)
|
|
|
|
{
|
|
|
|
elm_theme_flush(th);
|
|
|
|
}
|
|
|
|
elm_theme_flush(&(theme_default));
|
|
|
|
}
|
|
|
|
|
2010-09-23 22:11:33 -07:00
|
|
|
EAPI Eina_List *
|
|
|
|
elm_theme_name_available_list_new(void)
|
|
|
|
{
|
|
|
|
Eina_List *list = NULL;
|
|
|
|
Eina_List *dir, *l;
|
|
|
|
char buf[PATH_MAX], *file, *s, *th;
|
|
|
|
static const char *home = NULL;
|
2011-04-01 04:20:18 -07:00
|
|
|
|
2010-09-23 22:11:33 -07:00
|
|
|
if (!home)
|
|
|
|
{
|
|
|
|
home = getenv("HOME");
|
|
|
|
if (!home) home = "";
|
|
|
|
}
|
2011-04-01 04:20:18 -07:00
|
|
|
|
2012-01-19 09:12:15 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%s/"ELEMENTARY_BASE_DIR"/themes", home);
|
2010-09-23 22:11:33 -07:00
|
|
|
dir = ecore_file_ls(buf);
|
|
|
|
EINA_LIST_FREE(dir, file)
|
|
|
|
{
|
2012-01-19 09:12:15 -08:00
|
|
|
snprintf(buf, sizeof(buf), "%s/"ELEMENTARY_BASE_DIR"/themes/%s", home, file);
|
2010-09-23 22:11:33 -07:00
|
|
|
if ((!ecore_file_is_dir(buf)) && (ecore_file_size(buf) > 0))
|
|
|
|
{
|
|
|
|
s = strchr(file, '.');
|
|
|
|
if ((s) && (!strcasecmp(s, ".edj")))
|
|
|
|
{
|
|
|
|
th = strdup(file);
|
|
|
|
s = strchr(th, '.');
|
|
|
|
*s = 0;
|
|
|
|
list = eina_list_append(list, th);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s/themes", _elm_data_dir);
|
|
|
|
dir = ecore_file_ls(buf);
|
|
|
|
EINA_LIST_FREE(dir, file)
|
|
|
|
{
|
|
|
|
snprintf(buf, sizeof(buf), "%s/themes/%s", _elm_data_dir, file);
|
|
|
|
if ((!ecore_file_is_dir(buf)) && (ecore_file_size(buf) > 0))
|
|
|
|
{
|
|
|
|
s = strchr(file, '.');
|
|
|
|
if ((s) && (!strcasecmp(s, ".edj")))
|
|
|
|
{
|
2012-03-07 00:19:55 -08:00
|
|
|
int dupp;
|
2011-04-01 04:20:18 -07:00
|
|
|
|
2010-09-23 22:11:33 -07:00
|
|
|
th = strdup(file);
|
|
|
|
s = strchr(th, '.');
|
|
|
|
*s = 0;
|
2012-03-07 00:19:55 -08:00
|
|
|
dupp = 0;
|
2010-09-23 22:11:33 -07:00
|
|
|
EINA_LIST_FOREACH(list, l, s)
|
|
|
|
{
|
|
|
|
if (!strcmp(s, th))
|
|
|
|
{
|
2012-03-07 00:19:55 -08:00
|
|
|
dupp = 1;
|
2010-09-23 22:11:33 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-03-07 00:19:55 -08:00
|
|
|
if (dupp) free(th);
|
2010-09-23 22:11:33 -07:00
|
|
|
else list = eina_list_append(list, th);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(file);
|
|
|
|
}
|
|
|
|
list = eina_list_sort(list, 0, EINA_COMPARE_CB(strcasecmp));
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_theme_name_available_list_free(Eina_List *list)
|
|
|
|
{
|
|
|
|
char *s;
|
|
|
|
EINA_LIST_FREE(list, s) free(s);
|
|
|
|
}
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
EAPI void
|
|
|
|
elm_object_theme_set(Evas_Object *obj, Elm_Theme *th)
|
2009-01-13 01:20:53 -08:00
|
|
|
{
|
2010-12-03 06:08:33 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(obj);
|
2010-05-11 18:03:46 -07:00
|
|
|
elm_widget_theme_set(obj, th);
|
2009-01-13 01:20:53 -08:00
|
|
|
}
|
2010-04-28 16:14:04 -07:00
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
EAPI Elm_Theme *
|
2010-10-25 07:34:22 -07:00
|
|
|
elm_object_theme_get(const Evas_Object *obj)
|
2010-04-28 16:14:04 -07:00
|
|
|
{
|
2010-12-03 06:08:33 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
|
2010-05-11 18:03:46 -07:00
|
|
|
return elm_widget_theme_get(obj);
|
2010-04-28 16:14:04 -07:00
|
|
|
}
|
2011-09-11 18:05:07 -07:00
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
elm_theme_data_get(Elm_Theme *th, const char *key)
|
|
|
|
{
|
|
|
|
if (!th) th = &(theme_default);
|
|
|
|
return _elm_theme_data_find(th, key);
|
|
|
|
}
|