mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-02-16 20:15:38 +00:00
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:
parent
bd6c64aefb
commit
c7349cd99a
|
@ -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.
|
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:
|
An example gamelist.xml:
|
||||||
```
|
```
|
||||||
<gameList>
|
<gameList>
|
||||||
|
@ -55,7 +55,7 @@ The switch `--gamelist-only` can be used to skip automatic searching, and only d
|
||||||
Themes
|
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:
|
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
|
-Aloshi
|
||||||
http://www.aloshi.com
|
http://www.aloshi.com
|
||||||
|
|
||||||
|
|
|
@ -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
|
August 10
|
||||||
-Themes now load from system directories (and thus you can set a different theme for each system)
|
-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).
|
-Theme paths now expand . (to directory of this theme.xml) and ~ (to $HOME).
|
||||||
|
|
|
@ -242,12 +242,6 @@ void InputManager::loadConfig()
|
||||||
std::string InputManager::getConfigPath()
|
std::string InputManager::getConfigPath()
|
||||||
{
|
{
|
||||||
std::string home = getenv("HOME");
|
std::string home = getenv("HOME");
|
||||||
if(home.empty())
|
home += "/.emulationstation/es_input.cfg";
|
||||||
{
|
return home;
|
||||||
std::cerr << "FATAL ERROR - $HOME environment variable is blank or not defined!\n";
|
|
||||||
exit(1);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return(home + "/.emulationstation/es_input.cfg");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,18 +23,15 @@ GuiGameList::GuiGameList(bool useDetail)
|
||||||
{
|
{
|
||||||
mList = new GuiList<FileData*>(Renderer::getScreenWidth() * 0.4, Renderer::getFontHeight(Renderer::LARGE) + 2);
|
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);
|
mScreenshot = new GuiImage(Renderer::getScreenWidth() * 0.2, Renderer::getFontHeight(Renderer::LARGE) + 2, "", Renderer::getScreenWidth() * 0.3);
|
||||||
addChild(mScreenshot);
|
addChild(mScreenshot);
|
||||||
}else{
|
}else{
|
||||||
mList = new GuiList<FileData*>(0, Renderer::getFontHeight(Renderer::LARGE) + 2);
|
mList = new GuiList<FileData*>(0, Renderer::getFontHeight(Renderer::LARGE) + 2);
|
||||||
mScreenshot = NULL;
|
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);
|
addChild(mList);
|
||||||
|
|
||||||
setSystemId(0);
|
setSystemId(0);
|
||||||
|
@ -81,6 +78,7 @@ void GuiGameList::setSystemId(int id)
|
||||||
|
|
||||||
updateTheme();
|
updateTheme();
|
||||||
updateList();
|
updateList();
|
||||||
|
updateDetailData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiGameList::onRender()
|
void GuiGameList::onRender()
|
||||||
|
@ -142,6 +140,7 @@ void GuiGameList::onInput(InputManager::InputButton button, bool keyDown)
|
||||||
mFolder = mFolderStack.top();
|
mFolder = mFolderStack.top();
|
||||||
mFolderStack.pop();
|
mFolderStack.pop();
|
||||||
updateList();
|
updateList();
|
||||||
|
updateDetailData();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(button == InputManager::RIGHT && keyDown)
|
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(!keyDown && (button == InputManager::UP || button == InputManager::DOWN))
|
||||||
{
|
{
|
||||||
if(mList->getSelectedObject() && !mList->getSelectedObject()->isFolder())
|
updateDetailData();
|
||||||
{
|
|
||||||
mScreenshot->setImage(((GameData*)mList->getSelectedObject())->getImagePath());
|
|
||||||
}else{
|
|
||||||
mScreenshot->setImage("");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,24 +189,38 @@ void GuiGameList::updateTheme()
|
||||||
if(!mTheme)
|
if(!mTheme)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
std::string defaultPath = getenv("HOME");
|
||||||
|
defaultPath += "/.emulationstation/es_theme.xml";
|
||||||
std::string themePath = mSystem->getStartPath() + "/theme.xml";
|
std::string themePath = mSystem->getStartPath() + "/theme.xml";
|
||||||
|
|
||||||
if(boost::filesystem::exists(themePath))
|
if(boost::filesystem::exists(themePath))
|
||||||
mTheme->readXML(themePath);
|
mTheme->readXML(themePath);
|
||||||
|
else if(boost::filesystem::exists(defaultPath))
|
||||||
|
mTheme->readXML(defaultPath);
|
||||||
else
|
else
|
||||||
mTheme->readXML(""); //clears any current theme
|
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
|
//these are called when the menu opens/closes
|
||||||
//the second bit should be moved to GuiList
|
|
||||||
void GuiGameList::onPause()
|
void GuiGameList::onPause()
|
||||||
{
|
{
|
||||||
InputManager::unregisterComponent(this);
|
InputManager::unregisterComponent(this);
|
||||||
InputManager::unregisterComponent(mList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiGameList::onResume()
|
void GuiGameList::onResume()
|
||||||
{
|
{
|
||||||
InputManager::registerComponent(this);
|
InputManager::registerComponent(this);
|
||||||
InputManager::registerComponent(mList);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ public:
|
||||||
GuiGameList(bool useDetail = false);
|
GuiGameList(bool useDetail = false);
|
||||||
~GuiGameList();
|
~GuiGameList();
|
||||||
|
|
||||||
void updateList();
|
|
||||||
void setSystemId(int id);
|
void setSystemId(int id);
|
||||||
|
|
||||||
void onRender();
|
void onRender();
|
||||||
|
@ -26,7 +25,9 @@ public:
|
||||||
void onResume();
|
void onResume();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updateList();
|
||||||
void updateTheme();
|
void updateTheme();
|
||||||
|
void updateDetailData();
|
||||||
|
|
||||||
SystemData* mSystem;
|
SystemData* mSystem;
|
||||||
FolderData* mFolder;
|
FolderData* mFolder;
|
||||||
|
|
|
@ -156,13 +156,19 @@ void GuiList<listType>::clear()
|
||||||
template <typename listType>
|
template <typename listType>
|
||||||
std::string GuiList<listType>::getSelectedName()
|
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>
|
template <typename listType>
|
||||||
listType GuiList<listType>::getSelectedObject()
|
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>
|
template <typename listType>
|
||||||
|
@ -170,3 +176,15 @@ int GuiList<listType>::getSelection()
|
||||||
{
|
{
|
||||||
return mSelection;
|
return mSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename listType>
|
||||||
|
void GuiList<listType>::onPause()
|
||||||
|
{
|
||||||
|
InputManager::unregisterComponent(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename listType>
|
||||||
|
void GuiList<listType>::onResume()
|
||||||
|
{
|
||||||
|
InputManager::registerComponent(this);
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@ public:
|
||||||
void addObject(std::string name, listType obj, int color = 0xFF0000);
|
void addObject(std::string name, listType obj, int color = 0xFF0000);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
void onPause();
|
||||||
|
void onResume();
|
||||||
|
|
||||||
std::string getSelectedName();
|
std::string getSelectedName();
|
||||||
listType getSelectedObject();
|
listType getSelectedObject();
|
||||||
int getSelection();
|
int getSelection();
|
||||||
|
|
|
@ -31,6 +31,9 @@ void GuiTheme::deleteComponents()
|
||||||
|
|
||||||
void GuiTheme::readXML(std::string path)
|
void GuiTheme::readXML(std::string path)
|
||||||
{
|
{
|
||||||
|
if(mPath == path)
|
||||||
|
return;
|
||||||
|
|
||||||
deleteComponents();
|
deleteComponents();
|
||||||
|
|
||||||
mPath = path;
|
mPath = path;
|
||||||
|
|
22
src/main.cpp
22
src/main.cpp
|
@ -11,6 +11,8 @@ bool PARSEGAMELISTONLY = false;
|
||||||
bool IGNOREGAMELIST = false;
|
bool IGNOREGAMELIST = false;
|
||||||
float FRAMERATE = 0;
|
float FRAMERATE = 0;
|
||||||
|
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
bool running = true;
|
bool running = true;
|
||||||
|
@ -19,7 +21,7 @@ int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
std::cerr << "Error - could not initialize SDL!\n";
|
std::cerr << "Error - could not initialize SDL!\n";
|
||||||
std::cerr << " " << SDL_GetError() << "\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;
|
return 1;
|
||||||
}
|
}
|
||||||
if(TTF_Init() != 0)
|
if(TTF_Init() != 0)
|
||||||
|
@ -74,31 +76,31 @@ int main(int argc, char* argv[])
|
||||||
//make sure the config directory exists
|
//make sure the config directory exists
|
||||||
std::string home = getenv("HOME");
|
std::string home = getenv("HOME");
|
||||||
std::string configDir = home + "/.emulationstation";
|
std::string configDir = home + "/.emulationstation";
|
||||||
if(!boost::filesystem::exists(configDir))
|
if(!fs::exists(configDir))
|
||||||
{
|
{
|
||||||
std::cout << "Creating config directory \"" << configDir << "\"\n";
|
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
|
//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 oldSysPath = home + "/.es_systems.cfg";
|
||||||
std::string oldInpPath = home + "/.es_input.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";
|
std::cout << "Moving old system config file " << oldSysPath << " to new path at " << SystemData::getConfigPath() << "\n";
|
||||||
boost::filesystem::copy_file(oldSysPath, SystemData::getConfigPath());
|
fs::copy_file(oldSysPath, SystemData::getConfigPath());
|
||||||
boost::filesystem::remove(oldSysPath);
|
fs::remove(oldSysPath);
|
||||||
}
|
}
|
||||||
if(boost::filesystem::exists(oldInpPath))
|
if(fs::exists(oldInpPath))
|
||||||
{
|
{
|
||||||
std::cout << "Deleting old input config file\n";
|
std::cout << "Deleting old input config file\n";
|
||||||
boost::filesystem::remove(oldInpPath);
|
fs::remove(oldInpPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//try loading the system config file
|
//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";
|
std::cerr << "A system config file in " << SystemData::getConfigPath() << " was not found. An example will be created.\n";
|
||||||
SystemData::writeExampleConfig();
|
SystemData::writeExampleConfig();
|
||||||
|
@ -130,7 +132,7 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
//choose which Gui to open up
|
//choose which Gui to open up
|
||||||
if(boost::filesystem::exists(InputManager::getConfigPath()))
|
if(fs::exists(InputManager::getConfigPath()))
|
||||||
{
|
{
|
||||||
InputManager::loadConfig();
|
InputManager::loadConfig();
|
||||||
new GuiGameList(useDetail);
|
new GuiGameList(useDetail);
|
||||||
|
|
Loading…
Reference in a new issue