mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-25 17:08:07 +02:00
Add support for zooming to show all notes, separate from max zoom
This is now the behavior of Zoom Reset, with Max Zoom being given the previous behavior. Shift+Right-Click alternates between the two -- it zooms to all notes, unless it currently is zoomed to all notes in which case it performs a max zoom. This fixes Bug 2093. It also fixes Bug 1815, by performing the all-notes zoom when importing a track.
This commit is contained in:
parent
567b3972b8
commit
99f4c35e18
@ -1047,6 +1047,37 @@ void NoteTrack::ZoomTo(const wxRect &rect, int start, int end)
|
||||
SetNoteRange(pitch1, pitch2);
|
||||
}
|
||||
|
||||
void NoteTrack::ZoomAllNotes()
|
||||
{
|
||||
Alg_iterator iterator( &GetSeq(), false );
|
||||
iterator.begin();
|
||||
Alg_event_ptr evt;
|
||||
|
||||
// Go through all of the notes, finding the minimum and maximum value pitches.
|
||||
bool hasNotes = false;
|
||||
int minPitch = MaxPitch;
|
||||
int maxPitch = MinPitch;
|
||||
|
||||
while (NULL != (evt = iterator.next())) {
|
||||
if (evt->is_note()) {
|
||||
int pitch = (int) evt->get_pitch();
|
||||
hasNotes = true;
|
||||
if (pitch < minPitch)
|
||||
minPitch = pitch;
|
||||
if (pitch > maxPitch)
|
||||
maxPitch = pitch;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasNotes) {
|
||||
// Semi-arbitary default values:
|
||||
minPitch = 48;
|
||||
maxPitch = 72;
|
||||
}
|
||||
|
||||
SetNoteRange(minPitch, maxPitch);
|
||||
}
|
||||
|
||||
NoteTrackDisplayData::NoteTrackDisplayData(const NoteTrack* track, const wxRect &r)
|
||||
{
|
||||
auto span = track->GetTopNote() - track->GetBottomNote() + 1; // + 1 to make sure it includes both
|
||||
|
@ -131,6 +131,8 @@ class AUDACITY_DLL_API NoteTrack final
|
||||
/// Sets the top and bottom note (both pitches) automatically, swapping them if needed.
|
||||
void SetNoteRange(int note1, int note2);
|
||||
|
||||
/// Zooms so that all notes are visible
|
||||
void ZoomAllNotes();
|
||||
/// Zooms so that the entire track is visible
|
||||
void ZoomMaxExtent() { SetNoteRange(MinPitch, MaxPitch); }
|
||||
/// Shifts all notes vertically by the given pitch
|
||||
|
@ -69,27 +69,8 @@ bool ImportMIDI(const FilePath &fName, NoteTrack * dest)
|
||||
wxString trackNameBase = fName.AfterLast(wxFILE_SEP_PATH).BeforeLast('.');
|
||||
dest->SetName(trackNameBase);
|
||||
mf.Close();
|
||||
// the mean pitch should be somewhere in the middle of the display
|
||||
Alg_iterator iterator( &dest->GetSeq(), false );
|
||||
iterator.begin();
|
||||
// for every event
|
||||
Alg_event_ptr evt;
|
||||
int note_count = 0;
|
||||
int pitch_sum = 0;
|
||||
while (NULL != (evt = iterator.next())) {
|
||||
// if the event is a note
|
||||
if (evt->get_type() == 'n') {
|
||||
Alg_note_ptr note = (Alg_note_ptr) evt;
|
||||
pitch_sum += (int) note->pitch;
|
||||
note_count++;
|
||||
}
|
||||
}
|
||||
int mean_pitch = (note_count > 0 ? pitch_sum / note_count : 60);
|
||||
// initial track is about 27 half-steps high; if bottom note is C,
|
||||
// then middle pitch class is D. Round mean_pitch to the nearest D:
|
||||
int mid_pitch = ((mean_pitch - 2 + 6) / 12) * 12 + 2;
|
||||
dest->SetBottomNote(mid_pitch - 14);
|
||||
dest->SetTopNote(mid_pitch + 13);
|
||||
|
||||
dest->ZoomAllNotes();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -147,6 +147,7 @@ HitTestPreview NoteTrackVZoomHandle::Preview
|
||||
const int kZoomIn = 6;
|
||||
const int kZoomOut = 7;
|
||||
const int kZoomReset = 8;
|
||||
const int kZoomMax = 9;
|
||||
|
||||
enum {
|
||||
OnZoomFitVerticalID = 20000,
|
||||
@ -164,6 +165,8 @@ enum {
|
||||
// Reserve an ample block of ids for spectrum scale types
|
||||
OnFirstSpectrumScaleID,
|
||||
OnLastSpectrumScaleID = OnFirstSpectrumScaleID + 19,
|
||||
|
||||
OnZoomMaxID,
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Table class
|
||||
@ -187,6 +190,7 @@ protected:
|
||||
// void OnZoomHalfWave(wxCommandEvent&){ OnZoom( kZoomHalfWave );};
|
||||
void OnZoomInVertical(wxCommandEvent&){ OnZoom( kZoomIn );};
|
||||
void OnZoomOutVertical(wxCommandEvent&){ OnZoom( kZoomOut );};
|
||||
void OnZoomMax(wxCommandEvent&){ OnZoom( kZoomMax );};
|
||||
|
||||
private:
|
||||
void DestroyMenu() override
|
||||
@ -211,7 +215,7 @@ void NoteTrackVRulerMenuTable::InitMenu(Menu *WXUNUSED(pMenu), void *pUserData)
|
||||
void NoteTrackVRulerMenuTable::OnZoom( int iZoomCode ){
|
||||
switch( iZoomCode ){
|
||||
case kZoomReset:
|
||||
mpData->pTrack->ZoomMaxExtent();
|
||||
mpData->pTrack->ZoomAllNotes();
|
||||
break;
|
||||
case kZoomIn:
|
||||
mpData->pTrack->ZoomIn(mpData->rect, mpData->yy);
|
||||
@ -219,7 +223,9 @@ void NoteTrackVRulerMenuTable::OnZoom( int iZoomCode ){
|
||||
case kZoomOut:
|
||||
mpData->pTrack->ZoomOut(mpData->rect, mpData->yy);
|
||||
break;
|
||||
|
||||
case kZoomMax:
|
||||
mpData->pTrack->ZoomMaxExtent();
|
||||
break;
|
||||
}
|
||||
GetActiveProject()->ModifyState(false);
|
||||
}
|
||||
@ -228,6 +234,7 @@ void NoteTrackVRulerMenuTable::OnZoom( int iZoomCode ){
|
||||
BEGIN_POPUP_MENU(NoteTrackVRulerMenuTable)
|
||||
|
||||
POPUP_MENU_ITEM(OnZoomResetID, _("Zoom Reset\tShift-Right-Click"), OnZoomReset)
|
||||
POPUP_MENU_ITEM(OnZoomMaxID, _("Max Zoom"), OnZoomMax)
|
||||
|
||||
POPUP_MENU_SEPARATOR()
|
||||
POPUP_MENU_ITEM(OnZoomInVerticalID, _("Zoom In\tLeft-Click/Left-Drag"), OnZoomInVertical)
|
||||
@ -296,8 +303,15 @@ UIHandle::Result NoteTrackVZoomHandle::Release
|
||||
}
|
||||
else if (event.ShiftDown() || event.RightUp()) {
|
||||
if (event.ShiftDown() && event.RightUp()) {
|
||||
// Zoom out completely
|
||||
pTrack->ZoomMaxExtent();
|
||||
auto oldBotNote = pTrack->GetBottomNote();
|
||||
auto oldTopNote = pTrack->GetTopNote();
|
||||
// Zoom out to show all notes
|
||||
pTrack->ZoomAllNotes();
|
||||
if (pTrack->GetBottomNote() == oldBotNote &&
|
||||
pTrack->GetTopNote() == oldTopNote) {
|
||||
// However if we are already showing all notes, zoom out further
|
||||
pTrack->ZoomMaxExtent();
|
||||
}
|
||||
} else {
|
||||
// Zoom out
|
||||
pTrack->ZoomOut(evt.rect, mZoomEnd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user