From: <sv...@op...> - 2024-12-23 16:50:08
|
Author: sagamusix Date: Mon Dec 23 17:49:54 2024 New Revision: 22605 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=22605 Log: [Imp] Sample tab: Cue preview shortcuts now set the cue point if it's currently unused and the sample is playing (https://bugs.openmpt.org/view.php?id=1852). Modified: trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/View_smp.h Modified: trunk/OpenMPT/mptrack/View_smp.cpp ============================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp Mon Dec 23 13:57:57 2024 (r22604) +++ trunk/OpenMPT/mptrack/View_smp.cpp Mon Dec 23 17:49:54 2024 (r22605) @@ -1384,30 +1384,10 @@ if(m_nZoom != 0 && TrackerSettings::Instance().m_followSamplePlayCursor != FollowSamplePlayCursor::DoNotFollow) { // Scroll sample into view if it's not in the visible range - size_t count = 0; - SmpLength scrollToPos = 0; - bool backwards = false; - const auto &playChns = GetDocument()->GetSoundFile().m_PlayState.Chn; - for(CHANNELINDEX chn = 0; chn < MAX_CHANNELS; chn++) - { - if(m_dwNotifyPos[chn] == Notification::PosInvalid) - continue; - - // Only update based on notes triggered by this view - if(!playChns[chn].isPreviewNote) - continue; - if(!ModCommand::IsNote(playChns[chn].nNewNote) || m_noteChannel[playChns[chn].nNewNote - NOTE_MIN] != chn) - continue; - - count++; - if(count > 1) - break; - - scrollToPos = m_dwNotifyPos[chn]; - backwards = playChns[chn].dwFlags[CHN_PINGPONGFLAG]; - } - if(count == 1) + const CHANNELINDEX previewChannel = GetPreviewChannel(); + if(previewChannel != CHANNELINDEX_INVALID) { + const SmpLength scrollToPos = m_dwNotifyPos[previewChannel]; const auto screenPos = SampleToScreen(scrollToPos); const bool alwaysCenter = (TrackerSettings::Instance().m_followSamplePlayCursor == FollowSamplePlayCursor::FollowCentered); if(alwaysCenter || screenPos < m_rcClient.left || screenPos >= m_rcClient.right) @@ -1415,7 +1395,7 @@ ScrollTarget target = ScrollTarget::Left; if(alwaysCenter) target = ScrollTarget::Center; - else if(backwards) + else if(GetDocument()->GetSoundFile().m_PlayState.Chn[previewChannel].dwFlags[CHN_PINGPONGFLAG]) // TODO: this should be taken via notification, not directly from player state target = ScrollTarget::Right; ScrollToSample(scrollToPos, true, target); } @@ -1431,6 +1411,31 @@ } +CHANNELINDEX CViewSample::GetPreviewChannel() const +{ + size_t count = 0; + CHANNELINDEX channel = CHANNELINDEX_INVALID; + const auto &playChns = GetDocument()->GetSoundFile().m_PlayState.Chn; + for(CHANNELINDEX chn = 0; chn < MAX_CHANNELS; chn++) + { + if(m_dwNotifyPos[chn] == Notification::PosInvalid) + continue; + + // Only update based on notes triggered by this view + if(!playChns[chn].isPreviewNote) + continue; + if(!ModCommand::IsNote(playChns[chn].nNewNote) || m_noteChannel[playChns[chn].nNewNote - NOTE_MIN] != chn) + continue; + + count++; + if(count > 1) + return CHANNELINDEX_INVALID; + channel = chn; + } + return channel; +} + + bool CViewSample::GetNcButtonRect(UINT button, CRect &rect) const { rect.left = 4; @@ -3849,10 +3854,7 @@ } } else if(wParam >= kcStartSampleCues && wParam <= kcEndSampleCues) { - const ModSample &sample = sndFile.GetSample(m_nSample); - SmpLength offset = sample.cues[wParam - kcStartSampleCues]; - if(offset < sample.nLength) - PlayNote(NOTE_MIDDLEC, offset); + PlayOrSetCuePoint(wParam - kcStartSampleCues); return wParam; } @@ -3861,6 +3863,29 @@ } +void CViewSample::PlayOrSetCuePoint(size_t cue) +{ + CModDoc *modDoc = GetDocument(); + if(modDoc == nullptr) + return; + CSoundFile &sndFile = modDoc->GetSoundFile(); + ModSample &sample = sndFile.GetSample(m_nSample); + SmpLength offset = sample.cues[cue]; + if(offset < sample.nLength) + { + PlayNote(NOTE_MIDDLEC, offset); + return; + } + + const CHANNELINDEX previewChannel = GetPreviewChannel(); + if(previewChannel == CHANNELINDEX_INVALID) + return; + modDoc->GetSampleUndo().PrepareUndo(m_nSample, sundo_none, "Set Cue Point"); + sample.cues[cue] = m_dwNotifyPos[previewChannel]; + SetModified(SampleHint().Info(), true, false); +} + + void CViewSample::OnSampleSlice() { CModDoc *modDoc = GetDocument(); Modified: trunk/OpenMPT/mptrack/View_smp.h ============================================================================== --- trunk/OpenMPT/mptrack/View_smp.h Mon Dec 23 13:57:57 2024 (r22604) +++ trunk/OpenMPT/mptrack/View_smp.h Mon Dec 23 17:49:54 2024 (r22605) @@ -157,6 +157,11 @@ SmpLength SnapToGrid(const SmpLength pos) const; + // Returns index of preview channel if exactly one one is being previewed, CHANNELINDEX_INVALID otherwise. + CHANNELINDEX GetPreviewChannel() const; + + void PlayOrSetCuePoint(size_t cue); + public: //{{AFX_VIRTUAL(CViewSample) void OnDraw(CDC *) override; |