Generalized the carousel property names and added support for setting media types for gamelist carousels.

This commit is contained in:
Leon Styhre 2022-04-16 21:54:58 +02:00
parent b5ffd4a2c4
commit f463766497
5 changed files with 168 additions and 68 deletions

View file

@ -557,15 +557,43 @@ void GamelistBase::populateList(const std::vector<FileData*>& files, FileData* f
auto theme = mRoot->getSystem()->getTheme();
std::string name;
std::string carouselItemType;
std::string carouselDefaultItem;
unsigned int color {0};
if (mCarousel != nullptr) {
carouselItemType = mCarousel->getItemType();
carouselDefaultItem = mCarousel->getDefaultItem();
}
if (files.size() > 0) {
for (auto it = files.cbegin(); it != files.cend(); ++it) {
if (mCarousel != nullptr) {
assert(carouselItemType != "");
CarouselComponent<FileData*>::Entry carouselEntry;
carouselEntry.name = (*it)->getName();
carouselEntry.object = *it;
if (carouselItemType == "" || carouselItemType == "marquee")
carouselEntry.data.logoPath = (*it)->getMarqueePath();
else if (carouselItemType == "cover")
carouselEntry.data.logoPath = (*it)->getCoverPath();
else if (carouselItemType == "3dbox")
carouselEntry.data.logoPath = (*it)->get3DBoxPath();
else if (carouselItemType == "screenshot")
carouselEntry.data.logoPath = (*it)->getScreenshotPath();
else if (carouselItemType == "titlescreen")
carouselEntry.data.logoPath = (*it)->getTitleScreenPath();
else if (carouselItemType == "backcover")
carouselEntry.data.logoPath = (*it)->getBackCoverPath();
else if (carouselItemType == "miximage")
carouselEntry.data.logoPath = (*it)->getMiximagePath();
else if (carouselItemType == "fanart")
carouselEntry.data.logoPath = (*it)->getFanArtPath();
if (carouselDefaultItem != "")
carouselEntry.data.defaultLogoPath = carouselDefaultItem;
mCarousel->addEntry(carouselEntry, theme);
}

View file

@ -136,6 +136,27 @@ 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("itemType")) {
const std::string itemType {element.second.get<std::string>("itemType")};
if (itemType == "marquee" || itemType == "cover" || itemType == "3dbox" ||
itemType == "screenshot" || itemType == "titlescreen" ||
itemType == "backcover" || itemType == "miximage" ||
itemType == "fanart") {
mCarousel->setItemType(itemType);
}
else {
LOG(LogWarning)
<< "GamelistView::onThemeChanged(): Invalid theme configuration, "
"<itemType> property defined as \""
<< itemType << "\"";
mCarousel->setItemType("marquee");
}
}
else {
mCarousel->setItemType("marquee");
}
if (element.second.has("defaultItem"))
mCarousel->setDefaultItem(element.second.get<std::string>("defaultItem"));
mPrimary = mCarousel.get();
}
mPrimary->setCursorChangedCallback(

View file

@ -466,10 +466,10 @@ void SystemView::populate()
}
});
if (mCarousel != nullptr) {
if (element.second.has("logo"))
logoPath = element.second.get<std::string>("logo");
if (element.second.has("defaultLogo"))
defaultLogoPath = element.second.get<std::string>("defaultLogo");
if (element.second.has("staticItem"))
logoPath = element.second.get<std::string>("staticItem");
if (element.second.has("defaultItem"))
defaultLogoPath = element.second.get<std::string>("defaultItem");
}
}
else if (element.second.type == "image") {

View file

@ -48,7 +48,13 @@ std::vector<std::string> ThemeData::sLegacyElements {
{"showSnapshotDelay"},
{"forceUppercase"},
{"alignment"},
{"logoAlignment"}};
{"defaultLogo"},
{"logoSize"},
{"logoScale"},
{"logoRotation"},
{"logoRotationOrigin"},
{"logoAlignment"},
{"maxLogoCount"}};
std::vector<std::pair<std::string, std::string>> ThemeData::sSupportedAspectRatios {
{"16:9", "16:9"},
@ -247,16 +253,23 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"color", COLOR},
{"colorEnd", COLOR},
{"gradientType", STRING},
{"logo", PATH},
{"defaultLogo", PATH},
{"logoSize", NORMALIZED_PAIR},
{"logoScale", FLOAT},
{"logoRotation", FLOAT},
{"logoRotationOrigin", NORMALIZED_PAIR},
{"logoHorizontalAlignment", STRING},
{"logoVerticalAlignment", STRING},
{"staticItem", PATH},
{"itemType", STRING},
{"defaultItem", PATH},
{"itemSize", NORMALIZED_PAIR},
{"itemScale", FLOAT},
{"itemRotation", FLOAT},
{"itemRotationOrigin", NORMALIZED_PAIR},
{"itemHorizontalAlignment", STRING},
{"itemVerticalAlignment", STRING},
{"maxItemCount", FLOAT},
{"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.
{"maxLogoCount", FLOAT},
{"maxLogoCount", FLOAT}, // For backward compatibility with legacy themes.
{"text", STRING},
{"textColor", COLOR},
{"textBackgroundColor", COLOR},

View file

@ -55,6 +55,10 @@ public:
void addEntry(Entry& entry, const std::shared_ptr<ThemeData>& theme = nullptr);
Entry& getEntry(int index) { return mEntries.at(index); }
const CarouselType getType() { return mType; }
const std::string& getItemType() { return mItemType; }
void setItemType(std::string itemType) { mItemType = itemType; }
const std::string& getDefaultItem() { return mDefaultItem; }
void setDefaultItem(std::string defaultItem) { mDefaultItem = defaultItem; }
void setCursorChangedCallback(const std::function<void(CursorState state)>& func) override
{
@ -111,6 +115,8 @@ private:
bool mTriggerJump;
CarouselType mType;
std::string mItemType;
std::string mDefaultItem;
std::shared_ptr<Font> mFont;
unsigned int mTextColor;
unsigned int mTextBackgroundColor;
@ -547,6 +553,75 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
}
}
if (!theme->isLegacyTheme()) {
if (elem->has("itemScale"))
mLogoScale = glm::clamp(elem->get<float>("itemScale"), 0.5f, 3.0f);
if (elem->has("itemSize")) {
// Keep size within a 0.05 and 1.0 multiple of the screen size.
glm::vec2 logoSize {elem->get<glm::vec2>("itemSize")};
if (std::max(logoSize.x, logoSize.y) > 1.0f) {
logoSize /= std::max(logoSize.x, logoSize.y);
}
else if (std::min(logoSize.x, logoSize.y) < 0.005f) {
float ratio {std::min(logoSize.x, logoSize.y) / 0.005f};
logoSize /= ratio;
// Just an extra precaution if a crazy ratio was used.
logoSize.x = glm::clamp(logoSize.x, 0.005f, 1.0f);
logoSize.y = glm::clamp(logoSize.y, 0.005f, 1.0f);
}
mLogoSize =
logoSize * glm::vec2(Renderer::getScreenWidth(), Renderer::getScreenHeight());
}
if (elem->has("maxItemCount"))
mMaxLogoCount = glm::clamp(elem->get<float>("maxItemCount"), 0.5f, 30.0f);
if (elem->has("itemRotation"))
mLogoRotation = elem->get<float>("itemRotation");
if (elem->has("itemRotationOrigin"))
mLogoRotationOrigin = elem->get<glm::vec2>("itemRotationOrigin");
if (elem->has("itemHorizontalAlignment")) {
const std::string alignment {elem->get<std::string>("itemHorizontalAlignment")};
if (alignment == "left" && mType != CarouselType::HORIZONTAL) {
mLogoHorizontalAlignment = ALIGN_LEFT;
}
else if (alignment == "right" && mType != CarouselType::HORIZONTAL) {
mLogoHorizontalAlignment = ALIGN_RIGHT;
}
else if (alignment == "center") {
mLogoHorizontalAlignment = ALIGN_CENTER;
}
else {
LOG(LogWarning) << "CarouselComponent: Invalid theme configuration, property "
"<itemHorizontalAlignment> defined as \""
<< alignment << "\"";
mLogoHorizontalAlignment = ALIGN_CENTER;
}
}
if (elem->has("itemVerticalAlignment")) {
const std::string alignment {elem->get<std::string>("itemVerticalAlignment")};
if (alignment == "top" && mType != CarouselType::VERTICAL) {
mLogoVerticalAlignment = ALIGN_TOP;
}
else if (alignment == "bottom" && mType != CarouselType::VERTICAL) {
mLogoVerticalAlignment = ALIGN_BOTTOM;
}
else if (alignment == "center") {
mLogoVerticalAlignment = ALIGN_CENTER;
}
else {
LOG(LogWarning) << "CarouselComponent: Invalid theme configuration, property "
"<itemVerticalAlignment> defined as \""
<< alignment << "\"";
mLogoVerticalAlignment = ALIGN_CENTER;
}
}
}
// Start of legacy themes only section.
if (elem->has("logoScale"))
mLogoScale = glm::clamp(elem->get<float>("logoScale"), 0.5f, 3.0f);
if (elem->has("logoSize")) {
@ -577,45 +652,6 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (elem->has("logoRotationOrigin"))
mLogoRotationOrigin = elem->get<glm::vec2>("logoRotationOrigin");
if (elem->has("logoHorizontalAlignment")) {
const std::string alignment {elem->get<std::string>("logoHorizontalAlignment")};
if (alignment == "left" && mType != CarouselType::HORIZONTAL) {
mLogoHorizontalAlignment = ALIGN_LEFT;
}
else if (alignment == "right" && mType != CarouselType::HORIZONTAL) {
mLogoHorizontalAlignment = ALIGN_RIGHT;
}
else if (alignment == "center") {
mLogoHorizontalAlignment = ALIGN_CENTER;
}
else {
LOG(LogWarning) << "CarouselComponent: Invalid theme configuration, property "
"<logoHorizontalAlignment> defined as \""
<< alignment << "\"";
mLogoHorizontalAlignment = ALIGN_CENTER;
}
}
if (elem->has("logoVerticalAlignment")) {
const std::string alignment {elem->get<std::string>("logoVerticalAlignment")};
if (alignment == "top" && mType != CarouselType::VERTICAL) {
mLogoVerticalAlignment = ALIGN_TOP;
}
else if (alignment == "bottom" && mType != CarouselType::VERTICAL) {
mLogoVerticalAlignment = ALIGN_BOTTOM;
}
else if (alignment == "center") {
mLogoVerticalAlignment = ALIGN_CENTER;
}
else {
LOG(LogWarning) << "CarouselComponent: Invalid theme configuration, property "
"<logoVerticalAlignment> defined as \""
<< alignment << "\"";
mLogoVerticalAlignment = ALIGN_CENTER;
}
}
// Legacy themes only.
if (elem->has("logoAlignment")) {
const std::string alignment {elem->get<std::string>("logoAlignment")};
if (alignment == "left" && mType != CarouselType::HORIZONTAL) {
@ -647,6 +683,8 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
}
}
// End of legacy theme section.
mFont = Font::getFromTheme(elem, properties, mFont);
if (elem->has("textColor"))