From ce95bce85a3a2f041701ad3ccb47082c88225286 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 18 Apr 2016 21:49:27 -0400 Subject: [PATCH] Bug991: Pause button and command should be disabled during scrubbing... ... and they will be as soon as ctrl-mouse down. --- src/AudacityApp.h | 2 ++ src/Menus.cpp | 9 ++++++++- src/TrackPanel.cpp | 31 ++++++++++++++++--------------- src/TrackPanel.h | 30 +++++++++++++++++------------- src/commands/CommandManager.h | 2 ++ src/toolbars/ControlToolBar.cpp | 11 +++++++++-- src/tracks/ui/Scrubbing.cpp | 9 +++++++-- src/tracks/ui/Scrubbing.h | 2 +- 8 files changed, 62 insertions(+), 34 deletions(-) diff --git a/src/AudacityApp.h b/src/AudacityApp.h index a8148a87d..8df9af48b 100644 --- a/src/AudacityApp.h +++ b/src/AudacityApp.h @@ -92,6 +92,8 @@ enum IsRealtimeNotActiveFlag= 0x10000000, //lll CaptureNotBusyFlag = 0x20000000, CanStopAudioStreamFlag = 0x40000000, + AudioStreamNotScrubbingFlag + = 0x80000000, NoFlagsSpecifed = 0xffffffff }; diff --git a/src/Menus.cpp b/src/Menus.cpp index e6c302196..d346006b0 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -133,6 +133,8 @@ simplifies construction of menu items. #include "scorealign-glue.h" #endif /* EXPERIMENTAL_SCOREALIGN */ +#include "tracks/ui/Scrubbing.h" + enum { kAlignStartZero = 0, kAlignStartSelStart, @@ -816,7 +818,9 @@ void AudacityProject::CreateMenusAndCommands() c->AddItem(wxT("PlayLooped"), _("&Loop Play"), FN(OnPlayLooped), wxT("Shift+Space"), WaveTracksExistFlag | AudioIONotBusyFlag | CanStopAudioStreamFlag, WaveTracksExistFlag | AudioIONotBusyFlag | CanStopAudioStreamFlag); - c->AddItem(wxT("Pause"), _("&Pause"), FN(OnPause), wxT("P")); + c->AddItem(wxT("Pause"), _("&Pause"), FN(OnPause), wxT("P"), + c->GetDefaultFlags() | AudioStreamNotScrubbingFlag, + c->GetDefaultMask() | AudioStreamNotScrubbingFlag); c->AddItem(wxT("SkipStart"), _("S&kip to Start"), FN(OnSkipStart), wxT("Home"), AudioIONotBusyFlag, AudioIONotBusyFlag); c->AddItem(wxT("SkipEnd"), _("Skip to E&nd"), FN(OnSkipEnd), wxT("End"), @@ -1820,6 +1824,9 @@ wxUint32 AudacityProject::GetUpdateFlags() if (bar->ControlToolBar::CanStopAudioStream()) flags |= CanStopAudioStreamFlag; + if(!GetScrubber().HasStartedScrubbing()) + flags |= AudioStreamNotScrubbingFlag; + return flags; } diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index df59c19d6..741711198 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -1297,7 +1297,7 @@ bool TrackPanel::SetCursorByActivity( ) return false; } -bool TrackPanel::SetCursorForCutline(WaveTrack * track, wxRect &rect, wxMouseEvent &event) +bool TrackPanel::SetCursorForCutline(WaveTrack * track, wxRect &rect, const wxMouseEvent &event) { if (IsOverCutline(track, rect, event)) { bool unsafe = IsUnsafe(); @@ -1311,7 +1311,7 @@ bool TrackPanel::SetCursorForCutline(WaveTrack * track, wxRect &rect, wxMouseEve /// When in the "label" (TrackInfo or vertical ruler), we can either vertical zoom or re-order tracks. /// Dont't change cursor/tip to zoom if display is not waveform (either linear of dB) or Spectrum void TrackPanel::SetCursorAndTipWhenInLabel( Track * t, - wxMouseEvent &event, wxString &tip ) + const wxMouseEvent &event, wxString &tip ) { if (event.m_x >= GetVRulerOffset() && (t->GetKind() == Track::Wave) ) { @@ -1351,7 +1351,7 @@ void TrackPanel::SetCursorAndTipWhenInVResizeArea( bool bLinked, wxString &tip ) /// When in a label track, find out if we've hit anything that /// would cause a cursor change. void TrackPanel::SetCursorAndTipWhenInLabelTrack( LabelTrack * pLT, - wxMouseEvent & event, wxString &tip ) + const wxMouseEvent & event, wxString &tip ) { int edge=pLT->OverGlyph(event.m_x, event.m_y); if(edge !=0) @@ -1462,7 +1462,7 @@ void TrackPanel::HandleCenterFrequencyClick // we hover over, most notably when hovering over the selction boundaries. // Determine and set the cursor and tip accordingly. void TrackPanel::SetCursorAndTipWhenSelectTool( Track * t, - wxMouseEvent & event, wxRect &rect, bool bMultiToolMode, + const wxMouseEvent & event, wxRect &rect, bool bMultiToolMode, wxString &tip, const wxCursor ** ppCursor ) { // Do not set the default cursor here and re-set later, that causes @@ -1596,7 +1596,7 @@ void TrackPanel::SetCursorAndTipWhenSelectTool( Track * t, /// In this method we know what tool we are using, /// so set the cursor accordingly. void TrackPanel::SetCursorAndTipByTool( int tool, - wxMouseEvent & event, wxString& ) + const wxMouseEvent & event, wxString& ) { bool unsafe = IsUnsafe(); @@ -1628,7 +1628,7 @@ void TrackPanel::SetCursorAndTipByTool( int tool, /// TrackPanel::HandleCursor( ) sets the cursor drawn at the mouse location. /// As this procedure checks which region the mouse is over, it is /// appropriate to establish the message in the status bar. -void TrackPanel::HandleCursor(wxMouseEvent & event) +void TrackPanel::HandleCursor(const wxMouseEvent & event) { mLastMouseEvent = event; @@ -1704,7 +1704,7 @@ void TrackPanel::HandleCursor(wxMouseEvent & event) tip = ttb->GetMessageForTool(tool); const auto &scrubber = GetProject()->GetScrubber(); - if (scrubber.IsScrubbing()) { + if (scrubber.HasStartedScrubbing()) { if (scrubber.IsScrollScrubbing()) tip = _("Move to adjust speed, click to skip, ESC to stop."); else @@ -1954,8 +1954,9 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, event.LeftDClick() || #endif event.LeftDown()) { + SetCapturedTrack(nullptr, IsUncaptured); GetProject()->GetScrubber().MarkScrubStart( - event.m_x + event #ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL , event.LeftDClick() #endif @@ -2890,7 +2891,7 @@ TrackPanel::SelectionBoundary TrackPanel::ChooseTimeBoundary TrackPanel::SelectionBoundary TrackPanel::ChooseBoundary -(wxMouseEvent & event, const Track *pTrack, const wxRect &rect, +(const wxMouseEvent & event, const Track *pTrack, const wxRect &rect, bool mayDragWidth, bool onlyWithinSnapDistance, double *pPinValue) const { @@ -6128,7 +6129,7 @@ bool TrackPanel::HandleTrackLocationMouseEvent(WaveTrack * track, wxRect &rect, return false; } -bool TrackPanel::IsOverCutline(WaveTrack * track, wxRect &rect, wxMouseEvent &event) +bool TrackPanel::IsOverCutline(WaveTrack * track, wxRect &rect, const wxMouseEvent &event) { for (auto loc: track->GetCachedLocations()) { @@ -6420,7 +6421,7 @@ void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event) /// determine what object we are hovering over and hence what tool to use. /// @param pTtb - A pointer to the tools tool bar /// @param event - Mouse event, with info about position and what mouse buttons are down. -int TrackPanel::DetermineToolToUse( ToolsToolBar * pTtb, wxMouseEvent & event) +int TrackPanel::DetermineToolToUse( ToolsToolBar * pTtb, const wxMouseEvent & event) { int currentTool = pTtb->GetCurrentTool(); @@ -6483,7 +6484,7 @@ int TrackPanel::DetermineToolToUse( ToolsToolBar * pTtb, wxMouseEvent & event) #ifdef USE_MIDI -bool TrackPanel::HitTestStretch(Track *track, wxRect &rect, wxMouseEvent & event) +bool TrackPanel::HitTestStretch(Track *track, wxRect &rect, const wxMouseEvent & event) { // later, we may want a different policy, but for now, stretch is // selected when the cursor is near the center of the track and @@ -6507,7 +6508,7 @@ bool TrackPanel::HitTestStretch(Track *track, wxRect &rect, wxMouseEvent & event /// method that tells us if the mouse event landed on an /// envelope boundary. -bool TrackPanel::HitTestEnvelope(Track *track, wxRect &rect, wxMouseEvent & event) +bool TrackPanel::HitTestEnvelope(Track *track, wxRect &rect, const wxMouseEvent & event) { wxASSERT(track); if( track->GetKind() != Track::Wave ) @@ -6575,7 +6576,7 @@ bool TrackPanel::HitTestEnvelope(Track *track, wxRect &rect, wxMouseEvent & even /// method that tells us if the mouse event landed on an /// editable sample -bool TrackPanel::HitTestSamples(Track *track, wxRect &rect, wxMouseEvent & event) +bool TrackPanel::HitTestSamples(Track *track, wxRect &rect, const wxMouseEvent & event) { wxASSERT(track); if( track->GetKind() != Track::Wave ) @@ -6626,7 +6627,7 @@ bool TrackPanel::HitTestSamples(Track *track, wxRect &rect, wxMouseEvent & event /// method that tells us if the mouse event landed on a /// time-slider that allows us to time shift the sequence. -bool TrackPanel::HitTestSlide(Track * WXUNUSED(track), wxRect &rect, wxMouseEvent & event) +bool TrackPanel::HitTestSlide(Track * WXUNUSED(track), wxRect &rect, const wxMouseEvent & event) { // Perhaps we should delegate this to TrackArtist as only TrackArtist // knows what the real sizes are?? diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 5d27a5be6..f50cec89f 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -250,16 +250,16 @@ class AUDACITY_DLL_API TrackPanel final : public wxPanel { virtual void HandleGlyphDragRelease(LabelTrack * lTrack, wxMouseEvent & event); virtual void HandleTextDragRelease(LabelTrack * lTrack, wxMouseEvent & event); virtual bool HandleTrackLocationMouseEvent(WaveTrack * track, wxRect &rect, wxMouseEvent &event); - virtual bool IsOverCutline(WaveTrack * track, wxRect &rect, wxMouseEvent &event); + virtual bool IsOverCutline(WaveTrack * track, wxRect &rect, const wxMouseEvent &event); virtual void HandleTrackSpecificMouseEvent(wxMouseEvent & event); virtual void ScrollDuringDrag(); // Working out where to dispatch the event to. - virtual int DetermineToolToUse( ToolsToolBar * pTtb, wxMouseEvent & event); - virtual bool HitTestEnvelope(Track *track, wxRect &rect, wxMouseEvent & event); - virtual bool HitTestSamples(Track *track, wxRect &rect, wxMouseEvent & event); - virtual bool HitTestSlide(Track *track, wxRect &rect, wxMouseEvent & event); + virtual int DetermineToolToUse( ToolsToolBar * pTtb, const wxMouseEvent & event); + virtual bool HitTestEnvelope(Track *track, wxRect &rect, const wxMouseEvent & event); + virtual bool HitTestSamples(Track *track, wxRect &rect, const wxMouseEvent & event); + virtual bool HitTestSlide(Track *track, wxRect &rect, const wxMouseEvent & event); #ifdef USE_MIDI // data for NoteTrack interactive stretch operations: // Stretching applies to a selected region after quantizing the @@ -284,7 +284,7 @@ class AUDACITY_DLL_API TrackPanel final : public wxPanel { double mStretchSel1; // initial sel1 (left) quantized to nearest beat double mStretchLeftBeats; // how many beats from left to cursor double mStretchRightBeats; // how many beats from cursor to right - virtual bool HitTestStretch(Track *track, wxRect &rect, wxMouseEvent & event); + virtual bool HitTestStretch(Track *track, wxRect &rect, const wxMouseEvent & event); virtual void Stretch(int mouseXCoordinate, int trackLeftEdge, Track *pTrack); #endif @@ -325,14 +325,18 @@ protected: // AS: Cursor handling virtual bool SetCursorByActivity( ); - virtual bool SetCursorForCutline(WaveTrack * track, wxRect &rect, wxMouseEvent &event); - virtual void SetCursorAndTipWhenInLabel( Track * t, wxMouseEvent &event, wxString &tip ); + virtual bool SetCursorForCutline(WaveTrack * track, wxRect &rect, const wxMouseEvent &event); + virtual void SetCursorAndTipWhenInLabel( Track * t, const wxMouseEvent &event, wxString &tip ); virtual void SetCursorAndTipWhenInVResizeArea( bool blinked, wxString &tip ); - virtual void SetCursorAndTipWhenInLabelTrack( LabelTrack * pLT, wxMouseEvent & event, wxString &tip ); + virtual void SetCursorAndTipWhenInLabelTrack( LabelTrack * pLT, const wxMouseEvent & event, wxString &tip ); virtual void SetCursorAndTipWhenSelectTool - ( Track * t, wxMouseEvent & event, wxRect &rect, bool bMultiToolMode, wxString &tip, const wxCursor ** ppCursor ); - virtual void SetCursorAndTipByTool( int tool, wxMouseEvent & event, wxString &tip ); - virtual void HandleCursor(wxMouseEvent & event); + ( Track * t, const wxMouseEvent & event, wxRect &rect, bool bMultiToolMode, wxString &tip, const wxCursor ** ppCursor ); + virtual void SetCursorAndTipByTool( int tool, const wxMouseEvent & event, wxString &tip ); + +public: + virtual void HandleCursor(const wxMouseEvent & event); + +protected: virtual void MaySetOnDemandTip( Track * t, wxString &tip ); // AS: Envelope editing handlers @@ -699,7 +703,7 @@ protected: (double selend, bool onlyWithinSnapDistance, wxInt64 *pPixelDist = NULL, double *pPinValue = NULL) const; SelectionBoundary ChooseBoundary - (wxMouseEvent & event, const Track *pTrack, + (const wxMouseEvent & event, const Track *pTrack, const wxRect &rect, bool mayDragWidth, bool onlyWithinSnapDistance, diff --git a/src/commands/CommandManager.h b/src/commands/CommandManager.h index f784c9b11..7b5c83929 100644 --- a/src/commands/CommandManager.h +++ b/src/commands/CommandManager.h @@ -184,6 +184,8 @@ class AUDACITY_DLL_API CommandManager final : public XMLTagHandler // For NEW items/commands void SetDefaultFlags(wxUint32 flags, wxUint32 mask); + wxUint32 GetDefaultFlags() const { return mDefaultFlags; } + wxUint32 GetDefaultMask() const { return mDefaultMask; } void SetCommandFlags(const wxString &name, wxUint32 flags, wxUint32 mask); void SetCommandFlags(const wxChar **names, diff --git a/src/toolbars/ControlToolBar.cpp b/src/toolbars/ControlToolBar.cpp index 00e44bdb5..694f0539e 100644 --- a/src/toolbars/ControlToolBar.cpp +++ b/src/toolbars/ControlToolBar.cpp @@ -67,6 +67,8 @@ #include "../widgets/AButton.h" #include "../widgets/Meter.h" +#include "../tracks/ui/Scrubbing.h" + IMPLEMENT_CLASS(ControlToolBar, ToolBar); //static @@ -423,7 +425,11 @@ void ControlToolBar::EnableDisableButtons() mStop->SetEnabled(CanStopAudioStream() && (playing || recording)); mRewind->SetEnabled(!playing && !recording); mFF->SetEnabled(tracks && !playing && !recording); - mPause->SetEnabled(CanStopAudioStream()); + + auto pProject = GetActiveProject(); + mPause->SetEnabled(CanStopAudioStream() && + !(pProject && + pProject->GetScrubber().HasStartedScrubbing())); } void ControlToolBar::SetPlay(bool down, bool looped, bool cutPreview) @@ -1184,7 +1190,8 @@ wxString ControlToolBar::StateForStatusBar() { wxString state; - if (gAudioIO->IsScrubbing()) + auto pProject = GetActiveProject(); + if (pProject && pProject->GetScrubber().HasStartedScrubbing()) state = wxGetTranslation(mStateScrub); else if (mPlay->IsDown()) state = wxGetTranslation(mStatePlay); diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index d661fe989..926a73b75 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -140,12 +140,14 @@ Scrubber::~Scrubber() } void Scrubber::MarkScrubStart( - wxCoord xx + const wxMouseEvent &event #ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL , bool smoothScrolling #endif ) { + const wxCoord xx = event.m_x; + // Don't actually start scrubbing, but collect some information // needed for the decision to start scrubbing later when handling // drag events. @@ -154,6 +156,10 @@ void Scrubber::MarkScrubStart( #endif mScrubStartPosition = xx; mScrubStartClockTimeMillis = ::wxGetLocalTimeMillis(); + + ControlToolBar * const ctb = mProject->GetControlToolBar(); + ctb->UpdateStatusBar(mProject); + mProject->GetTrackPanel()->HandleCursor(event); } #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT @@ -218,7 +224,6 @@ bool Scrubber::MaybeStartScrubbing(const wxMouseEvent &event) mScrubToken = ctb->PlayPlayRegion(SelectedRegion(time0, time1), options, PlayMode::normalPlay, cutPreview, backwards); - ctb->UpdateStatusBar(mProject); } } else diff --git a/src/tracks/ui/Scrubbing.h b/src/tracks/ui/Scrubbing.h index 52d6a6444..715509bdf 100644 --- a/src/tracks/ui/Scrubbing.h +++ b/src/tracks/ui/Scrubbing.h @@ -27,7 +27,7 @@ public: ~Scrubber(); void MarkScrubStart( - wxCoord xx + const wxMouseEvent &event #ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL , bool smoothScrolling #endif