row reload fixes
This commit is contained in:
Chris Danford
2005-02-26 11:19:19 +00:00
parent 10ad53d845
commit 0bcaeb0c43
4 changed files with 123 additions and 89 deletions
+54 -47
View File
@@ -23,6 +23,9 @@ static const CString LayoutTypeNames[NUM_LAYOUT_TYPES] = {
XToString( LayoutType ); XToString( LayoutType );
StringToX( LayoutType ); StringToX( LayoutType );
#define FOREACH_OptionsPlayer( pn ) \
for( PlayerNumber pn=GetNextHumanPlayer((PlayerNumber)-1); pn!=PLAYER_INVALID && (!m_RowDef.bOneChoiceForAllPlayers || pn==0); pn=GetNextHumanPlayer(pn) )
const CString NEXT_ROW_NAME = "NextRow"; const CString NEXT_ROW_NAME = "NextRow";
@@ -455,18 +458,15 @@ void OptionRow::UpdateText()
switch( m_RowDef.layoutType ) switch( m_RowDef.layoutType )
{ {
case LAYOUT_SHOW_ONE_IN_ROW: case LAYOUT_SHOW_ONE_IN_ROW:
FOREACH_HumanPlayer( pn ) FOREACH_HumanPlayer( p )
{ {
unsigned pn = m_RowDef.bOneChoiceForAllPlayers ? 0 : p;
int iChoiceWithFocus = m_iChoiceInRowWithFocus[pn]; int iChoiceWithFocus = m_iChoiceInRowWithFocus[pn];
unsigned item_no = m_RowDef.bOneChoiceForAllPlayers ? 0 : pn;
/* If player_no is 2 and there is no player 1: */
item_no = min( item_no, m_textItems.size()-1 );
CString sText = m_RowDef.choices[iChoiceWithFocus]; CString sText = m_RowDef.choices[iChoiceWithFocus];
if( CAPITALIZE_ALL_OPTION_NAMES ) if( CAPITALIZE_ALL_OPTION_NAMES )
sText.MakeUpper(); sText.MakeUpper();
m_textItems[item_no]->SetText( sText ); m_textItems[pn]->SetText( sText );
} }
break; break;
} }
@@ -681,6 +681,23 @@ void OptionRow::Reload()
ImportOptions(); ImportOptions();
switch( m_RowDef.selectType )
{
case SELECT_ONE:
FOREACH_OptionsPlayer( p )
m_iChoiceInRowWithFocus[p] = GetOneSelection(p);
break;
case SELECT_MULTIPLE:
FOREACH_OptionsPlayer( p )
CLAMP( m_iChoiceInRowWithFocus[p], 0, m_RowDef.choices.size()-1 );
break;
default:
ASSERT(0);
}
if( m_RowDef.m_bExportOnChange )
ExportOptions();
UpdateEnabledDisabled(); UpdateEnabledDisabled();
UpdateText(); UpdateText();
PositionUnderlines(); PositionUnderlines();
@@ -720,63 +737,53 @@ static void VerifySelected( SelectType st, const vector<bool> vbSelected )
} }
} }
void OptionRow::ImportOptions() void OptionRow::ImportOptions( PlayerNumber pn )
{ {
if( m_pHand == NULL ) if( m_pHand == NULL )
return; return;
// clear selections
FOREACH_PlayerNumber( p )
FOREACH( bool, m_vbSelected[p], b )
*b = false;
ASSERT( m_RowDef.choices.size() > 0 ); ASSERT( m_RowDef.choices.size() > 0 );
if( m_RowDef.bOneChoiceForAllPlayers ) FOREACH( bool, m_vbSelected[pn], b )
{ *b = false;
ASSERT( m_vbSelected[0].size() == m_RowDef.choices.size() );
ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[0] ); ASSERT( m_vbSelected[pn].size() == m_RowDef.choices.size() );
m_pHand->ImportOption( m_RowDef, PLAYER_1, m_vbSelected[0] ); ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[pn] );
INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[0] ); m_pHand->ImportOption( m_RowDef, pn, m_vbSelected[pn] );
VerifySelected( m_RowDef.selectType, m_vbSelected[0] ); INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[pn] );
} VerifySelected( m_RowDef.selectType, m_vbSelected[pn] );
else
{
FOREACH_HumanPlayer( p )
{
ASSERT( m_vbSelected[p].size() == m_RowDef.choices.size() );
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] );
VerifySelected( m_RowDef.selectType, m_vbSelected[p] );
}
}
} }
int OptionRow::ExportOptions() void OptionRow::ImportOptions()
{
FOREACH_OptionsPlayer( p )
ImportOptions( p );
}
int OptionRow::ExportOptions( PlayerNumber pn )
{ {
if( m_pHand == NULL ) if( m_pHand == NULL )
return 0; return 0;
ASSERT( m_RowDef.choices.size() > 0 );
int iChangeMask = 0; int iChangeMask = 0;
if( m_RowDef.bOneChoiceForAllPlayers ) ASSERT( m_vbSelected[pn].size() == m_RowDef.choices.size() );
{ ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[pn] );
ASSERT( m_vbSelected[0].size() == m_RowDef.choices.size() ); iChangeMask |= m_pHand->ExportOption( m_RowDef, pn, m_vbSelected[pn] );
ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[0] ); INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[pn] );
iChangeMask |= m_pHand->ExportOption( m_RowDef, PLAYER_1, m_vbSelected[0] );
INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[0] ); return iChangeMask;
} }
else
int OptionRow::ExportOptions()
{ {
FOREACH_HumanPlayer( p ) int iChangeMask = 0;
{
ASSERT( m_vbSelected[p].size() == m_RowDef.choices.size() ); FOREACH_OptionsPlayer( p )
ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[p] ); iChangeMask |= ExportOptions( p );
iChangeMask |= m_pHand->ExportOption( m_RowDef, p, m_vbSelected[p] );
INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[p] );
}
}
return iChangeMask; return iChangeMask;
} }
+33 -4
View File
@@ -88,7 +88,9 @@ public:
void LoadExit(); void LoadExit();
void LoadOptionIcon( PlayerNumber pn, const CString &sText ); void LoadOptionIcon( PlayerNumber pn, const CString &sText );
void ImportOptions( PlayerNumber pn );
void ImportOptions(); void ImportOptions();
int ExportOptions( PlayerNumber pn );
int ExportOptions(); int ExportOptions();
void AfterImportOptions( void AfterImportOptions(
@@ -108,10 +110,33 @@ public:
void SetOneSelection( PlayerNumber pn, int iChoice ); void SetOneSelection( PlayerNumber pn, int iChoice );
void SetOneSharedSelection( int iChoice ); void SetOneSharedSelection( int iChoice );
int m_iChoiceInRowWithFocus[NUM_PLAYERS]; // this choice has input focus int GetChoiceInRowWithFocus( PlayerNumber pn ) const
{
// Only one will true at a time if m_RowDef.bMultiSelect if( m_RowDef.bOneChoiceForAllPlayers )
vector<bool> m_vbSelected[NUM_PLAYERS]; // size = m_RowDef.choices.size() pn = PLAYER_1;
int iChoice = m_iChoiceInRowWithFocus[pn];
ASSERT(iChoice<(int)m_RowDef.choices.size());
return iChoice;
}
void SetChoiceInRowWithFocus( PlayerNumber pn, int iChoice )
{
if( m_RowDef.bOneChoiceForAllPlayers )
pn = PLAYER_1;
ASSERT(iChoice<(int)m_RowDef.choices.size());
m_iChoiceInRowWithFocus[pn] = iChoice;
}
bool GetSelected( PlayerNumber pn, int iChoice ) const
{
if( m_RowDef.bOneChoiceForAllPlayers )
pn = PLAYER_1;
return m_vbSelected[pn][iChoice];
}
void SetSelected( PlayerNumber pn, int iChoice, bool b )
{
if( m_RowDef.bOneChoiceForAllPlayers )
pn = PLAYER_1;
m_vbSelected[pn][iChoice] = b;
}
enum RowType enum RowType
{ {
@@ -155,6 +180,10 @@ protected:
bool m_bFirstItemGoesDown; bool m_bFirstItemGoesDown;
bool m_bRowHasFocus[NUM_PLAYERS]; bool m_bRowHasFocus[NUM_PLAYERS];
int m_iChoiceInRowWithFocus[NUM_PLAYERS]; // this choice has input focus
// Only one will true at a time if m_RowDef.bMultiSelect
vector<bool> m_vbSelected[NUM_PLAYERS]; // size = m_RowDef.choices.size()
float m_fY; float m_fY;
bool m_bHidden; // currently off screen bool m_bHidden; // currently off screen
+25 -22
View File
@@ -191,13 +191,15 @@ void ScreenOptions::InitMenu( InputMode im, const vector<OptionRowDefinition> &v
m_framePage.AddChild( &row ); m_framePage.AddChild( &row );
} }
if( SEPARATE_EXIT_ROW )
{
// TRICKY: Add one more item. This will be "EXIT" // TRICKY: Add one more item. This will be "EXIT"
m_Rows.push_back( new OptionRow() ); m_Rows.push_back( new OptionRow() );
OptionRow &row = *m_Rows.back(); OptionRow &row = *m_Rows.back();
row.LoadMetrics( OPTION_ROW_TYPE ); row.LoadMetrics( OPTION_ROW_TYPE );
row.LoadExit(); row.LoadExit();
m_framePage.AddChild( &row ); m_framePage.AddChild( &row );
}
// add explanation here so it appears on top // add explanation here so it appears on top
FOREACH_PlayerNumber( p ) FOREACH_PlayerNumber( p )
@@ -406,7 +408,7 @@ void ScreenOptions::PositionCursors()
OptionsCursor &highlight = m_Highlight[pn]; OptionsCursor &highlight = m_Highlight[pn];
const int iChoiceWithFocus = OptionRow.m_iChoiceInRowWithFocus[pn]; const int iChoiceWithFocus = OptionRow.GetChoiceInRowWithFocus(pn);
int iWidth, iX, iY; int iWidth, iX, iY;
GetWidthXY( pn, iRow, iChoiceWithFocus, iWidth, iX, iY ); GetWidthXY( pn, iRow, iChoiceWithFocus, iWidth, iX, iY );
@@ -422,7 +424,7 @@ void ScreenOptions::TweenCursor( PlayerNumber pn )
ASSERT_M( iRow < (int)m_Rows.size(), ssprintf("%i < %i", iRow, (int)m_Rows.size() ) ); ASSERT_M( iRow < (int)m_Rows.size(), ssprintf("%i < %i", iRow, (int)m_Rows.size() ) );
const OptionRow &row = *m_Rows[iRow]; const OptionRow &row = *m_Rows[iRow];
const int iChoiceWithFocus = row.m_iChoiceInRowWithFocus[pn]; const int iChoiceWithFocus = row.GetChoiceInRowWithFocus(pn);
int iWidth, iX, iY; int iWidth, iX, iY;
GetWidthXY( pn, iRow, iChoiceWithFocus, iWidth, iX, iY ); GetWidthXY( pn, iRow, iChoiceWithFocus, iWidth, iX, iY );
@@ -689,7 +691,8 @@ void ScreenOptions::OnChange( PlayerNumber pn )
TweenCursor( p ); TweenCursor( p );
int iCurrentRow = m_iCurrentRow[pn]; int iCurrentRow = m_iCurrentRow[pn];
const bool ExitSelected = m_Rows[iCurrentRow]->GetRowType() == OptionRow::ROW_EXIT; OptionRow &row = *m_Rows[iCurrentRow];
const bool ExitSelected = row.GetRowType() == OptionRow::ROW_EXIT;
if( p == pn || GAMESTATE->GetNumHumanPlayers() == 1 ) if( p == pn || GAMESTATE->GetNumHumanPlayers() == 1 )
{ {
if( m_bWasOnExit[p] != ExitSelected ) if( m_bWasOnExit[p] != ExitSelected )
@@ -797,7 +800,7 @@ void ScreenOptions::MenuStart( PlayerNumber pn, const InputEventType selectType
if( row.GetFirstItemGoesDown() ) if( row.GetFirstItemGoesDown() )
{ {
int iChoiceInRow = row.m_iChoiceInRowWithFocus[pn]; int iChoiceInRow = row.GetChoiceInRowWithFocus(pn);
if( iChoiceInRow == 0 ) if( iChoiceInRow == 0 )
{ {
MenuDown( pn, selectType ); MenuDown( pn, selectType );
@@ -807,9 +810,10 @@ void ScreenOptions::MenuStart( PlayerNumber pn, const InputEventType selectType
if( row.GetRowDef().selectType == SELECT_MULTIPLE ) if( row.GetRowDef().selectType == SELECT_MULTIPLE )
{ {
int iChoiceInRow = row.m_iChoiceInRowWithFocus[pn]; int iChoiceInRow = row.GetChoiceInRowWithFocus(pn);
row.m_vbSelected[pn][iChoiceInRow] = !row.m_vbSelected[pn][iChoiceInRow]; bool bSelected = !row.GetSelected( pn, iChoiceInRow );
if( row.m_vbSelected[pn][iChoiceInRow] ) row.SetSelected( pn, iChoiceInRow, bSelected );
if( bSelected )
m_SoundToggleOn.Play(); m_SoundToggleOn.Play();
else else
m_SoundToggleOff.Play(); m_SoundToggleOff.Play();
@@ -819,7 +823,7 @@ void ScreenOptions::MenuStart( PlayerNumber pn, const InputEventType selectType
if( row.GetFirstItemGoesDown() ) if( row.GetFirstItemGoesDown() )
{ {
// move to the first choice in the row // move to the first choice in the row
ChangeValueInRow( pn, -row.m_iChoiceInRowWithFocus[pn], selectType != IET_FIRST_PRESS ); ChangeValueInRow( pn, -row.GetChoiceInRowWithFocus(pn), selectType != IET_FIRST_PRESS );
} }
} }
else // data.selectType != SELECT_MULTIPLE else // data.selectType != SELECT_MULTIPLE
@@ -833,14 +837,14 @@ void ScreenOptions::MenuStart( PlayerNumber pn, const InputEventType selectType
case NAV_TOGGLE_FIVE_KEY: case NAV_TOGGLE_FIVE_KEY:
if( row.GetRowDef().selectType != SELECT_MULTIPLE ) if( row.GetRowDef().selectType != SELECT_MULTIPLE )
{ {
int iChoiceInRow = row.m_iChoiceInRowWithFocus[pn]; int iChoiceInRow = row.GetChoiceInRowWithFocus(pn);
if( row.GetRowDef().bOneChoiceForAllPlayers ) if( row.GetRowDef().bOneChoiceForAllPlayers )
row.SetOneSharedSelection( iChoiceInRow ); row.SetOneSharedSelection( iChoiceInRow );
else else
row.SetOneSelection( pn, iChoiceInRow ); row.SetOneSelection( pn, iChoiceInRow );
} }
if( row.GetFirstItemGoesDown() ) if( row.GetFirstItemGoesDown() )
ChangeValueInRow( pn, -row.m_iChoiceInRowWithFocus[pn], selectType != IET_FIRST_PRESS ); // move to the first choice ChangeValueInRow( pn, -row.GetChoiceInRowWithFocus(pn), selectType != IET_FIRST_PRESS ); // move to the first choice
else else
ChangeValueInRow( pn, 0, selectType != IET_FIRST_PRESS ); ChangeValueInRow( pn, 0, selectType != IET_FIRST_PRESS );
break; break;
@@ -867,9 +871,9 @@ void ScreenOptions::StoreFocus( PlayerNumber pn )
return; return;
int iWidth, iY; int iWidth, iY;
GetWidthXY( pn, m_iCurrentRow[pn], m_Rows[m_iCurrentRow[pn]]->m_iChoiceInRowWithFocus[pn], iWidth, m_iFocusX[pn], iY ); GetWidthXY( pn, m_iCurrentRow[pn], row.GetChoiceInRowWithFocus(pn), iWidth, m_iFocusX[pn], iY );
LOG->Trace("cur selection %ix%i @ %i", m_iCurrentRow[pn], m_Rows[m_iCurrentRow[pn]]->m_iChoiceInRowWithFocus[pn], LOG->Trace("cur selection %ix%i @ %i",
m_iFocusX[pn]); m_iCurrentRow[pn], row.GetChoiceInRowWithFocus(pn), m_iFocusX[pn]);
} }
/* Left/right */ /* Left/right */
@@ -899,14 +903,14 @@ void ScreenOptions::ChangeValueInRow( PlayerNumber pn, int iDelta, bool Repeat )
bool bOneChanged = false; bool bOneChanged = false;
int iCurrentChoiceWithFocus = row.m_iChoiceInRowWithFocus[pn]; int iCurrentChoiceWithFocus = row.GetChoiceInRowWithFocus(pn);
int iNewChoiceWithFocus = iCurrentChoiceWithFocus + iDelta; int iNewChoiceWithFocus = iCurrentChoiceWithFocus + iDelta;
wrap( iNewChoiceWithFocus, iNumOptions ); wrap( iNewChoiceWithFocus, iNumOptions );
if( iCurrentChoiceWithFocus != iNewChoiceWithFocus ) if( iCurrentChoiceWithFocus != iNewChoiceWithFocus )
bOneChanged = true; bOneChanged = true;
row.m_iChoiceInRowWithFocus[pn] = iNewChoiceWithFocus; row.SetChoiceInRowWithFocus( pn, iNewChoiceWithFocus );
StoreFocus( pn ); StoreFocus( pn );
if( row.GetRowDef().bOneChoiceForAllPlayers ) if( row.GetRowDef().bOneChoiceForAllPlayers )
@@ -931,7 +935,7 @@ void ScreenOptions::ChangeValueInRow( PlayerNumber pn, int iDelta, bool Repeat )
// lock focus together // lock focus together
FOREACH_HumanPlayer( p ) FOREACH_HumanPlayer( p )
{ {
row.m_iChoiceInRowWithFocus[p] = iNewChoiceWithFocus; row.SetChoiceInRowWithFocus( p, iNewChoiceWithFocus );
StoreFocus( p ); StoreFocus( p );
} }
} }
@@ -988,7 +992,7 @@ void ScreenOptions::MoveRow( PlayerNumber pn, int dir, bool Repeat )
{ {
// If moving from a bFirstChoiceGoesDown row, put focus back on // If moving from a bFirstChoiceGoesDown row, put focus back on
// the first choice before moving. // the first choice before moving.
row.m_iChoiceInRowWithFocus[pn] = 0; row.SetChoiceInRowWithFocus( pn, 0 );
} }
LOG->Trace("move pn %i, dir %i, rep %i", pn, dir, Repeat); LOG->Trace("move pn %i, dir %i, rep %i", pn, dir, Repeat);
@@ -1004,8 +1008,7 @@ void ScreenOptions::MoveRow( PlayerNumber pn, int dir, bool Repeat )
wrap( r, m_Rows.size() ); wrap( r, m_Rows.size() );
int iCurrentRow = m_iCurrentRow[p]; const unsigned iOldSelection = row.GetChoiceInRowWithFocus(p);
const unsigned iOldSelection = m_Rows[iCurrentRow]->m_iChoiceInRowWithFocus[p];
m_iCurrentRow[p] = r; m_iCurrentRow[p] = r;
@@ -1026,10 +1029,10 @@ void ScreenOptions::MoveRow( PlayerNumber pn, int dir, bool Repeat )
if( iSelectionDist == -1 || iDist < iSelectionDist ) if( iSelectionDist == -1 || iDist < iSelectionDist )
{ {
iSelectionDist = iDist; iSelectionDist = iDist;
row.m_iChoiceInRowWithFocus[p] = i; row.SetChoiceInRowWithFocus( p, i );
} }
} }
row.m_iChoiceInRowWithFocus[p] = min( iOldSelection, row.GetTextItemsSize()-1 ); row.SetChoiceInRowWithFocus( p, min( iOldSelection, row.GetTextItemsSize()-1 ) );
} }
} }
+2 -7
View File
@@ -136,13 +136,8 @@ void ScreenOptionsMaster::ImportOptionsForPlayer( PlayerNumber pn )
for( unsigned i = 0; i < OptionRowHandlers.size(); ++i ) for( unsigned i = 0; i < OptionRowHandlers.size(); ++i )
{ {
const OptionRowHandler *pHand = OptionRowHandlers[i];
const OptionRowDefinition &def = m_OptionRowAlloc[i];
OptionRow &row = *m_Rows[i]; OptionRow &row = *m_Rows[i];
row.ImportOptions( pn );
if( def.bOneChoiceForAllPlayers )
continue;
pHand->ImportOption( def, pn, row.m_vbSelected[pn] );
} }
} }
@@ -244,7 +239,7 @@ void ScreenOptionsMaster::HandleScreenMessage( const ScreenMessage SM )
OptionRowHandler *pHand = OptionRowHandlers[r]; OptionRowHandler *pHand = OptionRowHandlers[r];
const int iChoice = row.m_iChoiceInRowWithFocus[GAMESTATE->m_MasterPlayerNumber]; const int iChoice = row.GetChoiceInRowWithFocus(GAMESTATE->m_MasterPlayerNumber);
CString sScreen = pHand->GetAndEraseScreen( iChoice ); CString sScreen = pHand->GetAndEraseScreen( iChoice );
if( !sScreen.empty() ) if( !sScreen.empty() )
m_sNextScreen = sScreen; m_sNextScreen = sScreen;