mirror of
				https://github.com/RetroDECK/ES-DE.git
				synced 2025-04-10 19:15:13 +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
	
	 Leon Styhre
						Leon Styhre