From 35ac843baf5918df53baa57c6766e33abc10efcc Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Tue, 19 May 2015 11:30:02 -0500 Subject: [PATCH] Scrub with ctrl-left clicks, not middle drags; also fix bug 937 Bug 937 was a consequence of mouse capture for drag, which no longer happens. Scrubbing starts with ctrl- (or cmd-) left- (double-) click, after which mouse movement and shift key and scroll wheel (undepressed) govern scrubbing. No buttons need be held. Another ctrl/cmd-left click can stop scrubbing, and so can SPACE or Stop button or other commands that stop normal playback. --- src/TrackPanel.cpp | 168 +++++++++++++++++++++++++-------------------- src/TrackPanel.h | 18 +++-- 2 files changed, 107 insertions(+), 79 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 565df6784..c88b3b952 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -604,7 +604,7 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id, #ifdef EXPERIMENTAL_SCRUBBING_BASIC mScrubToken = -1; mScrubStartClockTimeMillis = -1; - mScrubStartPosition = 0; + mScrubStartPosition = -1; mMaxScrubSpeed = 1.0; mScrubSpeedDisplayCountdown = 0; #endif @@ -2128,30 +2128,10 @@ void TrackPanel::HandleSelect(wxMouseEvent & event) wxRect r; Track *t = FindTrack(event.m_x, event.m_y, false, false, &r); -#ifdef EXPERIMENTAL_SCRUBBING_BASIC - if ( -#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL - event.MiddleDClick() || -#endif - event.MiddleDown()) { - if (IsScrubbing()) - StopScrubbing(); - // Don't actually start scrubbing, but collect some information - // needed for the decision to start scrubbing later when handling - // drag events. -#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL - mSmoothScrollingScrub = event.MiddleDClick(); -#endif - mScrubStartPosition = event.m_x; - mScrubStartClockTimeMillis = ::wxGetLocalTimeMillis(); - mMouseCapture = IsSelecting; - return; - } -#endif - // AS: Ok, did the user just click the mouse, release the mouse, // or drag? - if (event.LeftDown()) { + if (event.LeftDown() || + (event.LeftDClick() && event.CmdDown())) { // AS: Now, did they click in a track somewhere? If so, we want // to extend the current selection or start a new selection, // depending on the shift key. If not, cancel all selections. @@ -2179,7 +2159,11 @@ void TrackPanel::HandleSelect(wxMouseEvent & event) mFreqSelMode = FREQ_SEL_INVALID; #endif - } else if (event.LeftDClick() && !event.ShiftDown()) { + } else if (event.LeftDClick() && !event.ShiftDown() +#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL + && !event.CmdDown() +#endif + ) { if (!mCapturedTrack) { wxRect r; mCapturedTrack = @@ -2241,6 +2225,8 @@ void TrackPanel::HandleSelect(wxMouseEvent & event) } +// Made obsolete by scrubbing: +#ifndef EXPERIMENTAL_SCRUBBING_BASIC void TrackPanel::StartOrJumpPlayback(wxMouseEvent &event) { AudacityProject *p = GetActiveProject(); @@ -2276,23 +2262,9 @@ void TrackPanel::StartOrJumpPlayback(wxMouseEvent &event) } } } +#endif -#ifdef EXPERIMENTAL_SCRUBBING_BASIC -bool TrackPanel::IsScrubbing() -{ - if (mScrubToken <= 0) - return false; - else if (mScrubToken == GetProject()->GetAudioIOToken()) - return true; - else { - // Some other command might have stopped scrub play before we - // reached StopScrubbing()! But that is okay. - mScrubToken = -1; - return false; - } -} - #ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL double TrackPanel::FindScrubSpeed(double timeAtMouse) const { @@ -2335,12 +2307,48 @@ double TrackPanel::FindScrubSpeed(double timeAtMouse) const } #endif +#ifdef EXPERIMENTAL_SCRUBBING_BASIC +bool TrackPanel::IsScrubbing() +{ + if (mScrubToken <= 0) + return false; + else if (mScrubToken == GetProject()->GetAudioIOToken()) + return true; + else { + // Some other command might have stopped scrub play before we + // reached StopScrubbing()! But that is okay. + mScrubToken = -1; + mScrubStartPosition = -1; + return false; + } +} + +void TrackPanel::ToggleScrubbing( + wxCoord xx +#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL + , bool smoothScrolling +#endif +) +{ + if (IsScrubbing()) + StopScrubbing(); + else { + // Don't actually start scrubbing, but collect some information + // needed for the decision to start scrubbing later when handling + // drag events. +#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL + mSmoothScrollingScrub = smoothScrolling; +#endif + mScrubStartPosition = xx; + mScrubStartClockTimeMillis = ::wxGetLocalTimeMillis(); + } +} + bool TrackPanel::MaybeStartScrubbing(wxMouseEvent &event) { if (IsScrubbing()) return false; - else - { + else if (mScrubStartPosition >= 0) { const bool busy = gAudioIO->IsBusy(); if (busy && gAudioIO->GetNumCaptureChannels() > 0) // Do not stop recording @@ -2354,8 +2362,7 @@ bool TrackPanel::MaybeStartScrubbing(wxMouseEvent &event) double maxTime = p->GetTracks()->GetEndTime(); double time0 = std::min(maxTime, PositionToTime(mScrubStartPosition, GetLeftOffset())); double time1 = std::min(maxTime, PositionToTime(position, GetLeftOffset())); - if (time1 != time0) - { + if (time1 != time0) { if (busy) ctb->StopPlaying(); @@ -2383,13 +2390,17 @@ bool TrackPanel::MaybeStartScrubbing(wxMouseEvent &event) } } else + // Wait to test again mScrubStartClockTimeMillis = ::wxGetLocalTimeMillis(); + if (IsScrubbing()) { - mMouseCapture = IsMiddleButtonScrubbing; - CaptureMouse(); + //mMouseCapture = IsMiddleButtonScrubbing; + //CaptureMouse(); } return IsScrubbing(); } + else + return false; } bool TrackPanel::ContinueScrubbing(wxCoord position, bool maySkip) @@ -2424,6 +2435,7 @@ bool TrackPanel::StopScrubbing() } } mScrubToken = -1; + mScrubStartPosition = -1; #ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL mSmoothScrollingScrub = false; @@ -2554,22 +2566,37 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, return; } -/* Redundant now that we have a more comprehensive Quick-Play in the Timeline - // A control-click will set just the indicator to the clicked spot, - // and turn playback on. else if(event.CmdDown() #ifdef USE_MIDI && !stretch #endif ) { +#ifdef EXPERIMENTAL_SCRUBBING_BASIC + if ( +#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL + event.LeftDClick() || +#endif + event.LeftDown()) { + ToggleScrubbing( + event.m_x +#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL + , event.LeftDClick() +#endif + ); + return; + } + +#else + StartOrJumpPlayback(event); +#endif + // Not starting a drag SetCapturedTrack(NULL, IsUncaptured); return; } -*/ //Make sure you are within the selected track bool startNewSelection = true; @@ -3308,6 +3335,19 @@ void TrackPanel::Stretch(int mouseXCoordinate, int trackLeftEdge, /// handle it here. void TrackPanel::SelectionHandleDrag(wxMouseEvent & event, Track *clickedTrack) { +#ifdef EXPERIMENTAL_SCRUBBING_BASIC + if (IsScrubbing()) { + // May need a screen update. + if (mAutoScrolling) + UpdateSelectionDisplay(); + } + else if (mScrubStartPosition >= 0) { + MaybeStartScrubbing(event); + // Do nothing more, don't change selection + return; + } +#endif + // AS: If we're not in the process of selecting (set in // the SelectionHandleClick above), fuhggeddaboudit. if (mMouseCapture!=IsSelecting) @@ -3317,20 +3357,6 @@ void TrackPanel::SelectionHandleDrag(wxMouseEvent & event, Track *clickedTrack) if (!event.Dragging() && !mAutoScrolling) return; -#ifdef EXPERIMENTAL_SCRUBBING_BASIC - if (IsScrubbing()) { - // May need a screen update, but do nothing else. Don't change selection. - if (mAutoScrolling) - UpdateSelectionDisplay(); - return; - } - else if (event.MiddleIsDown()) { - MaybeStartScrubbing(event); - // Do nothing more, don't change selection - return; - } -#endif - if (event.CmdDown()) { // Ctrl-drag has no meaning, fuhggeddaboudit return; @@ -6520,18 +6546,6 @@ void TrackPanel::OnMouseEvent(wxMouseEvent & event) case IsAdjustingLabel: HandleLabelTrackMouseEvent((LabelTrack *)mCapturedTrack, mCapturedRect, event); break; -#ifdef EXPERIMENTAL_SCRUBBING_BASIC - case IsMiddleButtonScrubbing: - if (event.MiddleUp()) { - if (IsScrubbing()) { - StopScrubbing(); - if (HasCapture()) - ReleaseMouse(); - mMouseCapture = IsUncaptured; - } - } - break; -#endif default: //includes case of IsUncaptured HandleTrackSpecificMouseEvent(event); break; @@ -7335,10 +7349,13 @@ void TrackPanel::DrawEverythingElse(wxDC * dc, } } +#ifdef EXPERIMENTAL_SCRUBBING_BASIC if (IsScrubbing()) DrawScrubSpeed(*dc); +#endif } +#ifdef EXPERIMENTAL_SCRUBBING_BASIC void TrackPanel::DrawScrubSpeed(wxDC &dc) { // Don't draw it during stutter play with shift down @@ -7405,6 +7422,7 @@ void TrackPanel::DrawScrubSpeed(wxDC &dc) dc.DrawText(text, xx, yy); } } +#endif /// Draw zooming indicator that shows the region that will /// be zoomed into when the user clicks and drags with a diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 41138ce31..04f268cda 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -321,13 +321,24 @@ class AUDACITY_DLL_API TrackPanel:public wxPanel { // AS: Selection handling virtual void HandleSelect(wxMouseEvent & event); virtual void SelectionHandleDrag(wxMouseEvent &event, Track *pTrack); + + // Made obsolete by scrubbing: +#ifndef EXPERIMENTAL_SCRUBBING_BASIC void StartOrJumpPlayback(wxMouseEvent &event); +#endif #ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL double FindScrubSpeed(double timeAtMouse) const; #endif #ifdef EXPERIMENTAL_SCRUBBING_BASIC + bool IsScrubbing(); + void ToggleScrubbing( + wxCoord xx +#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL + , bool smoothScrolling +#endif + ); bool MaybeStartScrubbing(wxMouseEvent &event); bool ContinueScrubbing(wxCoord position, bool maySkip); bool StopScrubbing(); @@ -532,7 +543,9 @@ protected: const wxRect & clip); virtual void DrawOutside(Track *t, wxDC *dc, const wxRect & rec, const wxRect &trackRect); +#ifdef EXPERIMENTAL_SCRUBBING_BASIC void DrawScrubSpeed(wxDC &dc); +#endif virtual void DrawZooming(wxDC* dc, const wxRect & clip); virtual void HighlightFocusedTrack (wxDC* dc, const wxRect &r); @@ -772,9 +785,7 @@ protected: IsStretching, #endif IsZooming, -#ifdef EXPERIMENTAL_SCRUBBING_BASIC - IsMiddleButtonScrubbing, -#endif + }; enum MouseCaptureEnum mMouseCapture; @@ -791,7 +802,6 @@ protected: int mMoveDownThreshold; #ifdef EXPERIMENTAL_SCRUBBING_BASIC - bool IsScrubbing(); int mScrubToken; wxLongLong mScrubStartClockTimeMillis; wxCoord mScrubStartPosition;