diff --git a/THEMES.md b/THEMES.md
index 4bcd23048..72d99e5f7 100644
--- a/THEMES.md
+++ b/THEMES.md
@@ -182,43 +182,111 @@ You probably should not use the "common" view for element positioning. You also
Reference
=========
-## Views, their elements, and accepted properties:
+## Views, their elements, and themable properties:
#### basic
- * image name="background" - PATH | TILING
- * image name="header" - POSITION | SIZE | PATH
- * textlist name="gamelist" - ALL
+* `image name="background"` - ALL
+ - This is a background image that exists for convenience. It goes from (0, 0) to (1, 1).
+* `text name="headerText"` - ALL
+ - A header text, which displays the name of the system. Displayed at the top center of the screen. Centered by default.
+* `image name="header"` - ALL
+ - A header image. If a non-empty `path` is specified, `text name="headerText"` will be hidden and this image will be, by default, displayed roughly in its place.
+* `textlist name="gamelist"` - ALL
+ - The gamelist. `primaryColor` is for games, `secondaryColor` is for folders. Centered by default.
+
+---
#### detailed
- * image name="background" - PATH | TILING
- * image name="header" - POSITION | SIZE | PATH
- * textlist name="gamelist" - ALL
- * image name="gameimage" - POSITION | SIZE
- * text name="description" - POSITION | SIZE | FONT_PATH | FONT_SIZE | COLOR
+* `image name="background"` - ALL
+ - This is a background image that exists for convenience. It goes from (0, 0) to (1, 1).
+* `text name="headerText"` - ALL
+ - A header text, which displays the name of the system. Displayed at the top center of the screen. Centered by default.
+* `image name="header"` - ALL
+ - A header image. If a non-empty `path` is specified, `text name="headerText"` will be hidden and this image will be, by default, displayed roughly in its place.
+* `textlist name="gamelist"` - ALL
+ - The gamelist. `primaryColor` is for games, `secondaryColor` is for folders. Left aligned by default.
+
+* Metadata
+ * Labels
+ * `text name="md_lbl_rating"` - ALL
+ * `text name="md_lbl_releasedate"` - ALL
+ * `text name="md_lbl_developer"` - ALL
+ * `text name="md_lbl_publisher"` - ALL
+ * `text name="md_lbl_genre"` - ALL
+ * `text name="md_lbl_players"` - ALL
+ * `text name="md_lbl_lastplayed"` - ALL
+ * `text name="md_lbl_playcount"` - ALL
+
+ * Values
+ * All values will follow to the right of their labels if a position isn't specified.
+
+ * `image name="md_image"` - POSITION | SIZE
+ - Path is the `image` metadata for the currently selected game.
+ * `rating name="md_rating"` - ALL
+ - The `rating` metadata.
+ * `datetime name="md_releasedate"` - ALL
+ - The `releasedate` metadata.
+ * `text name="md_developer"` - ALL
+ - The `developer` metadata.
+ * `text name="md_publisher"` - ALL
+ - The `publisher` metadata.
+ * `text name="md_genre"` - ALL
+ - The `genre` metadata.
+ * `text name="md_players"` - ALL
+ - The `players` metadata (number of players the game supports).
+ * `datetime name="md_lastplayed"` - ALL
+ - The `lastplayed` metadata. Displayed as a string representing the time relative to "now" (e.g. "3 hours ago").
+ * `text name="md_playcount"` - ALL
+ - The `playcount` metadata (number of times the game has been played).
+ * `text name="md_description"` - POSITION | SIZE | FONT_PATH | FONT_SIZE | COLOR
+ - Text is the `desc` metadata. If no `pos`/`size` is specified, will move and resize to fit under the lowest label and reach to the bottom of the screen.
+
+---
#### grid
- * image name="background" - PATH | TILING
- * image name="header" - POSITION | SIZE | PATH
+* `image name="background"` - ALL
+ - This is a background image that exists for convenience. It goes from (0, 0) to (1, 1).
+* `text name="headerText"` - ALL
+ - A header text, which displays the name of the system. Displayed at the top center of the screen. Centered by default.
+* `image name="header"` - ALL
+ - A header image. If a non-empty `path` is specified, `text name="headerText"` will be hidden and this image will be, by default, displayed roughly in its place.
+
+---
#### system
- * image name="header" - ALL
- * image name="system" - ALL
+* `text name="headerText"` - ALL
+ - A header text, which displays the name of the system. Displayed at the top center of the screen. Centered by default.
+* `image name="header"` - ALL
+ - A header image. If a non-empty `path` is specified, `text name="headerText"` will be hidden and this image will be, by default, displayed roughly in its place.
+* image name="system" - ALL
+ - A large image representing the system (usually a picture of the system itself).
-#### menu
- * ninepatch name="background" - PATH
- * textlist name="menulist" - FONT_PATH | COLOR | SOUND
- * sound name="menuOpen" - PATH
- * sound name="menuClose" - PATH
+---
#### fastSelect
- * ninepatch name="background" - PATH
- * text name="letter" - FONT_PATH | COLOR
- * text name="subtext" - FONT_PATH | COLOR
+* `ninepatch name="windowBackground"` - PATH
+ - Fit around the fast select UI as a background.
+* `text name="letter"` - FONT_PATH | COLOR
+ - The big letter that shows what letter you'll jump to when you let go of the fast select button.
+* `text name="subtext"` - FONT_PATH | COLOR
+ - The text that displays the current sort mode.
+
+---
+
+#### menu
+* `ninepatch name="windowBackground"` - PATH
+ - Background for the menu. Fit from top-left corner at (0.175, 0.05) to bottom-right corner at (0.825, 0.95).
+* `textlist name="menulist"` - FONT_PATH | COLOR | SOUND
+ - The list of menu options. `primaryColor` is for most options, `secondaryColor` is for the "shutdown" option.
+* `sound name="menuOpen"` - PATH
+ - Played when the menu opens.
+* `sound name="menuClose"` - PATH
+ - Played when the menu closes.
## Types of properties:
-* NORMALIZED_PAIR - two decimals, in the range [0..1]. For example, `0.25 0.5`.
+* NORMALIZED_PAIR - two decimals, in the range [0..1], delimited by a space. For example, `0.25 0.5`. Most commonly used for position (x and y coordinates) and size (width and height).
* PATH - a path. If the first character is a `~`, it will be expanded into the environment variable for the home path (`$HOME` or `%HOMEPATH%`, depending on platform). If the first character is a `.`, it will be expanded to the theme file's directory.
* BOOLEAN - `true`/`1` or `false`/`0`.
* COLOR - a hexidecimal RGB or RGBA color (6 or 8 digits). If 6 digits, will assume the alpha channel is `FF` (not transparent).
@@ -228,47 +296,76 @@ Reference
## Types of elements and their properties:
+Common to almost all elements is a `pos` and `size` property of the NORMALIZED_PAIR type. They are normalized in terms of their "parent" object's size; 99% of the time, this is just the size of the screen. In this case, `0 0` would correspond to the top left corner, and `1 1` the bottom right corner (a positive Y value points further down). `pos` almost always refers to the top left corner of your element. You *can* use numbers outside of the [0..1] range if you want to place an element partially or completely off-screen.
+
+The order you define properties in does not matter.
+
+Remember, you do *not* need to specify every property!
+
#### image
- * `pos` - type: NORMALIZED_PAIR.
- * `size` - type: NORMALIZED_PAIR.
- * `maxSize` - type: NORMALIZED_PAIR.
- * `origin` - type: NORMALIZED_PAIR.
- * `path` - type: PATH.
- * `tile` - type: BOOLEAN.
+
+Can be created as an extra.
+
+* `pos` - type: NORMALIZED_PAIR.
+* `size` - type: NORMALIZED_PAIR.
+* `maxSize` - type: NORMALIZED_PAIR.
+ - The image will be resized as large as possible so that it fits within this size and maintains its aspect ratio. Use this instead of `size` when you don't know what kind of image you're using so it doesn't get grossly oversized on one axis (e.g. with a game's image metadata).
+* `origin` - type: NORMALIZED_PAIR.
+ - Where on the image `pos` refers to. For example, an origin of `0.5 0.5` and a `pos` of `0.5 0.5` would place the image exactly in the middle of the screen.
+* `path` - type: PATH.
+ - Path to the image file. Most common extensions are supported (including .jpg, .png, and unanimated .gif).
+* `tile` - type: BOOLEAN.
+ - If true, the image will be tiled instead of stretched to fit its size. Useful for backgrounds.
#### text
- * `pos` - type: NORMALIZED_PAIR.
- * `size` - type: NORMALIZED_PAIR.
- * `text` - type: STRING.
- * `color` - type: COLOR.
- * `fontPath` - type: PATH.
- * `fontSize` - type: FLOAT.
- * `center` - type: BOOLEAN.
+
+Can be created as an extra.
+
+* `pos` - type: NORMALIZED_PAIR.
+* `size` - type: NORMALIZED_PAIR.
+* `text` - type: STRING.
+* `color` - type: COLOR.
+* `fontPath` - type: PATH.
+ - Path to a truetype font (.ttf).
+* `fontSize` - type: FLOAT.
+ - Size of the font as a percentage of screen height (e.g. for a value of `0.1`, the text's height would be 10% of the screen height).
+* `center` - type: BOOLEAN.
+ - If true, center the text on the x-axis.
#### textlist
- * `pos` - type: NORMALIZED_PAIR.
- * `size` - type: NORMALIZED_PAIR.
- * `selectorColor` - type: COLOR.
- * `selectedColor` - type: COLOR.
- * `primaryColor` - type: COLOR.
- * `secondaryColor` - type: COLOR.
- * `fontPath` - type: PATH.
- * `fontSize` - type: FLOAT.
- * `scrollSound` - type: PATH.
- * `center` - type: BOOLEAN.
+
+* `pos` - type: NORMALIZED_PAIR.
+* `size` - type: NORMALIZED_PAIR.
+* `selectorColor` - type: COLOR.
+ - Color of the "selector bar."
+* `selectedColor` - type: COLOR.
+ - Color of the highlighted entry text.
+* `primaryColor` - type: COLOR.
+ - Primary color; what this means depends on the text list. For example, for game lists, it is the color of a game.
+* `secondaryColor` - type: COLOR.
+ - Secondary color; what this means depends on the text list. For example, for game lists, it is the color of a folder.
+* `fontPath` - type: PATH.
+* `fontSize` - type: FLOAT.
+* `scrollSound` - type: PATH.
+ - Sound that is played when the list is scrolled.
+* `center` - type: BOOLEAN.
+ - True to center, false to left-align.
#### ninepatch
- * `pos` - type: NORMALIZED_PAIR.
- * `size` - type: NORMALIZED_PAIR.
- * `path` - type: PATH.
-A quick word on the "ninepatch" type - EmulationStation borrows the concept of "nine patches" from Android (or "9-Slices"). Currently the implementation is very simple and hard-coded to only use 48x48px images (16x16px for each "patch"). Check the `data/resources` directory for some examples (button.png, frame.png).
+* `pos` - type: NORMALIZED_PAIR.
+* `size` - type: NORMALIZED_PAIR.
+* `path` - type: PATH.
+
+EmulationStation borrows the concept of "nine patches" from Android (or "9-Slices"). Currently the implementation is very simple and hard-coded to only use 48x48px images (16x16px for each "patch"). Check the `data/resources` directory for some examples (button.png, frame.png).
#### sound
- * `path` - type: PATH.
+
+* `path` - type: PATH.
+ - Path to the sound file. Only .wav files are currently supported.
-*Note that a view may choose to only make only certain properties on a particular element themable.*
+*Note that a view may choose to only make only certain properties on a particular element themable!*
diff --git a/src/components/GuiFastSelect.cpp b/src/components/GuiFastSelect.cpp
index d200f7477..cecf73cfc 100644
--- a/src/components/GuiFastSelect.cpp
+++ b/src/components/GuiFastSelect.cpp
@@ -14,7 +14,7 @@ GuiFastSelect::GuiFastSelect(Window* window, IGameListView* gamelist) : GuiCompo
const std::shared_ptr& theme = mGameList->getTheme();
using namespace ThemeFlags;
- mBackground.applyTheme(theme, "fastSelect", "background", PATH);
+ mBackground.applyTheme(theme, "fastSelect", "windowBackground", PATH);
mBackground.fitTo(mSize);
addChild(&mBackground);
diff --git a/src/components/GuiMenu.cpp b/src/components/GuiMenu.cpp
index 696162ced..5c6f2e437 100644
--- a/src/components/GuiMenu.cpp
+++ b/src/components/GuiMenu.cpp
@@ -38,15 +38,15 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mBackground(window, ":/
mTheme = ThemeData::getDefault();
using namespace ThemeFlags;
- mBackground.applyTheme(mTheme, "menu", "background", PATH);
+ mBackground.applyTheme(mTheme, "menu", "windowBackground", PATH);
mBackground.fitTo(Eigen::Vector2f(mList.getSize().x(), mSize.y()), Eigen::Vector3f(mList.getPosition().x(), 0, 0));
addChild(&mBackground);
mList.setFont(Font::get((int)(0.09f * Renderer::getScreenHeight())));
- mList.applyTheme(mTheme, "menu", "menulist", FONT_PATH | COLOR | SOUND);
mList.setSelectorColor(0xBBBBBBFF);
mList.setColor(0, 0x0000FFFF);
mList.setColor(1, 0xFF0000FF);
+ mList.applyTheme(mTheme, "menu", "menulist", FONT_PATH | COLOR | SOUND);
Sound::getFromTheme(mTheme, "menu", "menuOpen")->play();
diff --git a/src/views/gamelist/DetailedGameListView.cpp b/src/views/gamelist/DetailedGameListView.cpp
index 8b2da5a68..256a6dd0d 100644
--- a/src/views/gamelist/DetailedGameListView.cpp
+++ b/src/views/gamelist/DetailedGameListView.cpp
@@ -75,7 +75,7 @@ void DetailedGameListView::onThemeChanged(const std::shared_ptr& them
BasicGameListView::onThemeChanged(theme);
using namespace ThemeFlags;
- mImage.applyTheme(theme, getName(), "gameimage", POSITION | ThemeFlags::SIZE);
+ mImage.applyTheme(theme, getName(), "md_image", POSITION | ThemeFlags::SIZE);
initMDLabels();
std::vector labels = getMDLabels();
@@ -104,9 +104,9 @@ void DetailedGameListView::onThemeChanged(const std::shared_ptr& them
values[i]->applyTheme(theme, getName(), valElements[i], ALL ^ ThemeFlags::TEXT);
}
- mDescContainer.applyTheme(theme, getName(), "description", POSITION | ThemeFlags::SIZE);
+ mDescContainer.applyTheme(theme, getName(), "md_description", POSITION | ThemeFlags::SIZE);
mDescription.setSize(mDescContainer.getSize().x(), 0);
- mDescription.applyTheme(theme, getName(), "description", FONT_PATH | FONT_SIZE | COLOR);
+ mDescription.applyTheme(theme, getName(), "md_description", FONT_PATH | FONT_SIZE | COLOR);
}
void DetailedGameListView::initMDLabels()
diff --git a/src/views/gamelist/ISimpleGameListView.cpp b/src/views/gamelist/ISimpleGameListView.cpp
index e9c8707ee..c0febefe6 100644
--- a/src/views/gamelist/ISimpleGameListView.cpp
+++ b/src/views/gamelist/ISimpleGameListView.cpp
@@ -26,8 +26,9 @@ ISimpleGameListView::ISimpleGameListView(Window* window, FileData* root) : IGame
void ISimpleGameListView::onThemeChanged(const std::shared_ptr& theme)
{
using namespace ThemeFlags;
- mBackground.applyTheme(theme, getName(), "background", PATH);
- mHeaderImage.applyTheme(theme, getName(), "header", POSITION | ThemeFlags::SIZE | PATH);
+ mBackground.applyTheme(theme, getName(), "background", ALL);
+ mHeaderImage.applyTheme(theme, getName(), "header", ALL);
+ mHeaderText.applyTheme(theme, getName(), "headerText", ALL);
mThemeExtras.setExtras(ThemeData::makeExtras(theme, getName(), mWindow));
if(mHeaderImage.hasImage())