From 57819b0e80a791b5a4b3b9646541c48ce8d6d846 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sat, 10 Jan 2004 08:57:08 +0000 Subject: [PATCH] more work on multiselect --- stepmania/src/ScreenOptions.cpp | 177 ++++++++++++++++---------- stepmania/src/ScreenOptions.h | 3 + stepmania/src/ScreenOptionsMaster.cpp | 19 +-- 3 files changed, 126 insertions(+), 73 deletions(-) diff --git a/stepmania/src/ScreenOptions.cpp b/stepmania/src/ScreenOptions.cpp index 0b62d856c4..f8b0bfd37f 100644 --- a/stepmania/src/ScreenOptions.cpp +++ b/stepmania/src/ScreenOptions.cpp @@ -134,6 +134,10 @@ void ScreenOptions::Init( InputMode im, OptionRowData OptionRows[], int iNumOpti vbSelected.resize( Row.m_RowDef.choices.size() ); for( int j=0; jm_RowDef.bOneChoiceForAllPlayers ) + // If this isn't a multiSelectRow, exactly one choice should be selected. + if( !Row.m_RowDef.bMultiSelect ) + { + if( Row.m_RowDef.bOneChoiceForAllPlayers ) + { + ASSERT( find( Row.m_vbSelected[0].begin(), Row.m_vbSelected[0].end(), true ) != Row.m_vbSelected[0].end() ); + } + else + { + for( int p=0; pm_vbSelected[0]; + + for( int p=0; pLoadFromFont( THEME->GetPathToF("ScreenOptions item") ); - bt->SetText( optline.choices[iChoiceInRow] ); + bt->SetText( optline.choices[iChoiceWithFocus] ); bt->SetZoom( ITEMS_ZOOM ); bt->EnableShadow( false ); @@ -553,6 +578,10 @@ void ScreenOptions::InitOptionsText() void ScreenOptions::PositionUnderlines() { + // OPTIMIZATION OPPORTUNITY: There's no reason to the underlines for + // all rows when something changes. Just recalulate for the row that + // changed. + // Set the position of the underscores showing the current choice for each option line. for( unsigned r=0; rm_RowDef; - - unsigned item_no = optrow.bOneChoiceForAllPlayers ? 0 : pn; + unsigned item_no = data.bOneChoiceForAllPlayers ? 0 : pn; /* If player_no is 2 and there is no player 1: */ - item_no = min( item_no, m_Rows[iRow]->m_textItems.size()-1 ); + item_no = min( item_no, row.m_textItems.size()-1 ); - m_Rows[iRow]->m_textItems[item_no]->SetText( m_Rows[iRow]->m_RowDef.choices[iChoiceInRow] ); + row.m_textItems[item_no]->SetText( data.choices[iChoiceWithFocus] ); } void ScreenOptions::UpdateEnabledDisabled() @@ -1072,25 +1100,38 @@ void ScreenOptions::MenuStart( PlayerNumber pn, const InputEventType type ) return; if( type == IET_RELEASE ) return; - - switch( m_OptionsNavigation ) + + Row &row = *m_Rows[m_iCurrentRow[pn]]; + OptionRowData &data = row.m_RowDef; + + // Toggle selection if this is a multiselect row. + // Is this the right thing to do for five key navigation? + if( data.bMultiSelect ) { - case NAV_THREE_KEY: - { - bool bAllOnExit = true; - for( int p=0; pIsHumanPlayer(p) && m_Rows[m_iCurrentRow[p]]->Type != Row::ROW_EXIT ) - bAllOnExit = false; - - if( m_Rows[m_iCurrentRow[pn]]->Type != Row::ROW_EXIT ) // not on exit - MenuDown( pn, type ); // can't go down any more - else if( bAllOnExit && type == IET_FIRST_PRESS ) - StartGoToNextState(); + int iChoiceInRow = row.m_iChoiceWithFocus[pn]; + row.m_vbSelected[pn][iChoiceInRow] ^= true; } - case NAV_THREE_KEY_MENU: - case NAV_FIVE_KEY: - if( type == IET_FIRST_PRESS ) // m_SMOptionsNavigation - StartGoToNextState(); + else + { + switch( m_OptionsNavigation ) + { + case NAV_THREE_KEY: + { + bool bAllOnExit = true; + for( int p=0; pIsHumanPlayer(p) && m_Rows[m_iCurrentRow[p]]->Type != Row::ROW_EXIT ) + bAllOnExit = false; + + if( m_Rows[m_iCurrentRow[pn]]->Type != Row::ROW_EXIT ) // not on exit + MenuDown( pn, type ); // can't go down any more + else if( bAllOnExit && type == IET_FIRST_PRESS ) + StartGoToNextState(); + } + case NAV_THREE_KEY_MENU: + case NAV_FIVE_KEY: + if( type == IET_FIRST_PRESS ) // m_SMOptionsNavigation + StartGoToNextState(); + } } } @@ -1125,36 +1166,44 @@ void ScreenOptions::ChangeValue( PlayerNumber pn, int iDelta, bool Repeat ) return; // don't allow a move bool bOneChanged = false; - for( int p=0; p m_vbSelected[NUM_PLAYERS]; // size = m_RowDef.choices.size(). int GetOneSelection( PlayerNumber pn ) @@ -129,6 +131,7 @@ protected: for( int i=0; iType == Row::ROW_EXIT ) continue; // skip - const OptionRowData &row = m_Rows[i]->m_RowDef; + Row &row = *m_Rows[i]; + const OptionRowData &data = row.m_RowDef; - int iSelection = m_Rows[i]->GetOneSelection((PlayerNumber)p); - if( iSelection >= (int)row.choices.size() ) + int iSelection = row.GetOneSelection((PlayerNumber)p); + if( iSelection >= (int)data.choices.size() ) { /* Invalid selection. Send debug output, to aid debugging. */ CString error = ssprintf("Option row with name '%s' selects item %i, but there are only %i items:\n", - row.name.c_str(), - iSelection, (int) row.choices.size() ); + data.name.c_str(), + iSelection, (int) data.choices.size() ); - for( unsigned j = 0; j < row.choices.size(); ++j ) - error += ssprintf(" %s\n", row.choices[j].c_str()); + for( unsigned j = 0; j < data.choices.size(); ++j ) + error += ssprintf(" %s\n", data.choices[j].c_str()); RageException::Throw( "%s", error.c_str() ); } @@ -611,14 +612,14 @@ void ScreenOptionsMaster::RefreshIcons() break; case ROW_STEP: case ROW_CHARACTER: - sIcon = row.choices[iSelection]; + sIcon = data.choices[iSelection]; break; case ROW_CONFIG: break; } /* XXX: hack to not display text in the song options menu */ - if( row.bOneChoiceForAllPlayers ) + if( data.bOneChoiceForAllPlayers ) sIcon = ""; LoadOptionIcon( (PlayerNumber)p, i, sIcon );