# EmulationStation Desktop Edition (ES-DE) v1.3 (development version) - Themes **Note:** This document is only relevant for the current ES-DE development version, if you would like to see the documentation for the latest stable release, refer to [THEMES.md](THEMES.md) instead. Table of contents: [[_TOC_]] ## Introduction ES-DE allows the grouping of themes for multiple game systems into a **theme set**. A theme is a collection of **elements**, each with their own **properties** that define the way they look and behave. These elements include things like text lists, carousels, images and animations. Every game system has its own subdirectory within the theme set directory structure, and these are defined in the systems configuration file `es_systems.xml` either via the optional `` tag, or otherwise via the mandatory `` tag. When ES-DE populates a system on startup it will look for a file named `theme.xml` in each such directory. By placing a theme.xml file directly in the root of the theme set directory, that file will be processed as a default if there is no system-specific theme.xml file available. In the example below, we have a theme set named `mythemeset-DE` which includes the `snes` and `nes` systems. Assuming you have some games installed for these systems, the files `mythemeset-DE/nes/theme.xml` and `mythemeset-DE/snes/theme.xml` will be processed on startup. If there are no games available for a system, its theme.xml file will be skipped. The directory structure of our example theme set could look something like the following: ``` ... themes/ mythemeset-DE/ core/ font.ttf bold_font.ttf frame.png nes/ theme.xml background.jpg logo.svg logo_video.svg snes/ theme.xml background.jpg logo.svg logo_video.svg fonts.xml theme.xml ``` The theme set approach makes it easy for users to install different themes and choose between them from the _UI Settings_ menu. There are two places that ES-DE can load theme sets from: * `[HOME]/.emulationstation/themes/[THEME_SET]/` * `[INSTALLATION PATH]/themes/[THEME_SET]/` An example installation path would be: \ `/usr/share/emulationstation/themes/rbsimple-DE/` If a theme set with the same name exists in both locations, the one in the home directory will be loaded and the other one will be skipped. ## Differences to legacy RetroPie themes If you are not familiar with theming for RetroPie or similar forks of EmulationStation you can skip this section as it only describes the key differences between the updated ES-DE themes and these _legacy_ theme sets. The term _legacy_ is used throughout this document to refer to this older style of themes which ES-DE still fully supports for backward compatibility reasons. The old theme format is described in [THEMES-LEGACY.md](THEMES-LEGACY.md) although this document is basically a historical artifact by now. With ES-DE v1.3 a new theme engine was introduced that fundamentally changed some aspects of how theming works. The previous design used specific view styles (basic, detailed, video and grid) and this was dropped completely and replaced with _variants_ that can accomplish the same thing while being much more powerful and flexible. In the past EmulationStation basically had hardcoded view styles with certain elements always being present and only a limited ability to manipulate these via positioning, resizing, coloring etc. As well so-called _extras_ were provided to expand theming support somehow but even this was quite limited. With the new theme engine the view presets were removed and the only views now available, _system_ and _gamelist_, were rewritten to be much more flexible. Essentially the element selection and placement is now unlimited; any number of elements of any type can be used, although with a few notable exceptions as explained throughout this document. In addition to the variant support which provides an unlimited flexibility for creating custom theme profiles, support for specific aspect ratios was introduced. This makes it possible to define different theme configuration for different display aspect ratios and to provide the user with the option to choose between these from the _UI Settings_ menu. That could for example be choice between a 16:9 and a 4:3 layout, or perhaps also a vertical screen orientation layout in addition to these. As well new theming abilities like Lottie animations were added with the new theme engine. The following are the most important changes compared to the legacy theme structure: * View styles are now limited to only _system_ and _gamelist_ (there is a special _all_ view style as well but that is only used for navigation sounds as explained later in this document) * The hardcoded metadata attributes like _md_image_ and _md_developer_ are gone, but a new `` property is available for populating views with metadata information * The concept of _extras_ is gone as all element can now be used however the theme author wishes * The concept of _features_ is gone * The `` tag is gone as tracking theme versions doesn't make much sense after all * The `video` element properties `showSnapshotNoVideo` and `showSnapshotDelay` have been removed * The ambiguous `alignment` property has been replaced with the `horizontalAlignment` and `verticalAlignment` properties (the same is true for `logoAlignment` for the `carousel` component) * The `forceUppercase` property has been replaced with the more versatile `letterCase` property * The carousel text element hacks `systemInfo` and `logoText` have been removed and replaced with proper carousel properties * Correct theme structure is enforced more strictly than before, and deviations will generate error log messages and make the theme loading fail * Many additional elements and properties have been added, refer to the [Reference](THEMES-DEV.md#reference) section for more information Attempting to use any of the legacy logic in the new theme structure will make the theme loading fail, for example adding the _extra="true"_ attribute to any element. Except the points mentioned above, theme configuration looks pretty similar to the legacy theme structure, so anyone having experience with these older themes should hopefully feel quite at home with the new theme engine. Probably the most important thing to keep in mind is that as there are no longer any view presets available, some more effort is needed from the theme developer to define values for some elements. This is especially true for zIndex values as elements could now be hidden by other elements if care is not taken to explicitly set the zIndex for each of them. This additional work is however a small price to pay for the much more powerful and flexible theming functionality provided by the new theme engine. ## Simple example Here is a very simple theme that changes the color of the game name text: ```xml 00FF00 0.5 0.5 0.5 0.5 0.8 0.8 ./core/frame.png 10 ``` ## How it works All configuration must be contained within a `` tag pair. That is true for each separate .xml file used to build the completely theme set. The `` tag pair refers to the available views within ES-DE, which is either _system_ or _gamelist_. There is a special _all_ view available as well, but that is only used for defining the navigation sounds as these are always applied globally to both view types. Views are defined like this: ```xml ... define elements here ... ``` An element is a particular visual component such as an image, an animation or a piece of text. It has a mandatory _name_ attribute which is used by ES-DE to track each element entry. By using this name attribute it's possible to split up the definition of an element to different locations. For example you may want to define the color properties separately from where the size and position are configured (see the example below). The name attribute can be set to any string value. This is the element structure: ```xml ... define properties here ... ``` Finally _properties_ control how a particular element looks and behaves, for example its position, size, image path, animation controls etc. The property type determines what kinds of values you can use. You can read about each type below in the [Reference](THEMES-DEV.md#reference) section. Properties are defined like this: ```xml ValueHere ``` Let's now put it all together. The following is a simple example of a text element which has its definition split across two separate XML files. `themes.xml`: ```xml 0.27 0.32 0.5 0.5 0.12 0.41 40 ``` `colors.xml`: ```xml 707070 ``` As long as the name attribute is identical, the element configuration will be combined automatically. But that is only true for elements of the same type, so for instance an image element could be defined that also uses _system_name_ for its name attribute without colliding with the text element: ```xml 0.27 0.32 0.5 0.5 0.12 0.41 40 0.49 0.8 0.4 0.28 35 ``` Whether this is a good idea is another question, it would probably be better to set the name attribute for the image to _system_logo_ or similar for this example. In addition to this, if the name is used for the same element type but for different views, then there will also not be any collision: ```xml 0.04 0.73 0.5 0.5 0.12 0.22 40 0.27 0.32 0.5 0.5 0.12 0.41 40 ``` ## Debugging during theme development If you are writing a theme it's recommended to launch ES-DE with the `--debug` flag from a terminal window. You can also pass the `--resolution` flag to avoid having the application window fill the entire screen. By doing so, you can read error messages directly in the terminal window without having to open the es_log.txt file. You can also reload the current gamelist or system view with `Ctrl+r` if the `--debug` flag has been set. There is also support for highlighting the size and position of each image and animation element by using the `Ctrl+i` key combination and likewise to highlight each text element by using the `Ctrl+t` keys. Again, both of these require that ES-DE has been launched with the `--debug` command line option, for example: ``` emulationstation --debug --resolution 1280 720 ``` Enforcement of a correct theme configuration is quite strict, and most errors will abort the theme loading, leading to an unthemed system. In each such situation the log output will be very clear of what happened, for instance: ``` Jan 28 17:17:30 Error: ThemeData::parseElement(): "/home/myusername/.emulationstation/themes/mythemeset-DE/theme.xml": Property "origin" for element "image" has no value defined ``` Sanitization for valid data format and structure is done in this manner, but verification that property values are actually correct (or reasonable) is handled by the individual component that takes care of creating and rendering the specific theme element. What happens in many instances is that a log warning entry is created and the invalid property is reset to its default value. So for these situations, the system will not become unthemed. Here's an example where a badges element accidentally had its horizontalAlignment property set to _leftr_ instead of _left_: ``` Jan 28 17:25:27 Warn: BadgeComponent: Invalid theme configuration, set to "leftr" ``` Note however that warnings are not printed for all invalid properties as that would lead to an excessive amount of logging code. This is especially true for numeric values which are commonly just clamped to the allowable range without notifying the theme author. So make sure to check the [Reference](THEMES-DEV.md#reference) section of this document for valid values for each property. ### Variants A core concept of ES-DE is the use of theme set _variants_ to provide different theme profiles. These are not fixed presets and a theme author can instead name and define whatever variants he wants for his theme (or possibly use no variants at all as they are optional). The variants could be purely cosmetic, such as providing light and dark mode versions of the theme set, or they could provide different functionality by for instance using different primary components such as a carousel or a text list. Before a variant can be used it needs to be declared, which is done in the `capabilities.xml` file that must be stored in the root of the theme set directory tree. How to setup this file is described in detailed later in this document. The use of variants is straightforward, a section of the configuration that should be included for a certain variant is enclosed inside the `` tag pair. This has to be placed inside the `` tag pair, and it can only be used on this level of the hierarchy and not inside a `` tag pair for example. The mandatory _name_ attribute is used to specificy which variants to use, and multiple variants can be specified at the same time by separating them by commas or by whitespace characters (tabs, spaces or line breaks). It could be a good idea to separate the various variant configuration into separate files that are then included from the main theme file as this could improve the structure and readability of the theme set configuration. Here are some example uses of the `` functionality: ```xml ./../colors_light.xml ./../colors_dark.xml ./core/font.ttf 0.035 0.3 0.56 titlescreen true 42 titlescreen true 42 ``` ### Aspect ratios The aspect ratio support works almost identically to the variants support with the main difference that the available aspect ratios are hardcoded into ES-DE. The theme set can still decide which of the aspect ratios to support (or none at all in which cast the theme aspect ratios is left undefined) but it can't create entirely new aspect ratios. The reason for why aspect ratios were implemented at all instead of only using variants was that the amount of defined variants would have grown exponentially for all possible combinations, making the theme sets very hard to create and maintain. In the same manner as for the variants, the aspect ratios that the theme set provides need to be declared in the `capabilities.xml` file that must be stored in the root of the theme set directory tree. How to setup this file is described in detailed later in this document. Once the aspect ratios have been defined, they are applied to the theme configuration in exactly the same way as the variants: ```xml ./../layout_narrow.xml ./../layout_wide.xml ./../layout_ultrawide.xml ./core/font.ttf 0.035 0.3 0.56 0.42 0.31 0.3 0.56 ``` ### capabilities.xml Variant and aspect ratio values need to be declared before they can be used inside the actual theme set configuration files and that is done in the `capabilities.xml` file. This file needs to exist in the root of the theme directory, for example: ``` ~/.emulationstation/themes/mythemeset-DE/capabilities.xml ``` This file type was introduced with the new ES-DE theme engine in v1.3 and is an indicator that the theme set is of the new generation instead of being of the legacy type (i.e. a theme set backward compatible with RetroPie EmulationStation). In other words, if the capabilities.xml file is absent, the theme will get loaded as a legacy set. The structure of the file is simple, it just contains the declarations for the variants and aspect ratios, such as in this example: ```xml 16:9 4:3 4:3_vertical true true ``` The file format is hopefully mostly self-explanatory; this example provides three aspect ratios and two variants. The `