make theme browser in elm config util actually work. add api's needed.

it's simple. only allows 1 level of theme. would need an advanced
dialog to allow:

theme1:theme2:theme3:theme4... etc.

also no browsing for themes - just whats instaleld n system and user
dirs atm.



SVN revision: 52667
This commit is contained in:
Carsten Haitzler 2010-09-24 05:11:33 +00:00
parent 8c4df25efe
commit d81485068a
4 changed files with 307 additions and 18 deletions

View File

@ -1,6 +1,19 @@
#include <Elementary.h>
#ifndef ELM_LIB_QUICKLAUNCH
typedef struct _Theme Theme;
struct _Theme
{
const char *label;
const char *name;
const char *path;
Eina_Bool in_search_path;
};
static Theme *tsel = NULL;
static Eina_List *themes = NULL;
static int quiet = 0;
static int interactive = 1;
@ -238,7 +251,63 @@ _cf_caches(void *data, Evas_Object *obj, void *event_info)
static void
_theme_use(void *data, Evas_Object *obj, void *event_info)
{
printf("not implemented\n");
const char *defth;
char *newth;
Theme *t = tsel;
if (!t) return;
defth = elm_theme_get(NULL);
newth = malloc(strlen(defth) + 1 + strlen(t->name) + 1);
if (newth)
{
char *rest;
newth[0] = 0;
rest = strchr(defth, ':');
if (!rest)
strcpy(newth, t->name);
else
{
strcpy(newth, t->name);
strcat(newth, rest);
}
elm_theme_all_set(newth);
free(newth);
}
}
static void
_theme_sel(void *data, Evas_Object *obj, void *event_info)
{
Theme *t = data;
Evas_Object *win = elm_object_top_widget_get(obj);
Evas_Object *sample = evas_object_data_get(win, "sample");
Elm_Theme *th;
const char *defth;
char *newth;
tsel = t;
defth = elm_theme_get(NULL);
newth = malloc(strlen(defth) + 1 + strlen(t->name) + 1);
th = elm_theme_new();
if (newth)
{
char *rest;
newth[0] = 0;
rest = strchr(defth, ':');
if (!rest)
strcpy(newth, t->name);
else
{
strcpy(newth, t->name);
strcat(newth, rest);
}
elm_theme_set(th, newth);
free(newth);
}
elm_object_theme_set(sample, th);
elm_theme_free(th);
}
static void
@ -336,7 +405,7 @@ _sample_theme_new(Evas_Object *win)
bg = elm_bg_add(win);
evas_object_size_hint_weight_set(bg, 1.0, 1.0);
evas_object_size_hint_align_set(bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_table_pack(base, bg, 0, 0, 2, 4);
elm_table_pack(base, bg, 0, 0, 2, 5);
evas_object_show(bg);
bt = elm_button_add(win);
@ -409,6 +478,8 @@ static void
_status_config_themes(Evas_Object *win, Evas_Object *holder)
{
Evas_Object *tb, *rc, *sc, *sp, *li, *pd, *fr, *bt, *sample;
Eina_List *list, *l;
char *th, *s, *ext;
tb = elm_table_add(win);
evas_object_size_hint_weight_set(tb, 1.0, 1.0);
@ -437,17 +508,49 @@ _status_config_themes(Evas_Object *win, Evas_Object *holder)
elm_frame_content_set(pd, li);
evas_object_show(li);
// FIXME: list all themes:
// ~/.elementary/themes/*.edj
// $PREFIX/datadir/themes/*.edj
elm_list_item_append(li, "theme 1", NULL, NULL, NULL, NULL);
elm_list_item_append(li, "theme 2", NULL, NULL, NULL, NULL);
elm_list_item_append(li, "theme 3", NULL, NULL, NULL, NULL);
elm_list_item_append(li, "theme 4", NULL, NULL, NULL, NULL);
elm_list_item_append(li, "theme 5", NULL, NULL, NULL, NULL);
elm_list_item_append(li, "theme 6", NULL, NULL, NULL, NULL);
elm_list_item_append(li, "theme 7", NULL, NULL, NULL, NULL);
list = elm_theme_name_available_list_new();
EINA_LIST_FOREACH(list, l, th)
{
Theme *t;
t = calloc(1, sizeof(Theme));
t->name = eina_stringshare_add(th);
s = elm_theme_list_item_path_get(th, &(t->in_search_path));
if (s)
{
t->path = eina_stringshare_add(s);
free(s);
}
if (t->in_search_path)
{
s = strdup(th);
if (s)
{
s[0] = toupper(s[0]);
t->label = eina_stringshare_add(s);
free(s);
}
else
t->label = eina_stringshare_add(s);
}
else
{
s = strdup(ecore_file_file_get(th));
if (s)
{
s[0] = toupper(s[0]);
ext = strrchr(s, '.');
if (ext) *ext = 0;
t->label = eina_stringshare_add(s);
free(s);
}
else
t->label = eina_stringshare_add(s);
}
themes = eina_list_append(themes, t);
elm_list_item_append(li, t->label, NULL, NULL, _theme_sel, t);
}
elm_theme_name_available_list_free(list);
elm_list_go(li);
@ -458,6 +561,7 @@ _status_config_themes(Evas_Object *win, Evas_Object *holder)
elm_table_pack(tb, pd, 0, 0, 1, 1);
evas_object_show(pd);
/* FIXME: not implemented yet
bt = elm_button_add(win);
evas_object_smart_callback_add(bt, "clicked", _theme_browse, win);
elm_button_label_set(bt, "Browse...");
@ -465,7 +569,7 @@ _status_config_themes(Evas_Object *win, Evas_Object *holder)
evas_object_size_hint_align_set(bt, 0.9, 0.9);
elm_frame_content_set(pd, bt);
evas_object_show(bt);
*/
pd = elm_frame_add(win);
elm_object_style_set(pd, "pad_medium");
evas_object_size_hint_weight_set(pd, 1.0, 0.0);

View File

@ -339,11 +339,16 @@ extern "C" {
EAPI void elm_theme_extension_del(Elm_Theme *th, const char *item);
EAPI void elm_theme_set(Elm_Theme *th, const char *theme);
EAPI const char *elm_theme_get(Elm_Theme *th);
EAPI const Eina_List *elm_theme_list_get(Elm_Theme *th);
EAPI char *elm_theme_list_item_path_get(const char *f, Eina_Bool *in_search_path);
EAPI void elm_theme_flush(Elm_Theme *th);
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);

View File

@ -14,6 +14,7 @@ struct _Widget_Data
{
Evas_Object *frm;
Evas_Object *content;
const char *label;
};
static const char *widtype = NULL;
@ -28,6 +29,7 @@ _del_hook(Evas_Object *obj)
{
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
if (wd->label) eina_stringshare_del(wd->label);
free(wd);
}
@ -37,6 +39,7 @@ _theme_hook(Evas_Object *obj)
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
_elm_theme_object_set(obj, wd->frm, "frame", "base", elm_widget_style_get(obj));
edje_object_part_text_set(wd->frm, "elm.text", wd->label);
if (wd->content)
edje_object_part_swallow(wd->frm, "elm.swallow.content", wd->content);
edje_object_scale_set(wd->frm, elm_widget_scale_get(obj) * _elm_config->scale);
@ -129,7 +132,8 @@ elm_frame_label_set(Evas_Object *obj, const char *label)
ELM_CHECK_WIDTYPE(obj, widtype);
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
edje_object_part_text_set(wd->frm, "elm.text", label);
eina_stringshare_replace(&(wd->label), label);
edje_object_part_text_set(wd->frm, "elm.text", wd->label);
_sizing_eval(obj);
}
@ -147,8 +151,8 @@ elm_frame_label_get(const Evas_Object *obj)
{
ELM_CHECK_WIDTYPE(obj, widtype) NULL;
Widget_Data *wd = elm_widget_data_get(obj);
if ((!wd) || (!wd->frm)) return NULL;
return edje_object_part_text_get(wd->frm, "elm.text");
if (!wd) return NULL;
return wd->label;
}
/**

View File

@ -433,6 +433,7 @@ elm_theme_set(Elm_Theme *th, const char *theme)
EAPI const char *
elm_theme_get(Elm_Theme *th)
{
if (!th) th = &(theme_default);
if (!th->theme)
{
Eina_List *l;
@ -458,6 +459,90 @@ elm_theme_get(Elm_Theme *th)
return th->theme;
}
/**
* Return a list of theme elements to be used in a theme.
*
* @param th Theme to get the list of theme elements from.
* @return The internal list of theme elements
*
* This returns the internal list of theme elements (will only be valid as
* long as the theme is not modified by elm_theme_set() or theme is not
* freed by elm_theme_free(). This is a list of strings which must not be
* altered as they are also internal. If @p th is NULL, then the default
* theme element list is returned.
*/
EAPI const Eina_List *
elm_theme_list_get(Elm_Theme *th)
{
if (!th) th = &(theme_default);
return th->themes;
}
/**
* Return the full patrh for a theme element
*
* @param f The theme element name
* @param in_search_path Pointer to a boolean to indicate if item is in the search path or not
* @return The full path to the file found.
*
* This returns a string you should free with free() on success, NULL on
* failure. This will search for the given theme element, and if it is a
* full or relative path element or a simple searchable name. The returned
* path is the full path to the file, if searched, and the file exists, or it
* is simply the full path given in the element or a resolved path if
* relative to home. The @p in_search_path boolean pointed to is set to
* EINA_TRUE if the file was a searchable file andis in the search path,
* and EINA_FALSE otherwise.
*/
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];
if (!f)
{
if (in_search_path) *in_search_path = EINA_FALSE;
return NULL;
}
if (!home)
{
home = getenv("HOME");
if (!home) home = "";
}
if ((f[0] == '/') || ((f[0] == '.') && (f[1] == '/')) ||
((f[0] == '.') && (f[1] == '.') && (f[2] == '/')) ||
(isalpha(f[0]) && f[1] == ':'))
{
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;
snprintf(buf, sizeof(buf), "%s/%s", home, f + 2);
return strdup(buf);
}
snprintf(buf, sizeof(buf), "%s/.elementary/themes/%s.edj", home, f);
if (ecore_file_exists(buf))
{
if (in_search_path) *in_search_path = EINA_TRUE;
return strdup(buf);
}
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);
}
if (in_search_path) *in_search_path = EINA_FALSE;
return NULL;
}
/**
* Flush the current theme.
*
@ -521,6 +606,97 @@ elm_theme_all_set(const char *theme)
elm_theme_set(NULL, theme);
}
/**
* Return a list of theme elements in the theme search path
*
* @return A list of strings that are the theme element names.
*
* This lists all available theme files in the standard Elementary search path
* for theme elements, and returns them in alphabetical order as theme
* element names in a list of strings. Free this with
* elm_theme_name_available_list_free() when you are done with the list.
*/
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;
if (!home)
{
home = getenv("HOME");
if (!home) home = "";
}
snprintf(buf, sizeof(buf), "%s/.elementary/themes", home);
dir = ecore_file_ls(buf);
EINA_LIST_FREE(dir, file)
{
snprintf(buf, sizeof(buf), "%s/.elementary/themes/%s", home, file);
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")))
{
int dup;
th = strdup(file);
s = strchr(th, '.');
*s = 0;
dup = 0;
EINA_LIST_FOREACH(list, l, s)
{
if (!strcmp(s, th))
{
dup = 1;
break;
}
}
if (dup) free(th);
else list = eina_list_append(list, th);
}
}
free(file);
}
list = eina_list_sort(list, 0, EINA_COMPARE_CB(strcasecmp));
return list;
}
/**
* Free the list returned by elm_theme_name_available_list_new()
*
* This frees the list of themes returned by
* elm_theme_name_available_list_new(). Once freed the list should no longer
* be used. a new list mys be created.
*/
EAPI void
elm_theme_name_available_list_free(Eina_List *list)
{
char *s;
EINA_LIST_FREE(list, s) free(s);
}
/**
* Set a specific theme to be used for this object and its children
*