mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-03-06 14:27:43 +00:00
Completely removed support for legacy EmulationStation theme sets
This commit is contained in:
parent
d0fc8cd56e
commit
ed1e11418b
|
@ -55,7 +55,6 @@ set(ES_HEADERS
|
|||
|
||||
# Views
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GamelistBase.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GamelistLegacy.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/GamelistView.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/SystemView.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/views/ViewController.h
|
||||
|
|
|
@ -152,8 +152,6 @@ void GuiMenu::openUIOptions()
|
|||
// If required, abbreviate the theme set name so it doesn't overlap the setting name.
|
||||
const float maxNameLength {mSize.x * 0.62f};
|
||||
std::string themeName {(*it).first};
|
||||
if ((*it).second.second.capabilities.legacyTheme)
|
||||
themeName.append(" [LEGACY]");
|
||||
themeSet->add(themeName, it->second.first, (*it).second.first == selectedSet->first,
|
||||
maxNameLength);
|
||||
}
|
||||
|
@ -217,10 +215,7 @@ void GuiMenu::openUIOptions()
|
|||
themeVariant->selectEntry(0);
|
||||
}
|
||||
else {
|
||||
if (currentSet->second.capabilities.legacyTheme)
|
||||
themeVariant->add("Legacy theme set", "none", true);
|
||||
else
|
||||
themeVariant->add("None defined", "none", true);
|
||||
themeVariant->add("None defined", "none", true);
|
||||
themeVariant->setEnabled(false);
|
||||
themeVariant->setOpacity(DISABLED_OPACITY);
|
||||
themeVariant->getParent()
|
||||
|
@ -266,10 +261,7 @@ void GuiMenu::openUIOptions()
|
|||
themeColorScheme->selectEntry(0);
|
||||
}
|
||||
else {
|
||||
if (currentSet->second.capabilities.legacyTheme)
|
||||
themeColorScheme->add("Legacy theme set", "none", true);
|
||||
else
|
||||
themeColorScheme->add("None defined", "none", true);
|
||||
themeColorScheme->add("None defined", "none", true);
|
||||
themeColorScheme->setEnabled(false);
|
||||
themeColorScheme->setOpacity(DISABLED_OPACITY);
|
||||
themeColorScheme->getParent()
|
||||
|
@ -311,10 +303,7 @@ void GuiMenu::openUIOptions()
|
|||
themeAspectRatio->selectEntry(0);
|
||||
}
|
||||
else {
|
||||
if (currentSet->second.capabilities.legacyTheme)
|
||||
themeAspectRatio->add("Legacy theme set", "none", true);
|
||||
else
|
||||
themeAspectRatio->add("None defined", "none", true);
|
||||
themeAspectRatio->add("None defined", "none", true);
|
||||
themeAspectRatio->setEnabled(false);
|
||||
themeAspectRatio->setOpacity(DISABLED_OPACITY);
|
||||
themeAspectRatio->getParent()
|
||||
|
@ -353,8 +342,56 @@ void GuiMenu::openUIOptions()
|
|||
return;
|
||||
// We need to recreate the OptionListComponent entries.
|
||||
themeTransitions->clearEntries();
|
||||
if (currentSet->second.capabilities.legacyTheme) {
|
||||
themeTransitions->add("Legacy theme set", "automatic", true);
|
||||
themeTransitions->add("AUTOMATIC", "automatic", "automatic" == selectedThemeTransitions);
|
||||
if (currentSet->second.capabilities.transitions.size() == 1 &&
|
||||
currentSet->second.capabilities.transitions.front().selectable) {
|
||||
std::string label;
|
||||
if (currentSet->second.capabilities.transitions.front().label == "")
|
||||
label = "THEME PROFILE";
|
||||
else
|
||||
label = currentSet->second.capabilities.transitions.front().label;
|
||||
const std::string transitions {
|
||||
currentSet->second.capabilities.transitions.front().name};
|
||||
themeTransitions->add(label, transitions, transitions == selectedThemeTransitions);
|
||||
}
|
||||
else {
|
||||
for (size_t i {0}; i < currentSet->second.capabilities.transitions.size(); ++i) {
|
||||
if (!currentSet->second.capabilities.transitions[i].selectable)
|
||||
continue;
|
||||
std::string label;
|
||||
if (currentSet->second.capabilities.transitions[i].label == "")
|
||||
label = "THEME PROFILE " + std::to_string(i + 1);
|
||||
else
|
||||
label = currentSet->second.capabilities.transitions[i].label;
|
||||
const std::string transitions {currentSet->second.capabilities.transitions[i].name};
|
||||
themeTransitions->add(label, transitions, transitions == selectedThemeTransitions);
|
||||
}
|
||||
}
|
||||
if (std::find(currentSet->second.capabilities.suppressedTransitionProfiles.cbegin(),
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend(),
|
||||
"builtin-instant") ==
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend()) {
|
||||
themeTransitions->add("INSTANT (BUILT-IN)", "builtin-instant",
|
||||
"builtin-instant" == selectedThemeTransitions);
|
||||
}
|
||||
if (std::find(currentSet->second.capabilities.suppressedTransitionProfiles.cbegin(),
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend(),
|
||||
"builtin-slide") ==
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend()) {
|
||||
themeTransitions->add("SLIDE (BUILT-IN)", "builtin-slide",
|
||||
"builtin-slide" == selectedThemeTransitions);
|
||||
}
|
||||
if (std::find(currentSet->second.capabilities.suppressedTransitionProfiles.cbegin(),
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend(),
|
||||
"builtin-fade") ==
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend()) {
|
||||
themeTransitions->add("FADE (BUILT-IN)", "builtin-fade",
|
||||
"builtin-fade" == selectedThemeTransitions);
|
||||
}
|
||||
if (themeTransitions->getSelectedObjects().size() == 0)
|
||||
themeTransitions->selectEntry(0);
|
||||
|
||||
if (themeTransitions->getNumEntries() == 1) {
|
||||
themeTransitions->setEnabled(false);
|
||||
themeTransitions->setOpacity(DISABLED_OPACITY);
|
||||
themeTransitions->getParent()
|
||||
|
@ -362,128 +399,17 @@ void GuiMenu::openUIOptions()
|
|||
->setOpacity(DISABLED_OPACITY);
|
||||
}
|
||||
else {
|
||||
themeTransitions->add("AUTOMATIC", "automatic",
|
||||
"automatic" == selectedThemeTransitions);
|
||||
if (currentSet->second.capabilities.transitions.size() == 1 &&
|
||||
currentSet->second.capabilities.transitions.front().selectable) {
|
||||
std::string label;
|
||||
if (currentSet->second.capabilities.transitions.front().label == "")
|
||||
label = "THEME PROFILE";
|
||||
else
|
||||
label = currentSet->second.capabilities.transitions.front().label;
|
||||
const std::string transitions {
|
||||
currentSet->second.capabilities.transitions.front().name};
|
||||
themeTransitions->add(label, transitions, transitions == selectedThemeTransitions);
|
||||
}
|
||||
else {
|
||||
for (size_t i {0}; i < currentSet->second.capabilities.transitions.size(); ++i) {
|
||||
if (!currentSet->second.capabilities.transitions[i].selectable)
|
||||
continue;
|
||||
std::string label;
|
||||
if (currentSet->second.capabilities.transitions[i].label == "")
|
||||
label = "THEME PROFILE " + std::to_string(i + 1);
|
||||
else
|
||||
label = currentSet->second.capabilities.transitions[i].label;
|
||||
const std::string transitions {
|
||||
currentSet->second.capabilities.transitions[i].name};
|
||||
themeTransitions->add(label, transitions,
|
||||
transitions == selectedThemeTransitions);
|
||||
}
|
||||
}
|
||||
if (std::find(currentSet->second.capabilities.suppressedTransitionProfiles.cbegin(),
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend(),
|
||||
"builtin-instant") ==
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend()) {
|
||||
themeTransitions->add("INSTANT (BUILT-IN)", "builtin-instant",
|
||||
"builtin-instant" == selectedThemeTransitions);
|
||||
}
|
||||
if (std::find(currentSet->second.capabilities.suppressedTransitionProfiles.cbegin(),
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend(),
|
||||
"builtin-slide") ==
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend()) {
|
||||
themeTransitions->add("SLIDE (BUILT-IN)", "builtin-slide",
|
||||
"builtin-slide" == selectedThemeTransitions);
|
||||
}
|
||||
if (std::find(currentSet->second.capabilities.suppressedTransitionProfiles.cbegin(),
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend(),
|
||||
"builtin-fade") ==
|
||||
currentSet->second.capabilities.suppressedTransitionProfiles.cend()) {
|
||||
themeTransitions->add("FADE (BUILT-IN)", "builtin-fade",
|
||||
"builtin-fade" == selectedThemeTransitions);
|
||||
}
|
||||
if (themeTransitions->getSelectedObjects().size() == 0)
|
||||
themeTransitions->selectEntry(0);
|
||||
|
||||
if (themeTransitions->getNumEntries() == 1) {
|
||||
themeTransitions->setEnabled(false);
|
||||
themeTransitions->setOpacity(DISABLED_OPACITY);
|
||||
themeTransitions->getParent()
|
||||
->getChild(themeTransitions->getChildIndex() - 1)
|
||||
->setOpacity(DISABLED_OPACITY);
|
||||
}
|
||||
else {
|
||||
themeTransitions->setEnabled(true);
|
||||
themeTransitions->setOpacity(1.0f);
|
||||
themeTransitions->getParent()
|
||||
->getChild(themeTransitions->getChildIndex() - 1)
|
||||
->setOpacity(1.0f);
|
||||
}
|
||||
themeTransitions->setEnabled(true);
|
||||
themeTransitions->setOpacity(1.0f);
|
||||
themeTransitions->getParent()
|
||||
->getChild(themeTransitions->getChildIndex() - 1)
|
||||
->setOpacity(1.0f);
|
||||
}
|
||||
};
|
||||
|
||||
themeTransitionsFunc(Settings::getInstance()->getString("ThemeSet"),
|
||||
Settings::getInstance()->getString("ThemeTransitions"));
|
||||
|
||||
// Legacy gamelist view style.
|
||||
auto gamelistViewStyle = std::make_shared<OptionListComponent<std::string>>(
|
||||
getHelpStyle(), "LEGACY GAMELIST VIEW STYLE", false);
|
||||
std::string selectedViewStyle {Settings::getInstance()->getString("GamelistViewStyle")};
|
||||
gamelistViewStyle->add("AUTOMATIC", "automatic", selectedViewStyle == "automatic");
|
||||
gamelistViewStyle->add("BASIC", "basic", selectedViewStyle == "basic");
|
||||
gamelistViewStyle->add("DETAILED", "detailed", selectedViewStyle == "detailed");
|
||||
gamelistViewStyle->add("VIDEO", "video", selectedViewStyle == "video");
|
||||
// If there are no objects returned, then there must be a manually modified entry in the
|
||||
// configuration file. Simply set the view style to "automatic" in this case.
|
||||
if (gamelistViewStyle->getSelectedObjects().size() == 0)
|
||||
gamelistViewStyle->selectEntry(0);
|
||||
s->addWithLabel("LEGACY GAMELIST VIEW STYLE", gamelistViewStyle);
|
||||
s->addSaveFunc([gamelistViewStyle, s] {
|
||||
if (gamelistViewStyle->getSelected() !=
|
||||
Settings::getInstance()->getString("GamelistViewStyle")) {
|
||||
Settings::getInstance()->setString("GamelistViewStyle",
|
||||
gamelistViewStyle->getSelected());
|
||||
s->setNeedsSaving();
|
||||
s->setNeedsReloading();
|
||||
s->setInvalidateCachedBackground();
|
||||
}
|
||||
});
|
||||
|
||||
// Legacy theme transitions.
|
||||
auto legacyThemeTransitions = std::make_shared<OptionListComponent<std::string>>(
|
||||
getHelpStyle(), "LEGACY THEME TRANSITIONS", false);
|
||||
const std::string& selectedLegacyThemeTransitions {
|
||||
Settings::getInstance()->getString("LegacyThemeTransitions")};
|
||||
legacyThemeTransitions->add("INSTANT", "builtin-instant",
|
||||
selectedLegacyThemeTransitions == "builtin-instant");
|
||||
legacyThemeTransitions->add("SLIDE", "builtin-slide",
|
||||
selectedLegacyThemeTransitions == "builtin-slide");
|
||||
legacyThemeTransitions->add("FADE", "builtin-fade",
|
||||
selectedLegacyThemeTransitions == "builtin-fade");
|
||||
// If there are no objects returned, then there must be a manually modified entry in the
|
||||
// configuration file. Simply set legacy theme transitions to "builtin-instant" in this case.
|
||||
if (legacyThemeTransitions->getSelectedObjects().size() == 0)
|
||||
legacyThemeTransitions->selectEntry(0);
|
||||
s->addWithLabel("LEGACY THEME TRANSITIONS", legacyThemeTransitions);
|
||||
s->addSaveFunc([legacyThemeTransitions, s] {
|
||||
if (legacyThemeTransitions->getSelected() !=
|
||||
Settings::getInstance()->getString("LegacyThemeTransitions")) {
|
||||
Settings::getInstance()->setString("LegacyThemeTransitions",
|
||||
legacyThemeTransitions->getSelected());
|
||||
ThemeData::setThemeTransitions();
|
||||
s->setNeedsSaving();
|
||||
}
|
||||
});
|
||||
|
||||
// Quick system select (navigate between systems in the gamelist view).
|
||||
auto quickSystemSelect = std::make_shared<OptionListComponent<std::string>>(
|
||||
getHelpStyle(), "QUICK SYSTEM SELECT", false);
|
||||
|
@ -807,32 +733,6 @@ void GuiMenu::openUIOptions()
|
|||
});
|
||||
}
|
||||
|
||||
// Display pillarboxes (and letterboxes) for videos in the gamelists.
|
||||
auto gamelistVideoPillarbox = std::make_shared<SwitchComponent>();
|
||||
gamelistVideoPillarbox->setState(Settings::getInstance()->getBool("GamelistVideoPillarbox"));
|
||||
s->addWithLabel("DISPLAY PILLARBOXES FOR GAMELIST VIDEOS", gamelistVideoPillarbox);
|
||||
s->addSaveFunc([gamelistVideoPillarbox, s] {
|
||||
if (gamelistVideoPillarbox->getState() !=
|
||||
Settings::getInstance()->getBool("GamelistVideoPillarbox")) {
|
||||
Settings::getInstance()->setBool("GamelistVideoPillarbox",
|
||||
gamelistVideoPillarbox->getState());
|
||||
s->setNeedsSaving();
|
||||
}
|
||||
});
|
||||
|
||||
// Render scanlines for videos in the gamelists.
|
||||
auto gamelistVideoScanlines = std::make_shared<SwitchComponent>();
|
||||
gamelistVideoScanlines->setState(Settings::getInstance()->getBool("GamelistVideoScanlines"));
|
||||
s->addWithLabel("RENDER SCANLINES FOR GAMELIST VIDEOS", gamelistVideoScanlines);
|
||||
s->addSaveFunc([gamelistVideoScanlines, s] {
|
||||
if (gamelistVideoScanlines->getState() !=
|
||||
Settings::getInstance()->getBool("GamelistVideoScanlines")) {
|
||||
Settings::getInstance()->setBool("GamelistVideoScanlines",
|
||||
gamelistVideoScanlines->getState());
|
||||
s->setNeedsSaving();
|
||||
}
|
||||
});
|
||||
|
||||
// Sort folders on top of the gamelists.
|
||||
auto foldersOnTop = std::make_shared<SwitchComponent>();
|
||||
foldersOnTop->setState(Settings::getInstance()->getBool("FoldersOnTop"));
|
||||
|
@ -948,7 +848,7 @@ void GuiMenu::openUIOptions()
|
|||
if (variant.selectable)
|
||||
++selectableVariants;
|
||||
}
|
||||
if (!selectedSet->second.capabilities.legacyTheme && selectableVariants > 0) {
|
||||
if (selectableVariants > 0) {
|
||||
themeVariant->setEnabled(true);
|
||||
themeVariant->setOpacity(1.0f);
|
||||
themeVariant->getParent()
|
||||
|
@ -962,8 +862,7 @@ void GuiMenu::openUIOptions()
|
|||
->getChild(themeVariant->getChildIndex() - 1)
|
||||
->setOpacity(DISABLED_OPACITY);
|
||||
}
|
||||
if (!selectedSet->second.capabilities.legacyTheme &&
|
||||
selectedSet->second.capabilities.colorSchemes.size() > 0) {
|
||||
if (selectedSet->second.capabilities.colorSchemes.size() > 0) {
|
||||
themeColorScheme->setEnabled(true);
|
||||
themeColorScheme->setOpacity(1.0f);
|
||||
themeColorScheme->getParent()
|
||||
|
@ -977,8 +876,7 @@ void GuiMenu::openUIOptions()
|
|||
->getChild(themeColorScheme->getChildIndex() - 1)
|
||||
->setOpacity(DISABLED_OPACITY);
|
||||
}
|
||||
if (!selectedSet->second.capabilities.legacyTheme &&
|
||||
selectedSet->second.capabilities.aspectRatios.size() > 0) {
|
||||
if (selectedSet->second.capabilities.aspectRatios.size() > 0) {
|
||||
themeAspectRatio->setEnabled(true);
|
||||
themeAspectRatio->setOpacity(1.0f);
|
||||
themeAspectRatio->getParent()
|
||||
|
@ -992,64 +890,6 @@ void GuiMenu::openUIOptions()
|
|||
->getChild(themeAspectRatio->getChildIndex() - 1)
|
||||
->setOpacity(DISABLED_OPACITY);
|
||||
}
|
||||
if (!selectedSet->second.capabilities.legacyTheme) {
|
||||
gamelistViewStyle->setEnabled(false);
|
||||
gamelistViewStyle->setOpacity(DISABLED_OPACITY);
|
||||
gamelistViewStyle->getParent()
|
||||
->getChild(gamelistViewStyle->getChildIndex() - 1)
|
||||
->setOpacity(DISABLED_OPACITY);
|
||||
|
||||
legacyThemeTransitions->setEnabled(false);
|
||||
legacyThemeTransitions->setOpacity(DISABLED_OPACITY);
|
||||
legacyThemeTransitions->getParent()
|
||||
->getChild(legacyThemeTransitions->getChildIndex() - 1)
|
||||
->setOpacity(DISABLED_OPACITY);
|
||||
|
||||
// Pillarboxes are theme-controlled for newer themes.
|
||||
gamelistVideoPillarbox->setEnabled(false);
|
||||
gamelistVideoPillarbox->setOpacity(DISABLED_OPACITY);
|
||||
gamelistVideoPillarbox->getParent()
|
||||
->getChild(gamelistVideoPillarbox->getChildIndex() - 1)
|
||||
->setOpacity(DISABLED_OPACITY);
|
||||
|
||||
// Scanlines are theme-controlled for newer themes.
|
||||
gamelistVideoScanlines->setEnabled(false);
|
||||
gamelistVideoScanlines->setOpacity(DISABLED_OPACITY);
|
||||
gamelistVideoScanlines->getParent()
|
||||
->getChild(gamelistVideoScanlines->getChildIndex() - 1)
|
||||
->setOpacity(DISABLED_OPACITY);
|
||||
}
|
||||
else {
|
||||
gamelistViewStyle->setEnabled(true);
|
||||
gamelistViewStyle->setOpacity(1.0f);
|
||||
gamelistViewStyle->getParent()
|
||||
->getChild(gamelistViewStyle->getChildIndex() - 1)
|
||||
->setOpacity(1.0f);
|
||||
|
||||
themeTransitions->setEnabled(false);
|
||||
themeTransitions->setOpacity(DISABLED_OPACITY);
|
||||
themeTransitions->getParent()
|
||||
->getChild(themeTransitions->getChildIndex() - 1)
|
||||
->setOpacity(DISABLED_OPACITY);
|
||||
|
||||
legacyThemeTransitions->setEnabled(true);
|
||||
legacyThemeTransitions->setOpacity(1.0f);
|
||||
legacyThemeTransitions->getParent()
|
||||
->getChild(legacyThemeTransitions->getChildIndex() - 1)
|
||||
->setOpacity(1.0f);
|
||||
|
||||
gamelistVideoPillarbox->setEnabled(true);
|
||||
gamelistVideoPillarbox->setOpacity(1.0f);
|
||||
gamelistVideoPillarbox->getParent()
|
||||
->getChild(gamelistVideoPillarbox->getChildIndex() - 1)
|
||||
->setOpacity(1.0f);
|
||||
|
||||
gamelistVideoScanlines->setEnabled(true);
|
||||
gamelistVideoScanlines->setOpacity(1.0f);
|
||||
gamelistVideoScanlines->getParent()
|
||||
->getChild(gamelistVideoScanlines->getChildIndex() - 1)
|
||||
->setOpacity(1.0f);
|
||||
}
|
||||
};
|
||||
|
||||
scrollThemeSetFunc(selectedSet->first, true);
|
||||
|
|
|
@ -1,750 +0,0 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// EmulationStation Desktop Edition
|
||||
// GamelistLegacy.h
|
||||
//
|
||||
// Specific gamelist functions for backward compatibility (legacy mode).
|
||||
//
|
||||
|
||||
#ifndef ES_APP_VIEWS_GAMELIST_LEGACY_H
|
||||
#define ES_APP_VIEWS_GAMELIST_LEGACY_H
|
||||
|
||||
#include "CollectionSystemsManager.h"
|
||||
#include "animations/LambdaAnimation.h"
|
||||
|
||||
#define FADE_IN_START_OPACITY 0.5f
|
||||
#define FADE_IN_TIME 325
|
||||
|
||||
void GamelistView::legacyPopulateFields()
|
||||
{
|
||||
const float padding {0.01f};
|
||||
|
||||
// Logo text (fallback if no logo image exists).
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setText(mRoot->getSystem()->getFullName(), false);
|
||||
mTextComponents.back()->setSize(mSize.x, 0.0f);
|
||||
mTextComponents.back()->setPosition(0.0f, 0.0f);
|
||||
mTextComponents.back()->setHorizontalAlignment(ALIGN_CENTER);
|
||||
mTextComponents.back()->setColor(0x000000FF);
|
||||
mTextComponents.back()->setDefaultZIndex(50.0f);
|
||||
mTextComponents.back()->setZIndex(10.0f);
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
// Logo.
|
||||
mImageComponents.push_back(std::make_unique<ImageComponent>());
|
||||
mImageComponents.back()->setResize(0.0f, mSize.y * 0.185f);
|
||||
mImageComponents.back()->setOrigin(0.5f, 0.0f);
|
||||
mImageComponents.back()->setPosition(mSize.x / 2.0f, 0.0f);
|
||||
mImageComponents.back()->setDefaultZIndex(50.0f);
|
||||
mImageComponents.back()->setVisible(false);
|
||||
addChild(mImageComponents.back().get());
|
||||
|
||||
// Background.
|
||||
mImageComponents.push_back(std::make_unique<ImageComponent>());
|
||||
mImageComponents.back()->setResize(mSize.x, mSize.y);
|
||||
mImageComponents.back()->setDefaultZIndex(0.0f);
|
||||
addChild(mImageComponents.back().get());
|
||||
|
||||
// Thumbnails.
|
||||
mImageComponents.push_back(std::make_unique<ImageComponent>());
|
||||
mImageComponents.back()->setThemeMetadata("image_md_thumbnail");
|
||||
mImageComponents.back()->setOrigin(0.5f, 0.5f);
|
||||
mImageComponents.back()->setMaxSize(mSize.x * (0.25f - 2.0f * padding), mSize.y * 0.10f);
|
||||
mImageComponents.back()->setDefaultZIndex(25.0f);
|
||||
mImageComponents.back()->setScrollFadeIn(true);
|
||||
mImageComponents.back()->setVisible(false);
|
||||
addChild(mImageComponents.back().get());
|
||||
|
||||
// Marquee.
|
||||
mImageComponents.push_back(std::make_unique<ImageComponent>());
|
||||
mImageComponents.back()->setThemeMetadata("image_md_marquee");
|
||||
mImageComponents.back()->setLinearInterpolation(true);
|
||||
mImageComponents.back()->setOrigin(0.5f, 0.5f);
|
||||
mImageComponents.back()->setMaxSize(mSize.x * (0.5f - 2.0f * padding), mSize.y * 0.18f);
|
||||
mImageComponents.back()->setDefaultZIndex(35.0f);
|
||||
mImageComponents.back()->setVisible(false);
|
||||
addChild(mImageComponents.back().get());
|
||||
|
||||
// Image.
|
||||
mImageComponents.push_back(std::make_unique<ImageComponent>());
|
||||
mImageComponents.back()->setThemeMetadata("image_md_image");
|
||||
mImageComponents.back()->setOrigin(0.5f, 0.5f);
|
||||
mImageComponents.back()->setPosition(mSize.x * 0.25f,
|
||||
mPrimary->getPosition().y + mSize.y * 0.2125f);
|
||||
mImageComponents.back()->setMaxSize(mSize.x * (0.50f - 2.0f * padding), mSize.y * 0.4f);
|
||||
mImageComponents.back()->setDefaultZIndex(30.0f);
|
||||
mImageComponents.back()->setScrollFadeIn(true);
|
||||
mImageComponents.back()->setVisible(false);
|
||||
addChild(mImageComponents.back().get());
|
||||
|
||||
if (mViewStyle == ViewController::VIDEO) {
|
||||
// Video.
|
||||
mVideoComponents.push_back(std::make_unique<VideoFFmpegComponent>());
|
||||
mVideoComponents.back()->setThemeMetadata("video_md_video");
|
||||
mVideoComponents.back()->setOrigin(0.5f, 0.5f);
|
||||
mVideoComponents.back()->setPosition(mSize.x * 0.25f,
|
||||
mPrimary->getPosition().y + mSize.y * 0.2125f);
|
||||
mVideoComponents.back()->setSize(mSize.x * (0.5f - 2.0f * padding), mSize.y * 0.4f);
|
||||
mVideoComponents.back()->setDefaultZIndex(30.0f);
|
||||
mVideoComponents.back()->setScrollFadeIn(true);
|
||||
mVideoComponents.back()->setVisible(false);
|
||||
addChild(mVideoComponents.back().get());
|
||||
}
|
||||
|
||||
mPrimary->setPosition(mSize.x * (0.50f + padding), mPrimary->getPosition().y);
|
||||
mPrimary->setSize(mSize.x * (0.50f - padding), mPrimary->getSize().y);
|
||||
mPrimary->setAlignment(TextListComponent<FileData*>::PrimaryAlignment::ALIGN_LEFT);
|
||||
mPrimary->setCursorChangedCallback([&](const CursorState& state) { legacyUpdateView(state); });
|
||||
|
||||
// Metadata labels + values.
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setText("Rating: ", false);
|
||||
mTextComponents.back()->setThemeMetadata("text_md_lbl_rating");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setText("Released: ", false);
|
||||
mTextComponents.back()->setThemeMetadata("text_md_lbl_releasedate");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setText("Developer: ", false);
|
||||
mTextComponents.back()->setThemeMetadata("text_md_lbl_developer");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setText("Publisher: ", false);
|
||||
mTextComponents.back()->setThemeMetadata("text_md_lbl_publisher");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setText("Genre: ", false);
|
||||
mTextComponents.back()->setThemeMetadata("text_md_lbl_genre");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setText("Players: ", false);
|
||||
mTextComponents.back()->setThemeMetadata("text_md_lbl_players");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setText("Last played: ", false);
|
||||
mTextComponents.back()->setThemeMetadata("text_md_lbl_lastplayed");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setText("Times played: ", false);
|
||||
mTextComponents.back()->setThemeMetadata("text_md_lbl_playcount");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mRatingComponents.push_back(std::make_unique<RatingComponent>());
|
||||
mRatingComponents.back()->setThemeMetadata("rating_md_rating");
|
||||
mRatingComponents.back()->setDefaultZIndex(40.0f);
|
||||
addChild(mRatingComponents.back().get());
|
||||
|
||||
mDateTimeComponents.push_back(std::make_unique<DateTimeComponent>());
|
||||
mDateTimeComponents.back()->setThemeMetadata("datetime_md_releasedate");
|
||||
addChild(mDateTimeComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setThemeMetadata("text_md_developer");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setThemeMetadata("text_md_publisher");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setThemeMetadata("text_md_genre");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setThemeMetadata("text_md_players");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mDateTimeComponents.push_back(std::make_unique<DateTimeComponent>());
|
||||
mDateTimeComponents.back()->setThemeMetadata("datetime_md_lastplayed");
|
||||
mDateTimeComponents.back()->setDisplayRelative(true);
|
||||
addChild(mDateTimeComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setThemeMetadata("text_md_playcount");
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setThemeMetadata("text_md_name");
|
||||
mTextComponents.back()->setPosition(mSize.x, mSize.y);
|
||||
mTextComponents.back()->setFont(Font::get(FONT_SIZE_MEDIUM_FIXED));
|
||||
mTextComponents.back()->setHorizontalAlignment(ALIGN_CENTER);
|
||||
mTextComponents.back()->setColor(0xAAAAAAFF);
|
||||
mTextComponents.back()->setDefaultZIndex(40.0f);
|
||||
addChild(mTextComponents.back().get());
|
||||
|
||||
// Badges.
|
||||
mBadgeComponents.push_back(std::make_unique<BadgeComponent>());
|
||||
mBadgeComponents.back()->setThemeMetadata("badges_md_badges");
|
||||
mBadgeComponents.back()->setOrigin(0.5f, 0.5f);
|
||||
mBadgeComponents.back()->setPosition(mSize.x * 0.8f, mSize.y * 0.7f);
|
||||
mBadgeComponents.back()->setSize(mSize.x * 0.15f, mSize.y * 0.2f);
|
||||
mBadgeComponents.back()->setDefaultZIndex(50.0f);
|
||||
addChild(mBadgeComponents.back().get());
|
||||
|
||||
// Scrollable container (game description).
|
||||
mContainerComponents.push_back(std::make_unique<ScrollableContainer>());
|
||||
mContainerComponents.back()->setThemeMetadata("text_md_description");
|
||||
mContainerComponents.back()->setAutoScroll(true);
|
||||
mContainerComponents.back()->setVisible(false);
|
||||
mContainerComponents.back()->setDefaultZIndex(40.0f);
|
||||
addChild(mContainerComponents.back().get());
|
||||
|
||||
mTextComponents.push_back(std::make_unique<TextComponent>());
|
||||
mTextComponents.back()->setFont(Font::get(FONT_SIZE_SMALL));
|
||||
mTextComponents.back()->setSize(mContainerComponents.back()->getSize().x, 0.0f);
|
||||
mContainerComponents.back()->addChild(mTextComponents.back().get());
|
||||
|
||||
mGamelistInfoComponents.push_back(std::make_unique<TextComponent>());
|
||||
mGamelistInfoComponents.back()->setThemeMetadata("text_gamelistInfo");
|
||||
mGamelistInfoComponents.back()->setOrigin(0.5f, 0.5f);
|
||||
mGamelistInfoComponents.back()->setFont(Font::get(FONT_SIZE_SMALL));
|
||||
mGamelistInfoComponents.back()->setDefaultZIndex(50.0f);
|
||||
mGamelistInfoComponents.back()->setVisible(true);
|
||||
addChild(mGamelistInfoComponents.back().get());
|
||||
}
|
||||
|
||||
void GamelistView::legacyOnThemeChanged(const std::shared_ptr<ThemeData>& theme)
|
||||
{
|
||||
if (mTextList == nullptr) {
|
||||
mTextList = std::make_unique<TextListComponent<FileData*>>();
|
||||
mPrimary = mTextList.get();
|
||||
}
|
||||
|
||||
mSystemNameSuffix = true;
|
||||
legacyPopulateFields();
|
||||
|
||||
using namespace ThemeFlags;
|
||||
|
||||
mTextComponents[LOGOTEXT]->applyTheme(theme, getName(), "text_logoText", ALL);
|
||||
mImageComponents[LOGO]->applyTheme(theme, getName(), "image_logo", ALL);
|
||||
mImageComponents[BACKGROUND]->applyTheme(theme, getName(), "image_background", ALL);
|
||||
|
||||
auto themeView = theme->getViewElements(getName());
|
||||
if (themeView.elements.find("text_logoText") == themeView.elements.end())
|
||||
mTextComponents[LOGOTEXT]->setVisible(false);
|
||||
|
||||
if (getName() == "basic")
|
||||
mPrimary->setAlignment(TextListComponent<FileData*>::PrimaryAlignment::ALIGN_CENTER);
|
||||
|
||||
// Make sure we don't display both the logo image and logo text.
|
||||
if (mImageComponents[LOGO]->hasImage())
|
||||
mTextComponents[LOGOTEXT]->setVisible(false);
|
||||
|
||||
// Remove old theme extras.
|
||||
for (auto extra : mThemeExtras) {
|
||||
removeChild(extra);
|
||||
delete extra;
|
||||
}
|
||||
mThemeExtras.clear();
|
||||
|
||||
// Add new theme extras.
|
||||
mThemeExtras = ThemeData::makeExtras(theme, getName());
|
||||
for (auto extra : mThemeExtras)
|
||||
addChild(extra);
|
||||
|
||||
mPrimary->setPosition(0.0f, mSize.y * 0.1f);
|
||||
mPrimary->setSize(mSize.x, mSize.y * 0.8f);
|
||||
mPrimary->setDefaultZIndex(50.0f);
|
||||
mPrimary->applyTheme(theme, getName(), "textlist_gamelist", ALL);
|
||||
addChild(mPrimary);
|
||||
|
||||
mImageComponents[LegacyImage::MD_THUMBNAIL]->applyTheme(
|
||||
theme, getName(), mImageComponents[LegacyImage::MD_THUMBNAIL]->getThemeMetadata(), ALL);
|
||||
mImageComponents[LegacyImage::MD_MARQUEE]->applyTheme(theme, getName(), "image_md_marquee",
|
||||
POSITION | ThemeFlags::SIZE | Z_INDEX |
|
||||
ROTATION | VISIBLE);
|
||||
|
||||
if (mViewStyle == ViewController::DETAILED) {
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->applyTheme(
|
||||
theme, getName(), mImageComponents[LegacyImage::MD_IMAGE]->getThemeMetadata(),
|
||||
POSITION | ThemeFlags::SIZE | Z_INDEX | ROTATION | VISIBLE);
|
||||
}
|
||||
else if (mViewStyle == ViewController::VIDEO) {
|
||||
mVideoComponents.front()->applyTheme(
|
||||
theme, getName(), mVideoComponents.front()->getThemeMetadata(),
|
||||
POSITION | ThemeFlags::SIZE | ThemeFlags::DELAY | Z_INDEX | ROTATION | VISIBLE);
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->setVisible(false);
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->applyTheme(
|
||||
theme, getName(), mImageComponents[LegacyImage::MD_IMAGE]->getThemeMetadata(),
|
||||
POSITION | ThemeFlags::SIZE | Z_INDEX | ROTATION | VISIBLE);
|
||||
}
|
||||
|
||||
legacyInitMDLabels();
|
||||
legacyInitMDValues();
|
||||
|
||||
mTextComponents[LegacyText::MD_NAME]->applyTheme(
|
||||
theme, getName(), mTextComponents[LegacyText::MD_NAME]->getThemeMetadata(), ALL);
|
||||
|
||||
for (size_t i = 0; i < mBadgeComponents.size(); ++i)
|
||||
mBadgeComponents[i]->applyTheme(theme, getName(), mBadgeComponents[i]->getThemeMetadata(),
|
||||
ALL);
|
||||
|
||||
for (size_t i = 0; i < mRatingComponents.size(); ++i)
|
||||
mRatingComponents[i]->applyTheme(theme, getName(), mRatingComponents[i]->getThemeMetadata(),
|
||||
ALL);
|
||||
|
||||
mDateTimeComponents[LegacyDateTime::MD_RELEASEDATE]->applyTheme(
|
||||
theme, getName(), mDateTimeComponents[LegacyDateTime::MD_RELEASEDATE]->getThemeMetadata(),
|
||||
ALL);
|
||||
|
||||
mDateTimeComponents[LegacyDateTime::MD_LASTPLAYED]->applyTheme(
|
||||
theme, getName(), mDateTimeComponents[LegacyDateTime::MD_LASTPLAYED]->getThemeMetadata(),
|
||||
ALL);
|
||||
|
||||
for (size_t i = LegacyText::MD_LBL_RATING; i < LegacyText::MD_NAME; ++i) {
|
||||
mTextComponents[i]->applyTheme(theme, getName(), mTextComponents[i]->getThemeMetadata(),
|
||||
ALL ^ ThemeFlags::TEXT);
|
||||
}
|
||||
|
||||
for (auto& container : mContainerComponents) {
|
||||
container->applyTheme(theme, getName(), container->getThemeMetadata(),
|
||||
POSITION | ThemeFlags::SIZE | Z_INDEX | VISIBLE);
|
||||
}
|
||||
|
||||
mTextComponents[LegacyText::MD_DESCRIPTION]->setSize(mContainerComponents.front()->getSize().x,
|
||||
0.0f);
|
||||
mTextComponents[LegacyText::MD_DESCRIPTION]->applyTheme(
|
||||
theme, getName(), "text_md_description",
|
||||
ALL ^ (POSITION | ThemeFlags::SIZE | ThemeFlags::ORIGIN | TEXT | ROTATION));
|
||||
|
||||
for (auto& gamelistInfo : mGamelistInfoComponents)
|
||||
gamelistInfo->applyTheme(theme, getName(), gamelistInfo->getThemeMetadata(),
|
||||
ALL ^ ThemeFlags::TEXT);
|
||||
|
||||
// If there is no position defined in the theme for gamelistInfo, then hide it.
|
||||
if (mGamelistInfoComponents.front()->getPosition() == glm::vec3 {})
|
||||
mGamelistInfoComponents.front()->setVisible(false);
|
||||
else
|
||||
mGamelistInfoComponents.front()->setVisible(true);
|
||||
|
||||
// Hide some components if we're in Basic mode.
|
||||
if (mViewStyle == ViewController::BASIC) {
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->setVisible(false);
|
||||
for (auto& container : mContainerComponents)
|
||||
container->setVisible(false);
|
||||
}
|
||||
|
||||
populateList(mRoot->getChildrenListToDisplay(), mRoot);
|
||||
sortChildren();
|
||||
mHelpStyle.applyTheme(mTheme, getName());
|
||||
}
|
||||
|
||||
void GamelistView::legacyUpdateView(const CursorState& state)
|
||||
{
|
||||
FileData* file {(mPrimary->size() > 0 && state == CursorState::CURSOR_STOPPED) ?
|
||||
mPrimary->getSelected() :
|
||||
nullptr};
|
||||
|
||||
// If the game data has already been rendered to the info panel, then skip it this time.
|
||||
if (file == mLastUpdated)
|
||||
return;
|
||||
|
||||
if (state == CursorState::CURSOR_STOPPED)
|
||||
mLastUpdated = file;
|
||||
|
||||
bool hideMetaDataFields {false};
|
||||
|
||||
if (file) {
|
||||
// Always hide the metadata fields if browsing grouped custom collections.
|
||||
if (file->getSystem()->isCustomCollection() &&
|
||||
file->getPath() == file->getSystem()->getName())
|
||||
hideMetaDataFields = true;
|
||||
else
|
||||
hideMetaDataFields = (file->metadata.get("hidemetadata") == "true");
|
||||
|
||||
// Always hide the metadata fields for placeholders as well.
|
||||
if (file->getType() == PLACEHOLDER) {
|
||||
hideMetaDataFields = true;
|
||||
mLastUpdated = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're scrolling, hide the metadata fields if the last game had this options set,
|
||||
// or if we're in the grouped custom collection view.
|
||||
if (mPrimary->isScrolling()) {
|
||||
if ((mLastUpdated && mLastUpdated->metadata.get("hidemetadata") == "true") ||
|
||||
(mLastUpdated->getSystem()->isCustomCollection() &&
|
||||
mLastUpdated->getPath() == mLastUpdated->getSystem()->getName()))
|
||||
hideMetaDataFields = true;
|
||||
}
|
||||
|
||||
if (hideMetaDataFields || mViewStyle == ViewController::BASIC) {
|
||||
for (size_t i = LegacyText::MD_LBL_RATING; i < LegacyText::MD_DESCRIPTION; ++i)
|
||||
mTextComponents[i]->setVisible(false);
|
||||
for (auto& date : mDateTimeComponents)
|
||||
date->setVisible(false);
|
||||
for (auto& badge : mBadgeComponents)
|
||||
badge->setVisible(false);
|
||||
for (auto& rating : mRatingComponents)
|
||||
rating->setVisible(false);
|
||||
}
|
||||
else {
|
||||
for (size_t i = LegacyText::MD_LBL_RATING; i < LegacyText::MD_DESCRIPTION; ++i)
|
||||
mTextComponents[i]->setVisible(true);
|
||||
for (auto& date : mDateTimeComponents)
|
||||
date->setVisible(true);
|
||||
for (auto& badge : mBadgeComponents)
|
||||
badge->setVisible(true);
|
||||
for (auto& rating : mRatingComponents)
|
||||
rating->setVisible(true);
|
||||
}
|
||||
|
||||
bool fadingOut {false};
|
||||
if (file == nullptr) {
|
||||
if (mViewStyle == ViewController::VIDEO) {
|
||||
mVideoComponents.front()->stopVideoPlayer();
|
||||
mVideoComponents.front()->setVideo("");
|
||||
if (!mVideoComponents.front()->hasStartDelay())
|
||||
mVideoComponents.front()->setImage("");
|
||||
}
|
||||
mVideoPlaying = false;
|
||||
fadingOut = true;
|
||||
}
|
||||
else {
|
||||
// If we're browsing a grouped custom collection, then update the folder metadata
|
||||
// which will generate a description of three random games and return a pointer to
|
||||
// the first of these so that we can display its game media.
|
||||
if (file->getSystem()->isCustomCollection() &&
|
||||
file->getPath() == file->getSystem()->getName()) {
|
||||
mRandomGame = CollectionSystemsManager::getInstance()->updateCollectionFolderMetadata(
|
||||
file->getSystem());
|
||||
if (mRandomGame) {
|
||||
mImageComponents[LegacyImage::MD_THUMBNAIL]->setImage(mRandomGame->getImagePath());
|
||||
mImageComponents[LegacyImage::MD_MARQUEE]->setImage(mRandomGame->getMarqueePath());
|
||||
if (mViewStyle == ViewController::VIDEO) {
|
||||
mVideoComponents.front()->setImage(mRandomGame->getImagePath());
|
||||
mVideoComponents.front()->stopVideoPlayer();
|
||||
|
||||
if (!mVideoComponents.front()->setVideo(mRandomGame->getVideoPath()))
|
||||
mVideoComponents.front()->setDefaultVideo();
|
||||
|
||||
mVideoComponents.front()->startVideoPlayer();
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->setImage(mRandomGame->getImagePath());
|
||||
}
|
||||
else {
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->setImage(mRandomGame->getImagePath());
|
||||
}
|
||||
}
|
||||
else {
|
||||
mImageComponents[LegacyImage::MD_THUMBNAIL]->setImage("");
|
||||
mImageComponents[LegacyImage::MD_MARQUEE]->setImage("");
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->setImage("");
|
||||
if (mViewStyle == ViewController::VIDEO) {
|
||||
mVideoComponents.front()->setImage("");
|
||||
mVideoComponents.front()->setVideo("");
|
||||
mVideoComponents.front()->setDefaultVideo();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
mImageComponents[LegacyImage::MD_THUMBNAIL]->setImage(file->getImagePath());
|
||||
mImageComponents[LegacyImage::MD_MARQUEE]->setImage(file->getMarqueePath());
|
||||
if (mViewStyle == ViewController::VIDEO) {
|
||||
mVideoComponents.front()->setImage(file->getImagePath());
|
||||
mVideoComponents.front()->stopVideoPlayer();
|
||||
|
||||
if (!mVideoComponents.front()->setVideo(file->getVideoPath()))
|
||||
mVideoComponents.front()->setDefaultVideo();
|
||||
|
||||
mVideoComponents.front()->startVideoPlayer();
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->setImage(file->getImagePath());
|
||||
}
|
||||
else {
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->setImage(file->getImagePath());
|
||||
}
|
||||
}
|
||||
|
||||
mVideoPlaying = true;
|
||||
|
||||
// Populate the gamelistInfo field which shows an icon if a folder has been entered
|
||||
// as well as the game count for the entire system (total and favorites separately).
|
||||
// If a filter has been applied, then the number of filtered and total games replaces
|
||||
// the game counter.
|
||||
for (auto& gamelistInfo : mGamelistInfoComponents) {
|
||||
std::string gamelistInfoString;
|
||||
Alignment infoAlign {gamelistInfo->getHorizontalAlignment()};
|
||||
|
||||
if (mIsFolder && infoAlign == ALIGN_RIGHT)
|
||||
gamelistInfoString = ViewController::FOLDER_CHAR + " ";
|
||||
|
||||
if (mIsFiltered) {
|
||||
if (mFilteredGameCountAll == mFilteredGameCount)
|
||||
gamelistInfoString.append(ViewController::FILTER_CHAR)
|
||||
.append(" ")
|
||||
.append(std::to_string(mFilteredGameCount))
|
||||
.append(" / ")
|
||||
.append(std::to_string(mGameCount));
|
||||
else
|
||||
gamelistInfoString.append(ViewController::FILTER_CHAR)
|
||||
.append(" ")
|
||||
.append(std::to_string(mFilteredGameCount))
|
||||
.append(" + ")
|
||||
.append(std::to_string(mFilteredGameCountAll - mFilteredGameCount))
|
||||
.append(" / ")
|
||||
.append(std::to_string(mGameCount));
|
||||
}
|
||||
else {
|
||||
gamelistInfoString.append(ViewController::CONTROLLER_CHAR)
|
||||
.append(" ")
|
||||
.append(std::to_string(mGameCount));
|
||||
if (!(file->getSystem()->isCollection() &&
|
||||
file->getSystem()->getFullName() == "favorites"))
|
||||
gamelistInfoString.append(" ")
|
||||
.append(ViewController::FAVORITE_CHAR)
|
||||
.append(" ")
|
||||
.append(std::to_string(mFavoritesGameCount));
|
||||
}
|
||||
|
||||
if (mIsFolder && infoAlign != ALIGN_RIGHT)
|
||||
gamelistInfoString.append(" ").append(ViewController::FOLDER_CHAR);
|
||||
|
||||
gamelistInfo->setValue(gamelistInfoString);
|
||||
}
|
||||
|
||||
if (mViewStyle == ViewController::DETAILED) {
|
||||
// Fade in the game image.
|
||||
auto funcImage = [this](float t) {
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->setOpacity(
|
||||
glm::mix(FADE_IN_START_OPACITY, 1.0f, t));
|
||||
};
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->setAnimation(
|
||||
new LambdaAnimation(funcImage, FADE_IN_TIME), 0, nullptr, false);
|
||||
|
||||
// Fade in the thumbnail.
|
||||
auto funcThumbnail = [this](float t) {
|
||||
mImageComponents[LegacyImage::MD_THUMBNAIL]->setOpacity(
|
||||
glm::mix(FADE_IN_START_OPACITY, 1.0f, t));
|
||||
};
|
||||
mImageComponents[LegacyImage::MD_THUMBNAIL]->setAnimation(
|
||||
new LambdaAnimation(funcThumbnail, FADE_IN_TIME), 0, nullptr, false);
|
||||
}
|
||||
else if (mViewStyle == ViewController::VIDEO) {
|
||||
// Fade in the static image.
|
||||
auto funcVideo = [this](float t) {
|
||||
mVideoComponents.front()->setOpacity(glm::mix(FADE_IN_START_OPACITY, 1.0f, t));
|
||||
};
|
||||
mVideoComponents.front()->setAnimation(new LambdaAnimation(funcVideo, FADE_IN_TIME), 0,
|
||||
nullptr, false);
|
||||
// Fade in the game image.
|
||||
auto funcImage = [this](float t) {
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->setOpacity(
|
||||
glm::mix(FADE_IN_START_OPACITY, 1.0f, t));
|
||||
};
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->setAnimation(
|
||||
new LambdaAnimation(funcImage, FADE_IN_TIME), 0, nullptr, false);
|
||||
}
|
||||
|
||||
mTextComponents[LegacyText::MD_DESCRIPTION]->setText(file->metadata.get("desc"));
|
||||
for (auto& container : mContainerComponents)
|
||||
container->reset();
|
||||
|
||||
for (auto& rating : mRatingComponents)
|
||||
rating->setValue(file->metadata.get("rating"));
|
||||
|
||||
mDateTimeComponents[LegacyDateTime::MD_RELEASEDATE]->setValue(
|
||||
file->metadata.get("releasedate"));
|
||||
mTextComponents[LegacyText::MD_DEVELOPER]->setValue(file->metadata.get("developer"));
|
||||
mTextComponents[LegacyText::MD_PUBLISHER]->setValue(file->metadata.get("publisher"));
|
||||
mTextComponents[LegacyText::MD_GENRE]->setValue(file->metadata.get("genre"));
|
||||
mTextComponents[LegacyText::MD_PLAYERS]->setValue(file->metadata.get("players"));
|
||||
|
||||
// Populate the badge slots based on game metadata.
|
||||
std::vector<BadgeComponent::BadgeInfo> badgeSlots;
|
||||
for (auto& badgeComponent : mBadgeComponents) {
|
||||
for (auto& badge : badgeComponent->getBadgeTypes()) {
|
||||
BadgeComponent::BadgeInfo badgeInfo;
|
||||
badgeInfo.badgeType = badge;
|
||||
if (badge == "collection" && CollectionSystemsManager::getInstance()->isEditing()) {
|
||||
if (CollectionSystemsManager::getInstance()->inCustomCollection(
|
||||
CollectionSystemsManager::getInstance()->getEditingCollection(),
|
||||
file)) {
|
||||
badgeSlots.emplace_back(badgeInfo);
|
||||
}
|
||||
}
|
||||
else if (badge == "folder") {
|
||||
if (file->getType() == FOLDER) {
|
||||
if (file->metadata.get("folderlink") != "")
|
||||
badgeInfo.folderLink = true;
|
||||
badgeSlots.emplace_back(badgeInfo);
|
||||
}
|
||||
}
|
||||
else if (badge == "controller") {
|
||||
if (file->metadata.get("controller") != "") {
|
||||
badgeInfo.gameController = file->metadata.get("controller");
|
||||
badgeSlots.emplace_back(badgeInfo);
|
||||
}
|
||||
}
|
||||
else if (badge == "altemulator") {
|
||||
if (file->metadata.get(badge) != "")
|
||||
badgeSlots.emplace_back(badgeInfo);
|
||||
}
|
||||
else {
|
||||
if (file->metadata.get(badge) == "true")
|
||||
badgeSlots.emplace_back(badgeInfo);
|
||||
}
|
||||
}
|
||||
badgeComponent->setBadges(badgeSlots);
|
||||
}
|
||||
|
||||
mTextComponents[LegacyText::MD_NAME]->setValue(file->metadata.get("name"));
|
||||
|
||||
if (file->getType() == GAME) {
|
||||
if (!hideMetaDataFields) {
|
||||
mDateTimeComponents[LegacyDateTime::MD_LASTPLAYED]->setValue(
|
||||
file->metadata.get("lastplayed"));
|
||||
mTextComponents[LegacyText::MD_PLAYCOUNT]->setValue(
|
||||
file->metadata.get("playcount"));
|
||||
}
|
||||
}
|
||||
else if (file->getType() == FOLDER) {
|
||||
if (!hideMetaDataFields) {
|
||||
mDateTimeComponents[LegacyDateTime::MD_LASTPLAYED]->setValue(
|
||||
file->metadata.get("lastplayed"));
|
||||
mTextComponents[LegacyText::MD_LBL_PLAYCOUNT]->setVisible(false);
|
||||
mTextComponents[LegacyText::MD_PLAYCOUNT]->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
fadingOut = false;
|
||||
}
|
||||
|
||||
std::vector<GuiComponent*> comps;
|
||||
|
||||
for (size_t i = LegacyText::MD_LBL_RATING; i < LegacyText::END; ++i)
|
||||
comps.emplace_back(mTextComponents[i].get());
|
||||
comps.emplace_back(mDateTimeComponents[LegacyDateTime::MD_RELEASEDATE].get());
|
||||
comps.emplace_back(mDateTimeComponents[LegacyDateTime::MD_LASTPLAYED].get());
|
||||
comps.emplace_back(mTextComponents[LegacyText::MD_NAME].get());
|
||||
comps.emplace_back(mImageComponents[LegacyImage::MD_THUMBNAIL].get());
|
||||
comps.emplace_back(mImageComponents[LegacyImage::MD_MARQUEE].get());
|
||||
comps.emplace_back(mImageComponents[LegacyImage::MD_IMAGE].get());
|
||||
if (mVideoComponents.size() > 0)
|
||||
comps.emplace_back(mVideoComponents.front().get());
|
||||
comps.push_back(mBadgeComponents.front().get());
|
||||
comps.push_back(mRatingComponents.front().get());
|
||||
|
||||
for (auto it = comps.cbegin(); it != comps.cend(); ++it) {
|
||||
GuiComponent* comp {*it};
|
||||
if ((comp->isAnimationPlaying(0) && comp->isAnimationReversed(0) != fadingOut) ||
|
||||
(!comp->isAnimationPlaying(0) &&
|
||||
comp->getOpacity() != (fadingOut ? 0.0f : comp->getColorOpacity()))) {
|
||||
auto func = [comp](float t) { comp->setOpacity(glm::mix(0.0f, 1.0f, t)); };
|
||||
comp->setAnimation(new LambdaAnimation(func, 150), 0, nullptr, fadingOut);
|
||||
}
|
||||
}
|
||||
|
||||
if (state == CursorState::CURSOR_SCROLLING)
|
||||
mLastUpdated = nullptr;
|
||||
}
|
||||
|
||||
void GamelistView::legacyUpdate(int deltaTime)
|
||||
{
|
||||
if (ViewController::getInstance()->getGameLaunchTriggered() &&
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->isAnimationPlaying(0))
|
||||
mImageComponents[LegacyImage::MD_IMAGE]->finishAnimation(0);
|
||||
|
||||
if (mViewStyle == ViewController::VIDEO) {
|
||||
if (ViewController::getInstance()->getGameLaunchTriggered() &&
|
||||
mVideoComponents.front()->isAnimationPlaying(0))
|
||||
mVideoComponents.front()->finishAnimation(0);
|
||||
}
|
||||
|
||||
updateChildren(deltaTime);
|
||||
}
|
||||
|
||||
void GamelistView::legacyInitMDLabels()
|
||||
{
|
||||
std::vector<TextComponent*> components;
|
||||
|
||||
for (size_t i = LegacyText::MD_LBL_RATING; i < LegacyText::MD_DEVELOPER; ++i)
|
||||
components.emplace_back(&*mTextComponents[i]);
|
||||
|
||||
const unsigned int colCount {2};
|
||||
const unsigned int rowCount {static_cast<unsigned int>(components.size() / 2)};
|
||||
|
||||
glm::vec3 start {mSize.x * 0.01f, mSize.y * 0.625f, 0.0f};
|
||||
|
||||
const float colSize {(mSize.x * 0.48f) / colCount};
|
||||
const float rowPadding {0.01f * mSize.y};
|
||||
|
||||
for (unsigned int i = 0; i < components.size(); ++i) {
|
||||
const unsigned int row {i % rowCount};
|
||||
glm::vec3 pos {0.0f, 0.0f, 0.0f};
|
||||
if (row == 0) {
|
||||
pos = start + glm::vec3 {colSize * (i / rowCount), 0.0f, 0.0f};
|
||||
}
|
||||
else {
|
||||
// Work from the last component.
|
||||
GuiComponent* lc {components[i - 1]};
|
||||
pos = lc->getPosition() + glm::vec3 {0.0f, lc->getSize().y + rowPadding, 0.0f};
|
||||
}
|
||||
|
||||
components[i]->setFont(Font::get(FONT_SIZE_SMALL));
|
||||
components[i]->setPosition(pos);
|
||||
components[i]->setDefaultZIndex(40.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void GamelistView::legacyInitMDValues()
|
||||
{
|
||||
std::vector<TextComponent*> labels;
|
||||
std::vector<GuiComponent*> values;
|
||||
|
||||
std::shared_ptr<Font> defaultFont {Font::get(FONT_SIZE_SMALL)};
|
||||
|
||||
for (size_t i = LegacyText::MD_LBL_RATING; i < LegacyText::MD_DEVELOPER; ++i) {
|
||||
labels.emplace_back(&*mTextComponents[i]);
|
||||
mTextComponents[i]->setFont(defaultFont);
|
||||
}
|
||||
|
||||
for (size_t i = LegacyText::MD_DEVELOPER; i < LegacyText::MD_DESCRIPTION; ++i)
|
||||
mTextComponents[i]->setFont(defaultFont);
|
||||
|
||||
mDateTimeComponents[LegacyDateTime::MD_RELEASEDATE]->setFont(defaultFont);
|
||||
mDateTimeComponents[LegacyDateTime::MD_LASTPLAYED]->setFont(defaultFont);
|
||||
|
||||
values.emplace_back(mRatingComponents.front().get());
|
||||
values.emplace_back(mDateTimeComponents[LegacyDateTime::MD_RELEASEDATE].get());
|
||||
values.emplace_back(mTextComponents[LegacyText::MD_DEVELOPER].get());
|
||||
values.emplace_back(mTextComponents[LegacyText::MD_PUBLISHER].get());
|
||||
values.emplace_back(mTextComponents[LegacyText::MD_GENRE].get());
|
||||
values.emplace_back(mTextComponents[LegacyText::MD_PLAYERS].get());
|
||||
values.emplace_back(mDateTimeComponents[LegacyDateTime::MD_LASTPLAYED].get());
|
||||
values.emplace_back(mTextComponents[LegacyText::MD_PLAYCOUNT].get());
|
||||
|
||||
float bottom {0.0f};
|
||||
const float colSize {(mSize.x * 0.48f) / 2.0f};
|
||||
for (unsigned int i = 0; i < labels.size(); ++i) {
|
||||
const float heightDiff {(labels[i]->getSize().y - values[i]->getSize().y) / 2.0f};
|
||||
values[i]->setPosition(mSize.x + glm::vec3 {labels[i]->getSize().x, heightDiff, 0.0f});
|
||||
values[i]->setSize(colSize - labels[i]->getSize().x, values[i]->getSize().y);
|
||||
values[i]->setDefaultZIndex(40.0f);
|
||||
|
||||
float testBot {values[i]->getPosition().y + values[i]->getSize().y};
|
||||
|
||||
if (testBot > bottom)
|
||||
bottom = testBot;
|
||||
}
|
||||
|
||||
// Default to off the screen for the following components.
|
||||
mRatingComponents.front()->setPosition(Renderer::getScreenWidth() * 2.0f,
|
||||
Renderer::getScreenHeight() * 2.0f);
|
||||
|
||||
mContainerComponents.front()->setPosition(Renderer::getScreenWidth() * 2.0f,
|
||||
Renderer::getScreenHeight() * 2.0f);
|
||||
|
||||
for (auto& container : mContainerComponents) {
|
||||
container->setPosition(container->getPosition().x, bottom + mSize.y * 0.01f);
|
||||
container->setSize(mSize.x * 0.2f, mSize.y * 0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ES_APP_VIEWS_GAMELIST_LEGACY_H
|
|
@ -7,7 +7,6 @@
|
|||
//
|
||||
|
||||
#include "views/GamelistView.h"
|
||||
#include "views/GamelistLegacy.h"
|
||||
|
||||
#include "CollectionSystemsManager.h"
|
||||
#include "UIModeController.h"
|
||||
|
@ -19,11 +18,8 @@
|
|||
GamelistView::GamelistView(FileData* root)
|
||||
: GamelistBase {root}
|
||||
, mRenderer {Renderer::getInstance()}
|
||||
, mViewStyle {ViewController::BASIC}
|
||||
, mLegacyMode {false}
|
||||
, mStaticVideoAudio {false}
|
||||
{
|
||||
mViewStyle = ViewController::getInstance()->getState().viewstyle;
|
||||
}
|
||||
|
||||
GamelistView::~GamelistView()
|
||||
|
@ -38,9 +34,6 @@ GamelistView::~GamelistView()
|
|||
|
||||
const std::pair<bool, LetterCase> GamelistView::getDescriptionSystemNameSuffix() const
|
||||
{
|
||||
if (mLegacyMode)
|
||||
return std::make_pair(true, LetterCase::UPPERCASE);
|
||||
|
||||
bool suffix {false};
|
||||
LetterCase letterCase {LetterCase::UPPERCASE};
|
||||
|
||||
|
@ -97,11 +90,7 @@ void GamelistView::onShow()
|
|||
mLastUpdated = nullptr;
|
||||
GuiComponent::onShow();
|
||||
|
||||
if (mLegacyMode)
|
||||
legacyUpdateView(CursorState::CURSOR_STOPPED);
|
||||
else
|
||||
updateView(CursorState::CURSOR_STOPPED);
|
||||
|
||||
updateView(CursorState::CURSOR_STOPPED);
|
||||
mPrimary->finishAnimation(0);
|
||||
}
|
||||
|
||||
|
@ -123,12 +112,6 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
|
|||
selectedSet {themeSets.find(Settings::getInstance()->getString("ThemeSet"))};
|
||||
|
||||
assert(selectedSet != themeSets.cend());
|
||||
mLegacyMode = selectedSet->second.capabilities.legacyTheme;
|
||||
|
||||
if (mLegacyMode) {
|
||||
legacyOnThemeChanged(theme);
|
||||
return;
|
||||
}
|
||||
|
||||
mStaticVideoAudio = false;
|
||||
const bool isStartupSystem {Settings::getInstance()->getString("StartupSystem") ==
|
||||
|
@ -391,11 +374,6 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
|
|||
|
||||
void GamelistView::update(int deltaTime)
|
||||
{
|
||||
if (mLegacyMode) {
|
||||
legacyUpdate(deltaTime);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ViewController::getInstance()->getGameLaunchTriggered()) {
|
||||
for (auto& image : mImageComponents) {
|
||||
if (image->isAnimationPlaying(0))
|
||||
|
@ -463,9 +441,7 @@ std::vector<HelpPrompt> GamelistView::getHelpPrompts()
|
|||
if (mRoot->getSystem()->getThemeFolder() == "custom-collections" &&
|
||||
!CollectionSystemsManager::getInstance()->isEditing() && mCursorStack.empty() &&
|
||||
ViewController::getInstance()->getState().viewing == ViewController::GAMELIST) {
|
||||
if (!(mLegacyMode &&
|
||||
ViewController::getInstance()->getState().viewstyle == ViewController::BASIC))
|
||||
prompts.push_back(HelpPrompt("y", "jump to game"));
|
||||
prompts.push_back(HelpPrompt("y", "jump to game"));
|
||||
}
|
||||
else if (mRoot->getSystem()->isGameSystem() &&
|
||||
(mRoot->getSystem()->getThemeFolder() != "custom-collections" ||
|
||||
|
@ -492,11 +468,6 @@ std::vector<HelpPrompt> GamelistView::getHelpPrompts()
|
|||
|
||||
void GamelistView::updateView(const CursorState& state)
|
||||
{
|
||||
if (mLegacyMode) {
|
||||
legacyUpdateView(state);
|
||||
return;
|
||||
}
|
||||
|
||||
bool loadedTexture {false};
|
||||
|
||||
if (mPrimary->isScrolling()) {
|
||||
|
|
|
@ -28,20 +28,6 @@ public:
|
|||
void preloadGamelist() { updateView(CursorState::CURSOR_STOPPED); }
|
||||
void launch(FileData* game) override { ViewController::getInstance()->triggerGameLaunch(game); }
|
||||
|
||||
std::string getName() const
|
||||
{
|
||||
auto selectedViewStyle = ViewController::getInstance()->getState();
|
||||
switch (selectedViewStyle.viewstyle) {
|
||||
case ViewController::VIDEO:
|
||||
return "video";
|
||||
case ViewController::DETAILED:
|
||||
return "detailed";
|
||||
case ViewController::BASIC:
|
||||
default:
|
||||
return "basic";
|
||||
}
|
||||
}
|
||||
|
||||
void startViewVideos() override
|
||||
{
|
||||
for (auto& video : mVideoComponents)
|
||||
|
@ -117,18 +103,8 @@ private:
|
|||
void updateView(const CursorState& state);
|
||||
void setGameImage(FileData* file, GuiComponent* comp);
|
||||
|
||||
// Legacy (backward compatibility) functions.
|
||||
void legacyPopulateFields();
|
||||
void legacyOnThemeChanged(const std::shared_ptr<ThemeData>& theme);
|
||||
void legacyUpdateView(const CursorState& state);
|
||||
void legacyUpdate(int deltaTime);
|
||||
void legacyInitMDLabels();
|
||||
void legacyInitMDValues();
|
||||
|
||||
Renderer* mRenderer;
|
||||
HelpStyle mHelpStyle;
|
||||
ViewController::GamelistViewStyle mViewStyle;
|
||||
bool mLegacyMode;
|
||||
bool mStaticVideoAudio;
|
||||
|
||||
std::shared_ptr<ThemeData> mTheme;
|
||||
|
@ -146,39 +122,6 @@ private:
|
|||
std::vector<std::unique_ptr<ScrollableContainer>> mContainerComponents;
|
||||
std::vector<std::unique_ptr<TextComponent>> mContainerTextComponents;
|
||||
std::vector<std::unique_ptr<TextComponent>> mGamelistInfoComponents;
|
||||
|
||||
enum LegacyText {
|
||||
LOGOTEXT = 0,
|
||||
MD_LBL_RATING = 1,
|
||||
MD_LBL_RELEASEDATE = 2,
|
||||
MD_LBL_DEVELOPER = 3,
|
||||
MD_LBL_PUBLISHER = 4,
|
||||
MD_LBL_GENRE = 5,
|
||||
MD_LBL_PLAYERS = 6,
|
||||
MD_LBL_LASTPLAYED = 7,
|
||||
MD_LBL_PLAYCOUNT = 8,
|
||||
MD_DEVELOPER = 9,
|
||||
MD_PUBLISHER = 10,
|
||||
MD_GENRE = 11,
|
||||
MD_PLAYERS = 12,
|
||||
MD_PLAYCOUNT = 13,
|
||||
MD_NAME = 14,
|
||||
MD_DESCRIPTION = 15,
|
||||
END
|
||||
};
|
||||
|
||||
enum LegacyDateTime {
|
||||
MD_RELEASEDATE = 0, //
|
||||
MD_LASTPLAYED = 1
|
||||
};
|
||||
|
||||
enum LegacyImage {
|
||||
LOGO = 0, //
|
||||
BACKGROUND = 1,
|
||||
MD_THUMBNAIL = 2,
|
||||
MD_MARQUEE = 3,
|
||||
MD_IMAGE = 4
|
||||
};
|
||||
};
|
||||
|
||||
#endif // ES_APP_VIEWS_GAMELIST_VIEW_H
|
||||
|
|
|
@ -31,7 +31,6 @@ SystemView::SystemView()
|
|||
, mPreviousScrollVelocity {0}
|
||||
, mUpdatedGameCount {false}
|
||||
, mViewNeedsReload {true}
|
||||
, mLegacyMode {false}
|
||||
, mNavigated {false}
|
||||
, mMaxFade {false}
|
||||
, mFadeTransitions {false}
|
||||
|
@ -41,18 +40,6 @@ SystemView::SystemView()
|
|||
populate();
|
||||
}
|
||||
|
||||
SystemView::~SystemView()
|
||||
{
|
||||
if (mLegacyMode) {
|
||||
// Delete any existing extras.
|
||||
for (auto& entry : mSystemElements) {
|
||||
for (auto extra : entry.legacyExtras)
|
||||
delete extra;
|
||||
entry.legacyExtras.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SystemView::onShow()
|
||||
{
|
||||
finishAnimation(0);
|
||||
|
@ -465,12 +452,6 @@ void SystemView::populate()
|
|||
selectedSet {themeSets.find(Settings::getInstance()->getString("ThemeSet"))};
|
||||
|
||||
assert(selectedSet != themeSets.cend());
|
||||
mLegacyMode = selectedSet->second.capabilities.legacyTheme;
|
||||
|
||||
if (mLegacyMode) {
|
||||
mLegacySystemInfo = std::make_unique<TextComponent>(
|
||||
"SYSTEM INFO", Font::get(FONT_SIZE_SMALL), 0x33333300, ALIGN_CENTER);
|
||||
}
|
||||
|
||||
for (auto it : SystemData::sSystemVector) {
|
||||
const std::shared_ptr<ThemeData>& theme {it->getTheme()};
|
||||
|
@ -478,294 +459,235 @@ void SystemView::populate()
|
|||
std::string defaultImagePath;
|
||||
std::string itemText;
|
||||
|
||||
if (mLegacyMode && mViewNeedsReload) {
|
||||
if (mCarousel == nullptr) {
|
||||
mCarousel = std::make_unique<CarouselComponent<SystemData*>>();
|
||||
mPrimary = mCarousel.get();
|
||||
// For legacy themes the carousel has a zIndex value of 40 instead of 50.
|
||||
mPrimary->setDefaultZIndex(40.0f);
|
||||
mPrimary->setCursorChangedCallback(
|
||||
[&](const CursorState& state) { onCursorChanged(state); });
|
||||
mPrimary->setCancelTransitionsCallback([&] {
|
||||
ViewController::getInstance()->cancelViewTransitions();
|
||||
mNavigated = true;
|
||||
if (mSystemElements.size() > 1) {
|
||||
for (auto& anim :
|
||||
mSystemElements[mPrimary->getCursor()].lottieAnimComponents)
|
||||
anim->setPauseAnimation(true);
|
||||
for (auto& anim : mSystemElements[mPrimary->getCursor()].GIFAnimComponents)
|
||||
anim->setPauseAnimation(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
legacyApplyTheme(theme);
|
||||
}
|
||||
|
||||
if (mLegacyMode) {
|
||||
SystemViewElements elements;
|
||||
elements.system = it;
|
||||
SystemViewElements elements;
|
||||
elements.system = it;
|
||||
if (theme->hasView("system")) {
|
||||
elements.name = it->getName();
|
||||
elements.legacyExtras = ThemeData::makeExtras(theme, "system");
|
||||
|
||||
// Sort the extras by z-index.
|
||||
std::stable_sort(
|
||||
elements.legacyExtras.begin(), elements.legacyExtras.end(),
|
||||
[](GuiComponent* a, GuiComponent* b) { return b->getZIndex() > a->getZIndex(); });
|
||||
|
||||
mSystemElements.emplace_back(std::move(elements));
|
||||
mSystemElements.back().helpStyle.applyTheme(theme, "system");
|
||||
}
|
||||
|
||||
if (!mLegacyMode) {
|
||||
SystemViewElements elements;
|
||||
elements.system = it;
|
||||
if (theme->hasView("system")) {
|
||||
elements.name = it->getName();
|
||||
elements.fullName = it->getFullName();
|
||||
for (auto& element : theme->getViewElements("system").elements) {
|
||||
if (element.second.type == "gameselector") {
|
||||
elements.gameSelectors.emplace_back(
|
||||
std::make_unique<GameSelectorComponent>(it));
|
||||
elements.gameSelectors.back()->applyTheme(theme, "system", element.first,
|
||||
ThemeFlags::ALL);
|
||||
elements.gameSelectors.back()->setNeedsRefresh();
|
||||
elements.fullName = it->getFullName();
|
||||
for (auto& element : theme->getViewElements("system").elements) {
|
||||
if (element.second.type == "gameselector") {
|
||||
elements.gameSelectors.emplace_back(
|
||||
std::make_unique<GameSelectorComponent>(it));
|
||||
elements.gameSelectors.back()->applyTheme(theme, "system", element.first,
|
||||
ThemeFlags::ALL);
|
||||
elements.gameSelectors.back()->setNeedsRefresh();
|
||||
}
|
||||
if (element.second.type == "carousel" || element.second.type == "grid" ||
|
||||
element.second.type == "textlist") {
|
||||
if (element.second.type == "carousel" &&
|
||||
(mGrid != nullptr || mTextList != nullptr)) {
|
||||
LOG(LogWarning) << "SystemView::populate(): Multiple primary components "
|
||||
<< "defined, skipping carousel configuration entry";
|
||||
continue;
|
||||
}
|
||||
if (element.second.type == "carousel" || element.second.type == "grid" ||
|
||||
element.second.type == "textlist") {
|
||||
if (element.second.type == "carousel" &&
|
||||
(mGrid != nullptr || mTextList != nullptr)) {
|
||||
LOG(LogWarning)
|
||||
<< "SystemView::populate(): Multiple primary components "
|
||||
<< "defined, skipping carousel configuration entry";
|
||||
continue;
|
||||
}
|
||||
if (element.second.type == "grid" &&
|
||||
(mCarousel != nullptr || mTextList != nullptr)) {
|
||||
LOG(LogWarning)
|
||||
<< "SystemView::populate(): Multiple primary components "
|
||||
<< "defined, skipping grid configuration entry";
|
||||
continue;
|
||||
}
|
||||
if (element.second.type == "textlist" &&
|
||||
(mCarousel != nullptr || mGrid != nullptr)) {
|
||||
LOG(LogWarning)
|
||||
<< "SystemView::populate(): Multiple primary components "
|
||||
<< "defined, skipping textlist configuration entry";
|
||||
continue;
|
||||
}
|
||||
if (element.second.type == "carousel" && mCarousel == nullptr) {
|
||||
mCarousel = std::make_unique<CarouselComponent<SystemData*>>();
|
||||
mPrimary = mCarousel.get();
|
||||
mPrimaryType = PrimaryType::CAROUSEL;
|
||||
}
|
||||
else if (element.second.type == "grid" && mGrid == nullptr) {
|
||||
mGrid = std::make_unique<GridComponent<SystemData*>>();
|
||||
mPrimary = mGrid.get();
|
||||
mPrimaryType = PrimaryType::GRID;
|
||||
}
|
||||
else if (element.second.type == "textlist" && mTextList == nullptr) {
|
||||
mTextList = std::make_unique<TextListComponent<SystemData*>>();
|
||||
mPrimary = mTextList.get();
|
||||
mPrimaryType = PrimaryType::TEXTLIST;
|
||||
}
|
||||
mPrimary->setDefaultZIndex(50.0f);
|
||||
mPrimary->applyTheme(theme, "system", element.first, ThemeFlags::ALL);
|
||||
mPrimary->setCursorChangedCallback(
|
||||
[&](const CursorState& state) { onCursorChanged(state); });
|
||||
mPrimary->setCancelTransitionsCallback([&] {
|
||||
ViewController::getInstance()->cancelViewTransitions();
|
||||
mNavigated = true;
|
||||
if (mSystemElements.size() > 1) {
|
||||
for (auto& anim :
|
||||
mSystemElements[mPrimary->getCursor()].lottieAnimComponents)
|
||||
anim->setPauseAnimation(true);
|
||||
for (auto& anim :
|
||||
mSystemElements[mPrimary->getCursor()].GIFAnimComponents)
|
||||
anim->setPauseAnimation(true);
|
||||
}
|
||||
});
|
||||
if (mCarousel != nullptr || mGrid != nullptr) {
|
||||
if (element.second.has("staticImage"))
|
||||
imagePath = element.second.get<std::string>("staticImage");
|
||||
if (element.second.has("defaultImage"))
|
||||
defaultImagePath = element.second.get<std::string>("defaultImage");
|
||||
if (element.second.has("text"))
|
||||
itemText = element.second.get<std::string>("text");
|
||||
}
|
||||
if (element.second.type == "grid" &&
|
||||
(mCarousel != nullptr || mTextList != nullptr)) {
|
||||
LOG(LogWarning) << "SystemView::populate(): Multiple primary components "
|
||||
<< "defined, skipping grid configuration entry";
|
||||
continue;
|
||||
}
|
||||
else if (element.second.type == "image" &&
|
||||
!(element.second.has("visible") &&
|
||||
!element.second.get<bool>("visible"))) {
|
||||
// If this is the first system then forceload to avoid texture pop-in.
|
||||
if (it == SystemData::sSystemVector.front())
|
||||
elements.imageComponents.emplace_back(
|
||||
std::make_unique<ImageComponent>(true));
|
||||
else
|
||||
elements.imageComponents.emplace_back(
|
||||
std::make_unique<ImageComponent>());
|
||||
|
||||
elements.imageComponents.back()->setDefaultZIndex(30.0f);
|
||||
elements.imageComponents.back()->applyTheme(theme, "system", element.first,
|
||||
ThemeFlags::ALL);
|
||||
elements.children.emplace_back(elements.imageComponents.back().get());
|
||||
if (element.second.type == "textlist" &&
|
||||
(mCarousel != nullptr || mGrid != nullptr)) {
|
||||
LOG(LogWarning) << "SystemView::populate(): Multiple primary components "
|
||||
<< "defined, skipping textlist configuration entry";
|
||||
continue;
|
||||
}
|
||||
else if (element.second.type == "video" &&
|
||||
!(element.second.has("visible") &&
|
||||
!element.second.get<bool>("visible"))) {
|
||||
elements.videoComponents.emplace_back(
|
||||
std::make_unique<VideoFFmpegComponent>());
|
||||
elements.videoComponents.back()->setDefaultZIndex(30.0f);
|
||||
elements.videoComponents.back()->setStaticVideo();
|
||||
elements.videoComponents.back()->applyTheme(theme, "system", element.first,
|
||||
ThemeFlags::ALL);
|
||||
elements.children.emplace_back(elements.videoComponents.back().get());
|
||||
if (element.second.type == "carousel" && mCarousel == nullptr) {
|
||||
mCarousel = std::make_unique<CarouselComponent<SystemData*>>();
|
||||
mPrimary = mCarousel.get();
|
||||
mPrimaryType = PrimaryType::CAROUSEL;
|
||||
}
|
||||
else if (element.second.type == "animation" && element.second.has("path") &&
|
||||
!(element.second.has("visible") &&
|
||||
!element.second.get<bool>("visible"))) {
|
||||
const std::string extension {Utils::FileSystem::getExtension(
|
||||
element.second.get<std::string>("path"))};
|
||||
if (extension == ".json") {
|
||||
elements.lottieAnimComponents.emplace_back(
|
||||
std::make_unique<LottieAnimComponent>());
|
||||
elements.lottieAnimComponents.back()->setDefaultZIndex(35.0f);
|
||||
elements.lottieAnimComponents.back()->applyTheme(
|
||||
theme, "system", element.first, ThemeFlags::ALL);
|
||||
elements.children.emplace_back(
|
||||
elements.lottieAnimComponents.back().get());
|
||||
}
|
||||
else if (extension == ".gif") {
|
||||
elements.GIFAnimComponents.emplace_back(
|
||||
std::make_unique<GIFAnimComponent>());
|
||||
elements.GIFAnimComponents.back()->setDefaultZIndex(35.0f);
|
||||
elements.GIFAnimComponents.back()->applyTheme(
|
||||
theme, "system", element.first, ThemeFlags::ALL);
|
||||
elements.children.emplace_back(elements.GIFAnimComponents.back().get());
|
||||
}
|
||||
else if (extension == ".") {
|
||||
LOG(LogWarning)
|
||||
<< "SystemView::populate(): Invalid theme configuration, "
|
||||
"animation file extension is missing";
|
||||
}
|
||||
else {
|
||||
LOG(LogWarning)
|
||||
<< "SystemView::populate(): Invalid theme configuration, "
|
||||
"animation file extension defined as \""
|
||||
<< extension << "\"";
|
||||
}
|
||||
else if (element.second.type == "grid" && mGrid == nullptr) {
|
||||
mGrid = std::make_unique<GridComponent<SystemData*>>();
|
||||
mPrimary = mGrid.get();
|
||||
mPrimaryType = PrimaryType::GRID;
|
||||
}
|
||||
else if (element.second.type == "text" &&
|
||||
!(element.second.has("visible") &&
|
||||
!element.second.get<bool>("visible"))) {
|
||||
// Set as container by default if metadata type is "description".
|
||||
bool container {false};
|
||||
if (element.second.has("container")) {
|
||||
container = element.second.get<bool>("container");
|
||||
}
|
||||
else if (element.second.has("metadata") &&
|
||||
element.second.get<std::string>("metadata") == "description") {
|
||||
container = true;
|
||||
}
|
||||
if (element.second.has("systemdata") &&
|
||||
element.second.get<std::string>("systemdata").substr(0, 9) ==
|
||||
"gamecount") {
|
||||
// A container can't be used if systemdata is set to a gamecount value.
|
||||
if (element.second.has("systemdata")) {
|
||||
elements.gameCountComponents.emplace_back(
|
||||
std::make_unique<TextComponent>());
|
||||
elements.gameCountComponents.back()->setDefaultZIndex(40.0f);
|
||||
elements.gameCountComponents.back()->applyTheme(
|
||||
theme, "system", element.first, ThemeFlags::ALL);
|
||||
elements.children.emplace_back(
|
||||
elements.gameCountComponents.back().get());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (container) {
|
||||
elements.containerComponents.push_back(
|
||||
std::make_unique<ScrollableContainer>());
|
||||
elements.containerComponents.back()->setDefaultZIndex(40.0f);
|
||||
elements.containerTextComponents.push_back(
|
||||
std::make_unique<TextComponent>());
|
||||
elements.containerTextComponents.back()->setDefaultZIndex(40.0f);
|
||||
elements.containerComponents.back()->addChild(
|
||||
elements.containerTextComponents.back().get());
|
||||
elements.containerComponents.back()->applyTheme(
|
||||
theme, "system", element.first,
|
||||
ThemeFlags::POSITION | ThemeFlags::SIZE | ThemeFlags::Z_INDEX |
|
||||
ThemeFlags::VISIBLE);
|
||||
elements.containerComponents.back()->setAutoScroll(true);
|
||||
elements.containerTextComponents.back()->setSize(
|
||||
elements.containerComponents.back()->getSize().x, 0.0f);
|
||||
elements.containerTextComponents.back()->applyTheme(
|
||||
theme, "system", element.first,
|
||||
ThemeFlags::ALL ^ ThemeFlags::POSITION ^ ThemeFlags::ORIGIN ^
|
||||
ThemeFlags::Z_INDEX ^ ThemeFlags::SIZE ^
|
||||
ThemeFlags::VISIBLE ^ ThemeFlags::ROTATION);
|
||||
elements.children.emplace_back(
|
||||
elements.containerComponents.back().get());
|
||||
}
|
||||
else {
|
||||
elements.textComponents.emplace_back(
|
||||
std::make_unique<TextComponent>());
|
||||
elements.textComponents.back()->setDefaultZIndex(40.0f);
|
||||
elements.textComponents.back()->applyTheme(
|
||||
theme, "system", element.first, ThemeFlags::ALL);
|
||||
elements.children.emplace_back(
|
||||
elements.textComponents.back().get());
|
||||
}
|
||||
}
|
||||
else if (element.second.type == "textlist" && mTextList == nullptr) {
|
||||
mTextList = std::make_unique<TextListComponent<SystemData*>>();
|
||||
mPrimary = mTextList.get();
|
||||
mPrimaryType = PrimaryType::TEXTLIST;
|
||||
}
|
||||
else if (element.second.type == "datetime" &&
|
||||
!(element.second.has("visible") &&
|
||||
!element.second.get<bool>("visible"))) {
|
||||
elements.dateTimeComponents.emplace_back(
|
||||
std::make_unique<DateTimeComponent>());
|
||||
elements.dateTimeComponents.back()->setDefaultZIndex(40.0f);
|
||||
elements.dateTimeComponents.back()->applyTheme(
|
||||
theme, "system", element.first, ThemeFlags::ALL);
|
||||
elements.dateTimeComponents.back()->setVisible(false);
|
||||
elements.children.emplace_back(elements.dateTimeComponents.back().get());
|
||||
}
|
||||
else if (element.second.type == "rating" &&
|
||||
!(element.second.has("visible") &&
|
||||
!element.second.get<bool>("visible"))) {
|
||||
elements.ratingComponents.emplace_back(std::make_unique<RatingComponent>());
|
||||
elements.ratingComponents.back()->setDefaultZIndex(45.0f);
|
||||
elements.ratingComponents.back()->applyTheme(theme, "system", element.first,
|
||||
ThemeFlags::ALL);
|
||||
elements.ratingComponents.back()->setVisible(false);
|
||||
elements.ratingComponents.back()->setOpacity(
|
||||
elements.ratingComponents.back()->getOpacity());
|
||||
elements.children.emplace_back(elements.ratingComponents.back().get());
|
||||
mPrimary->setDefaultZIndex(50.0f);
|
||||
mPrimary->applyTheme(theme, "system", element.first, ThemeFlags::ALL);
|
||||
mPrimary->setCursorChangedCallback(
|
||||
[&](const CursorState& state) { onCursorChanged(state); });
|
||||
mPrimary->setCancelTransitionsCallback([&] {
|
||||
ViewController::getInstance()->cancelViewTransitions();
|
||||
mNavigated = true;
|
||||
if (mSystemElements.size() > 1) {
|
||||
for (auto& anim :
|
||||
mSystemElements[mPrimary->getCursor()].lottieAnimComponents)
|
||||
anim->setPauseAnimation(true);
|
||||
for (auto& anim :
|
||||
mSystemElements[mPrimary->getCursor()].GIFAnimComponents)
|
||||
anim->setPauseAnimation(true);
|
||||
}
|
||||
});
|
||||
if (mCarousel != nullptr || mGrid != nullptr) {
|
||||
if (element.second.has("staticImage"))
|
||||
imagePath = element.second.get<std::string>("staticImage");
|
||||
if (element.second.has("defaultImage"))
|
||||
defaultImagePath = element.second.get<std::string>("defaultImage");
|
||||
if (element.second.has("text"))
|
||||
itemText = element.second.get<std::string>("text");
|
||||
}
|
||||
}
|
||||
else if (element.second.type == "image" &&
|
||||
!(element.second.has("visible") && !element.second.get<bool>("visible"))) {
|
||||
// If this is the first system then forceload to avoid texture pop-in.
|
||||
if (it == SystemData::sSystemVector.front())
|
||||
elements.imageComponents.emplace_back(
|
||||
std::make_unique<ImageComponent>(true));
|
||||
else
|
||||
elements.imageComponents.emplace_back(std::make_unique<ImageComponent>());
|
||||
|
||||
elements.imageComponents.back()->setDefaultZIndex(30.0f);
|
||||
elements.imageComponents.back()->applyTheme(theme, "system", element.first,
|
||||
ThemeFlags::ALL);
|
||||
elements.children.emplace_back(elements.imageComponents.back().get());
|
||||
}
|
||||
else if (element.second.type == "video" &&
|
||||
!(element.second.has("visible") && !element.second.get<bool>("visible"))) {
|
||||
elements.videoComponents.emplace_back(std::make_unique<VideoFFmpegComponent>());
|
||||
elements.videoComponents.back()->setDefaultZIndex(30.0f);
|
||||
elements.videoComponents.back()->setStaticVideo();
|
||||
elements.videoComponents.back()->applyTheme(theme, "system", element.first,
|
||||
ThemeFlags::ALL);
|
||||
elements.children.emplace_back(elements.videoComponents.back().get());
|
||||
}
|
||||
else if (element.second.type == "animation" && element.second.has("path") &&
|
||||
!(element.second.has("visible") && !element.second.get<bool>("visible"))) {
|
||||
const std::string extension {
|
||||
Utils::FileSystem::getExtension(element.second.get<std::string>("path"))};
|
||||
if (extension == ".json") {
|
||||
elements.lottieAnimComponents.emplace_back(
|
||||
std::make_unique<LottieAnimComponent>());
|
||||
elements.lottieAnimComponents.back()->setDefaultZIndex(35.0f);
|
||||
elements.lottieAnimComponents.back()->applyTheme(
|
||||
theme, "system", element.first, ThemeFlags::ALL);
|
||||
elements.children.emplace_back(elements.lottieAnimComponents.back().get());
|
||||
}
|
||||
else if (extension == ".gif") {
|
||||
elements.GIFAnimComponents.emplace_back(
|
||||
std::make_unique<GIFAnimComponent>());
|
||||
elements.GIFAnimComponents.back()->setDefaultZIndex(35.0f);
|
||||
elements.GIFAnimComponents.back()->applyTheme(
|
||||
theme, "system", element.first, ThemeFlags::ALL);
|
||||
elements.children.emplace_back(elements.GIFAnimComponents.back().get());
|
||||
}
|
||||
else if (extension == ".") {
|
||||
LOG(LogWarning) << "SystemView::populate(): Invalid theme configuration, "
|
||||
"animation file extension is missing";
|
||||
}
|
||||
else {
|
||||
LOG(LogWarning) << "SystemView::populate(): Invalid theme configuration, "
|
||||
"animation file extension defined as \""
|
||||
<< extension << "\"";
|
||||
}
|
||||
}
|
||||
else if (element.second.type == "text" &&
|
||||
!(element.second.has("visible") && !element.second.get<bool>("visible"))) {
|
||||
// Set as container by default if metadata type is "description".
|
||||
bool container {false};
|
||||
if (element.second.has("container")) {
|
||||
container = element.second.get<bool>("container");
|
||||
}
|
||||
else if (element.second.has("metadata") &&
|
||||
element.second.get<std::string>("metadata") == "description") {
|
||||
container = true;
|
||||
}
|
||||
if (element.second.has("systemdata") &&
|
||||
element.second.get<std::string>("systemdata").substr(0, 9) == "gamecount") {
|
||||
// A container can't be used if systemdata is set to a gamecount value.
|
||||
if (element.second.has("systemdata")) {
|
||||
elements.gameCountComponents.emplace_back(
|
||||
std::make_unique<TextComponent>());
|
||||
elements.gameCountComponents.back()->setDefaultZIndex(40.0f);
|
||||
elements.gameCountComponents.back()->applyTheme(
|
||||
theme, "system", element.first, ThemeFlags::ALL);
|
||||
elements.children.emplace_back(
|
||||
elements.gameCountComponents.back().get());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (container) {
|
||||
elements.containerComponents.push_back(
|
||||
std::make_unique<ScrollableContainer>());
|
||||
elements.containerComponents.back()->setDefaultZIndex(40.0f);
|
||||
elements.containerTextComponents.push_back(
|
||||
std::make_unique<TextComponent>());
|
||||
elements.containerTextComponents.back()->setDefaultZIndex(40.0f);
|
||||
elements.containerComponents.back()->addChild(
|
||||
elements.containerTextComponents.back().get());
|
||||
elements.containerComponents.back()->applyTheme(
|
||||
theme, "system", element.first,
|
||||
ThemeFlags::POSITION | ThemeFlags::SIZE | ThemeFlags::Z_INDEX |
|
||||
ThemeFlags::VISIBLE);
|
||||
elements.containerComponents.back()->setAutoScroll(true);
|
||||
elements.containerTextComponents.back()->setSize(
|
||||
elements.containerComponents.back()->getSize().x, 0.0f);
|
||||
elements.containerTextComponents.back()->applyTheme(
|
||||
theme, "system", element.first,
|
||||
ThemeFlags::ALL ^ ThemeFlags::POSITION ^ ThemeFlags::ORIGIN ^
|
||||
ThemeFlags::Z_INDEX ^ ThemeFlags::SIZE ^ ThemeFlags::VISIBLE ^
|
||||
ThemeFlags::ROTATION);
|
||||
elements.children.emplace_back(
|
||||
elements.containerComponents.back().get());
|
||||
}
|
||||
else {
|
||||
elements.textComponents.emplace_back(std::make_unique<TextComponent>());
|
||||
elements.textComponents.back()->setDefaultZIndex(40.0f);
|
||||
elements.textComponents.back()->applyTheme(
|
||||
theme, "system", element.first, ThemeFlags::ALL);
|
||||
elements.children.emplace_back(elements.textComponents.back().get());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (element.second.type == "datetime" &&
|
||||
!(element.second.has("visible") && !element.second.get<bool>("visible"))) {
|
||||
elements.dateTimeComponents.emplace_back(std::make_unique<DateTimeComponent>());
|
||||
elements.dateTimeComponents.back()->setDefaultZIndex(40.0f);
|
||||
elements.dateTimeComponents.back()->applyTheme(theme, "system", element.first,
|
||||
ThemeFlags::ALL);
|
||||
elements.dateTimeComponents.back()->setVisible(false);
|
||||
elements.children.emplace_back(elements.dateTimeComponents.back().get());
|
||||
}
|
||||
else if (element.second.type == "rating" &&
|
||||
!(element.second.has("visible") && !element.second.get<bool>("visible"))) {
|
||||
elements.ratingComponents.emplace_back(std::make_unique<RatingComponent>());
|
||||
elements.ratingComponents.back()->setDefaultZIndex(45.0f);
|
||||
elements.ratingComponents.back()->applyTheme(theme, "system", element.first,
|
||||
ThemeFlags::ALL);
|
||||
elements.ratingComponents.back()->setVisible(false);
|
||||
elements.ratingComponents.back()->setOpacity(
|
||||
elements.ratingComponents.back()->getOpacity());
|
||||
elements.children.emplace_back(elements.ratingComponents.back().get());
|
||||
}
|
||||
}
|
||||
|
||||
std::stable_sort(
|
||||
elements.children.begin(), elements.children.end(),
|
||||
[](GuiComponent* a, GuiComponent* b) { return b->getZIndex() > a->getZIndex(); });
|
||||
|
||||
std::stable_sort(elements.imageComponents.begin(), elements.imageComponents.end(),
|
||||
[](const std::unique_ptr<ImageComponent>& a,
|
||||
const std::unique_ptr<ImageComponent>& b) {
|
||||
return b->getZIndex() > a->getZIndex();
|
||||
});
|
||||
std::stable_sort(elements.textComponents.begin(), elements.textComponents.end(),
|
||||
[](const std::unique_ptr<TextComponent>& a,
|
||||
const std::unique_ptr<TextComponent>& b) {
|
||||
return b->getZIndex() > a->getZIndex();
|
||||
});
|
||||
std::stable_sort(elements.containerTextComponents.begin(),
|
||||
elements.containerTextComponents.end(),
|
||||
[](const std::unique_ptr<TextComponent>& a,
|
||||
const std::unique_ptr<TextComponent>& b) {
|
||||
return b->getZIndex() > a->getZIndex();
|
||||
});
|
||||
mSystemElements.emplace_back(std::move(elements));
|
||||
mSystemElements.back().helpStyle.applyTheme(theme, "system");
|
||||
}
|
||||
|
||||
std::stable_sort(
|
||||
elements.children.begin(), elements.children.end(),
|
||||
[](GuiComponent* a, GuiComponent* b) { return b->getZIndex() > a->getZIndex(); });
|
||||
|
||||
std::stable_sort(
|
||||
elements.imageComponents.begin(), elements.imageComponents.end(),
|
||||
[](const std::unique_ptr<ImageComponent>& a, const std::unique_ptr<ImageComponent>& b) {
|
||||
return b->getZIndex() > a->getZIndex();
|
||||
});
|
||||
std::stable_sort(
|
||||
elements.textComponents.begin(), elements.textComponents.end(),
|
||||
[](const std::unique_ptr<TextComponent>& a, const std::unique_ptr<TextComponent>& b) {
|
||||
return b->getZIndex() > a->getZIndex();
|
||||
});
|
||||
std::stable_sort(
|
||||
elements.containerTextComponents.begin(), elements.containerTextComponents.end(),
|
||||
[](const std::unique_ptr<TextComponent>& a, const std::unique_ptr<TextComponent>& b) {
|
||||
return b->getZIndex() > a->getZIndex();
|
||||
});
|
||||
mSystemElements.emplace_back(std::move(elements));
|
||||
mSystemElements.back().helpStyle.applyTheme(theme, "system");
|
||||
|
||||
if (mPrimary == nullptr) {
|
||||
mCarousel = std::make_unique<CarouselComponent<SystemData*>>();
|
||||
mPrimary = mCarousel.get();
|
||||
|
@ -812,17 +734,10 @@ void SystemView::populate()
|
|||
|
||||
if (mCarousel != nullptr) {
|
||||
CarouselComponent<SystemData*>::Entry entry;
|
||||
if (mLegacyMode) {
|
||||
// Keep showing only the short name for legacy themes to maintain maximum
|
||||
// backward compatibility. This also applies to unreadable theme sets.
|
||||
entry.name = it->getName();
|
||||
}
|
||||
else {
|
||||
if (itemText == "")
|
||||
entry.name = it->getFullName();
|
||||
else
|
||||
entry.name = itemText;
|
||||
}
|
||||
if (itemText == "")
|
||||
entry.name = it->getFullName();
|
||||
else
|
||||
entry.name = itemText;
|
||||
letterCaseFunc(entry.name);
|
||||
entry.object = it;
|
||||
entry.data.imagePath = imagePath;
|
||||
|
@ -924,47 +839,39 @@ void SystemView::updateGameCount(SystemData* system)
|
|||
games = true;
|
||||
}
|
||||
|
||||
if (mLegacyMode) {
|
||||
mLegacySystemInfo->setText(ss.str());
|
||||
}
|
||||
else {
|
||||
auto elementsIt = std::find_if(mSystemElements.cbegin(), mSystemElements.cend(),
|
||||
[sourceSystem](const SystemViewElements& systemElements) {
|
||||
return systemElements.system == sourceSystem;
|
||||
});
|
||||
for (auto& gameCountComp : (*elementsIt).gameCountComponents) {
|
||||
if (gameCountComp->getThemeSystemdata() == "gamecount") {
|
||||
auto elementsIt = std::find_if(mSystemElements.cbegin(), mSystemElements.cend(),
|
||||
[sourceSystem](const SystemViewElements& systemElements) {
|
||||
return systemElements.system == sourceSystem;
|
||||
});
|
||||
for (auto& gameCountComp : (*elementsIt).gameCountComponents) {
|
||||
if (gameCountComp->getThemeSystemdata() == "gamecount") {
|
||||
gameCountComp->setValue(ss.str());
|
||||
}
|
||||
else if (gameCountComp->getThemeSystemdata() == "gamecountGames") {
|
||||
if (games)
|
||||
gameCountComp->setValue(ssGames.str());
|
||||
else
|
||||
gameCountComp->setValue(ss.str());
|
||||
}
|
||||
else if (gameCountComp->getThemeSystemdata() == "gamecountGamesNoText") {
|
||||
gameCountComp->setValue(std::to_string(gameCount.first));
|
||||
}
|
||||
else if (gameCountComp->getThemeSystemdata() == "gamecountFavorites") {
|
||||
gameCountComp->setValue(ssFavorites.str());
|
||||
}
|
||||
else if (gameCountComp->getThemeSystemdata() == "gamecountFavoritesNoText") {
|
||||
if (!favoriteSystem && !recentSystem) {
|
||||
gameCountComp->setValue(std::to_string(gameCount.second));
|
||||
}
|
||||
else if (gameCountComp->getThemeSystemdata() == "gamecountGames") {
|
||||
if (games)
|
||||
gameCountComp->setValue(ssGames.str());
|
||||
else
|
||||
gameCountComp->setValue(ss.str());
|
||||
}
|
||||
else if (gameCountComp->getThemeSystemdata() == "gamecountGamesNoText") {
|
||||
gameCountComp->setValue(std::to_string(gameCount.first));
|
||||
}
|
||||
else if (gameCountComp->getThemeSystemdata() == "gamecountFavorites") {
|
||||
gameCountComp->setValue(ssFavorites.str());
|
||||
}
|
||||
else if (gameCountComp->getThemeSystemdata() == "gamecountFavoritesNoText") {
|
||||
if (!favoriteSystem && !recentSystem) {
|
||||
gameCountComp->setValue(std::to_string(gameCount.second));
|
||||
}
|
||||
}
|
||||
else {
|
||||
gameCountComp->setValue(gameCountComp->getThemeSystemdata());
|
||||
}
|
||||
}
|
||||
else {
|
||||
gameCountComp->setValue(gameCountComp->getThemeSystemdata());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SystemView::updateGameSelectors()
|
||||
{
|
||||
if (mLegacyMode)
|
||||
return;
|
||||
|
||||
const int cursor {mPrimary->getCursor()};
|
||||
|
||||
if (mSystemElements[cursor].gameSelectors.size() == 0)
|
||||
|
@ -1479,36 +1386,6 @@ void SystemView::updateGameSelectors()
|
|||
}
|
||||
}
|
||||
|
||||
void SystemView::legacyApplyTheme(const std::shared_ptr<ThemeData>& theme)
|
||||
{
|
||||
if (theme->hasView("system"))
|
||||
mViewNeedsReload = false;
|
||||
else
|
||||
mViewNeedsReload = true;
|
||||
|
||||
if (mCarousel != nullptr)
|
||||
mPrimary->applyTheme(theme, "system", "carousel_systemcarousel", ThemeFlags::ALL);
|
||||
else if (mTextList != nullptr)
|
||||
mPrimary->applyTheme(theme, "system", "textlist_gamelist", ThemeFlags::ALL);
|
||||
|
||||
mLegacySystemInfo->setSize(mSize.x, mLegacySystemInfo->getFont()->getLetterHeight() * 2.2f);
|
||||
mLegacySystemInfo->setPosition(0.0f,
|
||||
std::floor(mPrimary->getPosition().y) + mPrimary->getSize().y);
|
||||
mLegacySystemInfo->setBackgroundColor(0xDDDDDDD8);
|
||||
mLegacySystemInfo->setRenderBackground(true);
|
||||
mLegacySystemInfo->setFont(Font::get(0.035f * mSize.y, Font::getDefaultPath()));
|
||||
mLegacySystemInfo->setColor(0x000000FF);
|
||||
mLegacySystemInfo->setUppercase(true);
|
||||
mLegacySystemInfo->setZIndex(50.0f);
|
||||
mLegacySystemInfo->setDefaultZIndex(50.0f);
|
||||
|
||||
const ThemeData::ThemeElement* sysInfoElem {
|
||||
theme->getElement("system", "text_systemInfo", "text")};
|
||||
|
||||
if (sysInfoElem)
|
||||
mLegacySystemInfo->applyTheme(theme, "system", "text_systemInfo", ThemeFlags::ALL);
|
||||
}
|
||||
|
||||
void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary)
|
||||
{
|
||||
glm::mat4 trans {getTransform() * parentTrans};
|
||||
|
@ -1524,7 +1401,7 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary)
|
|||
renderAfter += 1;
|
||||
}
|
||||
|
||||
for (int i = renderBefore; i <= renderAfter; ++i) {
|
||||
for (int i {renderBefore}; i <= renderAfter; ++i) {
|
||||
int index {i};
|
||||
while (index < 0)
|
||||
index += static_cast<int>(mPrimary->getNumEntries());
|
||||
|
@ -1560,24 +1437,7 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary)
|
|||
static_cast<int>(glm::round(elementTrans[3].y))},
|
||||
glm::ivec2 {static_cast<int>(mSize.x), static_cast<int>(mSize.y)});
|
||||
|
||||
if (mLegacyMode && mSystemElements.size() > static_cast<size_t>(index)) {
|
||||
for (auto element : mSystemElements[index].legacyExtras) {
|
||||
if (abovePrimary && element->getZIndex() < primaryZIndex)
|
||||
continue;
|
||||
if ((mFadeTransitions || element->getDimming() != 1.0f) &&
|
||||
element->getZIndex() < primaryZIndex)
|
||||
element->setDimming(1.0f - mFadeOpacity);
|
||||
if (mFadeTransitions && mPrimary->getFadeAbovePrimary()) {
|
||||
if (mFadeTransitions && isAnimationPlaying(0))
|
||||
element->setOpacity(1.0f - mFadeOpacity);
|
||||
else
|
||||
element->setOpacity(1.0f);
|
||||
}
|
||||
|
||||
element->render(elementTrans);
|
||||
}
|
||||
}
|
||||
else if (!mLegacyMode && mSystemElements.size() > static_cast<size_t>(index)) {
|
||||
if (mSystemElements.size() > static_cast<size_t>(index)) {
|
||||
for (auto child : mSystemElements[index].children) {
|
||||
if (abovePrimary && (child->getZIndex() > primaryZIndex)) {
|
||||
if (mFadeTransitions && mPrimary->getFadeAbovePrimary()) {
|
||||
|
@ -1598,18 +1458,6 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary)
|
|||
}
|
||||
}
|
||||
|
||||
if (mLegacyMode) {
|
||||
if (mFadeTransitions && !abovePrimary) {
|
||||
if (mFadeTransitions && isAnimationPlaying(0))
|
||||
mLegacySystemInfo->setOpacity(1.0f - mFadeOpacity);
|
||||
else
|
||||
mLegacySystemInfo->setOpacity(1.0f);
|
||||
}
|
||||
if ((abovePrimary && mLegacySystemInfo->getZIndex() > 40.0f) ||
|
||||
(!abovePrimary && mLegacySystemInfo->getZIndex() <= 40.0f))
|
||||
mLegacySystemInfo->render(elementTrans);
|
||||
}
|
||||
|
||||
mRenderer->popClipRect();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ public:
|
|||
using PrimaryType = PrimaryComponent<SystemData*>::PrimaryType;
|
||||
|
||||
SystemView();
|
||||
~SystemView();
|
||||
|
||||
void onShow() override;
|
||||
void onTransition() override;
|
||||
|
@ -108,7 +107,6 @@ private:
|
|||
void populate();
|
||||
void updateGameCount(SystemData* system = nullptr);
|
||||
void updateGameSelectors();
|
||||
void legacyApplyTheme(const std::shared_ptr<ThemeData>& theme);
|
||||
void renderElements(const glm::mat4& parentTrans, bool abovePrimary);
|
||||
|
||||
struct SystemViewElements {
|
||||
|
@ -117,7 +115,6 @@ private:
|
|||
std::string name;
|
||||
std::string fullName;
|
||||
std::vector<std::unique_ptr<GameSelectorComponent>> gameSelectors;
|
||||
std::vector<GuiComponent*> legacyExtras;
|
||||
std::vector<GuiComponent*> children;
|
||||
|
||||
std::vector<std::unique_ptr<ImageComponent>> imageComponents;
|
||||
|
@ -136,7 +133,6 @@ private:
|
|||
std::unique_ptr<CarouselComponent<SystemData*>> mCarousel;
|
||||
std::unique_ptr<GridComponent<SystemData*>> mGrid;
|
||||
std::unique_ptr<TextListComponent<SystemData*>> mTextList;
|
||||
std::unique_ptr<TextComponent> mLegacySystemInfo;
|
||||
std::vector<SystemViewElements> mSystemElements;
|
||||
PrimaryComponent<SystemData*>* mPrimary;
|
||||
PrimaryType mPrimaryType;
|
||||
|
@ -152,7 +148,6 @@ private:
|
|||
|
||||
bool mUpdatedGameCount;
|
||||
bool mViewNeedsReload;
|
||||
bool mLegacyMode;
|
||||
bool mNavigated;
|
||||
bool mMaxFade;
|
||||
bool mFadeTransitions;
|
||||
|
|
|
@ -51,7 +51,6 @@ ViewController::ViewController() noexcept
|
|||
, mNextSystem {false}
|
||||
{
|
||||
mState.viewing = NOTHING;
|
||||
mState.viewstyle = AUTOMATIC;
|
||||
}
|
||||
|
||||
ViewController* ViewController::getInstance()
|
||||
|
@ -699,19 +698,6 @@ void ViewController::goToGamelist(SystemData* system)
|
|||
mState.viewing = GAMELIST;
|
||||
mState.system = system;
|
||||
|
||||
if (system->getTheme()->isLegacyTheme()) {
|
||||
auto it = mGamelistViews.find(system);
|
||||
if (it != mGamelistViews.cend()) {
|
||||
std::string viewStyle {it->second->getName()};
|
||||
if (viewStyle == "basic")
|
||||
mState.viewstyle = BASIC;
|
||||
else if (viewStyle == "detailed")
|
||||
mState.viewstyle = DETAILED;
|
||||
else if (viewStyle == "video")
|
||||
mState.viewstyle = VIDEO;
|
||||
}
|
||||
}
|
||||
|
||||
if (mCurrentView)
|
||||
mCurrentView->onShow();
|
||||
|
||||
|
@ -905,55 +891,7 @@ std::shared_ptr<GamelistView> ViewController::getGamelistView(SystemData* system
|
|||
// If there's no entry, then create it and return it.
|
||||
std::shared_ptr<GamelistView> view;
|
||||
|
||||
if (system->getTheme()->isLegacyTheme()) {
|
||||
const bool themeHasVideoView {system->getTheme()->hasView("video")};
|
||||
|
||||
// Decide which view style to use.
|
||||
GamelistViewStyle selectedViewStyle {AUTOMATIC};
|
||||
|
||||
const std::string& viewPreference {Settings::getInstance()->getString("GamelistViewStyle")};
|
||||
if (viewPreference == "basic")
|
||||
selectedViewStyle = BASIC;
|
||||
else if (viewPreference == "detailed")
|
||||
selectedViewStyle = DETAILED;
|
||||
else if (viewPreference == "video")
|
||||
selectedViewStyle = VIDEO;
|
||||
|
||||
if (selectedViewStyle == AUTOMATIC) {
|
||||
const std::vector<FileData*> files {
|
||||
system->getRootFolder()->getFilesRecursive(GAME | FOLDER)};
|
||||
|
||||
for (auto it = files.cbegin(); it != files.cend(); ++it) {
|
||||
if (themeHasVideoView && !(*it)->getVideoPath().empty()) {
|
||||
selectedViewStyle = VIDEO;
|
||||
break;
|
||||
}
|
||||
else if (!(*it)->getImagePath().empty()) {
|
||||
selectedViewStyle = DETAILED;
|
||||
// Don't break out in case any subsequent files have videos.
|
||||
}
|
||||
}
|
||||
}
|
||||
// Create the view.
|
||||
switch (selectedViewStyle) {
|
||||
case VIDEO: {
|
||||
mState.viewstyle = VIDEO;
|
||||
break;
|
||||
}
|
||||
case DETAILED: {
|
||||
mState.viewstyle = DETAILED;
|
||||
break;
|
||||
}
|
||||
case BASIC: {
|
||||
}
|
||||
default: {
|
||||
if (!system->isGroupedCustomCollection())
|
||||
mState.viewstyle = BASIC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Settings::getInstance()->getBool("ThemeVariantTriggers")) {
|
||||
if (Settings::getInstance()->getBool("ThemeVariantTriggers")) {
|
||||
const auto overrides = system->getTheme()->getCurrentThemeSetSelectedVariantOverrides();
|
||||
|
||||
if (!overrides.empty()) {
|
||||
|
@ -1469,15 +1407,8 @@ HelpStyle ViewController::getHelpStyle()
|
|||
|
||||
HelpStyle ViewController::getViewHelpStyle()
|
||||
{
|
||||
if (mState.getSystem()->getTheme()->isLegacyTheme()) {
|
||||
// For backward compatibility with legacy theme sets, read the helpsystem theme config
|
||||
// from the system view entry.
|
||||
if (mState.viewing == ViewMode::GAMELIST)
|
||||
return getGamelistView(mState.getSystem())->getHelpStyle();
|
||||
else
|
||||
return getSystemListView()->getHelpStyle();
|
||||
}
|
||||
else {
|
||||
if (mState.viewing == ViewMode::GAMELIST)
|
||||
return getGamelistView(mState.getSystem())->getHelpStyle();
|
||||
else
|
||||
return getSystemListView()->getHelpStyle();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,16 +104,8 @@ public:
|
|||
GAMELIST
|
||||
};
|
||||
|
||||
enum GamelistViewStyle {
|
||||
AUTOMATIC,
|
||||
BASIC,
|
||||
DETAILED,
|
||||
VIDEO
|
||||
};
|
||||
|
||||
struct State {
|
||||
ViewMode viewing;
|
||||
GamelistViewStyle viewstyle;
|
||||
|
||||
SystemData* getSystem() const
|
||||
{
|
||||
|
|
|
@ -34,7 +34,6 @@ HelpStyle::HelpStyle()
|
|||
, iconTextSpacingDimmed {iconTextSpacing}
|
||||
, opacity {1.0f}
|
||||
, opacityDimmed {opacity}
|
||||
, legacyTheme {false}
|
||||
, letterCase {"uppercase"}
|
||||
{
|
||||
}
|
||||
|
@ -45,8 +44,6 @@ void HelpStyle::applyTheme(const std::shared_ptr<ThemeData>& theme, const std::s
|
|||
if (!elem)
|
||||
return;
|
||||
|
||||
legacyTheme = theme->isLegacyTheme();
|
||||
|
||||
if (elem->has("pos"))
|
||||
position = elem->get<glm::vec2>("pos") *
|
||||
glm::vec2 {Renderer::getScreenWidth(), Renderer::getScreenHeight()};
|
||||
|
@ -82,15 +79,13 @@ void HelpStyle::applyTheme(const std::shared_ptr<ThemeData>& theme, const std::s
|
|||
iconColorDimmed = iconColor;
|
||||
|
||||
if (elem->has("fontPath") || elem->has("fontSize")) {
|
||||
font = Font::getFromTheme(elem, ThemeFlags::ALL, font, 0.0f, false, theme->isLegacyTheme());
|
||||
font = Font::getFromTheme(elem, ThemeFlags::ALL, font, 0.0f, false);
|
||||
if (!elem->has("fontSizeDimmed"))
|
||||
fontDimmed = Font::getFromTheme(elem, ThemeFlags::ALL, font, 0.0f, false,
|
||||
theme->isLegacyTheme());
|
||||
fontDimmed = Font::getFromTheme(elem, ThemeFlags::ALL, font, 0.0f, false);
|
||||
}
|
||||
|
||||
if (elem->has("fontSizeDimmed")) {
|
||||
fontDimmed = Font::getFromTheme(elem, ThemeFlags::ALL, font, 0.0f, false,
|
||||
theme->isLegacyTheme(), 1.0f, true);
|
||||
fontDimmed = Font::getFromTheme(elem, ThemeFlags::ALL, font, 0.0f, false, 1.0f, true);
|
||||
}
|
||||
|
||||
if (elem->has("entrySpacing"))
|
||||
|
|
|
@ -34,7 +34,6 @@ struct HelpStyle {
|
|||
float iconTextSpacingDimmed;
|
||||
float opacity;
|
||||
float opacityDimmed;
|
||||
bool legacyTheme;
|
||||
std::string letterCase;
|
||||
|
||||
struct CustomButtonIcons {
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace
|
|||
continue;
|
||||
}
|
||||
|
||||
pugi::xml_node node = doc.append_child(type.c_str());
|
||||
pugi::xml_node node {doc.append_child(type.c_str())};
|
||||
node.append_attribute("name").set_value(it->first.c_str());
|
||||
node.append_attribute("value").set_value(it->second.second);
|
||||
}
|
||||
|
@ -160,8 +160,6 @@ void Settings::setDefaults()
|
|||
mStringMap["ThemeColorScheme"] = {"", ""};
|
||||
mStringMap["ThemeAspectRatio"] = {"", ""};
|
||||
mStringMap["ThemeTransitions"] = {"automatic", "automatic"};
|
||||
mStringMap["GamelistViewStyle"] = {"automatic", "automatic"};
|
||||
mStringMap["LegacyThemeTransitions"] = {"builtin-instant", "builtin-instant"};
|
||||
mStringMap["QuickSystemSelect"] = {"leftrightshoulders", "leftrightshoulders"};
|
||||
mStringMap["StartupSystem"] = {"", ""};
|
||||
mStringMap["DefaultSortOrder"] = {"filename, ascending", "filename, ascending"};
|
||||
|
@ -214,8 +212,6 @@ void Settings::setDefaults()
|
|||
|
||||
mBoolMap["ThemeVariantTriggers"] = {true, true};
|
||||
mBoolMap["MenuBlurBackground"] = {true, true};
|
||||
mBoolMap["GamelistVideoPillarbox"] = {true, true};
|
||||
mBoolMap["GamelistVideoScanlines"] = {false, false};
|
||||
mBoolMap["FoldersOnTop"] = {true, true};
|
||||
mBoolMap["FavoritesFirst"] = {true, true};
|
||||
mBoolMap["FavoritesStar"] = {true, true};
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#include <algorithm>
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#define MINIMUM_LEGACY_THEME_FORMAT_VERSION 3
|
||||
|
||||
// clang-format off
|
||||
std::vector<std::string> ThemeData::sSupportedViews {
|
||||
{"all"},
|
||||
|
@ -53,35 +51,6 @@ std::vector<std::string> ThemeData::sSupportedTransitionAnimations {
|
|||
{"builtin-slide"},
|
||||
{"builtin-fade"}};
|
||||
|
||||
std::vector<std::string> ThemeData::sLegacySupportedViews {
|
||||
{"all"},
|
||||
{"system"},
|
||||
{"basic"},
|
||||
{"detailed"},
|
||||
{"grid"},
|
||||
{"video"}};
|
||||
|
||||
std::vector<std::string> ThemeData::sLegacySupportedFeatures {
|
||||
{"navigationsounds"},
|
||||
{"video"},
|
||||
{"carousel"},
|
||||
{"z-index"},
|
||||
{"visible"}};
|
||||
|
||||
std::vector<std::string> ThemeData::sLegacyProperties {
|
||||
{"showSnapshotNoVideo"},
|
||||
{"showSnapshotDelay"},
|
||||
{"forceUppercase"},
|
||||
{"alignment"},
|
||||
{"defaultLogo"},
|
||||
{"logoSize"},
|
||||
{"logoScale"},
|
||||
{"logoRotation"},
|
||||
{"logoRotationOrigin"},
|
||||
{"logoAlignment"},
|
||||
{"maxLogoCount"},
|
||||
{"selectorOffsetY"}};
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> ThemeData::sSupportedAspectRatios {
|
||||
{"automatic", "automatic"},
|
||||
{"16:9", "16:9"},
|
||||
|
@ -137,7 +106,6 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"defaultImage", PATH},
|
||||
{"defaultFolderImage", PATH},
|
||||
{"maxItemCount", FLOAT},
|
||||
{"maxLogoCount", FLOAT}, // For backward compatibility with legacy themes.
|
||||
{"itemsBeforeCenter", UNSIGNED_INTEGER},
|
||||
{"itemsAfterCenter", UNSIGNED_INTEGER},
|
||||
{"itemStacking", STRING},
|
||||
|
@ -173,12 +141,6 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"unfocusedItemSaturation", FLOAT},
|
||||
{"unfocusedItemDimming", FLOAT},
|
||||
{"fastScrolling", BOOLEAN},
|
||||
{"defaultLogo", PATH}, // For backward compatibility with legacy themes.
|
||||
{"logoSize", NORMALIZED_PAIR}, // For backward compatibility with legacy themes.
|
||||
{"logoScale", FLOAT}, // For backward compatibility with legacy themes.
|
||||
{"logoRotation", FLOAT}, // For backward compatibility with legacy themes.
|
||||
{"logoRotationOrigin", NORMALIZED_PAIR}, // For backward compatibility with legacy themes.
|
||||
{"logoAlignment", STRING}, // For backward compatibility with legacy themes.
|
||||
{"color", COLOR},
|
||||
{"colorEnd", COLOR},
|
||||
{"gradientType", STRING},
|
||||
|
@ -196,8 +158,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"systemNameSuffix", BOOLEAN},
|
||||
{"letterCaseSystemNameSuffix", STRING},
|
||||
{"fadeAbovePrimary", BOOLEAN},
|
||||
{"zIndex", FLOAT},
|
||||
{"legacyZIndexMode", STRING}}}, // For backward compatibility with legacy themes.
|
||||
{"zIndex", FLOAT}}},
|
||||
{"grid",
|
||||
{{"pos", NORMALIZED_PAIR},
|
||||
{"size", NORMALIZED_PAIR},
|
||||
|
@ -260,7 +221,6 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"selectorHeight", FLOAT},
|
||||
{"selectorHorizontalOffset", FLOAT},
|
||||
{"selectorVerticalOffset", FLOAT},
|
||||
{"selectorOffsetY", FLOAT}, // For backward compatibility with legacy themes.
|
||||
{"selectorColor", COLOR},
|
||||
{"selectorColorEnd", COLOR},
|
||||
{"selectorGradientType", STRING},
|
||||
|
@ -274,14 +234,11 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"selectedSecondaryBackgroundColor", COLOR},
|
||||
{"fontPath", PATH},
|
||||
{"fontSize", FLOAT},
|
||||
{"scrollSound", PATH}, // For backward compatibility with legacy themes.
|
||||
{"horizontalAlignment", STRING},
|
||||
{"alignment", STRING}, // For backward compatibility with legacy themes.
|
||||
{"horizontalMargin", FLOAT},
|
||||
{"letterCase", STRING},
|
||||
{"letterCaseAutoCollections", STRING},
|
||||
{"letterCaseCustomCollections", STRING},
|
||||
{"forceUppercase", BOOLEAN}, // For backward compatibility with legacy themes.
|
||||
{"lineSpacing", FLOAT},
|
||||
{"indicators", STRING},
|
||||
{"collectionIndicators", STRING},
|
||||
|
@ -348,9 +305,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"opacity", FLOAT},
|
||||
{"saturation", FLOAT},
|
||||
{"visible", BOOLEAN},
|
||||
{"zIndex", FLOAT},
|
||||
{"showSnapshotNoVideo", BOOLEAN}, // For backward compatibility with legacy themes.
|
||||
{"showSnapshotDelay", BOOLEAN}}}, // For backward compatibility with legacy themes.
|
||||
{"zIndex", FLOAT}}},
|
||||
{"animation",
|
||||
{{"pos", NORMALIZED_PAIR},
|
||||
{"size", NORMALIZED_PAIR},
|
||||
|
@ -379,7 +334,6 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"rotation", FLOAT},
|
||||
{"rotationOrigin", NORMALIZED_PAIR},
|
||||
{"horizontalAlignment", STRING},
|
||||
{"alignment", STRING}, // For backward compatibility with legacy themes.
|
||||
{"direction", STRING},
|
||||
{"lines", UNSIGNED_INTEGER},
|
||||
{"itemsPerLine", UNSIGNED_INTEGER},
|
||||
|
@ -428,11 +382,9 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"fontSize", FLOAT},
|
||||
{"horizontalAlignment", STRING},
|
||||
{"verticalAlignment", STRING},
|
||||
{"alignment", STRING}, // For backward compatibility with legacy themes.
|
||||
{"color", COLOR},
|
||||
{"backgroundColor", COLOR},
|
||||
{"letterCase", STRING},
|
||||
{"forceUppercase", BOOLEAN}, // For backward compatibility with legacy themes.
|
||||
{"lineSpacing", FLOAT},
|
||||
{"opacity", FLOAT},
|
||||
{"visible", BOOLEAN},
|
||||
|
@ -451,11 +403,9 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"fontSize", FLOAT},
|
||||
{"horizontalAlignment", STRING},
|
||||
{"verticalAlignment", STRING},
|
||||
{"alignment", STRING}, // For backward compatibility with legacy themes.
|
||||
{"color", COLOR},
|
||||
{"backgroundColor", COLOR},
|
||||
{"letterCase", STRING},
|
||||
{"forceUppercase", BOOLEAN}, // For backward compatibility with legacy themes.
|
||||
{"lineSpacing", FLOAT},
|
||||
{"format", STRING},
|
||||
{"displayRelative", BOOLEAN},
|
||||
|
@ -472,7 +422,6 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"fontSize", FLOAT},
|
||||
{"horizontalAlignment", STRING},
|
||||
{"verticalAlignment", STRING},
|
||||
{"alignment", STRING}, // For backward compatibility with legacy themes.
|
||||
{"color", COLOR},
|
||||
{"backgroundColor", COLOR},
|
||||
{"opacity", FLOAT},
|
||||
|
@ -515,56 +464,15 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"iconTextSpacing", FLOAT},
|
||||
{"iconTextSpacingDimmed", FLOAT},
|
||||
{"letterCase", STRING},
|
||||
{"textStyle", STRING}, // For backward compatibility with legacy themes.
|
||||
{"opacity", FLOAT},
|
||||
{"opacityDimmed", FLOAT},
|
||||
{"customButtonIcon", PATH}}},
|
||||
{"navigationsounds",
|
||||
{{"systembrowseSound", PATH},
|
||||
{"quicksysselectSound", PATH},
|
||||
{"selectSound", PATH},
|
||||
{"backSound", PATH},
|
||||
{"scrollSound", PATH},
|
||||
{"favoriteSound", PATH},
|
||||
{"launchSound", PATH}}},
|
||||
// Legacy components below, not in use any longer but needed for backward compatibility.
|
||||
{"sound",
|
||||
{{"path", PATH}}},
|
||||
{"imagegrid",
|
||||
{{"pos", NORMALIZED_PAIR},
|
||||
{"size", NORMALIZED_PAIR},
|
||||
{"margin", NORMALIZED_PAIR},
|
||||
{"padding", NORMALIZED_RECT},
|
||||
{"autoLayout", NORMALIZED_PAIR},
|
||||
{"autoLayoutSelectedZoom", FLOAT},
|
||||
{"gameImage", PATH},
|
||||
{"folderImage", PATH},
|
||||
{"imageSource", STRING},
|
||||
{"scrollDirection", STRING},
|
||||
{"centerSelection", BOOLEAN},
|
||||
{"scrollLoop", BOOLEAN},
|
||||
{"animate", BOOLEAN},
|
||||
{"zIndex", FLOAT}}},
|
||||
{"gridtile",
|
||||
{{"size", NORMALIZED_PAIR},
|
||||
{"padding", NORMALIZED_PAIR},
|
||||
{"imageColor", COLOR},
|
||||
{"backgroundImage", PATH},
|
||||
{"backgroundCornerSize", NORMALIZED_PAIR},
|
||||
{"backgroundColor", COLOR},
|
||||
{"backgroundCenterColor", COLOR},
|
||||
{"backgroundEdgeColor", COLOR}}},
|
||||
{"ninepatch",
|
||||
{{"pos", NORMALIZED_PAIR},
|
||||
{"size", NORMALIZED_PAIR},
|
||||
{"path", PATH},
|
||||
{"visible", BOOLEAN},
|
||||
{"zIndex", FLOAT}}}};
|
||||
{{"path", PATH}}}};
|
||||
// clang-format on
|
||||
|
||||
ThemeData::ThemeData()
|
||||
: mLegacyTheme {false}
|
||||
, mCustomCollection {false}
|
||||
: mCustomCollection {false}
|
||||
{
|
||||
sCurrentThemeSet = sThemeSets.find(Settings::getInstance()->getString("ThemeSet"));
|
||||
sVariantDefinedTransitions = "";
|
||||
|
@ -605,93 +513,70 @@ void ThemeData::loadFile(const std::map<std::string, std::string>& sysDataMap,
|
|||
if (!root)
|
||||
throw error << ": Missing <theme> tag";
|
||||
|
||||
if (sCurrentThemeSet != sThemeSets.cend())
|
||||
mLegacyTheme = sCurrentThemeSet->second.capabilities.legacyTheme;
|
||||
|
||||
// The resolution tag introduced in RetroPie EmulationStation in 2020 is a very bad idea
|
||||
// as it changes sizing of components from relative values to absolute pixel values.
|
||||
// So themes using it will simply not get loaded at all.
|
||||
if (root.child("resolution") != nullptr)
|
||||
throw error << ": <resolution> tag not supported";
|
||||
|
||||
// Check for legacy theme version.
|
||||
int legacyVersion {root.child("formatVersion").text().as_int(-1)};
|
||||
if (root.child("formatVersion") != nullptr)
|
||||
throw error << ": Legacy <formatVersion> tag found";
|
||||
|
||||
if (mLegacyTheme) {
|
||||
if (legacyVersion == -1)
|
||||
throw error << ": <formatVersion> tag missing for legacy theme set";
|
||||
if (sCurrentThemeSet->second.capabilities.variants.size() > 0) {
|
||||
for (auto& variant : sCurrentThemeSet->second.capabilities.variants)
|
||||
mVariants.emplace_back(variant.name);
|
||||
|
||||
if (legacyVersion < MINIMUM_LEGACY_THEME_FORMAT_VERSION)
|
||||
throw error << ": Defined legacy format version " << legacyVersion
|
||||
<< " is less than the minimum supported version "
|
||||
<< MINIMUM_LEGACY_THEME_FORMAT_VERSION;
|
||||
}
|
||||
else if (legacyVersion != -1) {
|
||||
throw error << ": Legacy <formatVersion> tag found for non-legacy theme set";
|
||||
if (std::find(mVariants.cbegin(), mVariants.cend(),
|
||||
Settings::getInstance()->getString("ThemeVariant")) != mVariants.cend())
|
||||
mSelectedVariant = Settings::getInstance()->getString("ThemeVariant");
|
||||
else
|
||||
mSelectedVariant = mVariants.front();
|
||||
// Special shortcut variant to apply configuration to all defined variants.
|
||||
mVariants.emplace_back("all");
|
||||
|
||||
if (trigger != ThemeTriggers::TriggerType::NONE) {
|
||||
auto overrides = getCurrentThemeSetSelectedVariantOverrides();
|
||||
if (overrides.find(trigger) != overrides.end())
|
||||
mOverrideVariant = overrides.at(trigger).first;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mLegacyTheme) {
|
||||
if (sCurrentThemeSet->second.capabilities.variants.size() > 0) {
|
||||
for (auto& variant : sCurrentThemeSet->second.capabilities.variants)
|
||||
mVariants.emplace_back(variant.name);
|
||||
if (sCurrentThemeSet->second.capabilities.colorSchemes.size() > 0) {
|
||||
for (auto& colorScheme : sCurrentThemeSet->second.capabilities.colorSchemes)
|
||||
mColorSchemes.emplace_back(colorScheme.name);
|
||||
|
||||
if (std::find(mVariants.cbegin(), mVariants.cend(),
|
||||
Settings::getInstance()->getString("ThemeVariant")) != mVariants.cend())
|
||||
mSelectedVariant = Settings::getInstance()->getString("ThemeVariant");
|
||||
else
|
||||
mSelectedVariant = mVariants.front();
|
||||
// Special shortcut variant to apply configuration to all defined variants.
|
||||
mVariants.emplace_back("all");
|
||||
if (std::find(mColorSchemes.cbegin(), mColorSchemes.cend(),
|
||||
Settings::getInstance()->getString("ThemeColorScheme")) !=
|
||||
mColorSchemes.cend())
|
||||
mSelectedColorScheme = Settings::getInstance()->getString("ThemeColorScheme");
|
||||
else
|
||||
mSelectedColorScheme = mColorSchemes.front();
|
||||
}
|
||||
|
||||
if (trigger != ThemeTriggers::TriggerType::NONE) {
|
||||
auto overrides = getCurrentThemeSetSelectedVariantOverrides();
|
||||
if (overrides.find(trigger) != overrides.end())
|
||||
mOverrideVariant = overrides.at(trigger).first;
|
||||
}
|
||||
}
|
||||
sAspectRatioMatch = false;
|
||||
|
||||
if (sCurrentThemeSet->second.capabilities.colorSchemes.size() > 0) {
|
||||
for (auto& colorScheme : sCurrentThemeSet->second.capabilities.colorSchemes)
|
||||
mColorSchemes.emplace_back(colorScheme.name);
|
||||
if (sCurrentThemeSet->second.capabilities.aspectRatios.size() > 0) {
|
||||
if (std::find(sCurrentThemeSet->second.capabilities.aspectRatios.cbegin(),
|
||||
sCurrentThemeSet->second.capabilities.aspectRatios.cend(),
|
||||
Settings::getInstance()->getString("ThemeAspectRatio")) !=
|
||||
sCurrentThemeSet->second.capabilities.aspectRatios.cend())
|
||||
sSelectedAspectRatio = Settings::getInstance()->getString("ThemeAspectRatio");
|
||||
else
|
||||
sSelectedAspectRatio = sCurrentThemeSet->second.capabilities.aspectRatios.front();
|
||||
|
||||
if (std::find(mColorSchemes.cbegin(), mColorSchemes.cend(),
|
||||
Settings::getInstance()->getString("ThemeColorScheme")) !=
|
||||
mColorSchemes.cend())
|
||||
mSelectedColorScheme = Settings::getInstance()->getString("ThemeColorScheme");
|
||||
else
|
||||
mSelectedColorScheme = mColorSchemes.front();
|
||||
}
|
||||
if (sSelectedAspectRatio == "automatic") {
|
||||
// Auto-detect the closest aspect ratio based on what's available in the theme set.
|
||||
sSelectedAspectRatio = "16:9";
|
||||
const float screenAspectRatio {Renderer::getScreenAspectRatio()};
|
||||
float diff {std::fabs(sAspectRatioMap["16:9"] - screenAspectRatio)};
|
||||
|
||||
sAspectRatioMatch = false;
|
||||
for (auto& aspectRatio : sCurrentThemeSet->second.capabilities.aspectRatios) {
|
||||
if (aspectRatio == "automatic")
|
||||
continue;
|
||||
|
||||
if (sCurrentThemeSet->second.capabilities.aspectRatios.size() > 0) {
|
||||
if (std::find(sCurrentThemeSet->second.capabilities.aspectRatios.cbegin(),
|
||||
sCurrentThemeSet->second.capabilities.aspectRatios.cend(),
|
||||
Settings::getInstance()->getString("ThemeAspectRatio")) !=
|
||||
sCurrentThemeSet->second.capabilities.aspectRatios.cend())
|
||||
sSelectedAspectRatio = Settings::getInstance()->getString("ThemeAspectRatio");
|
||||
else
|
||||
sSelectedAspectRatio = sCurrentThemeSet->second.capabilities.aspectRatios.front();
|
||||
|
||||
if (sSelectedAspectRatio == "automatic") {
|
||||
// Auto-detect the closest aspect ratio based on what's available in the theme set.
|
||||
sSelectedAspectRatio = "16:9";
|
||||
const float screenAspectRatio {Renderer::getScreenAspectRatio()};
|
||||
float diff {std::fabs(sAspectRatioMap["16:9"] - screenAspectRatio)};
|
||||
|
||||
for (auto& aspectRatio : sCurrentThemeSet->second.capabilities.aspectRatios) {
|
||||
if (aspectRatio == "automatic")
|
||||
continue;
|
||||
|
||||
if (sAspectRatioMap.find(aspectRatio) != sAspectRatioMap.end()) {
|
||||
const float newDiff {
|
||||
std::fabs(sAspectRatioMap[aspectRatio] - screenAspectRatio)};
|
||||
if (newDiff < 0.01f)
|
||||
sAspectRatioMatch = true;
|
||||
if (newDiff < diff) {
|
||||
diff = newDiff;
|
||||
sSelectedAspectRatio = aspectRatio;
|
||||
}
|
||||
if (sAspectRatioMap.find(aspectRatio) != sAspectRatioMap.end()) {
|
||||
const float newDiff {
|
||||
std::fabs(sAspectRatioMap[aspectRatio] - screenAspectRatio)};
|
||||
if (newDiff < 0.01f)
|
||||
sAspectRatioMatch = true;
|
||||
if (newDiff < diff) {
|
||||
diff = newDiff;
|
||||
sSelectedAspectRatio = aspectRatio;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -699,19 +584,13 @@ void ThemeData::loadFile(const std::map<std::string, std::string>& sysDataMap,
|
|||
}
|
||||
|
||||
parseVariables(root);
|
||||
if (!mLegacyTheme)
|
||||
parseColorSchemes(root);
|
||||
|
||||
parseColorSchemes(root);
|
||||
parseIncludes(root);
|
||||
parseViews(root);
|
||||
// For non-legacy themes this will simply check for the presence of a feature tag and throw
|
||||
// an error if it's found.
|
||||
parseFeatures(root);
|
||||
|
||||
if (!mLegacyTheme) {
|
||||
parseVariants(root);
|
||||
parseAspectRatios(root);
|
||||
}
|
||||
if (root.child("feature") != nullptr)
|
||||
throw error << ": Legacy <feature> tag found";
|
||||
parseVariants(root);
|
||||
parseAspectRatios(root);
|
||||
}
|
||||
|
||||
bool ThemeData::hasView(const std::string& view)
|
||||
|
@ -720,37 +599,6 @@ bool ThemeData::hasView(const std::string& view)
|
|||
return (viewIt != mViews.cend());
|
||||
}
|
||||
|
||||
std::vector<GuiComponent*> ThemeData::makeExtras(const std::shared_ptr<ThemeData>& theme,
|
||||
const std::string& view)
|
||||
{
|
||||
std::vector<GuiComponent*> comps;
|
||||
|
||||
auto viewIt = theme->mViews.find(view);
|
||||
if (viewIt == theme->mViews.cend())
|
||||
return comps;
|
||||
|
||||
for (auto it = viewIt->second.legacyOrderedKeys.cbegin(); // Line break.
|
||||
it != viewIt->second.legacyOrderedKeys.cend(); ++it) {
|
||||
ThemeElement& elem {viewIt->second.elements.at(*it)};
|
||||
if (elem.extra) {
|
||||
GuiComponent* comp {nullptr};
|
||||
const std::string& t {elem.type};
|
||||
if (t == "image")
|
||||
comp = new ImageComponent;
|
||||
else if (t == "text")
|
||||
comp = new TextComponent;
|
||||
|
||||
if (comp) {
|
||||
comp->setDefaultZIndex(10.0f);
|
||||
comp->applyTheme(theme, view, *it, ThemeFlags::ALL);
|
||||
comps.push_back(comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return comps;
|
||||
}
|
||||
|
||||
const ThemeData::ThemeElement* ThemeData::getElement(const std::string& view,
|
||||
const std::string& element,
|
||||
const std::string& expectedType) const
|
||||
|
@ -854,6 +702,9 @@ void ThemeData::populateThemeSets()
|
|||
#endif
|
||||
ThemeCapability capabilities {parseThemeCapabilities(*it)};
|
||||
|
||||
if (!capabilities.validTheme)
|
||||
continue;
|
||||
|
||||
std::string themeName;
|
||||
if (capabilities.themeName != "") {
|
||||
themeName.append(" (theme name \"")
|
||||
|
@ -862,27 +713,22 @@ void ThemeData::populateThemeSets()
|
|||
}
|
||||
|
||||
#if defined(_WIN64)
|
||||
LOG(LogInfo) << "Added" << (capabilities.legacyTheme ? " legacy" : "")
|
||||
<< " theme set \"" << Utils::String::replace(*it, "/", "\\") << "\""
|
||||
<< themeName;
|
||||
LOG(LogInfo) << "Added theme set \"" << Utils::String::replace(*it, "/", "\\")
|
||||
<< "\"" << themeName;
|
||||
#else
|
||||
LOG(LogInfo) << "Added" << (capabilities.legacyTheme ? " legacy" : "")
|
||||
<< " theme set \"" << *it << "\"" << themeName;
|
||||
LOG(LogInfo) << "Added theme set \"" << *it << "\"" << themeName;
|
||||
#endif
|
||||
if (!capabilities.legacyTheme) {
|
||||
int aspectRatios {0};
|
||||
if (capabilities.aspectRatios.size() > 0)
|
||||
aspectRatios = static_cast<int>(capabilities.aspectRatios.size()) - 1;
|
||||
LOG(LogDebug) << "Theme set includes support for "
|
||||
<< capabilities.variants.size() << " variant"
|
||||
<< (capabilities.variants.size() != 1 ? "s" : "") << ", "
|
||||
<< capabilities.colorSchemes.size() << " color scheme"
|
||||
<< (capabilities.colorSchemes.size() != 1 ? "s" : "") << ", "
|
||||
<< aspectRatios << " aspect ratio"
|
||||
<< (aspectRatios != 1 ? "s" : "") << " and "
|
||||
<< capabilities.transitions.size() << " transition"
|
||||
<< (capabilities.transitions.size() != 1 ? "s" : "");
|
||||
}
|
||||
int aspectRatios {0};
|
||||
if (capabilities.aspectRatios.size() > 0)
|
||||
aspectRatios = static_cast<int>(capabilities.aspectRatios.size()) - 1;
|
||||
LOG(LogDebug) << "Theme set includes support for " << capabilities.variants.size()
|
||||
<< " variant" << (capabilities.variants.size() != 1 ? "s" : "")
|
||||
<< ", " << capabilities.colorSchemes.size() << " color scheme"
|
||||
<< (capabilities.colorSchemes.size() != 1 ? "s" : "") << ", "
|
||||
<< aspectRatios << " aspect ratio" << (aspectRatios != 1 ? "s" : "")
|
||||
<< " and " << capabilities.transitions.size() << " transition"
|
||||
<< (capabilities.transitions.size() != 1 ? "s" : "");
|
||||
|
||||
ThemeSet set {*it, capabilities};
|
||||
sThemeSets[set.getName()] = set;
|
||||
}
|
||||
|
@ -958,77 +804,63 @@ void ThemeData::setThemeTransitions()
|
|||
int transitionAnim {ViewTransitionAnimation::INSTANT};
|
||||
setTransitionsFunc(transitionAnim);
|
||||
|
||||
if (sCurrentThemeSet->second.capabilities.legacyTheme) {
|
||||
const std::string& legacyTransitionsSetting {
|
||||
Settings::getInstance()->getString("LegacyThemeTransitions")};
|
||||
if (legacyTransitionsSetting == "builtin-slide")
|
||||
transitionAnim = static_cast<int>(ViewTransitionAnimation::SLIDE);
|
||||
else if (legacyTransitionsSetting == "builtin-fade")
|
||||
transitionAnim = static_cast<int>(ViewTransitionAnimation::FADE);
|
||||
setTransitionsFunc(transitionAnim);
|
||||
const std::string& transitionsSetting {Settings::getInstance()->getString("ThemeTransitions")};
|
||||
std::string profile;
|
||||
size_t profileEntry {0};
|
||||
|
||||
if (transitionsSetting == "automatic") {
|
||||
if (sVariantDefinedTransitions != "")
|
||||
profile = sVariantDefinedTransitions;
|
||||
else if (!sCurrentThemeSet->second.capabilities.transitions.empty())
|
||||
profile = sCurrentThemeSet->second.capabilities.transitions.front().name;
|
||||
}
|
||||
else {
|
||||
const std::string& transitionsSetting {
|
||||
Settings::getInstance()->getString("ThemeTransitions")};
|
||||
std::string profile;
|
||||
size_t profileEntry {0};
|
||||
profile = transitionsSetting;
|
||||
}
|
||||
|
||||
if (transitionsSetting == "automatic") {
|
||||
if (sVariantDefinedTransitions != "")
|
||||
profile = sVariantDefinedTransitions;
|
||||
else if (!sCurrentThemeSet->second.capabilities.transitions.empty())
|
||||
profile = sCurrentThemeSet->second.capabilities.transitions.front().name;
|
||||
}
|
||||
else {
|
||||
profile = transitionsSetting;
|
||||
}
|
||||
auto it = std::find_if(
|
||||
sCurrentThemeSet->second.capabilities.transitions.cbegin(),
|
||||
sCurrentThemeSet->second.capabilities.transitions.cend(),
|
||||
[&profile](const ThemeTransitions transitions) { return transitions.name == profile; });
|
||||
if (it != sCurrentThemeSet->second.capabilities.transitions.cend())
|
||||
profileEntry = static_cast<size_t>(
|
||||
std::distance(sCurrentThemeSet->second.capabilities.transitions.cbegin(), it) + 1);
|
||||
|
||||
auto it = std::find_if(
|
||||
sCurrentThemeSet->second.capabilities.transitions.cbegin(),
|
||||
sCurrentThemeSet->second.capabilities.transitions.cend(),
|
||||
[&profile](const ThemeTransitions transitions) { return transitions.name == profile; });
|
||||
if (it != sCurrentThemeSet->second.capabilities.transitions.cend())
|
||||
profileEntry = static_cast<size_t>(
|
||||
std::distance(sCurrentThemeSet->second.capabilities.transitions.cbegin(), it) + 1);
|
||||
|
||||
if (profileEntry != 0 &&
|
||||
sCurrentThemeSet->second.capabilities.transitions.size() > profileEntry - 1) {
|
||||
auto transitionMap =
|
||||
sCurrentThemeSet->second.capabilities.transitions[profileEntry - 1].animations;
|
||||
if (transitionMap.find(ViewTransition::SYSTEM_TO_SYSTEM) != transitionMap.end())
|
||||
Settings::getInstance()->setInt("TransitionsSystemToSystem",
|
||||
transitionMap[ViewTransition::SYSTEM_TO_SYSTEM]);
|
||||
if (transitionMap.find(ViewTransition::SYSTEM_TO_GAMELIST) != transitionMap.end())
|
||||
Settings::getInstance()->setInt("TransitionsSystemToGamelist",
|
||||
transitionMap[ViewTransition::SYSTEM_TO_GAMELIST]);
|
||||
if (transitionMap.find(ViewTransition::GAMELIST_TO_GAMELIST) != transitionMap.end())
|
||||
Settings::getInstance()->setInt(
|
||||
"TransitionsGamelistToGamelist",
|
||||
transitionMap[ViewTransition::GAMELIST_TO_GAMELIST]);
|
||||
if (transitionMap.find(ViewTransition::GAMELIST_TO_SYSTEM) != transitionMap.end())
|
||||
Settings::getInstance()->setInt("TransitionsGamelistToSystem",
|
||||
transitionMap[ViewTransition::GAMELIST_TO_SYSTEM]);
|
||||
if (transitionMap.find(ViewTransition::STARTUP_TO_SYSTEM) != transitionMap.end())
|
||||
Settings::getInstance()->setInt("TransitionsStartupToSystem",
|
||||
transitionMap[ViewTransition::STARTUP_TO_SYSTEM]);
|
||||
if (transitionMap.find(ViewTransition::STARTUP_TO_GAMELIST) != transitionMap.end())
|
||||
Settings::getInstance()->setInt("TransitionsStartupToGamelist",
|
||||
transitionMap[ViewTransition::STARTUP_TO_GAMELIST]);
|
||||
}
|
||||
else if (transitionsSetting == "builtin-slide" || transitionsSetting == "builtin-fade") {
|
||||
if (std::find(
|
||||
sCurrentThemeSet->second.capabilities.suppressedTransitionProfiles.cbegin(),
|
||||
sCurrentThemeSet->second.capabilities.suppressedTransitionProfiles.cend(),
|
||||
transitionsSetting) ==
|
||||
sCurrentThemeSet->second.capabilities.suppressedTransitionProfiles.cend()) {
|
||||
if (transitionsSetting == "builtin-slide") {
|
||||
transitionAnim = static_cast<int>(ViewTransitionAnimation::SLIDE);
|
||||
}
|
||||
else if (transitionsSetting == "builtin-fade") {
|
||||
transitionAnim = static_cast<int>(ViewTransitionAnimation::FADE);
|
||||
}
|
||||
setTransitionsFunc(transitionAnim);
|
||||
if (profileEntry != 0 &&
|
||||
sCurrentThemeSet->second.capabilities.transitions.size() > profileEntry - 1) {
|
||||
auto transitionMap =
|
||||
sCurrentThemeSet->second.capabilities.transitions[profileEntry - 1].animations;
|
||||
if (transitionMap.find(ViewTransition::SYSTEM_TO_SYSTEM) != transitionMap.end())
|
||||
Settings::getInstance()->setInt("TransitionsSystemToSystem",
|
||||
transitionMap[ViewTransition::SYSTEM_TO_SYSTEM]);
|
||||
if (transitionMap.find(ViewTransition::SYSTEM_TO_GAMELIST) != transitionMap.end())
|
||||
Settings::getInstance()->setInt("TransitionsSystemToGamelist",
|
||||
transitionMap[ViewTransition::SYSTEM_TO_GAMELIST]);
|
||||
if (transitionMap.find(ViewTransition::GAMELIST_TO_GAMELIST) != transitionMap.end())
|
||||
Settings::getInstance()->setInt("TransitionsGamelistToGamelist",
|
||||
transitionMap[ViewTransition::GAMELIST_TO_GAMELIST]);
|
||||
if (transitionMap.find(ViewTransition::GAMELIST_TO_SYSTEM) != transitionMap.end())
|
||||
Settings::getInstance()->setInt("TransitionsGamelistToSystem",
|
||||
transitionMap[ViewTransition::GAMELIST_TO_SYSTEM]);
|
||||
if (transitionMap.find(ViewTransition::STARTUP_TO_SYSTEM) != transitionMap.end())
|
||||
Settings::getInstance()->setInt("TransitionsStartupToSystem",
|
||||
transitionMap[ViewTransition::STARTUP_TO_SYSTEM]);
|
||||
if (transitionMap.find(ViewTransition::STARTUP_TO_GAMELIST) != transitionMap.end())
|
||||
Settings::getInstance()->setInt("TransitionsStartupToGamelist",
|
||||
transitionMap[ViewTransition::STARTUP_TO_GAMELIST]);
|
||||
}
|
||||
else if (transitionsSetting == "builtin-slide" || transitionsSetting == "builtin-fade") {
|
||||
if (std::find(sCurrentThemeSet->second.capabilities.suppressedTransitionProfiles.cbegin(),
|
||||
sCurrentThemeSet->second.capabilities.suppressedTransitionProfiles.cend(),
|
||||
transitionsSetting) ==
|
||||
sCurrentThemeSet->second.capabilities.suppressedTransitionProfiles.cend()) {
|
||||
if (transitionsSetting == "builtin-slide") {
|
||||
transitionAnim = static_cast<int>(ViewTransitionAnimation::SLIDE);
|
||||
}
|
||||
else if (transitionsSetting == "builtin-fade") {
|
||||
transitionAnim = static_cast<int>(ViewTransitionAnimation::FADE);
|
||||
}
|
||||
setTransitionsFunc(transitionAnim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1050,20 +882,15 @@ ThemeData::getCurrentThemeSetSelectedVariantOverrides()
|
|||
|
||||
const void ThemeData::themeLoadedLogOutput()
|
||||
{
|
||||
if (sCurrentThemeSet->second.capabilities.legacyTheme) {
|
||||
LOG(LogInfo) << "Finished loading legacy theme set \"" << sCurrentThemeSet->first << "\"";
|
||||
}
|
||||
else {
|
||||
LOG(LogInfo) << "Finished loading theme set \"" << sCurrentThemeSet->first << "\"";
|
||||
if (sSelectedAspectRatio != "") {
|
||||
const bool autoDetect {Settings::getInstance()->getString("ThemeAspectRatio") ==
|
||||
"automatic"};
|
||||
const std::string match {sAspectRatioMatch ? "exact match " : "closest match "};
|
||||
LOG(LogInfo) << "Finished loading theme set \"" << sCurrentThemeSet->first << "\"";
|
||||
if (sSelectedAspectRatio != "") {
|
||||
const bool autoDetect {Settings::getInstance()->getString("ThemeAspectRatio") ==
|
||||
"automatic"};
|
||||
const std::string match {sAspectRatioMatch ? "exact match " : "closest match "};
|
||||
|
||||
LOG(LogInfo) << "Aspect ratio " << (autoDetect ? "automatically " : "manually ")
|
||||
<< "set to " << (autoDetect ? match : "") << "\""
|
||||
<< Utils::String::replace(sSelectedAspectRatio, "_", " ") << "\"";
|
||||
}
|
||||
LOG(LogInfo) << "Aspect ratio " << (autoDetect ? "automatically " : "manually ")
|
||||
<< "set to " << (autoDetect ? match : "") << "\""
|
||||
<< Utils::String::replace(sSelectedAspectRatio, "_", " ") << "\"";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1117,7 +944,7 @@ ThemeData::ThemeCapability ThemeData::parseThemeCapabilities(const std::string&
|
|||
const std::string capFile {path + "/capabilities.xml"};
|
||||
|
||||
if (Utils::FileSystem::isRegularFile(capFile) || Utils::FileSystem::isSymlink(capFile)) {
|
||||
capabilities.legacyTheme = false;
|
||||
capabilities.validTheme = true;
|
||||
|
||||
pugi::xml_document doc;
|
||||
#if defined(_WIN64)
|
||||
|
@ -1519,8 +1346,10 @@ ThemeData::ThemeCapability ThemeData::parseThemeCapabilities(const std::string&
|
|||
}
|
||||
}
|
||||
else {
|
||||
LOG(LogDebug) << "No capabilities.xml file found, flagging as legacy theme set";
|
||||
capabilities.legacyTheme = true;
|
||||
capabilities.validTheme = false;
|
||||
LOG(LogWarning)
|
||||
<< "No capabilities.xml file found, this does not appear to be a valid theme set: \""
|
||||
<< path << "\"";
|
||||
}
|
||||
|
||||
// Add the aspect ratios in the order they are defined in sSupportedAspectRatios so they
|
||||
|
@ -1568,10 +1397,9 @@ void ThemeData::parseIncludes(const pugi::xml_node& root)
|
|||
error << "ThemeData::parseIncludes(): ";
|
||||
error.setFiles(mPaths);
|
||||
|
||||
if (!mLegacyTheme) {
|
||||
if (root.child("formatVersion").text().as_int(-1) != -1)
|
||||
throw error << ": Legacy <formatVersion> tag found for non-legacy theme set";
|
||||
}
|
||||
// Check for legacy theme version.
|
||||
if (root.child("formatVersion") != nullptr)
|
||||
throw error << ": Legacy <formatVersion> tag found";
|
||||
|
||||
for (pugi::xml_node node {root.child("include")}; node; node = node.next_sibling("include")) {
|
||||
std::string relPath {resolvePlaceholders(node.text().as_string())};
|
||||
|
@ -1624,49 +1452,20 @@ void ThemeData::parseIncludes(const pugi::xml_node& root)
|
|||
if (!theme)
|
||||
throw error << ": Missing <theme> tag";
|
||||
|
||||
if (!mLegacyTheme)
|
||||
parseTransitions(theme);
|
||||
parseTransitions(theme);
|
||||
parseVariables(theme);
|
||||
if (!mLegacyTheme)
|
||||
parseColorSchemes(theme);
|
||||
|
||||
parseColorSchemes(theme);
|
||||
parseIncludes(theme);
|
||||
parseViews(theme);
|
||||
// For non-legacy themes this will simply check for the presence of a feature tag and throw
|
||||
// an error if it's found.
|
||||
parseFeatures(theme);
|
||||
|
||||
if (!mLegacyTheme) {
|
||||
parseVariants(theme);
|
||||
parseAspectRatios(theme);
|
||||
}
|
||||
if (theme.child("feature") != nullptr)
|
||||
throw error << ": Legacy <feature> tag found";
|
||||
parseVariants(theme);
|
||||
parseAspectRatios(theme);
|
||||
|
||||
mPaths.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void ThemeData::parseFeatures(const pugi::xml_node& root)
|
||||
{
|
||||
ThemeException error;
|
||||
error << "ThemeData::parseFeatures(): ";
|
||||
error.setFiles(mPaths);
|
||||
|
||||
if (!mLegacyTheme && root.child("feature") != nullptr)
|
||||
throw error << ": Legacy <feature> tag found for non-legacy theme set";
|
||||
|
||||
for (pugi::xml_node node {root.child("feature")}; node; node = node.next_sibling("feature")) {
|
||||
if (!node.attribute("supported"))
|
||||
throw error << ": Feature missing \"supported\" attribute";
|
||||
|
||||
const std::string supportedAttr {node.attribute("supported").as_string()};
|
||||
|
||||
if (std::find(sLegacySupportedFeatures.cbegin(), sLegacySupportedFeatures.cend(),
|
||||
supportedAttr) != sLegacySupportedFeatures.cend()) {
|
||||
parseViews(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThemeData::parseVariants(const pugi::xml_node& root)
|
||||
{
|
||||
if (sCurrentThemeSet == sThemeSets.end())
|
||||
|
@ -1830,8 +1629,7 @@ void ThemeData::parseVariables(const pugi::xml_node& root)
|
|||
const std::string val {resolvePlaceholders(it->text().as_string())};
|
||||
|
||||
if (!val.empty()) {
|
||||
// Overriding existing variables is not allowed for legacy themes.
|
||||
if (!mLegacyTheme && mVariables.find(key) != mVariables.end())
|
||||
if (mVariables.find(key) != mVariables.end())
|
||||
mVariables[key] = val;
|
||||
else
|
||||
mVariables.insert(std::pair<std::string, std::string>(key, val));
|
||||
|
@ -1861,29 +1659,15 @@ void ThemeData::parseViews(const pugi::xml_node& root)
|
|||
prevOff = nameAttr.find_first_not_of(delim, off);
|
||||
off = nameAttr.find_first_of(delim, prevOff);
|
||||
|
||||
if (mLegacyTheme) {
|
||||
if (std::find(sLegacySupportedViews.cbegin(), sLegacySupportedViews.cend(),
|
||||
viewKey) != sLegacySupportedViews.cend()) {
|
||||
ThemeView& view {
|
||||
mViews.insert(std::pair<std::string, ThemeView>(viewKey, ThemeView()))
|
||||
.first->second};
|
||||
parseView(node, view);
|
||||
}
|
||||
else {
|
||||
throw error << ": Unsupported \"" << viewKey << "\" view style defined";
|
||||
}
|
||||
if (std::find(sSupportedViews.cbegin(), sSupportedViews.cend(), viewKey) !=
|
||||
sSupportedViews.cend()) {
|
||||
ThemeView& view {
|
||||
mViews.insert(std::pair<std::string, ThemeView>(viewKey, ThemeView()))
|
||||
.first->second};
|
||||
parseView(node, view);
|
||||
}
|
||||
else {
|
||||
if (std::find(sSupportedViews.cbegin(), sSupportedViews.cend(), viewKey) !=
|
||||
sSupportedViews.cend()) {
|
||||
ThemeView& view {
|
||||
mViews.insert(std::pair<std::string, ThemeView>(viewKey, ThemeView()))
|
||||
.first->second};
|
||||
parseView(node, view);
|
||||
}
|
||||
else {
|
||||
throw error << ": Unsupported \"" << viewKey << "\" view style defined";
|
||||
}
|
||||
throw error << ": Unsupported \"" << viewKey << "\" view style defined";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1913,75 +1697,29 @@ void ThemeData::parseView(const pugi::xml_node& root, ThemeView& view)
|
|||
off = nameAttr.find_first_of(delim, prevOff);
|
||||
|
||||
// Add the element type as a prefix to avoid name collisions between different
|
||||
// component types. Also include workarounds for legacy theme sets for when the
|
||||
// fixed labels have been defined with the wrong element type.
|
||||
const std::string elementType {node.name()};
|
||||
LegacyWorkaround legacyWorkaround {LegacyWorkaround::NONE};
|
||||
|
||||
if (mLegacyTheme && elementType == "text" &&
|
||||
(elemKey == "md_releasedate" || elemKey == "md_lastplayed")) {
|
||||
LOG(LogDebug) << "ThemeData::parseView(): Element type for \"" << elemKey
|
||||
<< "\" incorrectly set to \"text\" "
|
||||
"instead of \"datetime\", applying workaround";
|
||||
legacyWorkaround = LegacyWorkaround::DATETIME;
|
||||
elemKey = "datetime_" + elemKey;
|
||||
}
|
||||
else if (mLegacyTheme && elementType == "datetime" &&
|
||||
(elemKey == "md_lbl_releasedate" || elemKey == "md_lbl_lastplayed")) {
|
||||
LOG(LogDebug) << "ThemeData::parseView(): Element type for \"" << elemKey
|
||||
<< "\" incorrectly set to \"datetime\" "
|
||||
"instead of \"text\", applying workaround";
|
||||
legacyWorkaround = LegacyWorkaround::TEXT;
|
||||
elemKey = "text_" + elemKey;
|
||||
}
|
||||
else if (mLegacyTheme && elementType == "text" && elemKey == "md_rating") {
|
||||
LOG(LogDebug) << "ThemeData::parseView(): Element type for \"" << elemKey
|
||||
<< "\" incorrectly set to \"text\" "
|
||||
"instead of \"rating\", applying workaround";
|
||||
legacyWorkaround = LegacyWorkaround::RATING;
|
||||
elemKey = "rating_" + elemKey;
|
||||
}
|
||||
else {
|
||||
elemKey = elementType + "_" + elemKey;
|
||||
}
|
||||
// component types.
|
||||
elemKey = std::string {node.name()} + "_" + elemKey;
|
||||
|
||||
parseElement(
|
||||
node, elemTypeIt->second,
|
||||
view.elements.insert(std::pair<std::string, ThemeElement>(elemKey, ThemeElement()))
|
||||
.first->second,
|
||||
legacyWorkaround);
|
||||
|
||||
if (mLegacyTheme &&
|
||||
std::find(view.legacyOrderedKeys.cbegin(), view.legacyOrderedKeys.cend(),
|
||||
elemKey) == view.legacyOrderedKeys.cend())
|
||||
view.legacyOrderedKeys.push_back(elemKey);
|
||||
.first->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThemeData::parseElement(const pugi::xml_node& root,
|
||||
const std::map<std::string, ElementPropertyType>& typeMap,
|
||||
ThemeElement& element,
|
||||
const LegacyWorkaround legacyWorkaround)
|
||||
ThemeElement& element)
|
||||
{
|
||||
ThemeException error;
|
||||
error << "ThemeData::parseElement(): ";
|
||||
error.setFiles(mPaths);
|
||||
element.type = root.name();
|
||||
|
||||
if (legacyWorkaround == LegacyWorkaround::DATETIME)
|
||||
element.type = "datetime";
|
||||
else if (legacyWorkaround == LegacyWorkaround::TEXT)
|
||||
element.type = "text";
|
||||
else if (legacyWorkaround == LegacyWorkaround::RATING)
|
||||
element.type = "rating";
|
||||
else
|
||||
element.type = root.name();
|
||||
|
||||
element.extra = root.attribute("extra").as_bool(false);
|
||||
if (mLegacyTheme)
|
||||
element.extra = root.attribute("extra").as_bool(false);
|
||||
else if (!mLegacyTheme && std::string(root.attribute("extra").as_string("")) != "")
|
||||
throw error << ": Legacy \"extra\" attribute found for non-legacy theme set";
|
||||
if (root.attribute("extra") != nullptr)
|
||||
throw error << ": Legacy \"extra\" attribute found for element of type \"" << element.type
|
||||
<< "\"";
|
||||
|
||||
for (pugi::xml_node node {root.first_child()}; node; node = node.next_sibling()) {
|
||||
auto typeIt = typeMap.find(node.name());
|
||||
|
@ -1996,27 +1734,15 @@ void ThemeData::parseElement(const pugi::xml_node& root,
|
|||
// exist at the same time. A backspace is assigned in SystemData to flag the
|
||||
// variables that do not apply and if it's encountered here we simply skip the
|
||||
// property.
|
||||
if (!mLegacyTheme && str == "\b")
|
||||
if (str == "\b")
|
||||
continue;
|
||||
|
||||
// Skip this check for legacy themes to not break backward compatibility with some
|
||||
// themes sets that include empty property values.
|
||||
if (!mLegacyTheme && str == "")
|
||||
// Strictly enforce that there are no blank values in the theme configuration.
|
||||
if (str == "")
|
||||
throw error << ": Property \"" << typeIt->first << "\" for element \"" << element.type
|
||||
<< "\" has no value defined";
|
||||
|
||||
std::string nodeName = node.name();
|
||||
|
||||
// Strictly enforce removal of legacy properties for non-legacy theme sets by creating
|
||||
// an unthemed system if they're present in the configuration.
|
||||
if (!mLegacyTheme) {
|
||||
for (auto& legacyProperty : sLegacyProperties) {
|
||||
if (nodeName == legacyProperty) {
|
||||
throw error << ": Legacy <" << nodeName
|
||||
<< "> property found for non-legacy theme set";
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string nodeName {node.name()};
|
||||
|
||||
// If an attribute exists, then replace nodeName with its name.
|
||||
auto attributeEntry = sPropertyAttributeMap.find(element.type);
|
||||
|
|
|
@ -24,18 +24,6 @@
|
|||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
namespace pugi
|
||||
{
|
||||
class xml_node;
|
||||
}
|
||||
|
||||
class GuiComponent;
|
||||
class ImageComponent;
|
||||
class NinePatchComponent;
|
||||
class Sound;
|
||||
class TextComponent;
|
||||
class Window;
|
||||
|
||||
namespace ThemeFlags
|
||||
{
|
||||
// clang-format off
|
||||
|
@ -53,15 +41,14 @@ namespace ThemeFlags
|
|||
TEXT = 0x00000100,
|
||||
METADATA = 0x00000200,
|
||||
LETTER_CASE = 0x00000400,
|
||||
FORCE_UPPERCASE = 0x00000800, // For backward compatibility with legacy themes.
|
||||
LINE_SPACING = 0x00001000,
|
||||
DELAY = 0x00002000,
|
||||
Z_INDEX = 0x00004000,
|
||||
ROTATION = 0x00008000,
|
||||
BRIGHTNESS = 0x00010000,
|
||||
OPACITY = 0x00020000,
|
||||
SATURATION = 0x00040000,
|
||||
VISIBLE = 0x00080000,
|
||||
LINE_SPACING = 0x00000800,
|
||||
DELAY = 0x00001000,
|
||||
Z_INDEX = 0x00002000,
|
||||
ROTATION = 0x00004000,
|
||||
BRIGHTNESS = 0x00008000,
|
||||
OPACITY = 0x00010000,
|
||||
SATURATION = 0x00020000,
|
||||
VISIBLE = 0x00040000,
|
||||
ALL = 0xFFFFFFFF
|
||||
};
|
||||
// clang-format on
|
||||
|
@ -107,7 +94,6 @@ public:
|
|||
class ThemeElement
|
||||
{
|
||||
public:
|
||||
bool extra;
|
||||
std::string type;
|
||||
|
||||
struct Property {
|
||||
|
@ -162,7 +148,6 @@ public:
|
|||
{
|
||||
public:
|
||||
std::map<std::string, ThemeElement> elements;
|
||||
std::vector<std::string> legacyOrderedKeys;
|
||||
};
|
||||
|
||||
struct ThemeVariant {
|
||||
|
@ -202,7 +187,7 @@ public:
|
|||
std::vector<std::string> aspectRatios;
|
||||
std::vector<ThemeTransitions> transitions;
|
||||
std::vector<std::string> suppressedTransitionProfiles;
|
||||
bool legacyTheme;
|
||||
bool validTheme;
|
||||
};
|
||||
|
||||
struct ThemeSet {
|
||||
|
@ -230,9 +215,6 @@ public:
|
|||
bool hasView(const std::string& view);
|
||||
ThemeView& getViewElements(std::string view) { return mViews[view]; }
|
||||
|
||||
static std::vector<GuiComponent*> makeExtras(const std::shared_ptr<ThemeData>& theme,
|
||||
const std::string& view);
|
||||
|
||||
const ThemeElement* getElement(const std::string& view,
|
||||
const std::string& element,
|
||||
const std::string& expectedType) const;
|
||||
|
@ -247,7 +229,6 @@ public:
|
|||
const static std::string getCurrentThemeSetName() { return sCurrentThemeSet->first; }
|
||||
static void setThemeTransitions();
|
||||
|
||||
const bool isLegacyTheme() { return mLegacyTheme; }
|
||||
const std::map<ThemeTriggers::TriggerType, std::pair<std::string, std::vector<std::string>>>
|
||||
getCurrentThemeSetSelectedVariantOverrides();
|
||||
const static void themeLoadedLogOutput();
|
||||
|
@ -266,20 +247,12 @@ public:
|
|||
std::map<std::string, std::string> mVariables;
|
||||
|
||||
private:
|
||||
enum class LegacyWorkaround {
|
||||
NONE = 0x00000000,
|
||||
TEXT = 0x00000001,
|
||||
DATETIME = 0x00000002,
|
||||
RATING = 0x00000004
|
||||
};
|
||||
|
||||
unsigned int getHexColor(const std::string& str);
|
||||
std::string resolvePlaceholders(const std::string& in);
|
||||
|
||||
static ThemeCapability parseThemeCapabilities(const std::string& path);
|
||||
|
||||
void parseIncludes(const pugi::xml_node& root);
|
||||
void parseFeatures(const pugi::xml_node& root);
|
||||
void parseVariants(const pugi::xml_node& root);
|
||||
void parseColorSchemes(const pugi::xml_node& root);
|
||||
void parseAspectRatios(const pugi::xml_node& root);
|
||||
|
@ -289,16 +262,12 @@ private:
|
|||
void parseView(const pugi::xml_node& root, ThemeView& view);
|
||||
void parseElement(const pugi::xml_node& root,
|
||||
const std::map<std::string, ElementPropertyType>& typeMap,
|
||||
ThemeElement& element,
|
||||
const LegacyWorkaround legacyWorkaround);
|
||||
ThemeElement& element);
|
||||
|
||||
static std::vector<std::string> sSupportedViews;
|
||||
static std::vector<std::string> sSupportedMediaTypes;
|
||||
static std::vector<std::string> sSupportedTransitions;
|
||||
static std::vector<std::string> sSupportedTransitionAnimations;
|
||||
static std::vector<std::string> sLegacySupportedViews;
|
||||
static std::vector<std::string> sLegacySupportedFeatures;
|
||||
static std::vector<std::string> sLegacyProperties;
|
||||
static std::vector<std::pair<std::string, std::string>> sSupportedAspectRatios;
|
||||
static std::map<std::string, float> sAspectRatioMap;
|
||||
|
||||
|
@ -318,7 +287,6 @@ private:
|
|||
std::string mSelectedColorScheme;
|
||||
static inline std::string sSelectedAspectRatio;
|
||||
static inline bool sAspectRatioMatch {false};
|
||||
bool mLegacyTheme;
|
||||
bool mCustomCollection;
|
||||
};
|
||||
|
||||
|
|
|
@ -228,18 +228,6 @@ void BadgeComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
mFlexboxComponent.setAlignment(horizontalAlignment);
|
||||
}
|
||||
}
|
||||
// Legacy themes only.
|
||||
else if (elem->has("alignment")) {
|
||||
const std::string alignment {elem->get<std::string>("alignment")};
|
||||
if (alignment != "left" && alignment != "right") {
|
||||
LOG(LogWarning) << "BadgeComponent: Invalid theme configuration, property \"alignment\""
|
||||
" for element \""
|
||||
<< element.substr(7) << "\" defined as \"" << alignment << "\"";
|
||||
}
|
||||
else {
|
||||
mFlexboxComponent.setAlignment(alignment);
|
||||
}
|
||||
}
|
||||
|
||||
if (elem->has("direction")) {
|
||||
const std::string direction {elem->get<std::string>("direction")};
|
||||
|
|
|
@ -165,21 +165,6 @@ void DateTimeComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
<< verticalAlignment << "\"";
|
||||
}
|
||||
|
||||
// Legacy themes only.
|
||||
if (properties & ALIGNMENT && elem->has("alignment")) {
|
||||
const std::string& alignment {elem->get<std::string>("alignment")};
|
||||
if (alignment == "left")
|
||||
setHorizontalAlignment(ALIGN_LEFT);
|
||||
else if (alignment == "center")
|
||||
setHorizontalAlignment(ALIGN_CENTER);
|
||||
else if (alignment == "right")
|
||||
setHorizontalAlignment(ALIGN_RIGHT);
|
||||
else
|
||||
LOG(LogWarning) << "DateTimeComponent: Invalid theme configuration, property "
|
||||
"<alignment> defined as \""
|
||||
<< alignment << "\"";
|
||||
}
|
||||
|
||||
if (properties & METADATA && elem->has("metadata")) {
|
||||
mThemeMetadata = "";
|
||||
const std::string& metadata {elem->get<std::string>("metadata")};
|
||||
|
@ -226,18 +211,14 @@ void DateTimeComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
|
||||
float maxHeight {0.0f};
|
||||
|
||||
if (!theme->isLegacyTheme() && elem->has("size")) {
|
||||
if (elem->has("size")) {
|
||||
const glm::vec2 size {elem->get<glm::vec2>("size")};
|
||||
if (size.x != 0.0f && size.y != 0.0f)
|
||||
maxHeight = mSize.y * 2.0f;
|
||||
}
|
||||
|
||||
// Legacy themes only.
|
||||
if (properties & FORCE_UPPERCASE && elem->has("forceUppercase"))
|
||||
setUppercase(elem->get<bool>("forceUppercase"));
|
||||
|
||||
if (properties & LINE_SPACING && elem->has("lineSpacing"))
|
||||
setLineSpacing(glm::clamp(elem->get<float>("lineSpacing"), 0.5f, 3.0f));
|
||||
|
||||
setFont(Font::getFromTheme(elem, properties, mFont, maxHeight, false, theme->isLegacyTheme()));
|
||||
setFont(Font::getFromTheme(elem, properties, mFont, maxHeight, false));
|
||||
}
|
||||
|
|
|
@ -306,13 +306,7 @@ void HelpComponent::updateGrid()
|
|||
mGrid->setEntry(labels.at(i), glm::ivec2 {col + 2, 0}, false, false);
|
||||
}
|
||||
|
||||
// There is a bug for legacy themes where the entrySpacing width is added to the right of
|
||||
// the grid when aligning to the right using an X origin value of 1. This issue is retained
|
||||
// for legacy themes for backward compatibility reasons.
|
||||
if (mStyle.legacyTheme) {
|
||||
mGrid->setPosition({mStyle.position.x, mStyle.position.y, 0.0f});
|
||||
}
|
||||
else if (isDimmed) {
|
||||
if (isDimmed) {
|
||||
mGrid->setPosition(
|
||||
{mStyle.positionDimmed.x + ((mStyle.entrySpacingDimmed * mRenderer->getScreenWidth()) *
|
||||
mStyle.originDimmed.x),
|
||||
|
|
|
@ -32,7 +32,6 @@ TextComponent::TextComponent()
|
|||
, mNoTopMargin {false}
|
||||
, mSelectable {false}
|
||||
, mVerticalAutoSizing {false}
|
||||
, mLegacyTheme {false}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -63,7 +62,6 @@ TextComponent::TextComponent(const std::string& text,
|
|||
, mNoTopMargin {false}
|
||||
, mSelectable {false}
|
||||
, mVerticalAutoSizing {false}
|
||||
, mLegacyTheme {false}
|
||||
{
|
||||
setFont(font);
|
||||
setColor(color);
|
||||
|
@ -298,9 +296,6 @@ void TextComponent::onTextChanged()
|
|||
// Used to initialize all glyphs, which is needed to populate mMaxGlyphHeight.
|
||||
lineHeight = mFont->loadGlyphs(text + "\n") * mLineSpacing;
|
||||
|
||||
if (mLegacyTheme)
|
||||
font->useLegacyMaxGlyphHeight();
|
||||
|
||||
const bool isMultiline {mAutoCalcExtent.y == 1 || mSize.y > lineHeight};
|
||||
|
||||
if (isMultiline && !isScrollable) {
|
||||
|
@ -367,8 +362,6 @@ void TextComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
using namespace ThemeFlags;
|
||||
GuiComponent::applyTheme(theme, view, element, properties);
|
||||
|
||||
mLegacyTheme = theme->isLegacyTheme();
|
||||
|
||||
std::string elementType {"text"};
|
||||
std::string componentName {"TextComponent"};
|
||||
|
||||
|
@ -424,22 +417,6 @@ void TextComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
<< element.substr(5) << "\" defined as \"" << verticalAlignment << "\"";
|
||||
}
|
||||
|
||||
// Legacy themes only.
|
||||
if (properties & ALIGNMENT && elem->has("alignment")) {
|
||||
const std::string& alignment {elem->get<std::string>("alignment")};
|
||||
if (alignment == "left")
|
||||
setHorizontalAlignment(ALIGN_LEFT);
|
||||
else if (alignment == "center")
|
||||
setHorizontalAlignment(ALIGN_CENTER);
|
||||
else if (alignment == "right")
|
||||
setHorizontalAlignment(ALIGN_RIGHT);
|
||||
else
|
||||
LOG(LogWarning) << componentName
|
||||
<< ": Invalid theme configuration, property "
|
||||
"\"alignment\" for element \""
|
||||
<< element.substr(5) << "\" defined as \"" << alignment << "\"";
|
||||
}
|
||||
|
||||
if (properties & TEXT && elem->has("text"))
|
||||
setText(elem->get<std::string>("text"));
|
||||
|
||||
|
@ -540,18 +517,14 @@ void TextComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
|
||||
float maxHeight {0.0f};
|
||||
|
||||
if (!theme->isLegacyTheme() && elem->has("size")) {
|
||||
if (elem->has("size")) {
|
||||
const glm::vec2 size {elem->get<glm::vec2>("size")};
|
||||
if (size.x != 0.0f && size.y != 0.0f)
|
||||
maxHeight = mSize.y * 2.0f;
|
||||
}
|
||||
|
||||
// Legacy themes only.
|
||||
if (properties & FORCE_UPPERCASE && elem->has("forceUppercase"))
|
||||
setUppercase(elem->get<bool>("forceUppercase"));
|
||||
|
||||
if (properties & LINE_SPACING && elem->has("lineSpacing"))
|
||||
setLineSpacing(glm::clamp(elem->get<float>("lineSpacing"), 0.5f, 3.0f));
|
||||
|
||||
setFont(Font::getFromTheme(elem, properties, mFont, maxHeight, false, theme->isLegacyTheme()));
|
||||
setFont(Font::getFromTheme(elem, properties, mFont, maxHeight, false));
|
||||
}
|
||||
|
|
|
@ -131,7 +131,6 @@ private:
|
|||
bool mNoTopMargin;
|
||||
bool mSelectable;
|
||||
bool mVerticalAutoSizing;
|
||||
bool mLegacyTheme;
|
||||
};
|
||||
|
||||
#endif // ES_CORE_COMPONENTS_TEXT_COMPONENT_H
|
||||
|
|
|
@ -42,7 +42,6 @@ VideoComponent::VideoComponent()
|
|||
, mPlayAudio {true}
|
||||
, mDrawPillarboxes {true}
|
||||
, mRenderScanlines {false}
|
||||
, mLegacyTheme {false}
|
||||
, mHasVideo {false}
|
||||
, mGeneralFade {false}
|
||||
, mFadeIn {1.0f}
|
||||
|
@ -125,8 +124,6 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
|
||||
const ThemeData::ThemeElement* elem {theme->getElement(view, element, "video")};
|
||||
|
||||
mLegacyTheme = theme->isLegacyTheme();
|
||||
|
||||
if (!elem)
|
||||
return;
|
||||
|
||||
|
@ -226,15 +223,10 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
mConfig.startDelay =
|
||||
static_cast<unsigned int>(glm::clamp(elem->get<float>("delay"), 0.0f, 15.0f) * 1000.0f);
|
||||
|
||||
if (!theme->isLegacyTheme())
|
||||
mConfig.showSnapshotNoVideo = true;
|
||||
else if (elem->has("showSnapshotNoVideo"))
|
||||
mConfig.showSnapshotNoVideo = elem->get<bool>("showSnapshotNoVideo");
|
||||
mConfig.showSnapshotNoVideo = true;
|
||||
|
||||
if (!theme->isLegacyTheme() && mConfig.startDelay != 0)
|
||||
if (mConfig.startDelay != 0)
|
||||
mConfig.showSnapshotDelay = true;
|
||||
else if (elem->has("showSnapshotDelay"))
|
||||
mConfig.showSnapshotDelay = elem->get<bool>("showSnapshotDelay");
|
||||
|
||||
if (properties && elem->has("fadeInTime"))
|
||||
mFadeInTime = glm::clamp(elem->get<float>("fadeInTime"), 0.0f, 8.0f) * 1000.0f;
|
||||
|
@ -277,7 +269,7 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
}
|
||||
}
|
||||
|
||||
if (!mLegacyTheme && mThemeImageTypes.empty())
|
||||
if (mThemeImageTypes.empty())
|
||||
mConfig.startDelay = 0;
|
||||
|
||||
if (elem->has("color")) {
|
||||
|
@ -404,9 +396,6 @@ void VideoComponent::startVideoPlayer()
|
|||
|
||||
void VideoComponent::renderSnapshot(const glm::mat4& parentTrans)
|
||||
{
|
||||
if (mLegacyTheme && !mHasVideo && !mConfig.showSnapshotNoVideo)
|
||||
return;
|
||||
|
||||
if (mHasVideo && (!mConfig.showSnapshotDelay || mConfig.startDelay == 0))
|
||||
return;
|
||||
|
||||
|
|
|
@ -56,13 +56,7 @@ public:
|
|||
|
||||
bool hasStaticVideo() { return !mConfig.staticVideoPath.empty(); }
|
||||
bool hasStaticImage() { return mStaticImage.getTextureSize() != glm::ivec2 {0, 0}; }
|
||||
bool hasStartDelay()
|
||||
{
|
||||
if (mLegacyTheme)
|
||||
return mConfig.showSnapshotDelay && mConfig.startDelay > 0;
|
||||
else
|
||||
return mConfig.startDelay > 0;
|
||||
}
|
||||
bool hasStartDelay() { return mConfig.startDelay > 0; }
|
||||
|
||||
// These functions update the embedded static image.
|
||||
void onOriginChanged() override { mStaticImage.setOrigin(mOrigin); }
|
||||
|
@ -134,7 +128,6 @@ protected:
|
|||
bool mPlayAudio;
|
||||
bool mDrawPillarboxes;
|
||||
bool mRenderScanlines;
|
||||
bool mLegacyTheme;
|
||||
bool mHasVideo;
|
||||
bool mGeneralFade;
|
||||
float mFadeIn;
|
||||
|
|
|
@ -256,10 +256,8 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans)
|
|||
// in those modules as a post-processing step.
|
||||
if (!mScreensaverMode && !mMediaViewerMode) {
|
||||
vertices[0].opacity = mFadeIn * mOpacity * mThemeOpacity;
|
||||
if ((mLegacyTheme && Settings::getInstance()->getBool("GamelistVideoScanlines")) ||
|
||||
(!mLegacyTheme && mRenderScanlines)) {
|
||||
if (mRenderScanlines)
|
||||
vertices[0].shaders = Renderer::Shader::SCANLINES;
|
||||
}
|
||||
}
|
||||
|
||||
mRenderer->drawTriangleStrips(&vertices[0], 4, Renderer::BlendFactor::SRC_ALPHA,
|
||||
|
@ -995,8 +993,7 @@ void VideoFFmpegComponent::calculateBlackRectangle()
|
|||
mVideoRectangleCoords.clear();
|
||||
mRectangleOffset = {0.0f, 0.0f};
|
||||
|
||||
if ((mLegacyTheme && Settings::getInstance()->getBool("GamelistVideoPillarbox")) ||
|
||||
(!mLegacyTheme && mDrawPillarboxes)) {
|
||||
if (mDrawPillarboxes) {
|
||||
float rectHeight {0.0f};
|
||||
float rectWidth {0.0f};
|
||||
// Video is in landscape orientation.
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -131,7 +131,6 @@ private:
|
|||
int mLoopTime;
|
||||
bool mLoopScroll;
|
||||
bool mGamelistView;
|
||||
bool mLegacyMode;
|
||||
|
||||
std::shared_ptr<Font> mFont;
|
||||
float mSelectorHeight;
|
||||
|
@ -172,7 +171,6 @@ TextListComponent<T>::TextListComponent()
|
|||
, mLoopTime {0}
|
||||
, mLoopScroll {false}
|
||||
, mGamelistView {std::is_same_v<T, FileData*> ? true : false}
|
||||
, mLegacyMode {false}
|
||||
, mFont {Font::get(FONT_SIZE_MEDIUM_FIXED)}
|
||||
, mSelectorHeight {mFont->getSize() * 1.5f}
|
||||
, mSelectorHorizontalOffset {0.0f}
|
||||
|
@ -336,33 +334,11 @@ template <typename T> void TextListComponent<T>::render(const glm::mat4& parentT
|
|||
float entrySize {0.0f};
|
||||
float lineSpacingHeight {0.0f};
|
||||
|
||||
// The vertical spacing between rows for legacy themes is very inaccurate and will look
|
||||
// different depending on the resolution, but it's done for maximum backward compatibility.
|
||||
if (mLegacyMode) {
|
||||
font->useLegacyMaxGlyphHeight();
|
||||
entrySize = std::max(font->getHeight(mLineSpacing), font->getSize() * mLineSpacing);
|
||||
lineSpacingHeight = std::floor(font->getSize() * mLineSpacing - font->getSize());
|
||||
}
|
||||
else {
|
||||
entrySize = font->getSize() * mLineSpacing;
|
||||
lineSpacingHeight = font->getSize() * mLineSpacing - font->getSize() * 1.0f;
|
||||
}
|
||||
entrySize = font->getSize() * mLineSpacing;
|
||||
lineSpacingHeight = font->getSize() * mLineSpacing - font->getSize() * 1.0f;
|
||||
|
||||
if (mLegacyMode) {
|
||||
// This extra vertical margin is technically incorrect, but it adds a little extra leeway
|
||||
// to avoid removing the last row on some older theme sets. There was a sizing bug in the
|
||||
// RetroPie fork of EmulationStation and some theme authors set sizes that are just slightly
|
||||
// too small for the last row to show up when the sizing calculation is done correctly.
|
||||
const float extraMargin {(Renderer::getScreenHeightModifier() >= 1.0f ? 3.0f : 0.0f)};
|
||||
// Number of entries that can fit on the screen simultaneously.
|
||||
screenCount = static_cast<int>(
|
||||
floorf((mSize.y + lineSpacingHeight / 2.0f + extraMargin) / entrySize));
|
||||
}
|
||||
else {
|
||||
// Number of entries that can fit on the screen simultaneously.
|
||||
screenCount =
|
||||
static_cast<int>(std::floor((mSize.y + lineSpacingHeight / 2.0f) / entrySize));
|
||||
}
|
||||
// Number of entries that can fit on the screen simultaneously.
|
||||
screenCount = static_cast<int>(std::floor((mSize.y + lineSpacingHeight / 2.0f) / entrySize));
|
||||
|
||||
if (size() >= screenCount) {
|
||||
startEntry = mCursor - screenCount / 2;
|
||||
|
@ -532,8 +508,6 @@ void TextListComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
if (!elem)
|
||||
return;
|
||||
|
||||
mLegacyMode = theme->isLegacyTheme();
|
||||
|
||||
if (properties & COLOR) {
|
||||
if (elem->has("selectorColor")) {
|
||||
mSelectorColor = elem->get<unsigned int>("selectorColor");
|
||||
|
@ -577,9 +551,7 @@ void TextListComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
mSelectedSecondaryBackgroundColor = mSelectedBackgroundColor;
|
||||
}
|
||||
|
||||
setFont(Font::getFromTheme(elem, properties, mFont, 0.0f, false, mLegacyMode));
|
||||
if (mLegacyMode)
|
||||
mFont->useLegacyMaxGlyphHeight();
|
||||
setFont(Font::getFromTheme(elem, properties, mFont, 0.0f, false));
|
||||
const float selectorHeight {mFont->getHeight(mLineSpacing)};
|
||||
mSelectorHeight = selectorHeight;
|
||||
|
||||
|
@ -602,24 +574,6 @@ void TextListComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
<< "\"";
|
||||
}
|
||||
}
|
||||
else if (elem->has("alignment")) {
|
||||
// Legacy themes only.
|
||||
const std::string& alignment {elem->get<std::string>("alignment")};
|
||||
if (alignment == "left") {
|
||||
setAlignment(PrimaryAlignment::ALIGN_LEFT);
|
||||
}
|
||||
else if (alignment == "center") {
|
||||
setAlignment(PrimaryAlignment::ALIGN_CENTER);
|
||||
}
|
||||
else if (alignment == "right") {
|
||||
setAlignment(PrimaryAlignment::ALIGN_RIGHT);
|
||||
}
|
||||
else {
|
||||
LOG(LogWarning) << "TextListComponent: Invalid theme configuration, property "
|
||||
"\"alignment\" for element \""
|
||||
<< element.substr(9) << "\" defined as \"" << alignment << "\"";
|
||||
}
|
||||
}
|
||||
if (elem->has("horizontalMargin")) {
|
||||
mHorizontalMargin =
|
||||
elem->get<float>("horizontalMargin") *
|
||||
|
@ -687,12 +641,6 @@ void TextListComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
}
|
||||
}
|
||||
|
||||
// Legacy themes only.
|
||||
if (properties & FORCE_UPPERCASE && elem->has("forceUppercase")) {
|
||||
if (elem->get<bool>("forceUppercase"))
|
||||
mLetterCase = LetterCase::UPPERCASE;
|
||||
}
|
||||
|
||||
mSelectorHorizontalOffset = 0.0f;
|
||||
mSelectorVerticalOffset = 0.0f;
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "GuiComponent.h"
|
||||
#include "components/ButtonComponent.h"
|
||||
#include "components/ComponentGrid.h"
|
||||
#include "components/TextComponent.h"
|
||||
#include "components/TextEditComponent.h"
|
||||
|
||||
class GuiTextEditKeyboardPopup : public GuiComponent
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "GuiComponent.h"
|
||||
#include "components/ButtonComponent.h"
|
||||
#include "components/ComponentGrid.h"
|
||||
#include "components/TextComponent.h"
|
||||
#include "components/TextEditComponent.h"
|
||||
|
||||
class GuiTextEditPopup : public GuiComponent
|
||||
|
|
|
@ -22,7 +22,6 @@ Font::Font(float size, const std::string& path, const bool linearMagnify)
|
|||
, mLinearMagnify {linearMagnify}
|
||||
, mLetterHeight {0.0f}
|
||||
, mMaxGlyphHeight {static_cast<int>(std::round(size))}
|
||||
, mLegacyMaxGlyphHeight {0}
|
||||
{
|
||||
if (mFontSize < 3.0f) {
|
||||
mFontSize = 3.0f;
|
||||
|
@ -430,12 +429,9 @@ std::shared_ptr<Font> Font::getFromTheme(const ThemeData::ThemeElement* elem,
|
|||
const std::shared_ptr<Font>& orig,
|
||||
const float maxHeight,
|
||||
const bool linearMagnify,
|
||||
const bool legacyTheme,
|
||||
const float sizeMultiplier,
|
||||
const bool fontSizeDimmed)
|
||||
{
|
||||
mLegacyTheme = legacyTheme;
|
||||
|
||||
using namespace ThemeFlags;
|
||||
if (!(properties & FONT_PATH) && !(properties & FONT_SIZE))
|
||||
return orig;
|
||||
|
@ -472,10 +468,7 @@ std::shared_ptr<Font> Font::getFromTheme(const ThemeData::ThemeElement* elem,
|
|||
path = getDefaultPath();
|
||||
}
|
||||
|
||||
if (mLegacyTheme)
|
||||
return get(std::floor(size), path, false);
|
||||
else
|
||||
return get(size, path, linearMagnify);
|
||||
return get(size, path, linearMagnify);
|
||||
}
|
||||
|
||||
size_t Font::getMemUsage() const
|
||||
|
@ -784,9 +777,6 @@ Font::Glyph* Font::getGlyph(const unsigned int id)
|
|||
mRenderer->updateTexture(tex->textureId, Renderer::TextureType::RED, cursor.x, cursor.y,
|
||||
glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer);
|
||||
|
||||
if (glyphSize.y > mLegacyMaxGlyphHeight)
|
||||
mLegacyMaxGlyphHeight = glyphSize.y;
|
||||
|
||||
return &glyph;
|
||||
}
|
||||
|
||||
|
|
|
@ -89,9 +89,6 @@ public:
|
|||
// guaranteed and can be exceeded by a few pixels for some glyphs.
|
||||
int loadGlyphs(const std::string& text);
|
||||
|
||||
// This is needed to maintain maximum compatibility with legacy theme sets.
|
||||
void useLegacyMaxGlyphHeight() { mMaxGlyphHeight = mLegacyMaxGlyphHeight; }
|
||||
|
||||
TextCache* buildTextCache(const std::string& text,
|
||||
float offsetX,
|
||||
float offsetY,
|
||||
|
@ -137,7 +134,6 @@ public:
|
|||
const std::shared_ptr<Font>& orig,
|
||||
const float maxHeight = 0.0f,
|
||||
const bool linearMagnify = false,
|
||||
const bool legacyTheme = false,
|
||||
const float sizeMultiplier = 1.0f,
|
||||
const bool fontSizeDimmed = false);
|
||||
|
||||
|
@ -208,7 +204,6 @@ private:
|
|||
|
||||
static inline FT_Library sLibrary {nullptr};
|
||||
static inline std::map<std::tuple<float, std::string, bool>, std::weak_ptr<Font>> sFontMap;
|
||||
static inline bool mLegacyTheme {false};
|
||||
|
||||
Renderer* mRenderer;
|
||||
std::vector<std::unique_ptr<FontTexture>> mTextures;
|
||||
|
@ -220,7 +215,6 @@ private:
|
|||
const bool mLinearMagnify;
|
||||
float mLetterHeight;
|
||||
int mMaxGlyphHeight;
|
||||
int mLegacyMaxGlyphHeight;
|
||||
};
|
||||
|
||||
// Used to store a sort of "pre-rendered" string.
|
||||
|
|
Loading…
Reference in a new issue