Skip to content

Commit

Permalink
Merged revision(s) 22605 from trunk/OpenMPT:
Browse files Browse the repository at this point in the history
[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).
........


git-svn-id: https://source.openmpt.org/svn/openmpt/branches/OpenMPT-1.31@22606 56274372-70c3-4bfc-bfc3-4c3a0b034d27
  • Loading branch information
sagamusix committed Dec 23, 2024
1 parent 2d3da77 commit 360a9b1
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 28 deletions.
81 changes: 53 additions & 28 deletions mptrack/View_smp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1394,38 +1394,18 @@ LRESULT CViewSample::OnPlayerNotify(Notification *pnotify)
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)
{
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);
}
Expand All @@ -1441,6 +1421,31 @@ LRESULT CViewSample::OnPlayerNotify(Notification *pnotify)
}


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;
Expand Down Expand Up @@ -3853,10 +3858,7 @@ LRESULT CViewSample::OnCustomKeyMsg(WPARAM wParam, LPARAM lParam)
}
} 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;
}

Expand All @@ -3865,6 +3867,29 @@ LRESULT CViewSample::OnCustomKeyMsg(WPARAM wParam, LPARAM lParam)
}


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();
Expand Down
5 changes: 5 additions & 0 deletions mptrack/View_smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ class CViewSample: public CModScrollView

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;
Expand Down

0 comments on commit 360a9b1

Please sign in to comment.