elm theme can be copied, referenced and theme flush tries to ONLY

flush a specific theme if told so (and only those widgets and their
children).



SVN revision: 54169
This commit is contained in:
Carsten Haitzler 2010-11-05 08:37:31 +00:00
parent 7db634e8f9
commit 5400a9a7f1
7 changed files with 183 additions and 18 deletions

View File

@ -393,6 +393,10 @@ extern "C" {
EAPI Elm_Theme *elm_theme_new(void);
EAPI void elm_theme_free(Elm_Theme *th);
EAPI void elm_theme_copy(Elm_Theme *th, Elm_Theme *thdst);
EAPI void elm_theme_ref_set(Elm_Theme *th, Elm_Theme *thref);
EAPI Elm_Theme *elm_theme_ref_get(Elm_Theme *th);
EAPI Elm_Theme *elm_theme_default_get(void);
EAPI void elm_theme_overlay_add(Elm_Theme *th, const char *item);
EAPI void elm_theme_overlay_del(Elm_Theme *th, const char *item);
EAPI void elm_theme_extension_add(Elm_Theme *th, const char *item);

View File

@ -313,7 +313,7 @@ void
_elm_rescale(void)
{
edje_scale_set(_elm_config->scale);
_elm_win_rescale();
_elm_win_rescale(NULL, EINA_FALSE);
}
/**

View File

@ -35,6 +35,8 @@ struct _Elm_Theme
Eina_List *themes;
Eina_List *extension;
Eina_Hash *cache;
Elm_Theme *ref_theme;
Eina_List *referrers;
const char *theme;
int ref;
};
@ -52,18 +54,18 @@ struct _Elm_Theme
/* note: always remember to sync it with elm_config.c */
extern const char *_elm_engines[];
#define ELM_SOFTWARE_X11 (_elm_engines[0])
#define ELM_SOFTWARE_FB (_elm_engines[1])
#define ELM_SOFTWARE_X11 (_elm_engines[0])
#define ELM_SOFTWARE_FB (_elm_engines[1])
#define ELM_SOFTWARE_DIRECTFB (_elm_engines[2])
#define ELM_SOFTWARE_16_X11 (_elm_engines[3])
#define ELM_SOFTWARE_8_X11 (_elm_engines[4])
#define ELM_XRENDER_X11 (_elm_engines[5])
#define ELM_OPENGL_X11 (_elm_engines[6])
#define ELM_SOFTWARE_WIN32 (_elm_engines[7])
#define ELM_SOFTWARE_16_X11 (_elm_engines[3])
#define ELM_SOFTWARE_8_X11 (_elm_engines[4])
#define ELM_XRENDER_X11 (_elm_engines[5])
#define ELM_OPENGL_X11 (_elm_engines[6])
#define ELM_SOFTWARE_WIN32 (_elm_engines[7])
#define ELM_SOFTWARE_16_WINCE (_elm_engines[8])
#define ELM_SOFTWARE_SDL (_elm_engines[9])
#define ELM_SOFTWARE_16_SDL (_elm_engines[10])
#define ELM_OPENGL_SDL (_elm_engines[11])
#define ELM_SOFTWARE_SDL (_elm_engines[9])
#define ELM_SOFTWARE_16_SDL (_elm_engines[10])
#define ELM_OPENGL_SDL (_elm_engines[11])
struct _Elm_Config
{
@ -116,7 +118,7 @@ struct _Elm_Module
};
void _elm_win_shutdown(void);
void _elm_win_rescale(void);
void _elm_win_rescale(Elm_Theme *th, Eina_Bool use_theme);
Eina_Bool _elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style);
Eina_Bool _elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style);

View File

@ -9,8 +9,7 @@
static Elm_Theme theme_default =
{
NULL, NULL, NULL, NULL,
NULL, 1
NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1
};
static Eina_List *themes = NULL;
@ -35,6 +34,13 @@ _elm_theme_clear(Elm_Theme *th)
eina_stringshare_del(th->theme);
th->theme = NULL;
}
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;
}
}
static const char *
@ -106,6 +112,7 @@ _elm_theme_group_file_find(Elm_Theme *th, const char *group)
file = _elm_theme_theme_element_try(th, home, f, group);
if (file) return file;
}
if (th->ref_theme) return _elm_theme_group_file_find(th->ref_theme, group);
return NULL;
}
@ -285,6 +292,109 @@ elm_theme_free(Elm_Theme *th)
}
}
/**
* Copy the theme fom the source to the destination theme
*
* @param th The source theme to copy from
* @param thdst The destination theme to copy data to
*
* This makes a one-time static copy of all the theme config, extensions
* and overlays from @p th to @p thdst. If @p th references a theme, then
* @p thdst is also set to reference it, with all the theme settings,
* overlays and extensions that @p th had.
*/
EAPI void
elm_theme_copy(Elm_Theme *th, Elm_Theme *thdst)
{
const Eina_List *l;
const char *f;
if (!th) th = &(theme_default);
if (!thdst) thdst = &(theme_default);
_elm_theme_clear(thdst);
if (th->ref_theme)
{
thdst->ref_theme = th->ref_theme;
thdst->ref_theme->referrers =
eina_list_append(thdst->ref_theme->referrers, thdst);
thdst->ref_theme->ref++;
}
EINA_LIST_FOREACH(th->overlay, l, f)
{
const char *s = eina_stringshare_add(f);
if (s) thdst->overlay = eina_list_append(thdst->overlay, s);
}
EINA_LIST_FOREACH(th->themes, l, f)
{
const char *s = eina_stringshare_add(f);
if (s) thdst->themes = eina_list_append(thdst->themes, s);
}
EINA_LIST_FOREACH(th->extension, l, f)
{
const char *s = eina_stringshare_add(f);
if (s) thdst->extension = eina_list_append(thdst->extension, s);
}
if (th->theme) thdst->theme = eina_stringshare_add(th->theme);
elm_theme_flush(thdst);
}
/**
* Tell the source theme to reference the ref theme
*
* @param th The theme that will do the referencing
* @param thref The theme that is the reference source
*
* This clears @p th to be empty and then sets it to refer to @p thref
* so @p th acts as an override to @p thdst, but where its overrides
* don't apply, it will fall through to @pthref for configuration.
*/
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)
{
thref->referrers = eina_list_append(thref->referrers, th);
thref->ref++;
}
th->ref_theme = thref;
elm_theme_flush(th);
}
/**
* Return the theme referred to
*
* @param th The theme to get the reference from
* @return The referenced theme handle
*
* This gets the theme set as the reference theme by elm_theme_ref_set().
* If no theme is set as a reference, NULL is returned.
*/
EAPI Elm_Theme *
elm_theme_ref_get(Elm_Theme *th)
{
if (!th) th = &(theme_default);
return th->ref_theme;
}
/**
* Return the default theme
*
* @return The default theme handle
*
* This returns the internal default theme setup handle that all widgets
* use implicitly unless a specific theme is set. This is also often use
* as a shorthand of NULL.
*/
EAPI Elm_Theme *
elm_theme_default_get(void)
{
return &theme_default;
}
/**
* Prepends a theme overlay to the list of overlays
*
@ -568,7 +678,14 @@ elm_theme_flush(Elm_Theme *th)
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));
_elm_win_rescale();
_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);
}
}
/**

View File

@ -464,6 +464,39 @@ elm_widget_theme(Evas_Object *obj)
if (sd->theme_func) sd->theme_func(obj);
}
EAPI void
elm_widget_theme_specific(Evas_Object *obj, Elm_Theme *th, Eina_Bool force)
{
const Eina_List *l;
Evas_Object *child;
Elm_Tooltip *tt;
Elm_Cursor *cur;
Elm_Theme *th2;
API_ENTRY return;
if (!force)
{
th2 = sd->theme;
while (th2)
{
if (th2 == th)
{
force = EINA_TRUE;
break;
}
th2 = th->ref_theme;
}
}
if (!force) return;
EINA_LIST_FOREACH(sd->subobjs, l, child)
elm_widget_theme_specific(child, th, force);
if (sd->resize_obj) elm_widget_theme(sd->resize_obj);
if (sd->hover_obj) elm_widget_theme(sd->hover_obj);
EINA_LIST_FOREACH(sd->tooltips, l, tt) elm_tooltip_theme(tt);
EINA_LIST_FOREACH(sd->cursors, l, cur) elm_cursor_theme(cur);
if (sd->theme_func) sd->theme_func(obj);
}
/**
* Set hook to get next object in object focus chain.
*

View File

@ -219,6 +219,7 @@ EAPI void elm_widget_signal_emit_hook_set(Evas_Object *obj, void (*f
EAPI void elm_widget_signal_callback_add_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data));
EAPI void elm_widget_signal_callback_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data));
EAPI void elm_widget_theme(Evas_Object *obj);
EAPI void elm_widget_theme_specific(Evas_Object *obj, Elm_Theme *th, Eina_Bool force);
EAPI void elm_widget_focus_next_hook_set(Evas_Object *obj, Eina_Bool (*func) (const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next));
EAPI void elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);
EAPI void elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data);

View File

@ -481,13 +481,21 @@ _elm_win_shutdown(void)
}
void
_elm_win_rescale(void)
_elm_win_rescale(Elm_Theme *th, Eina_Bool use_theme)
{
const Eina_List *l;
Evas_Object *obj;
EINA_LIST_FOREACH(_elm_win_list, l, obj)
elm_widget_theme(obj);
if (!use_theme)
{
EINA_LIST_FOREACH(_elm_win_list, l, obj)
elm_widget_theme(obj);
}
else
{
EINA_LIST_FOREACH(_elm_win_list, l, obj)
elm_widget_theme_specific(obj, th, EINA_FALSE);
}
}
#ifdef HAVE_ELEMENTARY_X