diff --git a/CHANGELOG.md b/CHANGELOG.md index cb48ca715..12d9f5ea4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,14 @@ ### Detailed list of changes -* Added support for Lottie animations (vector graphics), fully configurable as a theme extra +* Made fundamental changes to the application logic by removing most view styles and replacing them with a new theme variants concept +* Added theme support for defining and applying different layouts for various display aspect ratios such as 16:9 and 4:3 +* Made gamelist theming much more flexible by allowing any number of elements of any types to be defined +* Deprecated multiple older theming concepts like features, extras and hardcoded metadata attributes +* Added support for defining what type of image metadata to use for all image elements (and also for the video component static image) +* Added a legacy (backward compatibility) mode for still supporting older RetroPie EmulationStation themes +* Added theme support for Lottie animations (vector graphics) +* Made it possible to set any text element as a scrollable container using either metadata values or literal strings * Added scraper support for displaying the returned platform if it does not match the game platform, or if multiple platforms are defined for the system * Added scraping of fan art and updated the media viewer to display these images * Added scraping of box back covers when using TheGamesDB @@ -20,12 +27,15 @@ * Reduced CPU usage significantly when a menu is open by not rendering the bottom of the stack * Added an OpenGL ES 2.0 renderer (borrowed from the RetroPie fork of EmulationStation) * Added logging of the display refresh rate on startup +* Improved the theme loading error logging to make it consistent and easier to understand +* Added a log warning for unthemed systems during theme set loading * Added a color model conversion shader for converting from BGRA to RGBA * Added renderer support for supplying a separate format than internalFormat when creating textures (although not really supported by the OpenGL standard) * Added the rlottie library as a Git subtree * On Windows all dependencies were moved in-tree to the "external" directory to greatly simplify the build environment * Large refactoring to improve thread safety and improve singleton pattern usage * Moved all Platform functions to the utility namespace instead of using the global namespace +* Implemented proper XML attribute support in ThemeData that eliminated the risk of name collisions * Changed all occurances of "GameList" to "Gamelist" throughout the codebase * Removed a huge amount of unnecessary Window* function parameters throughout the codebase * Refactored the six gamelist classes into two new classes; GamelistBase and GamelistView @@ -38,6 +48,7 @@ * Removed some unnecessary typedefs and replaced the remaining ones with the more modern "using" keyword * Removed the deprecated VideoVlcComponent * Lots of general code cleanup and refactoring +* Updated and improved the theming documentation ### Bug fixes diff --git a/THEMES-DEV.md b/THEMES-DEV.md index 87fbb3a6e..776aa42fb 100644 --- a/THEMES-DEV.md +++ b/THEMES-DEV.md @@ -10,11 +10,11 @@ Table of contents: ## Introduction -ES-DE allows the grouping of themes for multiple game systems into a **theme set**. Each theme is a collection of **views** that define some **elements**, each with their own **properties**. +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 game-specific theme.xml file available. +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. @@ -56,22 +56,50 @@ An example installation path would be: \ 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 +* Correct theme structure is enforced more strictly than before, and deviations will generate error log messages and make the theme loading fail + +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 description text: +Here is a very simple theme that changes the color of the game name text: ```xml - 7 - - + + 00FF00 - + 0.5 0.5 0.5 0.5 0.8 0.8 ./core/frame.png + 10 @@ -79,12 +107,11 @@ Here is a very simple theme that changes the color of the game description text: ## How it works -All configuration must be contained within a `` tag pair. +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 **must** be specified. This is the version of the theming system the theme was designed for. -The current version is 7. +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. -A _view_ can be thought of as a particular "screen" within ES-DE. Views are defined like this: +Views are defined like this: ```xml @@ -92,36 +119,294 @@ A _view_ can be thought of as a particular "screen" within ES-DE. Views are defi ``` -An *element* is a particular visual element, such as an image or a piece of text. You can modify an element that already exists for a particular view, as was done for the "description" example: +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). + +This is the element structure: ```xml - + ... define properties here ... - + ``` -Or you can create your own elements by adding `extra="true"`, as was done for the "frame" example: - -```xml - - ... define properties here ... - -``` - -"Extra" elements will be drawn in the order they are defined (so make sure to define backgrounds first). In what order they get drawn relative to the pre-existing elements depends on the view. Make sure "extra" element names do not clash with existing element names. An easy way to protect against this is to start all your extra element names with a prefix such as "e_". - - - -*Properties* control how a particular *element* looks - for example its position, size, image path etc. The type of the property determines what kinds of values you can use. You can read about the types below in the "Reference" section. Properties are defined like this: +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 + + + +``` -## Advanced features +`colors.xml`: +```xml + + + + 707070 + + + +``` -If you are writing a theme it's recommended to launch ES-DE with the `--debug` flag from a terminal window. If on Unix you can also pass the `--windowed` and `--resolution` flags to avoid having the application window fill the entire screen. On macOS and Windows you only need to pass the `--resolution` flag to accomplish this. By doing so, you can read error messages directly in the terminal window without having to open the log file. You can also reload the current gamelist view and system view with `Ctrl-R` if the `--debug` flag has been set. +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 creation + +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 most 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 alignment property set to _leftr_ instead of _left_: +``` +Jan 28 17:25:27 Warn: BadgeComponent: Invalid theme configuration, set to "leftr" +``` + +### 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 + + + + + + + + + + md_image + 40 + + + + + + + + + + + + + + + + + md_image + 40 + + + + +``` + +### 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 `