From c5e70385dd908cc3f9c6a13720e28b2b9fb876a9 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Sun, 7 Jun 2020 20:09:02 +0200 Subject: [PATCH] Expanded support for help system theming to entire application, as before it was only partially implemented. --- .../src/guis/GuiCollectionSystemsOptions.cpp | 18 +- es-app/src/guis/GuiCollectionSystemsOptions.h | 1 + es-app/src/guis/GuiGameScraper.cpp | 8 + es-app/src/guis/GuiGameScraper.h | 2 + es-app/src/guis/GuiGamelistFilter.cpp | 11 +- es-app/src/guis/GuiGamelistFilter.h | 1 + es-app/src/guis/GuiGamelistOptions.cpp | 7 +- .../src/guis/GuiGeneralScreensaverOptions.cpp | 4 +- es-app/src/guis/GuiMenu.cpp | 86 ++--- es-app/src/guis/GuiMetaDataEd.cpp | 22 +- es-app/src/guis/GuiMetaDataEd.h | 2 + es-app/src/guis/GuiScraperMenu.cpp | 30 +- es-app/src/guis/GuiScraperMulti.cpp | 9 +- es-app/src/guis/GuiScraperMulti.h | 2 + es-app/src/guis/GuiScraperSearch.cpp | 26 +- es-app/src/guis/GuiScraperSearch.h | 1 + es-app/src/guis/GuiScreensaverOptions.cpp | 2 +- .../src/guis/GuiVideoScreensaverOptions.cpp | 2 +- es-app/src/main.cpp | 5 +- es-app/src/views/SystemView.cpp | 2 +- es-core/src/components/OptionListComponent.h | 346 +++++++++--------- es-core/src/guis/GuiComplexTextEditPopup.cpp | 4 +- es-core/src/guis/GuiComplexTextEditPopup.h | 4 + es-core/src/guis/GuiInputConfig.cpp | 2 +- es-core/src/guis/GuiMsgBox.cpp | 3 +- es-core/src/guis/GuiMsgBox.h | 5 +- es-core/src/guis/GuiTextEditPopup.cpp | 4 +- es-core/src/guis/GuiTextEditPopup.h | 4 + 28 files changed, 356 insertions(+), 257 deletions(-) diff --git a/es-app/src/guis/GuiCollectionSystemsOptions.cpp b/es-app/src/guis/GuiCollectionSystemsOptions.cpp index 95eac3063..78ca87b09 100644 --- a/es-app/src/guis/GuiCollectionSystemsOptions.cpp +++ b/es-app/src/guis/GuiCollectionSystemsOptions.cpp @@ -7,6 +7,7 @@ #include "utils/StringUtil.h" #include "views/ViewController.h" #include "CollectionSystemManager.h" +#include "SystemData.h" #include "Window.h" GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window) : GuiComponent(window), mMenu(window, "GAME COLLECTION SETTINGS") @@ -30,7 +31,9 @@ void GuiCollectionSystemsOptions::initializeMenu() addEntry("CREATE NEW CUSTOM COLLECTION FROM THEME", 0x777777FF, true, [this, unusedFolders] { auto s = new GuiSettings(mWindow, "SELECT THEME FOLDER"); - std::shared_ptr< OptionListComponent > folderThemes = std::make_shared< OptionListComponent >(mWindow, "SELECT THEME FOLDER", true); + std::shared_ptr< OptionListComponent> + folderThemes = std::make_shared< OptionListComponent> + (mWindow, getHelpStyle(), "SELECT THEME FOLDER", true); // add Custom Systems for(auto it = unusedFolders.cbegin() ; it != unusedFolders.cend() ; it++ ) @@ -62,7 +65,7 @@ void GuiCollectionSystemsOptions::initializeMenu() createCollection(name); }; row.makeAcceptInputHandler([this, createCustomCollection] { - mWindow->pushGui(new GuiTextEditPopup(mWindow, "New Collection Name", "", createCustomCollection, false)); + mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), "New Collection Name", "", createCustomCollection, false)); }); mMenu.addRow(row); @@ -143,7 +146,7 @@ void GuiCollectionSystemsOptions::addSystemsToMenu() std::map autoSystems = CollectionSystemManager::get()->getAutoCollectionSystems(); - autoOptionList = std::make_shared< OptionListComponent >(mWindow, "SELECT COLLECTIONS", true); + autoOptionList = std::make_shared< OptionListComponent >(mWindow, getHelpStyle(), "SELECT COLLECTIONS", true); // add Auto Systems for(std::map::const_iterator it = autoSystems.cbegin() ; it != autoSystems.cend() ; it++ ) @@ -154,7 +157,7 @@ void GuiCollectionSystemsOptions::addSystemsToMenu() std::map customSystems = CollectionSystemManager::get()->getCustomCollectionSystems(); - customOptionList = std::make_shared< OptionListComponent >(mWindow, "SELECT COLLECTIONS", true); + customOptionList = std::make_shared< OptionListComponent >(mWindow, getHelpStyle(), "SELECT COLLECTIONS", true); // add Custom Systems for(std::map::const_iterator it = customSystems.cbegin() ; it != customSystems.cend() ; it++ ) @@ -220,3 +223,10 @@ std::vector GuiCollectionSystemsOptions::getHelpPrompts() prompts.push_back(HelpPrompt("b", "back")); return prompts; } + +HelpStyle GuiCollectionSystemsOptions::getHelpStyle() +{ + HelpStyle style = HelpStyle(); + style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + return style; +} diff --git a/es-app/src/guis/GuiCollectionSystemsOptions.h b/es-app/src/guis/GuiCollectionSystemsOptions.h index c3f4508c8..c5848d51a 100644 --- a/es-app/src/guis/GuiCollectionSystemsOptions.h +++ b/es-app/src/guis/GuiCollectionSystemsOptions.h @@ -17,6 +17,7 @@ public: bool input(InputConfig* config, Input input) override; virtual std::vector getHelpPrompts() override; + HelpStyle getHelpStyle() override; private: void initializeMenu(); diff --git a/es-app/src/guis/GuiGameScraper.cpp b/es-app/src/guis/GuiGameScraper.cpp index 5feb8ff93..5ae2a9298 100644 --- a/es-app/src/guis/GuiGameScraper.cpp +++ b/es-app/src/guis/GuiGameScraper.cpp @@ -11,6 +11,7 @@ #include "components/ButtonComponent.h" #include "components/MenuComponent.h" #include "components/TextComponent.h" +#include "views/ViewController.h" #include "FileData.h" #include "PowerSaver.h" #include "SystemData.h" @@ -137,6 +138,13 @@ std::vector GuiGameScraper::getHelpPrompts() return mGrid.getHelpPrompts(); } +HelpStyle GuiGameScraper::getHelpStyle() +{ + HelpStyle style = HelpStyle(); + style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + return style; +} + void GuiGameScraper::close() { mClose = true; diff --git a/es-app/src/guis/GuiGameScraper.h b/es-app/src/guis/GuiGameScraper.h index 360394a14..f3900d730 100644 --- a/es-app/src/guis/GuiGameScraper.h +++ b/es-app/src/guis/GuiGameScraper.h @@ -26,7 +26,9 @@ public: bool input(InputConfig* config, Input input) override; void update(int deltaTime); + virtual std::vector getHelpPrompts() override; + HelpStyle getHelpStyle() override; private: bool mClose; diff --git a/es-app/src/guis/GuiGamelistFilter.cpp b/es-app/src/guis/GuiGamelistFilter.cpp index f68c0ddd5..3e43d7b26 100644 --- a/es-app/src/guis/GuiGamelistFilter.cpp +++ b/es-app/src/guis/GuiGamelistFilter.cpp @@ -10,6 +10,7 @@ #include "components/OptionListComponent.h" #include "views/UIModeController.h" +#include "views/ViewController.h" #include "SystemData.h" GuiGamelistFilter::GuiGamelistFilter( @@ -85,7 +86,8 @@ void GuiGamelistFilter::addFiltersToMenu() ComponentListRow row; // Add genres. - optionList = std::make_shared< OptionListComponent >(mWindow, menuLabel, true); + optionList = std::make_shared< OptionListComponent> + (mWindow, getHelpStyle(), menuLabel, true); for (auto it: *allKeys) optionList->add(it.first, it.first, mFilterIndex->isKeyBeingFilteredBy(it.first, type)); if (allKeys->size() > 0) @@ -126,3 +128,10 @@ std::vector GuiGamelistFilter::getHelpPrompts() prompts.push_back(HelpPrompt("b", "back")); return prompts; } + +HelpStyle GuiGamelistFilter::getHelpStyle() +{ + HelpStyle style = HelpStyle(); + style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + return style; +} diff --git a/es-app/src/guis/GuiGamelistFilter.h b/es-app/src/guis/GuiGamelistFilter.h index b6475e6ca..87827046a 100644 --- a/es-app/src/guis/GuiGamelistFilter.h +++ b/es-app/src/guis/GuiGamelistFilter.h @@ -27,6 +27,7 @@ public: bool input(InputConfig* config, Input input) override; virtual std::vector getHelpPrompts() override; + HelpStyle getHelpStyle() override; private: void initializeMenu(); diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index 947a8ca04..cb1ce5c59 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -58,7 +58,8 @@ GuiGamelistOptions::GuiGamelistOptions( if (curChar < startChar || curChar > endChar) curChar = startChar; - mJumpToLetterList = std::make_shared(mWindow, "JUMP TO...", false); + mJumpToLetterList = std::make_shared(mWindow, getHelpStyle(), + "JUMP TO...", false); if (mFavoritesSorting && system->getName() != "favorites" && system->getName() != "recent") { @@ -120,11 +121,11 @@ GuiGamelistOptions::GuiGamelistOptions( mMenu.addRow(row); // Sort list by selected sort type (persistent throughout the program session). - mListSort = std::make_shared(mWindow, "SORT GAMES BY", false); + mListSort = std::make_shared(mWindow, getHelpStyle(), "SORT GAMES BY", false); FileData* root = mSystem->getRootFolder(); std::string sortType = root->getSortTypeString(); - for (unsigned int i = 0; i < FileSorts::SortTypes.size(); i++) { + for (unsigned int i = 0; i add(sort.description, &sort, 1); diff --git a/es-app/src/guis/GuiGeneralScreensaverOptions.cpp b/es-app/src/guis/GuiGeneralScreensaverOptions.cpp index 69817db9a..8cf22639d 100644 --- a/es-app/src/guis/GuiGeneralScreensaverOptions.cpp +++ b/es-app/src/guis/GuiGeneralScreensaverOptions.cpp @@ -26,7 +26,7 @@ GuiGeneralScreensaverOptions::GuiGeneralScreensaverOptions(Window* window, const addSaveFunc([ss_controls] { Settings::getInstance()->setBool("ScreenSaverControls", ss_controls->getState()); }); // screensaver behavior - auto screensaver_behavior = std::make_shared< OptionListComponent >(mWindow, "SCREENSAVER BEHAVIOR", false); + auto screensaver_behavior = std::make_shared< OptionListComponent >(mWindow, getHelpStyle(), "SCREENSAVER BEHAVIOR", false); std::vector screensavers; screensavers.push_back("dim"); screensavers.push_back("black"); @@ -38,7 +38,7 @@ GuiGeneralScreensaverOptions::GuiGeneralScreensaverOptions(Window* window, const addSaveFunc([this, screensaver_behavior] { if (Settings::getInstance()->getString("ScreenSaverBehavior") != "random video" && screensaver_behavior->getSelected() == "random video") { // if before it wasn't risky but now there's a risk of problems, show warning - mWindow->pushGui(new GuiMsgBox(mWindow, + mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), "The \"Random Video\" screensaver shows videos from your gamelist.\n\nIf you do not have videos, or if in several consecutive attempts the games it selects don't have videos it will default to black.\n\nMore options in the \"UI Settings\" > \"Video Screensaver\" menu.", "OK", [] { return; })); } diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index a87602ab2..b6580d674 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -83,8 +83,8 @@ void GuiMenu::openSoundSettings() if (UIModeController::getInstance()->isUIModeFull()) { #if defined(__linux__) // audio card - auto audio_card = std::make_shared< OptionListComponent - >(mWindow, "AUDIO CARD", false); + auto audio_card = std::make_shared> + (mWindow, getHelpStyle(), "AUDIO CARD", false); std::vector audio_cards; #ifdef _RPI_ // RPi Specific Audio Cards @@ -114,8 +114,8 @@ void GuiMenu::openSoundSettings() }); // Volume control device. - auto vol_dev = std::make_shared< OptionListComponent - >(mWindow, "AUDIO DEVICE", false); + auto vol_dev = std::make_shared> + (mWindow, getHelpStyle(), "AUDIO DEVICE", false); std::vector transitions; transitions.push_back("PCM"); transitions.push_back("Speaker"); @@ -140,8 +140,8 @@ void GuiMenu::openSoundSettings() #ifdef _RPI_ // OMX player Audio Device - auto omx_audio_dev = std::make_shared< OptionListComponent - >(mWindow, "OMX PLAYER AUDIO DEVICE", false); + auto omx_audio_dev = std::make_shared> + (mWindow, getHelpStyle(), "OMX PLAYER AUDIO DEVICE", false); std::vector omx_cards; // RPi Specific Audio Cards omx_cards.push_back("local"); @@ -194,8 +194,8 @@ void GuiMenu::openUISettings() auto s = new GuiSettings(mWindow, "UI SETTINGS"); // Optionally start in selected system/gamelist. - auto systemfocus_list = std::make_shared< OptionListComponent - >(mWindow, "GAMELIST ON STARTUP", false); + auto systemfocus_list = std::make_shared> + (mWindow, getHelpStyle(), "GAMELIST ON STARTUP", false); systemfocus_list->add("NONE", "", Settings::getInstance()->getString("StartupSystem") == ""); for (auto it = SystemData::sSystemVector.cbegin(); it != SystemData::sSystemVector.cend(); it++) { @@ -209,8 +209,8 @@ void GuiMenu::openUISettings() }); // GameList view style. - auto gamelist_style = std::make_shared< OptionListComponent - >(mWindow, "GAMELIST VIEW STYLE", false); + auto gamelist_style = std::make_shared> + (mWindow, getHelpStyle(), "GAMELIST VIEW STYLE", false); std::vector styles; styles.push_back("automatic"); styles.push_back("basic"); @@ -233,8 +233,8 @@ void GuiMenu::openUISettings() }); // Transition style. - auto transition_style = std::make_shared< OptionListComponent - >(mWindow, "TRANSITION STYLE", false); + auto transition_style = std::make_shared> + (mWindow, getHelpStyle(), "TRANSITION STYLE", false); std::vector transitions; transitions.push_back("fade"); transitions.push_back("slide"); @@ -263,8 +263,8 @@ void GuiMenu::openUISettings() if (selectedSet == themeSets.cend()) selectedSet = themeSets.cbegin(); - auto theme_set = std::make_shared< OptionListComponent - >(mWindow, "THEME SET", false); + auto theme_set = std::make_shared> + (mWindow, getHelpStyle(), "THEME SET", false); for (auto it = themeSets.cbegin(); it != themeSets.cend(); it++) theme_set->add(it->first, it->first, it == selectedSet); s->addWithLabel("THEME SET", theme_set); @@ -289,14 +289,14 @@ void GuiMenu::openUISettings() } // UI mode. - auto UImodeSelection = std::make_shared< OptionListComponent - >(mWindow, "UI MODE", false); + auto UImodeSelection = std::make_shared> + (mWindow, getHelpStyle(), "UI MODE", false); std::vector UImodes = UIModeController::getInstance()->getUIModes(); for (auto it = UImodes.cbegin(); it != UImodes.cend(); it++) UImodeSelection->add(*it, *it, Settings::getInstance()->getString("UIMode") == *it); s->addWithLabel("UI MODE", UImodeSelection); Window* window = mWindow; - s->addSaveFunc([ UImodeSelection, window] { + s->addSaveFunc([ UImodeSelection, window, this] { std::string selectedMode = UImodeSelection->getSelected(); if (selectedMode != "Full") { std::string msg = "You are changing the UI to a restricted mode:\n" + @@ -305,7 +305,7 @@ void GuiMenu::openUISettings() msg += "To unlock and return to the full UI, enter this code: \n"; msg += "\"" + UIModeController::getInstance()->getFormattedPassKeyStr() + "\"\n\n"; msg += "Do you want to proceed?"; - window->pushGui(new GuiMsgBox(window, msg, + window->pushGui(new GuiMsgBox(window, this->getHelpStyle(), msg, "YES", [selectedMode] { LOG(LogDebug) << "Setting UI mode to " << selectedMode; Settings::getInstance()->setString("UIMode", selectedMode); @@ -413,8 +413,8 @@ void GuiMenu::openOtherSettings() (int)Math::round(max_vram->getValue())); }); // Fullscreen mode. - auto fullscreen_mode = std::make_shared< OptionListComponent - >(mWindow, "FULLSCREEN MODE", false); + auto fullscreen_mode = std::make_shared> + (mWindow, getHelpStyle(), "FULLSCREEN MODE", false); std::vector screenmode; screenmode.push_back("normal"); screenmode.push_back("borderless"); @@ -431,8 +431,8 @@ void GuiMenu::openOtherSettings() }); // Power saver. - auto power_saver = std::make_shared< OptionListComponent - >(mWindow, "POWER SAVER MODES", false); + auto power_saver = std::make_shared> + (mWindow, getHelpStyle(), "POWER SAVER MODES", false); std::vector modes; modes.push_back("disabled"); modes.push_back("default"); @@ -473,8 +473,8 @@ void GuiMenu::openOtherSettings() #endif // When to save game metadata. - auto gamelistsSaveMode = std::make_shared< OptionListComponent - >(mWindow, "SAVE METADATA", false); + auto gamelistsSaveMode = std::make_shared> + (mWindow, getHelpStyle(), "SAVE METADATA", false); std::vector saveModes; saveModes.push_back("on exit"); saveModes.push_back("always"); @@ -543,9 +543,9 @@ void GuiMenu::openOtherSettings() void GuiMenu::openConfigInput() { Window* window = mWindow; - window->pushGui(new GuiMsgBox(window, "ARE YOU SURE YOU WANT TO CONFIGURE INPUT?", "YES", - [window] { - window->pushGui(new GuiDetectDevice(window, false, nullptr)); + window->pushGui(new GuiMsgBox(window, getHelpStyle(), + "ARE YOU SURE YOU WANT TO CONFIGURE INPUT?", "YES", [window] { + window->pushGui(new GuiDetectDevice(window, false, nullptr)); }, "NO", nullptr) ); } @@ -555,12 +555,14 @@ void GuiMenu::openQuitMenu() auto s = new GuiSettings(mWindow, "QUIT"); Window* window = mWindow; + HelpStyle style = getHelpStyle(); ComponentListRow row; if (UIModeController::getInstance()->isUIModeFull()) { if (Settings::getInstance()->getBool("ShowExit")) { - row.makeAcceptInputHandler([window] { - window->pushGui(new GuiMsgBox(window, "REALLY QUIT?", "YES", + row.makeAcceptInputHandler([window, this] { + window->pushGui(new GuiMsgBox(window, this->getHelpStyle(), + "REALLY QUIT?", "YES", [] { Scripting::fireEvent("quit"); quitES(); @@ -574,9 +576,9 @@ void GuiMenu::openQuitMenu() if (Settings::getInstance()->getBool("ShowRebootSystem")) { row.elements.clear(); - row.makeAcceptInputHandler([window] { - window->pushGui(new GuiMsgBox(window, "REALLY REBOOT?", "YES", - [] { + row.makeAcceptInputHandler([window, this] { + window->pushGui(new GuiMsgBox(window, this->getHelpStyle(), + "REALLY REBOOT?", "YES", [] { Scripting::fireEvent("quit", "reboot"); Scripting::fireEvent("reboot"); if (quitES(QuitMode::REBOOT) != 0) @@ -590,9 +592,9 @@ void GuiMenu::openQuitMenu() if (Settings::getInstance()->getBool("ShowPoweroffSystem")) { row.elements.clear(); - row.makeAcceptInputHandler([window] { - window->pushGui(new GuiMsgBox(window, "REALLY POWER OFF?", "YES", - [] { + row.makeAcceptInputHandler([window, this] { + window->pushGui(new GuiMsgBox(window, this->getHelpStyle(), + "REALLY POWER OFF?", "YES", [] { Scripting::fireEvent("quit", "poweroff"); Scripting::fireEvent("poweroff"); if (quitES(QuitMode::POWEROFF) != 0) @@ -663,13 +665,6 @@ bool GuiMenu::input(InputConfig* config, Input input) return false; } -HelpStyle GuiMenu::getHelpStyle() -{ - HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); - return style; -} - std::vector GuiMenu::getHelpPrompts() { std::vector prompts; @@ -678,3 +673,10 @@ std::vector GuiMenu::getHelpPrompts() prompts.push_back(HelpPrompt("start", "close")); return prompts; } + +HelpStyle GuiMenu::getHelpStyle() +{ + HelpStyle style = HelpStyle(); + style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + return style; +} diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index 0a4a527d5..62421513c 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -158,8 +158,8 @@ GuiMetaDataEd::GuiMetaDataEd( row.makeAcceptInputHandler([this, title, staticTextString, defaultLaunchString, ed, updateVal, multiLine] { - mWindow->pushGui(new GuiComplexTextEditPopup(mWindow, title, - staticTextString, defaultLaunchString, ed->getValue(), + mWindow->pushGui(new GuiComplexTextEditPopup(mWindow, getHelpStyle(), + title, staticTextString, defaultLaunchString, ed->getValue(), updateVal, multiLine)); }); break; @@ -186,8 +186,8 @@ GuiMetaDataEd::GuiMetaDataEd( // OK callback (apply new value to ed). auto updateVal = [ed](const std::string& newVal) { ed->setValue(newVal); }; row.makeAcceptInputHandler([this, title, ed, updateVal, multiLine] { - mWindow->pushGui(new GuiTextEditPopup(mWindow, title, ed->getValue(), - updateVal, multiLine)); + mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), title, + ed->getValue(), updateVal, multiLine)); }); break; } @@ -213,8 +213,9 @@ GuiMetaDataEd::GuiMetaDataEd( if (mDeleteFunc) { auto deleteFileAndSelf = [&] { mDeleteFunc(); delete this; }; auto deleteBtnFunc = [this, deleteFileAndSelf] { mWindow->pushGui( - new GuiMsgBox(mWindow, "THIS WILL DELETE THE ACTUAL GAME FILE(S)!\nARE " - "YOU SURE?", "YES", deleteFileAndSelf, "NO", nullptr)); }; + new GuiMsgBox(mWindow, getHelpStyle(), + "THIS WILL DELETE THE ACTUAL GAME FILE(S)!\nARE YOU SURE?", + "YES", deleteFileAndSelf, "NO", nullptr)); }; buttons.push_back(std::make_shared(mWindow, "DELETE", "delete", deleteBtnFunc)); } @@ -337,7 +338,7 @@ void GuiMetaDataEd::close(bool closeAllWindows) if (dirty) { // Changes were made, ask if the user wants to save them. - mWindow->pushGui(new GuiMsgBox(mWindow, + mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), "SAVE CHANGES?", "YES", [this, closeFunc] { save(); closeFunc(); }, "NO", closeFunc @@ -369,3 +370,10 @@ std::vector GuiMetaDataEd::getHelpPrompts() prompts.push_back(HelpPrompt("start", "close")); return prompts; } + +HelpStyle GuiMetaDataEd::getHelpStyle() +{ + HelpStyle style = HelpStyle(); + style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + return style; +} diff --git a/es-app/src/guis/GuiMetaDataEd.h b/es-app/src/guis/GuiMetaDataEd.h index dac9f7bda..1751030a1 100644 --- a/es-app/src/guis/GuiMetaDataEd.h +++ b/es-app/src/guis/GuiMetaDataEd.h @@ -33,7 +33,9 @@ public: bool input(InputConfig* config, Input input) override; void onSizeChanged() override; + virtual std::vector getHelpPrompts() override; + HelpStyle getHelpStyle() override; private: void save(); diff --git a/es-app/src/guis/GuiScraperMenu.cpp b/es-app/src/guis/GuiScraperMenu.cpp index e9f11f6de..a4438e027 100644 --- a/es-app/src/guis/GuiScraperMenu.cpp +++ b/es-app/src/guis/GuiScraperMenu.cpp @@ -21,8 +21,8 @@ GuiScraperMenu::GuiScraperMenu(Window* window) : GuiComponent(window), mMenu(window, "SCRAPER") { // Scrape from. - auto scraper_list = std::make_shared< OptionListComponent> - (mWindow, "SCRAPE FROM", false); + auto scraper_list = std::make_shared> + (mWindow, getHelpStyle(), "SCRAPE FROM", false); std::vector scrapers = getScraperList(); // Select either the first entry or the one read from the settings, @@ -37,7 +37,7 @@ GuiScraperMenu::GuiScraperMenu(Window* window) : GuiComponent(window), // Search filters, getSearches() will generate a queue of games to scrape // based on the outcome of the checks below. mFilters = std::make_shared< OptionListComponent> - (mWindow, "SCRAPE THESE GAMES", false); + (mWindow, getHelpStyle(), "SCRAPE THESE GAMES", false); mFilters->add("ALL GAMES", [](SystemData*, FileData*) -> bool { return true; }, true); mFilters->add("NO METADATA", @@ -50,7 +50,7 @@ GuiScraperMenu::GuiScraperMenu(Window* window) : GuiComponent(window), // Add systems (all systems with an existing platform ID are listed). mSystems = std::make_shared< OptionListComponent> - (mWindow, "SCRAPE THESE SYSTEMS", true); + (mWindow, getHelpStyle(), "SCRAPE THESE SYSTEMS", true); for (unsigned int i = 0; i < SystemData::sSystemVector.size(); i++) { if (!SystemData::sSystemVector[i]->hasPlatformId(PlatformIds::PLATFORM_IGNORE)) { mSystems->add(SystemData::sSystemVector[i]->getFullName(), @@ -153,7 +153,7 @@ void GuiScraperMenu::openOtherSettings() // Scraper region. auto scraper_region = std::make_shared> - (mWindow, "REGION", false); + (mWindow, getHelpStyle(), "REGION", false); std::vector transitions_rg; transitions_rg.push_back("eu"); transitions_rg.push_back("jp"); @@ -176,7 +176,7 @@ void GuiScraperMenu::openOtherSettings() // Scraper language. auto scraper_language = std::make_shared> - (mWindow, "LANGUAGE", false); + (mWindow, getHelpStyle(), "LANGUAGE", false); std::vector transitions_lg; transitions_lg.push_back("en"); transitions_lg.push_back("wor"); @@ -220,7 +220,7 @@ void GuiScraperMenu::pressedStart() std::vector sys = mSystems->getSelectedObjects(); for (auto it = sys.cbegin(); it != sys.cend(); it++) { if ((*it)->getPlatformIds().empty()) { - mWindow->pushGui(new GuiMsgBox(mWindow, + mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), Utils::String::toUpper("Warning: some of your selected systems do not " "have a platform set. Results may be even more inaccurate than " "usual!\nContinue anyway?"), @@ -238,7 +238,7 @@ void GuiScraperMenu::start() mFilters->getSelected()); if (searches.empty()) { - mWindow->pushGui(new GuiMsgBox(mWindow, + mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), "NO GAMES TO SCRAPE")); } else { @@ -302,13 +302,6 @@ bool GuiScraperMenu::input(InputConfig* config, Input input) return false; } -HelpStyle GuiScraperMenu::getHelpStyle() -{ - HelpStyle style = HelpStyle(); - style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); - return style; -} - std::vector GuiScraperMenu::getHelpPrompts() { std::vector prompts; @@ -317,3 +310,10 @@ std::vector GuiScraperMenu::getHelpPrompts() prompts.push_back(HelpPrompt("start", "close")); return prompts; } + +HelpStyle GuiScraperMenu::getHelpStyle() +{ + HelpStyle style = HelpStyle(); + style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + return style; +} diff --git a/es-app/src/guis/GuiScraperMulti.cpp b/es-app/src/guis/GuiScraperMulti.cpp index 763a44f71..fcb3a174b 100644 --- a/es-app/src/guis/GuiScraperMulti.cpp +++ b/es-app/src/guis/GuiScraperMulti.cpp @@ -169,7 +169,7 @@ void GuiScraperMulti::finish() " SKIPPED"; } - mWindow->pushGui(new GuiMsgBox(mWindow, ss.str(), "OK", [&] { + mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), ss.str(), "OK", [&] { delete this; })); mIsProcessing = false; @@ -180,3 +180,10 @@ std::vector GuiScraperMulti::getHelpPrompts() { return mGrid.getHelpPrompts(); } + +HelpStyle GuiScraperMulti::getHelpStyle() +{ + HelpStyle style = HelpStyle(); + style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + return style; +} diff --git a/es-app/src/guis/GuiScraperMulti.h b/es-app/src/guis/GuiScraperMulti.h index a93e6c53e..9a366f85f 100644 --- a/es-app/src/guis/GuiScraperMulti.h +++ b/es-app/src/guis/GuiScraperMulti.h @@ -31,7 +31,9 @@ public: virtual ~GuiScraperMulti(); void onSizeChanged() override; + std::vector getHelpPrompts() override; + HelpStyle getHelpStyle() override; private: void acceptResult(const ScraperSearchResult& result); diff --git a/es-app/src/guis/GuiScraperSearch.cpp b/es-app/src/guis/GuiScraperSearch.cpp index 1c017bf52..e3232712d 100644 --- a/es-app/src/guis/GuiScraperSearch.cpp +++ b/es-app/src/guis/GuiScraperSearch.cpp @@ -23,11 +23,13 @@ #include "guis/GuiTextEditPopup.h" #include "resources/Font.h" #include "utils/StringUtil.h" -#include "PlatformId.h" -#include "MameNames.h" -#include "SystemData.h" +#include "views/ViewController.h" +#include "CollectionSystemManager.h" #include "FileData.h" #include "Log.h" +#include "MameNames.h" +#include "PlatformId.h" +#include "SystemData.h" #include "Window.h" GuiScraperSearch::GuiScraperSearch( @@ -277,8 +279,9 @@ void GuiScraperSearch::onSearchDone(const std::vector& resu if (results.empty()) { // Check if the scraper used is still valid. if (!isValidConfiguredScraper()) { - mWindow->pushGui(new GuiMsgBox(mWindow, Utils::String::toUpper("Configured scraper " - "is no longer available.\nPlease change the scraping source in the settings."), + mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), + Utils::String::toUpper("Configured scraper is no longer available.\n" + "Please change the scraping source in the settings."), "FINISH", mSkipCallback)); } else { @@ -325,7 +328,7 @@ void GuiScraperSearch::onSearchDone(const std::vector& resu void GuiScraperSearch::onSearchError(const std::string& error) { LOG(LogInfo) << "GuiScraperSearch search error: " << error; - mWindow->pushGui(new GuiMsgBox(mWindow, Utils::String::toUpper(error), + mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), Utils::String::toUpper(error), "RETRY", std::bind(&GuiScraperSearch::search, this, mLastSearch), "SKIP", mSkipCallback, "CANCEL", mCancelCallback)); @@ -584,7 +587,7 @@ void GuiScraperSearch::openInputScreen(ScraperSearchParams& params) if (params.system->hasPlatformId(PlatformIds::ARCADE) || params.system->hasPlatformId(PlatformIds::NEOGEO)) { - mWindow->pushGui(new GuiTextEditPopup(mWindow, "SEARCH FOR", + mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), "SEARCH FOR", // Initial value is last search if there was one, otherwise the clean path name. // If it's a MAME or Neo Geo game, expand the game name accordingly. params.nameOverride.empty() ? @@ -593,7 +596,7 @@ void GuiScraperSearch::openInputScreen(ScraperSearchParams& params) searchForFunc, false, "SEARCH", "APPLY CHANGES?")); } else { - mWindow->pushGui(new GuiTextEditPopup(mWindow, "SEARCH FOR", + mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), "SEARCH FOR", // Initial value is last search if there was one, otherwise the clean path name. params.nameOverride.empty() ? params.game->getCleanName() : params.nameOverride, searchForFunc, false, "SEARCH", "APPLY CHANGES?")); @@ -664,6 +667,13 @@ std::vector GuiScraperSearch::getHelpPrompts() return prompts; } +HelpStyle GuiScraperSearch::getHelpStyle() +{ + HelpStyle style = HelpStyle(); + style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + return style; +} + void GuiScraperSearch::onFocusGained() { mGrid.onFocusGained(); diff --git a/es-app/src/guis/GuiScraperSearch.h b/es-app/src/guis/GuiScraperSearch.h index 6045c866e..254dc008f 100644 --- a/es-app/src/guis/GuiScraperSearch.h +++ b/es-app/src/guis/GuiScraperSearch.h @@ -57,6 +57,7 @@ public: void update(int deltaTime) override; void render(const Transform4x4f& parentTrans) override; std::vector getHelpPrompts() override; + HelpStyle getHelpStyle() override; void onSizeChanged() override; void onFocusGained() override; void onFocusLost() override; diff --git a/es-app/src/guis/GuiScreensaverOptions.cpp b/es-app/src/guis/GuiScreensaverOptions.cpp index 6537694e5..095361ea7 100644 --- a/es-app/src/guis/GuiScreensaverOptions.cpp +++ b/es-app/src/guis/GuiScreensaverOptions.cpp @@ -89,7 +89,7 @@ void GuiScreensaverOptions::addEditableTextComponent(ComponentListRow row, const auto updateVal = [ed](const std::string& newVal) { ed->setValue(newVal); }; // ok callback (apply new value to ed) row.makeAcceptInputHandler([this, label, ed, updateVal] { - mWindow->pushGui(new GuiTextEditPopup(mWindow, label, ed->getValue(), updateVal, false)); + mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), label, ed->getValue(), updateVal, false)); }); assert(ed); addRow(row); diff --git a/es-app/src/guis/GuiVideoScreensaverOptions.cpp b/es-app/src/guis/GuiVideoScreensaverOptions.cpp index b757a8761..840b7ac1c 100644 --- a/es-app/src/guis/GuiVideoScreensaverOptions.cpp +++ b/es-app/src/guis/GuiVideoScreensaverOptions.cpp @@ -31,7 +31,7 @@ GuiVideoScreensaverOptions::GuiVideoScreensaverOptions(Window* window, const cha #endif // Render Video Game Name as subtitles - auto ss_info = std::make_shared< OptionListComponent >(mWindow, "SHOW GAME INFO", false); + auto ss_info = std::make_shared< OptionListComponent >(mWindow, getHelpStyle(), "SHOW GAME INFO", false); std::vector info_type; info_type.push_back("always"); info_type.push_back("start & end"); diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 3b459d997..f80d47b80 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -381,9 +381,12 @@ int main(int argc, char* argv[]) return 1; } + HelpStyle helpStyle = HelpStyle(); + helpStyle.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system"); + // We can't handle es_systems.cfg file problems inside ES itself, // so display the error message and then quit. - window.pushGui(new GuiMsgBox(&window, + window.pushGui(new GuiMsgBox(&window, helpStyle, errorMsg, "QUIT", [] { SDL_Event* quit = new SDL_Event(); diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index f36284db9..41d214fcf 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -131,7 +131,7 @@ void SystemView::populate() // Something is wrong, there is not a single system to show, check if UI mode is not full. if (!UIModeController::getInstance()->isUIModeFull()) { Settings::getInstance()->setString("UIMode", "Full"); - mWindow->pushGui(new GuiMsgBox(mWindow, + mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), "The selected UI mode has nothing to show,\n returning to UI mode: FULL", "OK", nullptr)); } diff --git a/es-core/src/components/OptionListComponent.h b/es-core/src/components/OptionListComponent.h index cfbf98568..36b700fc3 100644 --- a/es-core/src/components/OptionListComponent.h +++ b/es-core/src/components/OptionListComponent.h @@ -1,141 +1,45 @@ +// +// OptionListComponent.h +// +// Provides a list of options. +// Supports various types using templates. +// + #pragma once #ifndef ES_CORE_COMPONENTS_OPTION_LIST_COMPONENT_H #define ES_CORE_COMPONENTS_OPTION_LIST_COMPONENT_H +#define CHECKED_PATH ":/checkbox_checked.svg" +#define UNCHECKED_PATH ":/checkbox_unchecked.svg" + #include "GuiComponent.h" #include "Log.h" #include "Window.h" -//Used to display a list of options. -//Can select one or multiple options. +// Used to display a list of options. +// Can select one or multiple options. // if !multiSelect // * <- curEntry -> - -// always -// * press a -> open full list - -#define CHECKED_PATH ":/checkbox_checked.svg" -#define UNCHECKED_PATH ":/checkbox_unchecked.svg" +// Always +// * press a -> open full list. template class OptionListComponent : public GuiComponent { -private: - struct OptionListData - { - std::string name; - T object; - bool selected; - }; - - class OptionListPopup : public GuiComponent - { - private: - MenuComponent mMenu; - OptionListComponent* mParent; - - public: - OptionListPopup(Window* window, OptionListComponent* parent, const std::string& title) : GuiComponent(window), - mMenu(window, title.c_str()), mParent(parent) - { - auto font = Font::get(FONT_SIZE_MEDIUM); - ComponentListRow row; - - // for select all/none - std::vector checkboxes; - - for(auto it = mParent->mEntries.begin(); it != mParent->mEntries.end(); it++) - { - row.elements.clear(); - row.addElement(std::make_shared(mWindow, Utils::String::toUpper(it->name), font, 0x777777FF), true); - - OptionListData& e = *it; - - if(mParent->mMultiSelect) - { - // add checkbox - auto checkbox = std::make_shared(mWindow); - checkbox->setImage(it->selected ? CHECKED_PATH : UNCHECKED_PATH); - checkbox->setResize(0, font->getLetterHeight()); - row.addElement(checkbox, false); - - // input handler - // update checkbox state & selected value - row.makeAcceptInputHandler([this, &e, checkbox] - { - e.selected = !e.selected; - checkbox->setImage(e.selected ? CHECKED_PATH : UNCHECKED_PATH); - mParent->onSelectedChanged(); - }); - - // for select all/none - checkboxes.push_back(checkbox.get()); - }else{ - // input handler for non-multiselect - // update selected value and close - row.makeAcceptInputHandler([this, &e] - { - mParent->mEntries.at(mParent->getSelectedId()).selected = false; - e.selected = true; - mParent->onSelectedChanged(); - delete this; - }); - } - - // also set cursor to this row if we're not multi-select and this row is selected - mMenu.addRow(row, (!mParent->mMultiSelect && it->selected)); - } - - mMenu.addButton("BACK", "accept", [this] { delete this; }); - - if(mParent->mMultiSelect) - { - mMenu.addButton("SELECT ALL", "select all", [this, checkboxes] { - for(unsigned int i = 0; i < mParent->mEntries.size(); i++) - { - mParent->mEntries.at(i).selected = true; - checkboxes.at(i)->setImage(CHECKED_PATH); - } - mParent->onSelectedChanged(); - }); - - mMenu.addButton("SELECT NONE", "select none", [this, checkboxes] { - for(unsigned int i = 0; i < mParent->mEntries.size(); i++) - { - mParent->mEntries.at(i).selected = false; - checkboxes.at(i)->setImage(UNCHECKED_PATH); - } - mParent->onSelectedChanged(); - }); - } - - mMenu.setPosition((Renderer::getScreenWidth() - mMenu.getSize().x()) / 2, Renderer::getScreenHeight() * 0.15f); - addChild(&mMenu); - } - - bool input(InputConfig* config, Input input) override - { - if(config->isMappedTo("b", input) && input.value != 0) - { - delete this; - return true; - } - - return GuiComponent::input(config, input); - } - - std::vector getHelpPrompts() override - { - auto prompts = mMenu.getHelpPrompts(); - prompts.push_back(HelpPrompt("b", "back")); - return prompts; - } - }; - public: - OptionListComponent(Window* window, const std::string& name, bool multiSelect = false) : GuiComponent(window), mMultiSelect(multiSelect), mName(name), - mText(window), mLeftArrow(window), mRightArrow(window) + OptionListComponent( + Window* window, + const HelpStyle& helpstyle, + const std::string& name, + bool multiSelect = false) + : GuiComponent(window), + mHelpStyle(helpstyle), + mMultiSelect(multiSelect), + mName(name), + mText(window), + mLeftArrow(window), + mRightArrow(window) { auto font = Font::get(FONT_SIZE_MEDIUM, FONT_PATH_LIGHT); mText.setFont(font); @@ -146,11 +50,11 @@ public: mLeftArrow.setResize(0, mText.getFont()->getLetterHeight()); mRightArrow.setResize(0, mText.getFont()->getLetterHeight()); - if(mMultiSelect) - { + if(mMultiSelect) { mRightArrow.setImage(":/arrow.svg"); addChild(&mRightArrow); - }else{ + } + else { mLeftArrow.setImage(":/option_arrow.svg"); mLeftArrow.setFlipX(true); addChild(&mLeftArrow); @@ -162,7 +66,7 @@ public: setSize(mLeftArrow.getSize().x() + mRightArrow.getSize().x(), font->getHeight()); } - // handles positioning/resizing of text and arrows + // Handles positioning/resizing of text and arrows. void onSizeChanged() override { mLeftArrow.setResize(0, mText.getFont()->getLetterHeight()); @@ -171,28 +75,27 @@ public: if(mSize.x() < (mLeftArrow.getSize().x() + mRightArrow.getSize().x())) LOG(LogWarning) << "OptionListComponent too narrow!"; - mText.setSize(mSize.x() - mLeftArrow.getSize().x() - mRightArrow.getSize().x(), mText.getFont()->getHeight()); + mText.setSize(mSize.x() - mLeftArrow.getSize().x() - + mRightArrow.getSize().x(), mText.getFont()->getHeight()); - // position + // Position. mLeftArrow.setPosition(0, (mSize.y() - mLeftArrow.getSize().y()) / 2); - mText.setPosition(mLeftArrow.getPosition().x() + mLeftArrow.getSize().x(), (mSize.y() - mText.getSize().y()) / 2); - mRightArrow.setPosition(mText.getPosition().x() + mText.getSize().x(), (mSize.y() - mRightArrow.getSize().y()) / 2); + mText.setPosition(mLeftArrow.getPosition().x() + mLeftArrow.getSize().x(), + (mSize.y() - mText.getSize().y()) / 2); + mRightArrow.setPosition(mText.getPosition().x() + mText.getSize().x(), + (mSize.y() - mRightArrow.getSize().y()) / 2); } bool input(InputConfig* config, Input input) override { - if(input.value != 0) - { - if(config->isMappedTo("a", input)) - { + if(input.value != 0) { + if(config->isMappedTo("a", input)) { open(); return true; } - if(!mMultiSelect) - { - if(config->isMappedLike("left", input)) - { - // move selection to previous + if(!mMultiSelect) { + if(config->isMappedLike("left", input)) { + // Move selection to previous. unsigned int i = getSelectedId(); int next = (int)i - 1; if(next < 0) @@ -203,16 +106,15 @@ public: onSelectedChanged(); return true; - }else if(config->isMappedLike("right", input)) - { - // move selection to next + } + else if(config->isMappedLike("right", input)) { + // Move selection to next. unsigned int i = getSelectedId(); int next = (i + 1) % mEntries.size(); mEntries.at(i).selected = false; mEntries.at(next).selected = true; onSelectedChanged(); return true; - } } } @@ -222,8 +124,7 @@ public: std::vector getSelectedObjects() { std::vector ret; - for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++) - { + for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++) { if(it->selected) ret.push_back(it->object); } @@ -277,62 +178,67 @@ public: void selectAll() { for(unsigned int i = 0; i < mEntries.size(); i++) - { mEntries.at(i).selected = true; - } onSelectedChanged(); } void selectNone() { for(unsigned int i = 0; i < mEntries.size(); i++) - { mEntries.at(i).selected = false; - } onSelectedChanged(); } + HelpStyle getHelpStyle() override { return mHelpStyle; }; + private: + struct OptionListData { + std::string name; + T object; + bool selected; + }; + + HelpStyle mHelpStyle; + unsigned int getSelectedId() { assert(mMultiSelect == false); - for(unsigned int i = 0; i < mEntries.size(); i++) - { + for(unsigned int i = 0; i < mEntries.size(); i++) { if(mEntries.at(i).selected) return i; } - LOG(LogWarning) << "OptionListComponent::getSelectedId() - no selected element found, defaulting to 0"; + LOG(LogWarning) << "OptionListComponent::getSelectedId() - " + "no selected element found, defaulting to 0"; return 0; } void open() { - mWindow->pushGui(new OptionListPopup(mWindow, this, mName)); + mWindow->pushGui(new OptionListPopup(mWindow, getHelpStyle(), this, mName)); } void onSelectedChanged() { - if(mMultiSelect) - { - // display # selected + if(mMultiSelect) { + // Display # selected. std::stringstream ss; ss << getSelectedObjects().size() << " SELECTED"; mText.setText(ss.str()); mText.setSize(0, mText.getSize().y()); setSize(mText.getSize().x() + mRightArrow.getSize().x() + 24, mText.getSize().y()); - if(mParent) // hack since theres no "on child size changed" callback atm... + if(mParent) // Hack since theres no "on child size changed" callback atm... mParent->onSizeChanged(); - }else{ - // display currently selected + l/r cursors - for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++) - { - if(it->selected) - { + } + else { + // Display currently selected + l/r cursors. + for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++) { + if(it->selected) { mText.setText(Utils::String::toUpper(it->name)); mText.setSize(0, mText.getSize().y()); - setSize(mText.getSize().x() + mLeftArrow.getSize().x() + mRightArrow.getSize().x() + 24, mText.getSize().y()); - if(mParent) // hack since theres no "on child size changed" callback atm... + setSize(mText.getSize().x() + mLeftArrow.getSize().x() + + mRightArrow.getSize().x() + 24, mText.getSize().y()); + if(mParent) // Hack since theres no "on child size changed" callback atm... mParent->onSizeChanged(); break; } @@ -358,6 +264,116 @@ private: ImageComponent mRightArrow; std::vector mEntries; + + // Subclass to OptionListComponent. + class OptionListPopup : public GuiComponent + { + public: + OptionListPopup( + Window* window, + const HelpStyle& helpstyle, + OptionListComponent* parent, + const std::string& title) + : GuiComponent(window), + mHelpStyle(helpstyle), + mMenu(window, title.c_str()), + mParent(parent) + { + auto font = Font::get(FONT_SIZE_MEDIUM); + ComponentListRow row; + + // For select all/none. + std::vector checkboxes; + + for(auto it = mParent->mEntries.begin(); it != mParent->mEntries.end(); it++) { + row.elements.clear(); + row.addElement(std::make_shared + (mWindow, Utils::String::toUpper(it->name), font, 0x777777FF), true); + + OptionListData& e = *it; + + if(mParent->mMultiSelect) { + // Add checkbox. + auto checkbox = std::make_shared(mWindow); + checkbox->setImage(it->selected ? CHECKED_PATH : UNCHECKED_PATH); + checkbox->setResize(0, font->getLetterHeight()); + row.addElement(checkbox, false); + + // Input handler. + // Update checkbox state & selected value. + row.makeAcceptInputHandler([this, &e, checkbox] { + e.selected = !e.selected; + checkbox->setImage(e.selected ? CHECKED_PATH : UNCHECKED_PATH); + mParent->onSelectedChanged(); + }); + + // For select all/none. + checkboxes.push_back(checkbox.get()); + } + else { + // Input handler for non-multiselect. + // Update selected value and close. + row.makeAcceptInputHandler([this, &e] { + mParent->mEntries.at(mParent->getSelectedId()).selected = false; + e.selected = true; + mParent->onSelectedChanged(); + delete this; + }); + } + + // Also set cursor to this row if we're not multi-select and this row is selected. + mMenu.addRow(row, (!mParent->mMultiSelect && it->selected)); + } + + mMenu.addButton("BACK", "accept", [this] { delete this; }); + + if(mParent->mMultiSelect) { + mMenu.addButton("SELECT ALL", "select all", [this, checkboxes] { + for(unsigned int i = 0; i < mParent->mEntries.size(); i++) { + mParent->mEntries.at(i).selected = true; + checkboxes.at(i)->setImage(CHECKED_PATH); + } + mParent->onSelectedChanged(); + }); + + mMenu.addButton("SELECT NONE", "select none", [this, checkboxes] { + for(unsigned int i = 0; i < mParent->mEntries.size(); i++) { + mParent->mEntries.at(i).selected = false; + checkboxes.at(i)->setImage(UNCHECKED_PATH); + } + mParent->onSelectedChanged(); + }); + } + + mMenu.setPosition((Renderer::getScreenWidth() - mMenu.getSize().x()) / 2, + Renderer::getScreenHeight() * 0.15f); + addChild(&mMenu); + } + + bool input(InputConfig* config, Input input) override + { + if(config->isMappedTo("b", input) && input.value != 0) { + delete this; + return true; + } + + return GuiComponent::input(config, input); + } + + std::vector getHelpPrompts() override + { + auto prompts = mMenu.getHelpPrompts(); + prompts.push_back(HelpPrompt("b", "back")); + return prompts; + } + + HelpStyle getHelpStyle() override { return mHelpStyle; }; + + private: + MenuComponent mMenu; + OptionListComponent* mParent; + HelpStyle mHelpStyle; + }; }; #endif // ES_CORE_COMPONENTS_OPTION_LIST_COMPONENT_H diff --git a/es-core/src/guis/GuiComplexTextEditPopup.cpp b/es-core/src/guis/GuiComplexTextEditPopup.cpp index c1e689986..b4ee95ad7 100644 --- a/es-core/src/guis/GuiComplexTextEditPopup.cpp +++ b/es-core/src/guis/GuiComplexTextEditPopup.cpp @@ -16,6 +16,7 @@ GuiComplexTextEditPopup::GuiComplexTextEditPopup( Window* window, + const HelpStyle& helpstyle, const std::string& title, const std::string& infoString1, const std::string& infoString2, @@ -25,6 +26,7 @@ GuiComplexTextEditPopup::GuiComplexTextEditPopup( const char* acceptBtnText, const char* saveConfirmationText) : GuiComponent(window), + mHelpStyle(helpstyle), mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 5)), mMultiLine(multiLine), @@ -102,7 +104,7 @@ bool GuiComplexTextEditPopup::input(InputConfig* config, Input input) if (config->isMappedTo("b", input) && input.value) { if (mText->getValue() != mInitValue) { // Changes were made, ask if the user wants to save them. - mWindow->pushGui(new GuiMsgBox(mWindow, mSaveConfirmationText, "YES", + mWindow->pushGui(new GuiMsgBox(mWindow, mHelpStyle, mSaveConfirmationText, "YES", [this] { this->mOkCallback(mText->getValue()); delete this; return true; }, "NO", [this] { delete this; return false; })); } diff --git a/es-core/src/guis/GuiComplexTextEditPopup.h b/es-core/src/guis/GuiComplexTextEditPopup.h index 5046d7bcd..5027e0c12 100644 --- a/es-core/src/guis/GuiComplexTextEditPopup.h +++ b/es-core/src/guis/GuiComplexTextEditPopup.h @@ -22,6 +22,7 @@ class GuiComplexTextEditPopup : public GuiComponent public: GuiComplexTextEditPopup( Window* window, + const HelpStyle& helpstyle, const std::string& title, const std::string& infoString1, const std::string& infoString2, @@ -33,7 +34,9 @@ public: bool input(InputConfig* config, Input input); void onSizeChanged(); + std::vector getHelpPrompts() override; + HelpStyle getHelpStyle() override { return mHelpStyle; }; private: NinePatchComponent mBackground; @@ -45,6 +48,7 @@ private: std::shared_ptr mText; std::shared_ptr mButtonGrid; + HelpStyle mHelpStyle; bool mMultiLine; std::string mInitValue; std::function mOkCallback; diff --git a/es-core/src/guis/GuiInputConfig.cpp b/es-core/src/guis/GuiInputConfig.cpp index c3d72f9c3..0ea60b095 100755 --- a/es-core/src/guis/GuiInputConfig.cpp +++ b/es-core/src/guis/GuiInputConfig.cpp @@ -191,7 +191,7 @@ GuiInputConfig::GuiInputConfig(Window* window, InputConfig* target, bool reconfi // check if the hotkey enable button is set. if not prompt the user to use select or nothing. Input input; if (!mTargetConfig->getInputByName("HotKeyEnable", &input)) { - mWindow->pushGui(new GuiMsgBox(mWindow, + mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), "YOU DIDN'T CHOOSE A HOTKEY ENABLE BUTTON. THIS IS REQUIRED FOR EXITING GAMES WITH A CONTROLLER. DO YOU WANT TO USE THE SELECT BUTTON DEFAULT ? PLEASE ANSWER YES TO USE SELECT OR NO TO NOT SET A HOTKEY ENABLE BUTTON.", "YES", [this, okFunction] { Input input; diff --git a/es-core/src/guis/GuiMsgBox.cpp b/es-core/src/guis/GuiMsgBox.cpp index 367ebf9e0..88b550ecd 100644 --- a/es-core/src/guis/GuiMsgBox.cpp +++ b/es-core/src/guis/GuiMsgBox.cpp @@ -12,11 +12,12 @@ #define HORIZONTAL_PADDING_PX 20 -GuiMsgBox::GuiMsgBox(Window* window, const std::string& text, +GuiMsgBox::GuiMsgBox(Window* window, const HelpStyle& helpstyle, const std::string& text, const std::string& name1, const std::function& func1, const std::string& name2, const std::function& func2, const std::string& name3, const std::function& func3) : GuiComponent(window), + mHelpStyle(helpstyle), mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 2)) { diff --git a/es-core/src/guis/GuiMsgBox.h b/es-core/src/guis/GuiMsgBox.h index a22ed93dd..60b547b56 100644 --- a/es-core/src/guis/GuiMsgBox.h +++ b/es-core/src/guis/GuiMsgBox.h @@ -19,14 +19,16 @@ class TextComponent; class GuiMsgBox : public GuiComponent { public: - GuiMsgBox(Window* window, const std::string& text, + GuiMsgBox(Window* window, const HelpStyle& helpstyle, const std::string& text, const std::string& name1 = "OK", const std::function& func1 = nullptr, const std::string& name2 = "", const std::function& func2 = nullptr, const std::string& name3 = "", const std::function& func3 = nullptr); bool input(InputConfig* config, Input input) override; void onSizeChanged() override; + std::vector getHelpPrompts() override; + HelpStyle getHelpStyle() override { return mHelpStyle; }; private: void deleteMeAndCall(const std::function& func); @@ -34,6 +36,7 @@ private: NinePatchComponent mBackground; ComponentGrid mGrid; + HelpStyle mHelpStyle; std::shared_ptr mMsg; std::vector> mButtons; std::shared_ptr mButtonGrid; diff --git a/es-core/src/guis/GuiTextEditPopup.cpp b/es-core/src/guis/GuiTextEditPopup.cpp index 6eabe9b74..9fbf4ecf0 100644 --- a/es-core/src/guis/GuiTextEditPopup.cpp +++ b/es-core/src/guis/GuiTextEditPopup.cpp @@ -14,6 +14,7 @@ GuiTextEditPopup::GuiTextEditPopup( Window* window, + const HelpStyle& helpstyle, const std::string& title, const std::string& initValue, const std::function& okCallback, @@ -21,6 +22,7 @@ GuiTextEditPopup::GuiTextEditPopup( const char* acceptBtnText, const char* saveConfirmationText) : GuiComponent(window), + mHelpStyle(helpstyle), mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 3)), mMultiLine(multiLine), @@ -86,7 +88,7 @@ bool GuiTextEditPopup::input(InputConfig* config, Input input) if (config->isMappedTo("b", input) && input.value) { if (mText->getValue() != mInitValue) { // Changes were made, ask if the user wants to save them. - mWindow->pushGui(new GuiMsgBox(mWindow, mSaveConfirmationText, "YES", + mWindow->pushGui(new GuiMsgBox(mWindow, mHelpStyle, mSaveConfirmationText, "YES", [this] { this->mOkCallback(mText->getValue()); delete this; return true; }, "NO", [this] { delete this; return false; })); } diff --git a/es-core/src/guis/GuiTextEditPopup.h b/es-core/src/guis/GuiTextEditPopup.h index 52fa6f0dc..1ddaeaaaf 100644 --- a/es-core/src/guis/GuiTextEditPopup.h +++ b/es-core/src/guis/GuiTextEditPopup.h @@ -20,6 +20,7 @@ class GuiTextEditPopup : public GuiComponent public: GuiTextEditPopup( Window* window, + const HelpStyle& helpstyle, const std::string& title, const std::string& initValue, const std::function& okCallback, @@ -29,7 +30,9 @@ public: bool input(InputConfig* config, Input input); void onSizeChanged(); + std::vector getHelpPrompts() override; + HelpStyle getHelpStyle() override { return mHelpStyle; }; private: NinePatchComponent mBackground; @@ -39,6 +42,7 @@ private: std::shared_ptr mText; std::shared_ptr mButtonGrid; + HelpStyle mHelpStyle; bool mMultiLine; std::string mInitValue; std::function mOkCallback;