From 878b384b022ddbafd8965194c3670ee356a2f95f Mon Sep 17 00:00:00 2001 From: Aloshi Date: Fri, 10 Aug 2012 23:17:52 -0500 Subject: [PATCH] Themes now load from system directories. ~ and . are now expanded in theme image paths. Theme percentages should now work properly. See changelog (August 10) for more. --- changelog.txt | 7 +++++++ src/GuiComponent.cpp | 6 ++++++ src/GuiComponent.h | 1 + src/SystemData.cpp | 11 +++++++++-- src/components/GuiGameList.cpp | 22 ++++++++++++---------- src/components/GuiTheme.cpp | 33 +++++++++++++++++++++++++++++---- src/components/GuiTheme.h | 5 +++-- src/main.cpp | 16 +++++++++++----- 8 files changed, 78 insertions(+), 23 deletions(-) diff --git a/changelog.txt b/changelog.txt index eb584fa15..41e6a22f1 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,10 @@ +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). +-Added --ignore-gamelist switch. Does as it says, and forces the simple GuiGameList. +-Folders that do not contain games will not be added. +-Fixed float percentages in GuiTheme being converted to integers before they were converted to pixels...woops! + August 9 -Removed multithreaded image loading -Improved GuiImage rendering speed by adding additional processing at load time (SDL_DisplayFormat) diff --git a/src/GuiComponent.cpp b/src/GuiComponent.cpp index 3ea988eb7..6cbfafa0a 100644 --- a/src/GuiComponent.cpp +++ b/src/GuiComponent.cpp @@ -39,6 +39,11 @@ void GuiComponent::removeChild(GuiComponent* comp) std::cerr << "Error - tried to remove GuiComponent child, but couldn't find it!\n"; } +void GuiComponent::clearChildren() +{ + mChildren.clear(); +} + void GuiComponent::processTicks(int deltaTime) { for(unsigned int i = 0; i < sComponentVector.size(); i++) @@ -72,3 +77,4 @@ void GuiComponent::resume() for(unsigned int i = 0; i < mChildren.size(); i++) mChildren.at(i)->resume(); } + diff --git a/src/GuiComponent.h b/src/GuiComponent.h index 0648444c6..7bc38e575 100644 --- a/src/GuiComponent.h +++ b/src/GuiComponent.h @@ -24,6 +24,7 @@ public: void addChild(GuiComponent* comp); void removeChild(GuiComponent* comp); + void clearChildren(); unsigned int getChildCount() { return mChildren.size(); } GuiComponent* getChild(unsigned int i) { return mChildren.at(i); } diff --git a/src/SystemData.cpp b/src/SystemData.cpp index 47d9cd4c4..cf7e26736 100644 --- a/src/SystemData.cpp +++ b/src/SystemData.cpp @@ -11,6 +11,7 @@ std::vector SystemData::sSystemVector; namespace fs = boost::filesystem; extern bool PARSEGAMELISTONLY; +extern bool IGNOREGAMELIST; std::string SystemData::getStartPath() { return mStartPath; } std::string SystemData::getExtension() { return mSearchExtension; } @@ -44,7 +45,8 @@ SystemData::SystemData(std::string name, std::string startPath, std::string exte if(!PARSEGAMELISTONLY) populateFolder(mRootFolder); - parseGamelist(this); + if(!IGNOREGAMELIST) + parseGamelist(this); mRootFolder->sort(); } @@ -103,7 +105,12 @@ void SystemData::populateFolder(FolderData* folder) { FolderData* newFolder = new FolderData(this, filePath.string(), filePath.stem().string()); populateFolder(newFolder); - folder->pushFileData(newFolder); + + //ignore folders that do not contain games + if(newFolder->getFileCount() == 0) + delete newFolder; + else + folder->pushFileData(newFolder); }else{ if(filePath.extension().string() == mSearchExtension) { diff --git a/src/components/GuiGameList.cpp b/src/components/GuiGameList.cpp index cc9719d71..45b8be4e3 100644 --- a/src/components/GuiGameList.cpp +++ b/src/components/GuiGameList.cpp @@ -4,7 +4,7 @@ #include "GuiMenu.h" #include -//#define DRAWFRAMERATE +#define DRAWFRAMERATE #ifdef DRAWFRAMERATE #include @@ -24,8 +24,8 @@ GuiGameList::GuiGameList(bool useDetail) mList = new GuiList(Renderer::getScreenWidth() * 0.4, Renderer::getFontHeight(Renderer::LARGE) + 2); mTheme = new GuiTheme(); - //addChild(mTheme); - updateTheme(); + //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); @@ -79,16 +79,16 @@ void GuiGameList::setSystemId(int id) mFolder = mSystem->getRootFolder(); + updateTheme(); updateList(); } void GuiGameList::onRender() { + Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0xFFFFFF); + if(mTheme) mTheme->render(); - else - Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0xFFFFFF); - #ifdef DRAWFRAMERATE std::stringstream ss; @@ -192,13 +192,15 @@ void GuiGameList::updateList() void GuiGameList::updateTheme() { - std::string themePath = getenv("HOME"); - themePath += "/.emulationstation/theme.xml"; + if(!mTheme) + return; + + std::string themePath = mSystem->getStartPath() + "/theme.xml"; if(boost::filesystem::exists(themePath)) - { mTheme->readXML(themePath); - } + else + mTheme->readXML(""); //clears any current theme } //these are called when the menu opens/closes diff --git a/src/components/GuiTheme.cpp b/src/components/GuiTheme.cpp index a33207ae9..d74ba3122 100644 --- a/src/components/GuiTheme.cpp +++ b/src/components/GuiTheme.cpp @@ -2,6 +2,7 @@ #include "../MathExp.h" #include #include "GuiImage.h" +#include GuiTheme::GuiTheme(std::string path) { @@ -22,6 +23,8 @@ void GuiTheme::deleteComponents() } mComponentVector.clear(); + + clearChildren(); } @@ -30,6 +33,11 @@ void GuiTheme::readXML(std::string path) { deleteComponents(); + mPath = path; + + if(path.empty()) + return; + std::cout << "Loading theme \"" << path << "\"...\n"; pugi::xml_document doc; @@ -58,7 +66,14 @@ GuiComponent* GuiTheme::createElement(pugi::xml_node data, GuiComponent* parent) if(type == "image") { - std::string path = data.child("path").text().get(); + std::string path = expandPath(data.child("path").text().get()); + + if(!boost::filesystem::exists(path)) + { + std::cerr << "Error - theme image \"" << path << "\" does not exist.\n"; + return NULL; + } + std::string pos = data.child("pos").text().get(); std::string dim = data.child("dim").text().get(); @@ -79,7 +94,7 @@ GuiComponent* GuiTheme::createElement(pugi::xml_node data, GuiComponent* parent) int w = resolveExp(dimW) * Renderer::getScreenWidth(); int h = resolveExp(dimH) * Renderer::getScreenHeight(); - std::cout << "w: " << w << " h: " << h << "\n"; + std::cout << "w: " << w << "px, h: " << h << "px\n"; GuiComponent* comp = new GuiImage(x, y, path, w, h, true); parent->addChild(comp); @@ -92,7 +107,17 @@ GuiComponent* GuiTheme::createElement(pugi::xml_node data, GuiComponent* parent) return NULL; } -int GuiTheme::resolveExp(std::string str) +std::string GuiTheme::expandPath(std::string path) +{ + if(path[0] == '~') + path = getenv("HOME") + path.substr(1, path.length() - 1); + else if(path[0] == '.') + path = boost::filesystem::path(mPath).parent_path().string() + path.substr(1, path.length() - 1); + + return path; +} + +float GuiTheme::resolveExp(std::string str) { MathExp exp; exp.setExpression(str); @@ -100,5 +125,5 @@ int GuiTheme::resolveExp(std::string str) //set variables exp.setVariable("headerHeight", Renderer::getFontHeight(Renderer::LARGE) / Renderer::getScreenHeight()); - return (int)exp.eval(); + return exp.eval(); } diff --git a/src/components/GuiTheme.h b/src/components/GuiTheme.h index 8449164e0..254484495 100644 --- a/src/components/GuiTheme.h +++ b/src/components/GuiTheme.h @@ -14,11 +14,12 @@ public: private: void deleteComponents(); - GuiComponent* createElement(pugi::xml_node data, GuiComponent* parent); - int resolveExp(std::string str); + std::string expandPath(std::string path); + float resolveExp(std::string str); std::vector mComponentVector; + std::string mPath; }; #endif diff --git a/src/main.cpp b/src/main.cpp index 278284c83..3f3a0fbf4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,7 @@ #include "components/GuiInputConfig.h" bool PARSEGAMELISTONLY = false; +bool IGNOREGAMELIST = false; float FRAMERATE = 0; int main(int argc, char* argv[]) @@ -46,6 +47,9 @@ int main(int argc, char* argv[]) }else if(strcmp(argv[i], "--gamelist-only") == 0) { PARSEGAMELISTONLY = true; + }else if(strcmp(argv[i], "--ignore-gamelist") == 0) + { + IGNOREGAMELIST = true; } } } @@ -113,16 +117,18 @@ int main(int argc, char* argv[]) bool useDetail = false; //see if any systems had gamelists present, if so we'll use the detailed GuiGameList - for(unsigned int i = 0; i < SystemData::sSystemVector.size(); i++) + if(!IGNOREGAMELIST) { - if(SystemData::sSystemVector.at(i)->hasGamelist()) + for(unsigned int i = 0; i < SystemData::sSystemVector.size(); i++) { - useDetail = true; - break; + if(SystemData::sSystemVector.at(i)->hasGamelist()) + { + useDetail = true; + break; + } } } - //choose which Gui to open up if(boost::filesystem::exists(InputManager::getConfigPath())) {