From 329a8da441a34095194a34af821074d5cbc7fb21 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Sun, 26 Jul 2020 22:19:29 +0200 Subject: [PATCH] Properly implemented hiding of games. Also added a flag to force the Full UI mode from the command line. --- INSTALL.md | 4 ++ NEWS.md | 2 + es-app/src/CollectionSystemManager.cpp | 2 +- es-app/src/FileData.cpp | 52 +++++++++++++++++++++++++ es-app/src/FileData.h | 2 + es-app/src/Gamelist.cpp | 2 +- es-app/src/SystemData.cpp | 19 ++++++++- es-app/src/emulationstation.6.gz | Bin 1065 -> 1081 bytes es-app/src/guis/GuiMenu.cpp | 23 +++++++---- es-app/src/guis/GuiMetaDataEd.cpp | 18 +++++++++ es-app/src/main.cpp | 8 ++++ es-core/src/Settings.cpp | 3 +- 12 files changed, 124 insertions(+), 11 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 6facac11c..4d4370002 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -560,6 +560,7 @@ You can use `--help` or `-h` to view a list of command line options, as shown he --gamelist-only Skip automatic game ROM search, only read from gamelist.xml --ignore-gamelist Ignore the gamelist files (useful for troubleshooting) --show-hidden-files Show hidden files and folders +--show-hidden-games Show hidden games --draw-framerate Display the framerate --no-exit Don't show the exit option in the menu --no-splash Don't show the splash screen @@ -570,6 +571,7 @@ You can use `--help` or `-h` to view a list of command line options, as shown he --vsync [1/on or 0/off] Turn vsync on or off (default is on) --max-vram [size] Max VRAM to use in Mb before swapping Set to at least 20 to avoid unpredictable behavior +--force-full Force the UI mode to Full --force-kid Force the UI mode to Kid --force-kiosk Force the UI mode to Kiosk --force-disable-filters Force the UI to ignore applied filters in gamelist @@ -585,6 +587,7 @@ You can use `--help` or `-h` to view a list of command line options, as shown he --gamelist-only Skip automatic game ROM search, only read from gamelist.xml --ignore-gamelist Ignore the gamelist files (useful for troubleshooting) --show-hidden-files Show hidden files and folders +--show-hidden-games Show hidden games --draw-framerate Display the framerate --no-exit Don't show the exit option in the menu --no-splash Don't show the splash screen @@ -592,6 +595,7 @@ You can use `--help` or `-h` to view a list of command line options, as shown he --vsync [1/on or 0/off] Turn vsync on or off (default is on) --max-vram [size] Max VRAM to use in Mb before swapping Set to at least 20 to avoid unpredictable behavior +--force-full Force the UI mode to Full --force-kid Force the UI mode to Kid --force-kiosk Force the UI mode to Kiosk --force-disable-filters Force the UI to ignore applied filters in gamelist diff --git a/NEWS.md b/NEWS.md index cd0a3e066..e26c27056 100644 --- a/NEWS.md +++ b/NEWS.md @@ -17,6 +17,8 @@ v1.0.0 * Seamless (almost) launch of games without showing the desktop when starting and returning from RetroArch and other emulators * Per-game launch command override, so that different cores or emulators can be used on a per-game basis (saved to gamelist.xml) * Core location can be defined relative to the emulator binary using the %EMUPATH% varible in es_systems.cfg (mostly useful for Windows) +* Properly implemented the option to show or hide hidden files and folders +* Properly implemented the option to show or hide games flagged as hidden in the metadata editor * Help system updated and expanded to the complete application (previously it was only partially implemented) * Improved input device configuration, and default keyboard mappings are now applied if the keyboard has not been configured by the user * GUI-configurable option to sort favorite games on the top of the game lists (favorites marked with stars) diff --git a/es-app/src/CollectionSystemManager.cpp b/es-app/src/CollectionSystemManager.cpp index 85f4aa993..680062fb0 100644 --- a/es-app/src/CollectionSystemManager.cpp +++ b/es-app/src/CollectionSystemManager.cpp @@ -873,7 +873,7 @@ void CollectionSystemManager::populateCustomCollection(CollectionSystemData* sys // Get the ROM directory, either as configured in es_settings.cfg, or if no value // is set there, then use the default hardcoded path. - const std::string rompath = FileData::getROMDirectory(); + const std::string rompath = FileData::getROMDirectory(); // Iterate list of files in the config file. for (std::string gameKey; getline(input, gameKey); ) { diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 904c8f694..02c57b912 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -110,6 +110,32 @@ const bool FileData::getFavorite() return false; } +const bool FileData::getHidden() +{ + if (metadata.get("hidden") == "true") + return true; + else + return false; +} + +const std::vector FileData::getChildrenRercursive() const +{ + std::vector childrenRecursive; + + for (auto it = mChildrenByFilename.cbegin(); + it != mChildrenByFilename.cend(); it++) { + childrenRecursive.push_back((*it).second); + // Recurse through any subdirectories. + if ((*it).second->getType() == FOLDER) { + std::vector childrenSubdirectory = (*it).second->getChildrenRercursive(); + childrenRecursive.insert(childrenRecursive.end(), + childrenSubdirectory.begin(), childrenSubdirectory.end()); + } + } + + return childrenRecursive; +} + const std::string FileData::getROMDirectory() { std::string romDirSetting = Settings::getInstance()->getString("ROMDirectory"); @@ -346,6 +372,24 @@ void FileData::removeChild(FileData* file) void FileData::sort(ComparisonFunction& comparator, bool ascending) { mFirstLetterIndex.clear(); + + // Only run this section of code if the setting to show hidden games has been disabled, + // in order to avoid unnecessary processing. + if (!Settings::getInstance()->getBool("ShowHiddenGames")) { + std::vector mChildrenShown; + for (unsigned int i = 0; i < mChildren.size(); i++) { + if (mChildren[i]->getHidden()) { + LOG(LogDebug) << "Debug - FileData::sort(): Skipping hidden game '" << + mChildren[i]->getName() << "'"; + continue; + } + mChildrenShown.push_back(mChildren[i]); + } + mChildren.erase(mChildren.begin(), mChildren.end()); + mChildren.reserve(mChildrenShown.size()); + mChildren.insert(mChildren.end(), mChildrenShown.begin(), mChildrenShown.end()); + } + std::stable_sort(mChildren.begin(), mChildren.end(), comparator); for (auto it = mChildren.cbegin(); it != mChildren.cend(); it++) { @@ -371,8 +415,16 @@ void FileData::sortFavoritesOnTop(ComparisonFunction& comparator, bool ascending mFirstLetterIndex.clear(); std::vector mChildrenFavorites; std::vector mChildrenOthers; + bool showHiddenGames = Settings::getInstance()->getBool("ShowHiddenGames"); for (unsigned int i = 0; i < mChildren.size(); i++) { + // Exclude game if it's marked as hidden and the hide setting has been set. + if (!showHiddenGames && mChildren[i]->getHidden()) { + LOG(LogDebug) << "Debug - FileData::sortFavoritesOnTop(): Skipping hidden game '" << + mChildren[i]->getName() << "'"; + continue; + } + if (mChildren[i]->getFavorite()) { mChildrenFavorites.push_back(mChildren[i]); } diff --git a/es-app/src/FileData.h b/es-app/src/FileData.h index 2297c0ce4..9353e81d6 100644 --- a/es-app/src/FileData.h +++ b/es-app/src/FileData.h @@ -47,6 +47,8 @@ public: virtual const std::string& getName(); const std::string& getSortName(); const bool getFavorite(); + const bool getHidden(); + const std::vector getChildrenRercursive() const; inline FileType getType() const { return mType; } inline const std::string& getPath() const { return mPath; } inline FileData* getParent() const { return mParent; } diff --git a/es-app/src/Gamelist.cpp b/es-app/src/Gamelist.cpp index fe7e2d855..0a3739f77 100644 --- a/es-app/src/Gamelist.cpp +++ b/es-app/src/Gamelist.cpp @@ -128,7 +128,7 @@ void parseGamelist(SystemData* system) relativeTo, false); if (!trustGamelist && !Utils::FileSystem::exists(path)) { - LOG(LogWarning) << "File \"" << path << "\" does not exist! Ignoring."; + LOG(LogWarning) << "Warning - File \"" << path << "\" does not exist, ignoring."; continue; } diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 8ad83df51..01bb0976c 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -315,7 +315,24 @@ bool SystemData::loadConfig() envData->mPlatformIds = platformIds; SystemData* newSys = new SystemData(name, fullname, envData, themeFolder); - if (newSys->getRootFolder()->getChildrenByFilename().size() == 0) { + bool onlyHidden = false; + + // If the option to show hidden games has been disabled, then check whether all + // games for the system are hidden. That will flag the system as empty. + if (!Settings::getInstance()->getBool("ShowHiddenGames")) { + std::vector recursiveGames = + newSys->getRootFolder()->getChildrenRercursive(); + onlyHidden = true; + for (auto it = recursiveGames.cbegin(); it != recursiveGames.cend(); it++) { + if ((*it)->getType() != FOLDER) { + onlyHidden = (*it)->getHidden(); + if (!onlyHidden) + break; + } + } + } + + if (newSys->getRootFolder()->getChildrenByFilename().size() == 0 || onlyHidden) { LOG(LogDebug) << "SystemData::loadConfig(): System \"" << name << "\" has no games, ignoring it."; delete newSys; diff --git a/es-app/src/emulationstation.6.gz b/es-app/src/emulationstation.6.gz index 653c0d1a3d91a6c24c3fb713f3ef4a5e41f5a650..46527c69245aebc12ad3dee851a3e9e808da138c 100644 GIT binary patch literal 1081 zcmV-91jhRxiwFoKyd7Tv17&S>Y+-b1Z*FsRVRUJ4ZZ0+eg;h~+<2DR__pjjcayg)J z(r(xRhr@vMlCIv8CWzAwhq@24CC6H2$&=)y*{>fdr)`>Rw}&7W$&VDtk5ruXV6uRl z#Tw>|NpkfK*4If2SIKPp13=TtKRC7@?4d?MspW^c$<0xKV!*qT- z8?TeaO}Y+$(EGUuz2923hl|n02){+$D(0op&WAtPp2wqjG{}W#sQ#7J!u6s!y@s3d zd>VacK7i?yC_RWK!aaD?z?4fm2XOlBX0c3@G>R|b)JJrel}UDHnjp)DS-H9opvg4- zx=NOG@#z1efONp1WX=QA97-h~Wv&F2)@VNvBr+CqYj#fRO|Vg{)kQ_84P{BDHSA4m z0b_YNXfPmxYOumv6O5oRN{NC3#!-~`4-TaE=pCEj4den^ho4fTq5ccqhpX+RuMSxo z>%g@|1=v4d30RTqu|+{)tZ>-1t}@1B zV?G{xMd2A_*>zfoLR_dY(f{1hLA#~5xIVoHm0nl!SXNQcDO zhfJOo#~5w00g^9dJu&)&2Z|i*Nems&i6bPcg>FyL6u?z);5!Al!V2-Km0aZQh5$>8 ze1ves2*h4?+V-8)-0TD=^FI&YP#Z4JC{U|7(YP>mE;T9wci-aQu}f^9>MlhIU`#~@ zH{lCjlp)G{xZGIm81^r8QiXvOL*F~6(^C7B{P@|zKOB{{X z;$|Z)baIqJpNo>=q|@p!`jw-aJ)$@4ZgA%0KjJ=`vq$)2HJ;OqA!Vt7^Bikc60hBk zH4QR0igO#K!jlp6padC{C2gWN?e6;rtaS+ zT>;S76)NArJV^d7Tw*9~jiWf#TB9^}`f;9JB8nAhufqfMrn%)#_F!hpzgt>qePiWDYNY)k_Qxm+ zJANqzd^L65YU%gTf0p6J9?)hcFly@e6_%`j`m}X66ug&Cr!bzSi(W(&0B(vFH^|{h zq$hC8qzcqx{xf{3yl>p+;cz28N@JYrp%V1)QlR1KLyT)=_)GLJj;HomdiwFqqZXI6$17&S>Y+-b1Z*FsRVRUJ4ZZ0+eg;m>b<2Dd|*H=vavR=TF zowR6yMNz<6JB?c3U^y)oQ64CXve;0hN>X;*ukQ@yB(^u(J{T5;M&)&2`NbTtz?p6kUBE1<~dXrt|yR zcoQ!d$;SUd@5dhWerx3cu1D7+{N{BlnG;%B=l@`L6^)`%m~qGO`d3zS+Y6%P4i@A2 zH26wAgz1YYIf^FSJ~`dMv=DUm#>tn(a+SnM5Z%BfM(~i9aXQeAm!-qBTt9lF$u#-A zj#m_T@PA%FSYS{x>wu{OO39x^COMQwD;IJSX#<(jdn?q|>qyqByrR>VvLw|S4!Sjf zzMKdfbcjYZ819VrN|0+Qc}@I>94u!T z;s8hw!C2AN>IEQruH`AP*eXos!~sIbUgmRt5kn~?mc5T9D_iONgT-jEYqrwbVPig? zqM~r0hLtD^uF}xk`j}A+o%9Ik`>$oejXkw53`6_Upm&-YvYiNvO+NUjUN25w*u+Q7a3gWUlK>D7^4Ie2+_~kk|^@1w{#*bCpGo7dB&J@lE}vx7xqA#;(zEk(D`$x#aZ zf|m@Zmezn)XFxT3Ml|fM2eaZI{us>JGyJh0&uLzee$>EuhP5h*qjt}l2H6)xnF$i^ zNQpU+oR-V=$RBrF6ws>1@IvH{(Wc3G#dboQv!c)}rs0$D9lG_CNzK2HyZjOAcTv1+ zq3zRu*x>CuR)w$>ik}XL^#2L~ZM)$FOi>Et#8Hzf@G_UDz?H7KuUo@#*Wkby+dZKLP28cvlJzg2oKAaddSaveFunc([launchcommand_override] { Settings::getInstance()-> setBool("LaunchCommandOverride", launchcommand_override->getState()); }); + // Hidden files. + auto hidden_files = std::make_shared(mWindow); + hidden_files->setState(Settings::getInstance()->getBool("ShowHiddenFiles")); + s->addWithLabel("SHOW HIDDEN FILES AND FOLDERS (REQUIRES RESTART)", hidden_files); + s->addSaveFunc([hidden_files] { Settings::getInstance()->setBool("ShowHiddenFiles", + hidden_files->getState()); }); + + // Hidden games. + auto hidden_games = std::make_shared(mWindow); + hidden_games->setState(Settings::getInstance()->getBool("ShowHiddenGames")); + s->addWithLabel("SHOW HIDDEN GAMES (REQUIRES RESTART)", hidden_games); + s->addSaveFunc([hidden_games] { + Settings::getInstance()->setBool("ShowHiddenGames", + hidden_games->getState()); + }); + // Custom event scripts, fired using Scripting::fireEvent(). auto custom_eventscripts = std::make_shared(mWindow); custom_eventscripts->setState(Settings::getInstance()->getBool("CustomEventScripts")); @@ -637,13 +653,6 @@ void GuiMenu::openOtherSettings() s->addSaveFunc([local_art] { Settings::getInstance()-> setBool("LocalArt", local_art->getState()); }); - // Hidden files. - auto hidden_files = std::make_shared(mWindow); - hidden_files->setState(Settings::getInstance()->getBool("ShowHiddenFiles")); - s->addWithLabel("SHOW HIDDEN FILES AND FOLDERS (REQUIRES RESTART)", hidden_files); - s->addSaveFunc([hidden_files] { Settings::getInstance()->setBool("ShowHiddenFiles", - hidden_files->getState()); }); - // Framerate. auto framerate = std::make_shared(mWindow); framerate->setState(Settings::getInstance()->getBool("DrawFramerate")); diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index 12c891aa5..e46e95c36 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -26,6 +26,7 @@ #include "CollectionSystemManager.h" #include "FileData.h" #include "FileFilterIndex.h" +#include "Gamelist.h" #include "SystemData.h" #include "Window.h" @@ -283,10 +284,19 @@ void GuiMetaDataEd::save() // Remove game from index. mScraperParams.system->getIndex()->removeFromIndex(mScraperParams.game); + // We need this to handle the special situation where the user sets a game to hidden while + // ShowHiddenGames is set to false, meaning it will immediately disappear from the gamelist. + bool showHiddenGames = Settings::getInstance()->getBool("ShowHiddenGames"); + bool hideGameWhileHidden = false; + for (unsigned int i = 0; i < mEditors.size(); i++) { if (mMetaDataDecl.at(i).isStatistic) continue; + if (!showHiddenGames && mMetaDataDecl.at(i).key == "hidden" && + mEditors.at(i)->getValue() != mMetaData->get("hidden")) + hideGameWhileHidden = true; + // If the user has entered a blank game name, then set the name to the ROM // filename (minus the extension). if (mMetaDataDecl.at(i).key == "name" && mEditors.at(i)->getValue() == "") { @@ -298,6 +308,14 @@ void GuiMetaDataEd::save() } } + // If hidden games are not shown and the hide flag was set for the game, then write the + // metadata immediately regardless of the SaveGamelistsMode setting. Otherwise the file + // will never be written as the game will be filtered from the gamelist. This solution is not + // really good as the gamelist will be written twice, but it's a very special and hopefully + // rare situation. + if (hideGameWhileHidden) + updateGamelist(mScraperParams.system); + // Enter game in index. mScraperParams.system->getIndex()->addToIndex(mScraperParams.game); diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 688100832..0071ed265 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -232,6 +232,9 @@ bool parseArgs(int argc, char* argv[]) else if (strcmp(argv[i], "--show-hidden-files") == 0) { Settings::getInstance()->setBool("ShowHiddenFiles", true); } + else if (strcmp(argv[i], "--show-hidden-games") == 0) { + Settings::getInstance()->setBool("ShowHiddenGames", true); + } else if (strcmp(argv[i], "--draw-framerate") == 0) { Settings::getInstance()->setBool("DrawFramerate", true); } @@ -263,6 +266,9 @@ bool parseArgs(int argc, char* argv[]) Settings::getInstance()->setBool("VSync", vsync); i++; // Skip vsync value. } + else if (strcmp(argv[i], "--force-full") == 0) { + Settings::getInstance()->setString("UIMode", "Full"); + } else if (strcmp(argv[i], "--force-kiosk") == 0) { Settings::getInstance()->setBool("ForceKiosk", true); } @@ -286,6 +292,7 @@ bool parseArgs(int argc, char* argv[]) " --gamelist-only Skip automatic game ROM search, only read from gamelist.xml\n" " --ignore-gamelist Ignore the gamelist files (useful for troubleshooting)\n" " --show-hidden-files Show hidden files and folders\n" +" --show-hidden-games Show hidden games\n" " --draw-framerate Display the framerate\n" " --no-exit Don't show the exit option in the menu\n" " --no-splash Don't show the splash screen\n" @@ -298,6 +305,7 @@ bool parseArgs(int argc, char* argv[]) " --vsync [1/on or 0/off] Turn vsync on or off (default is on)\n" " --max-vram [size] Max VRAM to use in Mb before swapping\n" " Set to at least 20 to avoid unpredictable behavior\n" +" --force-full Force the UI mode to Full\n" " --force-kid Force the UI mode to Kid\n" " --force-kiosk Force the UI mode to Kiosk\n" " --force-disable-filters Force the UI to ignore applied filters in gamelist\n" diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index d2e482fa1..bc8d3f20c 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -194,7 +194,8 @@ void Settings::setDefaults() mBoolMap["CustomEventScripts"] = false; mBoolMap["ParseGamelistOnly"] = false; mBoolMap["LocalArt"] = false; - mBoolMap["ShowHiddenFiles"] = false; + mBoolMap["ShowHiddenFiles"] = true; + mBoolMap["ShowHiddenGames"] = true; mBoolMap["DrawFramerate"] = false; mBoolMap["ShowRebootSystem"] = true; mBoolMap["ShowPoweroffSystem"] = true;