Added a metadataElement theme property to the image, video, animation and text element types to control fading and hiding of arbitrary elements.

This commit is contained in:
Leon Styhre 2022-08-18 22:51:21 +02:00
parent 389dc6ed79
commit de5a642cf6
9 changed files with 144 additions and 18 deletions

View file

@ -61,13 +61,15 @@ void GamelistView::onFileChanged(FileData* file, bool reloadGamelist)
void GamelistView::onShow() void GamelistView::onShow()
{ {
// Reset any GIF and Lottie animations.
for (auto& animation : mLottieAnimComponents) for (auto& animation : mLottieAnimComponents)
animation->resetFileAnimation(); animation->resetFileAnimation();
for (auto& animation : mGIFAnimComponents) for (auto& animation : mGIFAnimComponents)
animation->resetFileAnimation(); animation->resetFileAnimation();
for (auto& video : mStaticVideoComponents)
video->stopVideoPlayer();
mLastUpdated = nullptr; mLastUpdated = nullptr;
GuiComponent::onShow(); GuiComponent::onShow();
@ -172,9 +174,21 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
mImageComponents.back()->applyTheme(theme, "gamelist", element.first, ALL); mImageComponents.back()->applyTheme(theme, "gamelist", element.first, ALL);
if (mImageComponents.back()->getThemeImageTypes().size() != 0) if (mImageComponents.back()->getThemeImageTypes().size() != 0)
mImageComponents.back()->setScrollHide(true); mImageComponents.back()->setScrollHide(true);
else if (mImageComponents.back()->getMetadataElement())
mImageComponents.back()->setScrollHide(true);
addChild(mImageComponents.back().get()); addChild(mImageComponents.back().get());
} }
else if (element.second.type == "video") { else if (element.second.type == "video") {
if (element.second.has("path")) {
mStaticVideoComponents.push_back(std::make_unique<VideoFFmpegComponent>());
mStaticVideoComponents.back()->setDefaultZIndex(30.0f);
addChild(mStaticVideoComponents.back().get());
mStaticVideoComponents.back()->applyTheme(theme, "gamelist", element.first,
ALL);
if (mStaticVideoComponents.back()->getMetadataElement())
mStaticVideoComponents.back()->setScrollHide(true);
}
else {
mVideoComponents.push_back(std::make_unique<VideoFFmpegComponent>()); mVideoComponents.push_back(std::make_unique<VideoFFmpegComponent>());
mVideoComponents.back()->setDefaultZIndex(30.0f); mVideoComponents.back()->setDefaultZIndex(30.0f);
addChild(mVideoComponents.back().get()); addChild(mVideoComponents.back().get());
@ -182,6 +196,7 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
if (mVideoComponents.back()->getThemeImageTypes().size() != 0) if (mVideoComponents.back()->getThemeImageTypes().size() != 0)
mVideoComponents.back()->setScrollHide(true); mVideoComponents.back()->setScrollHide(true);
} }
}
else if (element.second.type == "animation" && element.second.has("path")) { else if (element.second.type == "animation" && element.second.has("path")) {
const std::string extension { const std::string extension {
Utils::FileSystem::getExtension(element.second.get<std::string>("path"))}; Utils::FileSystem::getExtension(element.second.get<std::string>("path"))};
@ -189,12 +204,16 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
mLottieAnimComponents.push_back(std::make_unique<LottieAnimComponent>()); mLottieAnimComponents.push_back(std::make_unique<LottieAnimComponent>());
mLottieAnimComponents.back()->setDefaultZIndex(35.0f); mLottieAnimComponents.back()->setDefaultZIndex(35.0f);
mLottieAnimComponents.back()->applyTheme(theme, "gamelist", element.first, ALL); mLottieAnimComponents.back()->applyTheme(theme, "gamelist", element.first, ALL);
if (mLottieAnimComponents.back()->getMetadataElement())
mLottieAnimComponents.back()->setScrollHide(true);
addChild(mLottieAnimComponents.back().get()); addChild(mLottieAnimComponents.back().get());
} }
else if (extension == ".gif") { else if (extension == ".gif") {
mGIFAnimComponents.push_back(std::make_unique<GIFAnimComponent>()); mGIFAnimComponents.push_back(std::make_unique<GIFAnimComponent>());
mGIFAnimComponents.back()->setDefaultZIndex(35.0f); mGIFAnimComponents.back()->setDefaultZIndex(35.0f);
mGIFAnimComponents.back()->applyTheme(theme, "gamelist", element.first, ALL); mGIFAnimComponents.back()->applyTheme(theme, "gamelist", element.first, ALL);
if (mGIFAnimComponents.back()->getMetadataElement())
mGIFAnimComponents.back()->setScrollHide(true);
addChild(mGIFAnimComponents.back().get()); addChild(mGIFAnimComponents.back().get());
} }
else if (extension == ".") { else if (extension == ".") {
@ -233,14 +252,21 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
mContainerTextComponents.back()->applyTheme( mContainerTextComponents.back()->applyTheme(
theme, "gamelist", element.first, theme, "gamelist", element.first,
ALL ^ POSITION ^ Z_INDEX ^ ThemeFlags::SIZE ^ VISIBLE ^ ROTATION); ALL ^ POSITION ^ Z_INDEX ^ ThemeFlags::SIZE ^ VISIBLE ^ ROTATION);
if (mContainerTextComponents.back()->getThemeMetadata() != "")
mContainerComponents.back()->setScrollHide(true);
else if (mContainerTextComponents.back()->getMetadataElement())
mContainerComponents.back()->setScrollHide(true); mContainerComponents.back()->setScrollHide(true);
} }
else { else {
mTextComponents.push_back(std::make_unique<TextComponent>()); mTextComponents.push_back(std::make_unique<TextComponent>());
mTextComponents.back()->setDefaultZIndex(40.0f); mTextComponents.back()->setDefaultZIndex(40.0f);
mTextComponents.back()->applyTheme(theme, "gamelist", element.first, ALL); mTextComponents.back()->applyTheme(theme, "gamelist", element.first, ALL);
if (mTextComponents.back()->getThemeMetadata() != "") if (mTextComponents.back()->getThemeMetadata() != "") {
mTextComponents.back()->setScrollHide(true); mTextComponents.back()->setScrollHide(true);
}
else if (mTextComponents.back()->getMetadataElement()) {
mTextComponents.back()->setScrollHide(true);
}
addChild(mTextComponents.back().get()); addChild(mTextComponents.back().get());
} }
} }
@ -294,6 +320,11 @@ void GamelistView::onThemeChanged(const std::shared_ptr<ThemeData>& theme)
mLeftRightAvailable = false; mLeftRightAvailable = false;
} }
for (auto& video : mStaticVideoComponents) {
if (video->hasStaticVideo())
video->setStaticVideo();
}
sortChildren(); sortChildren();
} }
@ -311,6 +342,17 @@ void GamelistView::update(int deltaTime)
} }
} }
// We need to manually advance fade-in and fade-out animations since they will not get updated
// via GuiComponent as these components override the update() function.
for (auto& anim : mLottieAnimComponents) {
if (anim->isAnimationPlaying(0))
anim->advanceAnimation(0, deltaTime);
}
for (auto& anim : mGIFAnimComponents) {
if (anim->isAnimationPlaying(0))
anim->advanceAnimation(0, deltaTime);
}
updateChildren(deltaTime); updateChildren(deltaTime);
} }
@ -392,7 +434,8 @@ void GamelistView::updateInfoPanel(const CursorState& state)
if (mCarousel != nullptr) if (mCarousel != nullptr)
mCarousel->onDemandTextureLoad(); mCarousel->onDemandTextureLoad();
// If the game data has already been rendered to the info panel, then skip it this time. // If the game data has already been rendered to the view, then skip it this time.
// This also happens when fast-scrolling.
if (file == mLastUpdated) if (file == mLastUpdated)
return; return;
@ -427,25 +470,57 @@ void GamelistView::updateInfoPanel(const CursorState& state)
if (hideMetaDataFields) { if (hideMetaDataFields) {
for (auto& text : mTextComponents) { for (auto& text : mTextComponents) {
if (text->getThemeMetadata() != "") if (text->getMetadataElement() || text->getThemeMetadata() != "")
text->setVisible(false); text->setVisible(false);
} }
for (auto& date : mDateTimeComponents) for (auto& date : mDateTimeComponents)
date->setVisible(false); date->setVisible(false);
for (auto& image : mImageComponents) {
if (image->getMetadataElement())
image->setVisible(false);
}
for (auto& video : mStaticVideoComponents) {
if (video->getMetadataElement())
video->setVisible(false);
}
for (auto& anim : mLottieAnimComponents) {
if (anim->getMetadataElement())
anim->setVisible(false);
}
for (auto& anim : mGIFAnimComponents) {
if (anim->getMetadataElement())
anim->setVisible(false);
}
for (auto& badge : mBadgeComponents) for (auto& badge : mBadgeComponents)
badge->setVisible(false); badge->setVisible(false);
for (auto& rating : mRatingComponents) for (auto& rating : mRatingComponents)
rating->setVisible(false); rating->setVisible(false);
for (auto& cText : mContainerTextComponents) { for (auto& cText : mContainerTextComponents) {
if (cText->getThemeMetadata() != "description") if (cText->getThemeMetadata() != "description" || cText->getMetadataElement())
cText->setVisible(false); cText->setVisible(false);
} }
} }
else { else {
for (auto& text : mTextComponents) { for (auto& text : mTextComponents) {
if (text->getThemeMetadata() != "") if (text->getMetadataElement() || text->getThemeMetadata() != "")
text->setVisible(true); text->setVisible(true);
} }
for (auto& image : mImageComponents) {
if (image->getMetadataElement())
image->setVisible(true);
}
for (auto& video : mStaticVideoComponents) {
if (video->getMetadataElement())
video->setVisible(true);
}
for (auto& anim : mLottieAnimComponents) {
if (anim->getMetadataElement())
anim->setVisible(true);
}
for (auto& anim : mGIFAnimComponents) {
if (anim->getMetadataElement())
anim->setVisible(true);
}
for (auto& date : mDateTimeComponents) for (auto& date : mDateTimeComponents)
date->setVisible(true); date->setVisible(true);
for (auto& badge : mBadgeComponents) for (auto& badge : mBadgeComponents)
@ -453,7 +528,7 @@ void GamelistView::updateInfoPanel(const CursorState& state)
for (auto& rating : mRatingComponents) for (auto& rating : mRatingComponents)
rating->setVisible(true); rating->setVisible(true);
for (auto& cText : mContainerTextComponents) { for (auto& cText : mContainerTextComponents) {
if (cText->getThemeMetadata() != "description") if (cText->getThemeMetadata() != "description" || cText->getMetadataElement())
cText->setVisible(true); cText->setVisible(true);
} }
} }
@ -763,10 +838,22 @@ void GamelistView::updateInfoPanel(const CursorState& state)
if (image->getScrollHide()) if (image->getScrollHide())
comps.emplace_back(image.get()); comps.emplace_back(image.get());
} }
for (auto& video : mStaticVideoComponents) {
if (video->getScrollHide())
comps.emplace_back(video.get());
}
for (auto& video : mVideoComponents) { for (auto& video : mVideoComponents) {
if (video->getScrollHide()) if (video->getScrollHide())
comps.emplace_back(video.get()); comps.emplace_back(video.get());
} }
for (auto& anim : mLottieAnimComponents) {
if (anim->getScrollHide())
comps.emplace_back(anim.get());
}
for (auto& anim : mGIFAnimComponents) {
if (anim->getScrollHide())
comps.emplace_back(anim.get());
}
for (auto& badge : mBadgeComponents) { for (auto& badge : mBadgeComponents) {
if (badge->getScrollHide()) if (badge->getScrollHide())
comps.emplace_back(badge.get()); comps.emplace_back(badge.get());

View file

@ -44,22 +44,29 @@ public:
{ {
for (auto& video : mVideoComponents) for (auto& video : mVideoComponents)
video->startVideoPlayer(); video->startVideoPlayer();
for (auto& video : mStaticVideoComponents)
video->startVideoPlayer();
} }
void stopViewVideos() override void stopViewVideos() override
{ {
for (auto& video : mVideoComponents) for (auto& video : mVideoComponents)
video->stopVideoPlayer(); video->stopVideoPlayer();
for (auto& video : mStaticVideoComponents)
video->stopVideoPlayer();
} }
void pauseViewVideos() override void pauseViewVideos() override
{ {
for (auto& video : mVideoComponents) { for (auto& video : mVideoComponents)
video->pauseVideoPlayer();
for (auto& video : mStaticVideoComponents)
video->pauseVideoPlayer(); video->pauseVideoPlayer();
}
} }
void muteViewVideos() override void muteViewVideos() override
{ {
for (auto& video : mVideoComponents) for (auto& video : mVideoComponents)
video->muteVideoPlayer(); video->muteVideoPlayer();
for (auto& video : mStaticVideoComponents)
video->muteVideoPlayer();
} }
void stopScrollFadeIn() override void stopScrollFadeIn() override
@ -111,6 +118,7 @@ private:
std::vector<std::unique_ptr<TextComponent>> mTextComponents; std::vector<std::unique_ptr<TextComponent>> mTextComponents;
std::vector<std::unique_ptr<DateTimeComponent>> mDateTimeComponents; std::vector<std::unique_ptr<DateTimeComponent>> mDateTimeComponents;
std::vector<std::unique_ptr<ImageComponent>> mImageComponents; std::vector<std::unique_ptr<ImageComponent>> mImageComponents;
std::vector<std::unique_ptr<VideoFFmpegComponent>> mStaticVideoComponents;
std::vector<std::unique_ptr<VideoFFmpegComponent>> mVideoComponents; std::vector<std::unique_ptr<VideoFFmpegComponent>> mVideoComponents;
std::vector<std::unique_ptr<LottieAnimComponent>> mLottieAnimComponents; std::vector<std::unique_ptr<LottieAnimComponent>> mLottieAnimComponents;
std::vector<std::unique_ptr<GIFAnimComponent>> mGIFAnimComponents; std::vector<std::unique_ptr<GIFAnimComponent>> mGIFAnimComponents;

View file

@ -115,7 +115,8 @@ public:
// clang-format off // clang-format off
enum ComponentThemeFlags : unsigned int { enum ComponentThemeFlags : unsigned int {
SCROLL_HIDE = 0x00000001, SCROLL_HIDE = 0x00000001,
SCROLL_FADE_IN = 0x00000002 SCROLL_FADE_IN = 0x00000002,
METADATA_ELEMENT = 0x00000004
}; };
// clang-format on // clang-format on
@ -138,6 +139,17 @@ public:
else else
mComponentThemeFlags ^= ComponentThemeFlags::SCROLL_FADE_IN; mComponentThemeFlags ^= ComponentThemeFlags::SCROLL_FADE_IN;
} }
const bool getMetadataElement()
{
return mComponentThemeFlags & ComponentThemeFlags::METADATA_ELEMENT;
}
void setMetadataElement(bool state)
{
if (state)
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
else
mComponentThemeFlags ^= ComponentThemeFlags::METADATA_ELEMENT;
}
// Returns the center point of the image (takes origin into account). // Returns the center point of the image (takes origin into account).
const glm::vec2 getCenter() const; const glm::vec2 getCenter() const;

View file

@ -94,6 +94,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"path", PATH}, {"path", PATH},
{"default", PATH}, {"default", PATH},
{"imageType", STRING}, {"imageType", STRING},
{"metadataElement", BOOLEAN},
{"gameselector", STRING}, {"gameselector", STRING},
{"tile", BOOLEAN}, {"tile", BOOLEAN},
{"interpolation", STRING}, {"interpolation", STRING},
@ -110,6 +111,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"size", NORMALIZED_PAIR}, {"size", NORMALIZED_PAIR},
{"maxSize", NORMALIZED_PAIR}, {"maxSize", NORMALIZED_PAIR},
{"origin", NORMALIZED_PAIR}, {"origin", NORMALIZED_PAIR},
{"metadataElement", BOOLEAN},
{"path", PATH}, {"path", PATH},
{"default", PATH}, {"default", PATH},
{"defaultImage", PATH}, {"defaultImage", PATH},
@ -134,6 +136,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"origin", NORMALIZED_PAIR}, {"origin", NORMALIZED_PAIR},
{"rotation", FLOAT}, {"rotation", FLOAT},
{"rotationOrigin", NORMALIZED_PAIR}, {"rotationOrigin", NORMALIZED_PAIR},
{"metadataElement", BOOLEAN},
{"path", PATH}, {"path", PATH},
{"speed", FLOAT}, {"speed", FLOAT},
{"direction", STRING}, {"direction", STRING},
@ -175,6 +178,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"text", STRING}, {"text", STRING},
{"systemdata", STRING}, {"systemdata", STRING},
{"metadata", STRING}, {"metadata", STRING},
{"metadataElement", BOOLEAN},
{"gameselector", STRING}, {"gameselector", STRING},
{"container", BOOLEAN}, {"container", BOOLEAN},
{"containerScrollSpeed", FLOAT}, {"containerScrollSpeed", FLOAT},

View file

@ -267,6 +267,9 @@ void GIFAnimComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
} }
} }
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
if (elem->has("speed")) { if (elem->has("speed")) {
const float speed {elem->get<float>("speed")}; const float speed {elem->get<float>("speed")};
if (speed < 0.2f || speed > 3.0f) { if (speed < 0.2f || speed > 3.0f) {

View file

@ -557,6 +557,9 @@ void ImageComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
mThemeImageTypes = Utils::String::delimitedStringToVector(imageTypes, ","); mThemeImageTypes = Utils::String::delimitedStringToVector(imageTypes, ",");
} }
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
if (properties & COLOR) { if (properties & COLOR) {
if (elem->has("color")) if (elem->has("color"))
setColorShift(elem->get<unsigned int>("color")); setColorShift(elem->get<unsigned int>("color"));

View file

@ -238,6 +238,9 @@ void LottieAnimComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
} }
} }
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
if (elem->has("speed")) { if (elem->has("speed")) {
const float speed {elem->get<float>("speed")}; const float speed {elem->get<float>("speed")};
if (speed < 0.2f || speed > 3.0f) { if (speed < 0.2f || speed > 3.0f) {

View file

@ -389,6 +389,9 @@ void TextComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (!elem) if (!elem)
return; return;
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
if (properties & COLOR && elem->has("color")) if (properties & COLOR && elem->has("color"))
setColor(elem->get<unsigned int>("color")); setColor(elem->get<unsigned int>("color"));

View file

@ -147,6 +147,9 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
mVideoAreaPos = elem->get<glm::vec2>("pos") * scale; mVideoAreaPos = elem->get<glm::vec2>("pos") * scale;
} }
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
if (elem->has("audio")) if (elem->has("audio"))
mPlayAudio = elem->get<bool>("audio"); mPlayAudio = elem->get<bool>("audio");