Expanded support for help system theming to entire application, as before it was only partially implemented.

This commit is contained in:
Leon Styhre 2020-06-07 20:09:02 +02:00
parent b7d4274c6e
commit c5e70385dd
28 changed files with 356 additions and 257 deletions

View file

@ -7,6 +7,7 @@
#include "utils/StringUtil.h" #include "utils/StringUtil.h"
#include "views/ViewController.h" #include "views/ViewController.h"
#include "CollectionSystemManager.h" #include "CollectionSystemManager.h"
#include "SystemData.h"
#include "Window.h" #include "Window.h"
GuiCollectionSystemsOptions::GuiCollectionSystemsOptions(Window* window) : GuiComponent(window), mMenu(window, "GAME COLLECTION SETTINGS") 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, addEntry("CREATE NEW CUSTOM COLLECTION FROM THEME", 0x777777FF, true,
[this, unusedFolders] { [this, unusedFolders] {
auto s = new GuiSettings(mWindow, "SELECT THEME FOLDER"); auto s = new GuiSettings(mWindow, "SELECT THEME FOLDER");
std::shared_ptr< OptionListComponent<std::string> > folderThemes = std::make_shared< OptionListComponent<std::string> >(mWindow, "SELECT THEME FOLDER", true); std::shared_ptr< OptionListComponent<std::string>>
folderThemes = std::make_shared< OptionListComponent<std::string>>
(mWindow, getHelpStyle(), "SELECT THEME FOLDER", true);
// add Custom Systems // add Custom Systems
for(auto it = unusedFolders.cbegin() ; it != unusedFolders.cend() ; it++ ) for(auto it = unusedFolders.cbegin() ; it != unusedFolders.cend() ; it++ )
@ -62,7 +65,7 @@ void GuiCollectionSystemsOptions::initializeMenu()
createCollection(name); createCollection(name);
}; };
row.makeAcceptInputHandler([this, createCustomCollection] { 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); mMenu.addRow(row);
@ -143,7 +146,7 @@ void GuiCollectionSystemsOptions::addSystemsToMenu()
std::map<std::string, CollectionSystemData> autoSystems = CollectionSystemManager::get()->getAutoCollectionSystems(); std::map<std::string, CollectionSystemData> autoSystems = CollectionSystemManager::get()->getAutoCollectionSystems();
autoOptionList = std::make_shared< OptionListComponent<std::string> >(mWindow, "SELECT COLLECTIONS", true); autoOptionList = std::make_shared< OptionListComponent<std::string> >(mWindow, getHelpStyle(), "SELECT COLLECTIONS", true);
// add Auto Systems // add Auto Systems
for(std::map<std::string, CollectionSystemData>::const_iterator it = autoSystems.cbegin() ; it != autoSystems.cend() ; it++ ) for(std::map<std::string, CollectionSystemData>::const_iterator it = autoSystems.cbegin() ; it != autoSystems.cend() ; it++ )
@ -154,7 +157,7 @@ void GuiCollectionSystemsOptions::addSystemsToMenu()
std::map<std::string, CollectionSystemData> customSystems = CollectionSystemManager::get()->getCustomCollectionSystems(); std::map<std::string, CollectionSystemData> customSystems = CollectionSystemManager::get()->getCustomCollectionSystems();
customOptionList = std::make_shared< OptionListComponent<std::string> >(mWindow, "SELECT COLLECTIONS", true); customOptionList = std::make_shared< OptionListComponent<std::string> >(mWindow, getHelpStyle(), "SELECT COLLECTIONS", true);
// add Custom Systems // add Custom Systems
for(std::map<std::string, CollectionSystemData>::const_iterator it = customSystems.cbegin() ; it != customSystems.cend() ; it++ ) for(std::map<std::string, CollectionSystemData>::const_iterator it = customSystems.cbegin() ; it != customSystems.cend() ; it++ )
@ -220,3 +223,10 @@ std::vector<HelpPrompt> GuiCollectionSystemsOptions::getHelpPrompts()
prompts.push_back(HelpPrompt("b", "back")); prompts.push_back(HelpPrompt("b", "back"));
return prompts; return prompts;
} }
HelpStyle GuiCollectionSystemsOptions::getHelpStyle()
{
HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
return style;
}

View file

@ -17,6 +17,7 @@ public:
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
virtual std::vector<HelpPrompt> getHelpPrompts() override; virtual std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override;
private: private:
void initializeMenu(); void initializeMenu();

View file

@ -11,6 +11,7 @@
#include "components/ButtonComponent.h" #include "components/ButtonComponent.h"
#include "components/MenuComponent.h" #include "components/MenuComponent.h"
#include "components/TextComponent.h" #include "components/TextComponent.h"
#include "views/ViewController.h"
#include "FileData.h" #include "FileData.h"
#include "PowerSaver.h" #include "PowerSaver.h"
#include "SystemData.h" #include "SystemData.h"
@ -137,6 +138,13 @@ std::vector<HelpPrompt> GuiGameScraper::getHelpPrompts()
return mGrid.getHelpPrompts(); return mGrid.getHelpPrompts();
} }
HelpStyle GuiGameScraper::getHelpStyle()
{
HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
return style;
}
void GuiGameScraper::close() void GuiGameScraper::close()
{ {
mClose = true; mClose = true;

View file

@ -26,7 +26,9 @@ public:
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
void update(int deltaTime); void update(int deltaTime);
virtual std::vector<HelpPrompt> getHelpPrompts() override; virtual std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override;
private: private:
bool mClose; bool mClose;

View file

@ -10,6 +10,7 @@
#include "components/OptionListComponent.h" #include "components/OptionListComponent.h"
#include "views/UIModeController.h" #include "views/UIModeController.h"
#include "views/ViewController.h"
#include "SystemData.h" #include "SystemData.h"
GuiGamelistFilter::GuiGamelistFilter( GuiGamelistFilter::GuiGamelistFilter(
@ -85,7 +86,8 @@ void GuiGamelistFilter::addFiltersToMenu()
ComponentListRow row; ComponentListRow row;
// Add genres. // Add genres.
optionList = std::make_shared< OptionListComponent<std::string> >(mWindow, menuLabel, true); optionList = std::make_shared< OptionListComponent<std::string>>
(mWindow, getHelpStyle(), menuLabel, true);
for (auto it: *allKeys) for (auto it: *allKeys)
optionList->add(it.first, it.first, mFilterIndex->isKeyBeingFilteredBy(it.first, type)); optionList->add(it.first, it.first, mFilterIndex->isKeyBeingFilteredBy(it.first, type));
if (allKeys->size() > 0) if (allKeys->size() > 0)
@ -126,3 +128,10 @@ std::vector<HelpPrompt> GuiGamelistFilter::getHelpPrompts()
prompts.push_back(HelpPrompt("b", "back")); prompts.push_back(HelpPrompt("b", "back"));
return prompts; return prompts;
} }
HelpStyle GuiGamelistFilter::getHelpStyle()
{
HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
return style;
}

View file

@ -27,6 +27,7 @@ public:
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
virtual std::vector<HelpPrompt> getHelpPrompts() override; virtual std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override;
private: private:
void initializeMenu(); void initializeMenu();

View file

@ -58,7 +58,8 @@ GuiGamelistOptions::GuiGamelistOptions(
if (curChar < startChar || curChar > endChar) if (curChar < startChar || curChar > endChar)
curChar = startChar; curChar = startChar;
mJumpToLetterList = std::make_shared<LetterList>(mWindow, "JUMP TO...", false); mJumpToLetterList = std::make_shared<LetterList>(mWindow, getHelpStyle(),
"JUMP TO...", false);
if (mFavoritesSorting && system->getName() != "favorites" && if (mFavoritesSorting && system->getName() != "favorites" &&
system->getName() != "recent") { system->getName() != "recent") {
@ -120,11 +121,11 @@ GuiGamelistOptions::GuiGamelistOptions(
mMenu.addRow(row); mMenu.addRow(row);
// Sort list by selected sort type (persistent throughout the program session). // Sort list by selected sort type (persistent throughout the program session).
mListSort = std::make_shared<SortList>(mWindow, "SORT GAMES BY", false); mListSort = std::make_shared<SortList>(mWindow, getHelpStyle(), "SORT GAMES BY", false);
FileData* root = mSystem->getRootFolder(); FileData* root = mSystem->getRootFolder();
std::string sortType = root->getSortTypeString(); std::string sortType = root->getSortTypeString();
for (unsigned int i = 0; i < FileSorts::SortTypes.size(); i++) { for (unsigned int i = 0; i <FileSorts::SortTypes.size(); i++) {
const FileData::SortType& sort = FileSorts::SortTypes.at(i); const FileData::SortType& sort = FileSorts::SortTypes.at(i);
if (sort.description == sortType) if (sort.description == sortType)
mListSort->add(sort.description, &sort, 1); mListSort->add(sort.description, &sort, 1);

View file

@ -26,7 +26,7 @@ GuiGeneralScreensaverOptions::GuiGeneralScreensaverOptions(Window* window, const
addSaveFunc([ss_controls] { Settings::getInstance()->setBool("ScreenSaverControls", ss_controls->getState()); }); addSaveFunc([ss_controls] { Settings::getInstance()->setBool("ScreenSaverControls", ss_controls->getState()); });
// screensaver behavior // screensaver behavior
auto screensaver_behavior = std::make_shared< OptionListComponent<std::string> >(mWindow, "SCREENSAVER BEHAVIOR", false); auto screensaver_behavior = std::make_shared< OptionListComponent<std::string> >(mWindow, getHelpStyle(), "SCREENSAVER BEHAVIOR", false);
std::vector<std::string> screensavers; std::vector<std::string> screensavers;
screensavers.push_back("dim"); screensavers.push_back("dim");
screensavers.push_back("black"); screensavers.push_back("black");
@ -38,7 +38,7 @@ GuiGeneralScreensaverOptions::GuiGeneralScreensaverOptions(Window* window, const
addSaveFunc([this, screensaver_behavior] { addSaveFunc([this, screensaver_behavior] {
if (Settings::getInstance()->getString("ScreenSaverBehavior") != "random video" && screensaver_behavior->getSelected() == "random video") { 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 // 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.", "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; })); "OK", [] { return; }));
} }

View file

@ -83,8 +83,8 @@ void GuiMenu::openSoundSettings()
if (UIModeController::getInstance()->isUIModeFull()) { if (UIModeController::getInstance()->isUIModeFull()) {
#if defined(__linux__) #if defined(__linux__)
// audio card // audio card
auto audio_card = std::make_shared< OptionListComponent<std::string> auto audio_card = std::make_shared<OptionListComponent<std::string>>
>(mWindow, "AUDIO CARD", false); (mWindow, getHelpStyle(), "AUDIO CARD", false);
std::vector<std::string> audio_cards; std::vector<std::string> audio_cards;
#ifdef _RPI_ #ifdef _RPI_
// RPi Specific Audio Cards // RPi Specific Audio Cards
@ -114,8 +114,8 @@ void GuiMenu::openSoundSettings()
}); });
// Volume control device. // Volume control device.
auto vol_dev = std::make_shared< OptionListComponent<std::string> auto vol_dev = std::make_shared<OptionListComponent<std::string>>
>(mWindow, "AUDIO DEVICE", false); (mWindow, getHelpStyle(), "AUDIO DEVICE", false);
std::vector<std::string> transitions; std::vector<std::string> transitions;
transitions.push_back("PCM"); transitions.push_back("PCM");
transitions.push_back("Speaker"); transitions.push_back("Speaker");
@ -140,8 +140,8 @@ void GuiMenu::openSoundSettings()
#ifdef _RPI_ #ifdef _RPI_
// OMX player Audio Device // OMX player Audio Device
auto omx_audio_dev = std::make_shared< OptionListComponent<std::string> auto omx_audio_dev = std::make_shared<OptionListComponent<std::string>>
>(mWindow, "OMX PLAYER AUDIO DEVICE", false); (mWindow, getHelpStyle(), "OMX PLAYER AUDIO DEVICE", false);
std::vector<std::string> omx_cards; std::vector<std::string> omx_cards;
// RPi Specific Audio Cards // RPi Specific Audio Cards
omx_cards.push_back("local"); omx_cards.push_back("local");
@ -194,8 +194,8 @@ void GuiMenu::openUISettings()
auto s = new GuiSettings(mWindow, "UI SETTINGS"); auto s = new GuiSettings(mWindow, "UI SETTINGS");
// Optionally start in selected system/gamelist. // Optionally start in selected system/gamelist.
auto systemfocus_list = std::make_shared< OptionListComponent<std::string> auto systemfocus_list = std::make_shared<OptionListComponent<std::string>>
>(mWindow, "GAMELIST ON STARTUP", false); (mWindow, getHelpStyle(), "GAMELIST ON STARTUP", false);
systemfocus_list->add("NONE", "", Settings::getInstance()->getString("StartupSystem") == ""); systemfocus_list->add("NONE", "", Settings::getInstance()->getString("StartupSystem") == "");
for (auto it = SystemData::sSystemVector.cbegin(); for (auto it = SystemData::sSystemVector.cbegin();
it != SystemData::sSystemVector.cend(); it++) { it != SystemData::sSystemVector.cend(); it++) {
@ -209,8 +209,8 @@ void GuiMenu::openUISettings()
}); });
// GameList view style. // GameList view style.
auto gamelist_style = std::make_shared< OptionListComponent<std::string> auto gamelist_style = std::make_shared<OptionListComponent<std::string>>
>(mWindow, "GAMELIST VIEW STYLE", false); (mWindow, getHelpStyle(), "GAMELIST VIEW STYLE", false);
std::vector<std::string> styles; std::vector<std::string> styles;
styles.push_back("automatic"); styles.push_back("automatic");
styles.push_back("basic"); styles.push_back("basic");
@ -233,8 +233,8 @@ void GuiMenu::openUISettings()
}); });
// Transition style. // Transition style.
auto transition_style = std::make_shared< OptionListComponent<std::string> auto transition_style = std::make_shared<OptionListComponent<std::string>>
>(mWindow, "TRANSITION STYLE", false); (mWindow, getHelpStyle(), "TRANSITION STYLE", false);
std::vector<std::string> transitions; std::vector<std::string> transitions;
transitions.push_back("fade"); transitions.push_back("fade");
transitions.push_back("slide"); transitions.push_back("slide");
@ -263,8 +263,8 @@ void GuiMenu::openUISettings()
if (selectedSet == themeSets.cend()) if (selectedSet == themeSets.cend())
selectedSet = themeSets.cbegin(); selectedSet = themeSets.cbegin();
auto theme_set = std::make_shared< OptionListComponent<std::string> auto theme_set = std::make_shared<OptionListComponent<std::string>>
>(mWindow, "THEME SET", false); (mWindow, getHelpStyle(), "THEME SET", false);
for (auto it = themeSets.cbegin(); it != themeSets.cend(); it++) for (auto it = themeSets.cbegin(); it != themeSets.cend(); it++)
theme_set->add(it->first, it->first, it == selectedSet); theme_set->add(it->first, it->first, it == selectedSet);
s->addWithLabel("THEME SET", theme_set); s->addWithLabel("THEME SET", theme_set);
@ -289,14 +289,14 @@ void GuiMenu::openUISettings()
} }
// UI mode. // UI mode.
auto UImodeSelection = std::make_shared< OptionListComponent<std::string> auto UImodeSelection = std::make_shared<OptionListComponent<std::string>>
>(mWindow, "UI MODE", false); (mWindow, getHelpStyle(), "UI MODE", false);
std::vector<std::string> UImodes = UIModeController::getInstance()->getUIModes(); std::vector<std::string> UImodes = UIModeController::getInstance()->getUIModes();
for (auto it = UImodes.cbegin(); it != UImodes.cend(); it++) for (auto it = UImodes.cbegin(); it != UImodes.cend(); it++)
UImodeSelection->add(*it, *it, Settings::getInstance()->getString("UIMode") == *it); UImodeSelection->add(*it, *it, Settings::getInstance()->getString("UIMode") == *it);
s->addWithLabel("UI MODE", UImodeSelection); s->addWithLabel("UI MODE", UImodeSelection);
Window* window = mWindow; Window* window = mWindow;
s->addSaveFunc([ UImodeSelection, window] { s->addSaveFunc([ UImodeSelection, window, this] {
std::string selectedMode = UImodeSelection->getSelected(); std::string selectedMode = UImodeSelection->getSelected();
if (selectedMode != "Full") { if (selectedMode != "Full") {
std::string msg = "You are changing the UI to a restricted mode:\n" + 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 += "To unlock and return to the full UI, enter this code: \n";
msg += "\"" + UIModeController::getInstance()->getFormattedPassKeyStr() + "\"\n\n"; msg += "\"" + UIModeController::getInstance()->getFormattedPassKeyStr() + "\"\n\n";
msg += "Do you want to proceed?"; msg += "Do you want to proceed?";
window->pushGui(new GuiMsgBox(window, msg, window->pushGui(new GuiMsgBox(window, this->getHelpStyle(), msg,
"YES", [selectedMode] { "YES", [selectedMode] {
LOG(LogDebug) << "Setting UI mode to " << selectedMode; LOG(LogDebug) << "Setting UI mode to " << selectedMode;
Settings::getInstance()->setString("UIMode", selectedMode); Settings::getInstance()->setString("UIMode", selectedMode);
@ -413,8 +413,8 @@ void GuiMenu::openOtherSettings()
(int)Math::round(max_vram->getValue())); }); (int)Math::round(max_vram->getValue())); });
// Fullscreen mode. // Fullscreen mode.
auto fullscreen_mode = std::make_shared< OptionListComponent<std::string> auto fullscreen_mode = std::make_shared<OptionListComponent<std::string>>
>(mWindow, "FULLSCREEN MODE", false); (mWindow, getHelpStyle(), "FULLSCREEN MODE", false);
std::vector<std::string> screenmode; std::vector<std::string> screenmode;
screenmode.push_back("normal"); screenmode.push_back("normal");
screenmode.push_back("borderless"); screenmode.push_back("borderless");
@ -431,8 +431,8 @@ void GuiMenu::openOtherSettings()
}); });
// Power saver. // Power saver.
auto power_saver = std::make_shared< OptionListComponent<std::string> auto power_saver = std::make_shared<OptionListComponent<std::string>>
>(mWindow, "POWER SAVER MODES", false); (mWindow, getHelpStyle(), "POWER SAVER MODES", false);
std::vector<std::string> modes; std::vector<std::string> modes;
modes.push_back("disabled"); modes.push_back("disabled");
modes.push_back("default"); modes.push_back("default");
@ -473,8 +473,8 @@ void GuiMenu::openOtherSettings()
#endif #endif
// When to save game metadata. // When to save game metadata.
auto gamelistsSaveMode = std::make_shared< OptionListComponent<std::string> auto gamelistsSaveMode = std::make_shared<OptionListComponent<std::string>>
>(mWindow, "SAVE METADATA", false); (mWindow, getHelpStyle(), "SAVE METADATA", false);
std::vector<std::string> saveModes; std::vector<std::string> saveModes;
saveModes.push_back("on exit"); saveModes.push_back("on exit");
saveModes.push_back("always"); saveModes.push_back("always");
@ -543,9 +543,9 @@ void GuiMenu::openOtherSettings()
void GuiMenu::openConfigInput() void GuiMenu::openConfigInput()
{ {
Window* window = mWindow; Window* window = mWindow;
window->pushGui(new GuiMsgBox(window, "ARE YOU SURE YOU WANT TO CONFIGURE INPUT?", "YES", window->pushGui(new GuiMsgBox(window, getHelpStyle(),
[window] { "ARE YOU SURE YOU WANT TO CONFIGURE INPUT?", "YES", [window] {
window->pushGui(new GuiDetectDevice(window, false, nullptr)); window->pushGui(new GuiDetectDevice(window, false, nullptr));
}, "NO", nullptr) }, "NO", nullptr)
); );
} }
@ -555,12 +555,14 @@ void GuiMenu::openQuitMenu()
auto s = new GuiSettings(mWindow, "QUIT"); auto s = new GuiSettings(mWindow, "QUIT");
Window* window = mWindow; Window* window = mWindow;
HelpStyle style = getHelpStyle();
ComponentListRow row; ComponentListRow row;
if (UIModeController::getInstance()->isUIModeFull()) { if (UIModeController::getInstance()->isUIModeFull()) {
if (Settings::getInstance()->getBool("ShowExit")) { if (Settings::getInstance()->getBool("ShowExit")) {
row.makeAcceptInputHandler([window] { row.makeAcceptInputHandler([window, this] {
window->pushGui(new GuiMsgBox(window, "REALLY QUIT?", "YES", window->pushGui(new GuiMsgBox(window, this->getHelpStyle(),
"REALLY QUIT?", "YES",
[] { [] {
Scripting::fireEvent("quit"); Scripting::fireEvent("quit");
quitES(); quitES();
@ -574,9 +576,9 @@ void GuiMenu::openQuitMenu()
if (Settings::getInstance()->getBool("ShowRebootSystem")) { if (Settings::getInstance()->getBool("ShowRebootSystem")) {
row.elements.clear(); row.elements.clear();
row.makeAcceptInputHandler([window] { row.makeAcceptInputHandler([window, this] {
window->pushGui(new GuiMsgBox(window, "REALLY REBOOT?", "YES", window->pushGui(new GuiMsgBox(window, this->getHelpStyle(),
[] { "REALLY REBOOT?", "YES", [] {
Scripting::fireEvent("quit", "reboot"); Scripting::fireEvent("quit", "reboot");
Scripting::fireEvent("reboot"); Scripting::fireEvent("reboot");
if (quitES(QuitMode::REBOOT) != 0) if (quitES(QuitMode::REBOOT) != 0)
@ -590,9 +592,9 @@ void GuiMenu::openQuitMenu()
if (Settings::getInstance()->getBool("ShowPoweroffSystem")) { if (Settings::getInstance()->getBool("ShowPoweroffSystem")) {
row.elements.clear(); row.elements.clear();
row.makeAcceptInputHandler([window] { row.makeAcceptInputHandler([window, this] {
window->pushGui(new GuiMsgBox(window, "REALLY POWER OFF?", "YES", window->pushGui(new GuiMsgBox(window, this->getHelpStyle(),
[] { "REALLY POWER OFF?", "YES", [] {
Scripting::fireEvent("quit", "poweroff"); Scripting::fireEvent("quit", "poweroff");
Scripting::fireEvent("poweroff"); Scripting::fireEvent("poweroff");
if (quitES(QuitMode::POWEROFF) != 0) if (quitES(QuitMode::POWEROFF) != 0)
@ -663,13 +665,6 @@ bool GuiMenu::input(InputConfig* config, Input input)
return false; return false;
} }
HelpStyle GuiMenu::getHelpStyle()
{
HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
return style;
}
std::vector<HelpPrompt> GuiMenu::getHelpPrompts() std::vector<HelpPrompt> GuiMenu::getHelpPrompts()
{ {
std::vector<HelpPrompt> prompts; std::vector<HelpPrompt> prompts;
@ -678,3 +673,10 @@ std::vector<HelpPrompt> GuiMenu::getHelpPrompts()
prompts.push_back(HelpPrompt("start", "close")); prompts.push_back(HelpPrompt("start", "close"));
return prompts; return prompts;
} }
HelpStyle GuiMenu::getHelpStyle()
{
HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
return style;
}

View file

@ -158,8 +158,8 @@ GuiMetaDataEd::GuiMetaDataEd(
row.makeAcceptInputHandler([this, title, staticTextString, row.makeAcceptInputHandler([this, title, staticTextString,
defaultLaunchString, ed, updateVal, multiLine] { defaultLaunchString, ed, updateVal, multiLine] {
mWindow->pushGui(new GuiComplexTextEditPopup(mWindow, title, mWindow->pushGui(new GuiComplexTextEditPopup(mWindow, getHelpStyle(),
staticTextString, defaultLaunchString, ed->getValue(), title, staticTextString, defaultLaunchString, ed->getValue(),
updateVal, multiLine)); updateVal, multiLine));
}); });
break; break;
@ -186,8 +186,8 @@ GuiMetaDataEd::GuiMetaDataEd(
// OK callback (apply new value to ed). // OK callback (apply new value to ed).
auto updateVal = [ed](const std::string& newVal) { ed->setValue(newVal); }; auto updateVal = [ed](const std::string& newVal) { ed->setValue(newVal); };
row.makeAcceptInputHandler([this, title, ed, updateVal, multiLine] { row.makeAcceptInputHandler([this, title, ed, updateVal, multiLine] {
mWindow->pushGui(new GuiTextEditPopup(mWindow, title, ed->getValue(), mWindow->pushGui(new GuiTextEditPopup(mWindow, getHelpStyle(), title,
updateVal, multiLine)); ed->getValue(), updateVal, multiLine));
}); });
break; break;
} }
@ -213,8 +213,9 @@ GuiMetaDataEd::GuiMetaDataEd(
if (mDeleteFunc) { if (mDeleteFunc) {
auto deleteFileAndSelf = [&] { mDeleteFunc(); delete this; }; auto deleteFileAndSelf = [&] { mDeleteFunc(); delete this; };
auto deleteBtnFunc = [this, deleteFileAndSelf] { mWindow->pushGui( auto deleteBtnFunc = [this, deleteFileAndSelf] { mWindow->pushGui(
new GuiMsgBox(mWindow, "THIS WILL DELETE THE ACTUAL GAME FILE(S)!\nARE " new GuiMsgBox(mWindow, getHelpStyle(),
"YOU SURE?", "YES", deleteFileAndSelf, "NO", nullptr)); }; "THIS WILL DELETE THE ACTUAL GAME FILE(S)!\nARE YOU SURE?",
"YES", deleteFileAndSelf, "NO", nullptr)); };
buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "DELETE", buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "DELETE",
"delete", deleteBtnFunc)); "delete", deleteBtnFunc));
} }
@ -337,7 +338,7 @@ void GuiMetaDataEd::close(bool closeAllWindows)
if (dirty) if (dirty)
{ {
// Changes were made, ask if the user wants to save them. // Changes were made, ask if the user wants to save them.
mWindow->pushGui(new GuiMsgBox(mWindow, mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(),
"SAVE CHANGES?", "SAVE CHANGES?",
"YES", [this, closeFunc] { save(); closeFunc(); }, "YES", [this, closeFunc] { save(); closeFunc(); },
"NO", closeFunc "NO", closeFunc
@ -369,3 +370,10 @@ std::vector<HelpPrompt> GuiMetaDataEd::getHelpPrompts()
prompts.push_back(HelpPrompt("start", "close")); prompts.push_back(HelpPrompt("start", "close"));
return prompts; return prompts;
} }
HelpStyle GuiMetaDataEd::getHelpStyle()
{
HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
return style;
}

View file

@ -33,7 +33,9 @@ public:
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
void onSizeChanged() override; void onSizeChanged() override;
virtual std::vector<HelpPrompt> getHelpPrompts() override; virtual std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override;
private: private:
void save(); void save();

View file

@ -21,8 +21,8 @@ GuiScraperMenu::GuiScraperMenu(Window* window) : GuiComponent(window),
mMenu(window, "SCRAPER") mMenu(window, "SCRAPER")
{ {
// Scrape from. // Scrape from.
auto scraper_list = std::make_shared< OptionListComponent<std::string>> auto scraper_list = std::make_shared<OptionListComponent<std::string>>
(mWindow, "SCRAPE FROM", false); (mWindow, getHelpStyle(), "SCRAPE FROM", false);
std::vector<std::string> scrapers = getScraperList(); std::vector<std::string> scrapers = getScraperList();
// Select either the first entry or the one read from the settings, // 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 // Search filters, getSearches() will generate a queue of games to scrape
// based on the outcome of the checks below. // based on the outcome of the checks below.
mFilters = std::make_shared< OptionListComponent<GameFilterFunc>> mFilters = std::make_shared< OptionListComponent<GameFilterFunc>>
(mWindow, "SCRAPE THESE GAMES", false); (mWindow, getHelpStyle(), "SCRAPE THESE GAMES", false);
mFilters->add("ALL GAMES", mFilters->add("ALL GAMES",
[](SystemData*, FileData*) -> bool { return true; }, true); [](SystemData*, FileData*) -> bool { return true; }, true);
mFilters->add("NO METADATA", 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). // Add systems (all systems with an existing platform ID are listed).
mSystems = std::make_shared< OptionListComponent<SystemData*>> mSystems = std::make_shared< OptionListComponent<SystemData*>>
(mWindow, "SCRAPE THESE SYSTEMS", true); (mWindow, getHelpStyle(), "SCRAPE THESE SYSTEMS", true);
for (unsigned int i = 0; i < SystemData::sSystemVector.size(); i++) { for (unsigned int i = 0; i < SystemData::sSystemVector.size(); i++) {
if (!SystemData::sSystemVector[i]->hasPlatformId(PlatformIds::PLATFORM_IGNORE)) { if (!SystemData::sSystemVector[i]->hasPlatformId(PlatformIds::PLATFORM_IGNORE)) {
mSystems->add(SystemData::sSystemVector[i]->getFullName(), mSystems->add(SystemData::sSystemVector[i]->getFullName(),
@ -153,7 +153,7 @@ void GuiScraperMenu::openOtherSettings()
// Scraper region. // Scraper region.
auto scraper_region = std::make_shared<OptionListComponent<std::string>> auto scraper_region = std::make_shared<OptionListComponent<std::string>>
(mWindow, "REGION", false); (mWindow, getHelpStyle(), "REGION", false);
std::vector<std::string> transitions_rg; std::vector<std::string> transitions_rg;
transitions_rg.push_back("eu"); transitions_rg.push_back("eu");
transitions_rg.push_back("jp"); transitions_rg.push_back("jp");
@ -176,7 +176,7 @@ void GuiScraperMenu::openOtherSettings()
// Scraper language. // Scraper language.
auto scraper_language = std::make_shared<OptionListComponent<std::string>> auto scraper_language = std::make_shared<OptionListComponent<std::string>>
(mWindow, "LANGUAGE", false); (mWindow, getHelpStyle(), "LANGUAGE", false);
std::vector<std::string> transitions_lg; std::vector<std::string> transitions_lg;
transitions_lg.push_back("en"); transitions_lg.push_back("en");
transitions_lg.push_back("wor"); transitions_lg.push_back("wor");
@ -220,7 +220,7 @@ void GuiScraperMenu::pressedStart()
std::vector<SystemData*> sys = mSystems->getSelectedObjects(); std::vector<SystemData*> sys = mSystems->getSelectedObjects();
for (auto it = sys.cbegin(); it != sys.cend(); it++) { for (auto it = sys.cbegin(); it != sys.cend(); it++) {
if ((*it)->getPlatformIds().empty()) { 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 " Utils::String::toUpper("Warning: some of your selected systems do not "
"have a platform set. Results may be even more inaccurate than " "have a platform set. Results may be even more inaccurate than "
"usual!\nContinue anyway?"), "usual!\nContinue anyway?"),
@ -238,7 +238,7 @@ void GuiScraperMenu::start()
mFilters->getSelected()); mFilters->getSelected());
if (searches.empty()) { if (searches.empty()) {
mWindow->pushGui(new GuiMsgBox(mWindow, mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(),
"NO GAMES TO SCRAPE")); "NO GAMES TO SCRAPE"));
} }
else { else {
@ -302,13 +302,6 @@ bool GuiScraperMenu::input(InputConfig* config, Input input)
return false; return false;
} }
HelpStyle GuiScraperMenu::getHelpStyle()
{
HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
return style;
}
std::vector<HelpPrompt> GuiScraperMenu::getHelpPrompts() std::vector<HelpPrompt> GuiScraperMenu::getHelpPrompts()
{ {
std::vector<HelpPrompt> prompts; std::vector<HelpPrompt> prompts;
@ -317,3 +310,10 @@ std::vector<HelpPrompt> GuiScraperMenu::getHelpPrompts()
prompts.push_back(HelpPrompt("start", "close")); prompts.push_back(HelpPrompt("start", "close"));
return prompts; return prompts;
} }
HelpStyle GuiScraperMenu::getHelpStyle()
{
HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
return style;
}

View file

@ -169,7 +169,7 @@ void GuiScraperMulti::finish()
" SKIPPED"; " SKIPPED";
} }
mWindow->pushGui(new GuiMsgBox(mWindow, ss.str(), "OK", [&] { mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(), ss.str(), "OK", [&] {
delete this; })); delete this; }));
mIsProcessing = false; mIsProcessing = false;
@ -180,3 +180,10 @@ std::vector<HelpPrompt> GuiScraperMulti::getHelpPrompts()
{ {
return mGrid.getHelpPrompts(); return mGrid.getHelpPrompts();
} }
HelpStyle GuiScraperMulti::getHelpStyle()
{
HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
return style;
}

View file

@ -31,7 +31,9 @@ public:
virtual ~GuiScraperMulti(); virtual ~GuiScraperMulti();
void onSizeChanged() override; void onSizeChanged() override;
std::vector<HelpPrompt> getHelpPrompts() override; std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override;
private: private:
void acceptResult(const ScraperSearchResult& result); void acceptResult(const ScraperSearchResult& result);

View file

@ -23,11 +23,13 @@
#include "guis/GuiTextEditPopup.h" #include "guis/GuiTextEditPopup.h"
#include "resources/Font.h" #include "resources/Font.h"
#include "utils/StringUtil.h" #include "utils/StringUtil.h"
#include "PlatformId.h" #include "views/ViewController.h"
#include "MameNames.h" #include "CollectionSystemManager.h"
#include "SystemData.h"
#include "FileData.h" #include "FileData.h"
#include "Log.h" #include "Log.h"
#include "MameNames.h"
#include "PlatformId.h"
#include "SystemData.h"
#include "Window.h" #include "Window.h"
GuiScraperSearch::GuiScraperSearch( GuiScraperSearch::GuiScraperSearch(
@ -277,8 +279,9 @@ void GuiScraperSearch::onSearchDone(const std::vector<ScraperSearchResult>& resu
if (results.empty()) { if (results.empty()) {
// Check if the scraper used is still valid. // Check if the scraper used is still valid.
if (!isValidConfiguredScraper()) { if (!isValidConfiguredScraper()) {
mWindow->pushGui(new GuiMsgBox(mWindow, Utils::String::toUpper("Configured scraper " mWindow->pushGui(new GuiMsgBox(mWindow, getHelpStyle(),
"is no longer available.\nPlease change the scraping source in the settings."), Utils::String::toUpper("Configured scraper is no longer available.\n"
"Please change the scraping source in the settings."),
"FINISH", mSkipCallback)); "FINISH", mSkipCallback));
} }
else { else {
@ -325,7 +328,7 @@ void GuiScraperSearch::onSearchDone(const std::vector<ScraperSearchResult>& resu
void GuiScraperSearch::onSearchError(const std::string& error) void GuiScraperSearch::onSearchError(const std::string& error)
{ {
LOG(LogInfo) << "GuiScraperSearch search error: " << 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), "RETRY", std::bind(&GuiScraperSearch::search, this, mLastSearch),
"SKIP", mSkipCallback, "SKIP", mSkipCallback,
"CANCEL", mCancelCallback)); "CANCEL", mCancelCallback));
@ -584,7 +587,7 @@ void GuiScraperSearch::openInputScreen(ScraperSearchParams& params)
if (params.system->hasPlatformId(PlatformIds::ARCADE) || if (params.system->hasPlatformId(PlatformIds::ARCADE) ||
params.system->hasPlatformId(PlatformIds::NEOGEO)) { 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. // 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. // If it's a MAME or Neo Geo game, expand the game name accordingly.
params.nameOverride.empty() ? params.nameOverride.empty() ?
@ -593,7 +596,7 @@ void GuiScraperSearch::openInputScreen(ScraperSearchParams& params)
searchForFunc, false, "SEARCH", "APPLY CHANGES?")); searchForFunc, false, "SEARCH", "APPLY CHANGES?"));
} }
else { 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. // Initial value is last search if there was one, otherwise the clean path name.
params.nameOverride.empty() ? params.game->getCleanName() : params.nameOverride, params.nameOverride.empty() ? params.game->getCleanName() : params.nameOverride,
searchForFunc, false, "SEARCH", "APPLY CHANGES?")); searchForFunc, false, "SEARCH", "APPLY CHANGES?"));
@ -664,6 +667,13 @@ std::vector<HelpPrompt> GuiScraperSearch::getHelpPrompts()
return prompts; return prompts;
} }
HelpStyle GuiScraperSearch::getHelpStyle()
{
HelpStyle style = HelpStyle();
style.applyTheme(ViewController::get()->getState().getSystem()->getTheme(), "system");
return style;
}
void GuiScraperSearch::onFocusGained() void GuiScraperSearch::onFocusGained()
{ {
mGrid.onFocusGained(); mGrid.onFocusGained();

View file

@ -57,6 +57,7 @@ public:
void update(int deltaTime) override; void update(int deltaTime) override;
void render(const Transform4x4f& parentTrans) override; void render(const Transform4x4f& parentTrans) override;
std::vector<HelpPrompt> getHelpPrompts() override; std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override;
void onSizeChanged() override; void onSizeChanged() override;
void onFocusGained() override; void onFocusGained() override;
void onFocusLost() override; void onFocusLost() override;

View file

@ -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) auto updateVal = [ed](const std::string& newVal) { ed->setValue(newVal); }; // ok callback (apply new value to ed)
row.makeAcceptInputHandler([this, label, ed, updateVal] { 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); assert(ed);
addRow(row); addRow(row);

View file

@ -31,7 +31,7 @@ GuiVideoScreensaverOptions::GuiVideoScreensaverOptions(Window* window, const cha
#endif #endif
// Render Video Game Name as subtitles // Render Video Game Name as subtitles
auto ss_info = std::make_shared< OptionListComponent<std::string> >(mWindow, "SHOW GAME INFO", false); auto ss_info = std::make_shared< OptionListComponent<std::string> >(mWindow, getHelpStyle(), "SHOW GAME INFO", false);
std::vector<std::string> info_type; std::vector<std::string> info_type;
info_type.push_back("always"); info_type.push_back("always");
info_type.push_back("start & end"); info_type.push_back("start & end");

View file

@ -381,9 +381,12 @@ int main(int argc, char* argv[])
return 1; 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, // We can't handle es_systems.cfg file problems inside ES itself,
// so display the error message and then quit. // so display the error message and then quit.
window.pushGui(new GuiMsgBox(&window, window.pushGui(new GuiMsgBox(&window, helpStyle,
errorMsg, errorMsg,
"QUIT", [] { "QUIT", [] {
SDL_Event* quit = new SDL_Event(); SDL_Event* quit = new SDL_Event();

View file

@ -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. // Something is wrong, there is not a single system to show, check if UI mode is not full.
if (!UIModeController::getInstance()->isUIModeFull()) { if (!UIModeController::getInstance()->isUIModeFull()) {
Settings::getInstance()->setString("UIMode", "Full"); 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", "The selected UI mode has nothing to show,\n returning to UI mode: FULL", "OK",
nullptr)); nullptr));
} }

View file

@ -1,141 +1,45 @@
//
// OptionListComponent.h
//
// Provides a list of options.
// Supports various types using templates.
//
#pragma once #pragma once
#ifndef ES_CORE_COMPONENTS_OPTION_LIST_COMPONENT_H #ifndef ES_CORE_COMPONENTS_OPTION_LIST_COMPONENT_H
#define 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 "GuiComponent.h"
#include "Log.h" #include "Log.h"
#include "Window.h" #include "Window.h"
//Used to display a list of options. // Used to display a list of options.
//Can select one or multiple options. // Can select one or multiple options.
// if !multiSelect // if !multiSelect
// * <- curEntry -> // * <- curEntry ->
// Always
// always // * press a -> open full list.
// * press a -> open full list
#define CHECKED_PATH ":/checkbox_checked.svg"
#define UNCHECKED_PATH ":/checkbox_unchecked.svg"
template<typename T> template<typename T>
class OptionListComponent : public GuiComponent class OptionListComponent : public GuiComponent
{ {
private:
struct OptionListData
{
std::string name;
T object;
bool selected;
};
class OptionListPopup : public GuiComponent
{
private:
MenuComponent mMenu;
OptionListComponent<T>* mParent;
public:
OptionListPopup(Window* window, OptionListComponent<T>* 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<ImageComponent*> checkboxes;
for(auto it = mParent->mEntries.begin(); it != mParent->mEntries.end(); it++)
{
row.elements.clear();
row.addElement(std::make_shared<TextComponent>(mWindow, Utils::String::toUpper(it->name), font, 0x777777FF), true);
OptionListData& e = *it;
if(mParent->mMultiSelect)
{
// add checkbox
auto checkbox = std::make_shared<ImageComponent>(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<HelpPrompt> getHelpPrompts() override
{
auto prompts = mMenu.getHelpPrompts();
prompts.push_back(HelpPrompt("b", "back"));
return prompts;
}
};
public: public:
OptionListComponent(Window* window, const std::string& name, bool multiSelect = false) : GuiComponent(window), mMultiSelect(multiSelect), mName(name), OptionListComponent(
mText(window), mLeftArrow(window), mRightArrow(window) 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); auto font = Font::get(FONT_SIZE_MEDIUM, FONT_PATH_LIGHT);
mText.setFont(font); mText.setFont(font);
@ -146,11 +50,11 @@ public:
mLeftArrow.setResize(0, mText.getFont()->getLetterHeight()); mLeftArrow.setResize(0, mText.getFont()->getLetterHeight());
mRightArrow.setResize(0, mText.getFont()->getLetterHeight()); mRightArrow.setResize(0, mText.getFont()->getLetterHeight());
if(mMultiSelect) if(mMultiSelect) {
{
mRightArrow.setImage(":/arrow.svg"); mRightArrow.setImage(":/arrow.svg");
addChild(&mRightArrow); addChild(&mRightArrow);
}else{ }
else {
mLeftArrow.setImage(":/option_arrow.svg"); mLeftArrow.setImage(":/option_arrow.svg");
mLeftArrow.setFlipX(true); mLeftArrow.setFlipX(true);
addChild(&mLeftArrow); addChild(&mLeftArrow);
@ -162,7 +66,7 @@ public:
setSize(mLeftArrow.getSize().x() + mRightArrow.getSize().x(), font->getHeight()); 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 void onSizeChanged() override
{ {
mLeftArrow.setResize(0, mText.getFont()->getLetterHeight()); mLeftArrow.setResize(0, mText.getFont()->getLetterHeight());
@ -171,28 +75,27 @@ public:
if(mSize.x() < (mLeftArrow.getSize().x() + mRightArrow.getSize().x())) if(mSize.x() < (mLeftArrow.getSize().x() + mRightArrow.getSize().x()))
LOG(LogWarning) << "OptionListComponent too narrow!"; 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); mLeftArrow.setPosition(0, (mSize.y() - mLeftArrow.getSize().y()) / 2);
mText.setPosition(mLeftArrow.getPosition().x() + mLeftArrow.getSize().x(), (mSize.y() - mText.getSize().y()) / 2); mText.setPosition(mLeftArrow.getPosition().x() + mLeftArrow.getSize().x(),
mRightArrow.setPosition(mText.getPosition().x() + mText.getSize().x(), (mSize.y() - mRightArrow.getSize().y()) / 2); (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 bool input(InputConfig* config, Input input) override
{ {
if(input.value != 0) if(input.value != 0) {
{ if(config->isMappedTo("a", input)) {
if(config->isMappedTo("a", input))
{
open(); open();
return true; return true;
} }
if(!mMultiSelect) if(!mMultiSelect) {
{ if(config->isMappedLike("left", input)) {
if(config->isMappedLike("left", input)) // Move selection to previous.
{
// move selection to previous
unsigned int i = getSelectedId(); unsigned int i = getSelectedId();
int next = (int)i - 1; int next = (int)i - 1;
if(next < 0) if(next < 0)
@ -203,16 +106,15 @@ public:
onSelectedChanged(); onSelectedChanged();
return true; return true;
}else if(config->isMappedLike("right", input)) }
{ else if(config->isMappedLike("right", input)) {
// move selection to next // Move selection to next.
unsigned int i = getSelectedId(); unsigned int i = getSelectedId();
int next = (i + 1) % mEntries.size(); int next = (i + 1) % mEntries.size();
mEntries.at(i).selected = false; mEntries.at(i).selected = false;
mEntries.at(next).selected = true; mEntries.at(next).selected = true;
onSelectedChanged(); onSelectedChanged();
return true; return true;
} }
} }
} }
@ -222,8 +124,7 @@ public:
std::vector<T> getSelectedObjects() std::vector<T> getSelectedObjects()
{ {
std::vector<T> ret; std::vector<T> ret;
for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++) for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++) {
{
if(it->selected) if(it->selected)
ret.push_back(it->object); ret.push_back(it->object);
} }
@ -277,62 +178,67 @@ public:
void selectAll() void selectAll()
{ {
for(unsigned int i = 0; i < mEntries.size(); i++) for(unsigned int i = 0; i < mEntries.size(); i++)
{
mEntries.at(i).selected = true; mEntries.at(i).selected = true;
}
onSelectedChanged(); onSelectedChanged();
} }
void selectNone() void selectNone()
{ {
for(unsigned int i = 0; i < mEntries.size(); i++) for(unsigned int i = 0; i < mEntries.size(); i++)
{
mEntries.at(i).selected = false; mEntries.at(i).selected = false;
}
onSelectedChanged(); onSelectedChanged();
} }
HelpStyle getHelpStyle() override { return mHelpStyle; };
private: private:
struct OptionListData {
std::string name;
T object;
bool selected;
};
HelpStyle mHelpStyle;
unsigned int getSelectedId() unsigned int getSelectedId()
{ {
assert(mMultiSelect == false); 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) if(mEntries.at(i).selected)
return i; 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; return 0;
} }
void open() void open()
{ {
mWindow->pushGui(new OptionListPopup(mWindow, this, mName)); mWindow->pushGui(new OptionListPopup(mWindow, getHelpStyle(), this, mName));
} }
void onSelectedChanged() void onSelectedChanged()
{ {
if(mMultiSelect) if(mMultiSelect) {
{ // Display # selected.
// display # selected
std::stringstream ss; std::stringstream ss;
ss << getSelectedObjects().size() << " SELECTED"; ss << getSelectedObjects().size() << " SELECTED";
mText.setText(ss.str()); mText.setText(ss.str());
mText.setSize(0, mText.getSize().y()); mText.setSize(0, mText.getSize().y());
setSize(mText.getSize().x() + mRightArrow.getSize().x() + 24, 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(); mParent->onSizeChanged();
}else{ }
// display currently selected + l/r cursors else {
for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++) // Display currently selected + l/r cursors.
{ for(auto it = mEntries.cbegin(); it != mEntries.cend(); it++) {
if(it->selected) if(it->selected) {
{
mText.setText(Utils::String::toUpper(it->name)); mText.setText(Utils::String::toUpper(it->name));
mText.setSize(0, mText.getSize().y()); mText.setSize(0, mText.getSize().y());
setSize(mText.getSize().x() + mLeftArrow.getSize().x() + mRightArrow.getSize().x() + 24, mText.getSize().y()); setSize(mText.getSize().x() + mLeftArrow.getSize().x() +
if(mParent) // hack since theres no "on child size changed" callback atm... mRightArrow.getSize().x() + 24, mText.getSize().y());
if(mParent) // Hack since theres no "on child size changed" callback atm...
mParent->onSizeChanged(); mParent->onSizeChanged();
break; break;
} }
@ -358,6 +264,116 @@ private:
ImageComponent mRightArrow; ImageComponent mRightArrow;
std::vector<OptionListData> mEntries; std::vector<OptionListData> mEntries;
// Subclass to OptionListComponent.
class OptionListPopup : public GuiComponent
{
public:
OptionListPopup(
Window* window,
const HelpStyle& helpstyle,
OptionListComponent<T>* 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<ImageComponent*> checkboxes;
for(auto it = mParent->mEntries.begin(); it != mParent->mEntries.end(); it++) {
row.elements.clear();
row.addElement(std::make_shared<TextComponent>
(mWindow, Utils::String::toUpper(it->name), font, 0x777777FF), true);
OptionListData& e = *it;
if(mParent->mMultiSelect) {
// Add checkbox.
auto checkbox = std::make_shared<ImageComponent>(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<HelpPrompt> getHelpPrompts() override
{
auto prompts = mMenu.getHelpPrompts();
prompts.push_back(HelpPrompt("b", "back"));
return prompts;
}
HelpStyle getHelpStyle() override { return mHelpStyle; };
private:
MenuComponent mMenu;
OptionListComponent<T>* mParent;
HelpStyle mHelpStyle;
};
}; };
#endif // ES_CORE_COMPONENTS_OPTION_LIST_COMPONENT_H #endif // ES_CORE_COMPONENTS_OPTION_LIST_COMPONENT_H

View file

@ -16,6 +16,7 @@
GuiComplexTextEditPopup::GuiComplexTextEditPopup( GuiComplexTextEditPopup::GuiComplexTextEditPopup(
Window* window, Window* window,
const HelpStyle& helpstyle,
const std::string& title, const std::string& title,
const std::string& infoString1, const std::string& infoString1,
const std::string& infoString2, const std::string& infoString2,
@ -25,6 +26,7 @@ GuiComplexTextEditPopup::GuiComplexTextEditPopup(
const char* acceptBtnText, const char* acceptBtnText,
const char* saveConfirmationText) const char* saveConfirmationText)
: GuiComponent(window), : GuiComponent(window),
mHelpStyle(helpstyle),
mBackground(window, ":/frame.png"), mBackground(window, ":/frame.png"),
mGrid(window, Vector2i(1, 5)), mGrid(window, Vector2i(1, 5)),
mMultiLine(multiLine), mMultiLine(multiLine),
@ -102,7 +104,7 @@ bool GuiComplexTextEditPopup::input(InputConfig* config, Input input)
if (config->isMappedTo("b", input) && input.value) { if (config->isMappedTo("b", input) && input.value) {
if (mText->getValue() != mInitValue) { if (mText->getValue() != mInitValue) {
// Changes were made, ask if the user wants to save them. // 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; }, [this] { this->mOkCallback(mText->getValue()); delete this; return true; },
"NO", [this] { delete this; return false; })); "NO", [this] { delete this; return false; }));
} }

View file

@ -22,6 +22,7 @@ class GuiComplexTextEditPopup : public GuiComponent
public: public:
GuiComplexTextEditPopup( GuiComplexTextEditPopup(
Window* window, Window* window,
const HelpStyle& helpstyle,
const std::string& title, const std::string& title,
const std::string& infoString1, const std::string& infoString1,
const std::string& infoString2, const std::string& infoString2,
@ -33,7 +34,9 @@ public:
bool input(InputConfig* config, Input input); bool input(InputConfig* config, Input input);
void onSizeChanged(); void onSizeChanged();
std::vector<HelpPrompt> getHelpPrompts() override; std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override { return mHelpStyle; };
private: private:
NinePatchComponent mBackground; NinePatchComponent mBackground;
@ -45,6 +48,7 @@ private:
std::shared_ptr<TextEditComponent> mText; std::shared_ptr<TextEditComponent> mText;
std::shared_ptr<ComponentGrid> mButtonGrid; std::shared_ptr<ComponentGrid> mButtonGrid;
HelpStyle mHelpStyle;
bool mMultiLine; bool mMultiLine;
std::string mInitValue; std::string mInitValue;
std::function<void(const std::string&)> mOkCallback; std::function<void(const std::string&)> mOkCallback;

View file

@ -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. // check if the hotkey enable button is set. if not prompt the user to use select or nothing.
Input input; Input input;
if (!mTargetConfig->getInputByName("HotKeyEnable", &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.", "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] { "YES", [this, okFunction] {
Input input; Input input;

View file

@ -12,11 +12,12 @@
#define HORIZONTAL_PADDING_PX 20 #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<void()>& func1, const std::string& name1, const std::function<void()>& func1,
const std::string& name2, const std::function<void()>& func2, const std::string& name2, const std::function<void()>& func2,
const std::string& name3, const std::function<void()>& func3) const std::string& name3, const std::function<void()>& func3)
: GuiComponent(window), : GuiComponent(window),
mHelpStyle(helpstyle),
mBackground(window, ":/frame.png"), mBackground(window, ":/frame.png"),
mGrid(window, Vector2i(1, 2)) mGrid(window, Vector2i(1, 2))
{ {

View file

@ -19,14 +19,16 @@ class TextComponent;
class GuiMsgBox : public GuiComponent class GuiMsgBox : public GuiComponent
{ {
public: 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<void()>& func1 = nullptr, const std::string& name1 = "OK", const std::function<void()>& func1 = nullptr,
const std::string& name2 = "", const std::function<void()>& func2 = nullptr, const std::string& name2 = "", const std::function<void()>& func2 = nullptr,
const std::string& name3 = "", const std::function<void()>& func3 = nullptr); const std::string& name3 = "", const std::function<void()>& func3 = nullptr);
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
void onSizeChanged() override; void onSizeChanged() override;
std::vector<HelpPrompt> getHelpPrompts() override; std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override { return mHelpStyle; };
private: private:
void deleteMeAndCall(const std::function<void()>& func); void deleteMeAndCall(const std::function<void()>& func);
@ -34,6 +36,7 @@ private:
NinePatchComponent mBackground; NinePatchComponent mBackground;
ComponentGrid mGrid; ComponentGrid mGrid;
HelpStyle mHelpStyle;
std::shared_ptr<TextComponent> mMsg; std::shared_ptr<TextComponent> mMsg;
std::vector<std::shared_ptr<ButtonComponent>> mButtons; std::vector<std::shared_ptr<ButtonComponent>> mButtons;
std::shared_ptr<ComponentGrid> mButtonGrid; std::shared_ptr<ComponentGrid> mButtonGrid;

View file

@ -14,6 +14,7 @@
GuiTextEditPopup::GuiTextEditPopup( GuiTextEditPopup::GuiTextEditPopup(
Window* window, Window* window,
const HelpStyle& helpstyle,
const std::string& title, const std::string& title,
const std::string& initValue, const std::string& initValue,
const std::function<void(const std::string&)>& okCallback, const std::function<void(const std::string&)>& okCallback,
@ -21,6 +22,7 @@ GuiTextEditPopup::GuiTextEditPopup(
const char* acceptBtnText, const char* acceptBtnText,
const char* saveConfirmationText) const char* saveConfirmationText)
: GuiComponent(window), : GuiComponent(window),
mHelpStyle(helpstyle),
mBackground(window, ":/frame.png"), mBackground(window, ":/frame.png"),
mGrid(window, Vector2i(1, 3)), mGrid(window, Vector2i(1, 3)),
mMultiLine(multiLine), mMultiLine(multiLine),
@ -86,7 +88,7 @@ bool GuiTextEditPopup::input(InputConfig* config, Input input)
if (config->isMappedTo("b", input) && input.value) { if (config->isMappedTo("b", input) && input.value) {
if (mText->getValue() != mInitValue) { if (mText->getValue() != mInitValue) {
// Changes were made, ask if the user wants to save them. // 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; }, [this] { this->mOkCallback(mText->getValue()); delete this; return true; },
"NO", [this] { delete this; return false; })); "NO", [this] { delete this; return false; }));
} }

View file

@ -20,6 +20,7 @@ class GuiTextEditPopup : public GuiComponent
public: public:
GuiTextEditPopup( GuiTextEditPopup(
Window* window, Window* window,
const HelpStyle& helpstyle,
const std::string& title, const std::string& title,
const std::string& initValue, const std::string& initValue,
const std::function<void(const std::string&)>& okCallback, const std::function<void(const std::string&)>& okCallback,
@ -29,7 +30,9 @@ public:
bool input(InputConfig* config, Input input); bool input(InputConfig* config, Input input);
void onSizeChanged(); void onSizeChanged();
std::vector<HelpPrompt> getHelpPrompts() override; std::vector<HelpPrompt> getHelpPrompts() override;
HelpStyle getHelpStyle() override { return mHelpStyle; };
private: private:
NinePatchComponent mBackground; NinePatchComponent mBackground;
@ -39,6 +42,7 @@ private:
std::shared_ptr<TextEditComponent> mText; std::shared_ptr<TextEditComponent> mText;
std::shared_ptr<ComponentGrid> mButtonGrid; std::shared_ptr<ComponentGrid> mButtonGrid;
HelpStyle mHelpStyle;
bool mMultiLine; bool mMultiLine;
std::string mInitValue; std::string mInitValue;
std::function<void(const std::string&)> mOkCallback; std::function<void(const std::string&)> mOkCallback;