Improved the integration of the variant and aspect ratio options in the UI Settings menu.

Also reorganized the order of some settings.
This commit is contained in:
Leon Styhre 2022-02-01 18:06:32 +01:00
parent 36fe3c871c
commit c530373ddc
3 changed files with 184 additions and 97 deletions

View file

@ -102,24 +102,17 @@ void GuiMenu::openUIOptions()
// Theme options section. // Theme options section.
std::map<std::string, ThemeData::ThemeSet> themeSets {ThemeData::getThemeSets()}; std::map<std::string, ThemeData::ThemeSet> themeSets {ThemeData::getThemeSets()};
std::vector<ThemeData::ThemeVariant> themeVariantsVector;
std::vector<std::string> themeAspectRatiosVector;
std::map<std::string, ThemeData::ThemeSet>::const_iterator selectedSet; std::map<std::string, ThemeData::ThemeSet>::const_iterator selectedSet;
auto theme_set =
std::make_shared<OptionListComponent<std::string>>(getHelpStyle(), "THEME SET", false);
// Theme selection. // Theme selection.
if (!themeSets.empty()) { if (!themeSets.empty()) {
selectedSet = themeSets.find(Settings::getInstance()->getString("ThemeSet")); selectedSet = themeSets.find(Settings::getInstance()->getString("ThemeSet"));
if (selectedSet == themeSets.cend()) if (selectedSet == themeSets.cend())
selectedSet = themeSets.cbegin(); 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<OptionListComponent<std::string>>(getHelpStyle(), "THEME SET", false);
for (auto it = themeSets.cbegin(); it != themeSets.cend(); ++it) { for (auto it = themeSets.cbegin(); it != themeSets.cend(); ++it) {
// If required, abbreviate the theme set name so it doesn't overlap the setting name. // If required, abbreviate the theme set name so it doesn't overlap the setting name.
float maxNameLength = mSize.x * 0.62f; float maxNameLength = mSize.x * 0.62f;
@ -150,74 +143,102 @@ void GuiMenu::openUIOptions()
// Theme variants. // Theme variants.
auto themeVariant = auto themeVariant =
std::make_shared<OptionListComponent<std::string>>(getHelpStyle(), "THEME VARIANT", false); std::make_shared<OptionListComponent<std::string>>(getHelpStyle(), "THEME VARIANT", false);
if (!themeVariantsVector.empty()) { s->addWithLabel("THEME VARIANT", themeVariant);
std::string selectedVariant {Settings::getInstance()->getString("ThemeVariant")}; s->addSaveFunc([themeVariant, s] {
for (auto& variant : themeVariantsVector) { if (themeVariant->getSelected() != Settings::getInstance()->getString("ThemeVariant")) {
if (variant.selectable) { Settings::getInstance()->setString("ThemeVariant", themeVariant->getSelected());
// If required, abbreviate the variant name so it doesn't overlap the setting name. s->setNeedsSaving();
float maxNameLength {mSize.x * 0.62f}; s->setNeedsReloading();
themeVariant->add(variant.label, variant.name, variant.name == selectedVariant, s->setInvalidateCachedBackground();
maxNameLength);
}
} }
if (themeVariant->getSelectedObjects().size() == 0) });
themeVariant->selectEntry(0);
s->addWithLabel("THEME VARIANT", themeVariant); auto themeVariantsFunc = [=](const std::string& selectedTheme,
s->addSaveFunc([themeVariant, selectedVariant, s] { const std::string& selectedVariant) {
if (themeVariant->getSelected() != selectedVariant) { std::map<std::string, ThemeData::ThemeSet>::const_iterator currentSet {
Settings::getInstance()->setString("ThemeVariant", themeVariant->getSelected()); themeSets.find(selectedTheme)};
s->setNeedsSaving(); if (currentSet == themeSets.cend())
s->setNeedsReloading(); return;
s->setInvalidateCachedBackground(); // 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);
}
} }
}); if (themeVariant->getSelectedObjects().size() == 0)
} themeVariant->selectEntry(0);
else { }
if (selectedSet->second.capabilities.legacyTheme) else {
themeVariant->add("Legacy theme set", "none", true); if (currentSet->second.capabilities.legacyTheme)
else themeVariant->add("Legacy theme set", "none", true);
themeVariant->add("None defined", "none", true); else
s->addWithLabel("THEME VARIANT", themeVariant); themeVariant->add("None defined", "none", true);
themeVariant->setEnabled(false); themeVariant->setEnabled(false);
themeVariant->setOpacity(DISABLED_OPACITY); themeVariant->setOpacity(DISABLED_OPACITY);
themeVariant->getParent() themeVariant->getParent()
->getChild(themeVariant->getChildIndex() - 1) ->getChild(themeVariant->getChildIndex() - 1)
->setOpacity(DISABLED_OPACITY); ->setOpacity(DISABLED_OPACITY);
} }
};
themeVariantsFunc(Settings::getInstance()->getString("ThemeSet"),
Settings::getInstance()->getString("ThemeVariant"));
// Theme aspect ratios. // Theme aspect ratios.
auto themeAspectRatio = std::make_shared<OptionListComponent<std::string>>( auto themeAspectRatio = std::make_shared<OptionListComponent<std::string>>(
getHelpStyle(), "THEME ASPECT RATIO", false); getHelpStyle(), "THEME ASPECT RATIO", false);
if (!themeAspectRatiosVector.empty()) { s->addWithLabel("THEME ASPECT RATIO", themeAspectRatio);
std::string selectedAspectRatio {Settings::getInstance()->getString("ThemeAspectRatio")}; s->addSaveFunc([themeAspectRatio, s] {
for (auto& aspectRatio : themeAspectRatiosVector) if (themeAspectRatio->getSelected() !=
themeAspectRatio->add(ThemeData::getAspectRatioLabel(aspectRatio), aspectRatio, Settings::getInstance()->getString("ThemeAspectRatio")) {
aspectRatio == selectedAspectRatio); Settings::getInstance()->setString("ThemeAspectRatio", themeAspectRatio->getSelected());
if (themeAspectRatio->getSelectedObjects().size() == 0) s->setNeedsSaving();
themeAspectRatio->selectEntry(0); s->setNeedsReloading();
s->addWithLabel("THEME ASPECT RATIO", themeAspectRatio); s->setInvalidateCachedBackground();
s->addSaveFunc([themeAspectRatio, selectedAspectRatio, s] { }
if (themeAspectRatio->getSelected() != selectedAspectRatio) { });
Settings::getInstance()->setString("ThemeAspectRatio",
themeAspectRatio->getSelected()); auto themeAspectRatiosFunc = [=](const std::string& selectedTheme,
s->setNeedsSaving(); const std::string& selectedAspectRatio) {
s->setNeedsReloading(); std::map<std::string, ThemeData::ThemeSet>::const_iterator currentSet {
s->setInvalidateCachedBackground(); themeSets.find(selectedTheme)};
} if (currentSet == themeSets.cend())
}); return;
} // We need to recreate the OptionListComponent entries.
else { themeAspectRatio->clearEntries();
if (selectedSet->second.capabilities.legacyTheme) if (currentSet->second.capabilities.aspectRatios.size() > 0) {
themeAspectRatio->add("Legacy theme set", "none", true); for (auto& aspectRatio : currentSet->second.capabilities.aspectRatios)
else themeAspectRatio->add(ThemeData::getAspectRatioLabel(aspectRatio), aspectRatio,
themeAspectRatio->add("None defined", "none", true); aspectRatio == selectedAspectRatio);
s->addWithLabel("THEME ASPECT RATIO", themeAspectRatio); if (themeAspectRatio->getSelectedObjects().size() == 0)
themeAspectRatio->setEnabled(false); themeAspectRatio->selectEntry(0);
themeAspectRatio->setOpacity(DISABLED_OPACITY); }
themeAspectRatio->getParent() else {
->getChild(themeAspectRatio->getChildIndex() - 1) if (currentSet->second.capabilities.legacyTheme)
->setOpacity(DISABLED_OPACITY); 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. // Legacy gamelist view style.
auto gamelist_view_style = std::make_shared<OptionListComponent<std::string>>( auto gamelist_view_style = std::make_shared<OptionListComponent<std::string>>(
@ -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. // Legacy ransition style.
auto transition_style = std::make_shared<OptionListComponent<std::string>>( auto transition_style = std::make_shared<OptionListComponent<std::string>>(
getHelpStyle(), "LEGACY TRANSITION STYLE", false); getHelpStyle(), "LEGACY TRANSITION STYLE", false);
@ -270,14 +283,78 @@ void GuiMenu::openUIOptions()
} }
}); });
// TEMPORARY // When the theme set entries are scrolled or selected, update the relevant rows.
// if (!selectedSet->second.capabilities.legacyTheme) { auto scrollThemeSetFunc = [=](const std::string& themeName, bool firstRun = false) {
// transition_style->setEnabled(false); auto selectedSet = themeSets.find(themeName);
// transition_style->setOpacity(DISABLED_OPACITY); if (selectedSet == themeSets.cend())
// transition_style->getParent() return;
// ->getChild(transition_style->getChildIndex() - 1) if (!firstRun) {
// ->setOpacity(DISABLED_OPACITY); 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. // Optionally start in selected system/gamelist.
auto startupSystem = std::make_shared<OptionListComponent<std::string>>( auto startupSystem = std::make_shared<OptionListComponent<std::string>>(

View file

@ -129,16 +129,16 @@ void Settings::setDefaults()
mBoolMap["ScraperRetryPeerVerification"] = {false, false}; mBoolMap["ScraperRetryPeerVerification"] = {false, false};
// UI settings. // UI settings.
mStringMap["StartupSystem"] = {"", ""};
mStringMap["GamelistViewStyle"] = {"automatic", "automatic"};
mStringMap["TransitionStyle"] = {"slide", "slide"};
mStringMap["ThemeSet"] = {"rbsimple-DE", "rbsimple-DE"}; mStringMap["ThemeSet"] = {"rbsimple-DE", "rbsimple-DE"};
mStringMap["ThemeVariant"] = {"", ""}; mStringMap["ThemeVariant"] = {"", ""};
mStringMap["ThemeAspectRatio"] = {"", ""}; mStringMap["ThemeAspectRatio"] = {"", ""};
mStringMap["UIMode"] = {"full", "full"}; mStringMap["GamelistViewStyle"] = {"automatic", "automatic"};
mStringMap["TransitionStyle"] = {"slide", "slide"};
mStringMap["StartupSystem"] = {"", ""};
mStringMap["DefaultSortOrder"] = {"filename, ascending", "filename, ascending"}; mStringMap["DefaultSortOrder"] = {"filename, ascending", "filename, ascending"};
mStringMap["MenuOpeningEffect"] = {"scale-up", "scale-up"}; mStringMap["MenuOpeningEffect"] = {"scale-up", "scale-up"};
mStringMap["LaunchScreenDuration"] = {"normal", "normal"}; mStringMap["LaunchScreenDuration"] = {"normal", "normal"};
mStringMap["UIMode"] = {"full", "full"};
// UI settings -> media viewer settings. // UI settings -> media viewer settings.
mBoolMap["MediaViewerKeepVideoRunning"] = {true, true}; mBoolMap["MediaViewerKeepVideoRunning"] = {true, true};

View file

@ -246,6 +246,11 @@ public:
} }
void setOverrideMultiText(const std::string& text) { mOverrideMultiText = text; } void setOverrideMultiText(const std::string& text) { mOverrideMultiText = text; }
void clearEntries() { mEntries.clear(); }
void setCallback(const std::function<void(const std::string&)>& callbackFunc)
{
mSelectedChangedCallback = callbackFunc;
}
void setKeyRepeat(bool state, void setKeyRepeat(bool state,
int delay = OPTIONLIST_REPEAT_START_DELAY, int delay = OPTIONLIST_REPEAT_START_DELAY,
@ -297,6 +302,7 @@ private:
}; };
HelpStyle mHelpStyle; HelpStyle mHelpStyle;
std::function<void(const std::string&)> mSelectedChangedCallback;
void open() void open()
{ {
@ -337,11 +343,11 @@ private:
// this value, so abbreviate the string inside the arrows. // this value, so abbreviate the string inside the arrows.
auto font = Font::get(FONT_SIZE_MEDIUM); auto font = Font::get(FONT_SIZE_MEDIUM);
// Calculate with an extra dot to give some leeway. // Calculate with an extra dot to give some leeway.
float dotsSize = font->sizeText("....").x; float dotsSize {font->sizeText("....").x};
std::string abbreviatedString = font->getTextMaxWidth( std::string abbreviatedString {font->getTextMaxWidth(
Utils::String::toUpper(it->name), it->maxNameLength); Utils::String::toUpper(it->name), it->maxNameLength)};
float sizeDifference = font->sizeText(Utils::String::toUpper(it->name)).x - float sizeDifference {font->sizeText(Utils::String::toUpper(it->name)).x -
font->sizeText(abbreviatedString).x; font->sizeText(abbreviatedString).x};
if (sizeDifference > 0.0f) { if (sizeDifference > 0.0f) {
// It doesn't make sense to abbreviate if the number of pixels removed // 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 // by the abbreviation is less or equal to the size of the three dots
@ -367,6 +373,10 @@ private:
mText.getSize().y); mText.getSize().y);
if (mParent) // Hack since there's no "on child size changed" callback. if (mParent) // Hack since there's no "on child size changed" callback.
mParent->onSizeChanged(); mParent->onSizeChanged();
if (mSelectedChangedCallback)
mSelectedChangedCallback(it->name);
break; break;
} }
} }