mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 06:05:38 +00:00
Improved transitions for SystemView.
This commit is contained in:
parent
a67ee27815
commit
0a6e1f280f
|
@ -625,10 +625,6 @@ The order in which to sort your gamelists. This can be overriden per game system
|
|||
|
||||
Animation to play when opening the main menu or the game options menu. Can be set to _scale-up_, _fade-in_ or _none_.
|
||||
|
||||
**Display carousel transitions**
|
||||
|
||||
Whether to perform an animation when transitioning between systems in the system view.
|
||||
|
||||
**Render scanlines for gamelist videos** _(OpenGL renderer only)_
|
||||
|
||||
Whether to use a shader to render scanlines for videos in the gamelist view. The effect is usually pretty subtle as the video is normally renderered in a limited size in the GUI, and the scanlines are sized relative to the video window size.
|
||||
|
|
|
@ -258,22 +258,7 @@ void GuiMenu::openUISettings()
|
|||
s->setNeedsSaving();
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
// Carousel transitions.
|
||||
auto carousel_transitions = std::make_shared<SwitchComponent>(mWindow);
|
||||
carousel_transitions->setState(Settings::getInstance()->getBool("CarouselTransitions"));
|
||||
s->addWithLabel("DISPLAY CAROUSEL TRANSITIONS", carousel_transitions);
|
||||
s->addSaveFunc([carousel_transitions, s] {
|
||||
if (carousel_transitions->getState() !=
|
||||
Settings::getInstance()->getBool("CarouselTransitions")) {
|
||||
Settings::getInstance()->setBool("CarouselTransitions",
|
||||
carousel_transitions->getState());
|
||||
s->setNeedsSaving();
|
||||
}
|
||||
});
|
||||
|
||||
#if defined(USE_OPENGL_21)
|
||||
// Render scanlines for videos in the gamelists.
|
||||
auto gamelist_video_scanlines = std::make_shared<SwitchComponent>(mWindow);
|
||||
gamelist_video_scanlines->setState(Settings::getInstance()->getBool("GamelistVideoScanlines"));
|
||||
|
|
|
@ -31,6 +31,7 @@ SystemView::SystemView(
|
|||
: IList<SystemViewData, SystemData*>
|
||||
(window, LIST_SCROLL_STYLE_SLOW, LIST_ALWAYS_LOOP),
|
||||
mPreviousScrollVelocity(0),
|
||||
mUpdatedGameCount(false),
|
||||
mViewNeedsReload(true),
|
||||
mSystemInfo(window, "SYSTEM INFO", Font::get(FONT_SIZE_SMALL), 0x33333300, ALIGN_CENTER)
|
||||
{
|
||||
|
@ -152,9 +153,31 @@ void SystemView::populate()
|
|||
}
|
||||
}
|
||||
|
||||
void SystemView::updateGameCount()
|
||||
{
|
||||
std::pair<unsigned int, unsigned int> gameCount = getSelected()->getDisplayedGameCount();
|
||||
std::stringstream ss;
|
||||
|
||||
if (!getSelected()->isGameSystem())
|
||||
ss << "CONFIGURATION";
|
||||
else if (getSelected()->isCollection() && (getSelected()->getName() == "favorites"))
|
||||
ss << gameCount.first << " GAME" << (gameCount.first == 1 ? " " : "S");
|
||||
// The 'recent' gamelist has probably been trimmed after sorting, so we'll cap it at
|
||||
// its maximum limit of 50 games.
|
||||
else if (getSelected()->isCollection() && (getSelected()->getName() == "recent"))
|
||||
ss << (gameCount.first > 50 ? 50 : gameCount.first) << " GAME" <<
|
||||
(gameCount.first == 1 ? " " : "S");
|
||||
else
|
||||
ss << gameCount.first << " GAME" << (gameCount.first == 1 ? " " : "S ") << "(" <<
|
||||
gameCount.second << " FAVORITE" << (gameCount.second == 1 ? ")" : "S)");
|
||||
|
||||
mSystemInfo.setText(ss.str());
|
||||
}
|
||||
|
||||
void SystemView::goToSystem(SystemData* system, bool animate)
|
||||
{
|
||||
setCursor(system);
|
||||
updateGameCount();
|
||||
|
||||
if (!animate)
|
||||
finishAnimation(0);
|
||||
|
@ -273,70 +296,31 @@ void SystemView::onCursorChanged(const CursorState& /*state*/)
|
|||
mPreviousScrollVelocity = 1;
|
||||
}
|
||||
|
||||
// Animate mSystemInfo's opacity (fade out, wait, fade back in).
|
||||
cancelAnimation(1);
|
||||
cancelAnimation(2);
|
||||
|
||||
std::string transition_style = Settings::getInstance()->getString("TransitionStyle");
|
||||
bool goFast = transition_style == "instant";
|
||||
const float infoStartOpacity = mSystemInfo.getOpacity() / 255.f;
|
||||
|
||||
Animation* infoFadeOut = new LambdaAnimation(
|
||||
[infoStartOpacity, this] (float t) {
|
||||
mSystemInfo.setOpacity(static_cast<unsigned char>(
|
||||
Math::lerp(infoStartOpacity, 0.f, t) * 255));
|
||||
}, static_cast<int>(infoStartOpacity * (goFast ? 10 : 150)));
|
||||
|
||||
// To prevent ugly jumps with two systems when quickly repeating the same direction.
|
||||
if (mPreviousScrollVelocity != 0 && posMax == 2 &&
|
||||
mScrollVelocity == mPreviousScrollVelocity ) {
|
||||
if (fabs(endPos - startPos) < 0.5 || fabs(endPos - startPos) > 1.5) {
|
||||
(mScrollVelocity < 0) ? endPos -= 1 : endPos += 1;
|
||||
(mCursor == 0) ? mCursor = 1 : mCursor = 0;
|
||||
updateGameCount();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<unsigned int, unsigned int> gameCount = getSelected()->getDisplayedGameCount();
|
||||
|
||||
// Also change the text after we've fully faded out.
|
||||
setAnimation(infoFadeOut, 0, [this, gameCount] {
|
||||
std::stringstream ss;
|
||||
|
||||
if (!getSelected()->isGameSystem())
|
||||
ss << "CONFIGURATION";
|
||||
else if (getSelected()->isCollection() && (getSelected()->getName() == "favorites"))
|
||||
ss << gameCount.first << " GAME" << (gameCount.first == 1 ? " " : "S");
|
||||
// The 'recent' gamelist has probably been trimmed after sorting, so we'll cap it at
|
||||
// its maximum limit of 50 games.
|
||||
else if (getSelected()->isCollection() && (getSelected()->getName() == "recent"))
|
||||
ss << (gameCount.first > 50 ? 50 : gameCount.first) << " GAME" <<
|
||||
(gameCount.first == 1 ? " " : "S");
|
||||
else
|
||||
ss << gameCount.first << " GAME" << (gameCount.first == 1 ? " " : "S ") << "(" <<
|
||||
gameCount.second << " FAVORITE" << (gameCount.second == 1 ? ")" : "S)");
|
||||
|
||||
mSystemInfo.setText(ss.str());
|
||||
}, false, 1);
|
||||
|
||||
Animation* infoFadeIn = new LambdaAnimation(
|
||||
[this](float t) {
|
||||
mSystemInfo.setOpacity(static_cast<unsigned char>(Math::lerp(0.f, 1.f, t) * 255));
|
||||
}, goFast ? 10 : 300);
|
||||
|
||||
// Wait 150ms to fade in.
|
||||
setAnimation(infoFadeIn, goFast ? 0 : 500, nullptr, false, 2);
|
||||
|
||||
// No need to animate transition, we're not going anywhere (probably mEntries.size() == 1).
|
||||
if (endPos == mCamOffset && endPos == mExtrasCamOffset)
|
||||
return;
|
||||
|
||||
Animation* anim;
|
||||
bool carousel_transitions = Settings::getInstance()->getBool("CarouselTransitions");
|
||||
|
||||
if (transition_style == "fade") {
|
||||
float startExtrasFade = mExtrasFadeOpacity;
|
||||
anim = new LambdaAnimation(
|
||||
[this, startExtrasFade, startPos, endPos, posMax, carousel_transitions](float t) {
|
||||
[this, startExtrasFade, startPos, endPos, posMax](float t) {
|
||||
t -= 1;
|
||||
float f = Math::lerp(startPos, endPos, t*t*t + 1);
|
||||
if (f < 0)
|
||||
|
@ -344,7 +328,7 @@ void SystemView::onCursorChanged(const CursorState& /*state*/)
|
|||
if (f >= posMax)
|
||||
f -= posMax;
|
||||
|
||||
this->mCamOffset = carousel_transitions ? f : endPos;
|
||||
this->mCamOffset = f;
|
||||
|
||||
t += 1;
|
||||
if (t < 0.3f)
|
||||
|
@ -357,12 +341,15 @@ void SystemView::onCursorChanged(const CursorState& /*state*/)
|
|||
if (t > 0.5f)
|
||||
this->mExtrasCamOffset = endPos;
|
||||
|
||||
// Update the game count when the entire animation has been completed.
|
||||
if (mExtrasFadeOpacity == 1.0)
|
||||
updateGameCount();
|
||||
}, 500);
|
||||
}
|
||||
else if (transition_style == "slide") {
|
||||
// Slide.
|
||||
mUpdatedGameCount = false;
|
||||
anim = new LambdaAnimation(
|
||||
[this, startPos, endPos, posMax, carousel_transitions](float t) {
|
||||
[this, startPos, endPos, posMax](float t) {
|
||||
t -= 1;
|
||||
float f = Math::lerp(startPos, endPos, t*t*t + 1);
|
||||
if (f < 0)
|
||||
|
@ -370,14 +357,30 @@ void SystemView::onCursorChanged(const CursorState& /*state*/)
|
|||
if (f >= posMax)
|
||||
f -= posMax;
|
||||
|
||||
this->mCamOffset = carousel_transitions ? f : endPos;
|
||||
this->mCamOffset = f;
|
||||
this->mExtrasCamOffset = f;
|
||||
|
||||
// Hack to make the game count being updated in the middle of the animation.
|
||||
bool update = false;
|
||||
if (endPos == -1 && fabs(fabs(posMax) - fabs(mCamOffset)) > 0.5 && !mUpdatedGameCount)
|
||||
update = true;
|
||||
else if (endPos > posMax && fabs(endPos - posMax - fabs(mCamOffset)) <
|
||||
0.5 && !mUpdatedGameCount)
|
||||
update = true;
|
||||
else if (fabs(fabs(endPos) - fabs(mCamOffset)) < 0.5 && !mUpdatedGameCount)
|
||||
update = true;
|
||||
|
||||
if (update) {
|
||||
mUpdatedGameCount = true;
|
||||
updateGameCount();
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
else {
|
||||
// Instant.
|
||||
updateGameCount();
|
||||
anim = new LambdaAnimation(
|
||||
[this, startPos, endPos, posMax, carousel_transitions ](float t) {
|
||||
[this, startPos, endPos, posMax ](float t) {
|
||||
t -= 1;
|
||||
float f = Math::lerp(startPos, endPos, t*t*t + 1);
|
||||
if (f < 0)
|
||||
|
@ -385,9 +388,9 @@ void SystemView::onCursorChanged(const CursorState& /*state*/)
|
|||
if (f >= posMax)
|
||||
f -= posMax;
|
||||
|
||||
this->mCamOffset = carousel_transitions ? f : endPos;
|
||||
this->mCamOffset = f;
|
||||
this->mExtrasCamOffset = endPos;
|
||||
}, carousel_transitions ? 500 : 1);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
setAnimation(anim, 0, nullptr, false, 0);
|
||||
|
@ -400,29 +403,16 @@ void SystemView::render(const Transform4x4f& parentTrans)
|
|||
|
||||
Transform4x4f trans = getTransform() * parentTrans;
|
||||
|
||||
auto systemInfoZIndex = mSystemInfo.getZIndex();
|
||||
auto minMax = std::minmax(mCarousel.zIndex, systemInfoZIndex);
|
||||
renderExtras(trans, INT16_MIN, INT16_MAX);
|
||||
|
||||
renderExtras(trans, INT16_MIN, minMax.first);
|
||||
// Fade the screen if we're using fade transitions and we're currently transitioning.
|
||||
// This basically renders a black rectangle on top of the currently visible extras
|
||||
// (and beneath the carousel and help prompts).
|
||||
if (mExtrasFadeOpacity)
|
||||
renderFade(trans);
|
||||
|
||||
if (mCarousel.zIndex > mSystemInfo.getZIndex()) {
|
||||
renderInfoBar(trans);
|
||||
}
|
||||
else {
|
||||
// Always render the carousel on top so that it's not faded.
|
||||
renderCarousel(trans);
|
||||
}
|
||||
|
||||
renderExtras(trans, minMax.first, minMax.second);
|
||||
|
||||
if (mCarousel.zIndex > mSystemInfo.getZIndex()) {
|
||||
renderCarousel(trans);
|
||||
}
|
||||
else {
|
||||
renderInfoBar(trans);
|
||||
}
|
||||
|
||||
renderExtras(trans, minMax.second, INT16_MAX);
|
||||
}
|
||||
|
||||
std::vector<HelpPrompt> SystemView::getHelpPrompts()
|
||||
|
@ -597,12 +587,6 @@ void SystemView::renderCarousel(const Transform4x4f& trans)
|
|||
Renderer::popClipRect();
|
||||
}
|
||||
|
||||
void SystemView::renderInfoBar(const Transform4x4f& trans)
|
||||
{
|
||||
Renderer::setMatrix(trans);
|
||||
mSystemInfo.render(trans);
|
||||
}
|
||||
|
||||
// Draw background extras.
|
||||
void SystemView::renderExtras(const Transform4x4f& trans, float lower, float upper)
|
||||
{
|
||||
|
@ -637,10 +621,10 @@ void SystemView::renderExtras(const Transform4x4f& trans, float lower, float upp
|
|||
SystemViewData data = mEntries.at(index).data;
|
||||
for (unsigned int j = 0; j < data.backgroundExtras.size(); j++) {
|
||||
GuiComponent *extra = data.backgroundExtras[j];
|
||||
if (extra->getZIndex() >= lower && extra->getZIndex() < upper) {
|
||||
if (extra->getZIndex() >= lower && extra->getZIndex() < upper)
|
||||
extra->render(extrasTrans);
|
||||
}
|
||||
}
|
||||
mSystemInfo.render(extrasTrans);
|
||||
Renderer::popClipRect();
|
||||
}
|
||||
}
|
||||
|
@ -649,12 +633,9 @@ void SystemView::renderExtras(const Transform4x4f& trans, float lower, float upp
|
|||
|
||||
void SystemView::renderFade(const Transform4x4f& trans)
|
||||
{
|
||||
// Fade extras if necessary.
|
||||
if (mExtrasFadeOpacity) {
|
||||
unsigned int fadeColor = 0x00000000 | static_cast<unsigned char>(mExtrasFadeOpacity * 255);
|
||||
Renderer::setMatrix(trans);
|
||||
Renderer::drawRect(0.0f, 0.0f, mSize.x(), mSize.y(), fadeColor, fadeColor);
|
||||
}
|
||||
}
|
||||
|
||||
// Populate the system carousel with the legacy values.
|
||||
|
|
|
@ -76,13 +76,13 @@ protected:
|
|||
|
||||
private:
|
||||
void populate();
|
||||
void updateGameCount();
|
||||
void getViewElements(const std::shared_ptr<ThemeData>& theme);
|
||||
void getDefaultElements(void);
|
||||
void getCarouselFromTheme(const ThemeData::ThemeElement* elem);
|
||||
|
||||
void renderCarousel(const Transform4x4f& parentTrans);
|
||||
void renderExtras(const Transform4x4f& parentTrans, float lower, float upper);
|
||||
void renderInfoBar(const Transform4x4f& trans);
|
||||
void renderFade(const Transform4x4f& trans);
|
||||
|
||||
SystemViewCarousel mCarousel;
|
||||
|
@ -94,6 +94,7 @@ private:
|
|||
float mExtrasFadeOpacity;
|
||||
|
||||
int mPreviousScrollVelocity;
|
||||
bool mUpdatedGameCount;
|
||||
bool mViewNeedsReload;
|
||||
bool mShowing;
|
||||
};
|
||||
|
|
|
@ -110,7 +110,6 @@ void Settings::setDefaults()
|
|||
mStringMap["UIMode"] = "full";
|
||||
mStringMap["DefaultSortOrder"] = "filename, ascending";
|
||||
mStringMap["MenuOpeningEffect"] = "scale-up";
|
||||
mBoolMap["CarouselTransitions"] = true;
|
||||
mBoolMap["GamelistVideoScanlines"] = true;
|
||||
mBoolMap["FoldersOnTop"] = true;
|
||||
mBoolMap["FavoritesFirst"] = true;
|
||||
|
|
Loading…
Reference in a new issue