From dcb2f74c8da15250aed3a0cee72eca8075112659 Mon Sep 17 00:00:00 2001 From: Rhythm Lunatic Date: Thu, 28 Mar 2019 16:49:46 -0500 Subject: [PATCH] Add More OptionsList functionality (#1810) * Add More OptionsList functionality * Remove Size parameter because it's broken * Make OptionsList inputs remappable * Change Next/Prev OptionsList to CodeDetector --- Themes/_fallback/Scripts/03 Gameplay.lua | 25 ++++++++++ Themes/_fallback/metrics.ini | 60 ++++++++++++++++++++++++ src/CodeDetector.cpp | 11 +++++ src/CodeDetector.h | 4 ++ src/OptionRowHandler.cpp | 2 +- src/OptionRowHandler.h | 2 +- src/OptionsList.cpp | 60 +++++++++++++++--------- src/OptionsList.h | 5 +- 8 files changed, 144 insertions(+), 25 deletions(-) diff --git a/Themes/_fallback/Scripts/03 Gameplay.lua b/Themes/_fallback/Scripts/03 Gameplay.lua index fb284cb076..84a1ef1218 100644 --- a/Themes/_fallback/Scripts/03 Gameplay.lua +++ b/Themes/_fallback/Scripts/03 Gameplay.lua @@ -331,6 +331,13 @@ local CodeDetectorCodes = { CloseCurrentFolder = { default = "MenuUp-MenuDown", }, + -- OptionsList + PrevOptionsList = { + default = "@MenuUp-MenuDown", + }, + NextOptionsList = { + default = "@MenuDown-MenuUp", + }, -- sorts NextSort1 = { default = "@MenuLeft-@MenuRight-Start", @@ -461,6 +468,24 @@ function GetCodeForGame(codeName) return inputCode[gameName] or inputCode["default"] end +local OptionsListKeys = { + PrevItem = { + pump="MenuLeft", + default="MenuUp" + }, + NextItem = { + pump="MenuRight", + default="MenuDown" + } +}; + +function GetOptionsListMapping(name) + local sGame = string.lower(GAMESTATE:GetCurrentGame():GetName()) + local map = OptionsListKeys[name] + return map[sGame] or map["default"] +end + + function oitg_zoom_mode_actor() return Def.Actor{ OnCommand= function(self) diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 882a70f748..0eb954bbaa 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -368,6 +368,10 @@ PrevGroup=GetCodeForGame("PrevGroup") CloseCurrentFolder=GetCodeForGame("CloseCurrentFolder") Hidden=GetCodeForGame("Hidden") RandomVanish=GetCodeForGame("RandomVanish") +# OptionsList (if enabled) +PrevOptionsList=GetCodeForGame("PrevOptionsList") +NextOptionsList=GetCodeForGame("NextOptionsList") +# Evaluation screen SaveScreenshot1=GetCodeForGame("SaveScreenshot1") SaveScreenshot2=GetCodeForGame("SaveScreenshot2") # on the player options menu. @@ -2875,6 +2879,62 @@ ExplanationTogetherOffCommand=stoptweening [ScreenOptionsServiceExtendedChild] Fallback="ScreenOptionsServiceChild" +[OptionsList] +Fallback="ScreenWithMenuElements" + +PrevMenuButton=GetOptionsListMapping("PrevMenu") +NextMenuButton=GetOptionsListMapping("NextMenu") +PrevItemButton=GetOptionsListMapping("PrevItem") +NextItemButton=GetOptionsListMapping("NextItem") +CodeNames="" + +#It takes from ScreenOptionsMaster. +#This is the equivalent to LineNames +TopMenus="" +TopMenu="" + +DirectLines="" +ItemsSpacingY= +MaxItemsBeforeSplit= +ItemsSplitWidth= + +TextOnCommand= +TextOffCommand= +TextTweenOffCommand= +TextTweenOnCommand= +TextResetCommand= + +UnderlineOnCommand= +UnderlineOffCommand= +UnderlineSetTwoRowsCommand= +UnderlineSetOneRowCommand= +UnderlineShowCommand= +UnderlineHideCommand= +UnderlineTweenOnCommand= +UnderlineTweenOffCommand= +UnderlineResetCommand= + +CursorOnCommand= +CursorPositionTwoRowsCommand= +CursorPositionOneRowCommand= +CursorTweenOnCommand= +CursorTweenOffCommand= +CursorResetCommand= + +OptionsListOnCommand= +OptionsListOffCommand= +OptionsListTweenOffCommand= +OptionsListTweenOnCommand= +OptionsListResetCommand= + +OptionsListTweenOutForwardCommand= +OptionsListTweenOutBackwardCommand= +OptionsListTweenInForwardCommand= +OptionsListTweenInBackwardCommand= + +OptionsListFadeOffCommand= +OptionsListFadeOnCommand= + [ScreenMiniMenu] Class="ScreenMiniMenu" Fallback="ScreenOptions" diff --git a/src/CodeDetector.cpp b/src/CodeDetector.cpp index d35a3a00c2..42780e0805 100644 --- a/src/CodeDetector.cpp +++ b/src/CodeDetector.cpp @@ -53,6 +53,8 @@ const char *CodeNames[] = { "CancelAllPlayerOptions", "BackInEventMode", "CloseCurrentFolder", + "PrevOptionsList", + "NextOptionsList" }; XToString( Code ); @@ -116,6 +118,15 @@ bool CodeDetector::EnteredModeMenu( GameController controller ) return EnteredCode(controller,CODE_MODE_MENU1) || EnteredCode(controller,CODE_MODE_MENU2); } +bool CodeDetector::EnteredPrevOpList( GameController controller ) +{ + return EnteredCode(controller,CODE_PREV_OPLIST); +} +bool CodeDetector::EnteredNextOpList( GameController controller ) +{ + return EnteredCode(controller,CODE_NEXT_OPLIST); +} + #define TOGGLE(v,a,b) if(v!=a) v=a; else v=b; #define FLOAT_TOGGLE(v) if(v!=1.f) v=1.f; else v=0.f; // XXX: Read the metrics file instead! diff --git a/src/CodeDetector.h b/src/CodeDetector.h index d9b6089fbb..f54616af8c 100644 --- a/src/CodeDetector.h +++ b/src/CodeDetector.h @@ -47,6 +47,8 @@ enum Code { CODE_CANCEL_ALL_PLAYER_OPTIONS, CODE_BACK_IN_EVENT_MODE, CODE_CLOSE_CURRENT_FOLDER, + CODE_NEXT_OPLIST, + CODE_PREV_OPLIST, NUM_Code // leave this at the end }; @@ -63,6 +65,8 @@ public: static bool EnteredPrevGroup( GameController controller ); static bool EnteredNextGroup( GameController controller ); static bool EnteredCloseFolder( GameController controller ); + static bool EnteredPrevOpList( GameController controller ); + static bool EnteredNextOpList( GameController controller ); // todo: move to PlayerOptions.h -aj void ChangeScrollSpeed( GameController controller, bool bIncrement ); diff --git a/src/OptionRowHandler.cpp b/src/OptionRowHandler.cpp index cb92d6a4cc..1810e0d04d 100644 --- a/src/OptionRowHandler.cpp +++ b/src/OptionRowHandler.cpp @@ -1326,7 +1326,7 @@ public: LUA->Release(L); return changed; } - virtual bool GoToFirstOnStart() + virtual bool GoToFirstOnStart() const { return m_GoToFirstOnStart; } diff --git a/src/OptionRowHandler.h b/src/OptionRowHandler.h index d115ca8676..b126634114 100644 --- a/src/OptionRowHandler.h +++ b/src/OptionRowHandler.h @@ -186,7 +186,7 @@ public: virtual RString GetScreen( int /* iChoice */ ) const { return RString(); } // Exists so that a lua function can act on the selection. Returns true if the choices should be reloaded. virtual bool NotifyOfSelection(PlayerNumber pn, int choice) { return false; } - virtual bool GoToFirstOnStart() { return true; } + virtual bool GoToFirstOnStart() const { return true; } }; /** @brief Utilities for the OptionRowHandlers. */ diff --git a/src/OptionsList.cpp b/src/OptionsList.cpp index 80f2410217..109cfecbad 100644 --- a/src/OptionsList.cpp +++ b/src/OptionsList.cpp @@ -181,13 +181,16 @@ OptionsList::~OptionsList() delete hand->second; } +//This is the initialization function. void OptionsList::Load( RString sType, PlayerNumber pn ) { TOP_MENU.Load( sType, "TopMenu" ); m_pn = pn; m_bStartIsDown = false; - + m_GameButtonPreviousItem = INPUTMAPPER->GetInputScheme()->ButtonNameToIndex( THEME->GetMetric( m_sName,"PrevItemButton" ) ); + m_GameButtonNextItem = INPUTMAPPER->GetInputScheme()->ButtonNameToIndex( THEME->GetMetric( m_sName,"NextItemButton" ) ); + m_Codes.Load( sType ); m_Cursor.Load( THEME->GetPathG(sType, "cursor") ); @@ -290,7 +293,8 @@ RString OptionsList::GetCurrentRow() const return m_asMenuStack.back(); } -const OptionRowHandler *OptionsList::GetCurrentHandler() +//This can't be const because OptionRowHandler->NotifyOfSelection() will modify the OptionRow. +OptionRowHandler *OptionsList::GetCurrentHandler() { RString sCurrentRow = GetCurrentRow(); return m_Rows[sCurrentRow]; @@ -414,18 +418,11 @@ bool OptionsList::Input( const InputEventPlus &input ) } } - if( input.MenuI == GAME_BUTTON_LEFT ) + if( input.MenuI == m_GameButtonPreviousItem ) { if( input.type == IET_RELEASE ) return false; - if( INPUTMAPPER->IsBeingPressed(GAME_BUTTON_RIGHT, pn) ) - { - if( input.type == IET_FIRST_PRESS ) - SwitchMenu( -1 ); - return true; - } - --m_iMenuStackSelection; wrap( m_iMenuStackSelection, pHandler->m_Def.m_vsChoices.size()+1 ); // +1 for exit row PositionCursor(); @@ -436,18 +433,11 @@ bool OptionsList::Input( const InputEventPlus &input ) MESSAGEMAN->Broadcast( lMsg ); return true; } - else if( input.MenuI == GAME_BUTTON_RIGHT ) + else if( input.MenuI == m_GameButtonNextItem ) { if( input.type == IET_RELEASE ) return false; - if( INPUTMAPPER->IsBeingPressed(GAME_BUTTON_LEFT, pn) ) - { - if( input.type == IET_FIRST_PRESS ) - SwitchMenu( +1 ); - return true; - } - ++m_iMenuStackSelection; wrap( m_iMenuStackSelection, pHandler->m_Def.m_vsChoices.size()+1 ); // +1 for exit row PositionCursor(); @@ -458,6 +448,18 @@ bool OptionsList::Input( const InputEventPlus &input ) MESSAGEMAN->Broadcast( lMsg ); return true; } + else if ( CodeDetector::EnteredPrevOpList(input.GameI.controller) ) + { + if( input.type == IET_FIRST_PRESS ) + SwitchMenu( -1 ); + return true; + } + else if ( CodeDetector::EnteredNextOpList(input.GameI.controller) ) + { + if( input.type == IET_FIRST_PRESS ) + SwitchMenu( +1 ); + return true; + } else if( input.MenuI == GAME_BUTTON_START ) { if( input.type == IET_FIRST_PRESS ) @@ -662,7 +664,7 @@ void OptionsList::UpdateMenuFromSelections() bool OptionsList::Start() { - const OptionRowHandler *pHandler = GetCurrentHandler(); + OptionRowHandler *pHandler = GetCurrentHandler(); const RString &sCurrentRow = m_asMenuStack.back(); vector &bSelections = m_bSelections[sCurrentRow]; if( m_iMenuStackSelection == (int)bSelections.size() ) @@ -717,12 +719,26 @@ bool OptionsList::Start() SelectItem( GetCurrentRow(), m_iMenuStackSelection ); - /* Move to the exit row. */ - m_iMenuStackSelection = (int)bSelections.size(); - PositionCursor(); + /* Move to the exit row, but only if it's SelectOne. */ + if (pHandler->m_Def.m_selectType == SELECT_ONE) + { + m_iMenuStackSelection = (int)bSelections.size(); + PositionCursor(); + } + if (pHandler->NotifyOfSelection(m_pn, m_iMenuStackSelection)) + { + /* The current selections are irrelevant when we're getting them + * from NotifyOfSelection. Re import them from the OptionRow. */ + ImportRow(sCurrentRow); + UpdateMenuFromSelections(); + } + /* Better to include Selection as a parameter since + * the index may or may not change depending on if SelectType + * is SELECT_ONE or SELECT_MULTIPLE. */ Message msg("OptionsListStart"); msg.SetParam( "Player", m_pn ); + msg.SetParam( "Selection", m_iMenuStackSelection ); MESSAGEMAN->Broadcast( msg ); return false; diff --git a/src/OptionsList.h b/src/OptionsList.h index 6a03f166fb..783e1d77c2 100644 --- a/src/OptionsList.h +++ b/src/OptionsList.h @@ -70,7 +70,7 @@ private: void SelectionsChanged( const RString &sRowName ); void UpdateMenuFromSelections(); RString GetCurrentRow() const; - const OptionRowHandler *GetCurrentHandler(); + OptionRowHandler *GetCurrentHandler(); int GetOneSelection( RString sRow, bool bAllowFail=false ) const; void SwitchToCurrentRow(); void TweenOnCurrentRow( bool bForward ); @@ -101,6 +101,9 @@ private: vector m_asMenuStack; int m_iMenuStackSelection; +protected: + GameButton m_GameButtonPreviousItem; + GameButton m_GameButtonNextItem; };