2020-09-21 17:17:34 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
2020-06-22 15:27:53 +00:00
|
|
|
//
|
2020-09-21 17:17:34 +00:00
|
|
|
// EmulationStation Desktop Edition
|
2020-06-22 15:27:53 +00:00
|
|
|
// GuiCollectionSystemsOptions.cpp
|
|
|
|
//
|
|
|
|
// User interface for the game collection settings.
|
2020-06-28 16:39:18 +00:00
|
|
|
// Submenu to the GuiMenu main menu.
|
2020-06-22 15:27:53 +00:00
|
|
|
//
|
|
|
|
|
2017-06-12 16:38:59 +00:00
|
|
|
#include "guis/GuiCollectionSystemsOptions.h"
|
|
|
|
|
|
|
|
#include "components/OptionListComponent.h"
|
2017-11-01 22:21:10 +00:00
|
|
|
#include "components/SwitchComponent.h"
|
2020-11-09 16:50:02 +00:00
|
|
|
#include "guis/GuiMsgBox.h"
|
2017-11-01 22:21:10 +00:00
|
|
|
#include "guis/GuiSettings.h"
|
|
|
|
#include "guis/GuiTextEditPopup.h"
|
|
|
|
#include "views/ViewController.h"
|
2020-12-23 17:06:30 +00:00
|
|
|
#include "CollectionSystemsManager.h"
|
2017-06-12 16:38:59 +00:00
|
|
|
|
2020-11-09 16:50:02 +00:00
|
|
|
GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(
|
|
|
|
Window* window,
|
|
|
|
std::string title)
|
|
|
|
: GuiSettings(window, title),
|
|
|
|
mAddedCustomCollection(false),
|
|
|
|
mDeletedCustomCollection(false)
|
2017-06-12 16:38:59 +00:00
|
|
|
{
|
2020-11-06 19:27:41 +00:00
|
|
|
// Finish editing custom collection.
|
2020-12-23 17:06:30 +00:00
|
|
|
if (CollectionSystemsManager::get()->isEditing()) {
|
2020-11-06 19:27:41 +00:00
|
|
|
ComponentListRow row;
|
|
|
|
row.addElement(std::make_shared<TextComponent>(mWindow, "FINISH EDITING '" +
|
2020-12-23 17:06:30 +00:00
|
|
|
Utils::String::toUpper(CollectionSystemsManager::get()->getEditingCollection()) +
|
2020-11-06 19:27:41 +00:00
|
|
|
"' COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF), true);
|
|
|
|
row.makeAcceptInputHandler([this] {
|
2020-12-23 17:06:30 +00:00
|
|
|
CollectionSystemsManager::get()->exitEditMode();
|
2020-12-31 15:40:08 +00:00
|
|
|
mWindow->invalidateCachedBackground();
|
2020-11-06 19:27:41 +00:00
|
|
|
delete this;
|
|
|
|
});
|
|
|
|
addRow(row);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Automatic collections.
|
|
|
|
collection_systems_auto = std::make_shared<OptionListComponent<std::string>>
|
|
|
|
(mWindow, getHelpStyle(), "SELECT COLLECTIONS", true);
|
|
|
|
std::map<std::string, CollectionSystemData, stringComparator> autoSystems =
|
2020-12-23 17:06:30 +00:00
|
|
|
CollectionSystemsManager::get()->getAutoCollectionSystems();
|
2020-11-06 19:27:41 +00:00
|
|
|
// Add automatic systems.
|
|
|
|
for (std::map<std::string, CollectionSystemData, stringComparator>::const_iterator
|
|
|
|
it = autoSystems.cbegin(); it != autoSystems.cend() ; it++)
|
|
|
|
collection_systems_auto->add(it->second.decl.longName, it->second.decl.name,
|
|
|
|
it->second.isEnabled);
|
|
|
|
addWithLabel("AUTOMATIC GAME COLLECTIONS", collection_systems_auto);
|
|
|
|
addSaveFunc([this] {
|
|
|
|
std::string autoSystemsSelected =
|
|
|
|
Utils::String::vectorToCommaString(collection_systems_auto->getSelectedObjects(), true);
|
|
|
|
std::string autoSystemsConfig = Settings::getInstance()->getString("CollectionSystemsAuto");
|
|
|
|
if (autoSystemsSelected != autoSystemsConfig) {
|
2020-12-23 17:06:30 +00:00
|
|
|
if (CollectionSystemsManager::get()->isEditing())
|
|
|
|
CollectionSystemsManager::get()->exitEditMode();
|
2020-11-06 19:27:41 +00:00
|
|
|
Settings::getInstance()->setString("CollectionSystemsAuto", autoSystemsSelected);
|
|
|
|
setNeedsSaving();
|
|
|
|
setNeedsReloading();
|
|
|
|
setNeedsCollectionsUpdate();
|
|
|
|
if (!mAddedCustomCollection)
|
|
|
|
setNeedsGoToSystemView(SystemData::sSystemVector.front());
|
|
|
|
}
|
|
|
|
});
|
2020-06-22 15:27:53 +00:00
|
|
|
|
2020-11-06 19:27:41 +00:00
|
|
|
// Custom collections.
|
|
|
|
collection_systems_custom = std::make_shared<OptionListComponent<std::string>>
|
|
|
|
(mWindow, getHelpStyle(), "SELECT COLLECTIONS", true);
|
|
|
|
std::map<std::string, CollectionSystemData, stringComparator> customSystems =
|
2020-12-23 17:06:30 +00:00
|
|
|
CollectionSystemsManager::get()->getCustomCollectionSystems();
|
2020-11-06 19:27:41 +00:00
|
|
|
// Add custom systems.
|
|
|
|
for (std::map<std::string, CollectionSystemData, stringComparator>::const_iterator
|
|
|
|
it = customSystems.cbegin(); it != customSystems.cend() ; it++)
|
|
|
|
collection_systems_custom->add(it->second.decl.longName, it->second.decl.name,
|
|
|
|
it->second.isEnabled);
|
|
|
|
addWithLabel("CUSTOM GAME COLLECTIONS", collection_systems_custom);
|
|
|
|
addSaveFunc([this] {
|
2020-11-09 16:50:02 +00:00
|
|
|
if (!mDeletedCustomCollection) {
|
|
|
|
std::string customSystemsSelected = Utils::String::vectorToCommaString(
|
|
|
|
collection_systems_custom->getSelectedObjects(), true);
|
|
|
|
std::string customSystemsConfig = Settings::getInstance()->
|
|
|
|
getString("CollectionSystemsCustom");
|
|
|
|
if (customSystemsSelected != customSystemsConfig) {
|
2020-12-23 17:06:30 +00:00
|
|
|
if (CollectionSystemsManager::get()->isEditing())
|
|
|
|
CollectionSystemsManager::get()->exitEditMode();
|
2020-11-09 16:50:02 +00:00
|
|
|
Settings::getInstance()->setString("CollectionSystemsCustom",
|
|
|
|
customSystemsSelected);
|
|
|
|
setNeedsSaving();
|
|
|
|
setNeedsReloading();
|
|
|
|
setNeedsCollectionsUpdate();
|
|
|
|
if (!mAddedCustomCollection)
|
|
|
|
setNeedsGoToSystemView(SystemData::sSystemVector.front());
|
|
|
|
}
|
2020-11-06 19:27:41 +00:00
|
|
|
}
|
|
|
|
});
|
2020-06-22 15:27:53 +00:00
|
|
|
|
2020-11-06 19:27:41 +00:00
|
|
|
// Create custom collection from theme.
|
2020-06-22 15:27:53 +00:00
|
|
|
std::vector<std::string> unusedFolders =
|
2020-12-23 17:06:30 +00:00
|
|
|
CollectionSystemsManager::get()->getUnusedSystemsFromTheme();
|
2020-06-22 15:27:53 +00:00
|
|
|
if (unusedFolders.size() > 0) {
|
2020-11-06 19:27:41 +00:00
|
|
|
ComponentListRow row;
|
|
|
|
auto themeCollection = std::make_shared<TextComponent>(mWindow,
|
|
|
|
"CREATE NEW CUSTOM COLLECTION FROM THEME", Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
|
|
|
|
auto bracketThemeCollection = std::make_shared<ImageComponent>(mWindow);
|
|
|
|
bracketThemeCollection->setImage(":/graphics/arrow.svg");
|
|
|
|
bracketThemeCollection->setResize(Vector2f(0,
|
|
|
|
Font::get(FONT_SIZE_MEDIUM)->getLetterHeight()));
|
|
|
|
row.addElement(themeCollection, true);
|
|
|
|
row.addElement(bracketThemeCollection, false);
|
|
|
|
row.makeAcceptInputHandler([this, unusedFolders] {
|
|
|
|
auto ss = new GuiSettings(mWindow, "SELECT THEME FOLDER");
|
|
|
|
std::shared_ptr<OptionListComponent<std::string>> folderThemes =
|
|
|
|
std::make_shared<OptionListComponent<std::string>>(mWindow,
|
|
|
|
getHelpStyle(), "SELECT THEME FOLDER", true);
|
2020-06-22 15:27:53 +00:00
|
|
|
// Add custom systems.
|
2020-07-13 18:58:25 +00:00
|
|
|
for (auto it = unusedFolders.cbegin() ; it != unusedFolders.cend() ; it++ ) {
|
2020-06-22 15:27:53 +00:00
|
|
|
ComponentListRow row;
|
|
|
|
std::string name = *it;
|
2020-11-06 19:27:41 +00:00
|
|
|
std::function<void()> createCollectionCall = [this, name] {
|
|
|
|
createCustomCollection(name);
|
2020-06-22 15:27:53 +00:00
|
|
|
};
|
|
|
|
row.makeAcceptInputHandler(createCollectionCall);
|
|
|
|
auto themeFolder = std::make_shared<TextComponent>(mWindow,
|
|
|
|
Utils::String::toUpper(name), Font::get(FONT_SIZE_SMALL), 0x777777FF);
|
|
|
|
row.addElement(themeFolder, true);
|
2020-11-09 16:50:02 +00:00
|
|
|
// This transparent bracket is only added to generate the correct help prompts.
|
|
|
|
auto bracket = std::make_shared<ImageComponent>(mWindow);
|
|
|
|
bracket->setImage(":/graphics/arrow.svg");
|
|
|
|
bracket->setOpacity(0);
|
|
|
|
row.addElement(bracket, false);
|
2020-11-06 19:27:41 +00:00
|
|
|
ss->addRow(row);
|
2020-06-22 15:27:53 +00:00
|
|
|
}
|
2020-11-06 19:27:41 +00:00
|
|
|
mWindow->pushGui(ss);
|
2020-06-22 15:27:53 +00:00
|
|
|
});
|
2020-11-06 19:27:41 +00:00
|
|
|
addRow(row);
|
2020-06-22 15:27:53 +00:00
|
|
|
}
|
|
|
|
|
2020-11-06 19:27:41 +00:00
|
|
|
// Create new custom collection.
|
2020-06-22 15:27:53 +00:00
|
|
|
ComponentListRow row;
|
2020-11-06 19:27:41 +00:00
|
|
|
auto newCollection = std::make_shared<TextComponent>(mWindow,
|
|
|
|
"CREATE NEW CUSTOM COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
|
|
|
|
auto bracketNewCollection = std::make_shared<ImageComponent>(mWindow);
|
|
|
|
bracketNewCollection->setImage(":/graphics/arrow.svg");
|
|
|
|
bracketNewCollection->setResize(Vector2f(0,
|
|
|
|
Font::get(FONT_SIZE_MEDIUM)->getLetterHeight()));
|
|
|
|
row.addElement(newCollection, true);
|
|
|
|
row.addElement(bracketNewCollection, false);
|
|
|
|
auto createCollectionCall = [this](const std::string& newVal) {
|
2020-06-22 15:27:53 +00:00
|
|
|
std::string name = newVal;
|
2020-11-06 19:27:41 +00:00
|
|
|
// We need to store the first GUI and remove it, as it'll be deleted
|
|
|
|
// by the actual GUI.
|
2020-06-22 15:27:53 +00:00
|
|
|
Window* window = mWindow;
|
|
|
|
GuiComponent* topGui = window->peekGui();
|
|
|
|
window->removeGui(topGui);
|
2020-11-06 19:27:41 +00:00
|
|
|
createCustomCollection(name);
|
2020-06-22 15:27:53 +00:00
|
|
|
};
|
2020-11-06 19:27:41 +00:00
|
|
|
row.makeAcceptInputHandler([this, createCollectionCall] {
|
2020-06-22 15:27:53 +00:00
|
|
|
mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(),
|
2020-11-06 19:27:41 +00:00
|
|
|
"New Collection Name", "", createCollectionCall, false, "SAVE"));
|
|
|
|
});
|
|
|
|
addRow(row);
|
|
|
|
|
2020-11-09 16:50:02 +00:00
|
|
|
// Delete custom collection.
|
|
|
|
row.elements.clear();
|
|
|
|
auto deleteCollection = std::make_shared<TextComponent>(mWindow,
|
|
|
|
"DELETE CUSTOM COLLECTION", Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
|
|
|
|
auto bracketDeleteCollection = std::make_shared<ImageComponent>(mWindow);
|
|
|
|
bracketDeleteCollection->setImage(":/graphics/arrow.svg");
|
|
|
|
bracketDeleteCollection->setResize(Vector2f(0,
|
|
|
|
Font::get(FONT_SIZE_MEDIUM)->getLetterHeight()));
|
|
|
|
row.addElement(deleteCollection, true);
|
|
|
|
row.addElement(bracketDeleteCollection, false);
|
|
|
|
row.makeAcceptInputHandler([this, customSystems] {
|
|
|
|
auto ss = new GuiSettings(mWindow, "SELECT COLLECTION TO DELETE");
|
|
|
|
std::shared_ptr<OptionListComponent<std::string>> customCollections =
|
|
|
|
std::make_shared<OptionListComponent<std::string>>(mWindow,
|
|
|
|
getHelpStyle(), "", true);
|
|
|
|
for (std::map<std::string, CollectionSystemData, stringComparator>::const_iterator
|
|
|
|
it = customSystems.cbegin(); it != customSystems.cend() ; it++) {
|
|
|
|
ComponentListRow row;
|
|
|
|
std::string name = (*it).first;
|
|
|
|
std::function<void()> deleteCollectionCall = [this, name] {
|
|
|
|
mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(),
|
|
|
|
"THIS WILL PERMANENTLY\nDELETE THE COLLECTION\n'" +
|
2020-11-09 23:02:09 +00:00
|
|
|
Utils::String::toUpper(name) + "'\n"
|
2020-11-09 16:50:02 +00:00
|
|
|
"ARE YOU SURE?",
|
|
|
|
"YES", [this, name] {
|
2020-12-23 17:06:30 +00:00
|
|
|
if (CollectionSystemsManager::get()->isEditing())
|
|
|
|
CollectionSystemsManager::get()->exitEditMode();
|
2020-11-09 16:50:02 +00:00
|
|
|
mDeletedCustomCollection = true;
|
|
|
|
std::vector<std::string> selectedCustomCollections =
|
|
|
|
collection_systems_custom->getSelectedObjects();
|
|
|
|
std::string collectionsConfigEntry;
|
|
|
|
// Create the configuration file entry. If the collection to be
|
|
|
|
// deleted was activated, then exclude it.
|
|
|
|
for (auto it = selectedCustomCollections.begin();
|
|
|
|
it != selectedCustomCollections.end(); it++) {
|
|
|
|
if ((*it) != name) {
|
|
|
|
if ((*it) != selectedCustomCollections.front() &&
|
|
|
|
collectionsConfigEntry != "")
|
|
|
|
collectionsConfigEntry += ",";
|
|
|
|
collectionsConfigEntry += (*it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// If the system to be deleted was present in es_settings.cfg, we
|
|
|
|
// need to re-write it.
|
|
|
|
if (collectionsConfigEntry !=
|
|
|
|
Settings::getInstance()->getString("CollectionSystemsCustom")) {
|
|
|
|
Settings::getInstance()->setString("CollectionSystemsCustom",
|
|
|
|
collectionsConfigEntry);
|
|
|
|
setNeedsSaving();
|
|
|
|
setNeedsGoToSystemView(SystemData::sSystemVector.front());
|
|
|
|
}
|
2020-12-23 17:06:30 +00:00
|
|
|
CollectionSystemsManager::get()->deleteCustomCollection(name);
|
2020-11-09 16:50:02 +00:00
|
|
|
return true;
|
|
|
|
},
|
|
|
|
"NO", [this] {
|
|
|
|
return false;
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
row.makeAcceptInputHandler(deleteCollectionCall);
|
|
|
|
auto customCollection = std::make_shared<TextComponent>(mWindow,
|
|
|
|
Utils::String::toUpper(name), Font::get(FONT_SIZE_SMALL), 0x777777FF);
|
|
|
|
row.addElement(customCollection, true);
|
|
|
|
// This transparent bracket is only added generate the correct help prompts.
|
|
|
|
auto bracket = std::make_shared<ImageComponent>(mWindow);
|
|
|
|
bracket->setImage(":/graphics/arrow.svg");
|
|
|
|
bracket->setOpacity(0);
|
|
|
|
row.addElement(bracket, false);
|
|
|
|
ss->addRow(row);
|
|
|
|
}
|
|
|
|
mWindow->pushGui(ss);
|
|
|
|
});
|
|
|
|
addRow(row);
|
|
|
|
|
2020-11-06 19:27:41 +00:00
|
|
|
// Sort favorites on top for custom collections.
|
|
|
|
auto fav_first_custom = std::make_shared<SwitchComponent>(mWindow);
|
|
|
|
fav_first_custom->setState(Settings::getInstance()->getBool("FavFirstCustom"));
|
|
|
|
addWithLabel("SORT FAVORITES ON TOP FOR CUSTOM COLLECTIONS", fav_first_custom);
|
|
|
|
addSaveFunc([this, fav_first_custom] {
|
|
|
|
if (fav_first_custom->getState() != Settings::getInstance()->getBool("FavFirstCustom")) {
|
|
|
|
Settings::getInstance()->setBool("FavFirstCustom", fav_first_custom->getState());
|
|
|
|
setNeedsSaving();
|
|
|
|
setNeedsReloading();
|
|
|
|
setNeedsSorting();
|
|
|
|
setNeedsSortingCollections();
|
|
|
|
}
|
2020-06-22 15:27:53 +00:00
|
|
|
});
|
|
|
|
|
2020-11-06 19:27:41 +00:00
|
|
|
// Display star markings for custom collections.
|
|
|
|
auto fav_star_custom = std::make_shared<SwitchComponent>(mWindow);
|
|
|
|
fav_star_custom->setState(Settings::getInstance()->getBool("FavStarCustom"));
|
|
|
|
addWithLabel("DISPLAY STAR MARKINGS FOR CUSTOM COLLECTIONS", fav_star_custom);
|
|
|
|
addSaveFunc([this, fav_star_custom] {
|
|
|
|
if (fav_star_custom->getState() != Settings::getInstance()->getBool("FavStarCustom")) {
|
|
|
|
Settings::getInstance()->setBool("FavStarCustom", fav_star_custom->getState());
|
|
|
|
setNeedsSaving();
|
|
|
|
setNeedsReloading();
|
|
|
|
}
|
|
|
|
});
|
2020-10-25 20:29:54 +00:00
|
|
|
|
2020-11-06 19:27:41 +00:00
|
|
|
// Group unthemed custom collections.
|
|
|
|
auto use_custom_collections_system = std::make_shared<SwitchComponent>(mWindow);
|
|
|
|
use_custom_collections_system->setState(Settings::getInstance()->
|
2020-06-22 15:27:53 +00:00
|
|
|
getBool("UseCustomCollectionsSystem"));
|
2020-11-06 19:27:41 +00:00
|
|
|
addWithLabel("GROUP UNTHEMED CUSTOM COLLECTIONS", use_custom_collections_system);
|
|
|
|
addSaveFunc([this, use_custom_collections_system] {
|
|
|
|
if (use_custom_collections_system->getState() !=
|
|
|
|
Settings::getInstance()->getBool("UseCustomCollectionsSystem")) {
|
|
|
|
Settings::getInstance()->setBool("UseCustomCollectionsSystem",
|
|
|
|
use_custom_collections_system->getState());
|
|
|
|
setNeedsSaving();
|
|
|
|
setNeedsCollectionsUpdate();
|
|
|
|
setNeedsReloading();
|
|
|
|
setNeedsGoToSystemView(SystemData::sSystemVector.front());
|
|
|
|
}
|
|
|
|
});
|
2020-06-22 15:27:53 +00:00
|
|
|
|
2020-11-06 19:27:41 +00:00
|
|
|
// Show system names in collections.
|
|
|
|
auto collection_show_system_info = std::make_shared<SwitchComponent>(mWindow);
|
|
|
|
collection_show_system_info->setState(Settings::getInstance()->
|
2020-06-22 15:27:53 +00:00
|
|
|
getBool("CollectionShowSystemInfo"));
|
2020-11-06 19:27:41 +00:00
|
|
|
addWithLabel("SHOW SYSTEM NAMES IN COLLECTIONS", collection_show_system_info);
|
|
|
|
addSaveFunc([this, collection_show_system_info] {
|
|
|
|
if (collection_show_system_info->getState() !=
|
|
|
|
Settings::getInstance()->getBool("CollectionShowSystemInfo")) {
|
|
|
|
Settings::getInstance()->setBool("CollectionShowSystemInfo",
|
|
|
|
collection_show_system_info->getState());
|
|
|
|
setNeedsSaving();
|
|
|
|
setNeedsReloading();
|
|
|
|
}
|
|
|
|
});
|
2017-06-12 16:38:59 +00:00
|
|
|
}
|
|
|
|
|
2020-11-06 19:27:41 +00:00
|
|
|
void GuiCollectionSystemsOptions::createCustomCollection(std::string inName)
|
2017-07-18 09:45:50 +00:00
|
|
|
{
|
2020-12-23 17:06:30 +00:00
|
|
|
if (CollectionSystemsManager::get()->isEditing())
|
|
|
|
CollectionSystemsManager::get()->exitEditMode();
|
2017-07-18 09:45:50 +00:00
|
|
|
|
2020-12-23 17:06:30 +00:00
|
|
|
std::string collectionName = CollectionSystemsManager::get()->
|
2020-11-06 19:27:41 +00:00
|
|
|
getValidNewCollectionName(inName);
|
2020-12-23 17:06:30 +00:00
|
|
|
SystemData* newCollection = CollectionSystemsManager::get()->
|
2020-11-06 19:27:41 +00:00
|
|
|
addNewCustomCollection(collectionName);
|
2017-07-18 09:45:50 +00:00
|
|
|
|
2020-12-23 17:06:30 +00:00
|
|
|
CollectionSystemsManager::get()->saveCustomCollection(newCollection);
|
2020-11-06 19:27:41 +00:00
|
|
|
collection_systems_custom->add(collectionName, collectionName, true);
|
2017-07-18 09:45:50 +00:00
|
|
|
|
2020-11-06 19:27:41 +00:00
|
|
|
mAddedCustomCollection = true;
|
|
|
|
setNeedsGoToSystemView(newCollection);
|
2020-06-22 15:27:53 +00:00
|
|
|
|
|
|
|
Window* window = mWindow;
|
2020-07-13 18:58:25 +00:00
|
|
|
while (window->peekGui() && window->peekGui() != ViewController::get())
|
2020-06-22 15:27:53 +00:00
|
|
|
delete window->peekGui();
|
2020-12-23 17:06:30 +00:00
|
|
|
CollectionSystemsManager::get()->setEditMode(collectionName);
|
2020-06-07 18:09:02 +00:00
|
|
|
}
|