void ViewController::reloadAll() { std::map<SystemData*, FileData*> cursorMap; for(auto it = mGameListViews.begin(); it != mGameListViews.end(); it++) { cursorMap[it->first] = it->second->getCursor(); } mGameListViews.clear(); for(auto it = cursorMap.begin(); it != cursorMap.end(); it++) { it->first->loadTheme(); getGameListView(it->first)->setCursor(it->second); } mSystemListView.reset(); getSystemListView(); // update mCurrentView since the pointers changed if(mState.viewing == GAME_LIST) { mCurrentView = getGameListView(mState.getSystem()); }else if(mState.viewing == SYSTEM_SELECT) { mSystemListView->goToSystem(mState.getSystem(), false); mCurrentView = mSystemListView; }else{ goToSystemView(SystemData::sSystemVector.front()); } updateHelpPrompts(); }
void ViewController::playViewTransition() { Eigen::Vector3f target(Eigen::Vector3f::Identity()); if(mCurrentView) target = mCurrentView->getPosition(); // no need to animate, we're not going anywhere (probably goToNextGamelist() or goToPrevGamelist() when there's only 1 system) if(target == -mCamera.translation() && !isAnimationPlaying(0)) return; if(Settings::getInstance()->getString("TransitionStyle") == "fade") { // fade // stop whatever's currently playing, leaving mFadeOpacity wherever it is cancelAnimation(0); auto fadeFunc = [this](float t) { mFadeOpacity = lerp<float>(0, 1, t); }; const static int FADE_DURATION = 240; // fade in/out time const static int FADE_WAIT = 320; // time to wait between in/out setAnimation(new LambdaAnimation(fadeFunc, FADE_DURATION), 0, [this, fadeFunc, target] { this->mCamera.translation() = -target; updateHelpPrompts(); setAnimation(new LambdaAnimation(fadeFunc, FADE_DURATION), FADE_WAIT, nullptr, true); }); // fast-forward animation if we're partway faded if(target == -mCamera.translation()) { // not changing screens, so cancel the first half entirely advanceAnimation(0, FADE_DURATION); advanceAnimation(0, FADE_WAIT); advanceAnimation(0, FADE_DURATION - (int)(mFadeOpacity * FADE_DURATION)); }else{ advanceAnimation(0, (int)(mFadeOpacity * FADE_DURATION)); } }else{ // slide setAnimation(new MoveCameraAnimation(mCamera, target)); updateHelpPrompts(); // update help prompts immediately } }
void ButtonComponent::setText(const std::string& text, const std::string& helpText) { mText = strToUpper(boost::locale::gettext(text.c_str())); mHelpText = boost::locale::gettext(helpText.c_str()); mTextCache = std::unique_ptr<TextCache>(mFont->buildTextCache(mText, 0, 0, getCurTextColor())); float minWidth = mFont->sizeText("DELETE").x() + 12; setSize(std::max(mTextCache->metrics.size.x() + 12, minWidth), mTextCache->metrics.size.y()); updateHelpPrompts(); }
bool SystemView::input(InputConfig* config, Input input) { if(input.value != 0) { if(config->getDeviceId() == DEVICE_KEYBOARD && input.value && input.id == SDLK_r && SDL_GetModState() & KMOD_LCTRL && Settings::getInstance()->getBool("Debug")) { LOG(LogInfo) << " Reloading SystemList view"; // reload themes for(auto it = mEntries.begin(); it != mEntries.end(); it++) it->object->loadTheme(); populate(); updateHelpPrompts(); return true; } if(config->isMappedTo("left", input)) { listInput(-1); return true; } if(config->isMappedTo("right", input)) { listInput(1); return true; } if(config->isMappedTo("a", input)) { stopScrolling(); SystemData *systemData = getSelected(); // decide whether to show game list or launch the command directly if ( !systemData->getDirectLaunch() ) { ViewController::get()->goToGameList(getSelected()); }else{ systemData->launchGame( mWindow, nullptr ); } return true; } }else{ if(config->isMappedTo("left", input) || config->isMappedTo("right", input)) listInput(0); } return GuiComponent::input(config, input); }
void SystemView::onCursorChanged(const CursorState& state) { // update help style updateHelpPrompts(); float startPos = mCamOffset; float posMax = (float)mEntries.size(); float target = (float)mCursor; // what's the shortest way to get to our target? // it's one of these... float endPos = target; // directly float dist = abs(endPos - startPos); if(abs(target + posMax - startPos) < dist) endPos = target + posMax; // loop around the end (0 -> max) if(abs(target - posMax - startPos) < dist) endPos = target - posMax; // loop around the start (max - 1 -> -1) // animate mSystemInfo's opacity (fade out, wait, fade back in) cancelAnimation(1); cancelAnimation(2); const float infoStartOpacity = mSystemInfo.getOpacity() / 255.f; Animation* infoFadeOut = new LambdaAnimation( [infoStartOpacity, this] (float t) { mSystemInfo.setOpacity((unsigned char)(lerp<float>(infoStartOpacity, 0.f, t) * 255)); }, (int)(infoStartOpacity * 150)); unsigned int gameCount = getSelected()->getGameCount(); // also change the text after we've fully faded out setAnimation(infoFadeOut, 0, [this, gameCount] { std::stringstream ss; // only display a game count if there are at least 2 games if(gameCount > 1) ss << gameCount << " GAMES AVAILABLE"; mSystemInfo.setText(ss.str()); }, false, 1); // only display a game count if there are at least 2 games if(gameCount > 1) { Animation* infoFadeIn = new LambdaAnimation( [this](float t) { mSystemInfo.setOpacity((unsigned char)(lerp<float>(0.f, 1.f, t) * 255)); }, 300); // wait 600ms to fade in setAnimation(infoFadeIn, 2000, 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; if(Settings::getInstance()->getString("TransitionStyle") == "fade") { float startExtrasFade = mExtrasFadeOpacity; anim = new LambdaAnimation( [startExtrasFade, startPos, endPos, posMax, this](float t) { t -= 1; float f = lerp<float>(startPos, endPos, t*t*t + 1); if(f < 0) f += posMax; if(f >= posMax) f -= posMax; this->mCamOffset = f; t += 1; if(t < 0.3f) this->mExtrasFadeOpacity = lerp<float>(0.0f, 1.0f, t / 0.3f + startExtrasFade); else if(t < 0.7f) this->mExtrasFadeOpacity = 1.0f; else this->mExtrasFadeOpacity = lerp<float>(1.0f, 0.0f, (t - 0.7f) / 0.3f); if(t > 0.5f) this->mExtrasCamOffset = endPos; }, 500); } else{ // slide anim = new LambdaAnimation( [startPos, endPos, posMax, this](float t) { t -= 1; float f = lerp<float>(startPos, endPos, t*t*t + 1); if(f < 0) f += posMax; if(f >= posMax) f -= posMax; this->mCamOffset = f; this->mExtrasCamOffset = f; }, 500); } setAnimation(anim, 0, nullptr, false, 0); }
void TextEditComponent::stopEditing() { SDL_StopTextInput(); mEditing = false; updateHelpPrompts(); }
void TextEditComponent::startEditing() { SDL_StartTextInput(); mEditing = true; updateHelpPrompts(); }
void SystemView::onCursorChanged(const CursorState& /*state*/) { // update help style updateHelpPrompts(); float startPos = mCamOffset; float posMax = (float)mEntries.size(); float target = (float)mCursor; // what's the shortest way to get to our target? // it's one of these... float endPos = target; // directly float dist = abs(endPos - startPos); if(abs(target + posMax - startPos) < dist) endPos = target + posMax; // loop around the end (0 -> max) if(abs(target - posMax - startPos) < dist) endPos = target - posMax; // loop around the start (max - 1 -> -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((unsigned char)(Math::lerp(infoStartOpacity, 0.f, t) * 255)); }, (int)(infoStartOpacity * (goFast ? 10 : 150))); 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 ss << gameCount << " GAMES AVAILABLE"; mSystemInfo.setText(ss.str()); }, false, 1); Animation* infoFadeIn = new LambdaAnimation( [this](float t) { mSystemInfo.setOpacity((unsigned char)(Math::lerp(0.f, 1.f, t) * 255)); }, goFast ? 10 : 300); // wait 600ms to fade in setAnimation(infoFadeIn, goFast ? 0 : 2000, 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 move_carousel = Settings::getInstance()->getBool("MoveCarousel"); if(transition_style == "fade") { float startExtrasFade = mExtrasFadeOpacity; anim = new LambdaAnimation( [this, startExtrasFade, startPos, endPos, posMax, move_carousel](float t) { t -= 1; float f = Math::lerp(startPos, endPos, t*t*t + 1); if(f < 0) f += posMax; if(f >= posMax) f -= posMax; this->mCamOffset = move_carousel ? f : endPos; t += 1; if(t < 0.3f) this->mExtrasFadeOpacity = Math::lerp(0.0f, 1.0f, t / 0.3f + startExtrasFade); else if(t < 0.7f) this->mExtrasFadeOpacity = 1.0f; else this->mExtrasFadeOpacity = Math::lerp(1.0f, 0.0f, (t - 0.7f) / 0.3f); if(t > 0.5f) this->mExtrasCamOffset = endPos; }, 500); } else if (transition_style == "slide") { // slide anim = new LambdaAnimation( [this, startPos, endPos, posMax, move_carousel](float t) { t -= 1; float f = Math::lerp(startPos, endPos, t*t*t + 1); if(f < 0) f += posMax; if(f >= posMax) f -= posMax; this->mCamOffset = move_carousel ? f : endPos; this->mExtrasCamOffset = f; }, 500); } else { // instant anim = new LambdaAnimation( [this, startPos, endPos, posMax, move_carousel ](float t) { t -= 1; float f = Math::lerp(startPos, endPos, t*t*t + 1); if(f < 0) f += posMax; if(f >= posMax) f -= posMax; this->mCamOffset = move_carousel ? f : endPos; this->mExtrasCamOffset = endPos; }, move_carousel ? 500 : 1); } setAnimation(anim, 0, nullptr, false, 0); }