From 6249b187027035aa35625e7a7e9abe7b069f63ca Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Fri, 25 Feb 2005 05:45:16 +0000 Subject: [PATCH] move bFirstRowGoesDown logic into OptionRow fix deleted OptionRowHanlder used in in ~OptionRow move options importing/exporting into OptionRow so that OptionRow can refresh itself in response to a Message --- stepmania/src/OptionRow.cpp | 96 ++++++++++++++++++++++++++- stepmania/src/OptionRow.h | 8 ++- stepmania/src/ScreenOptions.cpp | 27 +++----- stepmania/src/ScreenOptionsMaster.cpp | 77 ++------------------- 4 files changed, 119 insertions(+), 89 deletions(-) diff --git a/stepmania/src/OptionRow.cpp b/stepmania/src/OptionRow.cpp index 435d6cbb80..d1e463540a 100644 --- a/stepmania/src/OptionRow.cpp +++ b/stepmania/src/OptionRow.cpp @@ -22,6 +22,9 @@ XToString( LayoutType ); StringToX( LayoutType ); +const CString NEXT_ROW_NAME = "NextRow"; + + OptionRow::OptionRow() { FOREACH_PlayerNumber( p ) @@ -61,13 +64,16 @@ void OptionRow::Clear() } m_pHand = NULL; + + m_bFirstItemGoesDown = false; } -void OptionRow::LoadNormal( const OptionRowDefinition &def, OptionRowHandler *pHand ) +void OptionRow::LoadNormal( const OptionRowDefinition &def, OptionRowHandler *pHand, bool bFirstItemGoesDown ) { m_RowDef = def; m_RowType = OptionRow::ROW_NORMAL; m_pHand = pHand; + m_bFirstItemGoesDown = bFirstItemGoesDown; if( m_pHand ) { @@ -91,6 +97,13 @@ void OptionRow::LoadNormal( const OptionRowDefinition &def, OptionRowHandler *pH vbSelected[0] = true; } + // TRICKY: Insert a down arrow as the first choice in the row. + if( m_bFirstItemGoesDown ) + { + m_RowDef.choices.insert( m_RowDef.choices.begin(), ENTRY_NAME(NEXT_ROW_NAME) ); + FOREACH_PlayerNumber( p ) + m_vbSelected[p].insert( m_vbSelected[p].begin(), false ); + } } void OptionRow::AfterImportOptions( @@ -281,6 +294,13 @@ void OptionRow::AfterImportOptions( // set the Y position of each item in the line for( unsigned c=0; cSetY( fY ); + + // + // HACK: Set focus to one item in the row, which is "go down" + // + if( m_bFirstItemGoesDown ) + FOREACH_PlayerNumber( p ) + m_iChoiceInRowWithFocus[p] = 0; } void OptionRow::LoadExit( @@ -331,6 +351,8 @@ void OptionRow::PositionUnderlines( bool bShowUnderlines, float fTweenSeconds ) ul.SetGlobalX( (float)iX ); ul.SetGlobalDiffuseColor( RageColor(1,1,1, 1.0f) ); + ASSERT( m_vbSelected[p].size() == m_RowDef.choices.size() ); + bool bSelected = m_vbSelected[p][ iChoiceWithFocus ]; bool bHidden = !bSelected || m_bHidden; if( !bShowUnderlines ) @@ -584,6 +606,8 @@ void OptionRow::Reload() if( m_pHand == NULL ) return; + ExportOptions(); + OptionRowDefinition def; m_pHand->Reload( def ); @@ -602,6 +626,8 @@ void OptionRow::Reload() default: ASSERT(0); } + + ImportOptions(); } void OptionRow::HandleMessage( const CString& sMessage ) @@ -610,6 +636,74 @@ void OptionRow::HandleMessage( const CString& sMessage ) } +/* Hack: the NextRow entry is never set, and should be transparent. Remove + * it, and readd it below. */ +#define ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( vbSelected ) \ + if( GetFirstItemGoesDown() ) \ + vbSelected.erase( vbSelected.begin() ); +#define INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( vbSelected ) \ + if( GetFirstItemGoesDown() ) \ + vbSelected.insert( vbSelected.begin(), false ); +#define VERIFY_SELECTED( vbSelected ) if( m_RowDef.selectType == SELECT_ONE ) VerifyOneSelected(vbSelected); +static void VerifyOneSelected( const vector vbSelected ) +{ + int iNumSelected = 0; + for( unsigned e = 0; e < vbSelected.size(); ++e ) + if( vbSelected[e] ) + iNumSelected++; + ASSERT( iNumSelected == 1 ); +} + +void OptionRow::ImportOptions() +{ + if( m_pHand == NULL ) + return; + + if( m_RowDef.bOneChoiceForAllPlayers ) + { + ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[0] ); + m_pHand->ImportOption( m_RowDef, PLAYER_1, m_vbSelected[0] ); + INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[0] ); + VERIFY_SELECTED( m_vbSelected[0] ); + } + else + { + FOREACH_HumanPlayer( p ) + { + ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[p] ); + m_pHand->ImportOption( m_RowDef, p, m_vbSelected[p] ); + INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[p] ); + VERIFY_SELECTED( m_vbSelected[p] ); + } + } +} + +int OptionRow::ExportOptions() +{ + if( m_pHand == NULL ) + return 0; + + int iChangeMask = 0; + + if( m_RowDef.bOneChoiceForAllPlayers ) + { + ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[0] ); + iChangeMask |= m_pHand->ExportOption( m_RowDef, PLAYER_1, m_vbSelected[0] ); + INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[0] ); + } + else + { + FOREACH_HumanPlayer( p ) + { + ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[p] ); + iChangeMask |= m_pHand->ExportOption( m_RowDef, p, m_vbSelected[p] ); + INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[p] ); + } + } + return iChangeMask; +} + + /* * (c) 2001-2004 Chris Danford * All rights reserved. diff --git a/stepmania/src/OptionRow.h b/stepmania/src/OptionRow.h index 1d46a3f3ba..90b7ccb255 100644 --- a/stepmania/src/OptionRow.h +++ b/stepmania/src/OptionRow.h @@ -84,7 +84,7 @@ public: ~OptionRow(); void Clear(); - void LoadNormal( const OptionRowDefinition &def, OptionRowHandler *pHand ); + void LoadNormal( const OptionRowDefinition &def, OptionRowHandler *pHand, bool bFirstItemGoesDown ); void LoadExit( const CString &sFontPath, const CString &sExitText, @@ -93,6 +93,9 @@ public: ); void LoadOptionIcon( PlayerNumber pn, const CString &sText ); + void ImportOptions(); + int ExportOptions(); + void AfterImportOptions( Font* pFont, float fItemStartX, @@ -111,6 +114,7 @@ public: float fY, const ThemeMetric &cmdLabelOn ); + void DetachHandler() { m_pHand = NULL; } void PositionUnderlines( bool bShowUnderlines, float fTweenSeconds ); void PositionIcons( const ThemeMetric1D &fIconX, float fTweenSeconds ); @@ -150,6 +154,7 @@ public: void SetRowHidden( bool bRowHidden ) { m_bHidden = bRowHidden; } bool GetRowHidden() { return m_bHidden; } unsigned GetTextItemsSize() { return m_textItems.size(); } + bool GetFirstItemGoesDown() { return m_bFirstItemGoesDown; } void SetExitText( CString sExitText ); @@ -169,6 +174,7 @@ protected: Sprite m_sprBullet; BitmapText m_textTitle; OptionIcon m_OptionIcons[NUM_PLAYERS]; + bool m_bFirstItemGoesDown; float m_fY; bool m_bHidden; // currently off screen diff --git a/stepmania/src/ScreenOptions.cpp b/stepmania/src/ScreenOptions.cpp index 9062751712..f9a6624be8 100644 --- a/stepmania/src/ScreenOptions.cpp +++ b/stepmania/src/ScreenOptions.cpp @@ -167,7 +167,9 @@ void ScreenOptions::InitMenu( InputMode im, const vector &v m_Rows.push_back( new OptionRow() ); OptionRow &row = *m_Rows.back(); - row.LoadNormal( vDefs[r], vHands[r] ); + bool bFirstRowGoesDown = m_OptionsNavigation==NAV_TOGGLE_THREE_KEY; + + row.LoadNormal( vDefs[r], vHands[r], bFirstRowGoesDown ); this->ImportOptions( r ); @@ -195,13 +197,6 @@ void ScreenOptions::InitMenu( InputMode im, const vector &v fY, LABELS_ON_COMMAND ); - - // - // HACK: Set focus to one item in the row, which is "go down" - // - if( m_OptionsNavigation==NAV_TOGGLE_THREE_KEY || m_OptionsNavigation==NAV_TOGGLE_FIVE_KEY ) - FOREACH_PlayerNumber( p ) - row.m_iChoiceInRowWithFocus[p] = 0; } FONT->UnloadFont( pFont ); @@ -338,7 +333,7 @@ ScreenOptions::~ScreenOptions() { LOG->Trace( "ScreenOptions::~ScreenOptions()" ); for( unsigned i=0; iGetMetric (m_sName,"OptionMenuFlags") #define LINE(sLineName) THEME->GetMetric (m_sName,ssprintf("Line%s",sLineName.c_str())) -// keep this in sync with OptionRowHandler.cpp -#define ENTRY_NAME(s) THEME->GetMetric ("OptionNames", s) - #define NEXT_SCREEN THEME->GetMetric (m_sName,"NextScreen") #define PREV_SCREEN THEME->GetMetric (m_sName,"PrevScreen") -const CString NEXT_ROW_NAME = "NextRow"; - REGISTER_SCREEN_CLASS( ScreenOptionsMaster ); ScreenOptionsMaster::ScreenOptionsMaster( CString sClassName ): @@ -96,11 +91,6 @@ void ScreenOptionsMaster::Init() pHand = OptionRowHandlerUtil::Make( command, def ); if( pHand == NULL ) RageException::Throw( "Invalid OptionRowHandler '%s' in %s::Line%i", command.GetOriginalCommandString().c_str(), m_sName.c_str(), i ); - - - // TRICKY: Insert a down arrow as the first choice in the row. - if( m_OptionsNavigation == NAV_TOGGLE_THREE_KEY ) - def.choices.insert( def.choices.begin(), ENTRY_NAME(NEXT_ROW_NAME) ); } ASSERT( OptionRowHandlers.size() == asLineNames.size() ); @@ -110,6 +100,8 @@ void ScreenOptionsMaster::Init() ScreenOptionsMaster::~ScreenOptionsMaster() { + FOREACH( OptionRow*, m_Rows, r ) + (*r)->DetachHandler(); FOREACH( OptionRowHandler*, OptionRowHandlers, h ) SAFE_DELETE( *h ); OptionRowHandlers.clear(); @@ -133,50 +125,10 @@ void ScreenOptionsMaster::Update( float fDelta ) ScreenOptions::Update( fDelta ); } -//if( row.selectType != SELECT_MULTIPLE ) -//{ -// // The first row ("go down") should not be selected. -// ASSERT( !vbSelectedOut[0] ); - -// // there should be exactly one option selected -// int iNumSelected = 0; -// for( unsigned e = 1; e < pHand->ListEntries.size(); ++e ) -// if( vbSelectedOut[e] ) -// iNumSelected++; -// ASSERT( iNumSelected == 1 ); -//} - -/* Hack: the NextRow entry is never set, and should be transparent. Remove - * it, and readd it below. */ -#define ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( vbSelected ) \ - if( m_OptionsNavigation == NAV_TOGGLE_THREE_KEY ) \ - vbSelected.erase( vbSelected.begin() ); -#define INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( vbSelected ) \ - if( m_OptionsNavigation == NAV_TOGGLE_THREE_KEY ) \ - vbSelected.insert( vbSelected.begin(), false ); - - void ScreenOptionsMaster::ImportOptions( int r ) { - const OptionRowHandler *pHand = OptionRowHandlers[r]; - const OptionRowDefinition &def = m_OptionRowAlloc[r]; OptionRow &row = *m_Rows[r]; - - if( def.bOneChoiceForAllPlayers ) - { - ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( row.m_vbSelected[0] ); - pHand->ImportOption(def, PLAYER_1, row.m_vbSelected[0] ); - INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( row.m_vbSelected[0] ); - } - else - { - FOREACH_HumanPlayer( p ) - { - ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( row.m_vbSelected[p] ); - pHand->ImportOption( def, p, row.m_vbSelected[p] ); - INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( row.m_vbSelected[p] ); - } - } + row.ImportOptions(); } /* Import only settings specific to the given player. */ @@ -197,27 +149,10 @@ void ScreenOptionsMaster::ImportOptionsForPlayer( PlayerNumber pn ) } } -void ScreenOptionsMaster::ExportOptions( int iRow ) +void ScreenOptionsMaster::ExportOptions( int r ) { - const OptionRowHandler *pHand = OptionRowHandlers[iRow]; - const OptionRowDefinition &def = m_OptionRowAlloc[iRow]; - OptionRow &row = *m_Rows[iRow]; - - if( def.bOneChoiceForAllPlayers ) - { - ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( row.m_vbSelected[0] ); - m_iChangeMask |= pHand->ExportOption( def, PLAYER_1, row.m_vbSelected[0] ); - INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( row.m_vbSelected[0] ); - } - else - { - FOREACH_HumanPlayer( p ) - { - ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( row.m_vbSelected[p] ); - m_iChangeMask |= pHand->ExportOption( def, p, row.m_vbSelected[p] ); - INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( row.m_vbSelected[p] ); - } - } + OptionRow &row = *m_Rows[r]; + m_iChangeMask |= row.ExportOptions(); } void ScreenOptionsMaster::GoToNextScreen()