From c530373ddcac9d98a26e9c4b7ef880e76ceefcba Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Tue, 1 Feb 2022 18:06:32 +0100 Subject: [PATCH] Improved the integration of the variant and aspect ratio options in the UI Settings menu. Also reorganized the order of some settings. --- es-app/src/guis/GuiMenu.cpp | 253 ++++++++++++------- es-core/src/Settings.cpp | 8 +- es-core/src/components/OptionListComponent.h | 20 +- 3 files changed, 184 insertions(+), 97 deletions(-) diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index b03bcad1b..e4ecc7768 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -102,24 +102,17 @@ void GuiMenu::openUIOptions() // Theme options section. std::map themeSets {ThemeData::getThemeSets()}; - std::vector themeVariantsVector; - std::vector themeAspectRatiosVector; std::map::const_iterator selectedSet; + auto theme_set = + std::make_shared>(getHelpStyle(), "THEME SET", false); + // Theme selection. if (!themeSets.empty()) { selectedSet = themeSets.find(Settings::getInstance()->getString("ThemeSet")); if (selectedSet == themeSets.cend()) selectedSet = themeSets.cbegin(); - for (auto& variant : selectedSet->second.capabilities.variants) - themeVariantsVector.emplace_back(variant); - - for (auto& aspectRatio : selectedSet->second.capabilities.aspectRatios) - themeAspectRatiosVector.emplace_back(aspectRatio); - - auto theme_set = - std::make_shared>(getHelpStyle(), "THEME SET", false); for (auto it = themeSets.cbegin(); it != themeSets.cend(); ++it) { // If required, abbreviate the theme set name so it doesn't overlap the setting name. float maxNameLength = mSize.x * 0.62f; @@ -150,74 +143,102 @@ void GuiMenu::openUIOptions() // Theme variants. auto themeVariant = std::make_shared>(getHelpStyle(), "THEME VARIANT", false); - if (!themeVariantsVector.empty()) { - std::string selectedVariant {Settings::getInstance()->getString("ThemeVariant")}; - for (auto& variant : themeVariantsVector) { - if (variant.selectable) { - // If required, abbreviate the variant name so it doesn't overlap the setting name. - float maxNameLength {mSize.x * 0.62f}; - themeVariant->add(variant.label, variant.name, variant.name == selectedVariant, - maxNameLength); - } + s->addWithLabel("THEME VARIANT", themeVariant); + s->addSaveFunc([themeVariant, s] { + if (themeVariant->getSelected() != Settings::getInstance()->getString("ThemeVariant")) { + Settings::getInstance()->setString("ThemeVariant", themeVariant->getSelected()); + s->setNeedsSaving(); + s->setNeedsReloading(); + s->setInvalidateCachedBackground(); } - if (themeVariant->getSelectedObjects().size() == 0) - themeVariant->selectEntry(0); - s->addWithLabel("THEME VARIANT", themeVariant); - s->addSaveFunc([themeVariant, selectedVariant, s] { - if (themeVariant->getSelected() != selectedVariant) { - Settings::getInstance()->setString("ThemeVariant", themeVariant->getSelected()); - s->setNeedsSaving(); - s->setNeedsReloading(); - s->setInvalidateCachedBackground(); + }); + + auto themeVariantsFunc = [=](const std::string& selectedTheme, + const std::string& selectedVariant) { + std::map::const_iterator currentSet { + themeSets.find(selectedTheme)}; + if (currentSet == themeSets.cend()) + return; + // We need to recreate the OptionListComponent entries. + themeVariant->clearEntries(); + int selectableVariants {0}; + for (auto& variant : currentSet->second.capabilities.variants) { + if (variant.selectable) + ++selectableVariants; + } + if (selectableVariants > 0) { + for (auto& variant : currentSet->second.capabilities.variants) { + if (variant.selectable) { + // If required, abbreviate the variant name so it doesn't overlap the + // setting name. + float maxNameLength {mSize.x * 0.62f}; + themeVariant->add(variant.label, variant.name, variant.name == selectedVariant, + maxNameLength); + } } - }); - } - else { - if (selectedSet->second.capabilities.legacyTheme) - themeVariant->add("Legacy theme set", "none", true); - else - themeVariant->add("None defined", "none", true); - s->addWithLabel("THEME VARIANT", themeVariant); - themeVariant->setEnabled(false); - themeVariant->setOpacity(DISABLED_OPACITY); - themeVariant->getParent() - ->getChild(themeVariant->getChildIndex() - 1) - ->setOpacity(DISABLED_OPACITY); - } + if (themeVariant->getSelectedObjects().size() == 0) + themeVariant->selectEntry(0); + } + else { + if (currentSet->second.capabilities.legacyTheme) + themeVariant->add("Legacy theme set", "none", true); + else + themeVariant->add("None defined", "none", true); + themeVariant->setEnabled(false); + themeVariant->setOpacity(DISABLED_OPACITY); + themeVariant->getParent() + ->getChild(themeVariant->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + } + }; + + themeVariantsFunc(Settings::getInstance()->getString("ThemeSet"), + Settings::getInstance()->getString("ThemeVariant")); // Theme aspect ratios. auto themeAspectRatio = std::make_shared>( getHelpStyle(), "THEME ASPECT RATIO", false); - if (!themeAspectRatiosVector.empty()) { - std::string selectedAspectRatio {Settings::getInstance()->getString("ThemeAspectRatio")}; - for (auto& aspectRatio : themeAspectRatiosVector) - themeAspectRatio->add(ThemeData::getAspectRatioLabel(aspectRatio), aspectRatio, - aspectRatio == selectedAspectRatio); - if (themeAspectRatio->getSelectedObjects().size() == 0) - themeAspectRatio->selectEntry(0); - s->addWithLabel("THEME ASPECT RATIO", themeAspectRatio); - s->addSaveFunc([themeAspectRatio, selectedAspectRatio, s] { - if (themeAspectRatio->getSelected() != selectedAspectRatio) { - Settings::getInstance()->setString("ThemeAspectRatio", - themeAspectRatio->getSelected()); - s->setNeedsSaving(); - s->setNeedsReloading(); - s->setInvalidateCachedBackground(); - } - }); - } - else { - if (selectedSet->second.capabilities.legacyTheme) - themeAspectRatio->add("Legacy theme set", "none", true); - else - themeAspectRatio->add("None defined", "none", true); - s->addWithLabel("THEME ASPECT RATIO", themeAspectRatio); - themeAspectRatio->setEnabled(false); - themeAspectRatio->setOpacity(DISABLED_OPACITY); - themeAspectRatio->getParent() - ->getChild(themeAspectRatio->getChildIndex() - 1) - ->setOpacity(DISABLED_OPACITY); - } + s->addWithLabel("THEME ASPECT RATIO", themeAspectRatio); + s->addSaveFunc([themeAspectRatio, s] { + if (themeAspectRatio->getSelected() != + Settings::getInstance()->getString("ThemeAspectRatio")) { + Settings::getInstance()->setString("ThemeAspectRatio", themeAspectRatio->getSelected()); + s->setNeedsSaving(); + s->setNeedsReloading(); + s->setInvalidateCachedBackground(); + } + }); + + auto themeAspectRatiosFunc = [=](const std::string& selectedTheme, + const std::string& selectedAspectRatio) { + std::map::const_iterator currentSet { + themeSets.find(selectedTheme)}; + if (currentSet == themeSets.cend()) + return; + // We need to recreate the OptionListComponent entries. + themeAspectRatio->clearEntries(); + if (currentSet->second.capabilities.aspectRatios.size() > 0) { + for (auto& aspectRatio : currentSet->second.capabilities.aspectRatios) + themeAspectRatio->add(ThemeData::getAspectRatioLabel(aspectRatio), aspectRatio, + aspectRatio == selectedAspectRatio); + if (themeAspectRatio->getSelectedObjects().size() == 0) + themeAspectRatio->selectEntry(0); + } + else { + if (currentSet->second.capabilities.legacyTheme) + themeAspectRatio->add("Legacy theme set", "none", true); + else + themeAspectRatio->add("None defined", "none", true); + themeAspectRatio->setEnabled(false); + themeAspectRatio->setOpacity(DISABLED_OPACITY); + themeAspectRatio->getParent() + ->getChild(themeAspectRatio->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + } + }; + + themeAspectRatiosFunc(Settings::getInstance()->getString("ThemeSet"), + Settings::getInstance()->getString("ThemeAspectRatio")); // Legacy gamelist view style. auto gamelist_view_style = std::make_shared>( @@ -243,14 +264,6 @@ void GuiMenu::openUIOptions() } }); - if (!selectedSet->second.capabilities.legacyTheme) { - gamelist_view_style->setEnabled(false); - gamelist_view_style->setOpacity(DISABLED_OPACITY); - gamelist_view_style->getParent() - ->getChild(gamelist_view_style->getChildIndex() - 1) - ->setOpacity(DISABLED_OPACITY); - } - // Legacy ransition style. auto transition_style = std::make_shared>( getHelpStyle(), "LEGACY TRANSITION STYLE", false); @@ -270,14 +283,78 @@ void GuiMenu::openUIOptions() } }); - // TEMPORARY - // if (!selectedSet->second.capabilities.legacyTheme) { - // transition_style->setEnabled(false); - // transition_style->setOpacity(DISABLED_OPACITY); - // transition_style->getParent() - // ->getChild(transition_style->getChildIndex() - 1) - // ->setOpacity(DISABLED_OPACITY); - // } + // When the theme set entries are scrolled or selected, update the relevant rows. + auto scrollThemeSetFunc = [=](const std::string& themeName, bool firstRun = false) { + auto selectedSet = themeSets.find(themeName); + if (selectedSet == themeSets.cend()) + return; + if (!firstRun) { + themeVariantsFunc(themeName, themeVariant->getSelected()); + themeAspectRatiosFunc(themeName, themeAspectRatio->getSelected()); + } + int selectableVariants {0}; + for (auto& variant : selectedSet->second.capabilities.variants) { + if (variant.selectable) + ++selectableVariants; + } + if (!selectedSet->second.capabilities.legacyTheme && selectableVariants > 0) { + themeVariant->setEnabled(true); + themeVariant->setOpacity(255); + themeVariant->getParent()->getChild(themeVariant->getChildIndex() - 1)->setOpacity(255); + } + else { + themeVariant->setEnabled(false); + themeVariant->setOpacity(DISABLED_OPACITY); + themeVariant->getParent() + ->getChild(themeVariant->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + } + + if (!selectedSet->second.capabilities.legacyTheme && + selectedSet->second.capabilities.aspectRatios.size() > 0) { + themeAspectRatio->setEnabled(true); + themeAspectRatio->setOpacity(255); + themeAspectRatio->getParent() + ->getChild(themeAspectRatio->getChildIndex() - 1) + ->setOpacity(255); + } + else { + themeAspectRatio->setEnabled(false); + themeAspectRatio->setOpacity(DISABLED_OPACITY); + themeAspectRatio->getParent() + ->getChild(themeAspectRatio->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + } + if (!selectedSet->second.capabilities.legacyTheme) { + gamelist_view_style->setEnabled(false); + gamelist_view_style->setOpacity(DISABLED_OPACITY); + gamelist_view_style->getParent() + ->getChild(gamelist_view_style->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + // TEMPORARY + // transition_style->setEnabled(false); + transition_style->setOpacity(DISABLED_OPACITY); + transition_style->getParent() + ->getChild(transition_style->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + } + else { + gamelist_view_style->setEnabled(true); + gamelist_view_style->setOpacity(255); + gamelist_view_style->getParent() + ->getChild(gamelist_view_style->getChildIndex() - 1) + ->setOpacity(255); + + transition_style->setEnabled(true); + transition_style->setOpacity(255); + transition_style->getParent() + ->getChild(transition_style->getChildIndex() - 1) + ->setOpacity(255); + } + }; + + scrollThemeSetFunc(selectedSet->first, true); + theme_set->setCallback(scrollThemeSetFunc); // Optionally start in selected system/gamelist. auto startupSystem = std::make_shared>( diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index f97ae75bc..ff6e26627 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -129,16 +129,16 @@ void Settings::setDefaults() mBoolMap["ScraperRetryPeerVerification"] = {false, false}; // UI settings. - mStringMap["StartupSystem"] = {"", ""}; - mStringMap["GamelistViewStyle"] = {"automatic", "automatic"}; - mStringMap["TransitionStyle"] = {"slide", "slide"}; mStringMap["ThemeSet"] = {"rbsimple-DE", "rbsimple-DE"}; mStringMap["ThemeVariant"] = {"", ""}; mStringMap["ThemeAspectRatio"] = {"", ""}; - mStringMap["UIMode"] = {"full", "full"}; + mStringMap["GamelistViewStyle"] = {"automatic", "automatic"}; + mStringMap["TransitionStyle"] = {"slide", "slide"}; + mStringMap["StartupSystem"] = {"", ""}; mStringMap["DefaultSortOrder"] = {"filename, ascending", "filename, ascending"}; mStringMap["MenuOpeningEffect"] = {"scale-up", "scale-up"}; mStringMap["LaunchScreenDuration"] = {"normal", "normal"}; + mStringMap["UIMode"] = {"full", "full"}; // UI settings -> media viewer settings. mBoolMap["MediaViewerKeepVideoRunning"] = {true, true}; diff --git a/es-core/src/components/OptionListComponent.h b/es-core/src/components/OptionListComponent.h index d7eead14e..5cfd049f1 100644 --- a/es-core/src/components/OptionListComponent.h +++ b/es-core/src/components/OptionListComponent.h @@ -246,6 +246,11 @@ public: } void setOverrideMultiText(const std::string& text) { mOverrideMultiText = text; } + void clearEntries() { mEntries.clear(); } + void setCallback(const std::function& callbackFunc) + { + mSelectedChangedCallback = callbackFunc; + } void setKeyRepeat(bool state, int delay = OPTIONLIST_REPEAT_START_DELAY, @@ -297,6 +302,7 @@ private: }; HelpStyle mHelpStyle; + std::function mSelectedChangedCallback; void open() { @@ -337,11 +343,11 @@ private: // this value, so abbreviate the string inside the arrows. auto font = Font::get(FONT_SIZE_MEDIUM); // Calculate with an extra dot to give some leeway. - float dotsSize = font->sizeText("....").x; - std::string abbreviatedString = font->getTextMaxWidth( - Utils::String::toUpper(it->name), it->maxNameLength); - float sizeDifference = font->sizeText(Utils::String::toUpper(it->name)).x - - font->sizeText(abbreviatedString).x; + float dotsSize {font->sizeText("....").x}; + std::string abbreviatedString {font->getTextMaxWidth( + Utils::String::toUpper(it->name), it->maxNameLength)}; + float sizeDifference {font->sizeText(Utils::String::toUpper(it->name)).x - + font->sizeText(abbreviatedString).x}; if (sizeDifference > 0.0f) { // It doesn't make sense to abbreviate if the number of pixels removed // by the abbreviation is less or equal to the size of the three dots @@ -367,6 +373,10 @@ private: mText.getSize().y); if (mParent) // Hack since there's no "on child size changed" callback. mParent->onSizeChanged(); + + if (mSelectedChangedCallback) + mSelectedChangedCallback(it->name); + break; } }