Changed a number of property names in CarouselComponent and GridComponent.

This commit is contained in:
Leon Styhre 2022-12-11 11:22:08 +01:00
parent 51e06641f5
commit 0b5419316d
7 changed files with 342 additions and 272 deletions

View file

@ -577,17 +577,17 @@ void GamelistBase::populateList(const std::vector<FileData*>& files, FileData* f
auto theme = mRoot->getSystem()->getTheme();
std::string name;
std::string defaultItem;
std::string defaultImage;
if (mCarousel != nullptr) {
defaultItem = mCarousel->getDefaultItem();
if (!ResourceManager::getInstance().fileExists(defaultItem))
defaultItem = "";
defaultImage = mCarousel->getDefaultImage();
if (!ResourceManager::getInstance().fileExists(defaultImage))
defaultImage = "";
}
else if (mGrid != nullptr) {
defaultItem = mGrid->getDefaultItem();
if (!ResourceManager::getInstance().fileExists(defaultItem))
defaultItem = "";
defaultImage = mGrid->getDefaultImage();
if (!ResourceManager::getInstance().fileExists(defaultImage))
defaultImage = "";
}
if (files.size() > 0) {
@ -617,8 +617,8 @@ void GamelistBase::populateList(const std::vector<FileData*>& files, FileData* f
else if (letterCase == LetterCase::CAPITALIZED)
carouselEntry.name = Utils::String::toCapitalized(carouselEntry.name);
if (defaultItem != "")
carouselEntry.data.defaultItemPath = defaultItem;
if (defaultImage != "")
carouselEntry.data.defaultImagePath = defaultImage;
mCarousel->addEntry(carouselEntry, theme);
}
@ -634,8 +634,8 @@ void GamelistBase::populateList(const std::vector<FileData*>& files, FileData* f
else if (letterCase == LetterCase::CAPITALIZED)
gridEntry.name = Utils::String::toCapitalized(gridEntry.name);
if (defaultItem != "")
gridEntry.data.defaultItemPath = defaultItem;
if (defaultImage != "")
gridEntry.data.defaultImagePath = defaultImage;
mGrid->addEntry(gridEntry, theme);
}

View file

@ -155,14 +155,33 @@ 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")) {
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->setItemType(itemType);
mCarousel->setImageType(itemType);
}
else {
LOG(LogWarning) << "GamelistView::onThemeChanged(): Invalid theme "
@ -170,14 +189,17 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
"for element \""
<< element.first.substr(9) << "\" defined as \""
<< itemType << "\"";
mCarousel->setItemType("marquee");
mCarousel->setImageType("marquee");
}
}
else {
mCarousel->setItemType("marquee");
mCarousel->setImageType("marquee");
}
// TEMPORARY: Backward compatiblity due to property name changes.
if (element.second.has("defaultItem"))
mCarousel->setDefaultItem(element.second.get<std::string>("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(
@ -189,29 +211,29 @@ 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("itemType")) {
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") {
mGrid->setItemType(itemType);
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 \"itemType\" "
"configuration, grid property \"imageType\" "
"for element \""
<< element.first.substr(5) << "\" defined as \""
<< itemType << "\"";
mGrid->setItemType("marquee");
<< imageType << "\"";
mGrid->setImageType("marquee");
}
}
else {
mGrid->setItemType("marquee");
mGrid->setImageType("marquee");
}
if (element.second.has("defaultItem"))
mGrid->setDefaultItem(element.second.get<std::string>("defaultItem"));
if (element.second.has("defaultImage"))
mGrid->setDefaultImage(element.second.get<std::string>("defaultImage"));
mPrimary = mGrid.get();
}
mPrimary->setCursorChangedCallback(

View file

@ -466,8 +466,8 @@ void SystemView::populate()
for (auto it : SystemData::sSystemVector) {
const std::shared_ptr<ThemeData>& theme {it->getTheme()};
std::string itemPath;
std::string defaultItemPath;
std::string imagePath;
std::string defaultImagePath;
std::string itemText;
if (mLegacyMode && mViewNeedsReload) {
@ -575,10 +575,18 @@ void SystemView::populate()
}
});
if (mCarousel != nullptr || mGrid != nullptr) {
if (element.second.has("staticItem"))
itemPath = element.second.get<std::string>("staticItem");
if (element.second.has("defaultItem"))
defaultItemPath = element.second.get<std::string>("defaultItem");
if (mCarousel != nullptr) {
// TEMPORARY: Backward compatiblity due to property name changes.
if (element.second.has("staticItem"))
imagePath = element.second.get<std::string>("staticItem");
if (element.second.has("defaultItem"))
defaultImagePath =
element.second.get<std::string>("defaultItem");
}
if (element.second.has("staticImage"))
imagePath = element.second.get<std::string>("staticImage");
if (element.second.has("defaultImage"))
defaultImagePath = element.second.get<std::string>("defaultImage");
if (element.second.has("text"))
itemText = element.second.get<std::string>("text");
}
@ -755,8 +763,8 @@ void SystemView::populate()
}
letterCaseFunc(entry.name);
entry.object = it;
entry.data.itemPath = itemPath;
entry.data.defaultItemPath = defaultItemPath;
entry.data.imagePath = imagePath;
entry.data.defaultImagePath = defaultImagePath;
mCarousel->addEntry(entry, theme);
}
else if (mGrid != nullptr) {
@ -767,8 +775,8 @@ void SystemView::populate()
entry.name = itemText;
letterCaseFunc(entry.name);
entry.object = it;
entry.data.itemPath = itemPath;
entry.data.defaultItemPath = defaultItemPath;
entry.data.imagePath = imagePath;
entry.data.defaultImagePath = defaultImagePath;
mGrid->addEntry(entry, theme);
}
else if (mTextList != nullptr) {

View file

@ -43,7 +43,7 @@ std::vector<std::string> ThemeData::sLegacySupportedFeatures {
{"z-index"},
{"visible"}};
std::vector<std::string> ThemeData::sLegacyElements {
std::vector<std::string> ThemeData::sLegacyProperties {
{"showSnapshotNoVideo"},
{"showSnapshotDelay"},
{"forceUppercase"},
@ -56,6 +56,12 @@ std::vector<std::string> ThemeData::sLegacyElements {
{"logoAlignment"},
{"maxLogoCount"}};
std::vector<std::string> ThemeData::sDeprecatedProperties {
{"staticItem"},
{"itemType"},
{"defaultItem"},
{"itemInterpolation"}};
std::vector<std::pair<std::string, std::string>> ThemeData::sSupportedAspectRatios {
{"automatic", "automatic"},
{"16:9", "16:9"},
@ -106,22 +112,26 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"size", NORMALIZED_PAIR},
{"origin", NORMALIZED_PAIR},
{"type", STRING},
{"staticItem", PATH},
{"itemType", STRING},
{"defaultItem", PATH},
{"staticImage", PATH},
{"imageType", STRING},
{"defaultImage", PATH},
{"staticItem", PATH}, // TEMPORARY: For backward compatibility.
{"itemType", STRING}, // TEMPORARY: For backward compatibility.
{"defaultItem", PATH}, // TEMPORARY: For backward compatibility.
{"maxItemCount", FLOAT},
{"maxLogoCount", FLOAT}, // For backward compatibility with legacy themes.
{"itemsBeforeCenter", UNSIGNED_INTEGER},
{"itemsAfterCenter", UNSIGNED_INTEGER},
{"itemSize", NORMALIZED_PAIR},
{"itemScale", FLOAT},
{"itemInterpolation", STRING},
{"itemRotation", FLOAT},
{"itemRotationOrigin", NORMALIZED_PAIR},
{"itemAxisHorizontal", BOOLEAN},
{"itemColor", COLOR},
{"itemColorEnd", COLOR},
{"itemGradientType", STRING},
{"itemInterpolation", STRING}, // TEMPORARY: For backward compatibility.
{"imageInterpolation", STRING},
{"imageColor", COLOR},
{"imageColorEnd", COLOR},
{"imageGradientType", STRING},
{"itemTransitions", STRING},
{"itemHorizontalAlignment", STRING},
{"itemVerticalAlignment", STRING},
@ -157,9 +167,22 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{{"pos", NORMALIZED_PAIR},
{"size", NORMALIZED_PAIR},
{"origin", NORMALIZED_PAIR},
{"staticItem", PATH},
{"itemType", STRING},
{"defaultItem", PATH},
{"staticImage", PATH},
{"imageType", STRING},
{"defaultImage", PATH},
{"itemSize", NORMALIZED_PAIR},
{"itemScale", FLOAT},
{"itemSpacing", NORMALIZED_PAIR},
{"fractionalRows", BOOLEAN},
{"itemTransitions", STRING},
{"rowTransitions", STRING},
{"unfocusedItemOpacity", FLOAT},
{"edgeScaleInwards", BOOLEAN}, // TODO
{"imageRelativeScale", FLOAT},
{"imageFit", STRING},
{"imageColor", COLOR},
{"imageColorEnd", COLOR},
{"imageGradientType", STRING},
{"backgroundImage", PATH},
{"backgroundRelativeScale", FLOAT},
{"backgroundColor", COLOR},
@ -171,19 +194,6 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"selectorColorEnd", COLOR},
{"selectorGradientType", STRING},
{"selectorLayer", STRING},
{"fractionalRows", BOOLEAN},
{"itemSize", NORMALIZED_PAIR},
{"itemScale", FLOAT},
{"itemRelativeScale", FLOAT},
{"itemFit", STRING},
{"itemSpacing", NORMALIZED_PAIR},
{"itemColor", COLOR},
{"itemColorEnd", COLOR},
{"itemGradientType", STRING},
{"itemTransitions", STRING},
{"rowTransitions", STRING},
{"unfocusedItemOpacity", FLOAT},
{"edgeScaleInwards", BOOLEAN},
{"text", STRING},
{"textRelativeScale", FLOAT},
{"textColor", COLOR},
@ -1461,17 +1471,29 @@ void ThemeData::parseElement(const pugi::xml_node& root,
std::string nodeName = node.name();
// Strictly enforce removal of legacy elements for non-legacy theme sets by creating
// Strictly enforce removal of legacy properties for non-legacy theme sets by creating
// an unthemed system if they're present in the configuration.
if (!mLegacyTheme) {
for (auto& legacyElement : sLegacyElements) {
if (nodeName == legacyElement) {
for (auto& legacyProperty : sLegacyProperties) {
if (nodeName == legacyProperty) {
throw error << ": Legacy <" << nodeName
<< "> property found for non-legacy theme set";
}
}
}
// Print a warning if a deprecated property is used for a non-legacy theme set.
if (!mLegacyTheme) {
for (auto& deprecatedProperty : sDeprecatedProperties) {
if (nodeName == deprecatedProperty) {
LOG(LogWarning)
<< "ThemeData::parseElement(): Property \"" << deprecatedProperty
<< "\" is deprecated and support for it will be removed in a future "
"version";
}
}
}
// If an attribute exists, then replace nodeName with its name.
auto attributeEntry = sPropertyAttributeMap.find(element.type);
if (attributeEntry != sPropertyAttributeMap.end()) {

View file

@ -281,7 +281,8 @@ private:
static std::vector<std::string> sSupportedViews;
static std::vector<std::string> sLegacySupportedViews;
static std::vector<std::string> sLegacySupportedFeatures;
static std::vector<std::string> sLegacyElements;
static std::vector<std::string> sLegacyProperties;
static std::vector<std::string> sDeprecatedProperties;
static std::vector<std::pair<std::string, std::string>> sSupportedAspectRatios;
static std::map<std::string, float> sAspectRatioMap;

View file

@ -17,8 +17,8 @@
struct CarouselEntry {
std::shared_ptr<GuiComponent> item;
std::string itemPath;
std::string defaultItemPath;
std::string imagePath;
std::string defaultImagePath;
};
template <typename T>
@ -53,10 +53,10 @@ public:
Entry& getEntry(int index) { return mEntries.at(index); }
void onDemandTextureLoad() override;
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; }
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(); }
const LetterCase getLetterCase() const override { return mLetterCase; }
const LetterCase getLetterCaseCollections() const override { return mLetterCaseCollections; }
@ -124,20 +124,20 @@ private:
bool mLegacyMode;
CarouselType mType;
std::string mItemType;
std::string mDefaultItem;
std::string mImageType;
std::string mDefaultImage;
float mMaxItemCount;
int mItemsBeforeCenter;
int mItemsAfterCenter;
glm::vec2 mItemSize;
float mItemScale;
bool mLinearInterpolation;
float mItemRotation;
glm::vec2 mItemRotationOrigin;
bool mItemAxisHorizontal;
unsigned int mItemColorShift;
unsigned int mItemColorShiftEnd;
bool mItemColorGradientHorizontal;
bool mLinearInterpolation;
unsigned int mImageColorShift;
unsigned int mImageColorShiftEnd;
bool mImageColorGradientHorizontal;
bool mInstantItemTransitions;
Alignment mItemHorizontalAlignment;
Alignment mItemVerticalAlignment;
@ -182,13 +182,13 @@ CarouselComponent<T>::CarouselComponent()
, mItemSize {glm::vec2 {Renderer::getScreenWidth() * 0.25f,
Renderer::getScreenHeight() * 0.155f}}
, mItemScale {1.2f}
, mLinearInterpolation {false}
, mItemRotation {7.5f}
, mItemRotationOrigin {-3.0f, 0.5f}
, mItemAxisHorizontal {false}
, mItemColorShift {0xFFFFFFFF}
, mItemColorShiftEnd {0xFFFFFFFF}
, mItemColorGradientHorizontal {true}
, mLinearInterpolation {false}
, mImageColorShift {0xFFFFFFFF}
, mImageColorShiftEnd {0xFFFFFFFF}
, mImageColorGradientHorizontal {true}
, mInstantItemTransitions {false}
, mItemHorizontalAlignment {ALIGN_CENTER}
, mItemVerticalAlignment {ALIGN_CENTER}
@ -245,46 +245,45 @@ void CarouselComponent<T>::addEntry(Entry& entry, const std::shared_ptr<ThemeDat
}
}
else {
if (entry.data.itemPath != "" &&
ResourceManager::getInstance().fileExists(entry.data.itemPath)) {
if (entry.data.imagePath != "" &&
ResourceManager::getInstance().fileExists(entry.data.imagePath)) {
auto item = std::make_shared<ImageComponent>(false, dynamic);
item->setLinearInterpolation(mLinearInterpolation);
item->setMipmapping(true);
item->setMaxSize(glm::round(mItemSize * (mItemScale >= 1.0f ? mItemScale : 1.0f)));
item->setImage(entry.data.itemPath);
item->setImage(entry.data.imagePath);
item->applyTheme(theme, "system", "", ThemeFlags::ALL);
if (mItemColorShift != 0xFFFFFFFF)
item->setColorShift(mItemColorShift);
if (mItemColorShiftEnd != mItemColorShift)
item->setColorShiftEnd(mItemColorShiftEnd);
if (!mItemColorGradientHorizontal)
if (mImageColorShift != 0xFFFFFFFF)
item->setColorShift(mImageColorShift);
if (mImageColorShiftEnd != mImageColorShift)
item->setColorShiftEnd(mImageColorShiftEnd);
if (!mImageColorGradientHorizontal)
item->setColorGradientHorizontal(false);
item->setRotateByTargetSize(true);
entry.data.item = item;
}
else if (entry.data.defaultItemPath != "" &&
ResourceManager::getInstance().fileExists(entry.data.defaultItemPath)) {
auto defaultItem = std::make_shared<ImageComponent>(false, dynamic);
defaultItem->setLinearInterpolation(mLinearInterpolation);
defaultItem->setMipmapping(true);
defaultItem->setMaxSize(
else if (entry.data.defaultImagePath != "" &&
ResourceManager::getInstance().fileExists(entry.data.defaultImagePath)) {
auto defaultImage = std::make_shared<ImageComponent>(false, dynamic);
defaultImage->setLinearInterpolation(mLinearInterpolation);
defaultImage->setMipmapping(true);
defaultImage->setMaxSize(
glm::round(mItemSize * (mItemScale >= 1.0f ? mItemScale : 1.0f)));
defaultItem->setImage(entry.data.defaultItemPath);
defaultItem->applyTheme(theme, "system", "", ThemeFlags::ALL);
if (mItemColorShift != 0xFFFFFFFF)
defaultItem->setColorShift(mItemColorShift);
if (mItemColorShiftEnd != mItemColorShift)
defaultItem->setColorShiftEnd(mItemColorShiftEnd);
if (!mItemColorGradientHorizontal)
defaultItem->setColorGradientHorizontal(false);
defaultItem->setRotateByTargetSize(true);
entry.data.item = defaultItem;
defaultImage->setImage(entry.data.defaultImagePath);
defaultImage->applyTheme(theme, "system", "", ThemeFlags::ALL);
if (mImageColorShift != 0xFFFFFFFF)
defaultImage->setColorShift(mImageColorShift);
if (mImageColorShiftEnd != mImageColorShift)
defaultImage->setColorShiftEnd(mImageColorShiftEnd);
if (!mImageColorGradientHorizontal)
defaultImage->setColorGradientHorizontal(false);
defaultImage->setRotateByTargetSize(true);
entry.data.item = defaultImage;
}
}
if (!entry.data.item) {
// If no item image is present, add item text as fallback.
auto text = std::make_shared<TextComponent>(
entry.name, mFont, 0x000000FF, mItemHorizontalAlignment, mItemVerticalAlignment,
glm::vec3 {0.0f, 0.0f, 0.0f},
@ -330,18 +329,18 @@ void CarouselComponent<T>::addEntry(Entry& entry, const std::shared_ptr<ThemeDat
template <typename T>
void CarouselComponent<T>::updateEntry(Entry& entry, const std::shared_ptr<ThemeData>& theme)
{
if (entry.data.itemPath != "") {
if (entry.data.imagePath != "") {
auto item = std::make_shared<ImageComponent>(false, true);
item->setLinearInterpolation(mLinearInterpolation);
item->setMipmapping(true);
item->setMaxSize(glm::round(mItemSize * (mItemScale >= 1.0f ? mItemScale : 1.0f)));
item->setImage(entry.data.itemPath);
item->setImage(entry.data.imagePath);
item->applyTheme(theme, "system", "", ThemeFlags::ALL);
if (mItemColorShift != 0xFFFFFFFF)
item->setColorShift(mItemColorShift);
if (mItemColorShiftEnd != mItemColorShift)
item->setColorShiftEnd(mItemColorShiftEnd);
if (!mItemColorGradientHorizontal)
if (mImageColorShift != 0xFFFFFFFF)
item->setColorShift(mImageColorShift);
if (mImageColorShiftEnd != mImageColorShift)
item->setColorShiftEnd(mImageColorShiftEnd);
if (!mImageColorGradientHorizontal)
item->setColorGradientHorizontal(false);
item->setRotateByTargetSize(true);
entry.data.item = item;
@ -432,28 +431,28 @@ template <typename T> void CarouselComponent<T>::onDemandTextureLoad()
auto& entry = mEntries.at(cursor);
if (entry.data.itemPath == "") {
if (entry.data.imagePath == "") {
FileData* game {entry.object};
if (mItemType == "" || mItemType == "marquee")
entry.data.itemPath = game->getMarqueePath();
else if (mItemType == "cover")
entry.data.itemPath = game->getCoverPath();
else if (mItemType == "backcover")
entry.data.itemPath = game->getBackCoverPath();
else if (mItemType == "3dbox")
entry.data.itemPath = game->get3DBoxPath();
else if (mItemType == "physicalmedia")
entry.data.itemPath = game->getPhysicalMediaPath();
else if (mItemType == "screenshot")
entry.data.itemPath = game->getScreenshotPath();
else if (mItemType == "titlescreen")
entry.data.itemPath = game->getTitleScreenPath();
else if (mItemType == "miximage")
entry.data.itemPath = game->getMiximagePath();
else if (mItemType == "fanart")
entry.data.itemPath = game->getFanArtPath();
else if (mItemType == "none") // Display the game name as text.
if (mImageType == "" || mImageType == "marquee")
entry.data.imagePath = game->getMarqueePath();
else if (mImageType == "cover")
entry.data.imagePath = game->getCoverPath();
else if (mImageType == "backcover")
entry.data.imagePath = game->getBackCoverPath();
else if (mImageType == "3dbox")
entry.data.imagePath = game->get3DBoxPath();
else if (mImageType == "physicalmedia")
entry.data.imagePath = game->getPhysicalMediaPath();
else if (mImageType == "screenshot")
entry.data.imagePath = game->getScreenshotPath();
else if (mImageType == "titlescreen")
entry.data.imagePath = game->getTitleScreenPath();
else if (mImageType == "miximage")
entry.data.imagePath = game->getMiximagePath();
else if (mImageType == "fanart")
entry.data.imagePath = game->getFanArtPath();
else if (mImageType == "none") // Display the game name as text.
return;
auto theme = game->getSystem()->getTheme();
@ -910,8 +909,8 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
// TODO: Rewrite to use "real" reflections instead of this hack.
// Don't attempt to add reflections for text entries.
if (mReflections && (mEntries.at(renderItem.index).data.itemPath != "" ||
mEntries.at(renderItem.index).data.defaultItemPath != "")) {
if (mReflections && (mEntries.at(renderItem.index).data.imagePath != "" ||
mEntries.at(renderItem.index).data.defaultImagePath != "")) {
glm::mat4 reflectionTrans {glm::translate(
renderItem.trans, glm::vec3 {0.0f, comp->getSize().y * renderItem.scale, 0.0f})};
float falloff {glm::clamp(mReflectionsFalloff, 0.0f, 1.0f)};
@ -1032,6 +1031,7 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
mItemScale = glm::clamp(elem->get<float>("itemScale"), 0.2f, 3.0f);
if (elem->has("itemInterpolation")) {
// TEMPORARY: Backward compatiblity due to property name changes.
const std::string& itemInterpolation {elem->get<std::string>("itemInterpolation")};
if (itemInterpolation == "linear") {
mLinearInterpolation = true;
@ -1048,6 +1048,23 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
}
}
if (elem->has("imageInterpolation")) {
const std::string& imageInterpolation {elem->get<std::string>("imageInterpolation")};
if (imageInterpolation == "linear") {
mLinearInterpolation = true;
}
else if (imageInterpolation == "nearest") {
mLinearInterpolation = false;
}
else {
mLinearInterpolation = true;
LOG(LogWarning) << "CarouselComponent: Invalid theme configuration, property "
"\"imageInterpolation\" for element \""
<< element.substr(9) << "\" defined as \"" << imageInterpolation
<< "\"";
}
}
if (elem->has("itemTransitions")) {
const std::string& itemTransitions {elem->get<std::string>("itemTransitions")};
if (itemTransitions == "animate") {
@ -1074,25 +1091,25 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
mItemAxisHorizontal =
(elem->has("itemAxisHorizontal") && elem->get<bool>("itemAxisHorizontal"));
if (elem->has("itemColor")) {
mItemColorShift = elem->get<unsigned int>("itemColor");
mItemColorShiftEnd = mItemColorShift;
if (elem->has("imageColor")) {
mImageColorShift = elem->get<unsigned int>("imageColor");
mImageColorShiftEnd = mImageColorShift;
}
if (elem->has("itemColorEnd"))
mItemColorShiftEnd = elem->get<unsigned int>("itemColorEnd");
if (elem->has("imageColorEnd"))
mImageColorShiftEnd = elem->get<unsigned int>("imageColorEnd");
if (elem->has("itemGradientType")) {
const std::string& gradientType {elem->get<std::string>("itemGradientType")};
if (elem->has("imageGradientType")) {
const std::string& gradientType {elem->get<std::string>("imageGradientType")};
if (gradientType == "horizontal") {
mItemColorGradientHorizontal = true;
mImageColorGradientHorizontal = true;
}
else if (gradientType == "vertical") {
mItemColorGradientHorizontal = false;
mImageColorGradientHorizontal = false;
}
else {
mItemColorGradientHorizontal = true;
mImageColorGradientHorizontal = true;
LOG(LogWarning) << "CarouselComponent: Invalid theme configuration, property "
"\"gradientType\" for element \""
"\"imageGradientType\" for element \""
<< element.substr(9) << "\" defined as \"" << gradientType << "\"";
}
}

View file

@ -14,8 +14,8 @@
struct GridEntry {
std::shared_ptr<GuiComponent> item;
std::string itemPath;
std::string defaultItemPath;
std::string imagePath;
std::string defaultImagePath;
};
template <typename T>
@ -62,10 +62,10 @@ public:
{
return mLetterCaseGroupedCollections;
}
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; }
const std::string& getImageType() { return mImageType; }
void setImageType(std::string imageType) { mImageType = imageType; }
const std::string& getDefaultImage() { return mDefaultImage; }
void setDefaultImage(std::string defaultItem) { mDefaultImage = defaultItem; }
bool input(InputConfig* config, Input input) override;
void update(int deltaTime) override;
void render(const glm::mat4& parentTrans) override;
@ -110,7 +110,7 @@ private:
BOTTOM
};
enum class ItemFit {
enum class ImageFit {
CONTAIN,
FILL,
COVER
@ -130,9 +130,23 @@ private:
bool mWasScrolling;
bool mJustCalculatedLayout;
bool mSuppressTransitions;
float mHorizontalMargin;
float mVerticalMargin;
std::string mItemType;
std::string mDefaultItem;
std::string mImageType;
std::string mDefaultImage;
glm::vec2 mItemSize;
float mItemScale;
glm::vec2 mItemSpacing;
bool mFractionalRows;
bool mInstantItemTransitions;
bool mInstantRowTransitions;
float mUnfocusedItemOpacity;
float mImageRelativeScale;
ImageFit mImagefit;
unsigned int mImageColor;
unsigned int mImageColorEnd;
bool mImageColorGradientHorizontal;
std::unique_ptr<ImageComponent> mBackgroundImage;
float mBackgroundRelativeScale;
unsigned int mBackgroundColor;
@ -146,18 +160,6 @@ private:
bool mSelectorColorGradientHorizontal;
bool mHasSelectorColor;
SelectorLayer mSelectorLayer;
bool mFractionalRows;
glm::vec2 mItemSize;
float mItemScale;
float mItemRelativeScale;
ItemFit mItemFit;
glm::vec2 mItemSpacing;
unsigned int mItemColor;
unsigned int mItemColorEnd;
bool mItemColorGradientHorizontal;
bool mInstantItemTransitions;
bool mInstantRowTransitions;
float mUnfocusedItemOpacity;
float mTextRelativeScale;
unsigned int mTextColor;
unsigned int mTextBackgroundColor;
@ -167,8 +169,6 @@ private:
LetterCase mLetterCaseGroupedCollections;
float mLineSpacing;
bool mFadeAbovePrimary;
float mHorizontalMargin;
float mVerticalMargin;
};
template <typename T>
@ -186,6 +186,21 @@ GridComponent<T>::GridComponent()
, mWasScrolling {false}
, mJustCalculatedLayout {false}
, mSuppressTransitions {false}
, mHorizontalMargin {0.0f}
, mVerticalMargin {0.0f}
, mItemSize {glm::vec2 {mRenderer->getScreenWidth() * 0.15f,
mRenderer->getScreenHeight() * 0.25f}}
, mItemScale {1.05f}
, mItemSpacing {0.0f, 0.0f}
, mFractionalRows {false}
, mInstantItemTransitions {false}
, mInstantRowTransitions {false}
, mUnfocusedItemOpacity {1.0f}
, mImageRelativeScale {1.0f}
, mImagefit {ImageFit::CONTAIN}
, mImageColor {0xFFFFFFFF}
, mImageColorEnd {0xFFFFFFFF}
, mImageColorGradientHorizontal {true}
, mBackgroundRelativeScale {1.0f}
, mBackgroundColor {0xFFFFFFFF}
, mBackgroundColorEnd {0xFFFFFFFF}
@ -197,19 +212,6 @@ GridComponent<T>::GridComponent()
, mSelectorColorGradientHorizontal {true}
, mHasSelectorColor {false}
, mSelectorLayer {SelectorLayer::TOP}
, mFractionalRows {false}
, mItemSize {glm::vec2 {mRenderer->getScreenWidth() * 0.15f,
mRenderer->getScreenHeight() * 0.25f}}
, mItemScale {1.05f}
, mItemRelativeScale {1.0f}
, mItemFit {ItemFit::CONTAIN}
, mItemSpacing {0.0f, 0.0f}
, mItemColor {0xFFFFFFFF}
, mItemColorEnd {0xFFFFFFFF}
, mItemColorGradientHorizontal {true}
, mInstantItemTransitions {false}
, mInstantRowTransitions {false}
, mUnfocusedItemOpacity {1.0f}
, mTextRelativeScale {1.0f}
, mTextColor {0x000000FF}
, mTextBackgroundColor {0xFFFFFF00}
@ -218,8 +220,6 @@ GridComponent<T>::GridComponent()
, mLetterCaseGroupedCollections {LetterCase::NONE}
, mLineSpacing {1.5f}
, mFadeAbovePrimary {false}
, mHorizontalMargin {0.0f}
, mVerticalMargin {0.0f}
{
}
@ -228,48 +228,48 @@ void GridComponent<T>::addEntry(Entry& entry, const std::shared_ptr<ThemeData>&
{
const bool dynamic {mGamelistView};
if (entry.data.itemPath != "" &&
ResourceManager::getInstance().fileExists(entry.data.itemPath)) {
if (entry.data.imagePath != "" &&
ResourceManager::getInstance().fileExists(entry.data.imagePath)) {
auto item = std::make_shared<ImageComponent>(false, dynamic);
item->setLinearInterpolation(true);
item->setMipmapping(true);
if (mItemFit == ItemFit::CONTAIN)
item->setMaxSize(mItemSize * mItemRelativeScale);
else if (mItemFit == ItemFit::FILL)
item->setResize(mItemSize * mItemRelativeScale);
else if (mItemFit == ItemFit::COVER)
item->setCroppedSize(mItemSize * mItemRelativeScale);
item->setImage(entry.data.itemPath);
if (mImagefit == ImageFit::CONTAIN)
item->setMaxSize(mItemSize * mImageRelativeScale);
else if (mImagefit == ImageFit::FILL)
item->setResize(mItemSize * mImageRelativeScale);
else if (mImagefit == ImageFit::COVER)
item->setCroppedSize(mItemSize * mImageRelativeScale);
item->setImage(entry.data.imagePath);
item->applyTheme(theme, "system", "", ThemeFlags::ALL);
if (mItemColor != 0xFFFFFFFF)
item->setColorShift(mItemColor);
if (mItemColorEnd != mItemColor) {
item->setColorShiftEnd(mItemColorEnd);
if (!mItemColorGradientHorizontal)
if (mImageColor != 0xFFFFFFFF)
item->setColorShift(mImageColor);
if (mImageColorEnd != mImageColor) {
item->setColorShiftEnd(mImageColorEnd);
if (!mImageColorGradientHorizontal)
item->setColorGradientHorizontal(false);
}
item->setOrigin(0.5f, 0.5f);
item->setRotateByTargetSize(true);
entry.data.item = item;
}
else if (entry.data.defaultItemPath != "" &&
ResourceManager::getInstance().fileExists(entry.data.defaultItemPath)) {
else if (entry.data.defaultImagePath != "" &&
ResourceManager::getInstance().fileExists(entry.data.defaultImagePath)) {
auto defaultItem = std::make_shared<ImageComponent>(false, dynamic);
defaultItem->setLinearInterpolation(true);
defaultItem->setMipmapping(true);
if (mItemFit == ItemFit::CONTAIN)
defaultItem->setMaxSize(mItemSize * mItemRelativeScale);
else if (mItemFit == ItemFit::FILL)
defaultItem->setResize(mItemSize * mItemRelativeScale);
else if (mItemFit == ItemFit::COVER)
defaultItem->setCroppedSize(mItemSize * mItemRelativeScale);
defaultItem->setImage(entry.data.defaultItemPath);
if (mImagefit == ImageFit::CONTAIN)
defaultItem->setMaxSize(mItemSize * mImageRelativeScale);
else if (mImagefit == ImageFit::FILL)
defaultItem->setResize(mItemSize * mImageRelativeScale);
else if (mImagefit == ImageFit::COVER)
defaultItem->setCroppedSize(mItemSize * mImageRelativeScale);
defaultItem->setImage(entry.data.defaultImagePath);
defaultItem->applyTheme(theme, "system", "", ThemeFlags::ALL);
if (mItemColor != 0xFFFFFFFF)
defaultItem->setColorShift(mItemColor);
if (mItemColorEnd != mItemColor) {
defaultItem->setColorShiftEnd(mItemColorEnd);
if (!mItemColorGradientHorizontal)
if (mImageColor != 0xFFFFFFFF)
defaultItem->setColorShift(mImageColor);
if (mImageColorEnd != mImageColor) {
defaultItem->setColorShiftEnd(mImageColorEnd);
if (!mImageColorGradientHorizontal)
defaultItem->setColorGradientHorizontal(false);
}
defaultItem->setOrigin(0.5f, 0.5f);
@ -299,24 +299,24 @@ void GridComponent<T>::addEntry(Entry& entry, const std::shared_ptr<ThemeData>&
template <typename T>
void GridComponent<T>::updateEntry(Entry& entry, const std::shared_ptr<ThemeData>& theme)
{
if (entry.data.itemPath != "") {
if (entry.data.imagePath != "") {
const glm::vec3& calculatedItemPos {entry.data.item->getPosition()};
auto item = std::make_shared<ImageComponent>(false, true);
item->setLinearInterpolation(true);
item->setMipmapping(true);
if (mItemFit == ItemFit::CONTAIN)
item->setMaxSize(mItemSize * mItemRelativeScale);
else if (mItemFit == ItemFit::FILL)
item->setResize(mItemSize * mItemRelativeScale);
else if (mItemFit == ItemFit::COVER)
item->setCroppedSize(mItemSize * mItemRelativeScale);
item->setImage(entry.data.itemPath);
if (mImagefit == ImageFit::CONTAIN)
item->setMaxSize(mItemSize * mImageRelativeScale);
else if (mImagefit == ImageFit::FILL)
item->setResize(mItemSize * mImageRelativeScale);
else if (mImagefit == ImageFit::COVER)
item->setCroppedSize(mItemSize * mImageRelativeScale);
item->setImage(entry.data.imagePath);
item->applyTheme(theme, "system", "", ThemeFlags::ALL);
if (mItemColor != 0xFFFFFFFF)
item->setColorShift(mItemColor);
if (mItemColorEnd != mItemColor) {
item->setColorShiftEnd(mItemColorEnd);
if (!mItemColorGradientHorizontal)
if (mImageColor != 0xFFFFFFFF)
item->setColorShift(mImageColor);
if (mImageColorEnd != mImageColor) {
item->setColorShiftEnd(mImageColorEnd);
if (!mImageColorGradientHorizontal)
item->setColorGradientHorizontal(false);
}
item->setOrigin(0.5f, 0.5f);
@ -368,28 +368,28 @@ template <typename T> void GridComponent<T>::onDemandTextureLoad()
auto& entry = mEntries.at(cursor);
if (entry.data.itemPath == "") {
if (entry.data.imagePath == "") {
FileData* game {entry.object};
if (mItemType == "" || mItemType == "marquee")
entry.data.itemPath = game->getMarqueePath();
else if (mItemType == "cover")
entry.data.itemPath = game->getCoverPath();
else if (mItemType == "backcover")
entry.data.itemPath = game->getBackCoverPath();
else if (mItemType == "3dbox")
entry.data.itemPath = game->get3DBoxPath();
else if (mItemType == "physicalmedia")
entry.data.itemPath = game->getPhysicalMediaPath();
else if (mItemType == "screenshot")
entry.data.itemPath = game->getScreenshotPath();
else if (mItemType == "titlescreen")
entry.data.itemPath = game->getTitleScreenPath();
else if (mItemType == "miximage")
entry.data.itemPath = game->getMiximagePath();
else if (mItemType == "fanart")
entry.data.itemPath = game->getFanArtPath();
else if (mItemType == "none") // Display the game name as text.
if (mImageType == "" || mImageType == "marquee")
entry.data.imagePath = game->getMarqueePath();
else if (mImageType == "cover")
entry.data.imagePath = game->getCoverPath();
else if (mImageType == "backcover")
entry.data.imagePath = game->getBackCoverPath();
else if (mImageType == "3dbox")
entry.data.imagePath = game->get3DBoxPath();
else if (mImageType == "physicalmedia")
entry.data.imagePath = game->getPhysicalMediaPath();
else if (mImageType == "screenshot")
entry.data.imagePath = game->getScreenshotPath();
else if (mImageType == "titlescreen")
entry.data.imagePath = game->getTitleScreenPath();
else if (mImageType == "miximage")
entry.data.imagePath = game->getMiximagePath();
else if (mImageType == "fanart")
entry.data.imagePath = game->getFanArtPath();
else if (mImageType == "none") // Display the game name as text.
return;
auto theme = game->getSystem()->getTheme();
@ -765,25 +765,25 @@ void GridComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (elem->has("itemScale"))
mItemScale = glm::clamp(elem->get<float>("itemScale"), 0.5f, 2.0f);
if (elem->has("itemRelativeScale"))
mItemRelativeScale = glm::clamp(elem->get<float>("itemRelativeScale"), 0.2f, 1.0f);
if (elem->has("imageRelativeScale"))
mImageRelativeScale = glm::clamp(elem->get<float>("imageRelativeScale"), 0.2f, 1.0f);
if (elem->has("itemFit")) {
const std::string& itemFit {elem->get<std::string>("itemFit")};
if (itemFit == "contain") {
mItemFit = ItemFit::CONTAIN;
if (elem->has("imageFit")) {
const std::string& imageFit {elem->get<std::string>("imageFit")};
if (imageFit == "contain") {
mImagefit = ImageFit::CONTAIN;
}
else if (itemFit == "fill") {
mItemFit = ItemFit::FILL;
else if (imageFit == "fill") {
mImagefit = ImageFit::FILL;
}
else if (itemFit == "cover") {
mItemFit = ItemFit::COVER;
else if (imageFit == "cover") {
mImagefit = ImageFit::COVER;
}
else {
mItemFit = ItemFit::CONTAIN;
mImagefit = ImageFit::CONTAIN;
LOG(LogWarning) << "GridComponent: Invalid theme configuration, property "
"\"itemFit\" for element \""
<< element.substr(5) << "\" defined as \"" << itemFit << "\"";
"\"imageFit\" for element \""
<< element.substr(5) << "\" defined as \"" << imageFit << "\"";
}
}
@ -974,25 +974,25 @@ void GridComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
mItemSpacing.y = ((mItemSize.y * mItemScale) - mItemSize.y) / 2.0f;
}
if (elem->has("itemColor")) {
mItemColor = elem->get<unsigned int>("itemColor");
mItemColorEnd = mItemColor;
if (elem->has("imageColor")) {
mImageColor = elem->get<unsigned int>("imageColor");
mImageColorEnd = mImageColor;
}
if (elem->has("itemColorEnd"))
mItemColorEnd = elem->get<unsigned int>("itemColorEnd");
if (elem->has("imageColorEnd"))
mImageColorEnd = elem->get<unsigned int>("imageColorEnd");
if (elem->has("itemGradientType")) {
const std::string& gradientType {elem->get<std::string>("itemGradientType")};
if (elem->has("imageGradientType")) {
const std::string& gradientType {elem->get<std::string>("imageGradientType")};
if (gradientType == "horizontal") {
mItemColorGradientHorizontal = true;
mImageColorGradientHorizontal = true;
}
else if (gradientType == "vertical") {
mItemColorGradientHorizontal = false;
mImageColorGradientHorizontal = false;
}
else {
mItemColorGradientHorizontal = true;
mImageColorGradientHorizontal = true;
LOG(LogWarning) << "GridComponent: Invalid theme configuration, property "
"\"itemGradientType\" for element \""
"\"imageGradientType\" for element \""
<< element.substr(5) << "\" defined as \"" << gradientType << "\"";
}
}