diff --git a/stepmania/src/OptionRowHandler.cpp b/stepmania/src/OptionRowHandler.cpp index 0105e153b7..2dfb2e4a6b 100644 --- a/stepmania/src/OptionRowHandler.cpp +++ b/stepmania/src/OptionRowHandler.cpp @@ -1168,7 +1168,7 @@ public: break; case EDIT_MENU_ACTION_DELETE: ASSERT( pSteps ); - SCREENMAN->Prompt( SM_None, "These notes will be lost permanently.\n\nContinue with delete?", true, false, DeleteCurNotes ); + SCREENMAN->Prompt( SM_None, "These notes will be lost permanently.\n\nContinue with delete?", PROMPT_YES_NO, ANSWER_NO, DeleteCurNotes ); break; case EDIT_MENU_ACTION_COPY: ASSERT( !pSteps ); diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 527560758f..42e267e921 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -29,6 +29,7 @@ #include "ScreenTextEntry.h" #include "Style.h" #include "ActorUtil.h" +#include "ScreenPrompt.h" const float RECORD_HOLD_SECONDS = 0.3f; @@ -1641,7 +1642,8 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) break; case SM_DoExit: - m_Out.StartTransitioning( SM_GoToNextScreen ); + if( ScreenPrompt::s_LastAnswer != ANSWER_CANCEL ) + m_Out.StartTransitioning( SM_GoToNextScreen ); break; case SM_GainFocus: @@ -1796,7 +1798,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, int* iAnswers ) g_DoReload = false; SCREENMAN->Prompt( SM_DoReloadFromDisk, "Do you want to reload from disk?\n\nThis will destroy all changes.", - true, false, ReloadFromDisk, NULL, NULL ); + PROMPT_YES_NO, ANSWER_NO, ReloadFromDisk, NULL, NULL ); break; case player_options: SCREENMAN->AddNewScreenToTop( "ScreenPlayerOptions", SM_BackFromPlayerOptions ); @@ -1925,7 +1927,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, int* iAnswers ) SCREENMAN->Prompt( SM_DoExit, "Do you want to save changes before exiting?", - true, true, DoSave ); + PROMPT_YES_NO_CANCEL, ANSWER_NO, DoSave ); break; default: ASSERT(0); diff --git a/stepmania/src/ScreenEditMenu.cpp b/stepmania/src/ScreenEditMenu.cpp index b0c13384f9..48e715dc80 100644 --- a/stepmania/src/ScreenEditMenu.cpp +++ b/stepmania/src/ScreenEditMenu.cpp @@ -172,7 +172,7 @@ void ScreenEditMenu::MenuStart( PlayerNumber pn ) break; case EDIT_MENU_ACTION_DELETE: ASSERT( pSteps ); - SCREENMAN->Prompt( SM_RefreshSelector, "These steps will be lost permanently.\n\nContinue with delete?", true, false, DeleteCurSteps ); + SCREENMAN->Prompt( SM_RefreshSelector, "These steps will be lost permanently.\n\nContinue with delete?", PROMPT_YES_NO, ANSWER_NO, DeleteCurSteps ); m_Selector.RefreshAll(); return; case EDIT_MENU_ACTION_COPY: diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 020300d6fc..29bd8d6e0c 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -1981,7 +1981,7 @@ void ScreenGameplay::ShowSavePrompt( ScreenMessage SM_SendWhenDone ) ASSERT(0); } - SCREENMAN->Prompt( SM_SendWhenDone, sMessage, true, false, SaveChanges, RevertChanges, &m_apSongsQueue ); + SCREENMAN->Prompt( SM_SendWhenDone, sMessage, PROMPT_YES_NO, ANSWER_NO, SaveChanges, RevertChanges, &m_apSongsQueue ); } /* diff --git a/stepmania/src/ScreenManager.cpp b/stepmania/src/ScreenManager.cpp index 835ac03214..a3c642eb4e 100644 --- a/stepmania/src/ScreenManager.cpp +++ b/stepmania/src/ScreenManager.cpp @@ -470,13 +470,13 @@ void ScreenManager::AddNewScreenToTop( const CString &sScreenName, ScreenMessage #include "ScreenTextEntry.h" #include "ScreenMiniMenu.h" -void ScreenManager::Prompt( ScreenMessage SM_SendWhenDone, const CString &sText, bool bYesNo, bool bDefaultAnswer, void(*OnYes)(void*), void(*OnNo)(void*), void* pCallbackData ) +void ScreenManager::Prompt( ScreenMessage SM_SendWhenDone, const CString &sText, PromptType type, PromptAnswer defaultAnswer, void(*OnYes)(void*), void(*OnNo)(void*), void* pCallbackData ) { if( m_ScreenStack.size() ) m_ScreenStack.back()->HandleScreenMessage( SM_LoseFocus ); // add the new state onto the back of the array - Screen *pNewScreen = new ScreenPrompt( sText, bYesNo, bDefaultAnswer, OnYes, OnNo, pCallbackData); + Screen *pNewScreen = new ScreenPrompt( sText, type, defaultAnswer, OnYes, OnNo, pCallbackData); pNewScreen->Init(); SetFromNewScreen( pNewScreen, true ); diff --git a/stepmania/src/ScreenManager.h b/stepmania/src/ScreenManager.h index 3e1c508659..f38c9cb6cf 100644 --- a/stepmania/src/ScreenManager.h +++ b/stepmania/src/ScreenManager.h @@ -18,6 +18,22 @@ class BGAnimation; struct lua_State; +enum PromptType +{ + PROMPT_OK, + PROMPT_YES_NO, + PROMPT_YES_NO_CANCEL +}; + +enum PromptAnswer +{ + ANSWER_YES, + ANSWER_NO, + ANSWER_CANCEL, + NUM_PROMPT_ANSWERS +}; + + typedef Screen* (*CreateScreenFn)(const CString& sClassName); class ScreenManager @@ -40,7 +56,7 @@ public: void SetNewScreen( const CString &sName ); void AddNewScreenToTop( const CString &sName, ScreenMessage messageSendOnPop ); - void Prompt( ScreenMessage SM_SendWhenDone, const CString &sText, bool bYesNo = false, bool bDefaultAnswer = false, void(*OnYes)(void*) = NULL, void(*OnNo)(void*) = NULL, void* pCallbackData = NULL ); + void Prompt( ScreenMessage SM_SendWhenDone, const CString &sText, PromptType type = PROMPT_OK, PromptAnswer defaultAnswer = ANSWER_NO, void(*OnYes)(void*) = NULL, void(*OnNo)(void*) = NULL, void* pCallbackData = NULL ); void Password( ScreenMessage SM_SendWhenDone, const CString &sText, void(*OnOK)(CString sPassword) = NULL, void(*OnCanel)() = NULL ); void TextEntry( ScreenMessage SM_SendWhenDone, CString sQuestion, CString sInitialAnswer, void(*OnOK)(CString sAnswer) = NULL, void(*OnCanel)() = NULL ); void MiniMenu( Menu* pDef, ScreenMessage SM_SendOnOK, ScreenMessage SM_SendOnCancel = SM_None ); diff --git a/stepmania/src/ScreenProfileOptions.cpp b/stepmania/src/ScreenProfileOptions.cpp index cfd46295b9..20f139a5c1 100644 --- a/stepmania/src/ScreenProfileOptions.cpp +++ b/stepmania/src/ScreenProfileOptions.cpp @@ -161,7 +161,7 @@ void ScreenProfileOptions::HandleScreenMessage( const ScreenMessage SM ) } break; case SM_DoneDeleting: - if( ScreenPrompt::s_bLastAnswer ) + if( ScreenPrompt::s_LastAnswer == ANSWER_YES ) { CString sProfileID = GetSelectedProfileID(); CString sName = GetSelectedProfileName(); @@ -196,7 +196,7 @@ void ScreenProfileOptions::MenuStart( PlayerNumber pn, const InputEventType type if( sProfileID=="" ) SCREENMAN->PlayInvalidSound(); else - SCREENMAN->Prompt( SM_DoneDeleting, ssprintf("Delete profile %s '%s'?",sProfileID.c_str(),sName.c_str()), true ); + SCREENMAN->Prompt( SM_DoneDeleting, ssprintf("Delete profile %s '%s'?",sProfileID.c_str(),sName.c_str()), PROMPT_YES_NO, ANSWER_NO ); break; } case PO_RENAME_: diff --git a/stepmania/src/ScreenPrompt.cpp b/stepmania/src/ScreenPrompt.cpp index c2a45ad4ee..65fb973115 100644 --- a/stepmania/src/ScreenPrompt.cpp +++ b/stepmania/src/ScreenPrompt.cpp @@ -15,16 +15,23 @@ #define PROMPT_X (SCREEN_CENTER_X) #define PROMPT_Y (SCREEN_CENTER_Y + 120) -bool ScreenPrompt::s_bLastAnswer = false; +PromptAnswer ScreenPrompt::s_LastAnswer = ANSWER_YES; //REGISTER_SCREEN_CLASS( ScreenPrompt ); -ScreenPrompt::ScreenPrompt( CString sText, bool bYesNoPrompt, bool bDefaultAnswer, void(*OnYes)(void*), void(*OnNo)(void*), void* pCallbackData ) : +ScreenPrompt::ScreenPrompt( + CString sText, + PromptType type, + PromptAnswer defaultAnswer, + void(*OnYes)(void*), + void(*OnNo)(void*), + void* pCallbackData + ) : Screen("ScreenPrompt") { m_bIsTransparent = true; // draw screens below us - m_bYesNoPrompt = bYesNoPrompt; - m_bAnswer = bDefaultAnswer; + m_PromptType = type; + m_Answer = defaultAnswer; m_pOnYes = OnYes; m_pOnNo = OnNo; m_pCallbackData = pCallbackData; @@ -39,7 +46,7 @@ void ScreenPrompt::Init() m_Background.PlayCommand("On"); this->AddChild( &m_Background ); - m_textQuestion.LoadFromFont( THEME->GetPathF("Common","normal") ); + m_textQuestion.LoadFromFont( THEME->GetPathF("ScreenPrompt","question") ); m_textQuestion.SetText( m_sText ); m_textQuestion.SetXY( QUESTION_X, QUESTION_Y ); this->AddChild( &m_textQuestion ); @@ -47,33 +54,40 @@ void ScreenPrompt::Init() m_rectAnswerBox.SetDiffuse( RageColor(0.5f,0.5f,1.0f,0.7f) ); this->AddChild( &m_rectAnswerBox ); - m_textAnswer[0].LoadFromFont( THEME->GetPathF("ScreenPrompt","answer") ); - m_textAnswer[1].LoadFromFont( THEME->GetPathF("ScreenPrompt","answer") ); - m_textAnswer[0].SetY( PROMPT_Y ); - m_textAnswer[1].SetY( PROMPT_Y ); - this->AddChild( &m_textAnswer[0] ); - this->AddChild( &m_textAnswer[1] ); - + for( int i=0; iGetPathF("ScreenPrompt","answer") ); + m_textAnswer[i].SetY( PROMPT_Y ); + this->AddChild( &m_textAnswer[i] ); + } - - if( m_bYesNoPrompt ) + switch( m_PromptType ) { - m_textAnswer[0].SetText( "NO" ); - m_textAnswer[1].SetText( "YES" ); - m_textAnswer[0].SetX( PROMPT_X+50 ); - m_textAnswer[1].SetX( PROMPT_X-50 ); - } - else - { - m_textAnswer[0].SetText( "OK" ); - m_textAnswer[0].SetX( PROMPT_X ); + case PROMPT_OK: + m_textAnswer[ANSWER_YES]. SetText( "OK" ); + m_textAnswer[ANSWER_YES]. SetX( PROMPT_X ); + break; + case PROMPT_YES_NO: + m_textAnswer[ANSWER_YES]. SetText( "YES" ); + m_textAnswer[ANSWER_NO]. SetText( "NO" ); + m_textAnswer[ANSWER_YES]. SetX( PROMPT_X-50 ); + m_textAnswer[ANSWER_NO]. SetX( PROMPT_X+50 ); + break; + case PROMPT_YES_NO_CANCEL: + m_textAnswer[ANSWER_YES]. SetText( "YES" ); + m_textAnswer[ANSWER_NO]. SetText( "NO" ); + m_textAnswer[ANSWER_CANCEL].SetText( "CANCEL" ); + m_textAnswer[ANSWER_YES]. SetX( PROMPT_X-120 ); + m_textAnswer[ANSWER_NO]. SetX( PROMPT_X-20 ); + m_textAnswer[ANSWER_CANCEL].SetX( PROMPT_X+150 ); + break; } - m_rectAnswerBox.SetXY( m_textAnswer[m_bAnswer].GetX(), m_textAnswer[m_bAnswer].GetY() ); - m_rectAnswerBox.SetZoomX( m_textAnswer[m_bAnswer].GetUnzoomedWidth()+10.0f ); + m_rectAnswerBox.SetXY( m_textAnswer[m_Answer].GetX(), m_textAnswer[m_Answer].GetY() ); + m_rectAnswerBox.SetZoomX( m_textAnswer[m_Answer].GetUnzoomedWidth()+10.0f ); m_rectAnswerBox.SetZoomY( 30 ); - m_textAnswer[m_bAnswer].SetEffectGlowShift(); + m_textAnswer[m_Answer].SetEffectGlowShift(); m_In.Load( THEME->GetPathB("ScreenPrompt","in") ); m_In.StartTransitioning(); @@ -135,29 +149,31 @@ void ScreenPrompt::HandleScreenMessage( const ScreenMessage SM ) } } +void ScreenPrompt::Change( int dir ) +{ + m_textAnswer[m_Answer].SetEffectNone(); + m_Answer = (PromptAnswer)(m_Answer+dir); + ASSERT( m_Answer >= 0 && m_Answer < NUM_PROMPT_ANSWERS ); + m_textAnswer[m_Answer].SetEffectGlowShift(); + + m_rectAnswerBox.StopTweening(); + m_rectAnswerBox.BeginTweening( 0.2f ); + m_rectAnswerBox.SetXY( m_textAnswer[m_Answer].GetX(), m_textAnswer[m_Answer].GetY() ); + m_rectAnswerBox.SetZoomX( m_textAnswer[m_Answer].GetUnzoomedWidth()+10.0f ); + + SOUND->PlayOnce( THEME->GetPathS("ScreenPrompt","change") ); +} + void ScreenPrompt::MenuLeft( PlayerNumber pn ) { - if( !m_bYesNoPrompt ) - return; - - MenuRight( pn ); + if( CanGoLeft() ) + Change( -1 ); } void ScreenPrompt::MenuRight( PlayerNumber pn ) { - if( !m_bYesNoPrompt ) - return; - - m_textAnswer[m_bAnswer].SetEffectNone(); - m_bAnswer = !m_bAnswer; - m_textAnswer[m_bAnswer].SetEffectGlowShift(); - - m_rectAnswerBox.StopTweening(); - m_rectAnswerBox.BeginTweening( 0.2f ); - m_rectAnswerBox.SetXY( m_textAnswer[m_bAnswer].GetX(), m_textAnswer[m_bAnswer].GetY() ); - m_rectAnswerBox.SetZoomX( m_textAnswer[m_bAnswer].GetUnzoomedWidth()+10.0f ); - - SOUND->PlayOnce( THEME->GetPathS("ScreenPrompt","change") ); + if( CanGoRight() ) + Change( +1 ); } void ScreenPrompt::MenuStart( PlayerNumber pn ) @@ -170,27 +186,29 @@ void ScreenPrompt::MenuStart( PlayerNumber pn ) m_rectAnswerBox.BeginTweening( 0.2f ); m_rectAnswerBox.SetDiffuse( RageColor(1,1,1,0) ); - m_textAnswer[m_bAnswer].SetEffectNone(); + m_textAnswer[m_Answer].SetEffectNone(); - m_textAnswer[0].BeginTweening( 0.2f ); - m_textAnswer[0].SetDiffuse( RageColor(1,1,1,0) ); - m_textAnswer[1].BeginTweening( 0.2f ); - m_textAnswer[1].SetDiffuse( RageColor(1,1,1,0) ); + for( int i=0; iPlayStartSound(); - if( m_bAnswer ) + switch( m_Answer ) { + case ANSWER_YES: if( m_pOnYes ) m_pOnYes(m_pCallbackData); - } - else - { + break; + case ANSWER_NO: if( m_pOnNo ) m_pOnNo(m_pCallbackData); + break; } - s_bLastAnswer = m_bAnswer; + s_LastAnswer = m_Answer; } void ScreenPrompt::MenuBack( PlayerNumber pn ) diff --git a/stepmania/src/ScreenPrompt.h b/stepmania/src/ScreenPrompt.h index 7c8db36ad8..76f0e9dfed 100644 --- a/stepmania/src/ScreenPrompt.h +++ b/stepmania/src/ScreenPrompt.h @@ -9,6 +9,7 @@ #include "Quad.h" #include "RandomSample.h" #include "BGAnimation.h" +#include "ScreenManager.h" class ScreenPrompt : public Screen @@ -16,29 +17,53 @@ class ScreenPrompt : public Screen public: ScreenPrompt( CString sName ); virtual void Init(); - ScreenPrompt( CString sText, bool bYesNoPrompt=false, bool bDefaultAnswer = false, void(*OnYes)(void*) = NULL, void(*OnNo)(void*) = NULL, void* pCallbackData = NULL ); + ScreenPrompt( + CString sText, + PromptType type = PROMPT_OK, + PromptAnswer defaultAnswer = ANSWER_NO, + void(*OnYes)(void*) = NULL, + void(*OnNo)(void*) = NULL, + void* pCallbackData = NULL + ); virtual void Update( float fDeltaTime ); virtual void DrawPrimitives(); virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); virtual void HandleScreenMessage( const ScreenMessage SM ); - static bool s_bLastAnswer; + static PromptAnswer s_LastAnswer; protected: + bool CanGoLeft() { return m_Answer > 0; } + bool CanGoRight() + { + switch( m_PromptType ) + { + case PROMPT_OK: + return false; + case PROMPT_YES_NO: + return m_Answer < ANSWER_NO; + case PROMPT_YES_NO_CANCEL: + return m_Answer < ANSWER_CANCEL; + default: + ASSERT(0); + } + return false; + } + void Change( int dir ); void MenuLeft( PlayerNumber pn ); void MenuRight( PlayerNumber pn ); void MenuBack( PlayerNumber pn ); void MenuStart( PlayerNumber pn ); CString m_sText; - BGAnimation m_Background; + BGAnimation m_Background; BitmapText m_textQuestion; Quad m_rectAnswerBox; - BitmapText m_textAnswer[2]; // "YES" or "NO" - bool m_bYesNoPrompt; // false = OK prompt, true = YES/NO prompt - bool m_bAnswer; // true = "YES", false = "NO"; - ScreenMessage m_SMSendWhenDone; + BitmapText m_textAnswer[NUM_PROMPT_ANSWERS]; + PromptType m_PromptType; + PromptAnswer m_Answer; + ScreenMessage m_SMSendWhenDone; // don't send on ANSWER_CANCEL void(*m_pOnYes)(void*); void(*m_pOnNo)(void*); void* m_pCallbackData;