Added the gameImageNotFound tag. See THEMES.md for details.

This commit is contained in:
Aloshi 2012-10-25 12:36:30 -05:00
parent aa6506aec1
commit 77e14423b9
6 changed files with 52 additions and 9 deletions

View file

@ -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.

View file

@ -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.

View file

@ -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);

View file

@ -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());
mScreenshot->setImage(((GameData*)mList->getSelectedObject())->getImagePath());
if(((GameData*)mList->getSelectedObject())->getImagePath().empty())
mScreenshot->setImage(mTheme->getImageNotFoundPath());
else
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{

View file

@ -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);
}

View file

@ -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