From b39f408afcde27e5cfbe7d2813117f364318bc69 Mon Sep 17 00:00:00 2001 From: Tyler Wilding Date: Sun, 23 Aug 2020 20:07:47 -0400 Subject: [PATCH] pcsx2-gui: Improve method of adding key shortcut to menu items --- pcsx2/gui/App.h | 5 +++-- pcsx2/gui/AppAccelerators.h | 41 ++++++++++++++++++++++++++++++++++++ pcsx2/gui/FrameForGS.cpp | 5 +++++ pcsx2/gui/GSFrame.h | 1 + pcsx2/gui/GlobalCommands.cpp | 15 +++++++++++++ pcsx2/gui/MainFrame.cpp | 32 ++++++++++++++++------------ pcsx2/gui/MainFrame.h | 3 +++ 7 files changed, 87 insertions(+), 15 deletions(-) diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index e24bae5cd6..f19a1e8720 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -202,10 +202,11 @@ enum MenuIdentifiers MenuId_Recording_New, MenuId_Recording_Play, MenuId_Recording_Stop, - MenuId_Recording_Editor, + MenuId_Recording_TogglePause, + MenuId_Recording_FrameAdvance, + MenuId_Recording_ToggleRecordingMode, MenuId_Recording_VirtualPad_Port0, MenuId_Recording_VirtualPad_Port1, - MenuId_Recording_Conversions, #endif }; diff --git a/pcsx2/gui/AppAccelerators.h b/pcsx2/gui/AppAccelerators.h index 44a1dd9c1a..ac3adc9340 100644 --- a/pcsx2/gui/AppAccelerators.h +++ b/pcsx2/gui/AppAccelerators.h @@ -58,6 +58,11 @@ struct KeyAcceleratorCode keycode = code; } + KeyAcceleratorCode(u32 value) + { + val32 = value; + } + KeyAcceleratorCode& Shift() { shift = true; @@ -83,6 +88,36 @@ struct KeyAcceleratorCode } wxString ToString() const; + + // Capitalizes the key portion of an accelerator code for displaying to the UI + // ie. Shift-a becomes Shift-A / Ctrl+Shift+a becomes Ctrl+Shift+A + wxString toTitleizedString() const + { + if (val32 == 0) + return wxEmptyString; + + std::vector tokens; + wxStringTokenizer tokenizer(ToString(), "+"); + while (tokenizer.HasMoreTokens()) + tokens.push_back(tokenizer.GetNextToken()); + + if (tokens.size() == 1) + return tokens.at(0); + else if (tokens.size() < 1) + return wxEmptyString; + + wxString lastToken = tokens.at(tokens.size() - 1); + tokens.at(tokens.size() - 1) = lastToken[0] = wxToupper(lastToken[0]); + wxString modifiedKeyCode; + for (int i = 0; i < (int)tokens.size(); i++) + { + if (i == tokens.size() - 1) + modifiedKeyCode.append(tokens.at(i)); + else + modifiedKeyCode.append(wxString::Format("%s+", tokens.at(i))); + } + return modifiedKeyCode; + } }; @@ -100,6 +135,8 @@ struct GlobalCommandDescriptor const wxChar* Tooltip; // text displayed in toolbar tooltips and menu status bars. bool AlsoApplyToGui; // Indicates that the GUI should be updated if possible. + + wxString keycodeString; }; // -------------------------------------------------------------------------------------- @@ -130,4 +167,8 @@ public: virtual ~AcceleratorDictionary() = default; void Map( const KeyAcceleratorCode& acode, const char *searchfor ); + // Searches the dictionary _by the value (command ID string)_ and returns + // the associated KeyAcceleratorCode. Do not expect constant time lookup + // Returns a blank KeyAcceleratorCode if nothing is found + KeyAcceleratorCode findKeycodeWithCommandId(const char *commandId); }; diff --git a/pcsx2/gui/FrameForGS.cpp b/pcsx2/gui/FrameForGS.cpp index be19ba7a90..a14ee4d644 100644 --- a/pcsx2/gui/FrameForGS.cpp +++ b/pcsx2/gui/FrameForGS.cpp @@ -20,6 +20,7 @@ #include "AppSaveStates.h" #include "Counters.h" #include "GS.h" +#include "MainFrame.h" #include "MSWstuff.h" #include "ConsoleLogger.h" @@ -130,6 +131,10 @@ void GSPanel::InitRecordingAccelerators() m_Accels->Map(AAC(WXK_NUMPAD8), "States_LoadSlot8"); m_Accels->Map(AAC(WXK_NUMPAD9), "States_LoadSlot9"); + GetMainFramePtr()->appendKeycodeNamesToRecordingMenuOptions(MenuId_Recording_FrameAdvance, m_Accels->findKeycodeWithCommandId("FrameAdvance").toTitleizedString()); + GetMainFramePtr()->appendKeycodeNamesToRecordingMenuOptions(MenuId_Recording_TogglePause, m_Accels->findKeycodeWithCommandId("TogglePause").toTitleizedString()); + GetMainFramePtr()->appendKeycodeNamesToRecordingMenuOptions(MenuId_Recording_ToggleRecordingMode, m_Accels->findKeycodeWithCommandId("InputRecordingModeToggle").toTitleizedString()); + recordingConLog(L"Initialized Recording Key Bindings\n"); } #endif diff --git a/pcsx2/gui/GSFrame.h b/pcsx2/gui/GSFrame.h index c474a25380..edbde63607 100644 --- a/pcsx2/gui/GSFrame.h +++ b/pcsx2/gui/GSFrame.h @@ -56,6 +56,7 @@ public: void DirectKeyCommand( wxKeyEvent& evt ); void DirectKeyCommand( const KeyAcceleratorCode& kac ); void InitDefaultAccelerators(); + wxString GetAssociatedKeyCode(const char* id); #ifndef DISABLE_RECORDING void InitRecordingAccelerators(); #endif diff --git a/pcsx2/gui/GlobalCommands.cpp b/pcsx2/gui/GlobalCommands.cpp index 34f2fe2487..c892930f54 100644 --- a/pcsx2/gui/GlobalCommands.cpp +++ b/pcsx2/gui/GlobalCommands.cpp @@ -912,6 +912,19 @@ void AcceleratorDictionary::Map( const KeyAcceleratorCode& _acode, const char *s } } +KeyAcceleratorCode AcceleratorDictionary::findKeycodeWithCommandId(const char* commandId) +{ + for (auto entry = this->begin(); entry != this->end(); entry++) + { + if (strcmp(entry->second->Id, commandId) == 0) + { + const KeyAcceleratorCode keycode(entry->first); + return keycode; + } + } + return KeyAcceleratorCode(0); +} + void Pcsx2App::BuildCommandHash() { if( !GlobalCommands ) GlobalCommands = std::unique_ptr(new CommandDictionary); @@ -932,6 +945,8 @@ void Pcsx2App::InitDefaultGlobalAccelerators() // Why do we even have those here? all of them seem to be overridden // by GSPanel::m_Accels ( GSPanel::InitDefaultAccelerators() ) + // - One reason is because this is used to initialize shortcuts in the MainFrame's UI (see - MainFrame::AppendShortcutToMenuOption) + // this is before the GS Window has been initialized. GlobalAccels->Map( AAC( WXK_F1 ), "States_FreezeCurrentSlot" ); GlobalAccels->Map( AAC( WXK_F3 ), "States_DefrostCurrentSlot" ); diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index 39062a67f6..3d30ec65f2 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -471,6 +471,10 @@ void MainEmuFrame::CreateRecordMenu() m_menuRecording.Append(MenuId_Recording_Stop, _("Stop"))->Enable(false); m_menuRecording.Append(MenuId_Recording_Play, _("Play")); m_menuRecording.AppendSeparator(); + m_menuRecording.Append(MenuId_Recording_TogglePause, _("Toggle Pause")); + m_menuRecording.Append(MenuId_Recording_FrameAdvance, _("Frame Advance")); + m_menuRecording.Append(MenuId_Recording_ToggleRecordingMode, _("Toggle Recording Mode")); + m_menuRecording.AppendSeparator(); m_menuRecording.Append(MenuId_Recording_VirtualPad_Port0, _("Virtual Pad (Port 1)")); m_menuRecording.Append(MenuId_Recording_VirtualPad_Port1, _("Virtual Pad (Port 2)")); #endif @@ -776,24 +780,26 @@ void MainEmuFrame::CommitPreset_noTrigger() g_Conf->EmuOptions.EnablePatches = menubar.IsChecked( MenuId_EnablePatches ); } -static void AppendShortcutToMenuOption( wxMenuItem& item, const char* id ) { - // this is NOT how a dictionary works but it has like 30 entries so this should still perform okay - auto* dict = &wxGetApp().GlobalAccels; - for ( auto it = ( *dict )->begin(); it != ( *dict )->end(); ++it ) { - if ( strcmp( it->second->Id, id ) == 0 ) { - wxString text = item.GetItemLabel(); - size_t tabPos = text.rfind( L'\t' ); - KeyAcceleratorCode keycode( (wxKeyCode)it->first ); - item.SetItemLabel( text.Mid( 0, tabPos ) + L"\t" + keycode.ToString() ); - } - } +static void AppendShortcutToMenuOption( wxMenuItem& item, wxString keyCodeStr ) { + wxString text = item.GetItemLabel(); + const size_t tabPos = text.rfind(L'\t'); + item.SetItemLabel(text.Mid(0, tabPos ) + L"\t" + keyCodeStr); } void MainEmuFrame::AppendKeycodeNamesToMenuOptions() { - AppendShortcutToMenuOption( *m_menuSys.FindChildItem( MenuId_Sys_LoadStates ), "States_DefrostCurrentSlot" ); - AppendShortcutToMenuOption( *m_menuSys.FindChildItem( MenuId_Sys_SaveStates ), "States_FreezeCurrentSlot" ); + + AppendShortcutToMenuOption(*m_menuSys.FindChildItem( MenuId_Sys_LoadStates ), wxGetApp().GlobalAccels->findKeycodeWithCommandId("States_DefrostCurrentSlot").toTitleizedString()); + AppendShortcutToMenuOption(*m_menuSys.FindChildItem( MenuId_Sys_SaveStates ), wxGetApp().GlobalAccels->findKeycodeWithCommandId("States_FreezeCurrentSlot").toTitleizedString()); } +#ifndef DISABLE_RECORDING +void MainEmuFrame::appendKeycodeNamesToRecordingMenuOptions(MenuIdentifiers menuId, wxString keyCodeStr) { + wxMenuItem& item = *m_menuRecording.FindChildItem(menuId); + wxString text = item.GetItemLabel(); + const size_t tabPos = text.rfind(L'\t'); + item.SetItemLabel(text.Mid(0, tabPos ) + L"\t" + keyCodeStr); +} +#endif // ------------------------------------------------------------------------ // "Extensible" Plugin Menus diff --git a/pcsx2/gui/MainFrame.h b/pcsx2/gui/MainFrame.h index b83689fafe..33ebec42a1 100644 --- a/pcsx2/gui/MainFrame.h +++ b/pcsx2/gui/MainFrame.h @@ -166,6 +166,9 @@ public: void CommitPreset_noTrigger(); void AppendKeycodeNamesToMenuOptions(); void UpdateStatusBar(); +#ifndef DISABLE_RECORDING + void AppendKeycodeNamesToRecordingMenuOptions(MenuIdentifiers menuId, wxString keyCodeStr); +#endif protected: void DoGiveHelp(const wxString& text, bool show);