From e0b31f5354f6776e1036bd1eb401d39d5ed365c4 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sun, 5 Dec 2004 11:55:35 +0000 Subject: [PATCH] add new row type, SELECT_NONE used in operator menu --- stepmania/src/ScreenOptions.cpp | 126 +++++++++++++------------- stepmania/src/ScreenOptions.h | 12 +-- stepmania/src/ScreenOptionsMaster.cpp | 38 +++++--- stepmania/src/ScreenOptionsMaster.h | 2 +- 4 files changed, 91 insertions(+), 87 deletions(-) diff --git a/stepmania/src/ScreenOptions.cpp b/stepmania/src/ScreenOptions.cpp index fc37da19c6..127cb30cbb 100644 --- a/stepmania/src/ScreenOptions.cpp +++ b/stepmania/src/ScreenOptions.cpp @@ -152,8 +152,8 @@ void ScreenOptions::Init( InputMode im, OptionRowData OptionRows[], int iNumOpti for( unsigned j=0; jm_vbSelected[0]; + row.m_vbSelected[p] = m_Rows[r]->m_vbSelected[0]; } - CHECKPOINT_M( ssprintf("row %i: %s", r, Row.m_RowDef.name.c_str()) ); + CHECKPOINT_M( ssprintf("row %i: %s", r, row.m_RowDef.name.c_str()) ); FOREACH_PlayerNumber( p ) { + // + // Set focus to one item in the row + // if( m_OptionsNavigation==NAV_TOGGLE_THREE_KEY || m_OptionsNavigation==NAV_TOGGLE_FIVE_KEY ) - Row.m_iChoiceWithFocus[p] = 0; // focus on the first row, which is "go down" - else + { + row.m_iChoiceInRowWithFocus[p] = 0; // focus on the first row, which is "go down" + } + else if( row.m_RowDef.type == OptionRowData::SELECT_ONE ) { /* Make sure the row actually has a selection. */ bool bHasSelection = false; unsigned i; - for( i=0; iWarn( "Options menu \"%s\" row %i has no selection", m_sName.c_str(), i ); - Row.m_vbSelected[p][0] = true; + row.m_vbSelected[p][0] = true; } - Row.m_iChoiceWithFocus[p] = Row.GetOneSelection( (PlayerNumber)p); // focus on the only selected choice + row.m_iChoiceInRowWithFocus[p] = row.GetOneSelection(p); // focus on the selection we just set + } + else + { + row.m_iChoiceInRowWithFocus[p] = 0; } } } @@ -204,11 +213,8 @@ void ScreenOptions::Init( InputMode im, OptionRowData OptionRows[], int iNumOpti m_framePage.AddChild( m_sprPage ); // init line highlights - FOREACH_PlayerNumber( p ) + FOREACH_HumanPlayer( p ) { - if( !GAMESTATE->IsHumanPlayer(p) ) - continue; // skip - m_sprLineHighlight[p].Load( THEME->GetPathToG("ScreenOptions line highlight") ); m_sprLineHighlight[p].SetName( "LineHighlight" ); m_sprLineHighlight[p].SetX( SCREEN_CENTER_X ); @@ -217,21 +223,15 @@ void ScreenOptions::Init( InputMode im, OptionRowData OptionRows[], int iNumOpti } // init highlights - FOREACH_PlayerNumber( p ) + FOREACH_HumanPlayer( p ) { - if( !GAMESTATE->IsHumanPlayer(p) ) - continue; // skip - m_Highlight[p].Load( (PlayerNumber)p, false ); m_framePage.AddChild( &m_Highlight[p] ); } // init row icons - FOREACH_PlayerNumber( p ) + FOREACH_HumanPlayer( p ) { - if( !GAMESTATE->IsHumanPlayer(p) ) - continue; // skip - for( unsigned l=0; lLoadFromFont( THEME->GetPathToF("ScreenOptions item") ); - bt->SetText( optline.choices[iChoiceWithFocus] ); + bt->SetText( optline.choices[iChoiceInRowWithFocus] ); bt->SetZoom( ITEMS_ZOOM ); bt->SetShadowLength( 0 ); @@ -572,7 +572,9 @@ BitmapText &ScreenOptions::GetTextItemForRow( PlayerNumber pn, int iRow, int iCh index = 0; } else + { index = iChoiceOnRow; + } ASSERT_M( index < (int)row.m_textItems.size(), ssprintf("%i < %i", index, (int)row.m_textItems.size() ) ); return *row.m_textItems[index]; @@ -636,11 +638,8 @@ void ScreenOptions::PositionUnderlines() if( row.Type == Row::ROW_EXIT ) continue; - FOREACH_PlayerNumber( p ) + FOREACH_HumanPlayer( p ) { - if( !GAMESTATE->IsHumanPlayer(p) ) - continue; // skip - vector &vpUnderlines = row.m_Underline[p]; const int iNumUnderlines = row.m_bRowIsLong ? 1 : vpUnderlines.size(); @@ -649,19 +648,16 @@ void ScreenOptions::PositionUnderlines() { OptionsCursor& ul = *vpUnderlines[i]; - int iChoiceWithFocus = row.m_bRowIsLong ? row.m_iChoiceWithFocus[p] : i; + int iChoiceWithFocus = row.m_bRowIsLong ? row.m_iChoiceInRowWithFocus[p] : i; /* Don't tween X movement and color changes. */ int iWidth, iX, iY; - GetWidthXY( (PlayerNumber)p, r, iChoiceWithFocus, iWidth, iX, iY ); + GetWidthXY( p, r, iChoiceWithFocus, iWidth, iX, iY ); ul.SetGlobalX( (float)iX ); ul.SetGlobalDiffuseColor( RageColor(1,1,1, 1.0f) ); - // Don't show underlines on the ScreenOptionsMenu. We know we're on this - // screen if the row title is empty. - bool bEmptyTitle = GetExplanationTitle(r).empty(); bool bSelected = row.m_vbSelected[p][ iChoiceWithFocus ]; - bool bHidden = bEmptyTitle || !bSelected || row.m_bHidden; + bool bHidden = !bSelected || row.m_bHidden; if( ul.GetDestY() != row.m_fY ) { @@ -669,8 +665,7 @@ void ScreenOptions::PositionUnderlines() ul.BeginTweening( 0.3f ); } - /* XXX: diffuse doesn't work since underline is an ActorFrame */ - ul.SetDiffuse( RageColor(1,1,1,bHidden? 0.0f:1.0f) ); + ul.SetHidden( bHidden ); ul.SetBarWidth( iWidth ); ul.SetY( (float)iY ); } @@ -693,7 +688,7 @@ void ScreenOptions::PositionIcons() OptionIcon &icon = row.m_OptionIcons[p]; - int iChoiceWithFocus = row.m_iChoiceWithFocus[p]; + int iChoiceWithFocus = row.m_iChoiceInRowWithFocus[p]; int iWidth, iX, iY; // We only use iY GetWidthXY( (PlayerNumber)p, i, iChoiceWithFocus, iWidth, iX, iY ); @@ -733,7 +728,7 @@ void ScreenOptions::PositionCursors() OptionsCursor &highlight = m_Highlight[pn]; - const int iChoiceWithFocus = Row.m_iChoiceWithFocus[pn]; + const int iChoiceWithFocus = Row.m_iChoiceInRowWithFocus[pn]; int iWidth, iX, iY; GetWidthXY( (PlayerNumber)pn, iRow, iChoiceWithFocus, iWidth, iX, iY ); @@ -749,7 +744,7 @@ void ScreenOptions::TweenCursor( PlayerNumber pn ) ASSERT_M( iRow < (int)m_Rows.size(), ssprintf("%i < %i", iRow, (int)m_Rows.size() ) ); const Row &Row = *m_Rows[iRow]; - const int iChoiceWithFocus = Row.m_iChoiceWithFocus[pn]; + const int iChoiceWithFocus = Row.m_iChoiceInRowWithFocus[pn]; int iWidth, iX, iY; GetWidthXY( pn, iRow, iChoiceWithFocus, iWidth, iX, iY ); @@ -785,7 +780,7 @@ void ScreenOptions::UpdateText( int iRow ) FOREACH_HumanPlayer( pn ) { - int iChoiceWithFocus = row.m_iChoiceWithFocus[pn]; + int iChoiceWithFocus = row.m_iChoiceInRowWithFocus[pn]; unsigned item_no = data.bOneChoiceForAllPlayers ? 0 : pn; /* If player_no is 2 and there is no player 1: */ @@ -1186,7 +1181,7 @@ void ScreenOptions::MenuStart( PlayerNumber pn, const InputEventType type ) if( m_OptionsNavigation == NAV_TOGGLE_THREE_KEY ) { - int iChoiceInRow = row.m_iChoiceWithFocus[pn]; + int iChoiceInRow = row.m_iChoiceInRowWithFocus[pn]; if( iChoiceInRow == 0 ) { MenuDown( pn, type ); @@ -1194,10 +1189,10 @@ void ScreenOptions::MenuStart( PlayerNumber pn, const InputEventType type ) } } - // If this is a bFirstChoiceGoesDown, then if this is a multiselect row. - if( data.bMultiSelect ) + // If this is a bFirstChoiceGoesDown, then if this is a multiselect row. + if( data.type == OptionRowData::SELECT_MULTIPLE ) { - int iChoiceInRow = row.m_iChoiceWithFocus[pn]; + int iChoiceInRow = row.m_iChoiceInRowWithFocus[pn]; row.m_vbSelected[pn][iChoiceInRow] = !row.m_vbSelected[pn][iChoiceInRow]; if( row.m_vbSelected[pn][iChoiceInRow] ) m_SoundToggleOn.Play(); @@ -1207,9 +1202,12 @@ void ScreenOptions::MenuStart( PlayerNumber pn, const InputEventType type ) RefreshIcons(); if( m_OptionsNavigation == NAV_TOGGLE_THREE_KEY ) - ChangeValueInRow( pn, -row.m_iChoiceWithFocus[pn], type != IET_FIRST_PRESS ); // move to the first choice + { + // move to the first choice in the row + ChangeValueInRow( pn, -row.m_iChoiceInRowWithFocus[pn], type != IET_FIRST_PRESS ); + } } - else + else // data.type != SELECT_MULTIPLE { switch( m_OptionsNavigation ) { @@ -1218,16 +1216,16 @@ void ScreenOptions::MenuStart( PlayerNumber pn, const InputEventType type ) break; case NAV_TOGGLE_THREE_KEY: case NAV_TOGGLE_FIVE_KEY: - if( !data.bMultiSelect ) + if( data.type != OptionRowData::SELECT_MULTIPLE ) { - int iChoiceInRow = row.m_iChoiceWithFocus[pn]; + int iChoiceInRow = row.m_iChoiceInRowWithFocus[pn]; if( row.m_RowDef.bOneChoiceForAllPlayers ) row.SetOneSharedSelection( iChoiceInRow ); else row.SetOneSelection( pn, iChoiceInRow ); } if( m_OptionsNavigation == NAV_TOGGLE_THREE_KEY ) - ChangeValueInRow( pn, -row.m_iChoiceWithFocus[pn], type != IET_FIRST_PRESS ); // move to the first choice + ChangeValueInRow( pn, -row.m_iChoiceInRowWithFocus[pn], type != IET_FIRST_PRESS ); // move to the first choice else ChangeValueInRow( pn, 0, type != IET_FIRST_PRESS ); break; @@ -1253,8 +1251,8 @@ void ScreenOptions::StoreFocus( PlayerNumber pn ) return; int iWidth, iY; - GetWidthXY( pn, m_iCurrentRow[pn], m_Rows[m_iCurrentRow[pn]]->m_iChoiceWithFocus[pn], iWidth, m_iFocusX[pn], iY ); - LOG->Trace("cur selection %ix%i @ %i", m_iCurrentRow[pn], m_Rows[m_iCurrentRow[pn]]->m_iChoiceWithFocus[pn], + GetWidthXY( pn, m_iCurrentRow[pn], m_Rows[m_iCurrentRow[pn]]->m_iChoiceInRowWithFocus[pn], iWidth, m_iFocusX[pn], iY ); + LOG->Trace("cur selection %ix%i @ %i", m_iCurrentRow[pn], m_Rows[m_iCurrentRow[pn]]->m_iChoiceInRowWithFocus[pn], m_iFocusX[pn]); } @@ -1286,14 +1284,14 @@ void ScreenOptions::ChangeValueInRow( PlayerNumber pn, int iDelta, bool Repeat ) bool bOneChanged = false; - int iCurrentChoiceWithFocus = row.m_iChoiceWithFocus[pn]; + int iCurrentChoiceWithFocus = row.m_iChoiceInRowWithFocus[pn]; int iNewChoiceWithFocus = iCurrentChoiceWithFocus + iDelta; wrap( iNewChoiceWithFocus, iNumOptions ); if( iCurrentChoiceWithFocus != iNewChoiceWithFocus ) bOneChanged = true; - row.m_iChoiceWithFocus[pn] = iNewChoiceWithFocus; + row.m_iChoiceInRowWithFocus[pn] = iNewChoiceWithFocus; StoreFocus( pn ); if( optrow.bOneChoiceForAllPlayers ) @@ -1316,7 +1314,7 @@ void ScreenOptions::ChangeValueInRow( PlayerNumber pn, int iDelta, bool Repeat ) // lock focus together FOREACH_HumanPlayer( p ) { - row.m_iChoiceWithFocus[p] = iNewChoiceWithFocus; + row.m_iChoiceInRowWithFocus[p] = iNewChoiceWithFocus; StoreFocus( pn ); } } @@ -1329,7 +1327,7 @@ void ScreenOptions::ChangeValueInRow( PlayerNumber pn, int iDelta, bool Repeat ) } else { - if( optrow.bMultiSelect ) + if( optrow.type == OptionRowData::SELECT_MULTIPLE ) ; // do nothing. User must press Start to toggle the selection. else row.SetOneSelection( (PlayerNumber)p, iNewChoiceWithFocus ); @@ -1344,7 +1342,7 @@ void ScreenOptions::ChangeValueInRow( PlayerNumber pn, int iDelta, bool Repeat ) } else { - if( optrow.bMultiSelect ) + if( optrow.type == OptionRowData::SELECT_MULTIPLE ) ; // do nothing. User must press Start to toggle the selection. else row.SetOneSelection( pn, iNewChoiceWithFocus ); @@ -1369,7 +1367,7 @@ void ScreenOptions::MoveRow( PlayerNumber pn, int dir, bool Repeat ) // the first choice before moving. const int iCurrentRow = m_iCurrentRow[pn]; Row &row = *m_Rows[iCurrentRow]; - row.m_iChoiceWithFocus[pn] = 0; + row.m_iChoiceInRowWithFocus[pn] = 0; } LOG->Trace("move pn %i, dir %i, rep %i", pn, dir, Repeat); @@ -1385,7 +1383,7 @@ void ScreenOptions::MoveRow( PlayerNumber pn, int dir, bool Repeat ) wrap( row, m_Rows.size() ); - const unsigned iOldSelection = m_Rows[m_iCurrentRow[p]]->m_iChoiceWithFocus[p]; + const unsigned iOldSelection = m_Rows[m_iCurrentRow[p]]->m_iChoiceInRowWithFocus[p]; m_iCurrentRow[p] = row; @@ -1404,10 +1402,10 @@ void ScreenOptions::MoveRow( PlayerNumber pn, int dir, bool Repeat ) if( iSelectionDist == -1 || iDist < iSelectionDist ) { iSelectionDist = iDist; - m_Rows[row]->m_iChoiceWithFocus[p] = i; + m_Rows[row]->m_iChoiceInRowWithFocus[p] = i; } } - m_Rows[row]->m_iChoiceWithFocus[p] = min( iOldSelection, m_Rows[row]->m_textItems.size()-1 ); + m_Rows[row]->m_iChoiceInRowWithFocus[p] = min( iOldSelection, m_Rows[row]->m_textItems.size()-1 ); } } @@ -1439,10 +1437,10 @@ ScreenOptions::Row::Row() ScreenOptions::Row::~Row() { for( unsigned i = 0; i < m_textItems.size(); ++i ) - delete m_textItems[i]; + SAFE_DELETE( m_textItems[i] ); FOREACH_PlayerNumber( p ) for( unsigned i = 0; i < m_Underline[p].size(); ++i ) - delete m_Underline[p][i]; + SAFE_DELETE( m_Underline[p][i] ); } /* diff --git a/stepmania/src/ScreenOptions.h b/stepmania/src/ScreenOptions.h index 2a485deee4..e07d1a5de7 100644 --- a/stepmania/src/ScreenOptions.h +++ b/stepmania/src/ScreenOptions.h @@ -17,16 +17,14 @@ struct OptionRowData { CString name; bool bOneChoiceForAllPlayers; - bool bMultiSelect; + enum Type { SELECT_ONE, SELECT_MULTIPLE, SELECT_NONE } type; vector choices; - OptionRowData(): name(""), bOneChoiceForAllPlayers(false), bMultiSelect(false) { } + OptionRowData(): name(""), bOneChoiceForAllPlayers(false), type(SELECT_ONE) { } - OptionRowData( const char *n, int b, const char *c0=NULL, const char *c1=NULL, const char *c2=NULL, const char *c3=NULL, const char *c4=NULL, const char *c5=NULL, const char *c6=NULL, const char *c7=NULL, const char *c8=NULL, const char *c9=NULL, const char *c10=NULL, const char *c11=NULL, const char *c12=NULL, const char *c13=NULL, const char *c14=NULL, const char *c15=NULL, const char *c16=NULL, const char *c17=NULL, const char *c18=NULL, const char *c19=NULL ) + OptionRowData( const char *n, bool b, const char *c0=NULL, const char *c1=NULL, const char *c2=NULL, const char *c3=NULL, const char *c4=NULL, const char *c5=NULL, const char *c6=NULL, const char *c7=NULL, const char *c8=NULL, const char *c9=NULL, const char *c10=NULL, const char *c11=NULL, const char *c12=NULL, const char *c13=NULL, const char *c14=NULL, const char *c15=NULL, const char *c16=NULL, const char *c17=NULL, const char *c18=NULL, const char *c19=NULL ) : + name(n), bOneChoiceForAllPlayers(b), type(SELECT_ONE) { - name = n; - bOneChoiceForAllPlayers = !!b; - bMultiSelect = false; #define PUSH( c ) if(c) choices.push_back(c); PUSH(c0);PUSH(c1);PUSH(c2);PUSH(c3);PUSH(c4);PUSH(c5);PUSH(c6);PUSH(c7);PUSH(c8);PUSH(c9);PUSH(c10);PUSH(c11);PUSH(c12);PUSH(c13);PUSH(c14);PUSH(c15);PUSH(c16);PUSH(c17);PUSH(c18);PUSH(c19); #undef PUSH @@ -111,7 +109,7 @@ protected: bool m_bRowIsLong; // goes off edge of screen bool m_bHidden; // currently off screen - int m_iChoiceWithFocus[NUM_PLAYERS]; // this choice has input focus + int m_iChoiceInRowWithFocus[NUM_PLAYERS]; // this choice has input focus // Only one will true at a time if m_RowDef.bMultiSelect vector m_vbSelected[NUM_PLAYERS]; // size = m_RowDef.choices.size(). diff --git a/stepmania/src/ScreenOptionsMaster.cpp b/stepmania/src/ScreenOptionsMaster.cpp index d51c82052e..45bd9b9225 100644 --- a/stepmania/src/ScreenOptionsMaster.cpp +++ b/stepmania/src/ScreenOptionsMaster.cpp @@ -72,8 +72,10 @@ void ScreenOptionsMaster::SetList( OptionRowData &row, OptionRowHandler &hand, C { if( asParts[i].CompareNoCase("together") == 0 ) row.bOneChoiceForAllPlayers = true; - else if( asParts[i].CompareNoCase("multiselect") == 0 ) - row.bMultiSelect = true; + else if( asParts[i].CompareNoCase("SelectMultiple") == 0 ) + row.type = OptionRowData::SELECT_MULTIPLE; + else if( asParts[i].CompareNoCase("SelectNone") == 0 ) + row.type = OptionRowData::SELECT_NONE; } for( int col = 0; col < NumCols; ++col ) @@ -335,7 +337,7 @@ void ScreenOptionsMaster::ImportOption( const OptionRowData &row, const OptionRo /* The entry has no effect. This is usually a default "none of the * above" entry. It will always return true for DescribesCurrentMode(). * It's only the selected choice if nothing else matches. */ - if( !row.bMultiSelect ) + if( row.type != OptionRowData::SELECT_MULTIPLE ) FallbackOption = e; continue; } @@ -345,7 +347,7 @@ void ScreenOptionsMaster::ImportOption( const OptionRowData &row, const OptionRo if( mc.DescribesCurrentModeForAllPlayers() ) { UseFallbackOption = false; - if( !row.bMultiSelect ) + if( row.type != OptionRowData::SELECT_MULTIPLE ) SelectExactlyOne( e, vbSelectedOut ); else vbSelectedOut[e] = true; @@ -356,7 +358,7 @@ void ScreenOptionsMaster::ImportOption( const OptionRowData &row, const OptionRo if( mc.DescribesCurrentMode( pn) ) { UseFallbackOption = false; - if( !row.bMultiSelect ) + if( row.type != OptionRowData::SELECT_MULTIPLE ) SelectExactlyOne( e, vbSelectedOut ); else vbSelectedOut[e] = true; @@ -364,8 +366,13 @@ void ScreenOptionsMaster::ImportOption( const OptionRowData &row, const OptionRo } } - if( UseFallbackOption && FallbackOption != -1 && !row.bMultiSelect ) + if( row.type != OptionRowData::SELECT_NONE && + UseFallbackOption && + FallbackOption != -1 && + row.type != OptionRowData::SELECT_MULTIPLE ) + { SelectExactlyOne( FallbackOption, vbSelectedOut ); + } return; } @@ -381,7 +388,7 @@ void ScreenOptionsMaster::ImportOption( const OptionRowData &row, const OptionRo ASSERT(0); } - if( !row.bMultiSelect ) + if( row.type != OptionRowData::SELECT_MULTIPLE ) { // The first row ("go down") should not be selected. ASSERT( !vbSelectedOut[0] ); @@ -513,7 +520,7 @@ void ScreenOptionsMaster::ExportOptions() CHECKPOINT; /* If the selection is on a LIST, and the selected LIST option sets the screen, * honor it. */ - m_NextScreen = ""; + m_sNextScreen = ""; const int row = this->GetCurrentRow(); if( row != -1 ) @@ -521,17 +528,18 @@ void ScreenOptionsMaster::ExportOptions() const OptionRowHandler &hand = OptionRowHandlers[row]; if( hand.type == ROW_LIST ) { - const int choice = m_Rows[row]->m_iChoiceWithFocus[0]; + const int choice = m_Rows[row]->m_iChoiceInRowWithFocus[0]; const GameCommand &mc = hand.ListEntries[choice]; if( mc.m_sScreen != "" ) - m_NextScreen = mc.m_sScreen; + m_sNextScreen = mc.m_sScreen; + mc.Apply( GAMESTATE->m_MasterPlayerNumber ); } } CHECKPOINT; // NEXT_SCREEN; - if( m_NextScreen == "" ) - m_NextScreen = NEXT_SCREEN; + if( m_sNextScreen == "" ) + m_sNextScreen = NEXT_SCREEN; /* Did the theme change? */ if( (ChangeMask & OPT_APPLY_THEME) || @@ -549,7 +557,7 @@ void ScreenOptionsMaster::ExportOptions() if( ChangeMask & OPT_RESET_GAME ) { ResetGame(); - m_NextScreen = ""; + m_sNextScreen = ""; } if( ChangeMask & OPT_APPLY_SOUND ) @@ -567,8 +575,8 @@ void ScreenOptionsMaster::GoToNextState() { if( GAMESTATE->m_bEditing ) SCREENMAN->PopTopScreen(); - else if( m_NextScreen != "" ) - SCREENMAN->SetNewScreen( m_NextScreen ); + else if( m_sNextScreen != "" ) + SCREENMAN->SetNewScreen( m_sNextScreen ); } void ScreenOptionsMaster::GoToPrevState() diff --git a/stepmania/src/ScreenOptionsMaster.h b/stepmania/src/ScreenOptionsMaster.h index 35bf3298e3..86906ac601 100644 --- a/stepmania/src/ScreenOptionsMaster.h +++ b/stepmania/src/ScreenOptionsMaster.h @@ -37,7 +37,7 @@ private: const ConfOption *opt; }; - CString m_NextScreen; + CString m_sNextScreen; vector OptionRowHandlers; OptionRowData *m_OptionRowAlloc;