mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-26 16:15:39 +00:00
Added the gameImageNotFound tag. See THEMES.md for details.
This commit is contained in:
parent
aa6506aec1
commit
77e14423b9
15
THEMES.md
15
THEMES.md
|
@ -3,7 +3,7 @@ Themes
|
||||||
|
|
||||||
EmulationStation allows each system to have its own "theme." A theme is a collection of display settings and images defined in an XML document.
|
EmulationStation allows each system to have its own "theme." A theme is a collection of display settings and images defined in an XML document.
|
||||||
|
|
||||||
ES will check two places for a theme: first, the system's search directory for theme.xml. Then, if that's not found, $HOME/.emulationstation/es_theme.xml.
|
ES will check two places for a theme: first, the system's search directory for theme.xml. Then, if that's not found, $HOME/.emulationstation/es_theme.xml will be used.
|
||||||
|
|
||||||
Almost all positions, dimensions, origins, etc. work in percentages - that is, they are a decimal between 0 and 1, representing the percentage of the screen on that axis to use. This ensures that themes look similar at every resolution.
|
Almost all positions, dimensions, origins, etc. work in percentages - that is, they are a decimal between 0 and 1, representing the percentage of the screen on that axis to use. This ensures that themes look similar at every resolution.
|
||||||
|
|
||||||
|
@ -56,6 +56,9 @@ Display tags
|
||||||
============
|
============
|
||||||
Display tags define some "meta" display attributes about your theme. Display tags must be at the root of the `<theme>` tree - for example, they can't be inside a component tag. They are not required.
|
Display tags define some "meta" display attributes about your theme. Display tags must be at the root of the `<theme>` tree - for example, they can't be inside a component tag. They are not required.
|
||||||
|
|
||||||
|
|
||||||
|
**Game list attributes:**
|
||||||
|
|
||||||
`<listPrimaryColor>` - the hex font color to use for games on the GuiGameList.
|
`<listPrimaryColor>` - the hex font color to use for games on the GuiGameList.
|
||||||
|
|
||||||
`<listSecondaryColor>` - the hex font color to use for folders on the GuiGameList.
|
`<listSecondaryColor>` - the hex font color to use for folders on the GuiGameList.
|
||||||
|
@ -78,15 +81,21 @@ Display tags define some "meta" display attributes about your theme. Display tag
|
||||||
|
|
||||||
~~`<gameImageOffsetY>` - the percentage to offset the displayed game image by. Default is the height of the header font.~~
|
~~`<gameImageOffsetY>` - the percentage to offset the displayed game image by. Default is the height of the header font.~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
**Game image attributes:**
|
||||||
|
|
||||||
`<gameImagePos>` - two values for the position of the game art, in the form of `[x] [y]`, as a percentage. Default is `$infoWidth/2 $headerHeight`.
|
`<gameImagePos>` - two values for the position of the game art, in the form of `[x] [y]`, as a percentage. Default is `$infoWidth/2 $headerHeight`.
|
||||||
|
|
||||||
`<gameImageDim>` - two values for the dimensions of the game art, in the form of `[width] [height]`, as a percentage of the screen. Default is `$infoWidth/2 0` (width fits within the info column). The image will only be resized if at least one axis is nonzero *and* exceeded by the image's size. You should always leave at least one axis as zero to preserve the aspect ratio.
|
`<gameImageDim>` - two values for the dimensions of the game art, in the form of `[width] [height]`, as a percentage of the screen. Default is `$infoWidth/2 0` (width fits within the info column). The image will only be resized if at least one axis is nonzero *and* exceeded by the image's size. You should always leave at least one axis as zero to preserve the aspect ratio.
|
||||||
|
|
||||||
`<gameImageOrigin>` two values for the origin of the game art, in the form of `[x] [y]`, as a percentage. Default is `0.5 0` (top-center of the image).
|
`<gameImageOrigin>` - two values for the origin of the game art, in the form of `[x] [y]`, as a percentage. Default is `0.5 0` (top-center of the image).
|
||||||
|
|
||||||
|
`<gameImageNotFound>` - path to the image to display if a game's image is missing. '.' and '~' are expanded.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**The Fast Select box can be themed with these tags:**
|
**Fast Select box attributes:**
|
||||||
|
|
||||||
`<fastSelectColor>` - the hex color to use for the letter display on the Fast Select box.
|
`<fastSelectColor>` - the hex color to use for the letter display on the Fast Select box.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
October 25
|
||||||
|
-Added gameImageNotFound tag for an image to display if a game image is not found/defined.
|
||||||
|
|
||||||
October 17
|
October 17
|
||||||
-Added GuiAnimation class which animates its children.
|
-Added GuiAnimation class which animates its children.
|
||||||
-The game image on the game list now slides/fades in and out.
|
-The game image on the game list now slides/fades in and out.
|
||||||
|
|
|
@ -168,6 +168,10 @@ void parseGamelist(SystemData* system)
|
||||||
newImage.erase(0, 1);
|
newImage.erase(0, 1);
|
||||||
newImage.insert(0, system->getRootFolder()->getPath());
|
newImage.insert(0, system->getRootFolder()->getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if the image doesn't exist, forget it
|
||||||
|
if(!boost::filesystem::exists(newImage))
|
||||||
|
newImage = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
game->set(newName, newDesc, newImage);
|
game->set(newName, newDesc, newImage);
|
||||||
|
|
|
@ -23,7 +23,7 @@ GuiGameList::GuiGameList(bool useDetail)
|
||||||
{
|
{
|
||||||
mList = new GuiList<FileData*>(Renderer::getScreenWidth() * sInfoWidth, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2);
|
mList = new GuiList<FileData*>(Renderer::getScreenWidth() * sInfoWidth, Renderer::getDefaultFont(Renderer::LARGE)->getHeight() + 2);
|
||||||
|
|
||||||
mScreenshot = new GuiImage(Renderer::getScreenWidth() * sInfoWidth * 0.5, Renderer::getScreenHeight() * mTheme->getGameImageOffsetY(), "", Renderer::getScreenWidth() * sInfoWidth * 0.7, 0, false);
|
mScreenshot = new GuiImage(Renderer::getScreenWidth() * mTheme->getGameImageOffsetX(), Renderer::getScreenHeight() * mTheme->getGameImageOffsetY(), "", Renderer::getScreenWidth() * sInfoWidth * 0.7, 0, false);
|
||||||
mScreenshot->setOrigin(mTheme->getGameImageOriginX(), mTheme->getGameImageOriginY());
|
mScreenshot->setOrigin(mTheme->getGameImageOriginX(), mTheme->getGameImageOriginY());
|
||||||
//addChild(mScreenshot);
|
//addChild(mScreenshot);
|
||||||
|
|
||||||
|
@ -248,7 +248,12 @@ void GuiGameList::updateDetailData()
|
||||||
if(mList->getSelectedObject() && !mList->getSelectedObject()->isFolder())
|
if(mList->getSelectedObject() && !mList->getSelectedObject()->isFolder())
|
||||||
{
|
{
|
||||||
mScreenshot->setOffset((mTheme->getGameImageOffsetX() - 0.05) * Renderer::getScreenWidth(), mTheme->getGameImageOffsetY() * Renderer::getScreenHeight());
|
mScreenshot->setOffset((mTheme->getGameImageOffsetX() - 0.05) * Renderer::getScreenWidth(), mTheme->getGameImageOffsetY() * Renderer::getScreenHeight());
|
||||||
|
|
||||||
|
if(((GameData*)mList->getSelectedObject())->getImagePath().empty())
|
||||||
|
mScreenshot->setImage(mTheme->getImageNotFoundPath());
|
||||||
|
else
|
||||||
mScreenshot->setImage(((GameData*)mList->getSelectedObject())->getImagePath());
|
mScreenshot->setImage(((GameData*)mList->getSelectedObject())->getImagePath());
|
||||||
|
|
||||||
mImageAnimation->fadeIn(15);
|
mImageAnimation->fadeIn(15);
|
||||||
mImageAnimation->move((int)(0.05 * Renderer::getScreenWidth()), 0, 5);
|
mImageAnimation->move((int)(0.05 * Renderer::getScreenWidth()), 0, 5);
|
||||||
}else{
|
}else{
|
||||||
|
|
|
@ -34,6 +34,8 @@ float GuiTheme::getGameImageHeight() { return mGameImageHeight; }
|
||||||
float GuiTheme::getGameImageOriginX() { return mGameImageOriginX; }
|
float GuiTheme::getGameImageOriginX() { return mGameImageOriginX; }
|
||||||
float GuiTheme::getGameImageOriginY() { return mGameImageOriginY; }
|
float GuiTheme::getGameImageOriginY() { return mGameImageOriginY; }
|
||||||
|
|
||||||
|
std::string GuiTheme::getImageNotFoundPath() { return mImageNotFoundPath; }
|
||||||
|
|
||||||
GuiTheme::GuiTheme(std::string path)
|
GuiTheme::GuiTheme(std::string path)
|
||||||
{
|
{
|
||||||
setDefaults();
|
setDefaults();
|
||||||
|
@ -81,6 +83,8 @@ void GuiTheme::setDefaults()
|
||||||
mMenuSelectSound.loadFile("");
|
mMenuSelectSound.loadFile("");
|
||||||
mMenuBackSound.loadFile("");
|
mMenuBackSound.loadFile("");
|
||||||
mMenuOpenSound.loadFile("");
|
mMenuOpenSound.loadFile("");
|
||||||
|
|
||||||
|
mImageNotFoundPath = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiTheme::deleteComponents()
|
void GuiTheme::deleteComponents()
|
||||||
|
@ -148,7 +152,6 @@ void GuiTheme::readXML(std::string path)
|
||||||
mListOffsetX = strToFloat(root.child("listOffsetX").text().get(), mListOffsetX);
|
mListOffsetX = strToFloat(root.child("listOffsetX").text().get(), mListOffsetX);
|
||||||
mListTextOffsetX = strToFloat(root.child("listTextOffsetX").text().get(), mListTextOffsetX);
|
mListTextOffsetX = strToFloat(root.child("listTextOffsetX").text().get(), mListTextOffsetX);
|
||||||
|
|
||||||
|
|
||||||
//game image stuff
|
//game image stuff
|
||||||
std::string artPos = root.child("gameImagePos").text().get();
|
std::string artPos = root.child("gameImagePos").text().get();
|
||||||
std::string artDim = root.child("gameImageDim").text().get();
|
std::string artDim = root.child("gameImageDim").text().get();
|
||||||
|
@ -166,12 +169,17 @@ void GuiTheme::readXML(std::string path)
|
||||||
mGameImageOriginX = resolveExp(artOriginX, mGameImageOriginX);
|
mGameImageOriginX = resolveExp(artOriginX, mGameImageOriginX);
|
||||||
mGameImageOriginY = resolveExp(artOriginY, mGameImageOriginY);
|
mGameImageOriginY = resolveExp(artOriginY, mGameImageOriginY);
|
||||||
|
|
||||||
|
mImageNotFoundPath = expandPath(root.child("gameImageNotFound").text().get());
|
||||||
|
|
||||||
//sounds
|
//sounds
|
||||||
mMenuScrollSound.loadFile(expandPath(root.child("menuScrollSound").text().get()));
|
mMenuScrollSound.loadFile(expandPath(root.child("menuScrollSound").text().get()));
|
||||||
mMenuSelectSound.loadFile(expandPath(root.child("menuSelectSound").text().get()));
|
mMenuSelectSound.loadFile(expandPath(root.child("menuSelectSound").text().get()));
|
||||||
mMenuBackSound.loadFile(expandPath(root.child("menuBackSound").text().get()));
|
mMenuBackSound.loadFile(expandPath(root.child("menuBackSound").text().get()));
|
||||||
mMenuOpenSound.loadFile(expandPath(root.child("menuOpenSound").text().get()));
|
mMenuOpenSound.loadFile(expandPath(root.child("menuOpenSound").text().get()));
|
||||||
|
|
||||||
|
//fonts
|
||||||
|
//mListFont = resolveFont(root.child("listFont"), NULL);
|
||||||
|
|
||||||
//actually read the components
|
//actually read the components
|
||||||
createComponentChildren(root, this);
|
createComponentChildren(root, this);
|
||||||
}
|
}
|
||||||
|
@ -322,3 +330,14 @@ float GuiTheme::strToFloat(std::string str, float defaultVal)
|
||||||
ss >> ret;
|
ss >> ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Font* GuiTheme::resolveFont(pugi::xml_node node, Font* def)
|
||||||
|
{
|
||||||
|
if(!node)
|
||||||
|
return def;
|
||||||
|
|
||||||
|
std::string path = expandPath(node.child("path").text().get());
|
||||||
|
int size = (int)(strToFloat(node.child("size").value()) * Renderer::getScreenHeight());
|
||||||
|
|
||||||
|
return new Font(path, size);
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "../pugiXML/pugixml.hpp"
|
#include "../pugiXML/pugixml.hpp"
|
||||||
#include "GuiBox.h"
|
#include "GuiBox.h"
|
||||||
#include "../Sound.h"
|
#include "../Sound.h"
|
||||||
|
#include "../Font.h"
|
||||||
|
|
||||||
//This class loads an XML-defined list of GuiComponents.
|
//This class loads an XML-defined list of GuiComponents.
|
||||||
class GuiTheme : public GuiComponent
|
class GuiTheme : public GuiComponent
|
||||||
|
@ -41,6 +42,8 @@ public:
|
||||||
Sound* getMenuSelectSound();
|
Sound* getMenuSelectSound();
|
||||||
Sound* getMenuBackSound();
|
Sound* getMenuBackSound();
|
||||||
Sound* getMenuOpenSound();
|
Sound* getMenuOpenSound();
|
||||||
|
|
||||||
|
std::string getImageNotFoundPath();
|
||||||
private:
|
private:
|
||||||
void setDefaults();
|
void setDefaults();
|
||||||
void deleteComponents();
|
void deleteComponents();
|
||||||
|
@ -53,17 +56,17 @@ private:
|
||||||
unsigned int resolveColor(std::string str, unsigned int defaultColor = 0x000000FF);
|
unsigned int resolveColor(std::string str, unsigned int defaultColor = 0x000000FF);
|
||||||
void splitString(std::string str, char delim, std::string* before, std::string* after);
|
void splitString(std::string str, char delim, std::string* before, std::string* after);
|
||||||
float strToFloat(std::string str, float defaultVal = 0.0f);
|
float strToFloat(std::string str, float defaultVal = 0.0f);
|
||||||
|
Font* resolveFont(pugi::xml_node node, Font* def);
|
||||||
|
|
||||||
std::vector<GuiComponent*> mComponentVector;
|
std::vector<GuiComponent*> mComponentVector;
|
||||||
std::string mPath;
|
std::string mPath;
|
||||||
|
|
||||||
unsigned int mListPrimaryColor, mListSecondaryColor, mListSelectorColor, mListSelectedColor, mDescColor, mFastSelectColor;
|
unsigned int mListPrimaryColor, mListSecondaryColor, mListSelectorColor, mListSelectedColor, mDescColor, mFastSelectColor;
|
||||||
bool mHideHeader, mHideDividers, mListCentered;
|
bool mHideHeader, mHideDividers, mListCentered;
|
||||||
|
|
||||||
float mListOffsetX, mListTextOffsetX, mGameImageOffsetX, mGameImageOffsetY, mGameImageWidth, mGameImageHeight, mGameImageOriginX, mGameImageOriginY;
|
float mListOffsetX, mListTextOffsetX, mGameImageOffsetX, mGameImageOffsetY, mGameImageWidth, mGameImageHeight, mGameImageOriginX, mGameImageOriginY;
|
||||||
|
|
||||||
GuiBoxData mBoxData;
|
GuiBoxData mBoxData;
|
||||||
|
|
||||||
Sound mMenuScrollSound, mMenuSelectSound, mMenuBackSound, mMenuOpenSound;
|
Sound mMenuScrollSound, mMenuSelectSound, mMenuBackSound, mMenuOpenSound;
|
||||||
|
std::string mImageNotFoundPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue