From b9e917816984aa471446b2753d58f0a98529a852 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Wed, 9 Feb 2022 18:22:06 +0100 Subject: [PATCH] Fixed multiple issues in CarouselComponent. --- es-app/src/views/SystemView.cpp | 205 +++++++++---------- es-app/src/views/SystemView.h | 7 +- es-core/src/components/CarouselComponent.cpp | 30 ++- 3 files changed, 115 insertions(+), 127 deletions(-) diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index c4c1cb09f..39a244cf4 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -24,8 +24,8 @@ namespace { // Buffer values for scrolling velocity (left, stopped, right). - const int logoBuffersLeft[] = {-5, -2, -1}; - const int logoBuffersRight[] = {1, 2, 5}; + const int logoBuffersLeft[] {-5, -2, -1}; + const int logoBuffersRight[] {1, 2, 5}; } // namespace @@ -120,70 +120,21 @@ void SystemView::render(const glm::mat4& parentTrans) if (mCarousel->getNumEntries() == 0) return; // Nothing to render. + renderElements(parentTrans, false); glm::mat4 trans {getTransform() * parentTrans}; - // Adding texture loading buffers depending on scrolling speed and status. - int bufferIndex {mCarousel->getScrollingVelocity() + 1}; - - Renderer::pushClipRect(glm::ivec2 {}, - glm::ivec2 {static_cast(mSize.x), static_cast(mSize.y)}); - - for (int i = static_cast(mCamOffset) + logoBuffersLeft[bufferIndex]; - i <= static_cast(mCamOffset) + logoBuffersRight[bufferIndex]; ++i) { - int index {i}; - while (index < 0) - index += static_cast(mCarousel->getNumEntries()); - while (index >= static_cast(mCarousel->getNumEntries())) - index -= static_cast(mCarousel->getNumEntries()); - - if (mCarousel->isAnimationPlaying(0) || index == mCarousel->getCursor()) { - glm::mat4 elementTrans {trans}; - if (mCarousel->getType() == CarouselComponent::HORIZONTAL || - mCarousel->getType() == CarouselComponent::HORIZONTAL_WHEEL) - elementTrans = glm::translate(elementTrans, - glm::vec3 {(i - mCamOffset) * mSize.x, 0.0f, 0.0f}); - else - elementTrans = glm::translate(elementTrans, - glm::vec3 {0.0f, (i - mCamOffset) * mSize.y, 0.0f}); - - Renderer::pushClipRect( - glm::ivec2 {static_cast(elementTrans[3].x), - static_cast(elementTrans[3].y)}, - glm::ivec2 {static_cast(mSize.x), static_cast(mSize.y)}); - - if (mLegacyMode && mSystemElements.size() > static_cast(index)) { - for (auto element : mSystemElements[index].legacyExtras) - element->render(elementTrans); - } - else if (mSystemElements.size() > static_cast(index)) { - for (auto child : mSystemElements[index].children) { - if (child == mCarousel.get()) { - // Render black above anything lower than the zIndex of the carousel - // if fade transitions are in use and we're transitioning. - if (mFadeOpacity) - renderFade(trans); - child->render(trans); - } - else { - child->render(elementTrans); - } - } - } - - if (mLegacyMode) - mLegacySystemInfo->render(elementTrans); - - Renderer::popClipRect(); - } + // During fade transitions draw a black rectangle above all elements placed below the carousel. + if (mFadeOpacity != 0.0f) { + unsigned int fadeColor {0x00000000 | static_cast(mFadeOpacity * 255.0f)}; + Renderer::setMatrix(trans); + Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, fadeColor, fadeColor); } - if (mLegacyMode) { - if (mFadeOpacity) - renderFade(trans); - mCarousel->render(trans); - } + mCarousel->render(trans); - Renderer::popClipRect(); + // For legacy themes the carousel is always rendered on top of all other elements. + if (!mLegacyMode) + renderElements(parentTrans, true); } void SystemView::onThemeChanged(const std::shared_ptr& /*theme*/) @@ -264,24 +215,24 @@ void SystemView::onCursorChanged(const CursorState& /*state*/) anim = new LambdaAnimation( [this, startFade, startPos, endPos, posMax](float t) { t -= 1; - float f = glm::mix(startPos, endPos, t * t * t + 1); - if (f < 0) + float f {glm::mix(startPos, endPos, t * t * t + 1.0f)}; + if (f < 0.0f) f += posMax; if (f >= posMax) f -= posMax; t += 1; + if (t < 0.3f) - this->mFadeOpacity = + mFadeOpacity = glm::mix(0.0f, 1.0f, glm::clamp(t / 0.2f + startFade, 0.0f, 1.0f)); else if (t < 0.7f) - this->mFadeOpacity = 1.0f; + mFadeOpacity = 1.0f; else - this->mFadeOpacity = - glm::mix(1.0f, 0.0f, glm::clamp((t - 0.6f) / 0.3f, 0.0f, 1.0f)); + mFadeOpacity = glm::mix(1.0f, 0.0f, glm::clamp((t - 0.6f) / 0.3f, 0.0f, 1.0f)); if (t > 0.5f) - this->mCamOffset = endPos; + mCamOffset = endPos; // Update the game count when the entire animation has been completed. if (mFadeOpacity == 1.0f) @@ -294,13 +245,13 @@ void SystemView::onCursorChanged(const CursorState& /*state*/) anim = new LambdaAnimation( [this, startPos, endPos, posMax](float t) { t -= 1; - float f = glm::mix(startPos, endPos, t * t * t + 1); - if (f < 0) + float f {glm::mix(startPos, endPos, t * t * t + 1.0f)}; + if (f < 0.0f) f += posMax; if (f >= posMax) f -= posMax; - this->mCamOffset = f; + mCamOffset = f; // Hack to make the game count being updated in the middle of the animation. bool update {false}; @@ -329,13 +280,13 @@ void SystemView::onCursorChanged(const CursorState& /*state*/) anim = new LambdaAnimation( [this, startPos, endPos, posMax](float t) { t -= 1; - float f = glm::mix(startPos, endPos, t * t * t + 1); - if (f < 0) + float f {glm::mix(startPos, endPos, t * t * t + 1.0f)}; + if (f < 0.0f) f += posMax; if (f >= posMax) f -= posMax; - this->mCamOffset = endPos; + mCamOffset = endPos; }, 500); } @@ -345,6 +296,8 @@ void SystemView::onCursorChanged(const CursorState& /*state*/) void SystemView::populate() { + LOG(LogDebug) << "SystemView::populate(): Populating carousel"; + auto themeSets = ThemeData::getThemeSets(); std::map::const_iterator selectedSet { themeSets.find(Settings::getInstance()->getString("ThemeSet"))}; @@ -362,8 +315,8 @@ void SystemView::populate() std::string logoPath; std::string defaultLogoPath; - if (mViewNeedsReload) - getViewElements(theme); + if (mLegacyMode && mViewNeedsReload) + legacyApplyTheme(theme); if (mLegacyMode) { SystemViewElements elements; @@ -424,8 +377,10 @@ void SystemView::populate() } } } - - elements.children.emplace_back(mCarousel.get()); + else { + // Apply default carousel configuration. + mCarousel->applyTheme(theme, "system", "", ThemeFlags::ALL); + } std::stable_sort( elements.children.begin(), elements.children.end(), @@ -535,40 +490,82 @@ void SystemView::updateGameCount() } } -void SystemView::getViewElements(const std::shared_ptr& theme) +void SystemView::legacyApplyTheme(const std::shared_ptr& theme) { - LOG(LogDebug) << "SystemView::getViewElements()"; - if (theme->hasView("system")) mViewNeedsReload = false; else mViewNeedsReload = true; - if (mLegacyMode) { - mCarousel->applyTheme(theme, "system", "carousel_systemcarousel", ThemeFlags::ALL); + mCarousel->applyTheme(theme, "system", "carousel_systemcarousel", ThemeFlags::ALL); - mLegacySystemInfo->setSize(mSize.x, mLegacySystemInfo->getFont()->getLetterHeight() * 2.2f); - mLegacySystemInfo->setPosition(0.0f, mCarousel->getPosition().y + mCarousel->getSize().y); - mLegacySystemInfo->setBackgroundColor(0xDDDDDDD8); - mLegacySystemInfo->setRenderBackground(true); - mLegacySystemInfo->setFont( - Font::get(static_cast(0.035f * mSize.y), Font::getDefaultPath())); - mLegacySystemInfo->setColor(0x000000FF); - mLegacySystemInfo->setUppercase(true); - mLegacySystemInfo->setZIndex(49.0f); - mLegacySystemInfo->setDefaultZIndex(49.0f); + mLegacySystemInfo->setSize(mSize.x, mLegacySystemInfo->getFont()->getLetterHeight() * 2.2f); + mLegacySystemInfo->setPosition(0.0f, mCarousel->getPosition().y + mCarousel->getSize().y); + mLegacySystemInfo->setBackgroundColor(0xDDDDDDD8); + mLegacySystemInfo->setRenderBackground(true); + mLegacySystemInfo->setFont( + Font::get(static_cast(0.035f * mSize.y), Font::getDefaultPath())); + mLegacySystemInfo->setColor(0x000000FF); + mLegacySystemInfo->setUppercase(true); + mLegacySystemInfo->setZIndex(49.0f); + mLegacySystemInfo->setDefaultZIndex(49.0f); - const ThemeData::ThemeElement* sysInfoElem { - theme->getElement("system", "text_systemInfo", "text")}; + const ThemeData::ThemeElement* sysInfoElem { + theme->getElement("system", "text_systemInfo", "text")}; - if (sysInfoElem) - mLegacySystemInfo->applyTheme(theme, "system", "text_systemInfo", ThemeFlags::ALL); + if (sysInfoElem) + mLegacySystemInfo->applyTheme(theme, "system", "text_systemInfo", ThemeFlags::ALL); +} + +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(mCamOffset) + logoBuffersLeft[bufferIndex]; + i <= static_cast(mCamOffset) + logoBuffersRight[bufferIndex]; ++i) { + int index {i}; + while (index < 0) + index += static_cast(mCarousel->getNumEntries()); + while (index >= static_cast(mCarousel->getNumEntries())) + index -= static_cast(mCarousel->getNumEntries()); + + if (mCarousel->isAnimationPlaying(0) || index == mCarousel->getCursor()) { + glm::mat4 elementTrans {trans}; + if (mCarousel->getType() == CarouselComponent::HORIZONTAL || + mCarousel->getType() == CarouselComponent::HORIZONTAL_WHEEL) + elementTrans = glm::translate(elementTrans, + glm::vec3 {(i - mCamOffset) * mSize.x, 0.0f, 0.0f}); + else + elementTrans = glm::translate(elementTrans, + glm::vec3 {0.0f, (i - mCamOffset) * mSize.y, 0.0f}); + + Renderer::pushClipRect( + glm::ivec2 {static_cast(glm::round(elementTrans[3].x)), + static_cast(glm::round(elementTrans[3].y))}, + glm::ivec2 {static_cast(mSize.x), static_cast(mSize.y)}); + + if (mLegacyMode && mSystemElements.size() > static_cast(index)) { + for (auto element : mSystemElements[index].legacyExtras) + element->render(elementTrans); + } + else if (!mLegacyMode && mSystemElements.size() > static_cast(index)) { + for (auto child : mSystemElements[index].children) { + if (abovePrimary && child->getZIndex() > primaryZIndex && mFadeOpacity == 0.0f) + child->render(elementTrans); + else if (!abovePrimary && child->getZIndex() <= primaryZIndex) + child->render(elementTrans); + } + } + + if (mLegacyMode) + mLegacySystemInfo->render(elementTrans); + + Renderer::popClipRect(); + } } } - -void SystemView::renderFade(const glm::mat4& trans) -{ - unsigned int fadeColor {0x00000000 | static_cast(mFadeOpacity * 255.0f)}; - Renderer::setMatrix(trans); - Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, fadeColor, fadeColor); -} diff --git a/es-app/src/views/SystemView.h b/es-app/src/views/SystemView.h index a4e6cdeab..631119100 100644 --- a/es-app/src/views/SystemView.h +++ b/es-app/src/views/SystemView.h @@ -78,14 +78,11 @@ protected: private: void populate(); void updateGameCount(); - // Get the ThemeElements that make up the SystemView. - void getViewElements(const std::shared_ptr& theme); - - void renderFade(const glm::mat4& trans); + void legacyApplyTheme(const std::shared_ptr& theme); + void renderElements(const glm::mat4& parentTrans, bool abovePrimary); std::unique_ptr mCarousel; std::unique_ptr mLegacySystemInfo; - std::vector mSystemElements; float mCamOffset; diff --git a/es-core/src/components/CarouselComponent.cpp b/es-core/src/components/CarouselComponent.cpp index 1c2fd2821..efadc9296 100644 --- a/es-core/src/components/CarouselComponent.cpp +++ b/es-core/src/components/CarouselComponent.cpp @@ -14,8 +14,8 @@ namespace { // Buffer values for scrolling velocity (left, stopped, right). - const int logoBuffersLeft[] = {-5, -2, -1}; - const int logoBuffersRight[] = {1, 2, 5}; + const int logoBuffersLeft[] {-5, -2, -1}; + const int logoBuffersRight[] {1, 2, 5}; } // namespace @@ -138,12 +138,6 @@ void CarouselComponent::addEntry(const std::shared_ptr& theme, add(entry); } -void CarouselComponent::update(int deltaTime) -{ - listUpdate(deltaTime); - GuiComponent::update(deltaTime); -} - bool CarouselComponent::input(InputConfig* config, Input input) { if (input.value != 0) { @@ -191,21 +185,23 @@ bool CarouselComponent::input(InputConfig* config, Input input) return GuiComponent::input(config, input); } +void CarouselComponent::update(int deltaTime) +{ + listUpdate(deltaTime); + GuiComponent::update(deltaTime); +} + void CarouselComponent::render(const glm::mat4& parentTrans) { - // Background box behind logos. glm::mat4 carouselTrans {parentTrans}; carouselTrans = glm::translate(carouselTrans, glm::vec3 {mPosition.x, mPosition.y, 0.0f}); carouselTrans = glm::translate( carouselTrans, glm::vec3 {mOrigin.x * mSize.x * -1.0f, mOrigin.y * mSize.y * -1.0f, 0.0f}); glm::vec2 clipPos {carouselTrans[3].x, carouselTrans[3].y}; - Renderer::pushClipRect( - glm::ivec2 {static_cast(std::round(clipPos.x)), - static_cast(std::round(clipPos.y))}, - glm::ivec2 {static_cast(std::round(mSize.x)), static_cast(std::round(mSize.y))}); - Renderer::setMatrix(carouselTrans); + + // Background box behind logos. Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, mCarouselColor, mCarouselColorEnd, mColorGradientHorizontal); @@ -303,8 +299,6 @@ void CarouselComponent::render(const glm::mat4& parentTrans) comp->setOpacity(static_cast(opacity)); comp->render(logoTrans); } - - Renderer::popClipRect(); } void CarouselComponent::applyTheme(const std::shared_ptr& theme, @@ -456,13 +450,13 @@ void CarouselComponent::onCursorChanged(const CursorState& state) Animation* anim = new LambdaAnimation( [this, startPos, endPos, posMax](float t) { t -= 1; - float f = glm::mix(startPos, endPos, t * t * t + 1); + float f {glm::mix(startPos, endPos, t * t * t + 1)}; if (f < 0) f += posMax; if (f >= posMax) f -= posMax; - this->mCamOffset = f; + mCamOffset = f; }, 500);