From c7349cd99aa3b3c3c1a4709eac254a1a3953badb Mon Sep 17 00:00:00 2001 From: Aloshi Date: Sun, 12 Aug 2012 09:43:09 -0500 Subject: [PATCH] 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!) --- README.md | 5 ++--- changelog.txt | 6 ++++++ src/InputManager.cpp | 10 ++-------- src/components/GuiGameList.cpp | 36 +++++++++++++++++++++------------- src/components/GuiGameList.h | 3 ++- src/components/GuiList.cpp | 22 +++++++++++++++++++-- src/components/GuiList.h | 3 +++ src/components/GuiTheme.cpp | 3 +++ src/main.cpp | 22 +++++++++++---------- 9 files changed, 72 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index d4e04014b..f081cf03c 100644 --- a/README.md +++ b/README.md @@ -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: ``` @@ -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 - diff --git a/changelog.txt b/changelog.txt index 41e6a22f1..026a3c059 100644 --- a/changelog.txt +++ b/changelog.txt @@ -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). diff --git a/src/InputManager.cpp b/src/InputManager.cpp index bc7886765..f0eddedb9 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -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; } diff --git a/src/components/GuiGameList.cpp b/src/components/GuiGameList.cpp index 45b8be4e3..65b4004a5 100644 --- a/src/components/GuiGameList.cpp +++ b/src/components/GuiGameList.cpp @@ -23,18 +23,15 @@ GuiGameList::GuiGameList(bool useDetail) { mList = new GuiList(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(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); } diff --git a/src/components/GuiGameList.h b/src/components/GuiGameList.h index b84e42c6d..864e59b74 100644 --- a/src/components/GuiGameList.h +++ b/src/components/GuiGameList.h @@ -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; diff --git a/src/components/GuiList.cpp b/src/components/GuiList.cpp index 0b87843c5..f659e98d9 100644 --- a/src/components/GuiList.cpp +++ b/src/components/GuiList.cpp @@ -156,13 +156,19 @@ void GuiList::clear() template std::string GuiList::getSelectedName() { - return mRowVector.at(mSelection).name; + if((int)mRowVector.size() > mSelection) + return mRowVector.at(mSelection).name; + else + return ""; } template listType GuiList::getSelectedObject() { - return mRowVector.at(mSelection).object; + if((int)mRowVector.size() > mSelection) + return mRowVector.at(mSelection).object; + else + return NULL; } template @@ -170,3 +176,15 @@ int GuiList::getSelection() { return mSelection; } + +template +void GuiList::onPause() +{ + InputManager::unregisterComponent(this); +} + +template +void GuiList::onResume() +{ + InputManager::registerComponent(this); +} diff --git a/src/components/GuiList.h b/src/components/GuiList.h index d99b9351f..b2beb7236 100644 --- a/src/components/GuiList.h +++ b/src/components/GuiList.h @@ -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(); diff --git a/src/components/GuiTheme.cpp b/src/components/GuiTheme.cpp index d74ba3122..7c6a13957 100644 --- a/src/components/GuiTheme.cpp +++ b/src/components/GuiTheme.cpp @@ -31,6 +31,9 @@ void GuiTheme::deleteComponents() void GuiTheme::readXML(std::string path) { + if(mPath == path) + return; + deleteComponents(); mPath = path; diff --git a/src/main.cpp b/src/main.cpp index 3f3a0fbf4..e10b13d28 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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);