2013-04-25 22:13:00 -07:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "elementary_config.h"
|
|
|
|
#endif
|
|
|
|
|
2008-09-29 23:58:56 -07:00
|
|
|
#include <Elementary.h>
|
2013-04-25 22:13:00 -07:00
|
|
|
|
2008-09-29 23:58:56 -07:00
|
|
|
#include "elm_priv.h"
|
2019-03-05 14:00:37 -08:00
|
|
|
#include "elm_icon_eo.h"
|
2008-09-29 23:58:56 -07:00
|
|
|
|
2018-11-19 20:56:37 -08:00
|
|
|
#include "efl_ui_theme.eo.h"
|
|
|
|
|
|
|
|
static Elm_Theme *theme_default = NULL;
|
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
|
|
|
|
2013-11-03 19:17:58 -08:00
|
|
|
static Eina_File *
|
2018-02-28 08:01:26 -08:00
|
|
|
_elm_theme_find_try(Elm_Theme *th, Elm_Theme_File *etf, const char *group, Eina_Bool force)
|
2013-11-03 19:17:58 -08:00
|
|
|
{
|
2018-02-27 12:42:58 -08:00
|
|
|
if (edje_mmap_group_exists(etf->handle, group))
|
2013-11-03 19:17:58 -08:00
|
|
|
{
|
2018-02-28 08:01:26 -08:00
|
|
|
if (etf->match_theme && (!force)) // overlay or extension
|
2018-02-27 12:42:58 -08:00
|
|
|
{
|
|
|
|
Elm_Theme_File *base_etf;
|
|
|
|
Eina_Bool found = EINA_FALSE;
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(th->themes, base_etf)
|
|
|
|
{
|
|
|
|
if (base_etf->base_theme != etf->match_theme) continue;
|
|
|
|
found = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!found) return NULL;
|
|
|
|
}
|
|
|
|
eina_hash_add(th->cache, group, eina_file_dup(etf->handle));
|
|
|
|
return etf->handle;
|
2013-11-03 19:17:58 -08:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2018-02-27 12:07:13 -08:00
|
|
|
_elm_theme_item_finalize(Eina_Inlist **files,
|
2013-11-03 19:17:58 -08:00
|
|
|
const char *item,
|
2014-03-14 20:01:56 -07:00
|
|
|
Eina_File *f,
|
2014-03-28 00:17:38 -07:00
|
|
|
Eina_Bool prepend,
|
|
|
|
Eina_Bool istheme)
|
2013-11-03 19:17:58 -08:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
Elm_Theme_File *etf;
|
2018-02-27 12:42:58 -08:00
|
|
|
char *name;
|
2016-11-22 00:34:17 -08:00
|
|
|
/* Theme version history:
|
|
|
|
* <110: legacy, had no version tag
|
|
|
|
* 110: first supported version
|
|
|
|
* 119: switched windows to always use border
|
|
|
|
* win group has no menu, no blocker
|
|
|
|
* border group has all required swallows (conformant, bg, win)
|
|
|
|
* data: "elm_bg_version" matches "version" ("119")
|
|
|
|
*/
|
2014-03-14 19:44:20 -07:00
|
|
|
if (!f) return;
|
2014-03-28 00:17:38 -07:00
|
|
|
if (istheme)
|
2014-03-26 02:06:08 -07:00
|
|
|
{
|
2014-03-28 00:17:38 -07:00
|
|
|
char *version;
|
2016-12-07 02:27:05 -08:00
|
|
|
int v;
|
2014-03-28 00:17:38 -07:00
|
|
|
|
2019-08-20 07:16:04 -07:00
|
|
|
if (!(version = edje_mmap_data_get(f, "version")))
|
|
|
|
{
|
2019-08-20 16:32:38 -07:00
|
|
|
eina_file_close(f); // close matching open (finalize expected to consume eina file) OK
|
2019-08-20 07:16:04 -07:00
|
|
|
return;
|
|
|
|
}
|
2016-12-07 02:27:05 -08:00
|
|
|
v = atoi(version);
|
|
|
|
if (v < 110) // bump this version number when we need to
|
2014-03-28 00:17:38 -07:00
|
|
|
{
|
2016-12-07 02:27:05 -08:00
|
|
|
WRN("Selected theme is too old (version = %d, needs >= 110)", v);
|
2014-03-28 00:17:38 -07:00
|
|
|
}
|
2014-03-26 02:06:08 -07:00
|
|
|
free(version);
|
|
|
|
}
|
2018-02-27 12:07:13 -08:00
|
|
|
etf = calloc(1, sizeof(Elm_Theme_File));
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(etf);
|
|
|
|
etf->item = eina_stringshare_add(item);
|
2019-08-20 16:32:38 -07:00
|
|
|
etf->handle = f; // now own/consume the file handle
|
2018-02-27 12:42:58 -08:00
|
|
|
if (istheme)
|
|
|
|
{
|
|
|
|
name = edje_mmap_data_get(f, "efl_theme_base");
|
|
|
|
etf->base_theme = eina_stringshare_add(name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
name = edje_mmap_data_get(f, "efl_theme_match");
|
|
|
|
etf->match_theme = eina_stringshare_add(name);
|
|
|
|
}
|
|
|
|
free(name);
|
2014-03-14 20:01:56 -07:00
|
|
|
if (prepend)
|
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
*files = eina_inlist_prepend(*files, EINA_INLIST_GET(etf));
|
2014-03-14 20:01:56 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
*files = eina_inlist_append(*files, EINA_INLIST_GET(etf));
|
2014-03-14 20:01:56 -07:00
|
|
|
}
|
2013-11-03 19:17:58 -08:00
|
|
|
}
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
static void
|
2018-02-27 12:07:13 -08:00
|
|
|
_elm_theme_file_item_add(Eina_Inlist **files, const char *item, Eina_Bool prepend, Eina_Bool istheme)
|
2010-05-11 18:03:46 -07:00
|
|
|
{
|
2013-11-03 19:17:58 -08:00
|
|
|
Eina_Strbuf *buf = NULL;
|
|
|
|
Eina_File *f = NULL;
|
|
|
|
const char *home;
|
2013-05-29 05:08:05 -07:00
|
|
|
|
2015-05-14 12:26:44 -07:00
|
|
|
home = eina_environment_home_get();
|
2013-11-03 19:17:58 -08:00
|
|
|
buf = eina_strbuf_new();
|
|
|
|
|
|
|
|
if ((item[0] == '/') ||
|
|
|
|
((item[0] == '.') && (item[1] == '/')) ||
|
|
|
|
((item[0] == '.') && (item[1] == '.') && (item[2] == '/')) ||
|
|
|
|
((isalpha(item[0])) && (item[1] == ':')))
|
2011-04-01 04:20:18 -07:00
|
|
|
{
|
2013-11-03 19:17:58 -08:00
|
|
|
f = eina_file_open(item, EINA_FALSE);
|
|
|
|
if (!f) goto on_error;
|
|
|
|
}
|
|
|
|
else if (((item[0] == '~') && (item[1] == '/')))
|
|
|
|
{
|
|
|
|
eina_strbuf_append_printf(buf, "%s/%s", home, item + 2);
|
|
|
|
|
|
|
|
f = eina_file_open(eina_strbuf_string_get(buf), EINA_FALSE);
|
|
|
|
if (!f) goto on_error;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
eina_strbuf_append_printf(buf,
|
|
|
|
"%s/"ELEMENTARY_BASE_DIR"/themes/%s.edj",
|
|
|
|
home, item);
|
|
|
|
f = eina_file_open(eina_strbuf_string_get(buf), EINA_FALSE);
|
2014-03-28 00:17:38 -07:00
|
|
|
_elm_theme_item_finalize(files, item, f, prepend, istheme);
|
2013-11-03 19:17:58 -08:00
|
|
|
|
|
|
|
eina_strbuf_reset(buf);
|
2016-03-23 22:48:45 -07:00
|
|
|
|
2013-11-03 19:17:58 -08:00
|
|
|
eina_strbuf_append_printf(buf,
|
|
|
|
"%s/themes/%s.edj",
|
|
|
|
_elm_data_dir, item);
|
|
|
|
f = eina_file_open(eina_strbuf_string_get(buf), EINA_FALSE);
|
|
|
|
/* Finalize will be done by the common one */
|
2011-04-01 04:20:18 -07:00
|
|
|
}
|
2013-11-03 19:17:58 -08:00
|
|
|
|
2014-03-28 00:17:38 -07:00
|
|
|
_elm_theme_item_finalize(files, item, f, prepend, istheme);
|
2013-11-03 19:17:58 -08:00
|
|
|
|
|
|
|
on_error:
|
|
|
|
if (buf) eina_strbuf_free(buf);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
2009-01-13 01:20:53 -08:00
|
|
|
|
2013-11-03 19:17:58 -08:00
|
|
|
static void
|
2018-02-27 12:07:13 -08:00
|
|
|
_elm_theme_file_item_del(Eina_Inlist **files, const char *str)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
Eina_Inlist *l;
|
|
|
|
Elm_Theme_File *item;
|
2013-11-03 19:17:58 -08:00
|
|
|
|
|
|
|
str = eina_stringshare_add(str);
|
2009-07-06 23:46:51 -07:00
|
|
|
|
2018-02-27 12:07:13 -08:00
|
|
|
EINA_INLIST_FOREACH_SAFE(*files, l, item)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
if (item->item != str) continue;
|
2019-08-20 16:32:38 -07:00
|
|
|
eina_file_close(item->handle); // close matching open (file consumed in finalize by putting it in etf) OK
|
2018-02-27 12:07:13 -08:00
|
|
|
eina_stringshare_del(item->item);
|
|
|
|
*files = eina_inlist_remove(*files, EINA_INLIST_GET(item));
|
|
|
|
free(item);
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
2013-11-03 19:17:58 -08:00
|
|
|
|
|
|
|
eina_stringshare_del(str);
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
|
|
|
|
2013-11-03 21:26:05 -08:00
|
|
|
static void
|
2018-02-27 12:07:13 -08:00
|
|
|
_elm_theme_file_mmap_del(Eina_Inlist **files, const Eina_File *file)
|
2013-11-03 21:26:05 -08:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
Eina_Inlist *l;
|
|
|
|
Elm_Theme_File *item;
|
2013-11-03 21:26:05 -08:00
|
|
|
|
2018-02-27 12:07:13 -08:00
|
|
|
EINA_INLIST_FOREACH_SAFE(*files, l, item)
|
2013-11-03 21:26:05 -08:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
if (item->handle != file) continue;
|
2019-08-20 16:32:38 -07:00
|
|
|
eina_file_close(item->handle); // close matching open (file consumed in finalize by putting it in etf) OK
|
2018-02-27 12:07:13 -08:00
|
|
|
eina_stringshare_del(item->item);
|
|
|
|
*files = eina_inlist_remove(*files, EINA_INLIST_GET(item));
|
|
|
|
free(item);
|
2013-11-03 21:26:05 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-03 19:17:58 -08:00
|
|
|
static void
|
2018-02-27 12:07:13 -08:00
|
|
|
_elm_theme_file_clean(Eina_Inlist **files)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
while (*files)
|
|
|
|
{
|
|
|
|
Elm_Theme_File *etf = EINA_INLIST_CONTAINER_GET(*files, Elm_Theme_File);
|
2009-07-06 23:46:51 -07:00
|
|
|
|
2018-02-27 12:07:13 -08:00
|
|
|
eina_stringshare_del(etf->item);
|
2019-08-20 16:32:38 -07:00
|
|
|
eina_file_close(etf->handle); // close matching open (file consumed in finalize by putting it in etf) OK
|
2018-02-27 12:42:58 -08:00
|
|
|
eina_stringshare_del(etf->match_theme);
|
2018-02-27 12:07:13 -08:00
|
|
|
*files = eina_inlist_remove(*files, *files);
|
|
|
|
free(etf);
|
|
|
|
}
|
2013-11-03 19:17:58 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_elm_theme_clear(Elm_Theme *th)
|
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
Efl_Ui_Theme_Data *td;
|
|
|
|
|
2013-11-03 19:17:58 -08:00
|
|
|
_elm_theme_file_clean(&th->themes);
|
|
|
|
_elm_theme_file_clean(&th->overlay);
|
|
|
|
_elm_theme_file_clean(&th->extension);
|
|
|
|
|
2018-02-27 12:07:13 -08:00
|
|
|
ELM_SAFE_FREE(th->overlay_items, eina_list_free);
|
|
|
|
ELM_SAFE_FREE(th->theme_items, eina_list_free);
|
|
|
|
ELM_SAFE_FREE(th->extension_items, eina_list_free);
|
|
|
|
|
2013-11-03 19:17:58 -08:00
|
|
|
ELM_SAFE_FREE(th->cache, eina_hash_free);
|
|
|
|
ELM_SAFE_FREE(th->cache_data, eina_hash_free);
|
2014-03-18 01:18:09 -07:00
|
|
|
ELM_SAFE_FREE(th->cache_style_load_failed, eina_hash_free);
|
2013-11-03 19:17:58 -08:00
|
|
|
ELM_SAFE_FREE(th->theme, eina_stringshare_del);
|
|
|
|
if (th->ref_theme)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
2013-11-03 19:17:58 -08:00
|
|
|
th->ref_theme->referrers =
|
|
|
|
eina_list_remove(th->ref_theme->referrers, th);
|
|
|
|
elm_theme_free(th->ref_theme);
|
|
|
|
th->ref_theme = NULL;
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
2018-11-19 20:56:37 -08:00
|
|
|
|
|
|
|
td = efl_data_scope_get(th->eo_theme, EFL_UI_THEME_CLASS);
|
|
|
|
td->th = NULL;
|
|
|
|
th->eo_theme = NULL;
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
|
|
|
|
2018-02-28 08:01:26 -08:00
|
|
|
static Eina_File *
|
|
|
|
_elm_theme_group_file_find_internal(Elm_Theme *th, const char *group, Eina_Bool force)
|
2009-01-13 01:20:53 -08:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
Elm_Theme_File *etf;
|
2013-11-03 19:17:58 -08:00
|
|
|
Eina_File *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;
|
2013-11-03 19:17:58 -08:00
|
|
|
|
2018-02-27 12:07:13 -08:00
|
|
|
EINA_INLIST_FOREACH(th->overlay, etf)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
2018-02-28 08:01:26 -08:00
|
|
|
file = _elm_theme_find_try(th, etf, group, force);
|
2011-04-01 04:20:18 -07:00
|
|
|
if (file) return file;
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
2018-02-27 12:07:13 -08:00
|
|
|
EINA_INLIST_FOREACH(th->themes, etf)
|
2009-01-13 01:20:53 -08:00
|
|
|
{
|
2018-02-28 08:01:26 -08:00
|
|
|
file = _elm_theme_find_try(th, etf, group, force);
|
2011-04-01 04:20:18 -07:00
|
|
|
if (file) return file;
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
2018-02-27 12:07:13 -08:00
|
|
|
EINA_INLIST_FOREACH(th->extension, etf)
|
2009-02-23 00:40:58 -08:00
|
|
|
{
|
2018-02-28 08:01:26 -08:00
|
|
|
file = _elm_theme_find_try(th, etf, group, force);
|
2011-04-01 04:20:18 -07:00
|
|
|
if (file) return file;
|
2009-01-13 01:20:53 -08:00
|
|
|
}
|
2018-02-28 08:01:26 -08:00
|
|
|
if (th->ref_theme) return _elm_theme_group_file_find_internal(th->ref_theme, group, force);
|
2009-01-13 01:20:53 -08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-02-28 08:01:26 -08:00
|
|
|
Eina_File *
|
|
|
|
_elm_theme_group_file_find(Elm_Theme *th, const char *group)
|
|
|
|
{
|
|
|
|
Eina_File *file = _elm_theme_group_file_find_internal(th, group, EINA_FALSE);
|
|
|
|
if (file) return file;
|
|
|
|
file = _elm_theme_group_file_find_internal(th, group, EINA_TRUE);
|
|
|
|
return file;
|
|
|
|
}
|
|
|
|
|
2011-09-11 18:05:07 -07:00
|
|
|
static const char *
|
2013-11-03 19:17:58 -08:00
|
|
|
_elm_theme_find_data_try(Elm_Theme *th, const Eina_File *f, const char *key)
|
2011-09-11 18:05:07 -07:00
|
|
|
{
|
|
|
|
char *data;
|
|
|
|
const char *t;
|
|
|
|
|
2013-11-03 19:17:58 -08:00
|
|
|
data = edje_mmap_data_get(f, key);
|
2011-09-11 18:05:07 -07:00
|
|
|
t = eina_stringshare_add(data);
|
|
|
|
free(data);
|
|
|
|
if (t)
|
|
|
|
{
|
2016-12-07 23:10:20 -08:00
|
|
|
eina_hash_add(th->cache_data, key, t);
|
2011-09-11 18:05:07 -07:00
|
|
|
return t;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
_elm_theme_data_find(Elm_Theme *th, const char *key)
|
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
Elm_Theme_File *etf;
|
2011-09-11 18:05:07 -07:00
|
|
|
|
2013-11-03 19:17:58 -08:00
|
|
|
const char *data = eina_hash_find(th->cache_data, key);
|
2011-09-11 18:05:07 -07:00
|
|
|
if (data) return data;
|
2013-11-03 19:17:58 -08:00
|
|
|
|
2018-02-27 12:07:13 -08:00
|
|
|
EINA_INLIST_FOREACH(th->overlay, etf)
|
2011-09-11 18:05:07 -07:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
data = _elm_theme_find_data_try(th, etf->handle, key);
|
2011-09-11 18:05:07 -07:00
|
|
|
if (data) return data;
|
|
|
|
}
|
2018-04-17 08:46:37 -07:00
|
|
|
EINA_INLIST_FOREACH(th->themes, etf)
|
2011-09-11 18:05:07 -07:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
data = _elm_theme_find_data_try(th, etf->handle, key);
|
2011-09-11 18:05:07 -07:00
|
|
|
if (data) return data;
|
|
|
|
}
|
2018-04-17 08:46:37 -07:00
|
|
|
EINA_INLIST_FOREACH(th->extension, etf)
|
2011-09-11 18:05:07 -07:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
data = _elm_theme_find_data_try(th, etf->handle, key);
|
2011-09-11 18:05:07 -07:00
|
|
|
if (data) return data;
|
|
|
|
}
|
|
|
|
if (th->ref_theme) return _elm_theme_data_find(th->ref_theme, key);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-03-04 10:37:07 -08:00
|
|
|
Eina_Error
|
2013-02-25 20:26:22 -08:00
|
|
|
_elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style)
|
2010-05-11 18:03:46 -07:00
|
|
|
{
|
|
|
|
Elm_Theme *th = NULL;
|
2012-05-09 03:46:14 -07:00
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
if (parent) th = elm_widget_theme_get(parent);
|
2018-01-23 22:50:58 -08:00
|
|
|
|
2017-11-14 02:59:42 -08:00
|
|
|
return _elm_theme_set(th, o, clas, group, style, elm_widget_is_legacy(parent));
|
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);
|
|
|
|
}
|
|
|
|
|
2019-03-04 10:37:07 -08:00
|
|
|
Eina_Error
|
2018-01-16 21:03:00 -08:00
|
|
|
_elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *group, const char *style, Eina_Bool is_legacy)
|
2010-05-11 18:03:46 -07:00
|
|
|
{
|
2013-11-03 19:17:58 -08:00
|
|
|
Eina_File *file;
|
2010-05-11 18:03:46 -07:00
|
|
|
char buf2[1024];
|
2018-01-16 21:03:00 -08:00
|
|
|
const char *group_sep = "/";
|
|
|
|
const char *style_sep = ":";
|
2010-05-11 18:03:46 -07:00
|
|
|
|
2019-03-04 10:36:41 -08:00
|
|
|
if ((!clas) || !o) return EFL_UI_THEME_APPLY_ERROR_GENERIC;
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
2019-03-04 10:36:41 -08:00
|
|
|
if (!th) return EFL_UI_THEME_APPLY_ERROR_GENERIC;
|
2018-11-08 21:19:30 -08:00
|
|
|
|
|
|
|
if (eina_streq(style, "default")) style = NULL;
|
|
|
|
|
2018-01-16 20:59:22 -08:00
|
|
|
if (is_legacy)
|
2017-11-14 02:59:42 -08:00
|
|
|
snprintf(buf2, sizeof(buf2), "elm/%s/%s/%s", clas, (group) ? group : "base", (style) ? style : "default");
|
2018-01-16 20:59:22 -08:00
|
|
|
else
|
|
|
|
snprintf(buf2, sizeof(buf2), "efl/%s%s%s%s%s", clas,
|
|
|
|
((group) ? group_sep : "\0"), ((group) ? group : "\0"),
|
|
|
|
((style) ? style_sep : "\0"), ((style) ? style : "\0"));
|
2014-03-18 01:18:09 -07:00
|
|
|
if (!eina_hash_find(th->cache_style_load_failed, buf2))
|
2010-05-11 18:03:46 -07:00
|
|
|
{
|
2014-03-18 01:18:09 -07:00
|
|
|
file = _elm_theme_group_file_find(th, buf2);
|
|
|
|
if (file)
|
2013-02-19 00:22:15 -08:00
|
|
|
{
|
2019-03-04 10:36:41 -08:00
|
|
|
if (edje_object_mmap_set(o, file, buf2)) return EFL_UI_THEME_APPLY_ERROR_NONE;
|
2014-03-18 01:18:09 -07:00
|
|
|
else
|
|
|
|
{
|
2017-11-14 02:59:42 -08:00
|
|
|
ERR("could not set theme group '%s' from file '%s': %s",
|
2014-03-18 01:18:09 -07:00
|
|
|
buf2,
|
|
|
|
eina_file_filename_get(file),
|
|
|
|
edje_load_error_str(edje_object_load_error_get(o)));
|
|
|
|
}
|
2013-02-19 00:22:15 -08:00
|
|
|
}
|
2014-03-18 01:18:09 -07:00
|
|
|
//style not found, add to the not found list
|
|
|
|
eina_hash_add(th->cache_style_load_failed, buf2, (void *)1);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
2013-02-19 00:22:15 -08:00
|
|
|
|
2017-11-14 02:59:42 -08:00
|
|
|
if (!style)
|
2019-03-04 10:36:41 -08:00
|
|
|
return EFL_UI_THEME_APPLY_ERROR_GENERIC;
|
2017-11-14 02:59:42 -08:00
|
|
|
|
2016-12-07 02:27:05 -08:00
|
|
|
// Use the elementary default style.
|
2019-03-04 10:36:41 -08:00
|
|
|
if (_elm_theme_set(th, o, clas, group, NULL, is_legacy) == EFL_UI_THEME_APPLY_ERROR_NONE)
|
|
|
|
return EFL_UI_THEME_APPLY_ERROR_DEFAULT;
|
|
|
|
return EFL_UI_THEME_APPLY_ERROR_GENERIC;
|
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
|
|
|
{
|
2013-11-03 19:17:58 -08:00
|
|
|
Eina_File *file;
|
2010-05-11 18:03:46 -07:00
|
|
|
char buf2[1024];
|
|
|
|
int w, h;
|
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
if (efl_isa((o), ELM_ICON_CLASS) && elm_icon_standard_get(o) &&
|
2016-04-28 02:27:56 -07:00
|
|
|
strcmp(elm_config_icon_theme_get(), ELM_CONFIG_ICON_THEME_ELEMENTARY))
|
|
|
|
{
|
|
|
|
elm_icon_standard_set(o, elm_icon_standard_get(o));
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return EINA_FALSE;
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
snprintf(buf2, sizeof(buf2), "elm/icon/%s/%s", group, style);
|
|
|
|
file = _elm_theme_group_file_find(th, buf2);
|
|
|
|
if (file)
|
|
|
|
{
|
2013-11-03 19:17:58 -08:00
|
|
|
elm_image_mmap_set(o, file, buf2);
|
2012-05-28 14:50:11 -07:00
|
|
|
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
|
|
|
|
2013-11-03 19:17:58 -08:00
|
|
|
elm_image_mmap_set(o, file, buf2);
|
2012-05-28 14:50:11 -07:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2016-12-07 02:27:05 -08:00
|
|
|
void
|
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;
|
|
|
|
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
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;
|
|
|
|
}
|
2016-10-21 05:46:49 -07:00
|
|
|
#ifdef HAVE_ELEMENTARY_WIN32
|
|
|
|
else if (isalpha(pe[0]) && (pe[1] == ':') &&
|
|
|
|
((pe[2] == '/') || (pe[2] == '\\')))
|
2015-08-24 21:10:33 -07:00
|
|
|
{
|
2016-10-21 05:46:49 -07:00
|
|
|
// Correct processing file path on Windows OS "<disk>:/" or "<disk>:\"
|
2015-08-24 21:10:33 -07:00
|
|
|
eina_strbuf_append_char(buf, *pe);
|
|
|
|
pe++;
|
|
|
|
eina_strbuf_append_char(buf, *pe);
|
|
|
|
pe++;
|
|
|
|
}
|
2016-10-21 05:46:49 -07:00
|
|
|
#endif
|
2012-09-25 01:04:17 -07:00
|
|
|
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));
|
2018-02-28 23:44:01 -08:00
|
|
|
if ((!p) || (strcmp(p, "default")))
|
2010-05-11 18:03:46 -07:00
|
|
|
{
|
2018-02-28 23:44:01 -08:00
|
|
|
p = eina_stringshare_add("default");
|
2011-04-01 04:20:18 -07:00
|
|
|
if (p) names = eina_list_append(names, p);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
if (th->cache) eina_hash_free(th->cache);
|
2013-11-03 19:17:58 -08:00
|
|
|
th->cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_file_close));
|
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));
|
2014-03-18 01:18:09 -07:00
|
|
|
if (th->cache_style_load_failed) eina_hash_free(th->cache_style_load_failed);
|
|
|
|
th->cache_style_load_failed = eina_hash_string_superfast_new(NULL);
|
2018-02-27 12:07:13 -08:00
|
|
|
_elm_theme_file_clean(&th->themes);
|
|
|
|
th->theme_items = eina_list_free(th->theme_items);
|
2010-05-11 18:03:46 -07:00
|
|
|
|
2013-11-03 19:17:58 -08:00
|
|
|
EINA_LIST_FREE(names, p)
|
2014-03-28 00:17:38 -07:00
|
|
|
_elm_theme_file_item_add(&th->themes, p, EINA_FALSE, EINA_TRUE);
|
2018-02-27 11:21:14 -08:00
|
|
|
elm_theme_get(th);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
2018-11-19 20:56:37 -08:00
|
|
|
void
|
|
|
|
_elm_theme_init(void)
|
|
|
|
{
|
|
|
|
Eo *theme_default_obj;
|
|
|
|
Efl_Ui_Theme_Data *td;
|
|
|
|
|
|
|
|
if (theme_default) return;
|
|
|
|
|
|
|
|
theme_default_obj = efl_add(EFL_UI_THEME_CLASS, efl_main_loop_get());
|
|
|
|
td = efl_data_scope_get(theme_default_obj, EFL_UI_THEME_CLASS);
|
|
|
|
theme_default = td->th;
|
|
|
|
}
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
void
|
|
|
|
_elm_theme_shutdown(void)
|
|
|
|
{
|
2013-07-10 19:34:21 -07:00
|
|
|
Elm_Theme *th;
|
2018-11-19 20:56:37 -08:00
|
|
|
|
|
|
|
while (themes)
|
2013-07-10 19:34:21 -07:00
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
th = eina_list_data_get(themes);
|
|
|
|
|
|
|
|
/* In theme object destructor, theme is deallocated and the theme is
|
|
|
|
* removed from themes list in _elm_theme_free_internal().
|
|
|
|
* Consequently, themes list is updated.
|
|
|
|
*/
|
|
|
|
efl_del(th->eo_theme);
|
2013-07-10 19:34:21 -07:00
|
|
|
}
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
2021-10-31 04:44:57 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static Eina_List *
|
|
|
|
_elm_theme_file_color_class_list(Eina_List *list,
|
|
|
|
Eina_Inlist *handles)
|
|
|
|
{
|
|
|
|
Eina_Stringshare *c;
|
|
|
|
Eina_List *ccl;
|
|
|
|
Eina_List *ll;
|
|
|
|
Elm_Theme_File *etf;
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(handles, etf)
|
|
|
|
{
|
|
|
|
ccl = edje_mmap_color_class_used_list(etf->handle);
|
|
|
|
EINA_LIST_FOREACH(ccl, ll, c)
|
|
|
|
{
|
|
|
|
list = eina_list_append(list, eina_stringshare_add(c));
|
|
|
|
}
|
|
|
|
edje_file_color_class_used_free(ccl);
|
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_Bool
|
|
|
|
_elm_theme_color_class_list_hash_cb(const Eina_Hash *hash EINA_UNUSED,
|
|
|
|
const void *key,
|
|
|
|
void *data EINA_UNUSED,
|
|
|
|
void *fdata)
|
|
|
|
{
|
|
|
|
Eina_List **list = fdata;
|
|
|
|
|
|
|
|
*list = eina_list_append(*list, eina_stringshare_add(key));
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_List *
|
|
|
|
elm_theme_color_class_list(Elm_Theme *th)
|
|
|
|
{
|
|
|
|
Eina_List *list;
|
|
|
|
Eina_Hash *hash;
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return NULL;
|
|
|
|
|
|
|
|
// go through all possible theme files and find collections that match
|
|
|
|
list = _elm_theme_file_color_class_list(NULL, th->overlay);
|
|
|
|
list = _elm_theme_file_color_class_list(list, th->themes);
|
|
|
|
list = _elm_theme_file_color_class_list(list, th->extension);
|
|
|
|
|
|
|
|
hash = eina_hash_string_superfast_new(NULL);
|
|
|
|
EINA_LIST_FREE(list, s)
|
|
|
|
{
|
|
|
|
if (!eina_hash_find(hash, s)) eina_hash_add(hash, s, hash);
|
|
|
|
eina_stringshare_del(s);
|
|
|
|
}
|
|
|
|
eina_hash_foreach(hash, _elm_theme_color_class_list_hash_cb, &list);
|
|
|
|
eina_hash_free(hash);
|
|
|
|
|
|
|
|
// sort the list nicely at the end
|
|
|
|
list = eina_list_sort(list, 0, EINA_COMPARE_CB(strcmp));
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_theme_color_class_list_free(Eina_List *list)
|
|
|
|
{
|
|
|
|
const char *s;
|
|
|
|
|
|
|
|
EINA_LIST_FREE(list, s) eina_stringshare_del(s);
|
|
|
|
}
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
EAPI Elm_Theme *
|
|
|
|
elm_theme_new(void)
|
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
Eo *obj = efl_add(EFL_UI_THEME_CLASS, efl_main_loop_get());
|
|
|
|
Efl_Ui_Theme_Data *td = efl_data_scope_get(obj, EFL_UI_THEME_CLASS);
|
|
|
|
return td->th;
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_theme_free(Elm_Theme *th)
|
|
|
|
{
|
2010-12-03 06:08:33 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(th);
|
2018-11-19 20:56:37 -08:00
|
|
|
|
|
|
|
/* Destructs theme object and theme is deallocated in
|
|
|
|
* _elm_theme_free_internal() in theme object desctructor.
|
|
|
|
*/
|
2019-04-25 05:24:42 -07:00
|
|
|
if (efl_ref_count(th->eo_theme) > 1)
|
|
|
|
efl_unref(th->eo_theme);
|
|
|
|
else
|
|
|
|
efl_del(th->eo_theme);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
2013-11-03 19:17:58 -08:00
|
|
|
static void
|
2018-02-27 12:07:13 -08:00
|
|
|
elm_theme_files_copy(Eina_Inlist **dst, Eina_Inlist **src)
|
2010-11-05 01:37:31 -07:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
Elm_Theme_File *etf, *cpy;
|
2011-04-01 04:20:18 -07:00
|
|
|
|
2018-02-27 12:07:13 -08:00
|
|
|
EINA_INLIST_FOREACH(*src, etf)
|
|
|
|
{
|
|
|
|
cpy = malloc(sizeof(Elm_Theme_File));
|
2019-01-29 06:23:44 -08:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(cpy);
|
2018-02-27 12:07:13 -08:00
|
|
|
cpy->item = eina_stringshare_ref(etf->item);
|
|
|
|
cpy->handle = eina_file_dup(etf->handle);
|
|
|
|
*dst = eina_inlist_append(*dst, EINA_INLIST_GET(cpy));
|
|
|
|
}
|
2013-11-03 19:17:58 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_theme_copy(Elm_Theme *th, Elm_Theme *thdst)
|
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
Eo *thdst_obj;
|
|
|
|
Efl_Ui_Theme_Data *thdst_td;
|
|
|
|
|
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
|
|
|
if (!thdst) thdst = theme_default;
|
|
|
|
if (!thdst) return;
|
|
|
|
|
|
|
|
//Clear the given theme and restore the relationship with theme object.
|
|
|
|
thdst_obj = thdst->eo_theme;
|
2010-11-05 01:37:31 -07:00
|
|
|
_elm_theme_clear(thdst);
|
2018-11-19 20:56:37 -08:00
|
|
|
thdst->eo_theme = thdst_obj;
|
|
|
|
thdst_td = efl_data_scope_get(thdst_obj, EFL_UI_THEME_CLASS);
|
|
|
|
thdst_td->th = thdst;
|
|
|
|
|
2010-11-05 01:37:31 -07:00
|
|
|
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);
|
2018-11-19 20:56:37 -08:00
|
|
|
efl_ref(thdst->ref_theme->eo_theme);
|
2010-11-05 01:37:31 -07:00
|
|
|
}
|
2013-11-03 19:17:58 -08:00
|
|
|
elm_theme_files_copy(&thdst->overlay, &th->overlay);
|
|
|
|
elm_theme_files_copy(&thdst->themes, &th->themes);
|
|
|
|
elm_theme_files_copy(&thdst->extension, &th->extension);
|
|
|
|
|
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)
|
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
Eo *th_obj;
|
|
|
|
Efl_Ui_Theme_Data *th_td;
|
|
|
|
|
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
|
|
|
if (!thref) thref = theme_default;
|
|
|
|
if (!thref) return;
|
2010-11-05 01:37:31 -07:00
|
|
|
if (th->ref_theme == thref) return;
|
2018-11-19 20:56:37 -08:00
|
|
|
|
|
|
|
//Clear the given theme and restore the relationship with theme object.
|
|
|
|
th_obj = th->eo_theme;
|
2010-11-05 01:37:31 -07:00
|
|
|
_elm_theme_clear(th);
|
2018-11-19 20:56:37 -08:00
|
|
|
th->eo_theme = th_obj;
|
|
|
|
th_td = efl_data_scope_get(th_obj, EFL_UI_THEME_CLASS);
|
|
|
|
th_td->th = th;
|
|
|
|
|
2010-11-05 01:37:31 -07:00
|
|
|
if (thref)
|
|
|
|
{
|
2011-04-01 04:20:18 -07:00
|
|
|
thref->referrers = eina_list_append(thref->referrers, th);
|
2018-11-19 20:56:37 -08:00
|
|
|
efl_ref(thref->eo_theme);
|
2010-11-05 01:37:31 -07:00
|
|
|
}
|
|
|
|
th->ref_theme = thref;
|
|
|
|
elm_theme_flush(th);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Elm_Theme *
|
2015-06-08 10:44:29 -07:00
|
|
|
elm_theme_ref_get(const Elm_Theme *th)
|
2010-11-05 01:37:31 -07:00
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return NULL;
|
2010-11-05 01:37:31 -07:00
|
|
|
return th->ref_theme;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Elm_Theme *
|
|
|
|
elm_theme_default_get(void)
|
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
return theme_default;
|
2010-11-05 01:37:31 -07:00
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
|
|
|
efl_ui_theme_overlay_add(th->eo_theme, item);
|
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
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
|
|
|
efl_ui_theme_overlay_del(th->eo_theme, item);
|
2009-02-23 00:40:58 -08:00
|
|
|
}
|
|
|
|
|
2013-11-03 21:26:05 -08:00
|
|
|
EAPI void
|
|
|
|
elm_theme_overlay_mmap_add(Elm_Theme *th, const Eina_File *f)
|
|
|
|
{
|
|
|
|
Eina_File *file = eina_file_dup(f);
|
|
|
|
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
2019-08-05 06:28:40 -07:00
|
|
|
if (!th)
|
|
|
|
{
|
2019-08-20 16:32:38 -07:00
|
|
|
eina_file_close(file); // close matching open (finalize expected to consume eina file) OK
|
2019-08-05 06:28:40 -07:00
|
|
|
return;
|
|
|
|
}
|
2018-02-27 12:07:13 -08:00
|
|
|
th->overlay_items = eina_list_free(th->overlay_items);
|
2016-09-27 10:54:09 -07:00
|
|
|
_elm_theme_item_finalize(&th->overlay, eina_file_filename_get(file), file, EINA_TRUE, EINA_FALSE);
|
2013-11-03 21:26:05 -08:00
|
|
|
elm_theme_flush(th);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_theme_overlay_mmap_del(Elm_Theme *th, const Eina_File *f)
|
|
|
|
{
|
2014-03-14 19:44:20 -07:00
|
|
|
if (!f) return;
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
2018-02-27 12:07:13 -08:00
|
|
|
th->overlay_items = eina_list_free(th->overlay_items);
|
2013-11-03 21:26:05 -08:00
|
|
|
_elm_theme_file_mmap_del(&th->overlay, f);
|
|
|
|
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_overlay_list_get(const Elm_Theme *th)
|
2012-03-05 13:48:32 -08:00
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return NULL;
|
2018-02-27 12:07:13 -08:00
|
|
|
if (!th->overlay_items)
|
|
|
|
{
|
|
|
|
Elm_Theme_File *etf;
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(th->overlay, etf)
|
|
|
|
((Elm_Theme*)th)->overlay_items = eina_list_append(th->overlay_items, etf->item);
|
|
|
|
}
|
|
|
|
return th->overlay_items;
|
2012-03-05 13:48:32 -08:00
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
|
|
|
efl_ui_theme_extension_add(th->eo_theme, item);
|
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
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
|
|
|
efl_ui_theme_extension_del(th->eo_theme, item);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
2013-11-03 21:26:05 -08:00
|
|
|
EAPI void
|
|
|
|
elm_theme_extension_mmap_add(Elm_Theme *th, const Eina_File *f)
|
|
|
|
{
|
2019-08-20 07:16:04 -07:00
|
|
|
Eina_File *file;
|
2013-11-03 21:26:05 -08:00
|
|
|
|
2014-03-14 19:44:20 -07:00
|
|
|
if (!f) return;
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
2019-08-20 07:16:04 -07:00
|
|
|
file = eina_file_dup(f);
|
2018-02-27 12:07:13 -08:00
|
|
|
th->extension_items = eina_list_free(th->extension_items);
|
2016-09-27 10:54:09 -07:00
|
|
|
_elm_theme_item_finalize(&th->extension, eina_file_filename_get(file), file, EINA_FALSE, EINA_FALSE);
|
2013-11-03 21:26:05 -08:00
|
|
|
elm_theme_flush(th);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
elm_theme_extension_mmap_del(Elm_Theme *th, const Eina_File *f)
|
|
|
|
{
|
2014-03-14 19:44:20 -07:00
|
|
|
if (!f) return;
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
2018-02-27 12:07:13 -08:00
|
|
|
th->extension_items = eina_list_free(th->extension_items);
|
2013-11-03 21:26:05 -08:00
|
|
|
_elm_theme_file_mmap_del(&th->extension, f);
|
|
|
|
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
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return NULL;
|
2018-02-27 12:07:13 -08:00
|
|
|
if (!th->extension_items)
|
|
|
|
{
|
|
|
|
Elm_Theme_File *etf;
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(th->extension, etf)
|
|
|
|
((Elm_Theme*)th)->extension_items = eina_list_append(th->extension_items, etf->item);
|
|
|
|
}
|
|
|
|
return th->extension_items;
|
2012-03-05 13:48:32 -08:00
|
|
|
}
|
|
|
|
|
2010-05-11 18:03:46 -07:00
|
|
|
EAPI void
|
|
|
|
elm_theme_set(Elm_Theme *th, const char *theme)
|
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
2010-05-11 18:03:46 -07:00
|
|
|
_elm_theme_parse(th, theme);
|
2013-05-29 05:08:05 -07:00
|
|
|
ELM_SAFE_FREE(th->theme, eina_stringshare_del);
|
2010-05-11 18:03:46 -07:00
|
|
|
elm_theme_flush(th);
|
2018-11-19 20:56:37 -08:00
|
|
|
if (th == theme_default)
|
2012-03-05 04:39:22 -08:00
|
|
|
eina_stringshare_replace(&_elm_config->theme, theme);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
elm_theme_get(Elm_Theme *th)
|
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return NULL;
|
2010-05-11 18:03:46 -07:00
|
|
|
if (!th->theme)
|
|
|
|
{
|
2012-09-25 01:04:17 -07:00
|
|
|
Eina_Strbuf *buf;
|
2018-02-27 12:07:13 -08:00
|
|
|
Elm_Theme_File *etf;
|
2010-05-11 18:03:46 -07:00
|
|
|
const char *f;
|
2010-10-25 07:34:22 -07:00
|
|
|
|
2012-09-25 01:04:17 -07:00
|
|
|
buf = eina_strbuf_new();
|
2018-02-27 12:07:13 -08:00
|
|
|
EINA_INLIST_FOREACH(th->themes, etf)
|
2010-05-11 18:03:46 -07:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
f = etf->item;
|
2012-09-25 01:04:17 -07:00
|
|
|
while (*f)
|
|
|
|
{
|
|
|
|
if (*f == ':')
|
|
|
|
eina_strbuf_append_char(buf, '\\');
|
|
|
|
eina_strbuf_append_char(buf, *f);
|
|
|
|
|
|
|
|
f++;
|
|
|
|
}
|
2018-02-27 12:07:13 -08:00
|
|
|
if (EINA_INLIST_GET(etf)->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
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return NULL;
|
2018-02-27 12:07:13 -08:00
|
|
|
if (!th->theme_items)
|
|
|
|
{
|
|
|
|
Elm_Theme_File *etf;
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(th->themes, etf)
|
|
|
|
((Elm_Theme*)th)->theme_items = eina_list_append(th->theme_items, etf->item);
|
|
|
|
}
|
|
|
|
return th->theme_items;
|
2010-09-23 22:11:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2015-05-14 12:26:44 -07:00
|
|
|
home = eina_environment_home_get();
|
2011-04-01 04:20:18 -07:00
|
|
|
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
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return;
|
2010-05-11 18:03:46 -07:00
|
|
|
if (th->cache) eina_hash_free(th->cache);
|
2013-11-03 19:17:58 -08:00
|
|
|
th->cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_file_close));
|
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));
|
2014-03-18 01:18:09 -07:00
|
|
|
if (th->cache_style_load_failed) eina_hash_free(th->cache_style_load_failed);
|
|
|
|
th->cache_style_load_failed = eina_hash_string_superfast_new(NULL);
|
2010-11-05 01:37:31 -07:00
|
|
|
_elm_win_rescale(th, EINA_TRUE);
|
|
|
|
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);
|
|
|
|
}
|
2018-11-19 20:56:37 -08:00
|
|
|
elm_theme_flush(theme_default);
|
2010-05-11 18:03:46 -07:00
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
{
|
2015-05-14 12:26:44 -07:00
|
|
|
home = eina_environment_home_get();
|
2010-09-23 22:11:33 -07:00
|
|
|
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))
|
|
|
|
{
|
2020-08-30 13:22:49 -07:00
|
|
|
if (eina_str_has_extension(file, ".edj"))
|
2010-09-23 22:11:33 -07:00
|
|
|
{
|
|
|
|
th = strdup(file);
|
2015-08-04 06:39:36 -07:00
|
|
|
s = strrchr(th, '.');
|
2010-09-23 22:11:33 -07:00
|
|
|
*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))
|
|
|
|
{
|
2020-08-30 13:22:49 -07:00
|
|
|
if (eina_str_has_extension(file, ".edj"))
|
2010-09-23 22:11:33 -07:00
|
|
|
{
|
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);
|
2015-08-04 06:39:36 -07:00
|
|
|
s = strrchr(th, '.');
|
2010-09-23 22:11:33 -07:00
|
|
|
*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)
|
|
|
|
{
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return NULL;
|
2011-09-11 18:05:07 -07:00
|
|
|
return _elm_theme_data_find(th, key);
|
|
|
|
}
|
2013-10-31 07:22:18 -07:00
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
elm_theme_group_path_find(Elm_Theme *th, const char *group)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(group, NULL);
|
2013-12-22 21:49:50 -08:00
|
|
|
Eina_File *th_file = NULL;
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return NULL;
|
2013-12-22 21:49:50 -08:00
|
|
|
|
|
|
|
th_file = _elm_theme_group_file_find(th, group);
|
|
|
|
if (th_file)
|
|
|
|
return eina_file_filename_get(th_file);
|
|
|
|
return NULL;
|
2013-10-31 07:22:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static Eina_List *
|
2013-11-03 19:17:58 -08:00
|
|
|
_elm_theme_file_group_base_list(Eina_List *list,
|
2018-02-27 12:07:13 -08:00
|
|
|
Eina_Inlist *handles,
|
2013-11-03 19:17:58 -08:00
|
|
|
const char *base, int len)
|
2013-10-31 07:22:18 -07:00
|
|
|
{
|
2013-11-03 19:17:58 -08:00
|
|
|
Eina_Stringshare *c, *c2;
|
|
|
|
Eina_List *coll;
|
2018-02-27 12:07:13 -08:00
|
|
|
Eina_List *in, *ll;
|
|
|
|
Elm_Theme_File *etf;
|
2013-10-31 07:22:18 -07:00
|
|
|
|
2018-02-27 12:07:13 -08:00
|
|
|
EINA_INLIST_FOREACH(handles, etf)
|
2013-10-31 07:22:18 -07:00
|
|
|
{
|
2018-02-27 12:07:13 -08:00
|
|
|
coll = edje_mmap_collection_list(etf->handle);
|
2013-11-03 19:17:58 -08:00
|
|
|
EINA_LIST_FOREACH(coll, ll, c)
|
|
|
|
{
|
|
|
|
// if base == start of collection str
|
|
|
|
if (!strncmp(c, base, len))
|
|
|
|
{
|
|
|
|
// check if already in list
|
|
|
|
EINA_LIST_FOREACH(list, in, c2)
|
|
|
|
if (c == c2)
|
|
|
|
break;
|
|
|
|
|
|
|
|
// if not already in list append shared str to list
|
|
|
|
if (!in)
|
|
|
|
list = eina_list_append(list, eina_stringshare_ref(c));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
edje_mmap_collection_list_free(coll);
|
2013-10-31 07:22:18 -07:00
|
|
|
}
|
2013-11-03 19:17:58 -08:00
|
|
|
|
2013-10-31 07:22:18 -07:00
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_List *
|
|
|
|
elm_theme_group_base_list(Elm_Theme *th, const char *base)
|
|
|
|
{
|
2013-11-03 19:17:58 -08:00
|
|
|
Eina_List *list;
|
2013-10-31 07:22:18 -07:00
|
|
|
int len;
|
2013-11-03 19:17:58 -08:00
|
|
|
|
2013-10-31 07:22:18 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(base, NULL);
|
2018-11-19 20:56:37 -08:00
|
|
|
if (!th) th = theme_default;
|
|
|
|
if (!th) return NULL;
|
2013-10-31 07:22:18 -07:00
|
|
|
|
|
|
|
// XXX: look results up in a hash for speed
|
|
|
|
len = strlen(base);
|
|
|
|
// go through all possible theme files and find collections that match
|
2018-02-27 12:07:13 -08:00
|
|
|
list = _elm_theme_file_group_base_list(NULL, th->overlay,
|
2013-11-03 19:17:58 -08:00
|
|
|
base, len);
|
2018-02-27 12:07:13 -08:00
|
|
|
list = _elm_theme_file_group_base_list(list, th->themes,
|
2013-11-03 19:17:58 -08:00
|
|
|
base, len);
|
2018-02-27 12:07:13 -08:00
|
|
|
list = _elm_theme_file_group_base_list(list, th->extension,
|
2013-11-03 19:17:58 -08:00
|
|
|
base, len);
|
|
|
|
|
2013-10-31 07:22:18 -07:00
|
|
|
// sort the list nicely at the end
|
|
|
|
list = eina_list_sort(list, 0, EINA_COMPARE_CB(strcmp));
|
|
|
|
// XXX: store results in hash for fast lookup...
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
elm_theme_system_dir_get(void)
|
|
|
|
{
|
|
|
|
static char *path = NULL;
|
|
|
|
char buf[PATH_MAX];
|
2013-12-02 02:43:46 -08:00
|
|
|
|
2013-10-31 07:22:18 -07:00
|
|
|
if (path) return path;
|
2014-05-03 14:18:44 -07:00
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s/themes", _elm_data_dir);
|
|
|
|
path = strdup(buf);
|
|
|
|
|
2013-10-31 07:22:18 -07:00
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
elm_theme_user_dir_get(void)
|
|
|
|
{
|
|
|
|
static char *path = NULL;
|
|
|
|
char buf[PATH_MAX];
|
2015-05-14 12:26:44 -07:00
|
|
|
const char *home;
|
2013-12-02 02:43:46 -08:00
|
|
|
|
2013-10-31 07:22:18 -07:00
|
|
|
if (path) return path;
|
2013-12-02 02:43:46 -08:00
|
|
|
|
2015-05-14 12:26:44 -07:00
|
|
|
home = eina_environment_home_get();
|
2014-05-03 14:18:44 -07:00
|
|
|
snprintf(buf, sizeof(buf), "%s/"ELEMENTARY_BASE_DIR"/themes", home);
|
|
|
|
path = strdup(buf);
|
|
|
|
|
2013-10-31 07:22:18 -07:00
|
|
|
return path;
|
|
|
|
}
|
2018-11-19 20:56:37 -08:00
|
|
|
|
|
|
|
/* Allocates memory for theme and appends the theme to themes list. */
|
|
|
|
static Elm_Theme *
|
|
|
|
_elm_theme_new_internal(Eo *obj)
|
|
|
|
{
|
|
|
|
Elm_Theme *th = calloc(1, sizeof(Elm_Theme));
|
|
|
|
if (!th) return NULL;
|
|
|
|
_elm_theme_file_item_add(&th->themes, "default", EINA_FALSE, EINA_TRUE);
|
|
|
|
themes = eina_list_append(themes, th);
|
|
|
|
th->eo_theme = obj;
|
|
|
|
return th;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eo *
|
|
|
|
_efl_ui_theme_efl_object_constructor(Eo *obj, Efl_Ui_Theme_Data *pd)
|
|
|
|
{
|
|
|
|
obj = efl_constructor(efl_super(obj, EFL_UI_THEME_CLASS));
|
|
|
|
|
|
|
|
pd->th = _elm_theme_new_internal(obj);
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Removes the given theme from themes list and deallocates the given theme. */
|
|
|
|
static void
|
|
|
|
_elm_theme_free_internal(Elm_Theme *th)
|
|
|
|
{
|
|
|
|
_elm_theme_clear(th);
|
|
|
|
themes = eina_list_remove(themes, th);
|
|
|
|
free(th);
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_ui_theme_efl_object_destructor(Eo *obj, Efl_Ui_Theme_Data *pd)
|
|
|
|
{
|
|
|
|
Eina_Bool is_theme_default = EINA_FALSE;
|
|
|
|
|
|
|
|
if (pd->th == theme_default)
|
|
|
|
is_theme_default = EINA_TRUE;
|
|
|
|
|
|
|
|
_elm_theme_free_internal(pd->th);
|
|
|
|
|
|
|
|
if (is_theme_default) theme_default = NULL;
|
|
|
|
|
|
|
|
efl_destructor(efl_super(obj, EFL_UI_THEME_CLASS));
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Efl_Ui_Theme *
|
2019-02-09 09:45:27 -08:00
|
|
|
_efl_ui_theme_default_get(void)
|
2018-11-19 20:56:37 -08:00
|
|
|
{
|
|
|
|
if (theme_default)
|
|
|
|
return theme_default->eo_theme;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_ui_theme_extension_add(Eo *obj EINA_UNUSED, Efl_Ui_Theme_Data *pd, const char *item)
|
|
|
|
{
|
|
|
|
if (!item) return;
|
|
|
|
pd->th->extension_items = eina_list_free(pd->th->extension_items);
|
|
|
|
_elm_theme_file_item_add(&pd->th->extension, item, EINA_FALSE, EINA_FALSE);
|
|
|
|
elm_theme_flush(pd->th);
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_ui_theme_extension_del(Eo *obj EINA_UNUSED, Efl_Ui_Theme_Data *pd, const char *item)
|
|
|
|
{
|
|
|
|
if (!item) return;
|
|
|
|
pd->th->extension_items = eina_list_free(pd->th->extension_items);
|
|
|
|
_elm_theme_file_item_del(&pd->th->extension, item);
|
|
|
|
elm_theme_flush(pd->th);
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_ui_theme_overlay_add(Eo *obj EINA_UNUSED, Efl_Ui_Theme_Data *pd, const char *item)
|
|
|
|
{
|
|
|
|
if (!item) return;
|
|
|
|
pd->th->overlay_items = eina_list_free(pd->th->overlay_items);
|
|
|
|
_elm_theme_file_item_add(&pd->th->overlay, item, EINA_TRUE, EINA_FALSE);
|
|
|
|
elm_theme_flush(pd->th);
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
|
|
|
_efl_ui_theme_overlay_del(Eo *obj EINA_UNUSED, Efl_Ui_Theme_Data *pd, const char *item)
|
|
|
|
{
|
|
|
|
if (!item) return;
|
|
|
|
pd->th->overlay_items = eina_list_free(pd->th->overlay_items);
|
|
|
|
_elm_theme_file_item_del(&pd->th->overlay, item);
|
|
|
|
elm_theme_flush(pd->th);
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "efl_ui_theme.eo.c"
|