fix ImportOptions/ExportOptions interaction with multiselect
This commit is contained in:
@@ -281,55 +281,85 @@ ScreenOptionsMaster::~ScreenOptionsMaster()
|
|||||||
delete [] m_OptionRowAlloc;
|
delete [] m_OptionRowAlloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScreenOptionsMaster::ImportOption( const OptionRowData &row, const OptionRowHandler &hand, int pn, int rowno )
|
void SelectExactlyOne( int iSelection, vector<bool> &vbSelectedOut )
|
||||||
|
{
|
||||||
|
for( int i=0; i<vbSelectedOut.size(); i++ )
|
||||||
|
vbSelectedOut[i] = i==iSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenOptionsMaster::ImportOption( const OptionRowData &row, const OptionRowHandler &hand, int pn, int rowno, vector<bool> &vbSelectedOut )
|
||||||
{
|
{
|
||||||
/* Figure out which selection is the default. */
|
/* Figure out which selection is the default. */
|
||||||
switch( hand.type )
|
switch( hand.type )
|
||||||
{
|
{
|
||||||
case ROW_LIST:
|
case ROW_LIST:
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
for( unsigned e = 0; e < hand.ListEntries.size(); ++e )
|
|
||||||
{
|
{
|
||||||
const ModeChoice &mc = hand.ListEntries[e];
|
for( unsigned e = 0; e < hand.ListEntries.size(); ++e )
|
||||||
|
|
||||||
if( mc.IsZero() )
|
|
||||||
{
|
{
|
||||||
/* The entry has no effect. This is usually a default "none of the
|
const ModeChoice &mc = hand.ListEntries[e];
|
||||||
* above" entry. It will always return true for DescribesCurrentMode().
|
|
||||||
* It's only the selected choice if nothing else matches. */
|
bool &bSelected = vbSelectedOut[e];
|
||||||
ret = e;
|
bSelected = false;
|
||||||
continue;
|
|
||||||
|
if( mc.IsZero() )
|
||||||
|
{
|
||||||
|
/* 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 )
|
||||||
|
SelectExactlyOne( e, vbSelectedOut );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( row.bOneChoiceForAllPlayers )
|
||||||
|
{
|
||||||
|
if( mc.DescribesCurrentModeForAllPlayers() )
|
||||||
|
{
|
||||||
|
if( !row.bMultiSelect )
|
||||||
|
SelectExactlyOne( e, vbSelectedOut );
|
||||||
|
else
|
||||||
|
bSelected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( mc.DescribesCurrentMode( (PlayerNumber) pn) )
|
||||||
|
{
|
||||||
|
if( !row.bMultiSelect )
|
||||||
|
SelectExactlyOne( e, vbSelectedOut );
|
||||||
|
else
|
||||||
|
bSelected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( row.bOneChoiceForAllPlayers )
|
if( !row.bMultiSelect )
|
||||||
{
|
{
|
||||||
if( mc.DescribesCurrentModeForAllPlayers() )
|
// there should be exactly one option selected
|
||||||
return e;
|
int iNumSelected = 0;
|
||||||
} else {
|
for( unsigned e = 0; e < hand.ListEntries.size(); ++e )
|
||||||
if( mc.DescribesCurrentMode( (PlayerNumber) pn) )
|
if( vbSelectedOut[e] )
|
||||||
return e;
|
iNumSelected++;
|
||||||
|
ASSERT( iNumSelected == 1 );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if( ret == -1 )
|
return;
|
||||||
{
|
|
||||||
LOG->Warn( "%s line %i (\"%s\"): couldn't find default", m_sName.c_str(), rowno, row.name.c_str() );
|
|
||||||
ret = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
case ROW_STEP:
|
case ROW_STEP:
|
||||||
if( GAMESTATE->m_bEditing )
|
if( GAMESTATE->m_bEditing )
|
||||||
return 0;
|
{
|
||||||
|
SelectExactlyOne( 0, vbSelectedOut );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( GAMESTATE->m_pCurCourse ) // playing a course
|
if( GAMESTATE->m_pCurCourse ) // playing a course
|
||||||
{
|
{
|
||||||
if( GAMESTATE->m_bDifficultCourses &&
|
if( GAMESTATE->m_bDifficultCourses &&
|
||||||
GAMESTATE->m_pCurCourse->HasDifficult( GAMESTATE->GetCurrentStyleDef()->m_StepsType ) )
|
GAMESTATE->m_pCurCourse->HasDifficult( GAMESTATE->GetCurrentStyleDef()->m_StepsType ) )
|
||||||
return 1;
|
SelectExactlyOne( 1, vbSelectedOut );
|
||||||
return 0;
|
else
|
||||||
|
SelectExactlyOne( 0, vbSelectedOut );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( GAMESTATE->m_pCurSong ) // playing a song
|
if( GAMESTATE->m_pCurSong ) // playing a song
|
||||||
@@ -340,30 +370,42 @@ int ScreenOptionsMaster::ImportOption( const OptionRowData &row, const OptionRow
|
|||||||
for( unsigned i=0; i<vNotes.size(); i++ )
|
for( unsigned i=0; i<vNotes.size(); i++ )
|
||||||
{
|
{
|
||||||
if( GAMESTATE->m_pCurNotes[pn] == vNotes[i] )
|
if( GAMESTATE->m_pCurNotes[pn] == vNotes[i] )
|
||||||
return i;
|
{
|
||||||
|
SelectExactlyOne( i, vbSelectedOut );
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
SelectExactlyOne( 0, vbSelectedOut );
|
||||||
|
return;
|
||||||
|
|
||||||
case ROW_CHARACTER:
|
case ROW_CHARACTER:
|
||||||
{
|
{
|
||||||
vector<Character*> apCharacters;
|
vector<Character*> apCharacters;
|
||||||
GAMESTATE->GetCharacters( apCharacters );
|
GAMESTATE->GetCharacters( apCharacters );
|
||||||
for( unsigned i=0; i<apCharacters.size(); i++ )
|
for( unsigned i=0; i<apCharacters.size(); i++ )
|
||||||
if( GAMESTATE->m_pCurCharacters[pn] == apCharacters[i] )
|
if( GAMESTATE->m_pCurCharacters[pn] == apCharacters[i] )
|
||||||
return i+1;
|
{
|
||||||
return 0;
|
SelectExactlyOne( i+1, vbSelectedOut );
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
SelectExactlyOne( 0, vbSelectedOut );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case ROW_CONFIG:
|
case ROW_CONFIG:
|
||||||
return hand.opt->Get( row.choices );
|
{
|
||||||
|
int iSelection = hand.opt->Get( row.choices );
|
||||||
|
SelectExactlyOne( iSelection, vbSelectedOut );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case ROW_SAVE_TO_PROFILE:
|
case ROW_SAVE_TO_PROFILE:
|
||||||
return 0;
|
SelectExactlyOne( 0, vbSelectedOut );
|
||||||
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,107 +419,128 @@ void ScreenOptionsMaster::ImportOptions()
|
|||||||
|
|
||||||
if( data.bOneChoiceForAllPlayers )
|
if( data.bOneChoiceForAllPlayers )
|
||||||
{
|
{
|
||||||
int choice = ImportOption( data, hand, 0, i );
|
ImportOption( data, hand, 0, i, row.m_vbSelected[0] );
|
||||||
row.SetOneSharedSelection( choice );
|
|
||||||
ASSERT( row.GetOneSharedSelection() < (int)data.choices.size() );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||||
{
|
{
|
||||||
if( !GAMESTATE->IsHumanPlayer(p) )
|
if( !GAMESTATE->IsHumanPlayer(p) )
|
||||||
continue;
|
continue; // skip
|
||||||
|
ImportOption( data, hand, p, i, row.m_vbSelected[p] );
|
||||||
int choice = ImportOption( data, hand, p, i );
|
|
||||||
row.SetOneSelection( (PlayerNumber)p, choice );
|
|
||||||
ASSERT( row.GetOneSelection((PlayerNumber)p) < (int)data.choices.size() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetOneSelection( const vector<bool> &vbSelected )
|
||||||
|
{
|
||||||
|
for( int i=0; i<vbSelected.size(); i++ )
|
||||||
|
if( vbSelected[i] )
|
||||||
|
return i;
|
||||||
|
ASSERT(0); // shouldn't call this if not expecting one to be selected
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns an OPT mask. */
|
/* Returns an OPT mask. */
|
||||||
int ScreenOptionsMaster::ExportOption( const OptionRowData &row, const OptionRowHandler &hand, int pn, int sel )
|
int ScreenOptionsMaster::ExportOption( const OptionRowData &row, const OptionRowHandler &hand, int pn, const vector<bool> &vbSelected )
|
||||||
{
|
{
|
||||||
/* Figure out which selection is the default. */
|
/* Figure out which selection is the default. */
|
||||||
switch( hand.type )
|
switch( hand.type )
|
||||||
{
|
{
|
||||||
case ROW_LIST:
|
case ROW_LIST:
|
||||||
hand.Default.Apply( (PlayerNumber)pn );
|
{
|
||||||
hand.ListEntries[sel].Apply( (PlayerNumber)pn );
|
hand.Default.Apply( (PlayerNumber)pn );
|
||||||
|
for( int i=0; i<vbSelected.size(); i++ )
|
||||||
|
if( vbSelected[i] )
|
||||||
|
hand.ListEntries[i].Apply( (PlayerNumber)pn );
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ROW_CONFIG:
|
case ROW_CONFIG:
|
||||||
{
|
{
|
||||||
/* Get the original choice. */
|
int sel = GetOneSelection( vbSelected );
|
||||||
int Original = hand.opt->Get( row.choices );
|
|
||||||
|
|
||||||
/* Apply. */
|
/* Get the original choice. */
|
||||||
hand.opt->Put( sel, row.choices );
|
int Original = hand.opt->Get( row.choices );
|
||||||
|
|
||||||
/* Get the new choice. */
|
/* Apply. */
|
||||||
int New = hand.opt->Get( row.choices );
|
hand.opt->Put( sel, row.choices );
|
||||||
|
|
||||||
/* If it didn't change, don't return any side-effects. */
|
/* Get the new choice. */
|
||||||
if( Original == New )
|
int New = hand.opt->Get( row.choices );
|
||||||
return 0;
|
|
||||||
|
|
||||||
return hand.opt->GetEffects();
|
/* If it didn't change, don't return any side-effects. */
|
||||||
}
|
if( Original == New )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return hand.opt->GetEffects();
|
||||||
|
}
|
||||||
|
|
||||||
case ROW_CHARACTER:
|
case ROW_CHARACTER:
|
||||||
if( sel == 0 )
|
|
||||||
GAMESTATE->m_pCurCharacters[pn] = GAMESTATE->GetDefaultCharacter();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
vector<Character*> apCharacters;
|
int sel = GetOneSelection( vbSelected );
|
||||||
GAMESTATE->GetCharacters( apCharacters );
|
|
||||||
ASSERT( sel - 1 < (int)apCharacters.size() );
|
if( sel == 0 )
|
||||||
GAMESTATE->m_pCurCharacters[pn] = apCharacters[sel - 1];
|
GAMESTATE->m_pCurCharacters[pn] = GAMESTATE->GetDefaultCharacter();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vector<Character*> apCharacters;
|
||||||
|
GAMESTATE->GetCharacters( apCharacters );
|
||||||
|
ASSERT( sel - 1 < (int)apCharacters.size() );
|
||||||
|
GAMESTATE->m_pCurCharacters[pn] = apCharacters[sel - 1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ROW_STEP:
|
case ROW_STEP:
|
||||||
if( GAMESTATE->m_bEditing )
|
|
||||||
{
|
{
|
||||||
// do nothing
|
int sel = GetOneSelection( vbSelected );
|
||||||
}
|
|
||||||
else if( GAMESTATE->m_pCurCourse ) // playing a course
|
|
||||||
{
|
|
||||||
if( sel == 1 )
|
|
||||||
{
|
|
||||||
GAMESTATE->m_bDifficultCourses = true;
|
|
||||||
LOG->Trace("ScreenPlayerOptions: Using difficult course");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GAMESTATE->m_bDifficultCourses = false;
|
|
||||||
LOG->Trace("ScreenPlayerOptions: Using normal course");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( GAMESTATE->m_pCurSong ) // playing a song
|
|
||||||
{
|
|
||||||
vector<Steps*> vSteps;
|
|
||||||
GAMESTATE->m_pCurSong->GetSteps( vSteps, GAMESTATE->GetCurrentStyleDef()->m_StepsType );
|
|
||||||
SortNotesArrayByDifficulty( vSteps );
|
|
||||||
Steps* pSteps = vSteps[ sel ];
|
|
||||||
// set current notes
|
|
||||||
GAMESTATE->m_pCurNotes[pn] = pSteps;
|
|
||||||
// set preferred difficulty
|
|
||||||
GAMESTATE->m_PreferredDifficulty[pn] = pSteps->GetDifficulty();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if( GAMESTATE->m_bEditing )
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
else if( GAMESTATE->m_pCurCourse ) // playing a course
|
||||||
|
{
|
||||||
|
if( sel == 1 )
|
||||||
|
{
|
||||||
|
GAMESTATE->m_bDifficultCourses = true;
|
||||||
|
LOG->Trace("ScreenPlayerOptions: Using difficult course");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GAMESTATE->m_bDifficultCourses = false;
|
||||||
|
LOG->Trace("ScreenPlayerOptions: Using normal course");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if( GAMESTATE->m_pCurSong ) // playing a song
|
||||||
|
{
|
||||||
|
vector<Steps*> vSteps;
|
||||||
|
GAMESTATE->m_pCurSong->GetSteps( vSteps, GAMESTATE->GetCurrentStyleDef()->m_StepsType );
|
||||||
|
SortNotesArrayByDifficulty( vSteps );
|
||||||
|
Steps* pSteps = vSteps[ sel ];
|
||||||
|
// set current notes
|
||||||
|
GAMESTATE->m_pCurNotes[pn] = pSteps;
|
||||||
|
// set preferred difficulty
|
||||||
|
GAMESTATE->m_PreferredDifficulty[pn] = pSteps->GetDifficulty();
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ROW_SAVE_TO_PROFILE:
|
case ROW_SAVE_TO_PROFILE:
|
||||||
if( sel == 1 )
|
|
||||||
{
|
{
|
||||||
if( PROFILEMAN->IsUsingProfile((PlayerNumber)pn) )
|
int sel = GetOneSelection( vbSelected );
|
||||||
|
|
||||||
|
if( sel == 1 )
|
||||||
{
|
{
|
||||||
Profile* pProfile = PROFILEMAN->GetProfile((PlayerNumber)pn);
|
if( PROFILEMAN->IsUsingProfile((PlayerNumber)pn) )
|
||||||
pProfile->m_bUsingProfileDefaultModifiers = true;
|
{
|
||||||
pProfile->m_sDefaultModifiers = GAMESTATE->m_PlayerOptions[pn].GetString();
|
Profile* pProfile = PROFILEMAN->GetProfile((PlayerNumber)pn);
|
||||||
|
pProfile->m_bUsingProfileDefaultModifiers = true;
|
||||||
|
pProfile->m_sDefaultModifiers = GAMESTATE->m_PlayerOptions[pn].GetString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -506,7 +569,9 @@ void ScreenOptionsMaster::ExportOptions()
|
|||||||
if( !GAMESTATE->IsHumanPlayer(p) )
|
if( !GAMESTATE->IsHumanPlayer(p) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ChangeMask |= ExportOption( data, hand, p, row.GetOneSelection((PlayerNumber)p) );
|
vector<bool> &vbSelected = row.m_vbSelected[p];
|
||||||
|
|
||||||
|
ChangeMask |= ExportOption( data, hand, p, vbSelected );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -618,7 +683,7 @@ void ScreenOptionsMaster::RefreshIcons()
|
|||||||
|
|
||||||
if( bMultipleSelected )
|
if( bMultipleSelected )
|
||||||
{
|
{
|
||||||
sIcon = "Multiple";
|
sIcon = "Multi";
|
||||||
}
|
}
|
||||||
else if( iFirstSelection != -1 )
|
else if( iFirstSelection != -1 )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ private:
|
|||||||
vector<OptionRowHandler> OptionRowHandlers;
|
vector<OptionRowHandler> OptionRowHandlers;
|
||||||
OptionRowData *m_OptionRowAlloc;
|
OptionRowData *m_OptionRowAlloc;
|
||||||
|
|
||||||
int ExportOption( const OptionRowData &row, const OptionRowHandler &hand, int pn, int sel );
|
int ExportOption( const OptionRowData &row, const OptionRowHandler &hand, int pn, const vector<bool> &vbSelected );
|
||||||
int ImportOption( const OptionRowData &row, const OptionRowHandler &hand, int pn, int rowno );
|
void ImportOption( const OptionRowData &row, const OptionRowHandler &hand, int pn, int rowno, vector<bool> &vbSelectedOut );
|
||||||
void SetList( OptionRowData &row, OptionRowHandler &hand, CString param, CString &TitleOut );
|
void SetList( OptionRowData &row, OptionRowHandler &hand, CString param, CString &TitleOut );
|
||||||
void SetStep( OptionRowData &row, OptionRowHandler &hand );
|
void SetStep( OptionRowData &row, OptionRowHandler &hand );
|
||||||
void SetConf( OptionRowData &row, OptionRowHandler &hand, CString param, CString &TitleOut );
|
void SetConf( OptionRowData &row, OptionRowHandler &hand, CString param, CString &TitleOut );
|
||||||
|
|||||||
Reference in New Issue
Block a user