Fixed multiple issues with view transitions.

This commit is contained in:
Leon Styhre 2020-11-16 17:44:33 +01:00
parent 858b20bcc1
commit 2220787c3b
9 changed files with 52 additions and 28 deletions

View file

@ -237,7 +237,7 @@ void SystemScreensaver::launchGame()
IGameListView* view = ViewController::get()->
getGameListView(mCurrentGame->getSystem()).get();
view->setCursor(mCurrentGame);
ViewController::get()->resetMovingCamera();
ViewController::get()->cancelViewTransitions();
ViewController::get()->launch(mCurrentGame);
}
}
@ -250,7 +250,7 @@ void SystemScreensaver::goToGame()
IGameListView* view = ViewController::get()->
getGameListView(mCurrentGame->getSystem()).get();
view->setCursor(mCurrentGame);
ViewController::get()->resetMovingCamera();
ViewController::get()->cancelViewTransitions();
}
}

View file

@ -162,7 +162,6 @@ void GuiMenu::openUISettings()
CollectionSystemManager::get()->updateSystemsList();
Settings::getInstance()->setString("ThemeSet", theme_set->getSelected());
s->setNeedsSaving();
s->setNeedsGoToSystemView(SystemData::sSystemVector.front());
s->setNeedsReloading();
}
});

View file

@ -200,12 +200,12 @@ bool SystemView::input(InputConfig* config, Input input)
case VERTICAL:
case VERTICAL_WHEEL:
if (config->isMappedLike("up", input)) {
ViewController::get()->resetMovingCamera();
ViewController::get()->cancelViewTransitions();
listInput(-1);
return true;
}
if (config->isMappedLike("down", input)) {
ViewController::get()->resetMovingCamera();
ViewController::get()->cancelViewTransitions();
listInput(1);
return true;
}
@ -214,12 +214,12 @@ bool SystemView::input(InputConfig* config, Input input)
case HORIZONTAL_WHEEL:
default:
if (config->isMappedLike("left", input)) {
ViewController::get()->resetMovingCamera();
ViewController::get()->cancelViewTransitions();
listInput(-1);
return true;
}
if (config->isMappedLike("right", input)) {
ViewController::get()->resetMovingCamera();
ViewController::get()->cancelViewTransitions();
listInput(1);
return true;
}
@ -244,6 +244,8 @@ bool SystemView::input(InputConfig* config, Input input)
config->isMappedTo("select", input) &&
Settings::getInstance()->getBool("ScreensaverControls")) {
if (!mWindow->isScreensaverActive()) {
ViewController::get()->stopScrolling();
ViewController::get()->cancelViewTransitions();
mWindow->startScreensaver();
mWindow->renderScreensaver();
}

View file

@ -53,6 +53,7 @@ ViewController::ViewController(
mCamera(Transform4x4f::Identity()),
mWrappedViews(false),
mFadeOpacity(0),
mCancelledAnimation(false),
mLockInput(false)
{
mState.viewing = NOTHING;
@ -124,13 +125,21 @@ bool ViewController::isCameraMoving()
return false;
}
void ViewController::resetMovingCamera()
void ViewController::cancelViewTransitions()
{
if (Settings::getInstance()->getString("TransitionStyle") == "slide" && isCameraMoving()) {
mCamera.r3().x() = -mCurrentView->getPosition().x();
mCamera.r3().y() = -mCurrentView->getPosition().y();
stopAllAnimations();
}
else if (Settings::getInstance()->getString("TransitionStyle") == "fade") {
if (isAnimationPlaying(0)) {
finishAnimation(0);
mCancelledAnimation = true;
mFadeOpacity = 0;
mWindow->invalidateCachedBackground();
}
}
}
void ViewController::stopScrolling()
@ -218,6 +227,10 @@ void ViewController::goToGameList(SystemData* system)
{
bool wrapFirstToLast = false;
bool wrapLastToFirst = false;
bool slideTransitions = false;
if (Settings::getInstance()->getString("TransitionStyle") == "slide")
slideTransitions = true;
// Restore the X position for the view, if it was previously moved.
if (mWrappedViews)
@ -226,8 +239,7 @@ void ViewController::goToGameList(SystemData* system)
// Find if we're wrapping around the first and last systems, which requires the gamelist
// to be moved in order to avoid weird camera movements. This is only needed for the
// slide transition style though.
if (mState.viewing == GAME_LIST &&
Settings::getInstance()->getString("TransitionStyle") == "slide") {
if (mState.viewing == GAME_LIST && slideTransitions) {
if (SystemData::sSystemVector.front() == mState.getSystem()) {
if (SystemData::sSystemVector.back() == system)
wrapFirstToLast = true;
@ -244,7 +256,9 @@ void ViewController::goToGameList(SystemData* system)
if (mSystemListView->isAnimationPlaying(0))
mSystemListView->finishAnimation(0);
}
resetMovingCamera();
if (slideTransitions)
cancelViewTransitions();
// Disable rendering of the system view.
if (getSystemListView()->getRenderView())
@ -259,7 +273,7 @@ void ViewController::goToGameList(SystemData* system)
float offsetX = sysList->getPosition().x();
int sysId = getSystemId(system);
sysList->setPosition(sysId* static_cast<float>(Renderer::getScreenWidth()),
sysList->setPosition(sysId * static_cast<float>(Renderer::getScreenWidth()),
sysList->getPosition().y());
offsetX = sysList->getPosition().x() - offsetX;
mCamera.translation().x() -= offsetX;
@ -309,6 +323,8 @@ void ViewController::goToGameList(SystemData* system)
void ViewController::playViewTransition(bool instant)
{
mCancelledAnimation = false;
Vector3f target(Vector3f::Zero());
if (mCurrentView)
target = mCurrentView->getPosition();
@ -330,7 +346,12 @@ void ViewController::playViewTransition(bool instant)
cancelAnimation(0);
auto fadeFunc = [this](float t) {
mFadeOpacity = Math::lerp(0, 1, t);
// The flag mCancelledAnimation is required only when cancelViewTransitions()
// cancels the animation, and it's only needed for the Fade transitions.
// Without this, a (much shorter) fade transition would still play as
// finishedCallback is calling this function.
if (!mCancelledAnimation)
mFadeOpacity = Math::lerp(0, 1, t);
};
const static int FADE_DURATION = 120; // Fade in/out time.
@ -540,7 +561,7 @@ bool ViewController::input(InputConfig* config, Input input)
// also continue to run after closing the menu.
mCurrentView->stopListScrolling();
// Finally, if the camera is currently moving, reset its position.
resetMovingCamera();
cancelViewTransitions();
mWindow->pushGui(new GuiMenu(mWindow));
return true;
@ -705,6 +726,7 @@ void ViewController::reloadAll()
goToSystemView(SystemData::sSystemVector.front(), false);
mSystemListView->goToSystem(system, false);
mCurrentView = mSystemListView;
mCamera.r3().x() = 0;
}
else {
goToSystemView(SystemData::sSystemVector.front(), false);

View file

@ -55,7 +55,7 @@ public:
// Functions to make the GUI behave properly.
bool isCameraMoving();
void resetMovingCamera();
void cancelViewTransitions();
void stopScrolling();
void onFileChanged(FileData* file, bool reloadGameList);
@ -123,6 +123,7 @@ private:
bool mWrappedViews;
float mWrapPreviousPositionX;
float mFadeOpacity;
bool mCancelledAnimation; // Needed only for the Fade transition style.
bool mLockInput;
State mState;

View file

@ -19,7 +19,7 @@ bool IGameListView::input(InputConfig* config, Input input)
// Select button opens GuiGamelistOptions.
if (!UIModeController::getInstance()->isUIModeKid() &&
config->isMappedTo("select", input) && input.value) {
ViewController::get()->resetMovingCamera();
ViewController::get()->cancelViewTransitions();
stopListScrolling();
mWindow->pushGui(new GuiGamelistOptions(mWindow, this->mRoot->getSystem()));
return true;

View file

@ -104,14 +104,14 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
if (config->isMappedTo("a", input)) {
FileData* cursor = getCursor();
if (cursor->getType() == GAME) {
ViewController::get()->resetMovingCamera();
ViewController::get()->cancelViewTransitions();
stopListScrolling();
launch(cursor);
}
else {
// It's a folder.
if (cursor->getChildren().size() > 0) {
ViewController::get()->resetMovingCamera();
ViewController::get()->cancelViewTransitions();
NavigationSounds::getInstance()->playThemeNavigationSound(SELECTSOUND);
mCursorStack.push(cursor);
populateList(cursor->getChildrenListToDisplay(), cursor);
@ -123,7 +123,7 @@ bool ISimpleGameListView::input(InputConfig* config, Input input)
return true;
}
else if (config->isMappedTo("b", input)) {
ViewController::get()->resetMovingCamera();
ViewController::get()->cancelViewTransitions();
if (mCursorStack.size()) {
NavigationSounds::getInstance()->playThemeNavigationSound(BACKSOUND);
populateList(mCursorStack.top()->getParent()->getChildrenListToDisplay(),

View file

@ -393,14 +393,14 @@ bool GuiComponent::cancelAnimation(unsigned char slot)
bool GuiComponent::finishAnimation(unsigned char slot)
{
assert(slot < MAX_ANIMATIONS);
if (mAnimationMap[slot]) {
AnimationController* anim = mAnimationMap[slot];
if (anim) {
// Skip to animation's end.
const bool done = mAnimationMap[slot]->update(mAnimationMap[slot]->
getAnimation()->getDuration() - mAnimationMap[slot]->getTime());
assert(done);
delete mAnimationMap[slot]; // Will also call finishedCallback.
mAnimationMap[slot] = nullptr;
const bool done = anim->update(anim->getAnimation()->getDuration() - anim->getTime());
if(done) {
mAnimationMap[slot] = nullptr;
delete anim; // Will also call finishedCallback.
}
return true;
}
else {
@ -416,7 +416,7 @@ bool GuiComponent::advanceAnimation(unsigned char slot, unsigned int time)
bool done = anim->update(time);
if (done) {
mAnimationMap[slot] = nullptr;
delete anim;
delete anim; // Will also call finishedCallback.
}
return true;
}

View file

@ -105,7 +105,7 @@ void Settings::setDefaults()
// UI settings.
mStringMap["StartupSystem"] = "";
mStringMap["GamelistViewStyle"] = "automatic";
mStringMap["TransitionStyle"] = "instant";
mStringMap["TransitionStyle"] = "slide";
mStringMap["ThemeSet"] = "rbsimple-DE";
mStringMap["UIMode"] = "full";
mStringMap["DefaultSortOrder"] = "filename, ascending";