123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816 |
- /*
- * KeyConfigDlg.cpp
- * ----------------
- * Purpose: Implementation of OpenMPT's keyboard configuration dialog.
- * Notes : (currently none)
- * Authors: OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
- #include "stdafx.h"
- #include "KeyConfigDlg.h"
- #include "FileDialog.h"
- #include "../soundlib/mod_specifications.h"
- #include "../soundlib/MIDIEvents.h"
- OPENMPT_NAMESPACE_BEGIN
- //***************************************************************************************//
- // CCustEdit: customised CEdit control to catch keypresses.
- // (does what CHotKeyCtrl does,but better)
- //***************************************************************************************//
- BEGIN_MESSAGE_MAP(CCustEdit, CEdit)
- ON_WM_SETFOCUS()
- ON_WM_KILLFOCUS()
- ON_MESSAGE(WM_MOD_MIDIMSG, &CCustEdit::OnMidiMsg)
- END_MESSAGE_MAP()
- LRESULT CCustEdit::OnMidiMsg(WPARAM dwMidiDataParam, LPARAM)
- {
- if(!m_isFocussed)
- return 1;
- uint32 midiData = static_cast<uint32>(dwMidiDataParam);
- const auto byte1 = MIDIEvents::GetDataByte1FromEvent(midiData), byte2 = MIDIEvents::GetDataByte2FromEvent(midiData);
- switch(MIDIEvents::GetTypeFromEvent(midiData))
- {
- case MIDIEvents::evControllerChange:
- if(byte2 != 0)
- {
- SetKey(ModMidi, byte1);
- if(!m_isDummy)
- m_pOptKeyDlg->OnSetKeyChoice();
- }
- break;
- case MIDIEvents::evNoteOn:
- case MIDIEvents::evNoteOff:
- SetKey(ModMidi, byte1 | 0x80);
- if(!m_isDummy)
- m_pOptKeyDlg->OnSetKeyChoice();
- break;
- }
- return 1;
- }
- BOOL CCustEdit::PreTranslateMessage(MSG *pMsg)
- {
- if(pMsg)
- {
- if(pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN)
- {
- SetKey(CMainFrame::GetInputHandler()->GetModifierMask(), static_cast<UINT>(pMsg->wParam));
- return -1; // Keypress handled, don't pass on message.
- } else if(pMsg->message == WM_KEYUP || pMsg->message == WM_SYSKEYUP)
- {
- //if a key has been released but custom edit box is empty, we have probably just
- //navigated into the box with TAB or SHIFT-TAB. No need to set keychoice.
- if(code != 0 && !m_isDummy)
- m_pOptKeyDlg->OnSetKeyChoice();
- }
- }
- return CEdit::PreTranslateMessage(pMsg);
- }
- void CCustEdit::SetKey(FlagSet<Modifiers> inMod, UINT inCode)
- {
- mod = inMod;
- code = inCode;
- //Setup display
- SetWindowText(KeyCombination::GetKeyText(mod, code));
- }
- void CCustEdit::OnSetFocus(CWnd *pOldWnd)
- {
- CEdit::OnSetFocus(pOldWnd);
- // Lock the input handler
- CMainFrame::GetInputHandler()->Bypass(true);
- // Accept MIDI input
- CMainFrame::GetMainFrame()->SetMidiRecordWnd(m_hWnd);
- m_isFocussed = true;
- }
- void CCustEdit::OnKillFocus(CWnd *pNewWnd)
- {
- CEdit::OnKillFocus(pNewWnd);
- //unlock the input handler
- CMainFrame::GetInputHandler()->Bypass(false);
- m_isFocussed = false;
- }
- //***************************************************************************************//
- // COptionsKeyboard:
- //
- //***************************************************************************************//
- // Initialisation
- BEGIN_MESSAGE_MAP(COptionsKeyboard, CPropertyPage)
- ON_LBN_SELCHANGE(IDC_CHOICECOMBO, &COptionsKeyboard::OnKeyChoiceSelect)
- ON_LBN_SELCHANGE(IDC_COMMAND_LIST, &COptionsKeyboard::OnCommandKeySelChanged)
- ON_LBN_SELCHANGE(IDC_KEYCATEGORY, &COptionsKeyboard::OnCategorySelChanged)
- ON_EN_UPDATE(IDC_CHORDDETECTWAITTIME, &COptionsKeyboard::OnChordWaitTimeChanged) //rewbs.autochord
- ON_COMMAND(IDC_DELETE, &COptionsKeyboard::OnDeleteKeyChoice)
- ON_COMMAND(IDC_RESTORE, &COptionsKeyboard::OnRestoreKeyChoice)
- ON_COMMAND(IDC_LOAD, &COptionsKeyboard::OnLoad)
- ON_COMMAND(IDC_SAVE, &COptionsKeyboard::OnSave)
- ON_COMMAND(IDC_CHECKKEYDOWN, &COptionsKeyboard::OnCheck)
- ON_COMMAND(IDC_CHECKKEYHOLD, &COptionsKeyboard::OnCheck)
- ON_COMMAND(IDC_CHECKKEYUP, &COptionsKeyboard::OnCheck)
- ON_COMMAND(IDC_NOTESREPEAT, &COptionsKeyboard::OnNotesRepeat)
- ON_COMMAND(IDC_NONOTESREPEAT, &COptionsKeyboard::OnNoNotesRepeat)
- ON_COMMAND(IDC_CLEARLOG, &COptionsKeyboard::OnClearLog)
- ON_COMMAND(IDC_RESTORE_KEYMAP, &COptionsKeyboard::OnRestoreDefaultKeymap)
- ON_EN_CHANGE(IDC_FIND, &COptionsKeyboard::OnSearchTermChanged)
- ON_EN_CHANGE(IDC_FINDHOTKEY, &COptionsKeyboard::OnFindHotKey)
- ON_EN_SETFOCUS(IDC_FINDHOTKEY, &COptionsKeyboard::OnClearHotKey)
- ON_WM_DESTROY()
- END_MESSAGE_MAP()
- void COptionsKeyboard::DoDataExchange(CDataExchange *pDX)
- {
- CPropertyPage::DoDataExchange(pDX);
- DDX_Control(pDX, IDC_KEYCATEGORY, m_cmbCategory);
- DDX_Control(pDX, IDC_COMMAND_LIST, m_lbnCommandKeys);
- DDX_Control(pDX, IDC_CHOICECOMBO, m_cmbKeyChoice);
- DDX_Control(pDX, IDC_CHORDDETECTWAITTIME, m_eChordWaitTime);//rewbs.autochord
- DDX_Control(pDX, IDC_KEYREPORT, m_eReport);
- DDX_Control(pDX, IDC_CUSTHOTKEY, m_eCustHotKey);
- DDX_Control(pDX, IDC_FINDHOTKEY, m_eFindHotKey);
- DDX_Control(pDX, IDC_CHECKKEYDOWN, m_bKeyDown);
- DDX_Control(pDX, IDC_CHECKKEYHOLD, m_bKeyHold);
- DDX_Control(pDX, IDC_CHECKKEYUP, m_bKeyUp);
- DDX_Control(pDX, IDC_FIND, m_eFind);
- }
- BOOL COptionsKeyboard::OnSetActive()
- {
- CMainFrame::m_nLastOptionsPage = OPTIONS_PAGE_KEYBOARD;
- return CPropertyPage::OnSetActive();
- }
- BOOL COptionsKeyboard::OnInitDialog()
- {
- CPropertyPage::OnInitDialog();
- m_fullPathName = TrackerSettings::Instance().m_szKbdFile;
- m_localCmdSet = std::make_unique<CCommandSet>();
- m_localCmdSet->Copy(CMainFrame::GetInputHandler()->m_activeCommandSet.get());
- //Fill category combo and automatically selects first category
- DefineCommandCategories();
- for(size_t c = 0; c < commandCategories.size(); c++)
- {
- if(commandCategories[c].name && !commandCategories[c].commands.empty())
- m_cmbCategory.SetItemData(m_cmbCategory.AddString(commandCategories[c].name), c);
- }
- m_cmbCategory.SetCurSel(0);
- UpdateDialog();
- m_eCustHotKey.SetParent(m_hWnd, IDC_CUSTHOTKEY, this);
- m_eFindHotKey.SetParent(m_hWnd, IDC_FINDHOTKEY, this);
- m_eReport.FmtLines(TRUE);
- m_eReport.SetWindowText(_T(""));
- m_eChordWaitTime.SetWindowText(mpt::cfmt::val(TrackerSettings::Instance().gnAutoChordWaitTime));
- return TRUE;
- }
- void CommandCategory::AddCommands(CommandID first, CommandID last, bool addSeparatorAtEnd)
- {
- int count = last - first + 1, val = first;
- commands.insert(commands.end(), count, kcNull);
- std::generate(commands.end() - count, commands.end(), [&val] { return static_cast<CommandID>(val++); });
- if(addSeparatorAtEnd)
- separators.push_back(last);
- }
- // Filter commands: We only need user to see a select set off commands
- // for each category
- void COptionsKeyboard::DefineCommandCategories()
- {
- {
- CommandCategory newCat(_T("Global keys"), kCtxAllContexts);
- newCat.AddCommands(kcStartFile, kcEndFile, true);
- newCat.AddCommands(kcStartPlayCommands, kcEndPlayCommands, true);
- newCat.AddCommands(kcStartEditCommands, kcEndEditCommands, true);
- newCat.AddCommands(kcStartView, kcEndView, true);
- newCat.AddCommands(kcStartMisc, kcEndMisc, true);
- newCat.commands.push_back(kcDummyShortcut);
- commandCategories.push_back(newCat);
- }
- commandCategories.emplace_back(_T(" General [Top]"), kCtxCtrlGeneral);
- commandCategories.emplace_back(_T(" General [Bottom]"), kCtxViewGeneral);
- commandCategories.emplace_back(_T(" Pattern Editor [Top]"), kCtxCtrlPatterns);
- {
- CommandCategory newCat(_T(" Pattern Editor - Order List"), kCtxCtrlOrderlist);
- newCat.AddCommands(kcStartOrderlistCommands, kcEndOrderlistCommands);
- newCat.separators.push_back(kcEndOrderlistNavigation);
- newCat.separators.push_back(kcEndOrderlistEdit);
- newCat.separators.push_back(kcEndOrderlistNum);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Pattern Editor - Quick Channel Settings"), kCtxChannelSettings);
- newCat.AddCommands(kcStartChnSettingsCommands, kcEndChnSettingsCommands);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Pattern Editor - General"), kCtxViewPatterns);
- newCat.AddCommands(kcStartPlainNavigate, kcEndPlainNavigate, true);
- newCat.AddCommands(kcStartJumpSnap, kcEndJumpSnap, true);
- newCat.AddCommands(kcStartHomeEnd, kcEndHomeEnd, true);
- newCat.AddCommands(kcPrevPattern, kcNextSequence, true);
- newCat.AddCommands(kcStartSelect, kcEndSelect, true);
- newCat.AddCommands(kcStartPatternClipboard, kcEndPatternClipboard, true);
- newCat.AddCommands(kcClearRow, kcInsertWholeRowGlobal, true);
- newCat.AddCommands(kcStartChannelKeys, kcEndChannelKeys, true);
- newCat.AddCommands(kcBeginTranspose, kcEndTranspose, true);
- newCat.AddCommands(kcPatternAmplify, kcPatternShrinkSelection, true);
- newCat.AddCommands(kcStartPatternEditMisc, kcEndPatternEditMisc, true);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Pattern Editor - Note Column"), kCtxViewPatternsNote);
- newCat.AddCommands(kcVPStartNotes, kcVPEndNotes, true);
- newCat.AddCommands(kcSetOctave0, kcSetOctave9, true);
- newCat.AddCommands(kcStartNoteMisc, kcEndNoteMisc);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Pattern Editor - Instrument Column"), kCtxViewPatternsIns);
- newCat.AddCommands(kcSetIns0, kcSetIns9);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Pattern Editor - Volume Column"), kCtxViewPatternsVol);
- newCat.AddCommands(kcSetVolumeStart, kcSetVolumeEnd);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Pattern Editor - Effect Column"), kCtxViewPatternsFX);
- newCat.AddCommands(kcSetFXStart, kcSetFXEnd);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Pattern Editor - Effect Parameter Column"), kCtxViewPatternsFXparam);
- newCat.AddCommands(kcSetFXParam0, kcSetFXParamF);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Sample [Top]"), kCtxCtrlSamples);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Sample Editor"), kCtxViewSamples);
- newCat.AddCommands(kcStartSampleEditing, kcEndSampleEditing, true);
- newCat.AddCommands(kcStartSampleMisc, kcEndSampleMisc, true);
- newCat.AddCommands(kcStartSampleCues, kcEndSampleCueGroup);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Instrument Editor"), kCtxCtrlInstruments);
- newCat.AddCommands(kcStartInstrumentCtrlMisc, kcEndInstrumentCtrlMisc);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Envelope Editor"), kCtxViewInstruments);
- newCat.AddCommands(kcStartInstrumentMisc, kcEndInstrumentMisc);
- commandCategories.push_back(newCat);
- }
- commandCategories.emplace_back(_T(" Comments [Top]"), kCtxCtrlComments);
- {
- CommandCategory newCat(_T(" Comments [Bottom]"), kCtxViewComments);
- newCat.AddCommands(kcStartCommentsCommands, kcEndCommentsCommands);
- commandCategories.push_back(newCat);
- }
- {
- CommandCategory newCat(_T(" Plugin Editor"), kCtxVSTGUI);
- newCat.AddCommands(kcStartVSTGUICommands, kcEndVSTGUICommands);
- commandCategories.push_back(newCat);
- }
- }
- // Pure GUI methods
- void COptionsKeyboard::UpdateDialog()
- {
- OnCategorySelChanged(); // Fills command list and automatically selects first command.
- OnCommandKeySelChanged(); // Fills command key choice list for that command and automatically selects first choice.
- }
- void COptionsKeyboard::OnKeyboardChanged()
- {
- OnSettingsChanged();
- UpdateDialog();
- }
- void COptionsKeyboard::OnCategorySelChanged()
- {
- int cat = static_cast<int>(m_cmbCategory.GetItemData(m_cmbCategory.GetCurSel()));
- if(cat >= 0 && cat != m_curCategory)
- {
- // Changed category
- UpdateShortcutList(cat);
- }
- }
- // Force last active category to be selected in dropdown menu.
- void COptionsKeyboard::UpdateCategory()
- {
- for(int i = 0; i < m_cmbCategory.GetCount(); i++)
- {
- if((int)m_cmbCategory.GetItemData(i) == m_curCategory)
- {
- m_cmbCategory.SetCurSel(i);
- break;
- }
- }
- }
- void COptionsKeyboard::OnSearchTermChanged()
- {
- CString findString;
- m_eFind.GetWindowText(findString);
- if(findString.IsEmpty())
- {
- UpdateCategory();
- }
- UpdateShortcutList(findString.IsEmpty() ? m_curCategory : -1);
- }
- void COptionsKeyboard::OnFindHotKey()
- {
- if(m_eFindHotKey.code == 0)
- {
- UpdateCategory();
- }
- UpdateShortcutList(m_eFindHotKey.code == 0 ? m_curCategory : -1);
- }
- void COptionsKeyboard::OnClearHotKey()
- {
- // Focus key search: Clear input
- m_eFindHotKey.SetKey(ModNone, 0);
- }
- // Fills command list and automatically selects first command.
- void COptionsKeyboard::UpdateShortcutList(int category)
- {
- CString findString;
- m_eFind.GetWindowText(findString);
- findString.MakeLower();
- const bool searchByName = !findString.IsEmpty(), searchByKey = (m_eFindHotKey.code != 0);
- const bool doSearch = (searchByName || searchByKey);
- int firstCat = category, lastCat = category;
- if(category == -1)
- {
- // We will search in all categories
- firstCat = 0;
- lastCat = static_cast<int>(commandCategories.size()) - 1;
- }
- CommandID curCommand = static_cast<CommandID>(m_lbnCommandKeys.GetItemData(m_lbnCommandKeys.GetCurSel()));
- m_lbnCommandKeys.ResetContent();
- for(int cat = firstCat; cat <= lastCat; cat++)
- {
- // When searching, we also add the category names to the list.
- bool addCategoryName = (firstCat != lastCat);
- for(size_t cmd = 0; cmd < commandCategories[cat].commands.size(); cmd++)
- {
- CommandID com = (CommandID)commandCategories[cat].commands[cmd];
- CString cmdText = m_localCmdSet->GetCommandText(com);
- bool addKey = true;
- if(searchByKey)
- {
- addKey = false;
- int numChoices = m_localCmdSet->GetKeyListSize(com);
- for(int choice = 0; choice < numChoices; choice++)
- {
- const KeyCombination &kc = m_localCmdSet->GetKey(com, choice);
- if(kc.KeyCode() == m_eFindHotKey.code && kc.Modifier() == m_eFindHotKey.mod)
- {
- addKey = true;
- break;
- }
- }
- }
- if(searchByName && addKey)
- {
- addKey = (cmdText.MakeLower().Find(findString) >= 0);
- }
- if(addKey)
- {
- m_curCategory = cat;
- if(!m_localCmdSet->isHidden(com))
- {
- if(doSearch && addCategoryName)
- {
- const CString catName = _T("------ ") + commandCategories[cat].name.Trim() + _T(" ------");
- m_lbnCommandKeys.SetItemData(m_lbnCommandKeys.AddString(catName), DWORD_PTR(-1));
- addCategoryName = false;
- }
- int item = m_lbnCommandKeys.AddString(m_localCmdSet->GetCommandText(com));
- m_lbnCommandKeys.SetItemData(item, com);
- if(curCommand == com)
- {
- // Keep selection on previously selected string
- m_lbnCommandKeys.SetCurSel(item);
- }
- }
- if(commandCategories[cat].SeparatorAt(com))
- m_lbnCommandKeys.SetItemData(m_lbnCommandKeys.AddString(_T("------------------------------------------------------")), DWORD_PTR(-1));
- }
- }
- }
- if(m_lbnCommandKeys.GetCurSel() == -1)
- {
- m_lbnCommandKeys.SetCurSel(0);
- }
- OnCommandKeySelChanged();
- }
- // Fills key choice list and automatically selects first key choice
- void COptionsKeyboard::OnCommandKeySelChanged()
- {
- const CommandID cmd = static_cast<CommandID>(m_lbnCommandKeys.GetItemData(m_lbnCommandKeys.GetCurSel()));
- CString str;
- //Separator
- if(cmd == kcNull)
- {
- m_cmbKeyChoice.SetWindowText(_T(""));
- m_cmbKeyChoice.EnableWindow(FALSE);
- m_eCustHotKey.SetWindowText(_T(""));
- m_eCustHotKey.EnableWindow(FALSE);
- m_bKeyDown.SetCheck(0);
- m_bKeyDown.EnableWindow(FALSE);
- m_bKeyHold.SetCheck(0);
- m_bKeyHold.EnableWindow(FALSE);
- m_bKeyUp.SetCheck(0);
- m_bKeyUp.EnableWindow(FALSE);
- m_curCommand = kcNull;
- }
- //Fill "choice" list
- else if((cmd >= 0) && (cmd != m_curCommand) || m_forceUpdate) // Have we changed command?
- {
- m_forceUpdate = false;
- m_cmbKeyChoice.EnableWindow(TRUE);
- m_eCustHotKey.EnableWindow(TRUE);
- m_bKeyDown.EnableWindow(TRUE);
- m_bKeyHold.EnableWindow(TRUE);
- m_bKeyUp.EnableWindow(TRUE);
- m_curCommand = cmd;
- m_curCategory = GetCategoryFromCommandID(cmd);
- m_cmbKeyChoice.ResetContent();
- int numChoices = m_localCmdSet->GetKeyListSize(cmd);
- if((cmd < kcNumCommands) && (numChoices > 0))
- {
- for(int i = 0; i < numChoices; i++)
- {
- CString s = MPT_CFORMAT("Choice {} (of {})")(i + 1, numChoices);
- m_cmbKeyChoice.SetItemData(m_cmbKeyChoice.AddString(s), i);
- }
- }
- m_cmbKeyChoice.SetItemData(m_cmbKeyChoice.AddString(_T("<new>")), numChoices);
- m_cmbKeyChoice.SetCurSel(0);
- m_curKeyChoice = -1;
- OnKeyChoiceSelect();
- }
- }
- //Fills or clears key choice info
- void COptionsKeyboard::OnKeyChoiceSelect()
- {
- int choice = static_cast<int>(m_cmbKeyChoice.GetItemData(m_cmbKeyChoice.GetCurSel()));
- CommandID cmd = m_curCommand;
- //If nothing there, clear
- if(cmd == kcNull || choice >= m_localCmdSet->GetKeyListSize(cmd) || choice < 0)
- {
- m_curKeyChoice = choice;
- m_forceUpdate = true;
- m_eCustHotKey.SetKey(ModNone, 0);
- m_bKeyDown.SetCheck(0);
- m_bKeyHold.SetCheck(0);
- m_bKeyUp.SetCheck(0);
- return;
- }
- //else, if changed, Fill
- if(choice != m_curKeyChoice || m_forceUpdate)
- {
- m_curKeyChoice = choice;
- m_forceUpdate = false;
- KeyCombination kc = m_localCmdSet->GetKey(cmd, choice);
- m_eCustHotKey.SetKey(kc.Modifier(), kc.KeyCode());
- m_bKeyDown.SetCheck((kc.EventType() & kKeyEventDown) ? BST_CHECKED : BST_UNCHECKED);
- m_bKeyHold.SetCheck((kc.EventType() & kKeyEventRepeat) ? BST_CHECKED : BST_UNCHECKED);
- m_bKeyUp.SetCheck((kc.EventType() & kKeyEventUp) ? BST_CHECKED : BST_UNCHECKED);
- }
- }
- void COptionsKeyboard::OnChordWaitTimeChanged()
- {
- CString s;
- UINT val;
- m_eChordWaitTime.GetWindowText(s);
- val = _tstoi(s);
- if(val > 5000)
- {
- val = 5000;
- m_eChordWaitTime.SetWindowText(_T("5000"));
- }
- OnSettingsChanged();
- }
- // Change handling
- void COptionsKeyboard::OnRestoreKeyChoice()
- {
- KeyCombination kc;
- CommandID cmd = m_curCommand;
- CInputHandler *ih = CMainFrame::GetInputHandler();
- // Do nothing if there's nothing to restore
- if(cmd == kcNull || m_curKeyChoice < 0 || m_curKeyChoice >= ih->GetKeyListSize(cmd))
- {
- ::MessageBeep(MB_ICONWARNING);
- return;
- }
- // Restore current key combination choice for currently selected command.
- kc = ih->m_activeCommandSet->GetKey(cmd, m_curKeyChoice);
- m_localCmdSet->Remove(m_curKeyChoice, cmd);
- m_localCmdSet->Add(kc, cmd, true, m_curKeyChoice);
- ForceUpdateGUI();
- return;
- }
- void COptionsKeyboard::OnDeleteKeyChoice()
- {
- CommandID cmd = m_curCommand;
- // Do nothing if there's no key defined for this slot.
- if(m_curCommand == kcNull || m_curKeyChoice < 0 || m_curKeyChoice >= m_localCmdSet->GetKeyListSize(cmd))
- {
- ::MessageBeep(MB_ICONWARNING);
- return;
- }
- // Delete current key combination choice for currently selected command.
- m_localCmdSet->Remove(m_curKeyChoice, cmd);
- ForceUpdateGUI();
- return;
- }
- void COptionsKeyboard::OnSetKeyChoice()
- {
- CommandID cmd = m_curCommand;
- if(cmd == kcNull)
- {
- Reporting::Warning("Invalid slot.", "Invalid key data", this);
- return;
- }
- FlagSet<KeyEventType> event = kKeyEventNone;
- if(m_bKeyDown.GetCheck() != BST_UNCHECKED)
- event |= kKeyEventDown;
- if(m_bKeyHold.GetCheck() != BST_UNCHECKED)
- event |= kKeyEventRepeat;
- if(m_bKeyUp.GetCheck() != BST_UNCHECKED)
- event |= kKeyEventUp;
- KeyCombination kc((commandCategories[m_curCategory]).id, m_eCustHotKey.mod, m_eCustHotKey.code, event);
- //detect invalid input
- if(!kc.KeyCode())
- {
- Reporting::Warning("You need to say to which key you'd like to map this command to.", "Invalid key data", this);
- return;
- }
- if(!kc.EventType())
- {
- ::MessageBeep(MB_ICONWARNING);
- kc.EventType(kKeyEventDown);
- }
- bool add = true;
- std::pair<CommandID, KeyCombination> conflictCmd;
- if((conflictCmd = m_localCmdSet->IsConflicting(kc, cmd)).first != kcNull
- && conflictCmd.first != cmd
- && !m_localCmdSet->IsCrossContextConflict(kc, conflictCmd.second))
- {
- ConfirmAnswer delOld = Reporting::Confirm(_T("New shortcut (") + kc.GetKeyText() + _T(") has the same key combination as ") + m_localCmdSet->GetCommandText(conflictCmd.first) + _T(" in ") + conflictCmd.second.GetContextText() + _T(".\nDo you want to delete the other shortcut, only keeping the new one?"), _T("Shortcut Conflict"), true, false, this);
- if(delOld == cnfYes)
- {
- m_localCmdSet->Remove(conflictCmd.second, conflictCmd.first);
- } else if(delOld == cnfCancel)
- {
- // Cancel altogther; restore original choice
- add = false;
- if(m_curKeyChoice >= 0 && m_curKeyChoice < m_localCmdSet->GetKeyListSize(cmd))
- {
- KeyCombination origKc = m_localCmdSet->GetKey(cmd, m_curKeyChoice);
- m_eCustHotKey.SetKey(origKc.Modifier(), origKc.KeyCode());
- } else
- {
- m_eCustHotKey.SetWindowText(_T(""));
- }
- }
- }
- if(add)
- {
- CString report, reportHistory;
- //process valid input
- m_localCmdSet->Remove(m_curKeyChoice, cmd);
- report = m_localCmdSet->Add(kc, cmd, true, m_curKeyChoice);
- //Update log
- m_eReport.GetWindowText(reportHistory);
- m_eReport.SetWindowText(report + reportHistory);
- ForceUpdateGUI();
- }
- }
- void COptionsKeyboard::OnOK()
- {
- CMainFrame::GetInputHandler()->SetNewCommandSet(m_localCmdSet.get());
- CString cs;
- m_eChordWaitTime.GetWindowText(cs);
- TrackerSettings::Instance().gnAutoChordWaitTime = _tstoi(cs);
- CPropertyPage::OnOK();
- }
- void COptionsKeyboard::OnDestroy()
- {
- CPropertyPage::OnDestroy();
- m_localCmdSet = nullptr;
- }
- void COptionsKeyboard::OnLoad()
- {
- auto dlg = OpenFileDialog()
- .DefaultExtension("mkb")
- .DefaultFilename(m_fullPathName)
- .ExtensionFilter("OpenMPT Key Bindings (*.mkb)|*.mkb||")
- .AddPlace(theApp.GetInstallPkgPath() + P_("extraKeymaps"))
- .WorkingDirectory(TrackerSettings::Instance().m_szKbdFile);
- if(!dlg.Show(this))
- return;
- m_fullPathName = dlg.GetFirstFile();
- m_localCmdSet->LoadFile(m_fullPathName);
- ForceUpdateGUI();
- }
- void COptionsKeyboard::OnSave()
- {
- auto dlg = SaveFileDialog()
- .DefaultExtension("mkb")
- .DefaultFilename(m_fullPathName)
- .ExtensionFilter("OpenMPT Key Bindings (*.mkb)|*.mkb||")
- .WorkingDirectory(TrackerSettings::Instance().m_szKbdFile);
- if(!dlg.Show(this))
- return;
- m_fullPathName = dlg.GetFirstFile();
- m_localCmdSet->SaveFile(m_fullPathName);
- }
- void COptionsKeyboard::OnNotesRepeat()
- {
- m_localCmdSet->QuickChange_NotesRepeat(true);
- ForceUpdateGUI();
- }
- void COptionsKeyboard::OnNoNotesRepeat()
- {
- m_localCmdSet->QuickChange_NotesRepeat(false);
- ForceUpdateGUI();
- }
- void COptionsKeyboard::ForceUpdateGUI()
- {
- m_forceUpdate = true; // m_nCurKeyChoice and m_nCurHotKey haven't changed, yet we still want to update.
- int ntmpChoice = m_curKeyChoice; // next call will overwrite m_nCurKeyChoice
- OnCommandKeySelChanged(); // update keychoice list
- m_cmbKeyChoice.SetCurSel(ntmpChoice); // select fresh keychoice (thus restoring m_nCurKeyChoice)
- OnKeyChoiceSelect(); // update key data
- OnSettingsChanged(); // Enable "apply" button
- }
- void COptionsKeyboard::OnClearLog()
- {
- m_eReport.SetWindowText(_T(""));
- ForceUpdateGUI();
- }
- void COptionsKeyboard::OnRestoreDefaultKeymap()
- {
- if(Reporting::Confirm("Discard all custom changes and restore default key configuration?", false, true, this) == cnfYes)
- {
- m_localCmdSet->LoadDefaultKeymap();
- ForceUpdateGUI();
- }
- }
- int COptionsKeyboard::GetCategoryFromCommandID(CommandID command) const
- {
- for(size_t cat = 0; cat < commandCategories.size(); cat++)
- {
- const auto &cmds = commandCategories[cat].commands;
- if(mpt::contains(cmds, command))
- return static_cast<int>(cat);
- }
- return -1;
- }
- OPENMPT_NAMESPACE_END
|