mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-02-18 04:45:39 +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 {
|
else {
|
||||||
for (auto& image : mImageComponents) {
|
for (auto& image : mImageComponents)
|
||||||
setGameImage(file, image.get());
|
setGameImage(file, image.get());
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& video : mVideoComponents) {
|
for (auto& video : mVideoComponents) {
|
||||||
setGameImage(file, video.get());
|
setGameImage(file, video.get());
|
||||||
|
@ -1018,74 +1017,79 @@ void GamelistView::setGameImage(FileData* file, GuiComponent* comp)
|
||||||
path = file->getImagePath();
|
path = file->getImagePath();
|
||||||
if (path != "") {
|
if (path != "") {
|
||||||
comp->setImage(path);
|
comp->setImage(path);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (imageType == "miximage") {
|
else if (imageType == "miximage") {
|
||||||
path = file->getMiximagePath();
|
path = file->getMiximagePath();
|
||||||
if (path != "") {
|
if (path != "") {
|
||||||
comp->setImage(path);
|
comp->setImage(path);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (imageType == "marquee") {
|
else if (imageType == "marquee") {
|
||||||
path = file->getMarqueePath();
|
path = file->getMarqueePath();
|
||||||
if (path != "") {
|
if (path != "") {
|
||||||
comp->setImage(path);
|
comp->setImage(path);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (imageType == "screenshot") {
|
else if (imageType == "screenshot") {
|
||||||
path = file->getScreenshotPath();
|
path = file->getScreenshotPath();
|
||||||
if (path != "") {
|
if (path != "") {
|
||||||
comp->setImage(path);
|
comp->setImage(path);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (imageType == "titlescreen") {
|
else if (imageType == "titlescreen") {
|
||||||
path = file->getTitleScreenPath();
|
path = file->getTitleScreenPath();
|
||||||
if (path != "") {
|
if (path != "") {
|
||||||
comp->setImage(path);
|
comp->setImage(path);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (imageType == "cover") {
|
else if (imageType == "cover") {
|
||||||
path = file->getCoverPath();
|
path = file->getCoverPath();
|
||||||
if (path != "") {
|
if (path != "") {
|
||||||
comp->setImage(path);
|
comp->setImage(path);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (imageType == "backcover") {
|
else if (imageType == "backcover") {
|
||||||
path = file->getBackCoverPath();
|
path = file->getBackCoverPath();
|
||||||
if (path != "") {
|
if (path != "") {
|
||||||
comp->setImage(path);
|
comp->setImage(path);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (imageType == "3dbox") {
|
else if (imageType == "3dbox") {
|
||||||
path = file->get3DBoxPath();
|
path = file->get3DBoxPath();
|
||||||
if (path != "") {
|
if (path != "") {
|
||||||
comp->setImage(path);
|
comp->setImage(path);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (imageType == "physicalmedia") {
|
else if (imageType == "physicalmedia") {
|
||||||
path = file->getPhysicalMediaPath();
|
path = file->getPhysicalMediaPath();
|
||||||
if (path != "") {
|
if (path != "") {
|
||||||
comp->setImage(path);
|
comp->setImage(path);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (imageType == "fanart") {
|
else if (imageType == "fanart") {
|
||||||
path = file->getFanArtPath();
|
path = file->getFanArtPath();
|
||||||
if (path != "") {
|
if (path != "") {
|
||||||
comp->setImage(path);
|
comp->setImage(path);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This is needed so the default image is set if no game media was found.
|
// 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("");
|
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 std::string& getThemeGameSelector() const { return mThemeGameSelector; }
|
||||||
const unsigned int getThemeGameSelectorEntry() const { return mThemeGameSelectorEntry; }
|
const unsigned int getThemeGameSelectorEntry() const { return mThemeGameSelectorEntry; }
|
||||||
virtual const std::string getDefaultImage() const { return ""; }
|
virtual const std::string getDefaultImage() const { return ""; }
|
||||||
|
virtual void setGameOverrideImage(const std::string& basename, const std::string& system) {}
|
||||||
const float getThemeOpacity() const { return mThemeOpacity; }
|
const float getThemeOpacity() const { return mThemeOpacity; }
|
||||||
|
|
||||||
virtual std::shared_ptr<Font> getFont() const { return nullptr; }
|
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},
|
{"flipHorizontal", BOOLEAN},
|
||||||
{"flipVertical", BOOLEAN},
|
{"flipVertical", BOOLEAN},
|
||||||
{"path", PATH},
|
{"path", PATH},
|
||||||
|
{"gameOverridePath", PATH},
|
||||||
{"default", PATH},
|
{"default", PATH},
|
||||||
{"imageType", STRING},
|
{"imageType", STRING},
|
||||||
{"metadataElement", BOOLEAN},
|
{"metadataElement", BOOLEAN},
|
||||||
|
|
|
@ -128,6 +128,25 @@ void ImageComponent::setImage(const std::shared_ptr<TextureResource>& texture, b
|
||||||
resize();
|
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)
|
void ImageComponent::setResize(const float width, const float height)
|
||||||
{
|
{
|
||||||
mTargetSize = glm::vec2 {width, 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"));
|
setDefaultImage(elem->get<std::string>("default"));
|
||||||
|
|
||||||
bool tile {elem->has("tile") && elem->get<bool>("tile")};
|
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)
|
if (tile && updateAlignment)
|
||||||
updateVertices();
|
updateVertices();
|
||||||
|
|
||||||
if (properties && elem->has("imageType")) {
|
// Per-game overrides of static images using the game file's basename. It's by design not
|
||||||
std::string imageTypes {elem->get<std::string>("imageType")};
|
// possible to override scraped media.
|
||||||
for (auto& character : imageTypes) {
|
if (mThemeImageTypes.empty() && elem->has("gameOverridePath")) {
|
||||||
if (std::isspace(character))
|
mGameOverridePath = elem->get<std::string>("gameOverridePath");
|
||||||
character = ',';
|
#if defined(_WIN64)
|
||||||
}
|
mBasenamePath = Utils::String::replace(mGameOverridePath, "\\", "/");
|
||||||
imageTypes = Utils::String::replace(imageTypes, ",,", ",");
|
#endif
|
||||||
mThemeImageTypes = Utils::String::delimitedStringToVector(imageTypes, ",");
|
if (mGameOverridePath.back() != '/')
|
||||||
|
mGameOverridePath.push_back('/');
|
||||||
|
|
||||||
if (mThemeImageTypes.empty()) {
|
if (elem->has("path"))
|
||||||
LOG(LogError) << "ImageComponent: Invalid theme configuration, property \"imageType\" "
|
mGameOverrideOriginalPath = elem->get<std::string>("path");
|
||||||
"for element \""
|
else
|
||||||
<< element.substr(6) << "\" contains no values";
|
mGameOverrideOriginalPath = "";
|
||||||
}
|
|
||||||
|
|
||||||
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("metadataElement") && elem->get<bool>("metadataElement"))
|
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
|
||||||
|
|
|
@ -30,6 +30,9 @@ public:
|
||||||
// Use an already existing texture.
|
// Use an already existing texture.
|
||||||
void setImage(const std::shared_ptr<TextureResource>& texture, bool resizeTexture = true);
|
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 setDynamic(bool state) { mDynamic = state; }
|
||||||
void onSizeChanged() override { updateVertices(); }
|
void onSizeChanged() override { updateVertices(); }
|
||||||
|
|
||||||
|
@ -143,7 +146,11 @@ private:
|
||||||
bool mColorGradientHorizontal;
|
bool mColorGradientHorizontal;
|
||||||
|
|
||||||
std::string mDefaultPath;
|
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 {
|
static inline std::vector<std::string> sSupportedImageTypes {
|
||||||
"image", "miximage", "marquee", "screenshot", "titlescreen",
|
"image", "miximage", "marquee", "screenshot", "titlescreen",
|
||||||
"cover", "backcover", "3dbox", "physicalmedia", "fanart"};
|
"cover", "backcover", "3dbox", "physicalmedia", "fanart"};
|
||||||
|
|
Loading…
Reference in a new issue