From 54e863259c128c878217f685eb9312956f3b0db8 Mon Sep 17 00:00:00 2001 From: Johannes Schultz Date: Tue, 31 Dec 2024 21:14:16 +0000 Subject: [PATCH] [New] Pattern tab: Added keyboard shortcuts for toggling various MIDI recording options (https://bugs.openmpt.org/view.php?id=500). [Imp] Pattern tab: Toggle shortcuts (existing and new ones) now show the new toggle status in the status bar (https://bugs.openmpt.org/view.php?id=500). git-svn-id: https://source.openmpt.org/svn/openmpt/trunk/OpenMPT@22667 56274372-70c3-4bfc-bfc3-4c3a0b034d27 --- mptrack/CommandSet.cpp | 8 +++++- mptrack/CommandSet.h | 8 +++++- mptrack/View_pat.cpp | 55 +++++++++++++++++++++++++++--------------- mptrack/View_pat.h | 8 +++--- 4 files changed, 55 insertions(+), 24 deletions(-) diff --git a/mptrack/CommandSet.cpp b/mptrack/CommandSet.cpp index ba9b5f2875f..d93f53fb9f2 100644 --- a/mptrack/CommandSet.cpp +++ b/mptrack/CommandSet.cpp @@ -937,6 +937,12 @@ static constexpr struct {2110, kcSetVolumeD, _T("Set volume digit D")}, {2111, kcSetVolumeE, _T("Set volume digit E")}, {2112, kcSetVolumeF, _T("Set volume digit F")}, + {2113, kcToggleOctaveTransposeMIDI, _T("Toggle Apply Octave Transpose to incoming MIDI Notes")}, + {2114, kcToggleContinueSongOnMIDINote, _T("Toggle Continue Song when MIDI Note is received")}, + {2115, kcToggleContinueSongOnMIDIPlayEvents, _T("Toggle Respond to Play / Continue / Stop Song MIDI messages")}, + {2116, kcToggleRecordMIDIVelocity, _T("Toggle Record MIDI Velocity")}, + {2117, kcToggleRecordMIDIPitchBend, _T("Toggle Record MIDI Pitch Bend")}, + {2118, kcToggleRecordMIDICCs, _T("Toggle Record MIDI CCs")}, }; // clang-format on @@ -951,7 +957,7 @@ void CCommandSet::SetupCommands() for(int j = kcStartSampleCues; j <= kcEndSampleCues; j++) { - CString s = MPT_CFORMAT("Preview Sample Cue {}")(j - kcStartSampleCues + 1); + CString s = MPT_CFORMAT("Preview / Set Sample Cue {}")(j - kcStartSampleCues + 1); m_commands[j] = {static_cast(1924 + j - kcStartSampleCues), s}; } static_assert(1924 + kcEndSampleCues - kcStartSampleCues < 1950); diff --git a/mptrack/CommandSet.h b/mptrack/CommandSet.h index b375cf05d09..cfaef27c25a 100644 --- a/mptrack/CommandSet.h +++ b/mptrack/CommandSet.h @@ -65,7 +65,7 @@ enum KeyEventType : int8 DECLARE_FLAGSET(KeyEventType) -enum CommandID +enum CommandID : int { kcCommandSetNumNotes = 59, // kcVPEndNotes - kcVPStartNotes @@ -341,6 +341,12 @@ enum CommandID kcToggleOverflowPaste, kcToggleNoteOffRecordPC, kcToggleNoteOffRecordMIDI, + kcToggleOctaveTransposeMIDI, + kcToggleContinueSongOnMIDINote, + kcToggleContinueSongOnMIDIPlayEvents, + kcToggleRecordMIDIVelocity, + kcToggleRecordMIDIPitchBend, + kcToggleRecordMIDICCs, kcToggleVisibilityInstrColumn, kcToggleVisibilityVolumeColumn, kcToggleVisibilityEffectColumn, diff --git a/mptrack/View_pat.cpp b/mptrack/View_pat.cpp index f37e9e6dc24..bbc006463c6 100644 --- a/mptrack/View_pat.cpp +++ b/mptrack/View_pat.cpp @@ -186,7 +186,6 @@ void CViewPattern::OnInitialUpdate() m_nXScroll = m_nYScroll = 0; m_nPattern = 0; m_nSpacing = 0; - m_nAccelChar = 0; PatternFont::UpdateFont(m_hWnd); UpdateSizes(); UpdateScrollSize(); @@ -1864,7 +1863,7 @@ void CViewPattern::OnSoloFromClick() // When trying to solo a channel that is already the only unmuted channel, // this will result in unmuting all channels, in order to satisfy user habits. -// In all other cases, soloing a channel unsoloes all and mutes all except this channel +// In all other cases, soloing a channel unsolos all and mutes all except this channel void CViewPattern::OnSoloChannel(CHANNELINDEX first, CHANNELINDEX last) { CModDoc *pModDoc = GetDocument(); @@ -4226,7 +4225,7 @@ LRESULT CViewPattern::OnModViewMsg(WPARAM wParam, LPARAM lParam) break; case VIEWMSG_SETSPACING: - m_nSpacing = static_cast(lParam); + m_nSpacing = static_cast(lParam); break; case VIEWMSG_PATTERNPROPERTIES: @@ -4378,6 +4377,18 @@ void CViewPattern::CursorJump(int distance, bool snap) } +static void ToggleFlag(CachedSetting &flagSet, uint32 flag, const TCHAR *description) +{ + flagSet ^= flag; + CString text = description; + if(flagSet & flag) + text += _T(" is now On"); + else + text += _T(" is now Off"); + CMainFrame::GetMainFrame()->SetHelpText(text); +} + + LRESULT CViewPattern::OnCustomKeyMsg(WPARAM wParam, LPARAM lParam) { CModDoc *pModDoc = GetDocument(); @@ -4744,10 +4755,16 @@ LRESULT CViewPattern::OnCustomKeyMsg(WPARAM wParam, LPARAM lParam) case kcDuplicatePattern: SendCtrlMessage(CTRLMSG_PAT_DUPPATTERN); return wParam; case kcSwitchToOrderList: OnSwitchToOrderList(); return wParam; - case kcToggleOverflowPaste: TrackerSettings::Instance().m_dwPatternSetup ^= PATTERN_OVERFLOWPASTE; return wParam; - case kcToggleNoteOffRecordPC: TrackerSettings::Instance().m_dwPatternSetup ^= PATTERN_KBDNOTEOFF; return wParam; - case kcToggleNoteOffRecordMIDI: TrackerSettings::Instance().m_dwMidiSetup ^= MIDISETUP_RECORDNOTEOFF; return wParam; - + case kcToggleOverflowPaste: ToggleFlag(TrackerSettings::Instance().m_dwPatternSetup, PATTERN_OVERFLOWPASTE, _T("Overflow Paste")); return wParam; + case kcToggleNoteOffRecordPC: ToggleFlag(TrackerSettings::Instance().m_dwPatternSetup, PATTERN_KBDNOTEOFF, _T("Record Note Off")); return wParam; + case kcToggleNoteOffRecordMIDI: ToggleFlag(TrackerSettings::Instance().m_dwMidiSetup, MIDISETUP_RECORDNOTEOFF, _T("Record MIDI Note Off")); return wParam; + case kcToggleOctaveTransposeMIDI: ToggleFlag(TrackerSettings::Instance().m_dwMidiSetup, MIDISETUP_TRANSPOSEKEYBOARD, _T("Apply Octave Transpose")); return wParam; + case kcToggleContinueSongOnMIDINote: ToggleFlag(TrackerSettings::Instance().m_dwMidiSetup, MIDISETUP_PLAYPATTERNONMIDIIN, _T("Continue Song when MIDI Note is received")); return wParam; + case kcToggleContinueSongOnMIDIPlayEvents: ToggleFlag(TrackerSettings::Instance().m_dwMidiSetup, MIDISETUP_RESPONDTOPLAYCONTROLMSGS, _T("Respond to Play / Continue Song MIDI messages")); return wParam; + case kcToggleRecordMIDIVelocity: ToggleFlag(TrackerSettings::Instance().m_dwMidiSetup, MIDISETUP_RECORDVELOCITY, _T("Record MIDI Velocity")); return wParam; + case kcToggleRecordMIDIPitchBend: ToggleFlag(TrackerSettings::Instance().m_dwMidiSetup, MIDISETUP_MIDIMACROPITCHBEND, _T("Record MIDI Pitch Bend")); return wParam; + case kcToggleRecordMIDICCs: ToggleFlag(TrackerSettings::Instance().m_dwMidiSetup, MIDISETUP_MIDIMACROCONTROL, _T("Record MIDI CCs")); return wParam; + case kcToggleVisibilityInstrColumn: UpdateVisibileColumns(m_visibleColumns.flip(PatternCursor::instrColumn)); return wParam; case kcToggleVisibilityVolumeColumn: UpdateVisibileColumns(m_visibleColumns.flip(PatternCursor::volumeColumn)); return wParam; case kcToggleVisibilityEffectColumn : UpdateVisibileColumns(m_visibleColumns.flip(PatternCursor::effectColumn)); return wParam; @@ -4871,7 +4888,7 @@ LRESULT CViewPattern::OnCustomKeyMsg(WPARAM wParam, LPARAM lParam) if(wParam >= kcSetSpacing0 && wParam <= kcSetSpacing9) { - SetSpacing(static_cast(wParam) - kcSetSpacing0); + SetSpacing(static_cast(wParam - kcSetSpacing0)); return wParam; } @@ -4898,7 +4915,7 @@ LRESULT CViewPattern::OnCustomKeyMsg(WPARAM wParam, LPARAM lParam) if(wParam >= kcSetVolumeStart && wParam <= kcSetVolumeEnd) { if(IsEditingEnabled_bmsg()) - TempEnterVol(static_cast(wParam) - kcSetVolumeStart); + TempEnterVol(static_cast(wParam)); return wParam; } @@ -4979,7 +4996,7 @@ static bool EnterPCNoteValue(int v, ModCommand &m, uint16 (ModCommand::*getMetho // Enter volume effect / number in the pattern. -void CViewPattern::TempEnterVol(int v) +void CViewPattern::TempEnterVol(CommandID cmd) { CSoundFile *pSndFile = GetSoundFile(); @@ -4989,7 +5006,8 @@ void CViewPattern::TempEnterVol(int v) ModCommand &target = GetCursorCommand(); ModCommand m = target; // This is the command we are about to overwrite const bool isHex = TrackerSettings::Instance().patternVolColHex; - const bool isDigit = (v >= 0x00) && (v <= 0x0F); + const bool isDigit = (cmd >= kcStartVolumeDigits) && (cmd <= kcEndVolumeDigits); + const int v = static_cast(cmd) - kcStartVolumeDigits; if(m.IsPcNote()) { @@ -5009,7 +5027,7 @@ void CViewPattern::TempEnterVol(int v) volcmd = VOLCMD_VOLUME; } else { - switch(v + kcSetVolumeStart) + switch(cmd) { case kcSetVolumeVol: volcmd = VOLCMD_VOLUME; break; case kcSetVolumePan: volcmd = VOLCMD_PANNING; break; @@ -5025,6 +5043,8 @@ void CViewPattern::TempEnterVol(int v) case kcSetVolumeITPortaUp: volcmd = VOLCMD_PORTAUP; break; case kcSetVolumeITPortaDown: volcmd = VOLCMD_PORTADOWN; break; case kcSetVolumeITOffset: volcmd = VOLCMD_OFFSET; break; + default: + break; } if(m.volcmd == VOLCMD_NONE && volcmd == m_cmdOld.volcmd) { @@ -5078,11 +5098,11 @@ void CViewPattern::TempEnterVol(int v) } -void CViewPattern::SetSpacing(int n) +void CViewPattern::SetSpacing(uint32 n) { - if(static_cast(n) != m_nSpacing) + if(n != m_nSpacing) { - m_nSpacing = static_cast(n); + m_nSpacing = n; PostCtrlMessage(CTRLMSG_SETSPACING, m_nSpacing); } } @@ -5092,11 +5112,8 @@ void CViewPattern::SetSpacing(int n) void CViewPattern::TempEnterFX(ModCommand::COMMAND c, int v) { CSoundFile *pSndFile = GetSoundFile(); - if(pSndFile == nullptr || !IsEditingEnabled_bmsg()) - { return; - } ModCommand &target = GetCursorCommand(); ModCommand m = target; @@ -5154,7 +5171,7 @@ void CViewPattern::TempEnterFX(ModCommand::COMMAND c, int v) } -// Enter an effect param in the pattenr +// Enter an effect param in the pattern void CViewPattern::TempEnterFXparam(int v) { CSoundFile *pSndFile = GetSoundFile(); diff --git a/mptrack/View_pat.h b/mptrack/View_pat.h index 1b2b2c490cf..c3cee5e8d0c 100644 --- a/mptrack/View_pat.h +++ b/mptrack/View_pat.h @@ -23,6 +23,8 @@ OPENMPT_NAMESPACE_BEGIN +enum CommandID : int; + class CModDoc; class CEditCommand; class CEffectVis; @@ -118,7 +120,7 @@ class CViewPattern final : public CModScrollView CEditCommand *m_pEditWnd = nullptr; CSize m_szHeader, m_szPluginHeader, m_szCell; CRect m_oldClient; - UINT m_nMidRow, m_nSpacing, m_nAccelChar, m_nLastPlayedRow, m_nLastPlayedOrder; + uint32 m_nMidRow, m_nSpacing, m_nLastPlayedRow, m_nLastPlayedOrder; FlagSet m_Status; ROWINDEX m_nPlayRow, m_nNextPlayRow; uint32 m_nPlayTick, m_nTicksOnRow; @@ -312,7 +314,7 @@ class CViewPattern final : public CModScrollView void TempEnterIns(int val); void TempEnterOctave(int val); void TempStopOctave(int val); - void TempEnterVol(int v); + void TempEnterVol(CommandID cmd); void TempEnterFX(ModCommand::COMMAND c, int v = -1); void TempEnterFXparam(int v); void EnterAftertouch(ModCommand::NOTE note, int atValue); @@ -328,7 +330,7 @@ class CViewPattern final : public CModScrollView PATTERNINDEX GetPrevPattern() const; PATTERNINDEX GetNextPattern() const; - void SetSpacing(int n); + void SetSpacing(uint32 n); void OnClearField(const std::bitset mask, bool step, bool ITStyle = false); void SetSelectionInstrument(const INSTRUMENTINDEX instr, bool setEmptyInstrument);