// SPDX-License-Identifier: MIT // // ES-DE Frontend // ScrollIndicatorComponent.h // // Visually indicates whether a menu can be scrolled (up, up/down or down). // #ifndef ES_CORE_COMPONENTS_SCROLL_INDICATOR_COMPONENT_H #define ES_CORE_COMPONENTS_SCROLL_INDICATOR_COMPONENT_H #define FADE_IN_TIME 90.0f #include "GuiComponent.h" #include "animations/LambdaAnimation.h" #include "components/ComponentList.h" class ScrollIndicatorComponent : public GuiComponent { public: ScrollIndicatorComponent(std::shared_ptr componentList, std::shared_ptr scrollUp, std::shared_ptr scrollDown) : mPreviousScrollState {ComponentList::SCROLL_NONE} { assert(componentList != nullptr && scrollUp != nullptr && scrollDown != nullptr); scrollUp->setImage(":/graphics/scroll_up.svg"); scrollDown->setImage(":/graphics/scroll_down.svg"); scrollUp->setColorShift(mMenuColorScrollIndicators); scrollDown->setColorShift(mMenuColorScrollIndicators); scrollUp->setOpacity(0.0f); scrollDown->setOpacity(0.0f); componentList.get()->setScrollIndicatorChangedCallback( [this, scrollUp, scrollDown](ComponentList::ScrollIndicator state, bool singleRowScroll) { float fadeTime {FADE_IN_TIME}; bool upFadeIn = false; bool upFadeOut = false; bool downFadeIn = false; bool downFadeOut = false; scrollUp->finishAnimation(0); scrollDown->finishAnimation(0); if (state == ComponentList::SCROLL_UP && mPreviousScrollState == ComponentList::SCROLL_NONE) { scrollUp->setOpacity(1.0f); } else if (state == ComponentList::SCROLL_UP && mPreviousScrollState == ComponentList::SCROLL_UP_DOWN) { downFadeOut = true; } else if (state == ComponentList::SCROLL_UP && mPreviousScrollState == ComponentList::SCROLL_DOWN) { upFadeIn = true; fadeTime *= 2.0f; scrollDown->setOpacity(0.0f); } else if (state == ComponentList::SCROLL_UP_DOWN && mPreviousScrollState == ComponentList::SCROLL_NONE) { scrollUp->setOpacity(1.0f); scrollDown->setOpacity(1.0f); } else if (state == ComponentList::SCROLL_UP_DOWN && mPreviousScrollState == ComponentList::SCROLL_DOWN) { upFadeIn = true; } else if (state == ComponentList::SCROLL_UP_DOWN && mPreviousScrollState == ComponentList::SCROLL_UP) { downFadeIn = true; } else if (state == ComponentList::SCROLL_DOWN && mPreviousScrollState == ComponentList::SCROLL_NONE) { scrollDown->setOpacity(1.0f); } else if (state == ComponentList::SCROLL_DOWN && mPreviousScrollState == ComponentList::SCROLL_UP_DOWN) { upFadeOut = true; } else if (state == ComponentList::SCROLL_DOWN && mPreviousScrollState == ComponentList::SCROLL_UP) { downFadeIn = true; fadeTime *= 2.0f; scrollUp->setOpacity(0.0f); } // If jumping more than one row using the shoulder or trigger buttons, then // don't fade the indicators. if (!singleRowScroll) fadeTime = 0.0f; if (upFadeIn) { auto upFadeInFunc = [scrollUp](float t) { scrollUp->setOpacity(glm::mix(0.0f, 1.0f, t)); }; scrollUp->setAnimation( new LambdaAnimation(upFadeInFunc, static_cast(fadeTime)), 0, nullptr, false); } if (upFadeOut) { auto upFadeOutFunc = [scrollUp](float t) { scrollUp->setOpacity(glm::mix(0.0f, 1.0f, t)); }; scrollUp->setAnimation( new LambdaAnimation(upFadeOutFunc, static_cast(fadeTime)), 0, nullptr, true); } if (downFadeIn) { auto downFadeInFunc = [scrollDown](float t) { scrollDown->setOpacity(glm::mix(0.0f, 1.0f, t)); }; scrollDown->setAnimation( new LambdaAnimation(downFadeInFunc, static_cast(fadeTime)), 0, nullptr, false); } if (downFadeOut) { auto downFadeOutFunc = [scrollDown](float t) { scrollDown->setOpacity(glm::mix(0.0f, 1.0f, t)); }; scrollDown->setAnimation( new LambdaAnimation(downFadeOutFunc, static_cast(fadeTime)), 0, nullptr, true); } mPreviousScrollState = state; }); } private: ComponentList::ScrollIndicator mPreviousScrollState; }; #endif // ES_CORE_COMPONENTS_SCROLL_INDICATOR_COMPONENT_H