Added a menu entry and functionality to delete custom collections.

This commit is contained in:
Leon Styhre 2020-11-09 17:50:02 +01:00
parent 2c3b452401
commit f17bf43d4f
8 changed files with 156 additions and 29 deletions

View file

@ -641,7 +641,7 @@ Whether to sort your favorite games above your other games in the gamelists.
With this setting enabled, there is a star symbol added at the beginning of the game name in the gamelist views. It's strongly recommended to keep this setting enabled if the option to sort favorite games above non-favorites has been enabled. If not, favorite games would be sorted on top of the gamelist with no visual indication that they are favorites, which would be very confusing. With this setting enabled, there is a star symbol added at the beginning of the game name in the gamelist views. It's strongly recommended to keep this setting enabled if the option to sort favorite games above non-favorites has been enabled. If not, favorite games would be sorted on top of the gamelist with no visual indication that they are favorites, which would be very confusing.
**Enable button shortcut to toggle favorites** **Enable shortcut to toggle favorites**
This setting enables the 'Y' button for quickly toggling a game as favorite. Although this may be convenient at times, it's also quite easy to accidentally remove a favorite tagging of a game when using the application more casually. As such it could sometimes make sense to disable this functionality. It's of course still possible to mark a game as favorite using the metadata editor when this setting is disabled. For additional restrictions, the application can be set to Kid or Kiosk mode as is explained elsewhere in this document. Note that this setting does not affect the functionality to use the 'Y' button to add games to custom collections. This setting enables the 'Y' button for quickly toggling a game as favorite. Although this may be convenient at times, it's also quite easy to accidentally remove a favorite tagging of a game when using the application more casually. As such it could sometimes make sense to disable this functionality. It's of course still possible to mark a game as favorite using the metadata editor when this setting is disabled. For additional restrictions, the application can be set to Kid or Kiosk mode as is explained elsewhere in this document. Note that this setting does not affect the functionality to use the 'Y' button to add games to custom collections.
@ -763,6 +763,10 @@ Enable or disable navigation sounds throughout the application. Sounds are playe
Handles collections, which are built using the games already present for your game systems. _(Details on how this works are discussed later in this guide.)_ Handles collections, which are built using the games already present for your game systems. _(Details on how this works are discussed later in this guide.)_
**Finish editing _'COLLECTION NAME'_ collection**
Self explanatory. This menu entry is only visible when editing a collection.
**Automatic game collections** **Automatic game collections**
This opens a screen that lets you enable or disable the automatic game collections _All games_, _Favorites_ and _Last played_. This opens a screen that lets you enable or disable the automatic game collections _All games_, _Favorites_ and _Last played_.
@ -773,12 +777,16 @@ This lets you create your own custom game collections.
**Create new custom collection from theme** **Create new custom collection from theme**
If the theme set in use provides themes for custom collections, then this can be selected here. For example, there could be themes for _"Fighting games"_ or _"Driving games"_ etc. As of version 1.0.0, the default rbsimple-DE theme set does not provides such themes for custom collections. If the theme set in use provides themes for custom collections, then this entry can be selected here. For example, there could be themes for _"Fighting games"_ or _"Driving games"_ etc. The default rbsimple-DE theme set does not provide such themes for custom collections and in general it's not recommended to use this approach, as is explained [later](USERGUIDE.md#custom-collections) in this guide. This menu entry is not visible if the theme does not have any available themes to use for custom collections.
**Create new custom collection** **Create new custom collection**
This lets you create a completely custom collection with a name that you choose. This lets you create a completely custom collection with a name that you choose.
**Delete custom collection**
This permanently deletes a custom collection, including its configuration file on the file system. A list of available collections is shown, and a confirmation dialog is displayed before committing the actual deletion. Only one collection at a time can be deleted.
**Sort favorites on top for custom collections** **Sort favorites on top for custom collections**
Whether to sort your favorite games above your other games. This is disabled by default, as for collections you probably want to be able to mix all games regardless of whether they are favorites or not. Whether to sort your favorite games above your other games. This is disabled by default, as for collections you probably want to be able to mix all games regardless of whether they are favorites or not.
@ -930,6 +938,10 @@ This opens the metadata editor, which will be described in detail below.
This is only shown if the system is a collection. This will also be described in more detail below. This is only shown if the system is a collection. This will also be described in more detail below.
### Finish editing _'COLLECTION NAME'_ collection
This menu entry is only visible when editing the collection.
## Metadata editor ## Metadata editor

View file

@ -857,6 +857,42 @@ SystemData* CollectionSystemManager::addNewCustomCollection(std::string name)
return createNewCollectionEntry(name, decl, true, true); return createNewCollectionEntry(name, decl, true, true);
} }
void CollectionSystemManager::deleteCustomCollection(std::string collectionName)
{
auto collectionEntry = mCustomCollectionSystemsData.find(collectionName);
// The window deletion needs to be located here instead of in GuiCollectionSystemsOptions
// (where the custom collection deletions are initiated), as there seems to be some random
// issue with accessing mWindow via the lambda expression.
while (mWindow->peekGui() && mWindow->peekGui() != ViewController::get())
delete mWindow->peekGui();
if (collectionEntry != mCustomCollectionSystemsData.end()) {
CollectionSystemManager::get()->loadEnabledListFromSettings();
CollectionSystemManager::get()->updateSystemsList();
ViewController::get()->removeGameListView(collectionEntry->second.system);
ViewController::get()->reloadAll();
delete collectionEntry->second.system;
mCustomCollectionSystemsData.erase(collectionName);
// Remove the collection configuration file.
std::string configFile = getCustomCollectionConfigPath(collectionName);
Utils::FileSystem::removeFile(configFile);
LOG(LogDebug) << "CollectionSystemManager::deleteCustomCollection(): Deleted the "
"configuration file '" << configFile << "'.";
GuiInfoPopup* s = new GuiInfoPopup(mWindow, "DELETED THE COLLECTION '" +
Utils::String::toUpper(collectionName) + "'", 5000);
mWindow->setInfoPopup(s);
}
else {
LOG(LogError) << "Attempted to delete custom collection '" + collectionName + "' " +
"which doesn't exist.";
}
}
// Functions below to Handle loading of collection systems, creating empty ones, // Functions below to Handle loading of collection systems, creating empty ones,
// and populating on demand. // and populating on demand.

View file

@ -103,6 +103,7 @@ public:
std::vector<std::string> getUnusedSystemsFromTheme(); std::vector<std::string> getUnusedSystemsFromTheme();
SystemData* addNewCustomCollection(std::string name); SystemData* addNewCustomCollection(std::string name);
void deleteCustomCollection(std::string collectionName);
private: private:
static CollectionSystemManager* sInstance; static CollectionSystemManager* sInstance;

View file

@ -11,15 +11,19 @@
#include "components/OptionListComponent.h" #include "components/OptionListComponent.h"
#include "components/SwitchComponent.h" #include "components/SwitchComponent.h"
#include "guis/GuiMsgBox.h"
#include "guis/GuiSettings.h" #include "guis/GuiSettings.h"
#include "guis/GuiTextEditPopup.h" #include "guis/GuiTextEditPopup.h"
#include "views/ViewController.h" #include "views/ViewController.h"
#include "CollectionSystemManager.h" #include "CollectionSystemManager.h"
GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::string title) GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(
: GuiSettings(window, title), mAddedCustomCollection(false) Window* window,
std::string title)
: GuiSettings(window, title),
mAddedCustomCollection(false),
mDeletedCustomCollection(false)
{ {
// Finish editing custom collection. // Finish editing custom collection.
if (CollectionSystemManager::get()->isEditing()) { if (CollectionSystemManager::get()->isEditing()) {
ComponentListRow row; ComponentListRow row;
@ -72,6 +76,7 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
it->second.isEnabled); it->second.isEnabled);
addWithLabel("CUSTOM GAME COLLECTIONS", collection_systems_custom); addWithLabel("CUSTOM GAME COLLECTIONS", collection_systems_custom);
addSaveFunc([this] { addSaveFunc([this] {
if (!mDeletedCustomCollection) {
std::string customSystemsSelected = Utils::String::vectorToCommaString( std::string customSystemsSelected = Utils::String::vectorToCommaString(
collection_systems_custom->getSelectedObjects(), true); collection_systems_custom->getSelectedObjects(), true);
std::string customSystemsConfig = Settings::getInstance()-> std::string customSystemsConfig = Settings::getInstance()->
@ -79,13 +84,15 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
if (customSystemsSelected != customSystemsConfig) { if (customSystemsSelected != customSystemsConfig) {
if (CollectionSystemManager::get()->isEditing()) if (CollectionSystemManager::get()->isEditing())
CollectionSystemManager::get()->exitEditMode(); CollectionSystemManager::get()->exitEditMode();
Settings::getInstance()->setString("CollectionSystemsCustom", customSystemsSelected); Settings::getInstance()->setString("CollectionSystemsCustom",
customSystemsSelected);
setNeedsSaving(); setNeedsSaving();
setNeedsReloading(); setNeedsReloading();
setNeedsCollectionsUpdate(); setNeedsCollectionsUpdate();
if (!mAddedCustomCollection) if (!mAddedCustomCollection)
setNeedsGoToSystemView(SystemData::sSystemVector.front()); setNeedsGoToSystemView(SystemData::sSystemVector.front());
} }
}
}); });
// Create custom collection from theme. // Create custom collection from theme.
@ -117,6 +124,11 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
auto themeFolder = std::make_shared<TextComponent>(mWindow, auto themeFolder = std::make_shared<TextComponent>(mWindow,
Utils::String::toUpper(name), Font::get(FONT_SIZE_SMALL), 0x777777FF); Utils::String::toUpper(name), Font::get(FONT_SIZE_SMALL), 0x777777FF);
row.addElement(themeFolder, true); row.addElement(themeFolder, true);
// 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);
ss->addRow(row); ss->addRow(row);
} }
mWindow->pushGui(ss); mWindow->pushGui(ss);
@ -149,6 +161,79 @@ GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window, std::st
}); });
addRow(row); addRow(row);
// 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'" +
Utils::String::toUpper(name) + "'.\n"
"ARE YOU SURE?",
"YES", [this, name] {
if (CollectionSystemManager::get()->isEditing())
CollectionSystemManager::get()->exitEditMode();
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());
}
CollectionSystemManager::get()->deleteCustomCollection(name);
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);
// Sort favorites on top for custom collections. // Sort favorites on top for custom collections.
auto fav_first_custom = std::make_shared<SwitchComponent>(mWindow); auto fav_first_custom = std::make_shared<SwitchComponent>(mWindow);
fav_first_custom->setState(Settings::getInstance()->getBool("FavFirstCustom")); fav_first_custom->setState(Settings::getInstance()->getBool("FavFirstCustom"));

View file

@ -27,6 +27,7 @@ private:
std::shared_ptr<OptionListComponent<std::string>> collection_systems_custom; std::shared_ptr<OptionListComponent<std::string>> collection_systems_custom;
bool mAddedCustomCollection; bool mAddedCustomCollection;
bool mDeletedCustomCollection;
}; };
#endif // ES_APP_GUIS_GUI_COLLECTION_SYSTEM_OPTIONS_H #endif // ES_APP_GUIS_GUI_COLLECTION_SYSTEM_OPTIONS_H

View file

@ -330,7 +330,7 @@ void GuiMenu::openUISettings()
// Enable the 'Y' button for tagging games as favorites. // Enable the 'Y' button for tagging games as favorites.
auto favorites_add_button = std::make_shared<SwitchComponent>(mWindow); auto favorites_add_button = std::make_shared<SwitchComponent>(mWindow);
favorites_add_button->setState(Settings::getInstance()->getBool("FavoritesAddButton")); favorites_add_button->setState(Settings::getInstance()->getBool("FavoritesAddButton"));
s->addWithLabel("ENABLE BUTTON SHORTCUT TO TOGGLE FAVORITES", favorites_add_button); s->addWithLabel("ENABLE SHORTCUT TO TOGGLE FAVORITES", favorites_add_button);
s->addSaveFunc([favorites_add_button, s] { s->addSaveFunc([favorites_add_button, s] {
if (Settings::getInstance()->getBool("FavoritesAddButton") != if (Settings::getInstance()->getBool("FavoritesAddButton") !=
favorites_add_button->getState()) { favorites_add_button->getState()) {

View file

@ -30,8 +30,7 @@ GuiSettings::GuiSettings(
mNeedsSortingCollections(false), mNeedsSortingCollections(false),
mGoToSystem(nullptr), mGoToSystem(nullptr),
mNeedsGoToStart(false), mNeedsGoToStart(false),
mNeedsGoToSystemView(false), mNeedsGoToSystemView(false)
mNeedsDestroyAllWindows(false)
{ {
addChild(&mMenu); addChild(&mMenu);
mMenu.addButton("BACK", "back", [this] { delete this; }); mMenu.addButton("BACK", "back", [this] { delete this; });
@ -82,13 +81,8 @@ void GuiSettings::save()
if (mNeedsGoToSystemView) if (mNeedsGoToSystemView)
ViewController::get()->goToSystemView(mGoToSystem); ViewController::get()->goToSystemView(mGoToSystem);
if (mNeedsDestroyAllWindows) {
while (mWindow->peekGui() && mWindow->peekGui() != ViewController::get())
delete mWindow->peekGui();
}
if (mNeedsSaving || mNeedsCollectionsUpdate || mNeedsReloading || mNeedsSorting || if (mNeedsSaving || mNeedsCollectionsUpdate || mNeedsReloading || mNeedsSorting ||
mNeedsGoToStart || mNeedsGoToSystemView || mNeedsDestroyAllWindows) mNeedsGoToStart || mNeedsGoToSystemView)
mWindow->invalidateCachedBackground(); mWindow->invalidateCachedBackground();
} }

View file

@ -41,7 +41,6 @@ public:
void setNeedsGoToStart() { mNeedsGoToStart = true; }; void setNeedsGoToStart() { mNeedsGoToStart = true; };
void setNeedsGoToSystemView(SystemData* goToSystem) void setNeedsGoToSystemView(SystemData* goToSystem)
{ mNeedsGoToSystemView = true; mGoToSystem = goToSystem; }; { mNeedsGoToSystemView = true; mGoToSystem = goToSystem; };
void setNeedsDestroyAllWindows() { mNeedsDestroyAllWindows = true; };
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
std::vector<HelpPrompt> getHelpPrompts() override; std::vector<HelpPrompt> getHelpPrompts() override;
@ -57,7 +56,6 @@ private:
bool mNeedsSortingCollections; bool mNeedsSortingCollections;
bool mNeedsGoToStart; bool mNeedsGoToStart;
bool mNeedsGoToSystemView; bool mNeedsGoToSystemView;
bool mNeedsDestroyAllWindows;
SystemData* mGoToSystem; SystemData* mGoToSystem;
}; };