Added support for up to two imageType values for CarouselComponent and GridComponent.

This commit is contained in:
Leon Styhre 2022-12-17 22:20:29 +01:00
parent 17597ab144
commit ae52489b6b
3 changed files with 160 additions and 109 deletions

View file

@ -155,51 +155,11 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
if (element.second.type == "carousel") {
if (mCarousel == nullptr) {
mCarousel = std::make_unique<CarouselComponent<FileData*>>();
if (element.second.has("imageType")) {
const std::string imageType {element.second.get<std::string>("imageType")};
if (imageType == "marquee" || imageType == "cover" ||
imageType == "backcover" || imageType == "3dbox" ||
imageType == "physicalmedia" || imageType == "screenshot" ||
imageType == "titlescreen" || imageType == "miximage" ||
imageType == "fanart" || imageType == "none") {
mCarousel->setImageType(imageType);
}
else {
LOG(LogWarning) << "GamelistView::onThemeChanged(): Invalid theme "
"configuration, carousel property \"imageType\" "
"for element \""
<< element.first.substr(9) << "\" defined as \""
<< imageType << "\"";
mCarousel->setImageType("marquee");
}
}
else if (element.second.has("itemType")) {
// TEMPORARY: Backward compatiblity due to property name changes.
const std::string itemType {element.second.get<std::string>("itemType")};
if (itemType == "marquee" || itemType == "cover" ||
itemType == "backcover" || itemType == "3dbox" ||
itemType == "physicalmedia" || itemType == "screenshot" ||
itemType == "titlescreen" || itemType == "miximage" ||
itemType == "fanart" || itemType == "none") {
mCarousel->setImageType(itemType);
}
else {
LOG(LogWarning) << "GamelistView::onThemeChanged(): Invalid theme "
"configuration, carousel property \"itemType\" "
"for element \""
<< element.first.substr(9) << "\" defined as \""
<< itemType << "\"";
mCarousel->setImageType("marquee");
}
}
else {
mCarousel->setImageType("marquee");
}
if (element.second.has("defaultImage"))
mCarousel->setDefaultImage(element.second.get<std::string>("defaultImage"));
// TEMPORARY: Backward compatiblity due to property name changes.
if (element.second.has("defaultItem"))
mCarousel->setDefaultImage(element.second.get<std::string>("defaultItem"));
if (element.second.has("defaultImage"))
mCarousel->setDefaultImage(element.second.get<std::string>("defaultImage"));
mPrimary = mCarousel.get();
}
mPrimary->setCursorChangedCallback(
@ -211,27 +171,6 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
if (element.second.type == "grid") {
if (mGrid == nullptr) {
mGrid = std::make_unique<GridComponent<FileData*>>();
if (element.second.has("imageType")) {
const std::string imageType {element.second.get<std::string>("imageType")};
if (imageType == "marquee" || imageType == "cover" ||
imageType == "backcover" || imageType == "3dbox" ||
imageType == "physicalmedia" || imageType == "screenshot" ||
imageType == "titlescreen" || imageType == "miximage" ||
imageType == "fanart" || imageType == "none") {
mGrid->setImageType(imageType);
}
else {
LOG(LogWarning) << "GamelistView::onThemeChanged(): Invalid theme "
"configuration, grid property \"imageType\" "
"for element \""
<< element.first.substr(5) << "\" defined as \""
<< imageType << "\"";
mGrid->setImageType("marquee");
}
}
else {
mGrid->setImageType("marquee");
}
if (element.second.has("defaultImage"))
mGrid->setDefaultImage(element.second.get<std::string>("defaultImage"));
mPrimary = mGrid.get();

View file

@ -61,8 +61,6 @@ public:
Entry& getEntry(int index) { return mEntries.at(index); }
void onDemandTextureLoad() override;
const CarouselType getType() { return mType; }
const std::string& getImageType() { return mImageType; }
void setImageType(std::string imageType) { mImageType = imageType; }
const std::string& getDefaultImage() { return mDefaultImage; }
void setDefaultImage(std::string defaultImage) { mDefaultImage = defaultImage; }
bool isScrolling() const override { return List::isScrolling(); }
@ -132,7 +130,7 @@ private:
bool mLegacyMode;
CarouselType mType;
std::string mImageType;
std::vector<std::string> mImageTypes;
std::string mDefaultImage;
float mMaxItemCount;
int mItemsBeforeCenter;
@ -399,6 +397,9 @@ void CarouselComponent<T>::updateEntry(Entry& entry, const std::shared_ptr<Theme
template <typename T> void CarouselComponent<T>::onDemandTextureLoad()
{
if constexpr (std::is_same_v<T, FileData*>) {
if (mImageTypes.empty())
mImageTypes.emplace_back("marquee");
const int numEntries {size()};
const int center {getCursor()};
const bool isWheel {mType == CarouselType::VERTICAL_WHEEL ||
@ -463,26 +464,31 @@ template <typename T> void CarouselComponent<T>::onDemandTextureLoad()
if (entry.data.imagePath == "") {
FileData* game {entry.object};
if (mImageType == "" || mImageType == "marquee")
for (auto& imageType : mImageTypes) {
if (imageType == "marquee")
entry.data.imagePath = game->getMarqueePath();
else if (mImageType == "cover")
else if (imageType == "cover")
entry.data.imagePath = game->getCoverPath();
else if (mImageType == "backcover")
else if (imageType == "backcover")
entry.data.imagePath = game->getBackCoverPath();
else if (mImageType == "3dbox")
else if (imageType == "3dbox")
entry.data.imagePath = game->get3DBoxPath();
else if (mImageType == "physicalmedia")
else if (imageType == "physicalmedia")
entry.data.imagePath = game->getPhysicalMediaPath();
else if (mImageType == "screenshot")
else if (imageType == "screenshot")
entry.data.imagePath = game->getScreenshotPath();
else if (mImageType == "titlescreen")
else if (imageType == "titlescreen")
entry.data.imagePath = game->getTitleScreenPath();
else if (mImageType == "miximage")
else if (imageType == "miximage")
entry.data.imagePath = game->getMiximagePath();
else if (mImageType == "fanart")
else if (imageType == "fanart")
entry.data.imagePath = game->getFanArtPath();
else if (mImageType == "none") // Display the game name as text.
return;
else if (imageType == "none") // Display the game name as text.
break;
if (entry.data.imagePath != "")
break;
}
if (entry.data.imagePath == "")
entry.data.imagePath = entry.data.defaultImagePath;
@ -1033,6 +1039,57 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
}
}
// TEMPORARY: Support for itemType is for backward compatiblity due to property name changes.
if (mGamelistView && properties && (elem->has("imageType") || elem->has("itemType"))) {
const std::vector<std::string> supportedImageTypes {
"marquee", "cover", "backcover", "3dbox", "physicalmedia",
"screenshot", "titlescreen", "miximage", "fanart", "none"};
std::string imageTypesString;
if (elem->has("imageType"))
imageTypesString = elem->get<std::string>("imageType");
else
imageTypesString = elem->get<std::string>("itemType");
for (auto& character : imageTypesString) {
if (std::isspace(character))
character = ',';
}
imageTypesString = Utils::String::replace(imageTypesString, ",,", ",");
mImageTypes = Utils::String::delimitedStringToVector(imageTypesString, ",");
// Only allow two imageType entries due to performance reasons.
if (mImageTypes.size() > 2)
mImageTypes.erase(mImageTypes.begin() + 2, mImageTypes.end());
if (mImageTypes.empty()) {
LOG(LogWarning)
<< "CarouselComponent: Invalid theme configuration, property \"imageType\" "
"for element \""
<< element.substr(9) << "\" contains no values";
}
for (std::string& type : mImageTypes) {
if (std::find(supportedImageTypes.cbegin(), supportedImageTypes.cend(), type) ==
supportedImageTypes.cend()) {
LOG(LogWarning)
<< "CarouselComponent: Invalid theme configuration, property \"imageType\" "
"for element \""
<< element.substr(9) << "\" defined as \"" << type << "\"";
mImageTypes.clear();
break;
}
}
if (mImageTypes.size() == 2 && mImageTypes.front() == mImageTypes.back()) {
LOG(LogError)
<< "CarouselComponent: Invalid theme configuration, property \"imageType\" "
"for element \""
<< element.substr(9) << "\" contains duplicate values";
mImageTypes.clear();
}
}
if (elem->has("color")) {
mCarouselColor = elem->get<unsigned int>("color");
mCarouselColorEnd = mCarouselColor;

View file

@ -63,8 +63,6 @@ public:
{
return mLetterCaseGroupedCollections;
}
const std::string& getImageType() { return mImageType; }
void setImageType(std::string imageType) { mImageType = imageType; }
const std::string& getDefaultImage() { return mDefaultImage; }
void setDefaultImage(std::string defaultImage) { mDefaultImage = defaultImage; }
bool input(InputConfig* config, Input input) override;
@ -134,7 +132,7 @@ private:
float mHorizontalMargin;
float mVerticalMargin;
std::string mImageType;
std::vector<std::string> mImageTypes;
std::string mDefaultImage;
glm::vec2 mItemSize;
float mItemScale;
@ -365,6 +363,9 @@ void GridComponent<T>::updateEntry(Entry& entry, const std::shared_ptr<ThemeData
template <typename T> void GridComponent<T>::onDemandTextureLoad()
{
if constexpr (std::is_same_v<T, FileData*>) {
if (mImageTypes.empty())
mImageTypes.emplace_back("marquee");
const int visibleRows {static_cast<int>(std::ceil(mVisibleRows))};
const int columnPos {mCursor % mColumns};
int loadItems {mColumns * visibleRows};
@ -404,26 +405,31 @@ template <typename T> void GridComponent<T>::onDemandTextureLoad()
if (entry.data.imagePath == "") {
FileData* game {entry.object};
if (mImageType == "" || mImageType == "marquee")
for (auto& imageType : mImageTypes) {
if (imageType == "marquee")
entry.data.imagePath = game->getMarqueePath();
else if (mImageType == "cover")
else if (imageType == "cover")
entry.data.imagePath = game->getCoverPath();
else if (mImageType == "backcover")
else if (imageType == "backcover")
entry.data.imagePath = game->getBackCoverPath();
else if (mImageType == "3dbox")
else if (imageType == "3dbox")
entry.data.imagePath = game->get3DBoxPath();
else if (mImageType == "physicalmedia")
else if (imageType == "physicalmedia")
entry.data.imagePath = game->getPhysicalMediaPath();
else if (mImageType == "screenshot")
else if (imageType == "screenshot")
entry.data.imagePath = game->getScreenshotPath();
else if (mImageType == "titlescreen")
else if (imageType == "titlescreen")
entry.data.imagePath = game->getTitleScreenPath();
else if (mImageType == "miximage")
else if (imageType == "miximage")
entry.data.imagePath = game->getMiximagePath();
else if (mImageType == "fanart")
else if (imageType == "fanart")
entry.data.imagePath = game->getFanArtPath();
else if (mImageType == "none") // Display the game name as text.
return;
else if (imageType == "none") // Display the game name as text.
break;
if (entry.data.imagePath != "")
break;
}
if (entry.data.imagePath == "")
entry.data.imagePath = entry.data.defaultImagePath;
@ -778,6 +784,55 @@ void GridComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (!elem)
return;
// TEMPORARY: Support for itemType is for backward compatiblity due to property name changes.
if (mGamelistView && properties && (elem->has("imageType") || elem->has("itemType"))) {
const std::vector<std::string> supportedImageTypes {
"marquee", "cover", "backcover", "3dbox", "physicalmedia",
"screenshot", "titlescreen", "miximage", "fanart", "none"};
std::string imageTypesString;
if (elem->has("imageType"))
imageTypesString = elem->get<std::string>("imageType");
else
imageTypesString = elem->get<std::string>("itemType");
for (auto& character : imageTypesString) {
if (std::isspace(character))
character = ',';
}
imageTypesString = Utils::String::replace(imageTypesString, ",,", ",");
mImageTypes = Utils::String::delimitedStringToVector(imageTypesString, ",");
// Only allow two imageType entries due to performance reasons.
if (mImageTypes.size() > 2)
mImageTypes.erase(mImageTypes.begin() + 2, mImageTypes.end());
if (mImageTypes.empty()) {
LOG(LogWarning) << "GridComponent: Invalid theme configuration, property \"imageType\" "
"for element \""
<< element.substr(5) << "\" contains no values";
}
for (std::string& type : mImageTypes) {
if (std::find(supportedImageTypes.cbegin(), supportedImageTypes.cend(), type) ==
supportedImageTypes.cend()) {
LOG(LogWarning)
<< "GridComponent: Invalid theme configuration, property \"imageType\" "
"for element \""
<< element.substr(5) << "\" defined as \"" << type << "\"";
mImageTypes.clear();
break;
}
}
if (mImageTypes.size() == 2 && mImageTypes.front() == mImageTypes.back()) {
LOG(LogError) << "GridComponent: Invalid theme configuration, property \"imageType\" "
"for element \""
<< element.substr(5) << "\" contains duplicate values";
mImageTypes.clear();
}
}
mFractionalRows = (elem->has("fractionalRows") && elem->get<bool>("fractionalRows"));
if (elem->has("itemSize")) {