From 5c7b8314f40f2033b739d73959f7820ce5705d03 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sun, 20 Feb 2005 10:12:50 +0000 Subject: [PATCH] allow hiding of option rows based on the value of other rows --- stepmania/Themes/default/metrics.ini | 69 +++++---- stepmania/src/ActorFrame.cpp | 5 + stepmania/src/ActorFrame.h | 1 + stepmania/src/GameState.cpp | 8 +- stepmania/src/OptionRow.cpp | 109 +++++++++---- stepmania/src/OptionRow.h | 51 ++++-- stepmania/src/PlayerNumber.cpp | 1 + stepmania/src/ProfileManager.cpp | 2 +- stepmania/src/ScreenOptions.cpp | 135 ++++++++++++---- stepmania/src/ScreenOptions.h | 14 +- stepmania/src/ScreenOptionsMaster.cpp | 213 +++++++++++++++++++------- stepmania/src/ScreenOptionsMaster.h | 58 ++++--- 12 files changed, 475 insertions(+), 191 deletions(-) diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index 8a3239a721..34c050b12a 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -2466,8 +2466,9 @@ PageOnCommand= LineHighlightOnCommand= LineHighlightChangeCommand= LineHighlightChangeToExitCommand= -ColorSelected=1,1,1,1 // normal -ColorNotSelected=0.5,0.5,0.5,1 // grayed +ColorSelected=1,1,1,1 +ColorNotSelected=0.5,0.5,0.5,1 +ColorDisabled=1,1,1,0 ShowScrollBar=0 ScrollBarHeight=0 ScrollBarTime=0 @@ -3752,16 +3753,16 @@ ScoreDisplay,2=mod,subtractscore;name,Subtract ScoreDisplay,3=mod,averagescore;name,Average # Song options -LifeType=2,together +LifeType=2;together LifeTypeDefault= LifeType,1=mod,bar;name,Bar LifeType,2=mod,battery;name,Battery -BarDrain=3,together +BarDrain=3;together BarDrainDefault= BarDrain,1=mod,normal-drain;name,Normal BarDrain,2=mod,norecover;name,NoRecover BarDrain,3=mod,suddendeath;name,SuddenDeath -BatLives=10,together +BatLives=10;together BatLivesDefault= BatLives,1=mod,1 life;name,1 BatLives,2=mod,2 lives;name,2 @@ -3773,16 +3774,16 @@ BatLives,7=mod,7 lives;name,7 BatLives,8=mod,8 lives;name,8 BatLives,9=mod,9 lives;name,9 BatLives,10=mod,10 lives;name,10 -Fail=3,together +Fail=3;together FailDefault= Fail,1=mod,failImmediate;name,Immediate Fail,2=mod,failendofsong;name,EndOfSong Fail,3=mod,failoff;name,Off -AssistTick=2,together +AssistTick=2;together AssistTickDefault= AssistTick,1=mod,no assisttick;name,Off AssistTick,2=mod,assisttick;name,On -Rate=18,together +Rate=18;together RateDefault= Rate,1=mod,0.3xmusic;name,0.3x Rate,2=mod,0.4xmusic;name,0.4x @@ -3802,86 +3803,86 @@ Rate,15=mod,1.7xmusic;name,1.7x Rate,16=mod,1.8xmusic;name,1.8x Rate,17=mod,1.9xmusic;name,1.9x Rate,18=mod,2.0xmusic;name,2.0x -AutoAdjust=2,together +AutoAdjust=2;together AutoAdjustDefault= AutoAdjust,1=mod,no autosync;name,Off AutoAdjust,2=mod,autosync;name,On -SaveScores=2,together +SaveScores=2;together SaveScoresDefault= SaveScores,1=mod,no savescore;name,Off SaveScores,2=mod,savescore;name,On # ScreenOptionsMenu -Appearance Options=1,together,SelectNone +Appearance Options=1;together;SelectNone Appearance OptionsDefault= Appearance Options,1=screen,ScreenAppearanceOptions;name,AppearanceOptions -Other Options=1,together,SelectNone +Other Options=1;together;SelectNone Other OptionsDefault= Other Options,1=screen,ScreenOtherOptions;name,OtherOptions -Background Options=1,together,SelectNone +Background Options=1;together;SelectNone Background OptionsDefault= Background Options,1=screen,ScreenBackgroundOptions;name,BackgroundOptions -Bookkeeping=1,together,SelectNone +Bookkeeping=1;together;SelectNone BookkeepingDefault= Bookkeeping,1=screen,ScreenBookkeeping;name,Bookkeeping -Clear Bookkeeping Data=1,together,SelectNone +Clear Bookkeeping Data=1;together;SelectNone Clear Bookkeeping DataDefault= Clear Bookkeeping Data,1=ClearBookkeepingData;name,ClearBookkeepingData -Center Image=1,together,SelectNone +Center Image=1;together;SelectNone Center ImageDefault= Center Image,1=screen,ScreenCenterImage;name,CenterImage -Coin Options=1,together,SelectNone +Coin Options=1;together;SelectNone Coin OptionsDefault= Coin Options,1=screen,ScreenCoinOptions;name,CoinOptions -Config Key/Joy Mappings=1,together,SelectNone +Config Key/Joy Mappings=1;together;SelectNone Config Key/Joy MappingsDefault= Config Key/Joy Mappings,1=screen,ScreenMapControllers;name,KeyJoyMappings -Clear Machine Stats=1,together,SelectNone +Clear Machine Stats=1;together;SelectNone Clear Machine StatsDefault= Clear Machine Stats,1=ClearMachineStats;name,ClearMachineStats;screen,ScreenOptionsMenu -Input Options=1,together,SelectNone +Input Options=1;together;SelectNone Input OptionsDefault= Input Options,1=screen,ScreenInputOptions;name,InputOptions -Insert Credit=1,together,SelectNone +Insert Credit=1;together;SelectNone Insert CreditDefault= Insert Credit,1=InsertCredit;name,InsertCredit;screen,ScreenOptionsMenu -Gameplay Options=1,together,SelectNone +Gameplay Options=1;together;SelectNone Gameplay OptionsDefault= Gameplay Options,1=screen,ScreenGameplayOptions;name,GameplayOptions -Graphic Options=1,together,SelectNone +Graphic Options=1;together;SelectNone Graphic OptionsDefault= Graphic Options,1=screen,ScreenGraphicOptions;name,GraphicOptions -Machine Options=1,together,SelectNone +Machine Options=1;together;SelectNone Machine OptionsDefault= Machine Options,1=screen,ScreenMachineOptions;name,MachineOptions -Sound Options=1,together,SelectNone +Sound Options=1;together;SelectNone Sound OptionsDefault= Sound Options,1=screen,ScreenSoundOptions;name,SoundOptions -Profile Options=1,together,SelectNone +Profile Options=1;together;SelectNone Profile OptionsDefault= Profile Options,1=screen,ScreenProfileOptions;name,ProfileOptions -Reload Songs/Courses=1,together,SelectNone +Reload Songs/Courses=1;together;SelectNone Reload Songs/CoursesDefault= Reload Songs/Courses,1=screen,ScreenReloadSongs;name,ReloadSongs -Reset To Defaults=1,together,SelectNone +Reset To Defaults=1;together;SelectNone Reset To DefaultsDefault= Reset To Defaults,1=ResetToFactoryDefaults;name,ResetToDefaults;screen,ScreenOptionsMenu -Test Input=1,together,SelectNone +Test Input=1;together;SelectNone Test InputDefault= Test Input,1=screen,ScreenTestInput;name,TestInput -Test Lights=1,together,SelectNone +Test Lights=1;together;SelectNone Test LightsDefault= Test Lights,1=screen,ScreenTestLights;name,TestLights -Transfer Stats From Machine=1,together,SelectNone +Transfer Stats From Machine=1;together;SelectNone Transfer Stats From MachineDefault= Transfer Stats From Machine,1=TransferStatsFromMachine;name,TransferStatsFromMachine;screen,ScreenOptionsMenu -Transfer Stats To Machine=1,together,SelectNone +Transfer Stats To Machine=1;together;SelectNone Transfer Stats To MachineDefault= Transfer Stats To Machine,1=TransferStatsToMachine;name,TransferStatsToMachine;screen,ScreenOptionsMenu -Set Machine Time=1,together,SelectNone +Set Machine Time=1;together;SelectNone Set Machine TimeDefault= Set Machine Time,1=screen,ScreenSetTime;name,SetMachineTime -Network Options=1,together,SelectNone +Network Options=1;together;SelectNone Network OptionsDefault= Network Options,1=screen,ScreenNetworkOptions;name,NetworkOptions diff --git a/stepmania/src/ActorFrame.cpp b/stepmania/src/ActorFrame.cpp index e4acb45b97..5336a63edc 100644 --- a/stepmania/src/ActorFrame.cpp +++ b/stepmania/src/ActorFrame.cpp @@ -64,6 +64,11 @@ void ActorFrame::RemoveChild( Actor* pActor ) m_SubActors.erase( iter ); } +void ActorFrame::RemoveAllChildren() +{ + m_SubActors.clear(); +} + void ActorFrame::MoveToTail( Actor* pActor ) { vector::iterator iter = find( m_SubActors.begin(), m_SubActors.end(), pActor ); diff --git a/stepmania/src/ActorFrame.h b/stepmania/src/ActorFrame.h index 2b68038692..f4894453cc 100644 --- a/stepmania/src/ActorFrame.h +++ b/stepmania/src/ActorFrame.h @@ -30,6 +30,7 @@ public: virtual void AddChild( Actor* pActor ); virtual void RemoveChild( Actor* pActor ); + void RemoveAllChildren(); void MoveToTail( Actor* pActor ); void MoveToHead( Actor* pActor ); void SortByDrawOrder(); diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index 9daf0abed6..4fa617759b 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -1848,9 +1848,10 @@ class LunaGameState : public Luna public: LunaGameState() { LUA->Register( Register ); } - static int IsPlayerEnabled( T* p, lua_State *L ) { lua_pushboolean(L, p->IsPlayerEnabled((PlayerNumber)(IArg(1)-1)) ); return 1; } - static int IsHumanPlayer( T* p, lua_State *L ) { lua_pushboolean(L, p->IsHumanPlayer((PlayerNumber)(IArg(1)-1)) ); return 1; } - static int GetPlayerDisplayName( T* p, lua_State *L ) { lua_pushstring(L, p->GetPlayerDisplayName((PlayerNumber)(IArg(1)-1)) ); return 1; } + static int IsPlayerEnabled( T* p, lua_State *L ) { lua_pushboolean(L, p->IsPlayerEnabled((PlayerNumber)(IArg(1))) ); return 1; } + static int IsHumanPlayer( T* p, lua_State *L ) { lua_pushboolean(L, p->IsHumanPlayer((PlayerNumber)(IArg(1))) ); return 1; } + static int GetPlayerDisplayName( T* p, lua_State *L ) { lua_pushstring(L, p->GetPlayerDisplayName((PlayerNumber)(IArg(1))) ); return 1; } + static int GetMasterPlayerNumber( T* p, lua_State *L ) { lua_pushnumber(L, p->m_MasterPlayerNumber ); return 1; } static int ApplyGameCommand( T* p, lua_State *L ) { PlayerNumber pn = PLAYER_INVALID; @@ -1865,6 +1866,7 @@ public: ADD_METHOD( IsPlayerEnabled ) ADD_METHOD( IsHumanPlayer ) ADD_METHOD( GetPlayerDisplayName ) + ADD_METHOD( GetMasterPlayerNumber ) ADD_METHOD( ApplyGameCommand ) Luna::Register( L ); diff --git a/stepmania/src/OptionRow.cpp b/stepmania/src/OptionRow.cpp index b644d817c0..0188550121 100644 --- a/stepmania/src/OptionRow.cpp +++ b/stepmania/src/OptionRow.cpp @@ -30,11 +30,16 @@ OptionRow::OptionRow() OptionRow::~OptionRow() { + ActorFrame::RemoveAllChildren(); for( unsigned i = 0; i < m_textItems.size(); ++i ) SAFE_DELETE( m_textItems[i] ); + m_textItems.clear(); FOREACH_PlayerNumber( p ) + { for( unsigned i = 0; i < m_Underline[p].size(); ++i ) SAFE_DELETE( m_Underline[p][i] ); + m_Underline[p].clear(); + } } @@ -341,57 +346,101 @@ void OptionRow::PositionIcons( const ThemeMetric1D &fIconX, float fTweenS void OptionRow::UpdateText( bool bCapitalizeAllOptionNames ) { - if( m_RowDef.layoutType != LAYOUT_SHOW_ONE_IN_ROW ) - return; - - FOREACH_HumanPlayer( pn ) + switch( m_RowDef.layoutType ) { - int iChoiceWithFocus = m_iChoiceInRowWithFocus[pn]; - unsigned item_no = m_RowDef.bOneChoiceForAllPlayers ? 0 : pn; + case LAYOUT_SHOW_ONE_IN_ROW: + FOREACH_HumanPlayer( 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 ); + /* 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]; - if( bCapitalizeAllOptionNames ) - sText.MakeUpper(); - m_textItems[item_no]->SetText( sText ); + CString sText = m_RowDef.choices[iChoiceWithFocus]; + if( bCapitalizeAllOptionNames ) + sText.MakeUpper(); + m_textItems[item_no]->SetText( sText ); + } + break; } } void OptionRow::UpdateEnabledDisabled( - bool bThisRowIsSelected, - bool bThisRowIsSelectedByAll, - const RageColor &colorSelected, - const RageColor &colorNotSelected, + bool bThisRowHasFocus[NUM_PLAYERS], + const RageColor &colorFocus, + const RageColor &colorNoFocus, + const RageColor &colorDisabled, float fTweenSeconds ) { + bool bThisRowHasFocusByAny = false; + FOREACH_HumanPlayer( p ) + bThisRowHasFocusByAny |= bThisRowHasFocus[p]; + + bool bThisRowHasFocusByAll = true; + FOREACH_HumanPlayer( p ) + bThisRowHasFocusByAll &= bThisRowHasFocus[p]; + const float DiffuseAlpha = m_bHidden? 0.0f:1.0f; /* Don't tween selection colors at all. */ - const RageColor color = bThisRowIsSelected? colorSelected:colorNotSelected; + RageColor color = bThisRowHasFocusByAny ? colorFocus:colorNoFocus; m_sprBullet.SetGlobalDiffuseColor( color ); m_textTitle.SetGlobalDiffuseColor( color ); - for( unsigned j=0; jSetGlobalDiffuseColor( color ); - - for( unsigned j=0; jGetDestY() == m_fY && - m_textItems[j]->DestTweenState().diffuse[0][3] == DiffuseAlpha ) - continue; + case LAYOUT_SHOW_ALL_IN_ROW: + for( unsigned j=0; jSetGlobalDiffuseColor( color ); + for( unsigned j=0; jGetDestY() == m_fY && + m_textItems[j]->DestTweenState().diffuse[0][3] == DiffuseAlpha ) + continue; - m_textItems[j]->StopTweening(); - m_textItems[j]->BeginTweening( fTweenSeconds ); - m_textItems[j]->SetDiffuseAlpha( DiffuseAlpha ); - m_textItems[j]->SetY( m_fY ); + m_textItems[j]->StopTweening(); + m_textItems[j]->BeginTweening( fTweenSeconds ); + m_textItems[j]->SetDiffuseAlpha( DiffuseAlpha ); + m_textItems[j]->SetY( m_fY ); + } + break; + case LAYOUT_SHOW_ONE_IN_ROW: + FOREACH_HumanPlayer( pn ) + { + bool bEnabled = m_RowDef.m_vEnabledForPlayers.find(pn) != m_RowDef.m_vEnabledForPlayers.end(); + + if( bThisRowHasFocus[pn] ) + color = colorFocus; + else if( bEnabled ) + color = colorNoFocus; + else + color = colorDisabled; + + 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 ); + + BitmapText &bt = *m_textItems[item_no]; + + if( bt.GetDestY() != m_fY || bt.DestTweenState().diffuse[0] != color ) + { + bt.StopTweening(); + bt.BeginTweening( fTweenSeconds ); + bt.SetDiffuse( color ); + bt.SetY( m_fY ); + } + } + break; + default: + ASSERT(0); } if( m_RowType == OptionRow::ROW_EXIT ) { - if( bThisRowIsSelectedByAll ) - m_textItems[0]->SetEffectDiffuseShift( 1.0f, colorSelected, colorNotSelected ); + if( bThisRowHasFocusByAll ) + m_textItems[0]->SetEffectDiffuseShift( 1.0f, colorFocus, colorNoFocus ); else m_textItems[0]->SetEffectNone(); } diff --git a/stepmania/src/OptionRow.h b/stepmania/src/OptionRow.h index 9f4d29a9fc..4462f40ae3 100644 --- a/stepmania/src/OptionRow.h +++ b/stepmania/src/OptionRow.h @@ -36,11 +36,34 @@ struct OptionRowDefinition { CString name; bool bOneChoiceForAllPlayers; - enum SelectType selectType; - enum LayoutType layoutType; + SelectType selectType; + LayoutType layoutType; vector choices; + set m_vEnabledForPlayers; // only players in this set may change focus to this row - OptionRowDefinition(): name(""), bOneChoiceForAllPlayers(false), selectType(SELECT_ONE), layoutType(LAYOUT_SHOW_ALL_IN_ROW) { } + void UpdateEnabledForPlayers( + set vEnabledForPlayers, + bool bThisRowIsSelected, + bool bThisRowIsSelectedByAll, + const RageColor &colorSelected, + const RageColor &colorNotSelected, + const RageColor &colorDisabled, + float fTweenSeconds + ); + bool EnabledForPlayer( PlayerNumber pn ) { return m_vEnabledForPlayers.find(pn) != m_vEnabledForPlayers.end(); } + + OptionRowDefinition() { Init(); } + void Init() + { + name = ""; + bOneChoiceForAllPlayers = false; + selectType = SELECT_ONE; + layoutType = LAYOUT_SHOW_ALL_IN_ROW; + choices.clear(); + m_vEnabledForPlayers.clear(); + FOREACH_PlayerNumber( pn ) + m_vEnabledForPlayers.insert( pn ); + } OptionRowDefinition( 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), selectType(SELECT_ONE), layoutType(LAYOUT_SHOW_ALL_IN_ROW) @@ -89,10 +112,10 @@ public: void PositionIcons( const ThemeMetric1D &fIconX, float fTweenSeconds ); void UpdateText( bool bCapitalizeAllOptionNames ); void UpdateEnabledDisabled( - bool bThisRowIsSelected, - bool bThisRowIsSelectedByAll, - const RageColor &colorSelected, - const RageColor &colorNotSelected, + bool bThisRowHasFocus[NUM_PLAYERS], + const RageColor &colorFocus, + const RageColor &colorNoFocus, + const RageColor &colorDisabled, float fTweenSeconds ); int GetOneSelection( PlayerNumber pn, bool bAllowFail=false ) const; @@ -105,16 +128,22 @@ public: // Only one will true at a time if m_RowDef.bMultiSelect vector m_vbSelected[NUM_PLAYERS]; // size = m_RowDef.choices.size() - enum RowType { ROW_NORMAL, ROW_EXIT }; + enum RowType + { + ROW_NORMAL, + ROW_EXIT + }; RowType GetRowType() const { return m_RowType; } const OptionRowDefinition &GetRowDef() const { return m_RowDef; } + OptionRowDefinition &GetRowDef() { return m_RowDef; } BitmapText &GetTextItemForRow( PlayerNumber pn, int iChoiceOnRow ); void GetWidthXY( PlayerNumber pn, int iChoiceOnRow, int &iWidthOut, int &iXOut, int &iYOut ); - void SetRowY( float fRowY ) { m_fY = fRowY; } - void SetRowHidden( bool bRowHidden ) { m_bHidden = bRowHidden; } - bool GetRowHidden() { return m_bHidden; } + void SetRowY( float fRowY ) { m_fY = fRowY; } + float GetRowY() { return m_fY; } + void SetRowHidden( bool bRowHidden ) { m_bHidden = bRowHidden; } + bool GetRowHidden() { return m_bHidden; } unsigned GetTextItemsSize() { return m_textItems.size(); } void SetExitText( CString sExitText ); diff --git a/stepmania/src/PlayerNumber.cpp b/stepmania/src/PlayerNumber.cpp index 54c34d728b..c4c527ed65 100644 --- a/stepmania/src/PlayerNumber.cpp +++ b/stepmania/src/PlayerNumber.cpp @@ -50,6 +50,7 @@ void LuaPlayerNumber(lua_State* L) { FOREACH_PlayerNumber( pn ) LUA->SetGlobal( ssprintf("PLAYER_%d",pn+1), pn ); + LUA->SetGlobal( "NUM_PLAYERS", NUM_PLAYERS ); } REGISTER_WITH_LUA_FUNCTION( LuaPlayerNumber ); diff --git a/stepmania/src/ProfileManager.cpp b/stepmania/src/ProfileManager.cpp index 59ce820329..a973ae04e3 100644 --- a/stepmania/src/ProfileManager.cpp +++ b/stepmania/src/ProfileManager.cpp @@ -541,7 +541,7 @@ public: LunaProfileManager() { LUA->Register( Register ); } static int IsUsingProfile( T* p, lua_State *L ) { lua_pushboolean(L, p->IsUsingProfile((PlayerNumber)IArg(1)) ); return 1; } - static int GetProfile( T* p, lua_State *L ) { Profile* pP = p->GetProfile((PlayerNumber)IArg(1)); ASSERT(pP); pP->PushSelf(L); return 1; } + static int GetProfile( T* p, lua_State *L ) { PlayerNumber pn = (PlayerNumber)IArg(1); Profile* pP = p->GetProfile(pn); ASSERT(pP); pP->PushSelf(L); return 1; } static int GetMachineProfile( T* p, lua_State *L ) { p->GetMachineProfile()->PushSelf(L); return 1; } static void Register(lua_State *L) diff --git a/stepmania/src/ScreenOptions.cpp b/stepmania/src/ScreenOptions.cpp index df2f13f044..d0c322e581 100644 --- a/stepmania/src/ScreenOptions.cpp +++ b/stepmania/src/ScreenOptions.cpp @@ -104,6 +104,7 @@ ScreenOptions::ScreenOptions( CString sClassName ) : ScreenWithMenuElements(sCla EXPLANATION_ZOOM (m_sName,"ExplanationZoom"), COLOR_SELECTED (m_sName,"ColorSelected"), COLOR_NOT_SELECTED (m_sName,"ColorNotSelected"), + COLOR_DISABLED (m_sName,"ColorDisabled"), SHOW_BPM_IN_SPEED_TITLE (m_sName,"ShowBpmInSpeedTitle"), FRAME_ON_COMMAND (m_sName,"FrameOnCommand"), FRAME_OFF_COMMAND (m_sName,"FrameOffCommand"), @@ -191,11 +192,6 @@ void ScreenOptions::InitMenu( InputMode im, OptionRowDefinition defs[], int iNum fY, LABELS_ON_COMMAND ); - - - - - // // HACK: Set focus to one item in the row, which is "go down" @@ -503,32 +499,26 @@ void ScreenOptions::UpdateText( int iRow ) row.UpdateText( CAPITALIZE_ALL_OPTION_NAMES ); } +void ScreenOptions::UpdateEnabledDisabled( int r ) +{ + OptionRow &row = *m_Rows[r]; + + bool bRowHasFocus[NUM_PLAYERS]; + FOREACH_PlayerNumber( pn ) + bRowHasFocus[pn] = GAMESTATE->IsHumanPlayer(pn) && m_iCurrentRow[pn] == (int)r; + + row.UpdateEnabledDisabled( + bRowHasFocus, + COLOR_SELECTED, + COLOR_NOT_SELECTED, + COLOR_DISABLED, + TWEEN_SECONDS ); +} + void ScreenOptions::UpdateEnabledDisabled() { - const RageColor colorSelected = COLOR_SELECTED, colorNotSelected = COLOR_NOT_SELECTED; - - // init text - for( unsigned i=0; iIsHumanPlayer(p) && m_iCurrentRow[p] == (int) i ) - bThisRowIsSelected = true; - - bool bThisRowIsSelectedByAll = true; - FOREACH_PlayerNumber( p ) - if( GAMESTATE->IsHumanPlayer(p) && m_iCurrentRow[p] != (int) i ) - bThisRowIsSelectedByAll = false; - - row.UpdateEnabledDisabled( - bThisRowIsSelected, - bThisRowIsSelectedByAll, - colorSelected, - colorNotSelected, - TWEEN_SECONDS ); - } + for( unsigned r=0; r=0; r-- ) + { + OptionRow &row = *m_Rows[r]; + if( row.GetRowDef().EnabledForPlayer(pn) ) + { + bFoundDest = true; + break; + } + } + int iDelta = bFoundDest ? r-m_iCurrentRow[pn] : -1; + MoveRow( pn, iDelta, type != IET_FIRST_PRESS ); +} + +void ScreenOptions::MenuDown( PlayerNumber pn, const InputEventType type ) +{ + int r; + bool bFoundDest = false; + for( r=m_iCurrentRow[pn]+1; rLoadFont( THEME->GetPathF(m_sName,"item") ); + + OptionRow &row = *m_Rows[r]; + OptionRow::RowType rt = row.GetRowType(); + row.Clear(); + switch( rt ) + { + case OptionRow::ROW_NORMAL: + row.LoadNormal( def ); + row.AfterImportOptions( + pFont, + ITEMS_START_X, + ITEMS_GAP_X, + ITEMS_END_X, + ITEMS_LONG_ROW_SHARED_X, + ITEMS_LONG_ROW_X, + ITEMS_ZOOM, + CAPITALIZE_ALL_OPTION_NAMES, + THEME->GetPathF(m_sName,"item"), + THEME->GetPathF(m_sName,"title"), + GetExplanationTitle( r ), + THEME->GetPathG(m_sName,"bullet"), + LABELS_X, + ARROWS_X, + row.GetRowY(), + LABELS_ON_COMMAND + ); + + break; + case OptionRow::ROW_EXIT: + // nothing to do + break; + default: + ASSERT(0); + } + + FONT->UnloadFont( pFont ); + pFont = NULL; + */ +} + /* * (c) 2001-2004 Chris Danford, Glenn Maynard * All rights reserved. diff --git a/stepmania/src/ScreenOptions.h b/stepmania/src/ScreenOptions.h index 476c86a2e8..06c3f58abb 100644 --- a/stepmania/src/ScreenOptions.h +++ b/stepmania/src/ScreenOptions.h @@ -45,7 +45,9 @@ protected: void TweenCursor( PlayerNumber pn ); void UpdateText( int row ); void UpdateEnabledDisabled(); + void UpdateEnabledDisabled( int row ); virtual void OnChange( PlayerNumber pn ); + void RefreshRowChoices( int row, const OptionRowDefinition &def ); virtual void MenuBack( PlayerNumber pn ); virtual void MenuStart( PlayerNumber pn, const InputEventType type ); @@ -55,13 +57,14 @@ protected: virtual void GoToNextScreen() = 0; virtual void GoToPrevScreen() = 0; - void MenuLeft( PlayerNumber pn, const InputEventType type ) { ChangeValueInRow(pn,-1,type != IET_FIRST_PRESS); } - void MenuRight( PlayerNumber pn, const InputEventType type ) { ChangeValueInRow(pn,+1,type != IET_FIRST_PRESS); } - void ChangeValueInRow( PlayerNumber pn, int iDelta, bool Repeat ); - void MenuUp( PlayerNumber pn, const InputEventType type ) { MoveRow( pn, -1, type != IET_FIRST_PRESS ); } - void MenuDown( PlayerNumber pn, const InputEventType type ) { MoveRow( pn, +1, type != IET_FIRST_PRESS ); } + virtual void ChangeValueInRow( PlayerNumber pn, int iDelta, bool Repeat ); void MoveRow( PlayerNumber pn, int dir, bool Repeat ); + void MenuLeft( PlayerNumber pn, const InputEventType type ) { ChangeValueInRow(pn,-1,type != IET_FIRST_PRESS); } + void MenuRight( PlayerNumber pn, const InputEventType type ) { ChangeValueInRow(pn,+1,type != IET_FIRST_PRESS); } + void MenuUp( PlayerNumber pn, const InputEventType type ); + void MenuDown( PlayerNumber pn, const InputEventType type ); + /* Returns -1 if on a row with no OptionRowDefinition (eg. EXIT). */ int GetCurrentRow(PlayerNumber pn = PLAYER_1) const; bool AllAreOnExit() const; @@ -140,6 +143,7 @@ protected: ThemeMetric EXPLANATION_ZOOM; ThemeMetric COLOR_SELECTED; ThemeMetric COLOR_NOT_SELECTED; + ThemeMetric COLOR_DISABLED; ThemeMetric SHOW_BPM_IN_SPEED_TITLE; ThemeMetric FRAME_ON_COMMAND; ThemeMetric FRAME_OFF_COMMAND; diff --git a/stepmania/src/ScreenOptionsMaster.cpp b/stepmania/src/ScreenOptionsMaster.cpp index edec5cebc8..ea3d0f03c3 100644 --- a/stepmania/src/ScreenOptionsMaster.cpp +++ b/stepmania/src/ScreenOptionsMaster.cpp @@ -25,23 +25,29 @@ #include "GameManager.h" #include "Foreach.h" -#define LINE_NAMES THEME->GetMetric (m_sName,"LineNames") -#define OPTION_MENU_FLAGS THEME->GetMetric (m_sName,"OptionMenuFlags") -#define LINE(sLineName) THEME->GetMetric (m_sName,ssprintf("Line%s",sLineName.c_str())) +#define LINE_NAMES THEME->GetMetric (m_sName,"LineNames") +#define OPTION_MENU_FLAGS THEME->GetMetric (m_sName,"OptionMenuFlags") +#define LINE(sLineName) THEME->GetMetric (m_sName,ssprintf("Line%s",sLineName.c_str())) -#define ENTRY(s) THEME->GetMetric ("ScreenOptionsMaster",s) -#define ENTRY_NAME(s) THEME->GetMetric ("OptionNames", s) -#define ENTRY_MODE(s,i) THEME->GetMetric ("ScreenOptionsMaster",ssprintf("%s,%i",(s).c_str(),(i+1))) -#define ENTRY_DEFAULT(s) THEME->GetMetric ("ScreenOptionsMaster",(s) + "Default") -#define NEXT_SCREEN THEME->GetMetric (m_sName,"NextScreen") -#define PREV_SCREEN THEME->GetMetric (m_sName,"PrevScreen") +#define ENTRY(s) THEME->GetMetric ("ScreenOptionsMaster",s) +#define ENTRY_NAME(s) THEME->GetMetric ("OptionNames", s) +#define ENTRY_MODE(s,i) THEME->GetMetric ("ScreenOptionsMaster",ssprintf("%s,%i",(s).c_str(),(i+1))) +#define ENTRY_DEFAULT(s) THEME->GetMetric ("ScreenOptionsMaster",(s) + "Default") +#define NEXT_SCREEN THEME->GetMetric (m_sName,"NextScreen") +#define PREV_SCREEN THEME->GetMetric (m_sName,"PrevScreen") /* Add the list named "ListName" to the given row/handler. */ -void ScreenOptionsMaster::SetList( OptionRowDefinition &row, OptionRowHandler &hand, CString ListName ) +void ScreenOptionsMaster::SetList( OptionRowDefinition &row, OptionRowHandler &hand, CString _ListName ) { - hand.type = ROW_LIST; - hand.m_bUseModNameForIcon = true; + CString ListName = _ListName; + row.Init(); + hand.Init(); + + hand.type = ROW_LIST; + hand.m_sName = ListName; + hand.m_bUseModNameForIcon = true; + row.name = ListName; if( !ListName.CompareNoCase("noteskins") ) { @@ -65,23 +71,37 @@ void ScreenOptionsMaster::SetList( OptionRowDefinition &row, OptionRowHandler &h hand.Default.Load( -1, ParseCommands(ENTRY_DEFAULT(ListName)) ); /* Parse the basic configuration metric. */ - CStringArray asParts; - split( ENTRY(ListName), ",", asParts ); - if( asParts.size() < 1 ) + Commands cmds = ParseCommands( ENTRY(ListName) ); + if( cmds.v.size() < 1 ) RageException::Throw( "Parse error in ScreenOptionsMasterEntries::ListName%s", ListName.c_str() ); row.bOneChoiceForAllPlayers = false; - const int NumCols = atoi( asParts[0] ); - for( unsigned i=0; i= 0 && pn < NUM_PLAYERS ); + row.m_vEnabledForPlayers.insert( pn ); + } + } } for( int col = 0; col < NumCols; ++col ) @@ -102,19 +122,25 @@ void ScreenOptionsMaster::SetList( OptionRowDefinition &row, OptionRowHandler &h } } -void ScreenOptionsMaster::SetLua( OptionRowDefinition &row, OptionRowHandler &hand, const CString &sLuaFunction ) +void ScreenOptionsMaster::SetLua( OptionRowDefinition &row, OptionRowHandler &hand, const CString &_sLuaFunction ) { + CString sLuaFunction = _sLuaFunction; + + row.Init(); + hand.Init(); + hand.type = ROW_LUA; + hand.m_sName = sLuaFunction; hand.m_bUseModNameForIcon = true; /* Run the Lua expression. It should return a table. */ - hand.m_LuaTable.SetFromExpression( sLuaFunction ); + hand.m_pLuaTable->SetFromExpression( sLuaFunction ); - if( hand.m_LuaTable.GetLuaType() != LUA_TTABLE ) + if( hand.m_pLuaTable->GetLuaType() != LUA_TTABLE ) RageException::Throw( "Result of \"%s\" is not a table", sLuaFunction.c_str() ); { - hand.m_LuaTable.PushSelf( LUA->L ); + hand.m_pLuaTable->PushSelf( LUA->L ); lua_pushstring( LUA->L, "Name" ); lua_gettable( LUA->L, -2 ); @@ -140,6 +166,7 @@ void ScreenOptionsMaster::SetLua( OptionRowDefinition &row, OptionRowHandler &ha ASSERT( row.layoutType != LAYOUT_INVALID ); lua_pop( LUA->L, 1 ); + lua_pushstring( LUA->L, "SelectType" ); lua_gettable( LUA->L, -2 ); pStr = lua_tostring( LUA->L, -1 ); @@ -149,6 +176,7 @@ void ScreenOptionsMaster::SetLua( OptionRowDefinition &row, OptionRowHandler &ha ASSERT( row.selectType != SELECT_INVALID ); lua_pop( LUA->L, 1 ); + /* Iterate over the "Choices" table. */ lua_pushstring( LUA->L, "Choices" ); lua_gettable( LUA->L, -2 ); @@ -171,6 +199,31 @@ void ScreenOptionsMaster::SetLua( OptionRowDefinition &row, OptionRowHandler &ha lua_pop( LUA->L, 1 ); /* pop choices table */ + + /* Iterate over the "EnabledForPlayers" table. */ + lua_pushstring( LUA->L, "EnabledForPlayers" ); + lua_gettable( LUA->L, -2 ); + if( !lua_isnil( LUA->L, -1 ) ) + { + if( !lua_istable( LUA->L, -1 ) ) + RageException::Throw( "\"%s\" \"EnabledForPlayers\" is not a table", sLuaFunction.c_str() ); + + row.m_vEnabledForPlayers.clear(); // and fill in with supplied PlayerNumbers below + + lua_pushnil( LUA->L ); + while( lua_next(LUA->L, -2) != 0 ) + { + /* `key' is at index -2 and `value' at index -1 */ + PlayerNumber pn = (PlayerNumber)luaL_checkint( LUA->L, -1 ); + + row.m_vEnabledForPlayers.insert( pn ); + + lua_pop( LUA->L, 1 ); /* removes `value'; keeps `key' for next iteration */ + } + } + lua_pop( LUA->L, 1 ); /* pop EnabledForPlayers table */ + + lua_pop( LUA->L, 1 ); /* pop main table */ ASSERT( lua_gettop(LUA->L) == 0 ); } @@ -416,22 +469,22 @@ ScreenOptionsMaster::ScreenOptionsMaster( CString sClassName ): RageException::Throw( "Parse error in %s::Line%i", m_sName.c_str(), i+1 ); OptionRowHandler hand; - for( unsigned part = 0; part < vCommands.v.size(); ++part) + for( unsigned c=0; cL) == 1 ); /* vbSelectedOut table */ /* Get the function to call from m_LuaTable. */ - hand.m_LuaTable.PushSelf( LUA->L ); + hand.m_pLuaTable->PushSelf( LUA->L ); ASSERT( lua_istable( LUA->L, -1 ) ); lua_pushstring( LUA->L, "LoadSelections" ); @@ -572,7 +625,7 @@ void ScreenOptionsMaster::ImportOption( const OptionRowDefinition &row, const Op RageException::Throw( "\"%s\" \"LoadSelections\" entry is not a function", row.name.c_str() ); /* Argument 1 (self): */ - hand.m_LuaTable.PushSelf( LUA->L ); + hand.m_pLuaTable->PushSelf( LUA->L ); /* Argument 2 (vbSelectedOut): */ lua_pushvalue( LUA->L, 1 ); @@ -627,18 +680,18 @@ void ScreenOptionsMaster::ImportOptions() for( unsigned i = 0; i < OptionRowHandlers.size(); ++i ) { const OptionRowHandler &hand = OptionRowHandlers[i]; - const OptionRowDefinition &data = m_OptionRowAlloc[i]; + const OptionRowDefinition &def = m_OptionRowAlloc[i]; OptionRow &row = *m_Rows[i]; - if( data.bOneChoiceForAllPlayers ) + if( def.bOneChoiceForAllPlayers ) { - ImportOption(data, hand, PLAYER_1, i, row.m_vbSelected[0] ); + ImportOption(def, hand, PLAYER_1, i, row.m_vbSelected[0] ); } else { FOREACH_HumanPlayer( p ) { - ImportOption( data, hand, p, i, row.m_vbSelected[p] ); + ImportOption( def, hand, p, i, row.m_vbSelected[p] ); } } } @@ -653,12 +706,12 @@ void ScreenOptionsMaster::ImportOptionsForPlayer( PlayerNumber pn ) for( unsigned i = 0; i < OptionRowHandlers.size(); ++i ) { const OptionRowHandler &hand = OptionRowHandlers[i]; - const OptionRowDefinition &data = m_OptionRowAlloc[i]; + const OptionRowDefinition &def = m_OptionRowAlloc[i]; OptionRow &row = *m_Rows[i]; - if( data.bOneChoiceForAllPlayers ) + if( def.bOneChoiceForAllPlayers ) continue; - ImportOption( data, hand, pn, i, row.m_vbSelected[pn] ); + ImportOption( def, hand, pn, i, row.m_vbSelected[pn] ); } } @@ -702,7 +755,7 @@ int ScreenOptionsMaster::ExportOption( const OptionRowDefinition &row, const Opt ASSERT( lua_gettop(LUA->L) == 1 ); /* vbSelectedOut table */ /* Get the function to call. */ - hand.m_LuaTable.PushSelf( LUA->L ); + hand.m_pLuaTable->PushSelf( LUA->L ); ASSERT( lua_istable( LUA->L, -1 ) ); lua_pushstring( LUA->L, "SaveSelections" ); @@ -711,7 +764,7 @@ int ScreenOptionsMaster::ExportOption( const OptionRowDefinition &row, const Opt RageException::Throw( "\"%s\" \"SaveSelections\" entry is not a function", row.name.c_str() ); /* Argument 1 (self): */ - hand.m_LuaTable.PushSelf( LUA->L ); + hand.m_pLuaTable->PushSelf( LUA->L ); /* Argument 2 (vbSelectedOut): */ lua_pushvalue( LUA->L, 1 ); @@ -765,13 +818,13 @@ int ScreenOptionsMaster::ExportOptionForAllPlayers( int iRow ) { int iChangeMask = 0; const OptionRowHandler &hand = OptionRowHandlers[iRow]; - const OptionRowDefinition &data = m_OptionRowAlloc[iRow]; + const OptionRowDefinition &def = m_OptionRowAlloc[iRow]; OptionRow &row = *m_Rows[iRow]; FOREACH_HumanPlayer( pn ) { vector &vbSelected = row.m_vbSelected[pn]; - iChangeMask |= ExportOption( data, hand, pn, vbSelected ); + iChangeMask |= ExportOption( def, hand, pn, vbSelected ); } return iChangeMask; } @@ -791,8 +844,8 @@ void ScreenOptionsMaster::ExportOptions() CHECKPOINT_M( ssprintf("%i/%i", i, int(OptionRowHandlers.size())) ); /* If SELECT_NONE, only apply it if it's the selected option. */ - const OptionRowDefinition &data = m_OptionRowAlloc[i]; - if( data.selectType == SELECT_NONE && i != row ) + const OptionRowDefinition &def = m_OptionRowAlloc[i]; + if( def.selectType == SELECT_NONE && i != row ) continue; OptionRowHandler &hand = OptionRowHandlers[i]; @@ -893,7 +946,7 @@ void ScreenOptionsMaster::RefreshIcons() continue; // skip OptionRow &row = *m_Rows[i]; - const OptionRowDefinition &data = row.GetRowDef(); + const OptionRowDefinition &def = row.GetRowDef(); // find first selection and whether multiple are selected int iFirstSelection = row.GetOneSelection( p, true ); @@ -913,7 +966,7 @@ void ScreenOptionsMaster::RefreshIcons() case ROW_LIST: sIcon = handler.m_bUseModNameForIcon ? handler.ListEntries[iFirstSelection].m_sModifiers : - data.choices[iFirstSelection]; + def.choices[iFirstSelection]; break; case ROW_CONFIG: break; @@ -922,7 +975,7 @@ void ScreenOptionsMaster::RefreshIcons() /* XXX: hack to not display text in the song options menu */ - if( data.bOneChoiceForAllPlayers ) + if( def.bOneChoiceForAllPlayers ) sIcon = ""; LoadOptionIcon( p, i, sIcon ); @@ -930,6 +983,52 @@ void ScreenOptionsMaster::RefreshIcons() } } +void ScreenOptionsMaster::ChangeValueInRow( PlayerNumber pn, int iDelta, bool Repeat ) +{ + ScreenOptions::ChangeValueInRow( pn, iDelta, Repeat ); + + int iRow = m_iCurrentRow[pn]; + + const OptionRowHandler &hand = OptionRowHandlers[iRow]; + + FOREACH_CONST( CString, hand.m_vsRefreshRowNames, sRowToRefreshName ) + { + for( unsigned r=0; r m_vsRefreshRowNames; // refresh these rows when the value of this row changes /* ROW_LIST: */ vector ListEntries; @@ -36,7 +50,7 @@ private: bool m_bUseModNameForIcon; /* ROW_LUA: */ - LuaExpression m_LuaTable; + LuaExpression *m_pLuaTable; /* ROW_CONFIG: */ const ConfOption *opt; @@ -47,20 +61,22 @@ private: vector OptionRowHandlers; OptionRowDefinition *m_OptionRowAlloc; - int ExportOption( const OptionRowDefinition &row, const OptionRowHandler &hand, PlayerNumber pn, const vector &vbSelected ); - void ImportOption( const OptionRowDefinition &row, const OptionRowHandler &hand, PlayerNumber pn, int rowno, vector &vbSelectedOut ); + int ExportOption( const OptionRowDefinition &def, const OptionRowHandler &hand, PlayerNumber pn, const vector &vbSelected ); + void ImportOption( const OptionRowDefinition &def, const OptionRowHandler &hand, PlayerNumber pn, int rowno, vector &vbSelectedOut ); int ExportOptionForAllPlayers( int iRow ); - static void SetList( OptionRowDefinition &row, OptionRowHandler &hand, CString param ); - static void SetLua( OptionRowDefinition &row, OptionRowHandler &hand, const CString &sLuaFunction ); - static void SetSteps( OptionRowDefinition &row, OptionRowHandler &hand ); - static void SetConf( OptionRowDefinition &row, OptionRowHandler &hand, CString param ); - static void SetCharacters( OptionRowDefinition &row, OptionRowHandler &hand ); - static void SetStyles( OptionRowDefinition &row, OptionRowHandler &hand ); - static void SetGroups( OptionRowDefinition &row, OptionRowHandler &hand ); - static void SetDifficulties( OptionRowDefinition &row, OptionRowHandler &hand ); + static void SetList( OptionRowDefinition &def, OptionRowHandler &hand, CString param ); + static void SetLua( OptionRowDefinition &def, OptionRowHandler &hand, const CString &sLuaFunction ); + static void SetSteps( OptionRowDefinition &def, OptionRowHandler &hand ); + static void SetConf( OptionRowDefinition &def, OptionRowHandler &hand, CString param ); + static void SetCharacters( OptionRowDefinition &def, OptionRowHandler &hand ); + static void SetStyles( OptionRowDefinition &def, OptionRowHandler &hand ); + static void SetGroups( OptionRowDefinition &def, OptionRowHandler &hand ); + static void SetDifficulties( OptionRowDefinition &def, OptionRowHandler &hand ); protected: + virtual void ChangeValueInRow( PlayerNumber pn, int iDelta, bool Repeat ); + virtual void ImportOptions(); virtual void ExportOptions(); virtual void ImportOptionsForPlayer( PlayerNumber pn ); // used by ScreenPlayerOptions