From 800f6500ba26b782364cea2d33404ff820b0231b Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 23 Oct 2018 18:13:55 -0400 Subject: [PATCH] No more member definitions of AudacityProject inside Menus.cpp --- src/Menus.cpp | 213 --------------------------------------- src/Menus.h | 3 - src/Project.cpp | 121 ++++++++++++++++++++++ src/Project.h | 1 - src/menus/EditMenus.cpp | 2 - src/menus/TrackMenus.cpp | 82 ++++++++++++++- 6 files changed, 201 insertions(+), 221 deletions(-) diff --git a/src/Menus.cpp b/src/Menus.cpp index f3ebeced1..f546215f9 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -447,10 +447,6 @@ void MenuCreator::RebuildMenuBar(AudacityProject &project) ModuleManager::Get().Dispatch(MenusRebuilt); } -void AudacityProject::RebuildOtherMenus() -{ -} - CommandFlag MenuManager::GetFocusedFrame(AudacityProject &project) { wxWindow *w = wxWindow::FindFocus(); @@ -647,32 +643,6 @@ CommandFlag MenuManager::GetUpdateFlags return flags; } -namespace SelectActions { -void DoSelectSomething(AudacityProject &project); -} - -// Select the full time range, if no -// time range is selected. -void AudacityProject::SelectAllIfNone() -{ - auto flags = GetMenuManager(*this).GetUpdateFlags(*this); - if(!(flags & TracksSelectedFlag) || - (mViewInfo.selectedRegion.isPoint())) - SelectActions::DoSelectSomething(*this); -} - -namespace TransportActions { - void DoStop( AudacityProject & ); -} - -// Stop playing or recording, if paused. -void AudacityProject::StopIfPaused() -{ - auto flags = GetMenuManager(*this).GetUpdateFlags(*this); - if( flags & PausedFlag ) - TransportActions::DoStop(*this); -} - void MenuManager::ModifyAllProjectToolbarMenus() { AProjectArray::iterator i; @@ -837,80 +807,6 @@ void MenuManager::UpdateMenus(AudacityProject &project, bool checkActive) MenuManager::ModifyToolbarMenus(project); } -//sort based on flags. see Project.h for sort flags -void AudacityProject::SortTracks(int flags) -{ - auto GetTime = [](const Track *t) { - return t->TypeSwitch< double >( - [&](const WaveTrack* w) { - auto stime = w->GetEndTime(); - - int ndx; - for (ndx = 0; ndx < w->GetNumClips(); ndx++) { - const auto c = w->GetClipByIndex(ndx); - if (c->GetNumSamples() == 0) - continue; - stime = std::min(stime, c->GetStartTime()); - } - return stime; - }, - [&](const LabelTrack* l) { - return l->GetStartTime(); - } - ); - }; - - size_t ndx = 0; - // This one place outside of TrackList where we must use undisguised - // std::list iterators! Avoid this elsewhere! - std::vector arr; - arr.reserve(mTracks->size()); - - // First find the permutation. - // This routine, very unusually, deals with the underlying stl list - // iterators, not with TrackIter! Dangerous! - for (auto iter = mTracks->ListOfTracks::begin(), - end = mTracks->ListOfTracks::end(); iter != end; ++iter) { - const auto &track = *iter; - if ( !track->IsLeader() ) - // keep channels contiguous - ndx++; - else { - auto size = arr.size(); - for (ndx = 0; ndx < size;) { - Track &arrTrack = **arr[ndx].first; - auto channels = TrackList::Channels(&arrTrack); - if(flags & kAudacitySortByName) { - //do case insensitive sort - cmpNoCase returns less than zero if the string is 'less than' its argument - //also if we have case insensitive equality, then we need to sort by case as well - //We sort 'b' before 'B' accordingly. We uncharacteristically use greater than for the case sensitive - //compare because 'b' is greater than 'B' in ascii. - auto cmpValue = track->GetName().CmpNoCase(arrTrack.GetName()); - if ( cmpValue < 0 || - ( 0 == cmpValue && - track->GetName().CompareTo(arrTrack.GetName()) > 0 ) ) - break; - } - //sort by time otherwise - else if(flags & kAudacitySortByTime) { - auto time1 = TrackList::Channels(track.get()).min( GetTime ); - - //get candidate's (from sorted array) time - auto time2 = channels.min( GetTime ); - - if (time1 < time2) - break; - } - ndx += channels.size(); - } - } - arr.insert(arr.begin() + ndx, TrackNodePointer{iter, mTracks.get()}); - } - - // Now apply the permutation - mTracks->Permute(arr); -} - /// The following method moves to the previous track /// selecting and unselecting depending if you are on the start of a /// block or not. @@ -933,112 +829,3 @@ void MenuCommandHandler::RebuildAllMenuBars() #endif } } - -void AudacityProject::SelectNone() -{ - for (auto t : GetTracks()->Any()) - t->SetSelected(false); - - mTrackPanel->Refresh(false); - if (mMixerBoard) - mMixerBoard->Refresh(false); -} - -// -// View Menu -// - -double AudacityProject::GetScreenEndTime() const -{ - return mTrackPanel->GetScreenEndTime(); -} - -void AudacityProject::ZoomInByFactor( double ZoomFactor ) -{ - // LLL: Handling positioning differently when audio is - // actively playing. Don't do this if paused. - if ((gAudioIO->IsStreamActive(GetAudioIOToken()) != 0) && !gAudioIO->IsPaused()){ - ZoomBy(ZoomFactor); - mTrackPanel->ScrollIntoView(gAudioIO->GetStreamTime()); - mTrackPanel->Refresh(false); - return; - } - - // DMM: Here's my attempt to get logical zooming behavior - // when there's a selection that's currently at least - // partially on-screen - - const double endTime = GetScreenEndTime(); - const double duration = endTime - mViewInfo.h; - - bool selectionIsOnscreen = - (mViewInfo.selectedRegion.t0() < endTime) && - (mViewInfo.selectedRegion.t1() >= mViewInfo.h); - - bool selectionFillsScreen = - (mViewInfo.selectedRegion.t0() < mViewInfo.h) && - (mViewInfo.selectedRegion.t1() > endTime); - - if (selectionIsOnscreen && !selectionFillsScreen) { - // Start with the center of the selection - double selCenter = (mViewInfo.selectedRegion.t0() + - mViewInfo.selectedRegion.t1()) / 2; - - // If the selection center is off-screen, pick the - // center of the part that is on-screen. - if (selCenter < mViewInfo.h) - selCenter = mViewInfo.h + - (mViewInfo.selectedRegion.t1() - mViewInfo.h) / 2; - if (selCenter > endTime) - selCenter = endTime - - (endTime - mViewInfo.selectedRegion.t0()) / 2; - - // Zoom in - ZoomBy(ZoomFactor); - const double newDuration = GetScreenEndTime() - mViewInfo.h; - - // Recenter on selCenter - TP_ScrollWindow(selCenter - newDuration / 2); - return; - } - - - double origLeft = mViewInfo.h; - double origWidth = duration; - ZoomBy(ZoomFactor); - - const double newDuration = GetScreenEndTime() - mViewInfo.h; - double newh = origLeft + (origWidth - newDuration) / 2; - - // MM: Commented this out because it was confusing users - /* - // make sure that the *right-hand* end of the selection is - // no further *left* than 1/3 of the way across the screen - if (mViewInfo.selectedRegion.t1() < newh + mViewInfo.screen / 3) - newh = mViewInfo.selectedRegion.t1() - mViewInfo.screen / 3; - - // make sure that the *left-hand* end of the selection is - // no further *right* than 2/3 of the way across the screen - if (mViewInfo.selectedRegion.t0() > newh + mViewInfo.screen * 2 / 3) - newh = mViewInfo.selectedRegion.t0() - mViewInfo.screen * 2 / 3; - */ - - TP_ScrollWindow(newh); -} - - -void AudacityProject::ZoomOutByFactor( double ZoomFactor ) -{ - //Zoom() may change these, so record original values: - const double origLeft = mViewInfo.h; - const double origWidth = GetScreenEndTime() - origLeft; - - ZoomBy(ZoomFactor); - const double newWidth = GetScreenEndTime() - mViewInfo.h; - - const double newh = origLeft + (origWidth - newWidth) / 2; - // newh = (newh > 0) ? newh : 0; - TP_ScrollWindow(newh); -} - -// diff --git a/src/Menus.h b/src/Menus.h index 49048b8d5..58be8d7c2 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -185,6 +185,3 @@ void DoShowLog( AudacityProject& ); } #endif - - - diff --git a/src/Project.cpp b/src/Project.cpp index 2679ebf31..95ad589fe 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -6245,3 +6245,124 @@ ContrastDialog *AudacityProject::GetContrastDialog(bool create) return mContrastDialog.get(); } + +double AudacityProject::GetScreenEndTime() const +{ + return mTrackPanel->GetScreenEndTime(); +} + +void AudacityProject::SelectNone() +{ + for (auto t : GetTracks()->Any()) + t->SetSelected(false); + + mTrackPanel->Refresh(false); + if (mMixerBoard) + mMixerBoard->Refresh(false); +} + +void AudacityProject::ZoomInByFactor( double ZoomFactor ) +{ + // LLL: Handling positioning differently when audio is + // actively playing. Don't do this if paused. + if ((gAudioIO->IsStreamActive(GetAudioIOToken()) != 0) && + !gAudioIO->IsPaused()){ + ZoomBy(ZoomFactor); + mTrackPanel->ScrollIntoView(gAudioIO->GetStreamTime()); + mTrackPanel->Refresh(false); + return; + } + + // DMM: Here's my attempt to get logical zooming behavior + // when there's a selection that's currently at least + // partially on-screen + + const double endTime = GetScreenEndTime(); + const double duration = endTime - mViewInfo.h; + + bool selectionIsOnscreen = + (mViewInfo.selectedRegion.t0() < endTime) && + (mViewInfo.selectedRegion.t1() >= mViewInfo.h); + + bool selectionFillsScreen = + (mViewInfo.selectedRegion.t0() < mViewInfo.h) && + (mViewInfo.selectedRegion.t1() > endTime); + + if (selectionIsOnscreen && !selectionFillsScreen) { + // Start with the center of the selection + double selCenter = (mViewInfo.selectedRegion.t0() + + mViewInfo.selectedRegion.t1()) / 2; + + // If the selection center is off-screen, pick the + // center of the part that is on-screen. + if (selCenter < mViewInfo.h) + selCenter = mViewInfo.h + + (mViewInfo.selectedRegion.t1() - mViewInfo.h) / 2; + if (selCenter > endTime) + selCenter = endTime - + (endTime - mViewInfo.selectedRegion.t0()) / 2; + + // Zoom in + ZoomBy(ZoomFactor); + const double newDuration = GetScreenEndTime() - mViewInfo.h; + + // Recenter on selCenter + TP_ScrollWindow(selCenter - newDuration / 2); + return; + } + + + double origLeft = mViewInfo.h; + double origWidth = duration; + ZoomBy(ZoomFactor); + + const double newDuration = GetScreenEndTime() - mViewInfo.h; + double newh = origLeft + (origWidth - newDuration) / 2; + + // MM: Commented this out because it was confusing users + /* + // make sure that the *right-hand* end of the selection is + // no further *left* than 1/3 of the way across the screen + if (mViewInfo.selectedRegion.t1() < newh + mViewInfo.screen / 3) + newh = mViewInfo.selectedRegion.t1() - mViewInfo.screen / 3; + + // make sure that the *left-hand* end of the selection is + // no further *right* than 2/3 of the way across the screen + if (mViewInfo.selectedRegion.t0() > newh + mViewInfo.screen * 2 / 3) + newh = mViewInfo.selectedRegion.t0() - mViewInfo.screen * 2 / 3; + */ + + TP_ScrollWindow(newh); +} + +void AudacityProject::ZoomOutByFactor( double ZoomFactor ) +{ + //Zoom() may change these, so record original values: + const double origLeft = mViewInfo.h; + const double origWidth = GetScreenEndTime() - origLeft; + + ZoomBy(ZoomFactor); + const double newWidth = GetScreenEndTime() - mViewInfo.h; + + const double newh = origLeft + (origWidth - newWidth) / 2; + // newh = (newh > 0) ? newh : 0; + TP_ScrollWindow(newh); +} + +// Select the full time range, if no +// time range is selected. +void AudacityProject::SelectAllIfNone() +{ + auto flags = GetMenuManager(*this).GetUpdateFlags(*this); + if(!(flags & TracksSelectedFlag) || + (mViewInfo.selectedRegion.isPoint())) + SelectActions::DoSelectSomething(*this); +} + +// Stop playing or recording, if paused. +void AudacityProject::StopIfPaused() +{ + auto flags = GetMenuManager(*this).GetUpdateFlags(*this); + if( flags & PausedFlag ) + TransportActions::DoStop(*this); +} diff --git a/src/Project.h b/src/Project.h index 32120eae4..a8a6c374a 100644 --- a/src/Project.h +++ b/src/Project.h @@ -375,7 +375,6 @@ public: static void CaptureKeyboard(wxWindow *handler); static void ReleaseKeyboard(wxWindow *handler); - void RebuildOtherMenus(); void MayStartMonitoring(); diff --git a/src/menus/EditMenus.cpp b/src/menus/EditMenus.cpp index e0506cf06..faa7fe23e 100644 --- a/src/menus/EditMenus.cpp +++ b/src/menus/EditMenus.cpp @@ -178,7 +178,6 @@ void DoReloadPreferences( AudacityProject &project ) AudacityProject *p = gAudacityProjects[i].get(); GetMenuManager(*p).RebuildMenuBar(*p); - p->RebuildOtherMenus(); // TODO: The comment below suggests this workaround is obsolete. #if defined(__WXGTK__) // Workaround for: @@ -1030,7 +1029,6 @@ void OnPreferences(const CommandContext &context) AudacityProject *p = gAudacityProjects[i].get(); GetMenuManager(*p).RebuildMenuBar(*p); - p->RebuildOtherMenus(); // TODO: The comment below suggests this workaround is obsolete. #if defined(__WXGTK__) // Workaround for: diff --git a/src/menus/TrackMenus.cpp b/src/menus/TrackMenus.cpp index c81519c52..305816521 100644 --- a/src/menus/TrackMenus.cpp +++ b/src/menus/TrackMenus.cpp @@ -427,6 +427,84 @@ long mixer_process(void *mixer, float **buffer, long n) #endif // EXPERIMENTAL_SCOREALIGN +//sort based on flags. see Project.h for sort flags +void DoSortTracks( AudacityProject &project, int flags ) +{ + auto GetTime = [](const Track *t) { + return t->TypeSwitch< double >( + [&](const WaveTrack* w) { + auto stime = w->GetEndTime(); + + int ndx; + for (ndx = 0; ndx < w->GetNumClips(); ndx++) { + const auto c = w->GetClipByIndex(ndx); + if (c->GetNumSamples() == 0) + continue; + stime = std::min(stime, c->GetStartTime()); + } + return stime; + }, + [&](const LabelTrack* l) { + return l->GetStartTime(); + } + ); + }; + + size_t ndx = 0; + // This one place outside of TrackList where we must use undisguised + // std::list iterators! Avoid this elsewhere! + std::vector arr; + auto pTracks = project.GetTracks(); + arr.reserve(pTracks->size()); + + // First find the permutation. + // This routine, very unusually, deals with the underlying stl list + // iterators, not with TrackIter! Dangerous! + for (auto iter = pTracks->ListOfTracks::begin(), + end = pTracks->ListOfTracks::end(); iter != end; ++iter) { + const auto &track = *iter; + if ( !track->IsLeader() ) + // keep channels contiguous + ndx++; + else { + auto size = arr.size(); + for (ndx = 0; ndx < size;) { + Track &arrTrack = **arr[ndx].first; + auto channels = TrackList::Channels(&arrTrack); + if(flags & kAudacitySortByName) { + //do case insensitive sort - cmpNoCase returns less than zero if + // the string is 'less than' its argument + //also if we have case insensitive equality, then we need to sort + // by case as well + //We sort 'b' before 'B' accordingly. We uncharacteristically + // use greater than for the case sensitive + //compare because 'b' is greater than 'B' in ascii. + auto cmpValue = track->GetName().CmpNoCase(arrTrack.GetName()); + if ( cmpValue < 0 || + ( 0 == cmpValue && + track->GetName().CompareTo(arrTrack.GetName()) > 0 ) ) + break; + } + //sort by time otherwise + else if(flags & kAudacitySortByTime) { + auto time1 = TrackList::Channels(track.get()).min( GetTime ); + + //get candidate's (from sorted array) time + auto time2 = channels.min( GetTime ); + + if (time1 < time2) + break; + } + ndx += channels.size(); + } + } + arr.insert(arr.begin() + ndx, TrackNodePointer{iter, pTracks}); + } + + // Now apply the permutation + pTracks->Permute(arr); +} + } namespace TrackActions { @@ -989,7 +1067,7 @@ void OnScoreAlign(const CommandContext &context) void OnSortTime(const CommandContext &context) { auto &project = context.project; - project.SortTracks(kAudacitySortByTime); + DoSortTracks(project, kAudacitySortByTime); project.PushState(_("Tracks sorted by time"), _("Sort by Time")); @@ -1000,7 +1078,7 @@ void OnSortTime(const CommandContext &context) void OnSortName(const CommandContext &context) { auto &project = context.project; - project.SortTracks(kAudacitySortByName); + DoSortTracks(project, kAudacitySortByName); project.PushState(_("Tracks sorted by name"), _("Sort by Name"));