summaryrefslogtreecommitdiff
path: root/src/lib/elm_theme.h
blob: fbe662420f56308d1dc74b8b78bba7b5caa81d38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
/**
 * @defgroup Theme Theme
 * @ingroup Elementary
 *
 * Elementary uses Edje to theme its widgets, naturally. But for the most
 * part this is hidden behind a simpler interface that lets the user set
 * extensions and choose the style of widgets in a much easier way.
 *
 * Instead of thinking in terms of paths to Edje files and their groups
 * each time you want to change the appearance of a widget, Elementary
 * works so you can add any theme file with extensions or replace the
 * main theme at one point in the application, and then just set the style
 * of widgets with elm_object_style_set() and related functions. Elementary
 * will then look in its list of themes for a matching group and apply it,
 * and when the theme changes midway through the application, all widgets
 * will be updated accordingly.
 *
 * There are three concepts you need to know to understand how Elementary
 * theming works: default theme, extensions and overlays.
 *
 * Default theme, obviously enough, is the one that provides the default
 * look of all widgets. End users can change the theme used by Elementary
 * by setting the @c ELM_THEME environment variable before running an
 * application, or globally for all programs using the @c elementary_config
 * utility. Applications can change the default theme using elm_theme_set(),
 * but this can go against the user wishes, so it's not an advised practice.
 *
 * Ideally, applications should find everything they need in the already
 * provided theme, but there may be occasions when that's not enough and
 * custom styles are required to correctly express the idea. For this
 * cases, Elementary has extensions.
 *
 * Extensions allow the application developer to write styles of its own
 * to apply to some widgets. This requires knowledge of how each widget
 * is themed, as extensions will always replace the entire group used by
 * the widget, so important signals and parts need to be there for the
 * object to behave properly (see documentation of Edje for details).
 * Once the theme for the extension is done, the application needs to add
 * it to the list of themes Elementary will look into, using
 * elm_theme_extension_add(), and set the style of the desired widgets as
 * he would normally with elm_object_style_set().
 *
 * Overlays, on the other hand, can replace the look of all widgets by
 * overriding the default style. Like extensions, it's up to the application
 * developer to write the theme for the widgets it wants, the difference
 * being that when looking for the theme, Elementary will check first the
 * list of overlays, then the set theme and lastly the list of extensions,
 * so with overlays it's possible to replace the default view and every
 * widget will be affected. This is very much alike to setting the whole
 * theme for the application and will probably clash with the end user
 * options, not to mention the risk of ending up with not matching styles
 * across the program. Unless there's a very special reason to use them,
 * overlays should be avoided for the reasons exposed before.
 *
 * All these theme lists are handled by ::Elm_Theme instances. Elementary
 * keeps one default internally and every function that receives one of
 * these can be called with NULL to refer to this default (except for
 * elm_theme_free()). It's possible to create a new instance of a
 * ::Elm_Theme to set other theme for a specific widget (and all of its
 * children), but this is as discouraged, if not even more so, than using
 * overlays. Don't use this unless you really know what you are doing.
 *
 * But to be less negative about things, you can look at the following
 * examples:
 * @li @ref theme_example_01 "Using extensions"
 * @li @ref theme_example_02 "Using overlays"
 *
 * @{
 */
/**
 * @typedef Elm_Theme
 *
 * Opaque handler for the list of themes Elementary looks for when
 * rendering widgets.
 *
 * Stay out of this unless you really know what you are doing. For most
 * cases, sticking to the default is all a developer needs.
 */
typedef struct _Elm_Theme Elm_Theme;

/**
 * Create a new specific theme
 *
 * This creates an empty specific theme that only uses the default theme. A
 * specific theme has its own private set of extensions and overlays too
 * (which are empty by default). Specific themes do not fall back to themes
 * of parent objects. They are not intended for this use. Use styles, overlays
 * and extensions when needed, but avoid specific themes unless there is no
 * other way (example: you want to have a preview of a new theme you are
 * selecting in a "theme selector" window. The preview is inside a scroller
 * and should display what the theme you selected will look like, but not
 * actually apply it yet. The child of the scroller will have a specific
 * theme set to show this preview before the user decides to apply it to all
 * applications).
 *
 * @ingroup Theme
 */
EAPI Elm_Theme       *elm_theme_new(void);

/**
 * Free a specific theme
 *
 * @param th The theme to free
 *
 * This frees a theme created with elm_theme_new().
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_free(Elm_Theme *th);

/**
 * Copy the theme from 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.
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_copy(Elm_Theme *th, Elm_Theme *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 thref, but where its overrides
 * don't apply, it will fall through to @p thref for configuration.
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_ref_set(Elm_Theme *th, Elm_Theme *thref);

/**
 * 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.
 *
 * @ingroup Theme
 */
EAPI Elm_Theme       *elm_theme_ref_get(Elm_Theme *th);

/**
 * 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.
 *
 * @ingroup Theme
 */
EAPI Elm_Theme       *elm_theme_default_get(void);

/**
 * Prepends a theme overlay to the list of overlays
 *
 * @param th The theme to add to, or if NULL, the default theme
 * @param item The Edje file path to be used
 *
 * Use this if your application needs to provide some custom overlay theme
 * (An Edje file that replaces some default styles of widgets) where adding
 * new styles, or changing system theme configuration is not possible. Do
 * NOT use this instead of a proper system theme configuration. Use proper
 * configuration files, profiles, environment variables etc. to set a theme
 * so that the theme can be altered by simple configuration by a user. Using
 * this call to achieve that effect is abusing the API and will create lots
 * of trouble.
 *
 * @see elm_theme_extension_add()
 * @see elm_theme_overlay_mmap_add()
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_overlay_add(Elm_Theme *th, const char *item);

/**
 * Delete a theme overlay from the list of overlays
 *
 * @param th The theme to delete from, or if NULL, the default theme
 * @param item The name of the theme overlay
 *
 * @see elm_theme_overlay_add()
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_overlay_del(Elm_Theme *th, const char *item);

/**
 * Prepends a theme overlay to the list of overlays
 *
 * @param th The theme to add to, or if NULL, the default theme
 * @param f The Edje file handle to be used
 *
 * Use this if your application needs to provide some custom overlay theme
 * (An Edje file that replaces some default styles of widgets) where adding
 * new styles, or changing system theme configuration is not possible. Do
 * NOT use this instead of a proper system theme configuration. Use proper
 * configuration files, profiles, environment variables etc. to set a theme
 * so that the theme can be altered by simple configuration by a user. Using
 * this call to achieve that effect is abusing the API and will create lots
 * of trouble.
 *
 * @see elm_theme_extension_add()
 * @see elm_theme_overlay_add()
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_overlay_mmap_add(Elm_Theme *th, const Eina_File *f);

/**
 * Delete a theme overlay from the list of overlays
 *
 * @param th The theme to delete from, or if NULL, the default theme
 * @param f The file handle of the theme overlay
 *
 * @see elm_theme_overlay_mmap_add()
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_overlay_mmap_del(Elm_Theme *th, const Eina_File *f);

/**
 * Get the list of registered overlays for the given theme
 *
 * @param th The theme from which to get the overlays
 * @return List of theme overlays. Do not free it.
 *
 * @see elm_theme_overlay_add()
 *
 * @ingroup Theme
 */
EAPI const Eina_List *elm_theme_overlay_list_get(const Elm_Theme *th);

/**
 * Appends a theme extension to the list of extensions.
 *
 * @param th The theme to add to, or if NULL, the default theme
 * @param item The Edje file path to be used
 *
 * This is intended when an application needs more styles of widgets or new
 * widget themes that the default does not provide (or may not provide). The
 * application has "extended" usage by coming up with new custom style names
 * for widgets for specific uses, but as these are not "standard", they are
 * not guaranteed to be provided by a default theme. This means the
 * application is required to provide these extra elements itself in specific
 * Edje files. This call adds one of those Edje files to the theme search
 * path to be search after the default theme. The use of this call is
 * encouraged when default styles do not meet the needs of the application.
 * Use this call instead of elm_theme_overlay_add() for almost all cases.
 *
 * @see elm_object_style_set()
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_extension_add(Elm_Theme *th, const char *item);

/**
 * Deletes a theme extension from the list of extensions.
 *
 * @param th The theme to delete from, or if NULL, the default theme
 * @param item The name of the theme extension
 *
 * @see elm_theme_extension_add()
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_extension_del(Elm_Theme *th, const char *item);

/**
 * Appends a theme extension to the list of extensions.
 *
 * @param th The theme to add to, or if NULL, the default theme
 * @param f The Edje file handle to be used
 *
 * This is intended when an application needs more styles of widgets or new
 * widget themes that the default does not provide (or may not provide). The
 * application has "extended" usage by coming up with new custom style names
 * for widgets for specific uses, but as these are not "standard", they are
 * not guaranteed to be provided by a default theme. This means the
 * application is required to provide these extra elements itself in specific
 * Edje files. This call adds one of those Edje files to the theme search
 * path to be search after the default theme. The use of this call is
 * encouraged when default styles do not meet the needs of the application.
 * Use this call instead of elm_theme_overlay_add() for almost all cases.
 *
 * @see elm_object_style_set()
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_extension_mmap_add(Elm_Theme *th, const Eina_File *f);

/**
 * Deletes a theme extension from the list of extensions.
 *
 * @param th The theme to delete from, or if NULL, the default theme
 * @param f The file handle of the theme extension
 *
 * @see elm_theme_extension_add()
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_extension_mmap_del(Elm_Theme *th, const Eina_File *f);

/**
 * Get the list of registered extensions for the given theme
 *
 * @param th The theme from which to get the extensions
 * @return List of theme extensions. Do not free it.
 *
 * @see elm_theme_extension_add()
 *
 * @ingroup Theme
 */
EAPI const Eina_List *elm_theme_extension_list_get(const Elm_Theme *th);

/**
 * Set the theme search order for the given theme
 *
 * @param th The theme to set the search order, or if NULL, the default theme
 * @param theme Theme search string
 *
 * This sets the search string for the theme in path-notation from first
 * theme to search, to last, delimited by the : character. Example:
 *
 * "shiny:/path/to/file.edj:default"
 *
 * See the ELM_THEME environment variable for more information.
 *
 * @see elm_theme_get()
 * @see elm_theme_list_get()
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_set(Elm_Theme *th, const char *theme);

/**
 * Return the theme search order
 *
 * @param th The theme to get the search order, or if NULL, the default theme
 * @return The internal search order path
 *
 * This function returns a colon separated string of theme elements as
 * returned by elm_theme_list_get().
 *
 * @see elm_theme_set()
 * @see elm_theme_list_get()
 *
 * @ingroup Theme
 */
EAPI const char      *elm_theme_get(Elm_Theme *th);

/**
 * 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.
 *
 * A theme element can consist of a full or relative path to a .edj file,
 * or a name, without extension, for a theme to be searched in the known
 * theme paths for Elementary.
 *
 * @see elm_theme_set()
 * @see elm_theme_get()
 *
 * @ingroup Theme
 */
EAPI const Eina_List *elm_theme_list_get(const Elm_Theme *th);

/**
 * Return the full path 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 search-able 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
 * @c EINA_TRUE if the file was a search-able file and is in the search path,
 * and @c EINA_FALSE otherwise.
 *
 * @ingroup Theme
 */
EAPI char            *elm_theme_list_item_path_get(const char *f, Eina_Bool *in_search_path);

/**
 * Flush the current theme.
 *
 * @param th Theme to flush
 *
 * This flushes caches that let elementary know where to find theme elements
 * in the given theme. If @p th is NULL, then the default theme is flushed.
 * Call this function if source theme data has changed in such a way as to
 * make any caches Elementary kept invalid.
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_flush(Elm_Theme *th);

/**
 * This flushes all themes (default and specific ones).
 *
 * This will flush all themes in the current application context, by calling
 * elm_theme_flush() on each of them.
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_full_flush(void);

/**
 * 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.
 *
 * @ingroup Theme
 */
EAPI Eina_List       *elm_theme_name_available_list_new(void);

/**
 * 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.
 *
 * @ingroup Theme
 */
EAPI void             elm_theme_name_available_list_free(Eina_List *list);

/**
 * Set a specific theme to be used for this object and its children
 *
 * @param obj The object to set the theme on
 * @param th The theme to set
 *
 * This sets a specific theme that will be used for the given object and any
 * child objects it has. If @p th is NULL then the theme to be used is
 * cleared and the object will inherit its theme from its parent (which
 * ultimately will use the default theme if no specific themes are set).
 *
 * Use special themes with great care as this will annoy users and make
 * configuration difficult. Avoid any custom themes at all if it can be
 * helped.
 *
 * @ingroup Theme
 */
EAPI void             elm_object_theme_set(Evas_Object *obj, Elm_Theme *th);

/**
 * Get the specific theme to be used
 *
 * @param obj The object to get the specific theme from
 * @return The specific theme set.
 *
 * This will return a specific theme set, or NULL if no specific theme is
 * set on that object. It will not return inherited themes from parents, only
 * the specific theme set for that specific object. See elm_object_theme_set()
 * for more information.
 *
 * @ingroup Theme
 */
EAPI Elm_Theme       *elm_object_theme_get(const Evas_Object *obj);

/**
 * Get a data item from a theme
 *
 * @param th The theme, or NULL for default theme
 * @param key The data key to search with
 * @return The data value, or NULL on failure
 *
 * This function is used to return data items from edc in @p th, an overlay, or an extension.
 * It works the same way as edje_file_data_get() except that the return is stringshared.
 *
 * @ingroup Theme
 */
EAPI const char      *elm_theme_data_get(Elm_Theme *th, const char *key);

/**
 * Get the file path for an edje file for the group and theme given
 *
 * @param th The theme, or NULL for default theme
 * @param group The group in the edje file to look for
 * @return The full path to the file as a string
 *
 * This function looks up the given edje @p group in the set of theme edje
 * files configured for the theme @p th (which if NULL indicates the default
 * theme). If not found in any, NULL wil be returned. If found, the string
 * returned is internal and should not be freed, but will only be valid
 * until the theme is re-configured, or cache flushed, so if the string needs
 * to be kept, duplicate it and store that. The string will be a stringshare
 * string that is returned by functions like eina_stringshare_add() so it can
 * be just references via stringshare functions if desired.
 *
 * If group is NULL, then nothing can be looked up, so it is a non-sensical
 * request.
 *
 * @since 1.8
 * @ingroup Theme
 */
EAPI const char *elm_theme_group_path_find(Elm_Theme *th, const char *group);

/**
 * Get a list of groups that match the initial base string given within all themes
 *
 * @param th The theme, or NULL for default theme
 * @param base The base string group collection to look for
 * @return A list of collection names (sorted) or NULL if none found
 *
 * This function will walk all theme files configured in the theme @p th (or
 * NULL if its the default) and find all groups that BEGIN with the string
 * @p begin and have that string as at LEAST their start, and then add the
 * fulll group name that matches to the list and return that full group
 * group string.
 *
 * The list returned must be freed by the caller, with each string being a
 * stringshared string to be freed with eina_stringshare_del(). Not doing so
 * may result in a leak.
 *
 * @since 1.8
 * @ingroup Theme
 */
 EAPI Eina_List *elm_theme_group_base_list(Elm_Theme *th, const char *base);

/**
 * Get the file path where elementary system theme files are found
 *
 * @return A string that holds the path where system themes are
 *
 * This returns the location in the filesystem where the system themes are
 * to be found that elementary looks for. This is useful for something
 * that wishes toiterate over the files in this folder and display them, for
 * example a theme selector.
 *
 * @since 1.8
 * @ingroup Theme
 */
EAPI const char *elm_theme_system_dir_get(void);

/**
 * Get the file path where elementary user theme files are found
 *
 * @return A string that holds the path where user themes are
 *
 * This returns the location in the filesystem where the user themes are
 * to be found that elementary looks for. This is useful for something
 * that wishes toiterate over the files in this folder and display them, for
 * example a theme selector.
 *
 * User themes are always looked for before system themes. The user theme
 * directory is normally expected to be writable by the user.
 *
 * @since 1.8
 * @ingroup Theme
 */
EAPI const char *elm_theme_user_dir_get(void);

/**
 * @}
 */