Themes can now be used without the detailed GuiGameList.

If a theme.xml is not found in a system's directory, ES will now check for $HOME/.emulationstation/es_theme.xml. If present, it will load that.
Fixed GuiGameList image data not updating on system change/initial startup. (finally!)
This commit is contained in:
Aloshi 2012-08-12 09:43:09 -05:00
parent bd6c64aefb
commit c7349cd99a
9 changed files with 72 additions and 38 deletions

View file

@ -34,7 +34,7 @@ gamelist.xml
============
If a file named gamelist.xml is found in the root of a system's search directory, it will be parsed and the detailed GuiGameList will be used. This means you can define images, descriptions, and different names for files.
Images are meant to be 256x256, but ES won't stop you from using other sizes - they'll just be placed wrong. I'd like to add automatic scaling (with SDL_gfx) in a future update.
Images will be automatically resized to fit within the left column of the screen. Smaller images will load faster, so try to keep your resolution low.
An example gamelist.xml:
```
<gameList>
@ -55,7 +55,7 @@ The switch `--gamelist-only` can be used to skip automatic searching, and only d
Themes
======
At the moment, theming is still in flux. But if you want to play around with what's here, you can place a theme.xml file in a system's directory. It will be automatically loaded if present (and you're using the detailed view - any system has a gamelist.xml set up).
At the moment, theming is still in flux. But if you want to play around with what's here, feel free. ES will first check a system's search directory for a file named theme.xml. If that's not found, it'll check $HOME/.emulationstation/es_theme.xml.
Themes are drawn before the rest of the game list. Here's the example I've been using to test a background:
```
@ -75,4 +75,3 @@ Variable support is present, but the only variable defined right now is $headerH
-Aloshi
http://www.aloshi.com

View file

@ -1,3 +1,9 @@
August 12
-If a theme.xml is not found in a system's directory, ES will now check for $HOME/.emulationstation/es_theme.xml. If present, it will load that.
-Themes can now be used without the detailed GuiGameList.
-Fixed GuiGameList image data not updating on system change/initial startup (finally!)
-Made the GuiList code a little bit less likely to crash on empty lists
August 10
-Themes now load from system directories (and thus you can set a different theme for each system)
-Theme paths now expand . (to directory of this theme.xml) and ~ (to $HOME).

View file

@ -242,12 +242,6 @@ void InputManager::loadConfig()
std::string InputManager::getConfigPath()
{
std::string home = getenv("HOME");
if(home.empty())
{
std::cerr << "FATAL ERROR - $HOME environment variable is blank or not defined!\n";
exit(1);
return "";
}
return(home + "/.emulationstation/es_input.cfg");
home += "/.emulationstation/es_input.cfg";
return home;
}

View file

@ -23,18 +23,15 @@ GuiGameList::GuiGameList(bool useDetail)
{
mList = new GuiList<FileData*>(Renderer::getScreenWidth() * 0.4, Renderer::getFontHeight(Renderer::LARGE) + 2);
mTheme = new GuiTheme();
//addChild(mTheme); //currently manually rendered before everything else in GuiGameList::onRender
//updateTheme();
mScreenshot = new GuiImage(Renderer::getScreenWidth() * 0.2, Renderer::getFontHeight(Renderer::LARGE) + 2, "", Renderer::getScreenWidth() * 0.3);
addChild(mScreenshot);
}else{
mList = new GuiList<FileData*>(0, Renderer::getFontHeight(Renderer::LARGE) + 2);
mScreenshot = NULL;
mTheme = NULL;
}
mTheme = new GuiTheme(); //not a child because it's rendered manually by GuiGameList::onRender (to make sure it's rendered first)
addChild(mList);
setSystemId(0);
@ -81,6 +78,7 @@ void GuiGameList::setSystemId(int id)
updateTheme();
updateList();
updateDetailData();
}
void GuiGameList::onRender()
@ -142,6 +140,7 @@ void GuiGameList::onInput(InputManager::InputButton button, bool keyDown)
mFolder = mFolderStack.top();
mFolderStack.pop();
updateList();
updateDetailData();
}
if(button == InputManager::RIGHT && keyDown)
@ -162,12 +161,7 @@ void GuiGameList::onInput(InputManager::InputButton button, bool keyDown)
{
if(!keyDown && (button == InputManager::UP || button == InputManager::DOWN))
{
if(mList->getSelectedObject() && !mList->getSelectedObject()->isFolder())
{
mScreenshot->setImage(((GameData*)mList->getSelectedObject())->getImagePath());
}else{
mScreenshot->setImage("");
}
updateDetailData();
}
}
}
@ -195,24 +189,38 @@ void GuiGameList::updateTheme()
if(!mTheme)
return;
std::string defaultPath = getenv("HOME");
defaultPath += "/.emulationstation/es_theme.xml";
std::string themePath = mSystem->getStartPath() + "/theme.xml";
if(boost::filesystem::exists(themePath))
mTheme->readXML(themePath);
else if(boost::filesystem::exists(defaultPath))
mTheme->readXML(defaultPath);
else
mTheme->readXML(""); //clears any current theme
}
void GuiGameList::updateDetailData()
{
if(!mDetailed)
return;
if(mList->getSelectedObject() && !mList->getSelectedObject()->isFolder())
{
mScreenshot->setImage(((GameData*)mList->getSelectedObject())->getImagePath());
}else{
mScreenshot->setImage("");
}
}
//these are called when the menu opens/closes
//the second bit should be moved to GuiList
void GuiGameList::onPause()
{
InputManager::unregisterComponent(this);
InputManager::unregisterComponent(mList);
}
void GuiGameList::onResume()
{
InputManager::registerComponent(this);
InputManager::registerComponent(mList);
}

View file

@ -17,7 +17,6 @@ public:
GuiGameList(bool useDetail = false);
~GuiGameList();
void updateList();
void setSystemId(int id);
void onRender();
@ -26,7 +25,9 @@ public:
void onResume();
private:
void updateList();
void updateTheme();
void updateDetailData();
SystemData* mSystem;
FolderData* mFolder;

View file

@ -156,13 +156,19 @@ void GuiList<listType>::clear()
template <typename listType>
std::string GuiList<listType>::getSelectedName()
{
return mRowVector.at(mSelection).name;
if((int)mRowVector.size() > mSelection)
return mRowVector.at(mSelection).name;
else
return "";
}
template <typename listType>
listType GuiList<listType>::getSelectedObject()
{
return mRowVector.at(mSelection).object;
if((int)mRowVector.size() > mSelection)
return mRowVector.at(mSelection).object;
else
return NULL;
}
template <typename listType>
@ -170,3 +176,15 @@ int GuiList<listType>::getSelection()
{
return mSelection;
}
template <typename listType>
void GuiList<listType>::onPause()
{
InputManager::unregisterComponent(this);
}
template <typename listType>
void GuiList<listType>::onResume()
{
InputManager::registerComponent(this);
}

View file

@ -25,6 +25,9 @@ public:
void addObject(std::string name, listType obj, int color = 0xFF0000);
void clear();
void onPause();
void onResume();
std::string getSelectedName();
listType getSelectedObject();
int getSelection();

View file

@ -31,6 +31,9 @@ void GuiTheme::deleteComponents()
void GuiTheme::readXML(std::string path)
{
if(mPath == path)
return;
deleteComponents();
mPath = path;

View file

@ -11,6 +11,8 @@ bool PARSEGAMELISTONLY = false;
bool IGNOREGAMELIST = false;
float FRAMERATE = 0;
namespace fs = boost::filesystem;
int main(int argc, char* argv[])
{
bool running = true;
@ -19,7 +21,7 @@ int main(int argc, char* argv[])
{
std::cerr << "Error - could not initialize SDL!\n";
std::cerr << " " << SDL_GetError() << "\n";
std::cerr << "\nAre you in the 'video' and 'input' groups?\n";
std::cerr << "Are you in the 'video' and 'input' groups? Are you running with X closed?\n";
return 1;
}
if(TTF_Init() != 0)
@ -74,31 +76,31 @@ int main(int argc, char* argv[])
//make sure the config directory exists
std::string home = getenv("HOME");
std::string configDir = home + "/.emulationstation";
if(!boost::filesystem::exists(configDir))
if(!fs::exists(configDir))
{
std::cout << "Creating config directory \"" << configDir << "\"\n";
boost::filesystem::create_directory(configDir);
fs::create_directory(configDir);
}
//check if there are config files in the old places, and if so, move them to the new directory
std::string oldSysPath = home + "/.es_systems.cfg";
std::string oldInpPath = home + "/.es_input.cfg";
if(boost::filesystem::exists(oldSysPath))
if(fs::exists(oldSysPath))
{
std::cout << "Moving old system config file " << oldSysPath << " to new path at " << SystemData::getConfigPath() << "\n";
boost::filesystem::copy_file(oldSysPath, SystemData::getConfigPath());
boost::filesystem::remove(oldSysPath);
fs::copy_file(oldSysPath, SystemData::getConfigPath());
fs::remove(oldSysPath);
}
if(boost::filesystem::exists(oldInpPath))
if(fs::exists(oldInpPath))
{
std::cout << "Deleting old input config file\n";
boost::filesystem::remove(oldInpPath);
fs::remove(oldInpPath);
}
//try loading the system config file
if(!boost::filesystem::exists(SystemData::getConfigPath())) //if it doesn't exist, create the example and quit
if(!fs::exists(SystemData::getConfigPath())) //if it doesn't exist, create the example and quit
{
std::cerr << "A system config file in " << SystemData::getConfigPath() << " was not found. An example will be created.\n";
SystemData::writeExampleConfig();
@ -130,7 +132,7 @@ int main(int argc, char* argv[])
}
//choose which Gui to open up
if(boost::filesystem::exists(InputManager::getConfigPath()))
if(fs::exists(InputManager::getConfigPath()))
{
InputManager::loadConfig();
new GuiGameList(useDetail);