From 78db6cd18c213f9ff8c7a67abc9667461a82d847 Mon Sep 17 00:00:00 2001
From: Leon Styhre <leon@leonstyhre.com>
Date: Sat, 25 Sep 2021 10:54:53 +0200
Subject: [PATCH] Improvements to the gamelist filter GUI.

---
 es-app/src/guis/GuiGamelistFilter.cpp | 47 ++++++++++++++++++++++-----
 es-app/src/guis/GuiGamelistFilter.h   |  3 +-
 2 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/es-app/src/guis/GuiGamelistFilter.cpp b/es-app/src/guis/GuiGamelistFilter.cpp
index 679e785cb..6feda35e7 100644
--- a/es-app/src/guis/GuiGamelistFilter.cpp
+++ b/es-app/src/guis/GuiGamelistFilter.cpp
@@ -21,7 +21,7 @@ GuiGamelistFilter::GuiGamelistFilter(Window* window,
                                      SystemData* system,
                                      std::function<void(bool)> filterChangedCallback)
     : GuiComponent(window)
-    , mMenu(window, "FILTER GAMELIST BY")
+    , mMenu(window, "FILTER GAMELIST")
     , mSystem(system)
     , mFiltersChangedCallback(filterChangedCallback)
     , mFiltersChanged(false)
@@ -92,8 +92,6 @@ void GuiGamelistFilter::resetAllFilters()
     mFiltersChanged = true;
 }
 
-GuiGamelistFilter::~GuiGamelistFilter() { mFilterOptions.clear(); }
-
 void GuiGamelistFilter::addFiltersToMenu()
 {
     ComponentListRow row;
@@ -151,18 +149,49 @@ void GuiGamelistFilter::addFiltersToMenu()
          it != decls.cend(); it++) {
         FilterIndexType type = (*it).type; // Type of filter.
 
-        // All possible filters for this type.
         std::map<std::string, int>* allKeys = (*it).allIndexKeys;
+
+        bool exclusiveSelect = false;
+
+        if (type == FAVORITES_FILTER || type == KIDGAME_FILTER || type == COMPLETED_FILTER ||
+            type == BROKEN_FILTER)
+            exclusiveSelect = true;
+
+        // Don't display the hidden games filter if we're actually hiding these games.
+        if (type == HIDDEN_FILTER) {
+            if (Settings::getInstance()->getBool("ShowHiddenGames"))
+                exclusiveSelect = true;
+            else
+                continue;
+        }
+
         std::string menuLabel = (*it).menuLabel; // Text to show in menu.
         std::shared_ptr<OptionListComponent<std::string>> optionList;
 
-        // Add genres.
-        optionList = std::make_shared<OptionListComponent<std::string>>(mWindow, getHelpStyle(),
-                                                                        menuLabel, true);
+        // For bool values, make the selection exclusive so that both True and False can't be
+        // selected at the same time. This should be changed to a SwitchComponent at some point.
+        if (exclusiveSelect)
+            optionList = std::make_shared<OptionListComponent<std::string>>(mWindow, getHelpStyle(),
+                                                                            menuLabel, true, true);
+        else
+            optionList = std::make_shared<OptionListComponent<std::string>>(mWindow, getHelpStyle(),
+                                                                            menuLabel, true, false);
+
+        // Still display fields that can't be filtered in the menu, but notify the user and set
+        // the OptionListComponent as disabled.
+        if (allKeys->size() == 1 || allKeys->empty()) {
+            optionList->setEnabled(false);
+            optionList->setOpacity(DISABLED_OPACITY);
+            optionList->setOverrideMultiText("NOTHING TO FILTER");
+        }
+
         for (auto it : *allKeys)
             optionList->add(it.first, it.first, mFilterIndex->isKeyBeingFilteredBy(it.first, type));
-        if (allKeys->size() > 0)
-            mMenu.addWithLabel(menuLabel, optionList);
+
+        if (allKeys->size() == 0)
+            optionList->add("", "", false);
+
+        mMenu.addWithLabel(menuLabel, optionList);
 
         mFilterOptions[type] = optionList;
     }
diff --git a/es-app/src/guis/GuiGamelistFilter.h b/es-app/src/guis/GuiGamelistFilter.h
index 90fdc0c02..977f0cb9c 100644
--- a/es-app/src/guis/GuiGamelistFilter.h
+++ b/es-app/src/guis/GuiGamelistFilter.h
@@ -25,7 +25,8 @@ public:
                       SystemData* system,
                       std::function<void(bool)> filtersChangedCallback);
 
-    ~GuiGamelistFilter();
+    ~GuiGamelistFilter() { mFilterOptions.clear(); }
+
     bool input(InputConfig* config, Input input) override;
 
     virtual std::vector<HelpPrompt> getHelpPrompts() override;