1 #include <Elementary.h>
5 * @defgroup Theme Theme
8 * Functions to modify the theme in the currently running app.
11 static Elm_Theme theme_default =
13 NULL, NULL, NULL, NULL,
17 static Eina_List *themes = NULL;
20 _elm_theme_clear(Elm_Theme *th)
23 EINA_LIST_FREE(th->themes, p)
24 eina_stringshare_del(p);
25 EINA_LIST_FREE(th->overlay, p)
26 eina_stringshare_del(p);
27 EINA_LIST_FREE(th->extension, p)
28 eina_stringshare_del(p);
31 eina_hash_free(th->cache);
36 eina_stringshare_del(th->theme);
42 _elm_theme_find_try(Elm_Theme *th, const char *f, const char *group)
46 if (edje_file_group_exists(f, group))
48 file = eina_stringshare_add(f);
51 eina_hash_add(th->cache, group, file);
59 _elm_theme_theme_element_try(Elm_Theme *th, const char *home, const char *f, const char *group)
62 const char *file = NULL;
64 if ((f[0] == '/') || ((f[0] == '.') && (f[1] == '/')) ||
65 ((f[0] == '.') && (f[1] == '.') && (f[2] == '/')) ||
66 (isalpha(f[0]) && f[1] == ':'))
67 return _elm_theme_find_try(th, f, group);
68 else if (((f[0] == '~') && (f[1] == '/')))
70 snprintf(buf, sizeof(buf), "%s/%s", home, f + 2);
71 return _elm_theme_find_try(th, buf, group);
73 snprintf(buf, sizeof(buf), "%s/.elementary/themes/%s.edj", home, f);
74 file = _elm_theme_find_try(th, buf, group);
75 if (file) return file;
76 snprintf(buf, sizeof(buf), "%s/themes/%s.edj", _elm_data_dir, f);
77 file = _elm_theme_find_try(th, buf, group);
82 _elm_theme_group_file_find(Elm_Theme *th, const char *group)
86 static const char *home = NULL;
87 const char *file = eina_hash_find(th->cache, group);
89 if (file) return file;
92 home = getenv("HOME");
95 EINA_LIST_FOREACH(th->overlay, l, f)
97 file = _elm_theme_theme_element_try(th, home, f, group);
98 if (file) return file;
100 EINA_LIST_FOREACH(th->themes, l, f)
102 file = _elm_theme_theme_element_try(th, home, f, group);
103 if (file) return file;
105 EINA_LIST_FOREACH(th->extension, l, f)
107 file = _elm_theme_theme_element_try(th, home, f, group);
108 if (file) return file;
114 _elm_theme_object_set(Evas_Object *parent, Evas_Object *o, const char *clas, const char *group, const char *style)
116 Elm_Theme *th = NULL;
117 if (parent) th = elm_widget_theme_get(parent);
118 return _elm_theme_set(th, o, clas, group, style);
122 _elm_theme_object_icon_set(Evas_Object *parent, Evas_Object *o, const char *group, const char *style)
124 Elm_Theme *th = NULL;
125 if (parent) th = elm_widget_theme_get(parent);
126 return _elm_theme_icon_set(th, o, group, style);
130 _elm_theme_set(Elm_Theme *th, Evas_Object *o, const char *clas, const char *group, const char *style)
136 if (!th) th = &(theme_default);
137 snprintf(buf2, sizeof(buf2), "elm/%s/%s/%s", clas, group, style);
138 file = _elm_theme_group_file_find(th, buf2);
141 ok = edje_object_file_set(o, file, buf2);
144 snprintf(buf2, sizeof(buf2), "elm/%s/%s/default", clas, group);
145 file = _elm_theme_group_file_find(th, buf2);
147 ok = edje_object_file_set(o, file, buf2);
152 _elm_theme_icon_set(Elm_Theme *th, Evas_Object *o, const char *group, const char *style)
158 if (!th) th = &(theme_default);
159 snprintf(buf2, sizeof(buf2), "elm/icon/%s/%s", group, style);
160 file = _elm_theme_group_file_find(th, buf2);
163 _els_smart_icon_file_edje_set(o, file, buf2);
164 _els_smart_icon_size_get(o, &w, &h);
167 snprintf(buf2, sizeof(buf2), "elm/icon/%s/default", group);
168 file = _elm_theme_group_file_find(th, buf2);
170 _els_smart_icon_file_edje_set(o, file, buf2);
171 _els_smart_icon_size_get(o, &w, &h);
176 _elm_theme_parse(Elm_Theme *th, const char *theme)
178 Eina_List *names = NULL;
181 if (!th) th = &(theme_default);
188 if ((*pe == ':') || (*pe == 0))
189 { // p -> pe == 'name:'
192 char *n = malloc(pe - p + 1);
197 strncpy(n, p, pe - p);
199 nn = eina_stringshare_add(n);
200 if (nn) names = eina_list_append(names, nn);
212 p = eina_list_data_get(eina_list_last(names));
213 if ((!p) || ((p) && (strcmp(p, "default"))))
215 p = eina_stringshare_add("default");
216 if (p) names = eina_list_append(names, p);
218 if (th->cache) eina_hash_free(th->cache);
219 th->cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
221 EINA_LIST_FREE(th->themes, p) eina_stringshare_del(p);
228 _elm_theme_shutdown(void)
230 _elm_theme_clear(&(theme_default));
234 * Create a new specific theme
236 * This creates an empty specific theme that only uses the default theme. A
237 * specific theme has its own private set of extensions and overlays too
238 * (which are empty by default). Specific themes do not fall back to themes
239 * of parent objects. They are not intended for this use. Use styles, overlays
240 * and extensions when needed, but avoid specific themes unless there is no
241 * other way (example: you want to have a preview of a new theme you are
242 * selecting in a "theme selector" window. The preview is inside a scroller
243 * and should display what the theme you selected will look like, but not
244 * actually apply it yet. The child of the scroller will have a specific
245 * theme set to show this preview before the user decides to apply it to all
253 Elm_Theme *th = calloc(1, sizeof(Elm_Theme));
254 if (!th) return NULL;
256 th->themes = eina_list_append(th->themes, eina_stringshare_add("default"));
257 themes = eina_list_append(themes, th);
262 * Free a specific theme
264 * @param th The theme to free
266 * This frees a theme created with elm_theme_new().
271 elm_theme_free(Elm_Theme *th)
276 _elm_theme_clear(th);
277 themes = eina_list_remove(themes, th);
283 * Prepends a theme overlay to the list of overlays
285 * @param th The theme to add to, or if NULL, the default theme
286 * @param item The Edje file path to be used
288 * Use this if your application needs to provide some custom overlay theme
289 * (An Edje file that replaces some default styles of widgets) where adding
290 * new styles, or changing system theme configuration is not possible. Do
291 * NOT use this instead of a proper system theme configuration. Use proper
292 * configuration files, profiles, environment variables etc. to set a theme
293 * so that the theme can be altered by simple confiugration by a user. Using
294 * this call to achieve that effect is abusing the API and will create lots
300 elm_theme_overlay_add(Elm_Theme *th, const char *item)
302 const char *f = eina_stringshare_add(item);
304 if (!th) th = &(theme_default);
305 if (f) th->overlay = eina_list_prepend(th->overlay, f);
310 * Delete a theme overlay from the list of overlays
312 * @param th The theme to delete from, or if NULL, the default theme
313 * @param item The name of the theme overlay
315 * See elm_theme_overlay_add().
320 elm_theme_overlay_del(Elm_Theme *th, const char *item)
325 if (!th) th = &(theme_default);
326 s = eina_stringshare_add(item);
327 EINA_LIST_FOREACH(th->overlay, l, f)
330 eina_stringshare_del(f);
331 th->overlay = eina_list_remove_list(th->overlay, (Eina_List *)l);
334 eina_stringshare_del(s);
339 * Prepends a theme extension to the list of extensions.
341 * @param th The theme to add to, or if NULL, the default theme
342 * @param item The Edje file path to be used
344 * This is intended when an application needs more styles of widgets or new
345 * widget themes that the default does not provide (or may not provide). The
346 * application has "extended" usage by coming up with new custom style names
347 * for widgets for specific uses, but as these are not "standard", they are
348 * not guaranteed to be provided by a default theme. This means the
349 * application is required to provide these extra elements itself in specific
350 * Edje files. This call adds one of those Edje files to the theme search
351 * path to be search after the default theme. The use of this call is
352 * encouraged when default styles do not meet the needs of the application.
353 * Use this call instead of elm_theme_overlay_add() for almost all cases.
358 elm_theme_extension_add(Elm_Theme *th, const char *item)
360 const char *f = eina_stringshare_add(item);
362 if (!th) th = &(theme_default);
363 if (f) th->extension = eina_list_append(th->extension, f);
368 * Deletes a theme extension from the list of extensions.
370 * @param th The theme to delete from, or if NULL, the default theme
371 * @param item The name of the theme extension
373 * See elm_theme_extension_add().
378 elm_theme_extension_del(Elm_Theme *th, const char *item)
383 if (!th) th = &(theme_default);
384 s = eina_stringshare_add(item);
385 EINA_LIST_FOREACH(th->extension, l, f)
388 eina_stringshare_del(f);
389 th->extension = eina_list_remove_list(th->extension, (Eina_List *)l);
392 eina_stringshare_del(s);
397 * Set the theme search order for the given theme
399 * @param th The theme to set the search order, or if NULL, the default theme
400 * @param theme Theme search string
402 * This sets the search string for the theme in path-notation from first
403 * theme to search, to last, delimited by the : character. Example:
405 * "shiny:/path/to/file.edj:default"
407 * See the ELM_THEME environment variable for more information.
412 elm_theme_set(Elm_Theme *th, const char *theme)
414 if (!th) th = &(theme_default);
415 _elm_theme_parse(th, theme);
418 eina_stringshare_del(th->theme);
425 * Return the theme search order
427 * @param th The theme to get the search order, or if NULL, the default theme
428 * @return The internal search order path
430 * See elm_theme_set() for more information.
435 elm_theme_get(Elm_Theme *th)
445 EINA_LIST_FOREACH(th->themes, l, f)
448 if (l->next) len += 1;
450 tmp = alloca(len + 1);
452 EINA_LIST_FOREACH(th->themes, l, f)
455 if (l->next) strcat(tmp, ":");
457 th->theme = eina_stringshare_add(tmp);
463 * Flush the current theme.
465 * @param th Theme to flush
467 * This flushes caches that let elementary know where to find theme elements
468 * in the given theme. If @p th is NULL, then the default theme is flushed.
469 * Call this call if source theme data has changed in such a way as to
470 * make any caches Elementary kept invalid.
475 elm_theme_flush(Elm_Theme *th)
477 if (!th) th = &(theme_default);
478 if (th->cache) eina_hash_free(th->cache);
479 th->cache = eina_hash_string_superfast_new(EINA_FREE_CB(eina_stringshare_del));
484 * This flushes all themems (default and specific ones).
486 * This will flush all themes in the current application context, by calling
487 * elm_theme_flush() on each of them.
492 elm_theme_full_flush(void)
497 EINA_LIST_FOREACH(themes, l, th)
501 elm_theme_flush(&(theme_default));
505 * Set the theme for all elementary using applications on the current display
507 * @param theme The name of the theme to use. Format same as the ELM_THEME
508 * environment variable.
513 elm_theme_all_set(const char *theme)
515 #ifdef HAVE_ELEMENTARY_X
516 static Ecore_X_Atom atom = 0;
518 if (!atom) atom = ecore_x_atom_get("ENLIGHTENMENT_THEME");
519 ecore_x_window_prop_string_set(ecore_x_window_root_first_get(),
522 elm_theme_set(NULL, theme);
526 * Set a specific theme to be used for this object and its children
528 * @param obj The object to set the theme on
529 * @param th The theme to set
531 * This sets a specific theme that will be used for the given object and any
532 * child objects it has. If @p th is NULL then the theme to be used is
533 * cleared and the object will inherit its theme from its parent (which
534 * ultimately will use the default theme if no specific themes are set).
536 * Use special themes with great care as this will annoy users and make
537 * configuration difficult. Avoid any custom themes at all if it can be
543 elm_object_theme_set(Evas_Object *obj, Elm_Theme *th)
545 elm_widget_theme_set(obj, th);
549 * Get the specific theme to be used
551 * @param obj The object to get the specific theme from
552 * @return The specifc theme set.
554 * This will return a specific theme set, or NULL if no specific theme is
555 * set on that object. It will not return inherited themes from parents, only
556 * the specific theme set for that specific object. See elm_object_theme_set()
557 * for more information.
562 elm_object_theme_get(Evas_Object *obj)
564 return elm_widget_theme_get(obj);