From ecdbf6d3d509fa6fd987d589df8f2494311cf7a5 Mon Sep 17 00:00:00 2001 From: Leon Styhre <leon@leonstyhre.com> Date: Sat, 5 Mar 2022 21:10:40 +0100 Subject: [PATCH] Added GIF animation support to SystemView. Also improved some rendering logic in SystemView. --- es-app/src/views/SystemView.cpp | 79 ++++++++++++++++++++++++--------- es-app/src/views/SystemView.h | 2 + 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index c2801487f..91c3d5bc5 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -21,14 +21,6 @@ #include <cmath> #endif -namespace -{ - // Buffer values for scrolling velocity (left, stopped, right). - const int logoBuffersLeft[] {-5, -2, -1}; - const int logoBuffersRight[] {1, 2, 5}; - -} // namespace - SystemView::SystemView() : mCamOffset {0.0f} , mFadeOpacity {0.0f} @@ -46,8 +38,12 @@ SystemView::SystemView() mCarousel->setCancelTransitionsCallback([&] { ViewController::getInstance()->cancelViewTransitions(); mNavigated = true; - for (auto& anim : mSystemElements[mCarousel->getCursor()].lottieAnimComponents) - anim->setPauseAnimation(true); + if (mSystemElements.size() > 1) { + for (auto& anim : mSystemElements[mCarousel->getCursor()].lottieAnimComponents) + anim->setPauseAnimation(true); + for (auto& anim : mSystemElements[mCarousel->getCursor()].GIFAnimComponents) + anim->setPauseAnimation(true); + } }); populate(); @@ -69,6 +65,9 @@ void SystemView::onTransition() { for (auto& anim : mSystemElements[mCarousel->getCursor()].lottieAnimComponents) anim->setPauseAnimation(true); + + for (auto& anim : mSystemElements[mCarousel->getCursor()].GIFAnimComponents) + anim->setPauseAnimation(true); } void SystemView::goToSystem(SystemData* system, bool animate) @@ -86,6 +85,9 @@ void SystemView::goToSystem(SystemData* system, bool animate) for (auto& anim : mSystemElements[mCarousel->getCursor()].lottieAnimComponents) anim->resetFileAnimation(); + for (auto& anim : mSystemElements[mCarousel->getCursor()].GIFAnimComponents) + anim->resetFileAnimation(); + updateGameSelectors(); updateGameCount(); startViewVideos(); @@ -152,6 +154,9 @@ void SystemView::update(int deltaTime) for (auto& anim : mSystemElements[mCarousel->getCursor()].lottieAnimComponents) anim->update(deltaTime); + for (auto& anim : mSystemElements[mCarousel->getCursor()].GIFAnimComponents) + anim->update(deltaTime); + GuiComponent::update(deltaTime); } @@ -234,6 +239,9 @@ void SystemView::onCursorChanged(const CursorState& /*state*/) for (auto& anim : mSystemElements[mCarousel->getCursor()].lottieAnimComponents) anim->resetFileAnimation(); + for (auto& anim : mSystemElements[mCarousel->getCursor()].GIFAnimComponents) + anim->resetFileAnimation(); + updateGameSelectors(); startViewVideos(); updateHelpPrompts(); @@ -428,12 +436,36 @@ void SystemView::populate() elements.children.emplace_back(elements.videoComponents.back().get()); } else if (element.second.type == "animation") { - elements.lottieAnimComponents.emplace_back( - std::make_unique<LottieAnimComponent>()); - elements.lottieAnimComponents.back()->setDefaultZIndex(35.0f); - elements.lottieAnimComponents.back()->applyTheme( - theme, "system", element.first, ThemeFlags::ALL); - elements.children.emplace_back(elements.lottieAnimComponents.back().get()); + const std::string extension {Utils::FileSystem::getExtension( + element.second.get<std::string>("path"))}; + if (extension == ".json") { + elements.lottieAnimComponents.emplace_back( + std::make_unique<LottieAnimComponent>()); + elements.lottieAnimComponents.back()->setDefaultZIndex(35.0f); + elements.lottieAnimComponents.back()->applyTheme( + theme, "system", element.first, ThemeFlags::ALL); + elements.children.emplace_back( + elements.lottieAnimComponents.back().get()); + } + else if (extension == ".gif") { + elements.GIFAnimComponents.emplace_back( + std::make_unique<GIFAnimComponent>()); + elements.GIFAnimComponents.back()->setDefaultZIndex(35.0f); + elements.GIFAnimComponents.back()->applyTheme( + theme, "system", element.first, ThemeFlags::ALL); + elements.children.emplace_back(elements.GIFAnimComponents.back().get()); + } + else if (extension == ".") { + LOG(LogWarning) + << "SystemView::populate(): Invalid theme configuration, " + "animation file extension is missing"; + } + else { + LOG(LogWarning) + << "SystemView::populate(): Invalid theme configuration, " + "animation file extension defined as \"" + << extension << "\""; + } } else if (element.second.type == "text") { if (element.second.has("systemdata") && @@ -989,13 +1021,18 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary) { glm::mat4 trans {getTransform() * parentTrans}; - // Adding texture loading buffers depending on scrolling speed and status. - int bufferIndex {mCarousel->getScrollingVelocity() + 1}; - const float primaryZIndex {mCarousel->getZIndex()}; - for (int i = static_cast<int>(mCamOffset) + logoBuffersLeft[bufferIndex]; - i <= static_cast<int>(mCamOffset) + logoBuffersRight[bufferIndex]; ++i) { + int renderLeft {static_cast<int>(mCamOffset)}; + int renderRight {static_cast<int>(mCamOffset)}; + + // If we're transitioning then also render the previous and next systems. + if (mCarousel->isAnimationPlaying(0)) { + renderLeft -= 1; + renderRight += 1; + } + + for (int i = renderLeft; i <= renderRight; ++i) { int index {i}; while (index < 0) index += static_cast<int>(mCarousel->getNumEntries()); diff --git a/es-app/src/views/SystemView.h b/es-app/src/views/SystemView.h index b3b4fd0f8..2784f9ae5 100644 --- a/es-app/src/views/SystemView.h +++ b/es-app/src/views/SystemView.h @@ -15,6 +15,7 @@ #include "SystemData.h" #include "components/CarouselComponent.h" #include "components/DateTimeComponent.h" +#include "components/GIFAnimComponent.h" #include "components/GameSelectorComponent.h" #include "components/LottieAnimComponent.h" #include "components/TextComponent.h" @@ -39,6 +40,7 @@ struct SystemViewElements { std::vector<std::unique_ptr<ImageComponent>> imageComponents; std::vector<std::unique_ptr<VideoFFmpegComponent>> videoComponents; std::vector<std::unique_ptr<LottieAnimComponent>> lottieAnimComponents; + std::vector<std::unique_ptr<GIFAnimComponent>> GIFAnimComponents; }; class SystemView : public GuiComponent