diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index d1d743344..d13ce2a97 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -84,6 +84,7 @@ It handles initialization and termination by subclassing wxApp. #include "PluginManager.h" #include "Project.h" #include "ProjectAudioIO.h" +#include "ProjectAudioManager.h" #include "ProjectFileManager.h" #include "ProjectHistory.h" #include "ProjectManager.h" diff --git a/src/BatchCommands.cpp b/src/BatchCommands.cpp index 6d86daccf..6f8eeee4f 100644 --- a/src/BatchCommands.cpp +++ b/src/BatchCommands.cpp @@ -25,6 +25,7 @@ processing. See also MacrosWindow and ApplyMacroDialog. #include #include "Project.h" +#include "ProjectAudioManager.h" #include "ProjectHistory.h" #include "ProjectSettings.h" #include "ProjectWindow.h" diff --git a/src/CommonCommandFlags.cpp b/src/CommonCommandFlags.cpp index e8f027c84..32ce3b3af 100644 --- a/src/CommonCommandFlags.cpp +++ b/src/CommonCommandFlags.cpp @@ -21,6 +21,7 @@ Paul Licameli split from Menus.cpp #include "NoteTrack.h" #include "Project.h" #include "ProjectAudioIO.h" +#include "ProjectAudioManager.h" #include "ProjectFileIO.h" #include "ProjectHistory.h" #include "ProjectSettings.h" diff --git a/src/Menus.h b/src/Menus.h index 97d42d615..18c44e941 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -100,21 +100,4 @@ public: bool mStopIfWasPaused; }; - -// Exported helper functions from various menu handling source files - - -/// Namespace for functions for Transport menu -namespace TransportActions { -void StopIfPaused( AudacityProject &project ); -bool DoPlayStopSelect( AudacityProject &project, bool click, bool shift ); -void DoPlayStopSelect( AudacityProject &project ); -void DoStop( AudacityProject & ); -void DoPause( AudacityProject & ); -void DoLockPlayRegion( AudacityProject & ); -void DoUnlockPlayRegion( AudacityProject & ); -void DoTogglePinnedHead( AudacityProject & ); -void DoRecord( AudacityProject & ); -} - #endif diff --git a/src/ProjectAudioManager.cpp b/src/ProjectAudioManager.cpp index 59694108a..050a71b1c 100644 --- a/src/ProjectAudioManager.cpp +++ b/src/ProjectAudioManager.cpp @@ -224,3 +224,171 @@ DefaultSpeedPlayOptions( AudacityProject &project ) options.listener = ProjectAudioManager::Get( project ).shared_from_this(); return options; } + +#include "AdornedRulerPanel.h" +#include "Menus.h" +#include "ViewInfo.h" +#include "prefs/TracksPrefs.h" +#include "tracks/ui/Scrubbing.h" +#include "widgets/AudacityMessageBox.h" + +namespace TransportActions { + +// exported helper functions + +// Stop playing or recording, if paused. +void StopIfPaused( AudacityProject &project ) +{ + if( AudioIOBase::Get()->IsPaused() ) + DoStop( project ); +} + +bool DoPlayStopSelect +(AudacityProject &project, bool click, bool shift) +{ + auto &toolbar = ControlToolBar::Get( project ); + auto &scrubber = Scrubber::Get( project ); + auto token = ProjectAudioIO::Get( project ).GetAudioIOToken(); + auto &viewInfo = ViewInfo::Get( project ); + auto &selection = viewInfo.selectedRegion; + auto gAudioIO = AudioIOBase::Get(); + + //If busy, stop playing, make sure everything is unpaused. + if (scrubber.HasMark() || + gAudioIO->IsStreamActive(token)) { + toolbar.SetPlay(false); //Pops + toolbar.SetStop(true); //Pushes stop down + + // change the selection + auto time = gAudioIO->GetStreamTime(); + // Test WasSpeedPlaying(), not IsSpeedPlaying() + // as we could be stopped now. + if (click && scrubber.WasSpeedPlaying()) + { + ;// don't change the selection. + } + else if (shift && click) { + // Change the region selection, as if by shift-click at the play head + auto t0 = selection.t0(), t1 = selection.t1(); + if (time < t0) + // Grow selection + t0 = time; + else if (time > t1) + // Grow selection + t1 = time; + else { + // Shrink selection, changing the nearer boundary + if (fabs(t0 - time) < fabs(t1 - time)) + t0 = time; + else + t1 = time; + } + selection.setTimes(t0, t1); + } + else if (click){ + // avoid a point at negative time. + time = wxMax( time, 0 ); + // Set a point selection, as if by a click at the play head + selection.setTimes(time, time); + } else + // How stop and set cursor always worked + // -- change t0, collapsing to point only if t1 was greater + selection.setT0(time, false); + + ProjectHistory::Get( project ).ModifyState(false); // without bWantsAutoSave + return true; + } + return false; +} + +// The code for "OnPlayStopSelect" is simply the code of "OnPlayStop" and +// "OnStopSelect" merged. +void DoPlayStopSelect(AudacityProject &project) +{ + auto &toolbar = ControlToolBar::Get( project ); + wxCommandEvent evt; + auto gAudioIO = AudioIO::Get(); + if (DoPlayStopSelect(project, false, false)) + toolbar.OnStop(evt); + else if (!gAudioIO->IsBusy()) { + //Otherwise, start playing (assuming audio I/O isn't busy) + //toolbar->SetPlay(true); // Not needed as set in PlayPlayRegion() + toolbar.SetStop(false); + + // Will automatically set mLastPlayMode + toolbar.PlayCurrentRegion(false); + } +} + +void DoPause( AudacityProject &project ) +{ + wxCommandEvent evt; + + auto &controlToolBar = ControlToolBar::Get( project ); + controlToolBar.OnPause(evt); +} + +void DoRecord( AudacityProject &project ) +{ + wxCommandEvent evt; + evt.SetInt(2); // 0 is default, use 1 to set shift on, 2 to clear it + + auto &controlToolBar = ControlToolBar::Get( project ); + controlToolBar.OnRecord(evt); +} + +void DoLockPlayRegion( AudacityProject &project ) +{ + auto &tracks = TrackList::Get( project ); + auto &ruler = AdornedRulerPanel::Get( project ); + + auto &viewInfo = ViewInfo::Get( project ); + auto &playRegion = viewInfo.playRegion; + if (playRegion.GetStart() >= tracks.GetEndTime()) { + AudacityMessageBox(_("Cannot lock region beyond\nend of project."), + _("Error")); + } + else { + playRegion.SetLocked( true ); + ruler.Refresh(false); + } +} + +void DoUnlockPlayRegion( AudacityProject &project ) +{ + auto &ruler = AdornedRulerPanel::Get( project ); + auto &viewInfo = ViewInfo::Get( project ); + auto &playRegion = viewInfo.playRegion; + playRegion.SetLocked( false ); + ruler.Refresh(false); +} + +void DoTogglePinnedHead( AudacityProject &project ) +{ + bool value = !TracksPrefs::GetPinnedHeadPreference(); + TracksPrefs::SetPinnedHeadPreference(value, true); + MenuManager::ModifyAllProjectToolbarMenus(); + + // Change what happens in case transport is in progress right now + auto ctb = ControlToolBar::Find( *GetActiveProject() ); + if (ctb) + ctb->StartScrollingIfPreferred(); + + auto &ruler = AdornedRulerPanel::Get( project ); + // Update button image + ruler.UpdateButtonStates(); + + auto &scrubber = Scrubber::Get( project ); + if (scrubber.HasMark()) + scrubber.SetScrollScrubbing(value); +} + +void DoStop( AudacityProject &project ) +{ + wxCommandEvent evt; + + auto &controlToolBar = ControlToolBar::Get( project ); + controlToolBar.OnStop(evt); +} + +} diff --git a/src/ProjectAudioManager.h b/src/ProjectAudioManager.h index 81eec1e8a..2d96e6a5c 100644 --- a/src/ProjectAudioManager.h +++ b/src/ProjectAudioManager.h @@ -53,4 +53,17 @@ private: AudioIOStartStreamOptions DefaultPlayOptions( AudacityProject &project ); AudioIOStartStreamOptions DefaultSpeedPlayOptions( AudacityProject &project ); +/// Namespace for functions for Transport menu +namespace TransportActions { +void StopIfPaused( AudacityProject &project ); +bool DoPlayStopSelect( AudacityProject &project, bool click, bool shift ); +void DoPlayStopSelect( AudacityProject &project ); +void DoStop( AudacityProject & ); +void DoPause( AudacityProject & ); +void DoLockPlayRegion( AudacityProject & ); +void DoUnlockPlayRegion( AudacityProject & ); +void DoTogglePinnedHead( AudacityProject & ); +void DoRecord( AudacityProject & ); +} + #endif diff --git a/src/TimerRecordDialog.cpp b/src/TimerRecordDialog.cpp index a3b896b84..4e4d5fa7b 100644 --- a/src/TimerRecordDialog.cpp +++ b/src/TimerRecordDialog.cpp @@ -44,9 +44,9 @@ #include "DirManager.h" #include "ShuttleGui.h" -#include "Menus.h" #include "MissingAliasFileDialog.h" #include "Project.h" +#include "ProjectAudioManager.h" #include "ProjectFileManager.h" #include "ProjectManager.h" #include "Prefs.h" diff --git a/src/effects/EffectManager.cpp b/src/effects/EffectManager.cpp index 369350e02..e0012420d 100644 --- a/src/effects/EffectManager.cpp +++ b/src/effects/EffectManager.cpp @@ -43,6 +43,7 @@ effects. #include "../MissingAliasFileDialog.h" #include "../PluginManager.h" #include "../ProjectHistory.h" +#include "../ProjectAudioManager.h" #include "../ProjectSettings.h" #include "../ProjectWindow.h" #include "../SelectUtilities.h" diff --git a/src/menus/TransportMenus.cpp b/src/menus/TransportMenus.cpp index 76cffc145..2164f588f 100644 --- a/src/menus/TransportMenus.cpp +++ b/src/menus/TransportMenus.cpp @@ -1,7 +1,6 @@ #include "../Audacity.h" #include "../Experimental.h" -#include "../AdornedRulerPanel.h" #include "../AudioIO.h" #include "../CommonCommandFlags.h" #include "../DeviceManager.h" @@ -23,7 +22,8 @@ #include "../prefs/RecordingPrefs.h" #include "../WaveTrack.h" #include "../ViewInfo.h" -#include "../prefs/TracksPrefs.h" +#include "../commands/CommandContext.h" +#include "../commands/CommandManager.h" #include "../toolbars/ControlToolBar.h" #include "../toolbars/TranscriptionToolBar.h" #include "../tracks/ui/Scrubbing.h" @@ -203,167 +203,10 @@ void DoMoveToLabel(AudacityProject &project, bool next) } -namespace TransportActions { - -// exported helper functions - -// Stop playing or recording, if paused. -void StopIfPaused( AudacityProject &project ) -{ - if( AudioIOBase::Get()->IsPaused() ) - DoStop( project ); -} - -bool DoPlayStopSelect -(AudacityProject &project, bool click, bool shift) -{ - auto &toolbar = ControlToolBar::Get( project ); - auto &scrubber = Scrubber::Get( project ); - auto token = ProjectAudioIO::Get( project ).GetAudioIOToken(); - auto &viewInfo = ViewInfo::Get( project ); - auto &selection = viewInfo.selectedRegion; - auto gAudioIO = AudioIOBase::Get(); - - //If busy, stop playing, make sure everything is unpaused. - if (scrubber.HasMark() || - gAudioIO->IsStreamActive(token)) { - toolbar.SetPlay(false); //Pops - toolbar.SetStop(true); //Pushes stop down - - // change the selection - auto time = gAudioIO->GetStreamTime(); - // Test WasSpeedPlaying(), not IsSpeedPlaying() - // as we could be stopped now. - if (click && scrubber.WasSpeedPlaying()) - { - ;// don't change the selection. - } - else if (shift && click) { - // Change the region selection, as if by shift-click at the play head - auto t0 = selection.t0(), t1 = selection.t1(); - if (time < t0) - // Grow selection - t0 = time; - else if (time > t1) - // Grow selection - t1 = time; - else { - // Shrink selection, changing the nearer boundary - if (fabs(t0 - time) < fabs(t1 - time)) - t0 = time; - else - t1 = time; - } - selection.setTimes(t0, t1); - } - else if (click){ - // avoid a point at negative time. - time = wxMax( time, 0 ); - // Set a point selection, as if by a click at the play head - selection.setTimes(time, time); - } else - // How stop and set cursor always worked - // -- change t0, collapsing to point only if t1 was greater - selection.setT0(time, false); - - ProjectHistory::Get( project ).ModifyState(false); // without bWantsAutoSave - return true; - } - return false; -} - -// The code for "OnPlayStopSelect" is simply the code of "OnPlayStop" and -// "OnStopSelect" merged. -void DoPlayStopSelect(AudacityProject &project) -{ - auto &toolbar = ControlToolBar::Get( project ); - wxCommandEvent evt; - auto gAudioIO = AudioIO::Get(); - if (DoPlayStopSelect(project, false, false)) - toolbar.OnStop(evt); - else if (!gAudioIO->IsBusy()) { - //Otherwise, start playing (assuming audio I/O isn't busy) - //toolbar->SetPlay(true); // Not needed as set in PlayPlayRegion() - toolbar.SetStop(false); - - // Will automatically set mLastPlayMode - toolbar.PlayCurrentRegion(false); - } -} - -void DoPause( AudacityProject &project ) -{ - wxCommandEvent evt; - - auto &controlToolBar = ControlToolBar::Get( project ); - controlToolBar.OnPause(evt); -} - -void DoRecord( AudacityProject &project ) -{ - wxCommandEvent evt; - evt.SetInt(2); // 0 is default, use 1 to set shift on, 2 to clear it - - auto &controlToolBar = ControlToolBar::Get( project ); - controlToolBar.OnRecord(evt); -} - -void DoLockPlayRegion( AudacityProject &project ) -{ - auto &tracks = TrackList::Get( project ); - auto &ruler = AdornedRulerPanel::Get( project ); - - auto &viewInfo = ViewInfo::Get( project ); - auto &playRegion = viewInfo.playRegion; - if (playRegion.GetStart() >= tracks.GetEndTime()) { - AudacityMessageBox(_("Cannot lock region beyond\nend of project."), - _("Error")); - } - else { - playRegion.SetLocked( true ); - ruler.Refresh(false); - } -} - -void DoUnlockPlayRegion( AudacityProject &project ) -{ - auto &ruler = AdornedRulerPanel::Get( project ); - auto &viewInfo = ViewInfo::Get( project ); - auto &playRegion = viewInfo.playRegion; - playRegion.SetLocked( false ); - ruler.Refresh(false); -} - -void DoTogglePinnedHead( AudacityProject &project ) -{ - bool value = !TracksPrefs::GetPinnedHeadPreference(); - TracksPrefs::SetPinnedHeadPreference(value, true); - MenuManager::ModifyAllProjectToolbarMenus(); - - // Change what happens in case transport is in progress right now - auto ctb = ControlToolBar::Find( *GetActiveProject() ); - if (ctb) - ctb->StartScrollingIfPreferred(); - - auto &ruler = AdornedRulerPanel::Get( project ); - // Update button image - ruler.UpdateButtonStates(); - - auto &scrubber = Scrubber::Get( project ); - if (scrubber.HasMark()) - scrubber.SetScrollScrubbing(value); -} - -void DoStop( AudacityProject &project ) -{ - wxCommandEvent evt; - - auto &controlToolBar = ControlToolBar::Get( project ); - controlToolBar.OnStop(evt); -} - // Menu handler functions +namespace TransportActions { + struct Handler : CommandHandlerObject { void OnPlayStop(const CommandContext &context) diff --git a/src/tracks/ui/TrackButtonHandles.cpp b/src/tracks/ui/TrackButtonHandles.cpp index c53f8c54e..f14492cc5 100644 --- a/src/tracks/ui/TrackButtonHandles.cpp +++ b/src/tracks/ui/TrackButtonHandles.cpp @@ -11,9 +11,9 @@ Paul Licameli split from TrackPanel.cpp #include "../../Audacity.h" #include "TrackButtonHandles.h" -#include "../../Menus.h" #include "../../Project.h" #include "../../ProjectAudioIO.h" +#include "../../ProjectAudioManager.h" #include "../../ProjectHistory.h" #include "../../SelectUtilities.h" #include "../../RefreshCode.h"