mirror of
https://github.com/RetroPie/EmulationStation.git
synced 2025-04-02 10:41:48 -04:00
Compare commits
6 commits
3cd6d4bba5
...
17118a2e73
Author | SHA1 | Date | |
---|---|---|---|
|
17118a2e73 | ||
|
e8fb5a0869 | ||
|
3c41f15374 | ||
|
a9ee7e48c4 | ||
|
6de6151b09 | ||
|
feab8293e5 |
7 changed files with 171 additions and 87 deletions
|
@ -248,6 +248,10 @@ All systems must be contained within the <systemList> tag.-->
|
||||||
You MUST include the period at the start of the extension! It's also case sensitive. -->
|
You MUST include the period at the start of the extension! It's also case sensitive. -->
|
||||||
<extension>.smc .sfc .SMC .SFC</extension>
|
<extension>.smc .sfc .SMC .SFC</extension>
|
||||||
|
|
||||||
|
<!-- A list of filenames to ignore, delimited by any of the whitespace characters (", \r\n\t").
|
||||||
|
You MUST wrap each filename in double quotes (since some filenames contain spaces). Not case sensitive. -->
|
||||||
|
<ignore>"filename1.bin" "filename2.iso" "filename3.zip"</ignore>
|
||||||
|
|
||||||
<!-- The shell command executed when a game is selected. A few special tags are replaced if found in a command, like %ROM% (see below). -->
|
<!-- The shell command executed when a game is selected. A few special tags are replaced if found in a command, like %ROM% (see below). -->
|
||||||
<command>snesemulator %ROM%</command>
|
<command>snesemulator %ROM%</command>
|
||||||
<!-- This example would run the bash command "snesemulator /home/user/roms/snes/Super\ Mario\ World.sfc". -->
|
<!-- This example would run the bash command "snesemulator /home/user/roms/snes/Super\ Mario\ World.sfc". -->
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "ThemeData.h"
|
#include "ThemeData.h"
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
/* Handling the getting, initialization, deinitialization, saving and deletion of
|
/* Handling the getting, initialization, deinitialization, saving and deletion of
|
||||||
* a CollectionSystemManager Instance */
|
* a CollectionSystemManager Instance */
|
||||||
|
@ -44,6 +45,8 @@ CollectionSystemManager::CollectionSystemManager(Window* window) : mWindow(windo
|
||||||
mCollectionEnvData->mStartPath = "";
|
mCollectionEnvData->mStartPath = "";
|
||||||
std::vector<std::string> exts;
|
std::vector<std::string> exts;
|
||||||
mCollectionEnvData->mSearchExtensions = exts;
|
mCollectionEnvData->mSearchExtensions = exts;
|
||||||
|
std::vector<std::string> ignores;
|
||||||
|
mCollectionEnvData->mFilesToIgnore = ignores;
|
||||||
mCollectionEnvData->mLaunchCommand = "";
|
mCollectionEnvData->mLaunchCommand = "";
|
||||||
std::vector<PlatformIds::PlatformId> allPlatformIds;
|
std::vector<PlatformIds::PlatformId> allPlatformIds;
|
||||||
allPlatformIds.push_back(PlatformIds::PLATFORM_IGNORE);
|
allPlatformIds.push_back(PlatformIds::PLATFORM_IGNORE);
|
||||||
|
@ -97,29 +100,37 @@ void CollectionSystemManager::deinit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollectionSystemManager::saveCustomCollection(SystemData* sys)
|
bool CollectionSystemManager::saveCustomCollection(SystemData* sys)
|
||||||
{
|
{
|
||||||
std::string name = sys->getName();
|
std::string name = sys->getName();
|
||||||
std::unordered_map<std::string, FileData*> games = sys->getRootFolder()->getChildrenByFilename();
|
std::unordered_map<std::string, FileData*> games = sys->getRootFolder()->getChildrenByFilename();
|
||||||
bool found = mCustomCollectionSystemsData.find(name) != mCustomCollectionSystemsData.cend();
|
bool found = mCustomCollectionSystemsData.find(name) != mCustomCollectionSystemsData.cend();
|
||||||
if (found) {
|
if (!found)
|
||||||
CollectionSystemData sysData = mCustomCollectionSystemsData.at(name);
|
|
||||||
if (sysData.needsSave)
|
|
||||||
{
|
|
||||||
std::ofstream configFile;
|
|
||||||
configFile.open(getCustomCollectionConfigPath(name));
|
|
||||||
for(std::unordered_map<std::string, FileData*>::const_iterator iter = games.cbegin(); iter != games.cend(); ++iter)
|
|
||||||
{
|
|
||||||
std::string path = iter->first;
|
|
||||||
configFile << path << std::endl;
|
|
||||||
}
|
|
||||||
configFile.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
LOG(LogError) << "Couldn't find collection to save! " << name;
|
LOG(LogError) << "Couldn't find collection to save! " << name;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CollectionSystemData sysData = mCustomCollectionSystemsData.at(name);
|
||||||
|
if (sysData.needsSave)
|
||||||
|
{
|
||||||
|
std::string absCollectionFn = getCustomCollectionConfigPath(name);
|
||||||
|
std::ofstream configFile;
|
||||||
|
configFile.open(absCollectionFn);
|
||||||
|
if (!configFile.good())
|
||||||
|
{
|
||||||
|
auto const errNo = errno;
|
||||||
|
LOG(LogError) << "Failed to create file, collection not created: " << absCollectionFn << ": " << std::strerror(errNo) << " (" << errNo << ")";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(std::unordered_map<std::string, FileData*>::const_iterator iter = games.cbegin(); iter != games.cend(); ++iter)
|
||||||
|
{
|
||||||
|
std::string path = iter->first;
|
||||||
|
configFile << path << std::endl;
|
||||||
|
}
|
||||||
|
configFile.close();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Methods to load all Collections into memory, and handle enabling the active ones */
|
/* Methods to load all Collections into memory, and handle enabling the active ones */
|
||||||
|
@ -128,7 +139,7 @@ void CollectionSystemManager::loadCollectionSystems(bool async)
|
||||||
{
|
{
|
||||||
initAutoCollectionSystems();
|
initAutoCollectionSystems();
|
||||||
CollectionSystemDecl decl = mCollectionSystemDeclsIndex[CUSTOM_COLL_ID];
|
CollectionSystemDecl decl = mCollectionSystemDeclsIndex[CUSTOM_COLL_ID];
|
||||||
mCustomCollectionsBundle = createNewCollectionEntry(decl.name, decl, false);
|
mCustomCollectionsBundle = createNewCollectionEntry(decl.name, decl, CollectionFlags::NONE);
|
||||||
// we will also load custom systems here
|
// we will also load custom systems here
|
||||||
initCustomCollectionSystems();
|
initCustomCollectionSystems();
|
||||||
if(Settings::getInstance()->getString("CollectionSystemsAuto") != "" || Settings::getInstance()->getString("CollectionSystemsCustom") != "")
|
if(Settings::getInstance()->getString("CollectionSystemsAuto") != "" || Settings::getInstance()->getString("CollectionSystemsCustom") != "")
|
||||||
|
@ -375,6 +386,7 @@ bool CollectionSystemManager::isThemeCustomCollectionCompatible(std::vector<std:
|
||||||
std::string CollectionSystemManager::getValidNewCollectionName(std::string inName, int index)
|
std::string CollectionSystemManager::getValidNewCollectionName(std::string inName, int index)
|
||||||
{
|
{
|
||||||
std::string name = inName;
|
std::string name = inName;
|
||||||
|
const std::string infix = " (" + std::to_string(index) + ")";
|
||||||
|
|
||||||
if(index == 0)
|
if(index == 0)
|
||||||
{
|
{
|
||||||
|
@ -388,7 +400,7 @@ std::string CollectionSystemManager::getValidNewCollectionName(std::string inNam
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
name += " (" + std::to_string(index) + ")";
|
name += infix;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(name == "")
|
if(name == "")
|
||||||
|
@ -398,7 +410,7 @@ std::string CollectionSystemManager::getValidNewCollectionName(std::string inNam
|
||||||
|
|
||||||
if(name != inName)
|
if(name != inName)
|
||||||
{
|
{
|
||||||
LOG(LogInfo) << "Had to change name, from: " << inName << " to: " << name;
|
LOG(LogInfo) << "Name collision, had to change name from: " << inName << " to: " << name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get used systems in es_systems.cfg
|
// get used systems in es_systems.cfg
|
||||||
|
@ -418,7 +430,7 @@ std::string CollectionSystemManager::getValidNewCollectionName(std::string inNam
|
||||||
if (*sysIt == name)
|
if (*sysIt == name)
|
||||||
{
|
{
|
||||||
if(index > 0) {
|
if(index > 0) {
|
||||||
name = name.substr(0, name.size()-4);
|
name = name.substr(0, name.size() - infix.size());
|
||||||
}
|
}
|
||||||
return getValidNewCollectionName(name, index+1);
|
return getValidNewCollectionName(name, index+1);
|
||||||
}
|
}
|
||||||
|
@ -448,7 +460,7 @@ void CollectionSystemManager::setEditMode(std::string collectionName, bool quiet
|
||||||
mEditingCollectionSystemData = sysData;
|
mEditingCollectionSystemData = sysData;
|
||||||
|
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
GuiInfoPopup* s = new GuiInfoPopup(mWindow, "Editing the '" + Utils::String::toUpper(collectionName) + "' Collection. Add/remove games with Y.", 10000);
|
GuiInfoPopup* s = new GuiInfoPopup(mWindow, "Editing the '" + Utils::String::toUpper(collectionName) + "' Collection. Add/remove games with Y.", 8000);
|
||||||
mWindow->setInfoPopup(s);
|
mWindow->setInfoPopup(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,14 +468,14 @@ void CollectionSystemManager::setEditMode(std::string collectionName, bool quiet
|
||||||
void CollectionSystemManager::exitEditMode(bool quiet)
|
void CollectionSystemManager::exitEditMode(bool quiet)
|
||||||
{
|
{
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
GuiInfoPopup* s = new GuiInfoPopup(mWindow, "Finished editing the '" + mEditingCollection + "' Collection.", 4000);
|
GuiInfoPopup* s = new GuiInfoPopup(mWindow, "Finished editing the '" + Utils::String::toUpper(mEditingCollection) + "' Collection.", 4000);
|
||||||
mWindow->setInfoPopup(s);
|
mWindow->setInfoPopup(s);
|
||||||
}
|
}
|
||||||
if (mIsEditingCustom) {
|
if (mIsEditingCustom) {
|
||||||
mIsEditingCustom = false;
|
mIsEditingCustom = false;
|
||||||
mEditingCollection = "Favorites";
|
mEditingCollection = "Favorites";
|
||||||
|
|
||||||
mEditingCollectionSystemData->system->onMetaDataSavePoint();
|
mEditingCollectionSystemData->system->onMetaDataSavePoint();
|
||||||
|
saveCustomCollection(mEditingCollectionSystemData->system);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,7 +668,7 @@ void CollectionSystemManager::initAutoCollectionSystems()
|
||||||
CollectionSystemDecl sysDecl = it->second;
|
CollectionSystemDecl sysDecl = it->second;
|
||||||
if (!sysDecl.isCustom)
|
if (!sysDecl.isCustom)
|
||||||
{
|
{
|
||||||
SystemData* newCol = createNewCollectionEntry(sysDecl.name, sysDecl);
|
SystemData* newCol = createNewCollectionEntry(sysDecl.name, sysDecl, CollectionFlags::HOLD_IN_MAP);
|
||||||
if (sysDecl.type == AUTO_RANDOM)
|
if (sysDecl.type == AUTO_RANDOM)
|
||||||
mRandomCollection = newCol;
|
mRandomCollection = newCol;
|
||||||
}
|
}
|
||||||
|
@ -756,17 +768,20 @@ SystemData* CollectionSystemManager::getAllGamesCollection()
|
||||||
return allSysData->system;
|
return allSysData->system;
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemData* CollectionSystemManager::addNewCustomCollection(std::string name)
|
SystemData* CollectionSystemManager::addNewCustomCollection(std::string name, bool needsSave)
|
||||||
{
|
{
|
||||||
CollectionSystemDecl decl = mCollectionSystemDeclsIndex[CUSTOM_COLL_ID];
|
CollectionSystemDecl decl = mCollectionSystemDeclsIndex[CUSTOM_COLL_ID];
|
||||||
decl.themeFolder = name;
|
decl.themeFolder = name;
|
||||||
decl.name = name;
|
decl.name = name;
|
||||||
decl.longName = name;
|
decl.longName = name;
|
||||||
return createNewCollectionEntry(name, decl);
|
CollectionFlags flags = CollectionFlags::HOLD_IN_MAP;
|
||||||
|
if (needsSave)
|
||||||
|
flags = flags | CollectionFlags::NEEDS_SAVE;
|
||||||
|
return createNewCollectionEntry(name, decl, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates a new, empty Collection system, based on the name and declaration
|
// creates a new, empty Collection system, based on the name and declaration
|
||||||
SystemData* CollectionSystemManager::createNewCollectionEntry(std::string name, CollectionSystemDecl sysDecl, bool index)
|
SystemData* CollectionSystemManager::createNewCollectionEntry(std::string name, CollectionSystemDecl sysDecl, const CollectionFlags flags)
|
||||||
{
|
{
|
||||||
SystemData* newSys = new SystemData(name, sysDecl.longName, mCollectionEnvData, sysDecl.themeFolder, true);
|
SystemData* newSys = new SystemData(name, sysDecl.longName, mCollectionEnvData, sysDecl.themeFolder, true);
|
||||||
|
|
||||||
|
@ -775,9 +790,9 @@ SystemData* CollectionSystemManager::createNewCollectionEntry(std::string name,
|
||||||
newCollectionData.decl = sysDecl;
|
newCollectionData.decl = sysDecl;
|
||||||
newCollectionData.isEnabled = false;
|
newCollectionData.isEnabled = false;
|
||||||
newCollectionData.isPopulated = false;
|
newCollectionData.isPopulated = false;
|
||||||
newCollectionData.needsSave = false;
|
newCollectionData.needsSave = (flags & CollectionFlags::NEEDS_SAVE) == CollectionFlags::NEEDS_SAVE ? true : false;
|
||||||
|
|
||||||
if (index)
|
if ((flags & CollectionFlags::HOLD_IN_MAP) == CollectionFlags::HOLD_IN_MAP)
|
||||||
{
|
{
|
||||||
if (!sysDecl.isCustom)
|
if (!sysDecl.isCustom)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,6 +30,24 @@ enum CollectionSystemType
|
||||||
CUSTOM_COLLECTION
|
CUSTOM_COLLECTION
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Flags when loading or creating a collection
|
||||||
|
enum class CollectionFlags : uint8_t
|
||||||
|
{
|
||||||
|
NONE, // create only
|
||||||
|
HOLD_IN_MAP, // create and keep in mAutoCollectionSystemsData or mCustomCollectionSystemsData
|
||||||
|
NEEDS_SAVE // force save of newly added collection
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr CollectionFlags operator|(CollectionFlags a,CollectionFlags b)
|
||||||
|
{
|
||||||
|
return static_cast<CollectionFlags>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr CollectionFlags operator&(CollectionFlags a, CollectionFlags b)
|
||||||
|
{
|
||||||
|
return static_cast<CollectionFlags>(static_cast<uint8_t>(a) & static_cast<uint8_t>(b));
|
||||||
|
}
|
||||||
|
|
||||||
struct CollectionSystemDecl
|
struct CollectionSystemDecl
|
||||||
{
|
{
|
||||||
CollectionSystemType type; // type of system
|
CollectionSystemType type; // type of system
|
||||||
|
@ -58,7 +76,7 @@ public:
|
||||||
static CollectionSystemManager* get();
|
static CollectionSystemManager* get();
|
||||||
static void init(Window* window);
|
static void init(Window* window);
|
||||||
static void deinit();
|
static void deinit();
|
||||||
void saveCustomCollection(SystemData* sys);
|
bool saveCustomCollection(SystemData* sys);
|
||||||
|
|
||||||
void loadCollectionSystems(bool async=false);
|
void loadCollectionSystems(bool async=false);
|
||||||
void loadEnabledListFromSettings();
|
void loadEnabledListFromSettings();
|
||||||
|
@ -74,7 +92,7 @@ public:
|
||||||
inline SystemData* getCustomCollectionsBundle() { return mCustomCollectionsBundle; };
|
inline SystemData* getCustomCollectionsBundle() { return mCustomCollectionsBundle; };
|
||||||
inline SystemData* getRandomCollection() { return mRandomCollection; };
|
inline SystemData* getRandomCollection() { return mRandomCollection; };
|
||||||
std::vector<std::string> getUnusedSystemsFromTheme();
|
std::vector<std::string> getUnusedSystemsFromTheme();
|
||||||
SystemData* addNewCustomCollection(std::string name);
|
SystemData* addNewCustomCollection(std::string name, bool needsSave = false);
|
||||||
|
|
||||||
bool isThemeGenericCollectionCompatible(bool genericCustomCollections);
|
bool isThemeGenericCollectionCompatible(bool genericCustomCollections);
|
||||||
bool isThemeCustomCollectionCompatible(std::vector<std::string> stringVector);
|
bool isThemeCustomCollectionCompatible(std::vector<std::string> stringVector);
|
||||||
|
@ -107,7 +125,7 @@ private:
|
||||||
|
|
||||||
void initAutoCollectionSystems();
|
void initAutoCollectionSystems();
|
||||||
void initCustomCollectionSystems();
|
void initCustomCollectionSystems();
|
||||||
SystemData* createNewCollectionEntry(std::string name, CollectionSystemDecl sysDecl, bool index = true);
|
SystemData* createNewCollectionEntry(std::string name, CollectionSystemDecl sysDecl, const CollectionFlags flags);
|
||||||
void populateAutoCollection(CollectionSystemData* sysData);
|
void populateAutoCollection(CollectionSystemData* sysData);
|
||||||
void populateCustomCollection(CollectionSystemData* sysData);
|
void populateCustomCollection(CollectionSystemData* sysData);
|
||||||
void addRandomGames(SystemData* newSys, SystemData* sourceSystem, FileData* rootFolder, FileFilterIndex* index,
|
void addRandomGames(SystemData* newSys, SystemData* sourceSystem, FileData* rootFolder, FileFilterIndex* index,
|
||||||
|
|
|
@ -103,6 +103,11 @@ void SystemData::populateFolder(FileData* folder)
|
||||||
if(!showHidden && Utils::FileSystem::isHidden(filePath))
|
if(!showHidden && Utils::FileSystem::isHidden(filePath))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// skip ignored files and folders
|
||||||
|
std::string fileName = Utils::String::toLower(Utils::FileSystem::getFileName(filePath));
|
||||||
|
if(std::find(mEnvData->mFilesToIgnore.cbegin(), mEnvData->mFilesToIgnore.cend(), fileName) != mEnvData->mFilesToIgnore.cend())
|
||||||
|
continue;
|
||||||
|
|
||||||
//this is a little complicated because we allow a list of extensions to be defined (delimited with a space)
|
//this is a little complicated because we allow a list of extensions to be defined (delimited with a space)
|
||||||
//we first get the extension of the file itself:
|
//we first get the extension of the file itself:
|
||||||
extension = Utils::FileSystem::getExtension(filePath);
|
extension = Utils::FileSystem::getExtension(filePath);
|
||||||
|
@ -192,6 +197,27 @@ SystemData* SystemData::loadSystem(pugi::xml_node system)
|
||||||
extensions.push_back(xt);
|
extensions.push_back(xt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list.clear();
|
||||||
|
|
||||||
|
list = readList(system.child("ignore").text().get());
|
||||||
|
std::vector<std::string> ignores;
|
||||||
|
|
||||||
|
for (auto ignore = list.cbegin(); ignore != list.cend(); ignore++)
|
||||||
|
{
|
||||||
|
std::string ig = Utils::String::toLower(*ignore);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ig = Utils::String::replace(ig, "\"", "");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (std::find(ignores.begin(), ignores.end(), ig) == ignores.end())
|
||||||
|
ignores.push_back(ig);
|
||||||
|
}
|
||||||
|
|
||||||
|
list.clear();
|
||||||
|
|
||||||
cmd = system.child("command").text().get();
|
cmd = system.child("command").text().get();
|
||||||
|
|
||||||
// platform id list
|
// platform id list
|
||||||
|
@ -244,6 +270,7 @@ SystemData* SystemData::loadSystem(pugi::xml_node system)
|
||||||
SystemEnvironmentData* envData = new SystemEnvironmentData;
|
SystemEnvironmentData* envData = new SystemEnvironmentData;
|
||||||
envData->mStartPath = path;
|
envData->mStartPath = path;
|
||||||
envData->mSearchExtensions = extensions;
|
envData->mSearchExtensions = extensions;
|
||||||
|
envData->mFilesToIgnore = ignores;
|
||||||
envData->mLaunchCommand = cmd;
|
envData->mLaunchCommand = cmd;
|
||||||
envData->mPlatformIds = platformIds;
|
envData->mPlatformIds = platformIds;
|
||||||
|
|
||||||
|
@ -414,6 +441,10 @@ void SystemData::writeExampleConfig(const std::string& path)
|
||||||
" You MUST include the period at the start of the extension! It's also case sensitive. -->\n"
|
" You MUST include the period at the start of the extension! It's also case sensitive. -->\n"
|
||||||
" <extension>.nes .NES</extension>\n"
|
" <extension>.nes .NES</extension>\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
" <!-- A list of filenames to ignore, delimited by any of the whitespace characters (\", \\r\\n\\t\").\n"
|
||||||
|
" You MUST wrap each filename in double quotes (since some filenames contain spaces). Not case sensitive. -->\n"
|
||||||
|
" <ignore>\"filename1.bin\" \"filename2.iso\" \"filename3.zip\"</ignore>\n"
|
||||||
|
"\n"
|
||||||
" <!-- The shell command executed when a game is selected. A few special tags are replaced if found in a command:\n"
|
" <!-- The shell command executed when a game is selected. A few special tags are replaced if found in a command:\n"
|
||||||
" %ROM% is replaced by a bash-special-character-escaped absolute path to the ROM.\n"
|
" %ROM% is replaced by a bash-special-character-escaped absolute path to the ROM.\n"
|
||||||
" %BASENAME% is replaced by the \"base\" name of the ROM. For example, \"/foo/bar.rom\" would have a basename of \"bar\". Useful for MAME.\n"
|
" %BASENAME% is replaced by the \"base\" name of the ROM. For example, \"/foo/bar.rom\" would have a basename of \"bar\". Useful for MAME.\n"
|
||||||
|
|
|
@ -20,6 +20,7 @@ struct SystemEnvironmentData
|
||||||
{
|
{
|
||||||
std::string mStartPath;
|
std::string mStartPath;
|
||||||
std::vector<std::string> mSearchExtensions;
|
std::vector<std::string> mSearchExtensions;
|
||||||
|
std::vector<std::string> mFilesToIgnore;
|
||||||
std::string mLaunchCommand;
|
std::string mLaunchCommand;
|
||||||
std::vector<PlatformIds::PlatformId> mPlatformIds;
|
std::vector<PlatformIds::PlatformId> mPlatformIds;
|
||||||
};
|
};
|
||||||
|
@ -35,6 +36,7 @@ public:
|
||||||
inline const std::string& getFullName() const { return mFullName; }
|
inline const std::string& getFullName() const { return mFullName; }
|
||||||
inline const std::string& getStartPath() const { return mEnvData->mStartPath; }
|
inline const std::string& getStartPath() const { return mEnvData->mStartPath; }
|
||||||
inline const std::vector<std::string>& getExtensions() const { return mEnvData->mSearchExtensions; }
|
inline const std::vector<std::string>& getExtensions() const { return mEnvData->mSearchExtensions; }
|
||||||
|
inline const std::vector<std::string>& getFilesToIgnore() const { return mEnvData->mFilesToIgnore; }
|
||||||
inline const std::string& getThemeFolder() const { return mThemeFolder; }
|
inline const std::string& getThemeFolder() const { return mThemeFolder; }
|
||||||
inline SystemEnvironmentData* getSystemEnvData() const { return mEnvData; }
|
inline SystemEnvironmentData* getSystemEnvData() const { return mEnvData; }
|
||||||
inline const std::vector<PlatformIds::PlatformId>& getPlatformIds() const { return mEnvData->mPlatformIds; }
|
inline const std::vector<PlatformIds::PlatformId>& getPlatformIds() const { return mEnvData->mPlatformIds; }
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
#include "guis/GuiCollectionSystemsOptions.h"
|
#include "guis/GuiCollectionSystemsOptions.h"
|
||||||
|
|
||||||
#include "components/OptionListComponent.h"
|
#include "components/OptionListComponent.h"
|
||||||
#include "components/SwitchComponent.h"
|
#include "components/SwitchComponent.h"
|
||||||
|
#include "guis/GuiInfoPopup.h"
|
||||||
#include "guis/GuiRandomCollectionOptions.h"
|
#include "guis/GuiRandomCollectionOptions.h"
|
||||||
#include "guis/GuiSettings.h"
|
#include "guis/GuiSettings.h"
|
||||||
#include "guis/GuiTextEditPopup.h"
|
#include "guis/GuiTextEditPopup.h"
|
||||||
|
@ -25,49 +28,58 @@ void GuiCollectionSystemsOptions::initializeMenu()
|
||||||
// manage random collection
|
// manage random collection
|
||||||
addEntry("RANDOM GAME COLLECTION SETTINGS", 0x777777FF, true, [this] { openRandomCollectionSettings(); });
|
addEntry("RANDOM GAME COLLECTION SETTINGS", 0x777777FF, true, [this] { openRandomCollectionSettings(); });
|
||||||
|
|
||||||
// add "Create New Custom Collection from Theme"
|
|
||||||
std::vector<std::string> unusedFolders = CollectionSystemManager::get()->getUnusedSystemsFromTheme();
|
|
||||||
if (unusedFolders.size() > 0)
|
|
||||||
{
|
|
||||||
addEntry("CREATE NEW CUSTOM COLLECTION FROM THEME", 0x777777FF, true,
|
|
||||||
[this, unusedFolders] {
|
|
||||||
auto s = new GuiSettings(mWindow, "SELECT THEME FOLDER");
|
|
||||||
std::shared_ptr< OptionListComponent<std::string> > folderThemes = std::make_shared< OptionListComponent<std::string> >(mWindow, "SELECT THEME FOLDER", true);
|
|
||||||
|
|
||||||
// add Custom Systems
|
|
||||||
for(auto it = unusedFolders.cbegin() ; it != unusedFolders.cend() ; it++ )
|
|
||||||
{
|
|
||||||
ComponentListRow row;
|
|
||||||
std::string name = *it;
|
|
||||||
|
|
||||||
std::function<void()> createCollectionCall = [name, this, s] {
|
|
||||||
createCollection(name);
|
|
||||||
};
|
|
||||||
row.makeAcceptInputHandler(createCollectionCall);
|
|
||||||
|
|
||||||
auto themeFolder = std::make_shared<TextComponent>(mWindow, Utils::String::toUpper(name), Font::get(FONT_SIZE_SMALL), 0x777777FF);
|
|
||||||
row.addElement(themeFolder, true);
|
|
||||||
s->addRow(row);
|
|
||||||
}
|
|
||||||
mWindow->pushGui(s);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ComponentListRow row;
|
ComponentListRow row;
|
||||||
row.addElement(std::make_shared<TextComponent>(mWindow, "CREATE NEW CUSTOM COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
|
if(CollectionSystemManager::get()->isEditing())
|
||||||
auto createCustomCollection = [this](const std::string& newVal) {
|
{
|
||||||
std::string name = newVal;
|
row.addElement(std::make_shared<TextComponent>(mWindow, "FINISH EDITING '" + Utils::String::toUpper(CollectionSystemManager::get()->getEditingCollection()) + "' COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
|
||||||
// we need to store the first Gui and remove it, as it'll be deleted by the actual Gui
|
row.makeAcceptInputHandler(std::bind(&GuiCollectionSystemsOptions::exitEditMode, this));
|
||||||
Window* window = mWindow;
|
mMenu.addRow(row);
|
||||||
GuiComponent* topGui = window->peekGui();
|
}
|
||||||
window->removeGui(topGui);
|
else
|
||||||
createCollection(name);
|
{
|
||||||
};
|
// add "Create New Custom Collection from Theme"
|
||||||
row.makeAcceptInputHandler([this, createCustomCollection] {
|
std::vector<std::string> unusedFolders = CollectionSystemManager::get()->getUnusedSystemsFromTheme();
|
||||||
mWindow->pushGui(new GuiTextEditPopup(mWindow, "New Collection Name", "", createCustomCollection, false));
|
if (unusedFolders.size() > 0)
|
||||||
});
|
{
|
||||||
|
addEntry("CREATE NEW CUSTOM COLLECTION FROM THEME", 0x777777FF, true,
|
||||||
|
[this, unusedFolders] {
|
||||||
|
auto s = new GuiSettings(mWindow, "SELECT THEME FOLDER");
|
||||||
|
std::shared_ptr< OptionListComponent<std::string> > folderThemes = std::make_shared< OptionListComponent<std::string> >(mWindow, "SELECT THEME FOLDER", true);
|
||||||
|
|
||||||
mMenu.addRow(row);
|
// add Custom Systems
|
||||||
|
for(auto it = unusedFolders.cbegin() ; it != unusedFolders.cend() ; it++ )
|
||||||
|
{
|
||||||
|
ComponentListRow row;
|
||||||
|
std::string name = *it;
|
||||||
|
|
||||||
|
std::function<void()> createCollectionCall = [name, this, s] {
|
||||||
|
createCollection(name);
|
||||||
|
};
|
||||||
|
row.makeAcceptInputHandler(createCollectionCall);
|
||||||
|
|
||||||
|
auto themeFolder = std::make_shared<TextComponent>(mWindow, Utils::String::toUpper(name), Font::get(FONT_SIZE_SMALL), 0x777777FF);
|
||||||
|
row.addElement(themeFolder, true);
|
||||||
|
s->addRow(row);
|
||||||
|
}
|
||||||
|
mWindow->pushGui(s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
row.addElement(std::make_shared<TextComponent>(mWindow, "CREATE NEW CUSTOM COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
|
||||||
|
auto createCustomCollection = [this](const std::string& newVal) {
|
||||||
|
std::string name = newVal;
|
||||||
|
// we need to store the first Gui and remove it, as it'll be deleted by the actual Gui
|
||||||
|
Window* window = mWindow;
|
||||||
|
GuiComponent* topGui = window->peekGui();
|
||||||
|
window->removeGui(topGui);
|
||||||
|
createCollection(name);
|
||||||
|
};
|
||||||
|
row.makeAcceptInputHandler([this, createCustomCollection] {
|
||||||
|
mWindow->pushGui(new GuiTextEditPopup(mWindow, "New Collection Name", "", createCustomCollection, false));
|
||||||
|
});
|
||||||
|
mMenu.addRow(row);
|
||||||
|
}
|
||||||
|
|
||||||
bundleCustomCollections = std::make_shared<SwitchComponent>(mWindow);
|
bundleCustomCollections = std::make_shared<SwitchComponent>(mWindow);
|
||||||
bundleCustomCollections->setState(Settings::getInstance()->getBool("UseCustomCollectionsSystem"));
|
bundleCustomCollections->setState(Settings::getInstance()->getBool("UseCustomCollectionsSystem"));
|
||||||
|
@ -103,14 +115,6 @@ void GuiCollectionSystemsOptions::initializeMenu()
|
||||||
|
|
||||||
mMenu.addWithLabel("ADD/REMOVE GAMES WHILE SCREENSAVER TO", defaultScreenSaverCollection);
|
mMenu.addWithLabel("ADD/REMOVE GAMES WHILE SCREENSAVER TO", defaultScreenSaverCollection);
|
||||||
|
|
||||||
if(CollectionSystemManager::get()->isEditing())
|
|
||||||
{
|
|
||||||
row.elements.clear();
|
|
||||||
row.addElement(std::make_shared<TextComponent>(mWindow, "FINISH EDITING '" + Utils::String::toUpper(CollectionSystemManager::get()->getEditingCollection()) + "' COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
|
|
||||||
row.makeAcceptInputHandler(std::bind(&GuiCollectionSystemsOptions::exitEditMode, this));
|
|
||||||
mMenu.addRow(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
mMenu.addButton("BACK", "back", std::bind(&GuiCollectionSystemsOptions::applySettings, this));
|
mMenu.addButton("BACK", "back", std::bind(&GuiCollectionSystemsOptions::applySettings, this));
|
||||||
|
|
||||||
mMenu.setPosition((Renderer::getScreenWidth() - mMenu.getSize().x()) / 2, Renderer::getScreenHeight() * 0.15f);
|
mMenu.setPosition((Renderer::getScreenWidth() - mMenu.getSize().x()) / 2, Renderer::getScreenHeight() * 0.15f);
|
||||||
|
@ -137,8 +141,15 @@ void GuiCollectionSystemsOptions::addEntry(const char* name, unsigned int color,
|
||||||
|
|
||||||
void GuiCollectionSystemsOptions::createCollection(std::string inName)
|
void GuiCollectionSystemsOptions::createCollection(std::string inName)
|
||||||
{
|
{
|
||||||
std::string name = CollectionSystemManager::get()->getValidNewCollectionName(inName);
|
CollectionSystemManager* collSysMgr = CollectionSystemManager::get();
|
||||||
SystemData* newSys = CollectionSystemManager::get()->addNewCustomCollection(name);
|
std::string name = collSysMgr->getValidNewCollectionName(inName);
|
||||||
|
|
||||||
|
SystemData* newSys = collSysMgr->addNewCustomCollection(name, true);
|
||||||
|
if (!collSysMgr->saveCustomCollection(newSys)) {
|
||||||
|
GuiInfoPopup* s = new GuiInfoPopup(mWindow, "Failed creating '" + Utils::String::toUpper(name) + "' Collection. See log for details.", 8000);
|
||||||
|
mWindow->setInfoPopup(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
customOptionList->add(name, name, true);
|
customOptionList->add(name, name, true);
|
||||||
std::string outAuto = Utils::String::vectorToDelimitedString(autoOptionList->getSelectedObjects(), ",");
|
std::string outAuto = Utils::String::vectorToDelimitedString(autoOptionList->getSelectedObjects(), ",");
|
||||||
std::string outCustom = Utils::String::vectorToDelimitedString(customOptionList->getSelectedObjects(), ",");
|
std::string outCustom = Utils::String::vectorToDelimitedString(customOptionList->getSelectedObjects(), ",");
|
||||||
|
@ -146,10 +157,9 @@ void GuiCollectionSystemsOptions::createCollection(std::string inName)
|
||||||
ViewController::get()->goToSystemView(newSys);
|
ViewController::get()->goToSystemView(newSys);
|
||||||
|
|
||||||
Window* window = mWindow;
|
Window* window = mWindow;
|
||||||
CollectionSystemManager::get()->setEditMode(name);
|
collSysMgr->setEditMode(name);
|
||||||
while(window->peekGui() && window->peekGui() != ViewController::get())
|
while(window->peekGui() && window->peekGui() != ViewController::get())
|
||||||
delete window->peekGui();
|
delete window->peekGui();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiCollectionSystemsOptions::openRandomCollectionSettings()
|
void GuiCollectionSystemsOptions::openRandomCollectionSettings()
|
||||||
|
|
|
@ -66,10 +66,14 @@ void BasicGameListView::setCursor(FileData* cursor, bool refreshListCursorPos)
|
||||||
if (refreshListCursorPos)
|
if (refreshListCursorPos)
|
||||||
setViewportTop(mList.REFRESH_LIST_CURSOR_POS);
|
setViewportTop(mList.REFRESH_LIST_CURSOR_POS);
|
||||||
|
|
||||||
if(!mList.setCursor(cursor) && (!cursor->isPlaceHolder()))
|
bool notInList = !mList.setCursor(cursor);
|
||||||
|
if(!refreshListCursorPos && notInList && !cursor->isPlaceHolder())
|
||||||
{
|
{
|
||||||
populateList(cursor->getParent()->getChildrenListToDisplay());
|
populateList(cursor->getParent()->getChildrenListToDisplay());
|
||||||
mList.setCursor(cursor);
|
// this extra call is needed iff a system has games organized in folders
|
||||||
|
// and the cursor is focusing a game in a folder
|
||||||
|
if (cursor->getParent()->getType() == FOLDER)
|
||||||
|
mList.setCursor(cursor);
|
||||||
|
|
||||||
// update our cursor stack in case our cursor just got set to some folder we weren't in before
|
// update our cursor stack in case our cursor just got set to some folder we weren't in before
|
||||||
if(mCursorStack.empty() || mCursorStack.top() != cursor->getParent())
|
if(mCursorStack.empty() || mCursorStack.top() != cursor->getParent())
|
||||||
|
|
Loading…
Add table
Reference in a new issue