mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 15:45:38 +00:00
Added a new gameOverridePath property to the image element to enable per-game static image overrides
Also fixed an issue where the default image element property could be used even if no imageType entries were defined
This commit is contained in:
parent
5030d45525
commit
1697508393
|
@ -670,9 +670,8 @@ void GamelistView::updateView(const CursorState& state)
|
|||
}
|
||||
}
|
||||
else {
|
||||
for (auto& image : mImageComponents) {
|
||||
for (auto& image : mImageComponents)
|
||||
setGameImage(file, image.get());
|
||||
}
|
||||
|
||||
for (auto& video : mVideoComponents) {
|
||||
setGameImage(file, video.get());
|
||||
|
@ -1018,74 +1017,79 @@ void GamelistView::setGameImage(FileData* file, GuiComponent* comp)
|
|||
path = file->getImagePath();
|
||||
if (path != "") {
|
||||
comp->setImage(path);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (imageType == "miximage") {
|
||||
path = file->getMiximagePath();
|
||||
if (path != "") {
|
||||
comp->setImage(path);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (imageType == "marquee") {
|
||||
path = file->getMarqueePath();
|
||||
if (path != "") {
|
||||
comp->setImage(path);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (imageType == "screenshot") {
|
||||
path = file->getScreenshotPath();
|
||||
if (path != "") {
|
||||
comp->setImage(path);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (imageType == "titlescreen") {
|
||||
path = file->getTitleScreenPath();
|
||||
if (path != "") {
|
||||
comp->setImage(path);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (imageType == "cover") {
|
||||
path = file->getCoverPath();
|
||||
if (path != "") {
|
||||
comp->setImage(path);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (imageType == "backcover") {
|
||||
path = file->getBackCoverPath();
|
||||
if (path != "") {
|
||||
comp->setImage(path);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (imageType == "3dbox") {
|
||||
path = file->get3DBoxPath();
|
||||
if (path != "") {
|
||||
comp->setImage(path);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (imageType == "physicalmedia") {
|
||||
path = file->getPhysicalMediaPath();
|
||||
if (path != "") {
|
||||
comp->setImage(path);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (imageType == "fanart") {
|
||||
path = file->getFanArtPath();
|
||||
if (path != "") {
|
||||
comp->setImage(path);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// This is needed so the default image is set if no game media was found.
|
||||
if (path == "" && (comp->getThemeImageTypes().size() > 0 || comp->getDefaultImage() != ""))
|
||||
if (path == "" && (comp->getThemeImageTypes().size() > 0 || comp->getDefaultImage() != "")) {
|
||||
comp->setImage("");
|
||||
return;
|
||||
}
|
||||
|
||||
// Sets per-game overrides of static images using the game file basename.
|
||||
comp->setGameOverrideImage(Utils::FileSystem::getStem(file->getPath()), file->getSystemName());
|
||||
}
|
||||
|
|
|
@ -279,6 +279,7 @@ public:
|
|||
const std::string& getThemeGameSelector() const { return mThemeGameSelector; }
|
||||
const unsigned int getThemeGameSelectorEntry() const { return mThemeGameSelectorEntry; }
|
||||
virtual const std::string getDefaultImage() const { return ""; }
|
||||
virtual void setGameOverrideImage(const std::string& basename, const std::string& system) {}
|
||||
const float getThemeOpacity() const { return mThemeOpacity; }
|
||||
|
||||
virtual std::shared_ptr<Font> getFont() const { return nullptr; }
|
||||
|
|
|
@ -299,6 +299,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"flipHorizontal", BOOLEAN},
|
||||
{"flipVertical", BOOLEAN},
|
||||
{"path", PATH},
|
||||
{"gameOverridePath", PATH},
|
||||
{"default", PATH},
|
||||
{"imageType", STRING},
|
||||
{"metadataElement", BOOLEAN},
|
||||
|
|
|
@ -128,6 +128,25 @@ void ImageComponent::setImage(const std::shared_ptr<TextureResource>& texture, b
|
|||
resize();
|
||||
}
|
||||
|
||||
void ImageComponent::setGameOverrideImage(const std::string& basename, const std::string& system)
|
||||
{
|
||||
if (mGameOverridePath == "")
|
||||
return;
|
||||
|
||||
if (!Utils::FileSystem::exists(mGameOverridePath + system))
|
||||
return;
|
||||
|
||||
const std::string imageFilePath {mGameOverridePath + system + "/" + basename};
|
||||
for (auto& extension : sSupportedOverrideExtensions) {
|
||||
if (Utils::FileSystem::exists(imageFilePath + extension)) {
|
||||
setImage(imageFilePath + extension);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setImage(mGameOverrideOriginalPath);
|
||||
}
|
||||
|
||||
void ImageComponent::setResize(const float width, const float height)
|
||||
{
|
||||
mTargetSize = glm::vec2 {width, height};
|
||||
|
@ -494,7 +513,45 @@ void ImageComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
}
|
||||
}
|
||||
|
||||
if (elem->has("default"))
|
||||
if (properties && elem->has("imageType")) {
|
||||
std::string imageTypes {elem->get<std::string>("imageType")};
|
||||
for (auto& character : imageTypes) {
|
||||
if (std::isspace(character))
|
||||
character = ',';
|
||||
}
|
||||
imageTypes = Utils::String::replace(imageTypes, ",,", ",");
|
||||
mThemeImageTypes = Utils::String::delimitedStringToVector(imageTypes, ",");
|
||||
|
||||
if (mThemeImageTypes.empty()) {
|
||||
LOG(LogError) << "ImageComponent: Invalid theme configuration, property \"imageType\" "
|
||||
"for element \""
|
||||
<< element.substr(6) << "\" contains no values";
|
||||
}
|
||||
|
||||
for (std::string& type : mThemeImageTypes) {
|
||||
if (std::find(sSupportedImageTypes.cbegin(), sSupportedImageTypes.cend(), type) ==
|
||||
sSupportedImageTypes.cend()) {
|
||||
LOG(LogError)
|
||||
<< "ImageComponent: Invalid theme configuration, property \"imageType\" "
|
||||
"for element \""
|
||||
<< element.substr(6) << "\" defined as \"" << type << "\"";
|
||||
mThemeImageTypes.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> sortedTypes {mThemeImageTypes};
|
||||
std::stable_sort(sortedTypes.begin(), sortedTypes.end());
|
||||
|
||||
if (std::adjacent_find(sortedTypes.begin(), sortedTypes.end()) != sortedTypes.end()) {
|
||||
LOG(LogError) << "ImageComponent: Invalid theme configuration, property \"imageType\" "
|
||||
"for element \""
|
||||
<< element.substr(6) << "\" contains duplicate values";
|
||||
mThemeImageTypes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (!mThemeImageTypes.empty() && elem->has("default"))
|
||||
setDefaultImage(elem->get<std::string>("default"));
|
||||
|
||||
bool tile {elem->has("tile") && elem->get<bool>("tile")};
|
||||
|
@ -567,42 +624,20 @@ void ImageComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
if (tile && updateAlignment)
|
||||
updateVertices();
|
||||
|
||||
if (properties && elem->has("imageType")) {
|
||||
std::string imageTypes {elem->get<std::string>("imageType")};
|
||||
for (auto& character : imageTypes) {
|
||||
if (std::isspace(character))
|
||||
character = ',';
|
||||
}
|
||||
imageTypes = Utils::String::replace(imageTypes, ",,", ",");
|
||||
mThemeImageTypes = Utils::String::delimitedStringToVector(imageTypes, ",");
|
||||
// Per-game overrides of static images using the game file's basename. It's by design not
|
||||
// possible to override scraped media.
|
||||
if (mThemeImageTypes.empty() && elem->has("gameOverridePath")) {
|
||||
mGameOverridePath = elem->get<std::string>("gameOverridePath");
|
||||
#if defined(_WIN64)
|
||||
mBasenamePath = Utils::String::replace(mGameOverridePath, "\\", "/");
|
||||
#endif
|
||||
if (mGameOverridePath.back() != '/')
|
||||
mGameOverridePath.push_back('/');
|
||||
|
||||
if (mThemeImageTypes.empty()) {
|
||||
LOG(LogError) << "ImageComponent: Invalid theme configuration, property \"imageType\" "
|
||||
"for element \""
|
||||
<< element.substr(6) << "\" contains no values";
|
||||
}
|
||||
|
||||
for (std::string& type : mThemeImageTypes) {
|
||||
if (std::find(sSupportedImageTypes.cbegin(), sSupportedImageTypes.cend(), type) ==
|
||||
sSupportedImageTypes.cend()) {
|
||||
LOG(LogError)
|
||||
<< "ImageComponent: Invalid theme configuration, property \"imageType\" "
|
||||
"for element \""
|
||||
<< element.substr(6) << "\" defined as \"" << type << "\"";
|
||||
mThemeImageTypes.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> sortedTypes {mThemeImageTypes};
|
||||
std::stable_sort(sortedTypes.begin(), sortedTypes.end());
|
||||
|
||||
if (std::adjacent_find(sortedTypes.begin(), sortedTypes.end()) != sortedTypes.end()) {
|
||||
LOG(LogError) << "ImageComponent: Invalid theme configuration, property \"imageType\" "
|
||||
"for element \""
|
||||
<< element.substr(6) << "\" contains duplicate values";
|
||||
mThemeImageTypes.clear();
|
||||
}
|
||||
if (elem->has("path"))
|
||||
mGameOverrideOriginalPath = elem->get<std::string>("path");
|
||||
else
|
||||
mGameOverrideOriginalPath = "";
|
||||
}
|
||||
|
||||
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
|
||||
|
|
|
@ -30,6 +30,9 @@ public:
|
|||
// Use an already existing texture.
|
||||
void setImage(const std::shared_ptr<TextureResource>& texture, bool resizeTexture = true);
|
||||
|
||||
// Sets per-game overrides of static images using the game file basename.
|
||||
void setGameOverrideImage(const std::string& basename, const std::string& system) override;
|
||||
|
||||
void setDynamic(bool state) { mDynamic = state; }
|
||||
void onSizeChanged() override { updateVertices(); }
|
||||
|
||||
|
@ -143,7 +146,11 @@ private:
|
|||
bool mColorGradientHorizontal;
|
||||
|
||||
std::string mDefaultPath;
|
||||
std::string mGameOverridePath;
|
||||
std::string mGameOverrideOriginalPath;
|
||||
|
||||
static inline std::vector<std::string> sSupportedOverrideExtensions {".jpg", ".png", ".gif",
|
||||
".svg"};
|
||||
static inline std::vector<std::string> sSupportedImageTypes {
|
||||
"image", "miximage", "marquee", "screenshot", "titlescreen",
|
||||
"cover", "backcover", "3dbox", "physicalmedia", "fanart"};
|
||||
|
|
Loading…
Reference in a new issue