From 3f29d1948dde00d4776b4afd343ed2b1d2d05af4 Mon Sep 17 00:00:00 2001 From: Evan Short Date: Thu, 8 Mar 2018 12:50:42 -0800 Subject: [PATCH 1/3] refactor SeekLeftOrRight --- src/Menus.cpp | 359 ++++++++++++++++++++++---------------------------- src/Menus.h | 14 +- 2 files changed, 166 insertions(+), 207 deletions(-) diff --git a/src/Menus.cpp b/src/Menus.cpp index 231b14c3b..b7d2633f1 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -3549,22 +3549,22 @@ void AudacityProject::OnCursorRight(const CommandContext &context) void AudacityProject::OnCursorShortJumpLeft(const CommandContext &WXUNUSED(context) ) { - OnCursorMove( false, true, false ); + OnCursorMove( false, false ); } void AudacityProject::OnCursorShortJumpRight(const CommandContext &WXUNUSED(context) ) { - OnCursorMove( true, true, false ); + OnCursorMove( true, false ); } void AudacityProject::OnCursorLongJumpLeft(const CommandContext &WXUNUSED(context) ) { - OnCursorMove( false, true, true ); + OnCursorMove( false, true ); } void AudacityProject::OnCursorLongJumpRight(const CommandContext &WXUNUSED(context) ) { - OnCursorMove( true, true, true ); + OnCursorMove( true, true ); } void AudacityProject::OnSelSetExtendLeft(const CommandContext &WXUNUSED(context) ) @@ -9020,13 +9020,7 @@ void AudacityProject::OnCursorLeft(bool shift, bool ctrl, bool keyup) // During playback: jump depends on preferences and is independent of the zoom // and does not vary if the key is held // Else: jump depends on the zoom and gets bigger if the key is held - int snapToTime = GetSnapTo(); - double quietSeekStepPositive = 1.0; // pixels - double audioSeekStepPositive = shift ? mSeekLong : mSeekShort; - SeekLeftOrRight - (true, shift, ctrl, keyup, snapToTime, true, false, - quietSeekStepPositive, true, - audioSeekStepPositive, false); + SeekLeftOrRight(true, shift, ctrl, keyup); } void AudacityProject::OnCursorRight(bool shift, bool ctrl, bool keyup) @@ -9035,195 +9029,167 @@ void AudacityProject::OnCursorRight(bool shift, bool ctrl, bool keyup) // During playback: jump depends on preferences and is independent of the zoom // and does not vary if the key is held // Else: jump depends on the zoom and gets bigger if the key is held - int snapToTime = GetSnapTo(); - double quietSeekStepPositive = 1.0; // pixels - double audioSeekStepPositive = shift ? mSeekLong : mSeekShort; - SeekLeftOrRight - (false, shift, ctrl, keyup, snapToTime, true, false, - quietSeekStepPositive, true, - audioSeekStepPositive, false); + SeekLeftOrRight(false, shift, ctrl, keyup); } // Handle small cursor and play head movements void AudacityProject::SeekLeftOrRight -(bool leftward, bool shift, bool ctrl, bool keyup, - int snapToTime, bool mayAccelerateQuiet, bool mayAccelerateAudio, - double quietSeekStepPositive, bool quietStepIsPixels, - double audioSeekStepPositive, bool audioStepIsPixels) +(bool leftward, bool shift, bool ctrl, bool keyup) { - if (keyup) - { - if (IsAudioActive()) - { - return; - } + if (IsAudioActive()) + { + if (!ctrl && !keyup) + { + const double seekStep = + (shift ? mSeekLong : mSeekShort) * (leftward ? -1.0 : 1.0); + SeekAudio(seekStep); + } + } + else + { + if (keyup) + { + ModifyState(false); + } + else + { + // If the last adjustment was very recent, we are + // holding the key down and should move faster. + const wxLongLong curtime = ::wxGetLocalTimeMillis(); + enum { MIN_INTERVAL = 50 }; + const bool fast = (curtime - mLastSelectionAdjustment < MIN_INTERVAL); - ModifyState(false); - return; - } + mLastSelectionAdjustment = curtime; - // If the last adjustment was very recent, we are - // holding the key down and should move faster. - const wxLongLong curtime = ::wxGetLocalTimeMillis(); - enum { MIN_INTERVAL = 50 }; - const bool fast = (curtime - mLastSelectionAdjustment < MIN_INTERVAL); + // How much faster should the cursor move if shift is down? + enum { LARGER_MULTIPLIER = 4 }; + const double seekStep = + (fast ? LARGER_MULTIPLIER : 1.0) * (leftward ? -1.0 : 1.0); - // How much faster should the cursor move if shift is down? - enum { LARGER_MULTIPLIER = 4 }; - int multiplier = (fast && mayAccelerateQuiet) ? LARGER_MULTIPLIER : 1; - if (leftward) - multiplier = -multiplier; + int snapToTime = GetSnapTo(); + SeekQuiet(seekStep, true, snapToTime != 0, shift, ctrl); + } + } +} - if (shift && ctrl) - { - mLastSelectionAdjustment = curtime; - - // Contract selection - // Reduce and constrain (counter-intuitive) - if (leftward) { - const double t1 = mViewInfo.selectedRegion.t1(); - mViewInfo.selectedRegion.setT1( - std::max(mViewInfo.selectedRegion.t0(), - snapToTime - ? GridMove(t1, multiplier) - : quietStepIsPixels - ? mViewInfo.OffsetTimeByPixels( - t1, (int)(multiplier * quietSeekStepPositive)) - : t1 + multiplier * quietSeekStepPositive - )); - - // Make sure it's visible. - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); - } - else { - const double t0 = mViewInfo.selectedRegion.t0(); - mViewInfo.selectedRegion.setT0( - std::min(mViewInfo.selectedRegion.t1(), - snapToTime - ? GridMove(t0, multiplier) - : quietStepIsPixels - ? mViewInfo.OffsetTimeByPixels( - t0, (int)(multiplier * quietSeekStepPositive)) - : t0 + multiplier * quietSeekStepPositive - )); - - // Make sure NEW position is in view. - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t0()); - } - GetTrackPanel()->Refresh(false); - } - else if (IsAudioActive()) { +void AudacityProject::SeekAudio(double seekStep) { #ifdef EXPERIMENTAL_IMPROVED_SEEKING - if (gAudioIO->GetLastPlaybackTime() < mLastSelectionAdjustment) { - // Allow time for the last seek to output a buffer before - // discarding samples again - // Do not advance mLastSelectionAdjustment - return; - } + if (gAudioIO->GetLastPlaybackTime() < mLastSelectionAdjustment) { + // Allow time for the last seek to output a buffer before + // discarding samples again + // Do not advance mLastSelectionAdjustment + return; + } #endif - mLastSelectionAdjustment = curtime; + mLastSelectionAdjustment = ::wxGetLocalTimeMillis(); - // Ignore the multiplier for the quiet case - multiplier = (fast && mayAccelerateAudio) ? LARGER_MULTIPLIER : 1; - if (leftward) - multiplier = -multiplier; + gAudioIO->SeekStream(seekStep); +} - // If playing, reposition - double seconds; - if (audioStepIsPixels) { - const double streamTime = gAudioIO->GetStreamTime(); - const double newTime = - mViewInfo.OffsetTimeByPixels(streamTime, (int)(audioSeekStepPositive)); - seconds = newTime - streamTime; - } - else - seconds = multiplier * audioSeekStepPositive; - gAudioIO->SeekStream(seconds); - return; - } - else if (shift) - { - mLastSelectionAdjustment = curtime; +void AudacityProject::SeekQuiet +(double seekStep, bool isPixels, bool snapToTime, bool shift, bool ctrl) +{ + const double t0 = mViewInfo.selectedRegion.t0(); + const double t1 = mViewInfo.selectedRegion.t1(); + const double end = mTracks->GetEndTime(); - // Extend selection - // Expand and constrain - if (leftward) { - const double t0 = mViewInfo.selectedRegion.t0(); - mViewInfo.selectedRegion.setT0( - std::max(0.0, - snapToTime - ? GridMove(t0, multiplier) - : quietStepIsPixels - ? mViewInfo.OffsetTimeByPixels( - t0, (int)(multiplier * quietSeekStepPositive)) - : t0 + multiplier * quietSeekStepPositive - )); + if (shift && ctrl) + { + // Contract selection + // Reduce and constrain (counter-intuitive) + if (seekStep < 0) + { + mViewInfo.selectedRegion.setT1( + std::max(t0, OffsetTime(t1, seekStep, isPixels, snapToTime))); - // Make sure it's visible. - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t0()); - } - else { - const double end = mTracks->GetEndTime(); - const double t1 = mViewInfo.selectedRegion.t1(); - mViewInfo.selectedRegion.setT1( - std::min(end, - snapToTime - ? GridMove(t1, multiplier) - : quietStepIsPixels - ? mViewInfo.OffsetTimeByPixels( - t1, (int)(multiplier * quietSeekStepPositive)) - : t1 + multiplier * quietSeekStepPositive - )); + // Make sure it's visible. + GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); + } + else + { + mViewInfo.selectedRegion.setT0( + std::min(t1, OffsetTime(t0, seekStep, isPixels, snapToTime))); - // Make sure NEW position is in view. - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); - } - GetTrackPanel()->Refresh(false); - } - else - { - mLastSelectionAdjustment = curtime; + // Make sure NEW position is in view. + GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t0()); + } + GetTrackPanel()->Refresh(false); + } + else if (shift) + { + // Extend selection + // Expand and constrain + if (seekStep < 0) + { + mViewInfo.selectedRegion.setT0( + std::max(0.0, OffsetTime(t0, seekStep, isPixels, snapToTime))); - // Move the cursor - // Already in cursor mode? - if (mViewInfo.selectedRegion.isPoint()) - { - // Move and constrain - const double end = mTracks->GetEndTime(); - const double t0 = mViewInfo.selectedRegion.t0(); - mViewInfo.selectedRegion.setT0( - std::max(0.0, - std::min(end, - snapToTime - ? GridMove(t0, multiplier) - : quietStepIsPixels - ? mViewInfo.OffsetTimeByPixels( - t0, (int)(multiplier * quietSeekStepPositive)) - : t0 + multiplier * quietSeekStepPositive)), - false // do not swap selection boundaries - ); - mViewInfo.selectedRegion.collapseToT0(); + // Make sure it's visible. + GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t0()); + } + else + { + mViewInfo.selectedRegion.setT1( + std::min(end, OffsetTime(t1, seekStep, isPixels, snapToTime))); - // Move the visual cursor, avoiding an unnecessary complete redraw - GetTrackPanel()->DrawOverlays(false); - GetRulerPanel()->DrawOverlays(false); - - // This updates the selection shown on the selection bar, and the play region - TP_DisplaySelection(); - } - else - { - // Transition to cursor mode. - if (leftward) + // Make sure NEW position is in view. + GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); + } + GetTrackPanel()->Refresh(false); + } + else + { + // Move the cursor + // Already in cursor mode? + if (mViewInfo.selectedRegion.isPoint()) + { + // Move and constrain + mViewInfo.selectedRegion.setT0( + std::max(0.0, + std::min(end, + OffsetTime(t0, seekStep, isPixels, snapToTime))), + false // do not swap selection boundaries + ); mViewInfo.selectedRegion.collapseToT0(); - else - mViewInfo.selectedRegion.collapseToT1(); - GetTrackPanel()->Refresh(false); - } - // Make sure NEW position is in view - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); - } + // Move the visual cursor, avoiding an unnecessary complete redraw + GetTrackPanel()->DrawOverlays(false); + GetRulerPanel()->DrawOverlays(false); + + // This updates the selection shown on the selection bar, and the play region + TP_DisplaySelection(); + } + else + { + // Transition to cursor mode. + if (seekStep < 0) + mViewInfo.selectedRegion.collapseToT0(); + else + mViewInfo.selectedRegion.collapseToT1(); + GetTrackPanel()->Refresh(false); + } + + // Make sure NEW position is in view + GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); + } +} + +double AudacityProject::OffsetTime(double t, double offset, bool isPixels, bool snapToTime) { + if (isPixels) + { + if (snapToTime) + { + return GridMove(t, (int)offset); + } + else + { + return mViewInfo.OffsetTimeByPixels(t, (int)offset); + } + } + else + { + return t + offset; // snapping is currently ignored for non-pixel moves + } } // Handles moving a selection edge with the keyboard in snap-to-time mode; @@ -9347,31 +9313,20 @@ void AudacityProject::OnBoundaryMove(bool left, bool boundaryContract) // Move the cursor forward or backward, while paused or while playing. // forward=true: Move cursor forward; forward=false: Move cursor backwards -// jump=false: Move cursor determined by zoom; jump=true: Use seek times // longjump=false: Use mSeekShort; longjump=true: Use mSeekLong -void AudacityProject::OnCursorMove(bool forward, bool jump, bool longjump ) +void AudacityProject::OnCursorMove(bool forward, bool longjump ) { - // PRL: nobody calls this yet with !jump + const double seekStep = + (longjump ? mSeekLong : mSeekShort) * (forward ? 1.0 : -1.0); - double positiveSeekStep; - bool byPixels; - if (jump) { - if (!longjump) { - positiveSeekStep = mSeekShort; - } else { - positiveSeekStep = mSeekLong; - } - byPixels = false; - } else { - positiveSeekStep = 1.0; - byPixels = true; - } - bool mayAccelerate = !jump; - SeekLeftOrRight - (!forward, false, false, false, - 0, mayAccelerate, mayAccelerate, - positiveSeekStep, byPixels, - positiveSeekStep, byPixels); + if (IsAudioActive()) { + SeekAudio(seekStep); + } + else + { + mLastSelectionAdjustment = ::wxGetLocalTimeMillis(); + SeekQuiet(seekStep, false, false, false, false); + } ModifyState(false); } diff --git a/src/Menus.h b/src/Menus.h index f5138c88c..6b329cb9e 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -546,15 +546,19 @@ void OnResample(const CommandContext &context ); private: void OnCursorLeft(bool shift, bool ctrl, bool keyup = false); void OnCursorRight(bool shift, bool ctrl, bool keyup = false); -void OnCursorMove(bool forward, bool jump, bool longjump); +void OnCursorMove(bool forward, bool longjump); void OnBoundaryMove(bool left, bool boundaryContract); // Handle small cursor and play head movements void SeekLeftOrRight -(bool left, bool shift, bool ctrl, bool keyup, - int snapToTime, bool mayAccelerateQuiet, bool mayAccelerateAudio, - double quietSeekStepPositive, bool quietStepIsPixels, - double audioSeekStepPositive, bool audioStepIsPixels); +(bool left, bool shift, bool ctrl, bool keyup); + +void SeekAudio(double seekStep); + +void SeekQuiet +(double seekStep, bool isPixels, bool snapToTime, bool shift, bool ctrl); + +double OffsetTime(double t, double offset, bool isPixels, bool snapToTime); // Helper for moving by keyboard with snap-to-grid enabled double GridMove(double t, int minPix); From 7c4ca093f3dfbb4b850070561ec6b27163c948b4 Mon Sep 17 00:00:00 2001 From: Evan Short Date: Tue, 13 Mar 2018 19:43:52 -0700 Subject: [PATCH 2/3] use enums instead of bool in seekLeftOrRight --- src/Menus.cpp | 148 +++++++++++++++++++++++--------------------------- src/Menus.h | 24 ++++++-- 2 files changed, 87 insertions(+), 85 deletions(-) diff --git a/src/Menus.cpp b/src/Menus.cpp index b7d2633f1..3089faa5a 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -3129,22 +3129,22 @@ void AudacityProject::OnSkipEnd(const CommandContext &WXUNUSED(context) ) void AudacityProject::OnSeekLeftShort(const CommandContext &WXUNUSED(context) ) { - OnCursorLeft( false, false ); + OnCursorLeft( CURSOR_MOVE ); } void AudacityProject::OnSeekRightShort(const CommandContext &WXUNUSED(context) ) { - OnCursorRight( false, false ); + OnCursorRight( CURSOR_MOVE ); } void AudacityProject::OnSeekLeftLong(const CommandContext &WXUNUSED(context) ) { - OnCursorLeft( true, false ); + OnCursorLeft( SELECTION_EXTEND ); } void AudacityProject::OnSeekRightLong(const CommandContext &WXUNUSED(context) ) { - OnCursorRight( true, false ); + OnCursorRight( SELECTION_EXTEND ); } void AudacityProject::OnSelToStart(const CommandContext &WXUNUSED(context) ) @@ -3537,34 +3537,34 @@ void AudacityProject::OnCursorLeft(const CommandContext &context) { auto evt = context.pEvt; bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorLeft( false, false, bKeyUp ); + OnCursorLeft( CURSOR_MOVE, bKeyUp ); } void AudacityProject::OnCursorRight(const CommandContext &context) { auto evt = context.pEvt; bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorRight( false, false, bKeyUp ); + OnCursorRight( CURSOR_MOVE, bKeyUp ); } void AudacityProject::OnCursorShortJumpLeft(const CommandContext &WXUNUSED(context) ) { - OnCursorMove( false, false ); + OnCursorMove( -mSeekShort ); } void AudacityProject::OnCursorShortJumpRight(const CommandContext &WXUNUSED(context) ) { - OnCursorMove( true, false ); + OnCursorMove( mSeekShort ); } void AudacityProject::OnCursorLongJumpLeft(const CommandContext &WXUNUSED(context) ) { - OnCursorMove( false, true ); + OnCursorMove( -mSeekLong ); } void AudacityProject::OnCursorLongJumpRight(const CommandContext &WXUNUSED(context) ) { - OnCursorMove( true, true ); + OnCursorMove( mSeekLong ); } void AudacityProject::OnSelSetExtendLeft(const CommandContext &WXUNUSED(context) ) @@ -3581,28 +3581,28 @@ void AudacityProject::OnSelExtendLeft(const CommandContext &context) { auto evt = context.pEvt; bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorLeft( true, false, bKeyUp ); + OnCursorLeft( SELECTION_EXTEND, bKeyUp ); } void AudacityProject::OnSelExtendRight(const CommandContext &context) { auto evt = context.pEvt; bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorRight( true, false, bKeyUp ); + OnCursorRight( SELECTION_EXTEND, bKeyUp ); } void AudacityProject::OnSelContractLeft(const CommandContext &context) { auto evt = context.pEvt; bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorRight( true, true, bKeyUp ); + OnCursorRight( SELECTION_CONTRACT, bKeyUp ); } void AudacityProject::OnSelContractRight(const CommandContext &context) { auto evt = context.pEvt; bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorLeft( true, true, bKeyUp ); + OnCursorLeft( SELECTION_CONTRACT, bKeyUp ); } #include "tracks/ui/TimeShiftHandle.h" @@ -9014,65 +9014,65 @@ void AudacityProject::OnFullScreen(const CommandContext &WXUNUSED(context) ) mCommandManager.Check(wxT("FullScreenOnOff"), bChecked); } -void AudacityProject::OnCursorLeft(bool shift, bool ctrl, bool keyup) +void AudacityProject::OnCursorLeft(SelectionOperation operation, bool keyup) { // PRL: What I found and preserved, strange though it be: // During playback: jump depends on preferences and is independent of the zoom // and does not vary if the key is held // Else: jump depends on the zoom and gets bigger if the key is held - SeekLeftOrRight(true, shift, ctrl, keyup); + SeekLeftOrRight(-1.0, operation, keyup); } -void AudacityProject::OnCursorRight(bool shift, bool ctrl, bool keyup) +void AudacityProject::OnCursorRight(SelectionOperation operation, bool keyup) { // PRL: What I found and preserved, strange though it be: // During playback: jump depends on preferences and is independent of the zoom // and does not vary if the key is held // Else: jump depends on the zoom and gets bigger if the key is held - SeekLeftOrRight(false, shift, ctrl, keyup); + SeekLeftOrRight(1.0, operation, keyup); } // Handle small cursor and play head movements void AudacityProject::SeekLeftOrRight -(bool leftward, bool shift, bool ctrl, bool keyup) +(double direction, SelectionOperation operation, bool keyup) { if (IsAudioActive()) - { - if (!ctrl && !keyup) - { - const double seekStep = - (shift ? mSeekLong : mSeekShort) * (leftward ? -1.0 : 1.0); - SeekAudio(seekStep); - } - } - else { if (keyup) - { - ModifyState(false); - } - else - { - // If the last adjustment was very recent, we are - // holding the key down and should move faster. - const wxLongLong curtime = ::wxGetLocalTimeMillis(); - enum { MIN_INTERVAL = 50 }; - const bool fast = (curtime - mLastSelectionAdjustment < MIN_INTERVAL); + return; - mLastSelectionAdjustment = curtime; + if (operation == CURSOR_MOVE) + SeekAudio(mSeekShort * direction); + else if (operation == SELECTION_EXTEND) + SeekAudio(mSeekLong * direction); - // How much faster should the cursor move if shift is down? - enum { LARGER_MULTIPLIER = 4 }; - const double seekStep = - (fast ? LARGER_MULTIPLIER : 1.0) * (leftward ? -1.0 : 1.0); - - int snapToTime = GetSnapTo(); - SeekQuiet(seekStep, true, snapToTime != 0, shift, ctrl); - } + return; } + + if (keyup) + { + ModifyState(false); + return; + } + + // If the last adjustment was very recent, we are + // holding the key down and should move faster. + const wxLongLong curtime = ::wxGetLocalTimeMillis(); + enum { MIN_INTERVAL = 50 }; + const bool fast = (curtime - mLastSelectionAdjustment < MIN_INTERVAL); + + mLastSelectionAdjustment = curtime; + + // How much faster should the cursor move if shift is down? + enum { LARGER_MULTIPLIER = 4 }; + const double seekStep = (fast ? LARGER_MULTIPLIER : 1.0) * direction; + + int snapToTime = GetSnapTo(); + SeekQuiet(seekStep, TIME_UNIT_PIXELS, snapToTime, operation); } -void AudacityProject::SeekAudio(double seekStep) { +void AudacityProject::SeekAudio(double seekStep) +{ #ifdef EXPERIMENTAL_IMPROVED_SEEKING if (gAudioIO->GetLastPlaybackTime() < mLastSelectionAdjustment) { // Allow time for the last seek to output a buffer before @@ -9087,20 +9087,21 @@ void AudacityProject::SeekAudio(double seekStep) { } void AudacityProject::SeekQuiet -(double seekStep, bool isPixels, bool snapToTime, bool shift, bool ctrl) +(double seekStep, TimeUnit timeUnit, int snapToTime, + SelectionOperation operation) { const double t0 = mViewInfo.selectedRegion.t0(); const double t1 = mViewInfo.selectedRegion.t1(); const double end = mTracks->GetEndTime(); - if (shift && ctrl) + if (operation == SELECTION_CONTRACT) { // Contract selection // Reduce and constrain (counter-intuitive) if (seekStep < 0) { mViewInfo.selectedRegion.setT1( - std::max(t0, OffsetTime(t1, seekStep, isPixels, snapToTime))); + std::max(t0, OffsetTime(t1, seekStep, timeUnit, snapToTime))); // Make sure it's visible. GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); @@ -9108,21 +9109,21 @@ void AudacityProject::SeekQuiet else { mViewInfo.selectedRegion.setT0( - std::min(t1, OffsetTime(t0, seekStep, isPixels, snapToTime))); + std::min(t1, OffsetTime(t0, seekStep, timeUnit, snapToTime))); // Make sure NEW position is in view. GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t0()); } GetTrackPanel()->Refresh(false); } - else if (shift) + else if (operation == SELECTION_EXTEND) { // Extend selection // Expand and constrain if (seekStep < 0) { mViewInfo.selectedRegion.setT0( - std::max(0.0, OffsetTime(t0, seekStep, isPixels, snapToTime))); + std::max(0.0, OffsetTime(t0, seekStep, timeUnit, snapToTime))); // Make sure it's visible. GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t0()); @@ -9130,14 +9131,14 @@ void AudacityProject::SeekQuiet else { mViewInfo.selectedRegion.setT1( - std::min(end, OffsetTime(t1, seekStep, isPixels, snapToTime))); + std::min(end, OffsetTime(t1, seekStep, timeUnit, snapToTime))); // Make sure NEW position is in view. GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); } GetTrackPanel()->Refresh(false); } - else + else if (operation == CURSOR_MOVE) { // Move the cursor // Already in cursor mode? @@ -9147,7 +9148,7 @@ void AudacityProject::SeekQuiet mViewInfo.selectedRegion.setT0( std::max(0.0, std::min(end, - OffsetTime(t0, seekStep, isPixels, snapToTime))), + OffsetTime(t0, seekStep, timeUnit, snapToTime))), false // do not swap selection boundaries ); mViewInfo.selectedRegion.collapseToT0(); @@ -9174,22 +9175,16 @@ void AudacityProject::SeekQuiet } } -double AudacityProject::OffsetTime(double t, double offset, bool isPixels, bool snapToTime) { - if (isPixels) - { - if (snapToTime) - { - return GridMove(t, (int)offset); - } - else - { - return mViewInfo.OffsetTimeByPixels(t, (int)offset); - } - } - else - { +double AudacityProject::OffsetTime +(double t, double offset, TimeUnit timeUnit, int snapToTime) +{ + if (timeUnit == TIME_UNIT_SECONDS) return t + offset; // snapping is currently ignored for non-pixel moves - } + + if (snapToTime == SNAP_OFF) + return mViewInfo.OffsetTimeByPixels(t, (int)offset); + + return GridMove(t, (int)offset); } // Handles moving a selection edge with the keyboard in snap-to-time mode; @@ -9312,20 +9307,15 @@ void AudacityProject::OnBoundaryMove(bool left, bool boundaryContract) } // Move the cursor forward or backward, while paused or while playing. -// forward=true: Move cursor forward; forward=false: Move cursor backwards -// longjump=false: Use mSeekShort; longjump=true: Use mSeekLong -void AudacityProject::OnCursorMove(bool forward, bool longjump ) +void AudacityProject::OnCursorMove(double seekStep) { - const double seekStep = - (longjump ? mSeekLong : mSeekShort) * (forward ? 1.0 : -1.0); - if (IsAudioActive()) { SeekAudio(seekStep); } else { mLastSelectionAdjustment = ::wxGetLocalTimeMillis(); - SeekQuiet(seekStep, false, false, false, false); + SeekQuiet(seekStep, TIME_UNIT_SECONDS, SNAP_OFF, CURSOR_MOVE); } ModifyState(false); diff --git a/src/Menus.h b/src/Menus.h index 6b329cb9e..657bc89d3 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -544,21 +544,33 @@ void NextWindow(const CommandContext &context ); void OnResample(const CommandContext &context ); private: -void OnCursorLeft(bool shift, bool ctrl, bool keyup = false); -void OnCursorRight(bool shift, bool ctrl, bool keyup = false); -void OnCursorMove(bool forward, bool longjump); +enum SelectionOperation { + SELECTION_EXTEND, + SELECTION_CONTRACT, + CURSOR_MOVE +}; + +enum TimeUnit { + TIME_UNIT_SECONDS, + TIME_UNIT_PIXELS +}; + +void OnCursorLeft(SelectionOperation operation, bool keyup = false); +void OnCursorRight(SelectionOperation operation, bool keyup = false); +void OnCursorMove(double seekStep); void OnBoundaryMove(bool left, bool boundaryContract); // Handle small cursor and play head movements void SeekLeftOrRight -(bool left, bool shift, bool ctrl, bool keyup); +(double direction, SelectionOperation operation, bool keyup); void SeekAudio(double seekStep); void SeekQuiet -(double seekStep, bool isPixels, bool snapToTime, bool shift, bool ctrl); +(double seekStep, TimeUnit timeUnit, int snapToTime, + SelectionOperation operation); -double OffsetTime(double t, double offset, bool isPixels, bool snapToTime); +double OffsetTime(double t, double offset, TimeUnit timeUnit, int snapToTime); // Helper for moving by keyboard with snap-to-grid enabled double GridMove(double t, int minPix); From dab9ad812f028cf14f133f83e78f1b0f18dd0be7 Mon Sep 17 00:00:00 2001 From: James Crook Date: Wed, 14 Mar 2018 13:05:16 +0000 Subject: [PATCH 3/3] Condense SeekLeftOrRight code further. --- src/Menus.cpp | 452 ++++++++++++++++++++++---------------------------- src/Menus.h | 23 ++- 2 files changed, 213 insertions(+), 262 deletions(-) diff --git a/src/Menus.cpp b/src/Menus.cpp index 3089faa5a..bd62f034f 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -3129,22 +3129,22 @@ void AudacityProject::OnSkipEnd(const CommandContext &WXUNUSED(context) ) void AudacityProject::OnSeekLeftShort(const CommandContext &WXUNUSED(context) ) { - OnCursorLeft( CURSOR_MOVE ); + SeekLeftOrRight( DIRECTION_LEFT, CURSOR_MOVE ); } void AudacityProject::OnSeekRightShort(const CommandContext &WXUNUSED(context) ) { - OnCursorRight( CURSOR_MOVE ); + SeekLeftOrRight( DIRECTION_RIGHT, CURSOR_MOVE ); } void AudacityProject::OnSeekLeftLong(const CommandContext &WXUNUSED(context) ) { - OnCursorLeft( SELECTION_EXTEND ); + SeekLeftOrRight( DIRECTION_LEFT, SELECTION_EXTEND ); } void AudacityProject::OnSeekRightLong(const CommandContext &WXUNUSED(context) ) { - OnCursorRight( SELECTION_EXTEND ); + SeekLeftOrRight( DIRECTION_RIGHT, SELECTION_EXTEND ); } void AudacityProject::OnSelToStart(const CommandContext &WXUNUSED(context) ) @@ -3532,19 +3532,33 @@ void AudacityProject::HandleListSelection(Track *t, bool shift, bool ctrl, ModifyState(true); } - -void AudacityProject::OnCursorLeft(const CommandContext &context) +// If this returns true, then there was a key up, and nothing more to do, +// after this function has completed. +// (at most this function just does a ModifyState for the keyup) +bool AudacityProject::OnlyHandleKeyUp( const CommandContext &context ) { auto evt = context.pEvt; bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorLeft( CURSOR_MOVE, bKeyUp ); + + if( IsAudioActive() ) + return bKeyUp; + if( !bKeyUp ) + return false; + + ModifyState(false); + return true; +} + +void AudacityProject::OnCursorLeft(const CommandContext &context) +{ + if( !OnlyHandleKeyUp( context ) ) + SeekLeftOrRight( DIRECTION_LEFT, CURSOR_MOVE); } void AudacityProject::OnCursorRight(const CommandContext &context) { - auto evt = context.pEvt; - bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorRight( CURSOR_MOVE, bKeyUp ); + if( !OnlyHandleKeyUp( context ) ) + SeekLeftOrRight( DIRECTION_RIGHT, CURSOR_MOVE); } void AudacityProject::OnCursorShortJumpLeft(const CommandContext &WXUNUSED(context) ) @@ -3569,40 +3583,36 @@ void AudacityProject::OnCursorLongJumpRight(const CommandContext &WXUNUSED(conte void AudacityProject::OnSelSetExtendLeft(const CommandContext &WXUNUSED(context) ) { - OnBoundaryMove( true, false); + OnBoundaryMove( DIRECTION_LEFT); } void AudacityProject::OnSelSetExtendRight(const CommandContext &WXUNUSED(context) ) { - OnBoundaryMove( false, false); + OnBoundaryMove( DIRECTION_RIGHT); } void AudacityProject::OnSelExtendLeft(const CommandContext &context) { - auto evt = context.pEvt; - bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorLeft( SELECTION_EXTEND, bKeyUp ); + if( !OnlyHandleKeyUp( context ) ) + SeekLeftOrRight( DIRECTION_LEFT, SELECTION_EXTEND ); } void AudacityProject::OnSelExtendRight(const CommandContext &context) { - auto evt = context.pEvt; - bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorRight( SELECTION_EXTEND, bKeyUp ); + if( !OnlyHandleKeyUp( context ) ) + SeekLeftOrRight( DIRECTION_RIGHT, SELECTION_EXTEND ); } void AudacityProject::OnSelContractLeft(const CommandContext &context) { - auto evt = context.pEvt; - bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorRight( SELECTION_CONTRACT, bKeyUp ); + if( !OnlyHandleKeyUp( context ) ) + SeekLeftOrRight( DIRECTION_LEFT, SELECTION_CONTRACT ); } void AudacityProject::OnSelContractRight(const CommandContext &context) { - auto evt = context.pEvt; - bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - OnCursorLeft( SELECTION_CONTRACT, bKeyUp ); + if( !OnlyHandleKeyUp( context ) ) + SeekLeftOrRight( DIRECTION_RIGHT, SELECTION_CONTRACT ); } #include "tracks/ui/TimeShiftHandle.h" @@ -9014,165 +9024,193 @@ void AudacityProject::OnFullScreen(const CommandContext &WXUNUSED(context) ) mCommandManager.Check(wxT("FullScreenOnOff"), bChecked); } -void AudacityProject::OnCursorLeft(SelectionOperation operation, bool keyup) -{ - // PRL: What I found and preserved, strange though it be: - // During playback: jump depends on preferences and is independent of the zoom - // and does not vary if the key is held - // Else: jump depends on the zoom and gets bigger if the key is held - SeekLeftOrRight(-1.0, operation, keyup); -} - -void AudacityProject::OnCursorRight(SelectionOperation operation, bool keyup) -{ - // PRL: What I found and preserved, strange though it be: - // During playback: jump depends on preferences and is independent of the zoom - // and does not vary if the key is held - // Else: jump depends on the zoom and gets bigger if the key is held - SeekLeftOrRight(1.0, operation, keyup); -} - // Handle small cursor and play head movements void AudacityProject::SeekLeftOrRight -(double direction, SelectionOperation operation, bool keyup) +(double direction, SelectionOperation operation) { - if (IsAudioActive()) - { - if (keyup) - return; + // PRL: What I found and preserved, strange though it be: + // During playback: jump depends on preferences and is independent of the zoom + // and does not vary if the key is held + // Else: jump depends on the zoom and gets bigger if the key is held - if (operation == CURSOR_MOVE) - SeekAudio(mSeekShort * direction); - else if (operation == SELECTION_EXTEND) - SeekAudio(mSeekLong * direction); + if( IsAudioActive() ) + { + if( operation == CURSOR_MOVE ) + SeekWhenAudioActive(mSeekShort * direction); + else if( operation == SELECTION_EXTEND ) + SeekWhenAudioActive(mSeekLong * direction); + // Note: no action for CURSOR_CONTRACT + return; + } - return; - } + // If the last adjustment was very recent, we are + // holding the key down and should move faster. + const wxLongLong curtime = ::wxGetLocalTimeMillis(); + enum { MIN_INTERVAL = 50 }; + const bool fast = (curtime - mLastSelectionAdjustment < MIN_INTERVAL); - if (keyup) - { - ModifyState(false); - return; - } + mLastSelectionAdjustment = curtime; - // If the last adjustment was very recent, we are - // holding the key down and should move faster. - const wxLongLong curtime = ::wxGetLocalTimeMillis(); - enum { MIN_INTERVAL = 50 }; - const bool fast = (curtime - mLastSelectionAdjustment < MIN_INTERVAL); + // How much faster should the cursor move if shift is down? + enum { LARGER_MULTIPLIER = 4 }; + const double seekStep = (fast ? LARGER_MULTIPLIER : 1.0) * direction; - mLastSelectionAdjustment = curtime; - - // How much faster should the cursor move if shift is down? - enum { LARGER_MULTIPLIER = 4 }; - const double seekStep = (fast ? LARGER_MULTIPLIER : 1.0) * direction; - - int snapToTime = GetSnapTo(); - SeekQuiet(seekStep, TIME_UNIT_PIXELS, snapToTime, operation); + SeekWhenAudioInactive( seekStep, TIME_UNIT_PIXELS, operation); } -void AudacityProject::SeekAudio(double seekStep) +void AudacityProject::SeekWhenAudioActive(double seekStep) { #ifdef EXPERIMENTAL_IMPROVED_SEEKING - if (gAudioIO->GetLastPlaybackTime() < mLastSelectionAdjustment) { - // Allow time for the last seek to output a buffer before - // discarding samples again - // Do not advance mLastSelectionAdjustment - return; - } + if (gAudioIO->GetLastPlaybackTime() < mLastSelectionAdjustment) { + // Allow time for the last seek to output a buffer before + // discarding samples again + // Do not advance mLastSelectionAdjustment + return; + } #endif - mLastSelectionAdjustment = ::wxGetLocalTimeMillis(); + mLastSelectionAdjustment = ::wxGetLocalTimeMillis(); - gAudioIO->SeekStream(seekStep); + gAudioIO->SeekStream(seekStep); } -void AudacityProject::SeekQuiet -(double seekStep, TimeUnit timeUnit, int snapToTime, - SelectionOperation operation) + +void AudacityProject::OnBoundaryMove(int step) { - const double t0 = mViewInfo.selectedRegion.t0(); - const double t1 = mViewInfo.selectedRegion.t1(); - const double end = mTracks->GetEndTime(); + // step is negative, then is moving left. step positive, moving right. + // Move the left/right selection boundary, to expand the selection - if (operation == SELECTION_CONTRACT) - { - // Contract selection - // Reduce and constrain (counter-intuitive) - if (seekStep < 0) - { - mViewInfo.selectedRegion.setT1( - std::max(t0, OffsetTime(t1, seekStep, timeUnit, snapToTime))); + // If the last adjustment was very recent, we are + // holding the key down and should move faster. + wxLongLong curtime = ::wxGetLocalTimeMillis(); + int pixels = step; + if( curtime - mLastSelectionAdjustment < 50 ) + { + pixels *= 4; + } + mLastSelectionAdjustment = curtime; - // Make sure it's visible. - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); - } - else - { - mViewInfo.selectedRegion.setT0( - std::min(t1, OffsetTime(t0, seekStep, timeUnit, snapToTime))); + // we used to have a parameter boundaryContract to say if expanding or contracting. + // it is no longer needed. + bool bMoveT0 = (step < 0 );// ^ boundaryContract ; - // Make sure NEW position is in view. - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t0()); - } - GetTrackPanel()->Refresh(false); - } - else if (operation == SELECTION_EXTEND) - { - // Extend selection - // Expand and constrain - if (seekStep < 0) - { - mViewInfo.selectedRegion.setT0( - std::max(0.0, OffsetTime(t0, seekStep, timeUnit, snapToTime))); + if( IsAudioActive() ) + { + double indicator = gAudioIO->GetStreamTime(); + if( bMoveT0 ) + mViewInfo.selectedRegion.setT0(indicator, false); + else + mViewInfo.selectedRegion.setT1(indicator); - // Make sure it's visible. - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t0()); - } - else - { - mViewInfo.selectedRegion.setT1( - std::min(end, OffsetTime(t1, seekStep, timeUnit, snapToTime))); + ModifyState(false); + GetTrackPanel()->Refresh(false); + return; + } - // Make sure NEW position is in view. - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); - } - GetTrackPanel()->Refresh(false); - } - else if (operation == CURSOR_MOVE) - { - // Move the cursor - // Already in cursor mode? - if (mViewInfo.selectedRegion.isPoint()) - { - // Move and constrain - mViewInfo.selectedRegion.setT0( - std::max(0.0, - std::min(end, - OffsetTime(t0, seekStep, timeUnit, snapToTime))), - false // do not swap selection boundaries - ); - mViewInfo.selectedRegion.collapseToT0(); + const double t0 = mViewInfo.selectedRegion.t0(); + const double t1 = mViewInfo.selectedRegion.t1(); + const double end = mTracks->GetEndTime(); - // Move the visual cursor, avoiding an unnecessary complete redraw - GetTrackPanel()->DrawOverlays(false); - GetRulerPanel()->DrawOverlays(false); + double newT = mViewInfo.OffsetTimeByPixels( bMoveT0 ? t0 : t1, pixels); + // constrain to be in the track limits. + newT = std::max( 0.0, newT ); + newT = std::min( newT, end); + // optionally constrain to be a contraction, i.e. so t0/t1 do not cross over + //if( boundaryContract ) + // newT = bMoveT0 ? std::min( t1, newT ) : std::max( t0, newT ); - // This updates the selection shown on the selection bar, and the play region - TP_DisplaySelection(); - } - else - { - // Transition to cursor mode. - if (seekStep < 0) - mViewInfo.selectedRegion.collapseToT0(); - else - mViewInfo.selectedRegion.collapseToT1(); - GetTrackPanel()->Refresh(false); - } + // Actually move + if( bMoveT0 ) + mViewInfo.selectedRegion.setT0( newT ); + else + mViewInfo.selectedRegion.setT1( newT ); - // Make sure NEW position is in view - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); - } + // Ensure it is visible, and refresh. + GetTrackPanel()->ScrollIntoView(newT); + GetTrackPanel()->Refresh(false); + + ModifyState(false); +} + +void AudacityProject::SeekWhenAudioInactive +(double seekStep, TimeUnit timeUnit, +SelectionOperation operation) +{ + if( operation == CURSOR_MOVE ) + { + MoveWhenAudioInactive( seekStep, timeUnit); + return; + } + + int snapToTime = GetSnapTo(); + const double t0 = mViewInfo.selectedRegion.t0(); + const double t1 = mViewInfo.selectedRegion.t1(); + const double end = mTracks->GetEndTime(); + + // Is it t0 or t1 moving? + bool bMoveT0 = ( operation == SELECTION_CONTRACT ) ^ ( seekStep < 0 ); + // newT is where we want to move to + double newT = OffsetTime( bMoveT0 ? t0 : t1, seekStep, timeUnit, snapToTime); + // constrain to be in the track limits. + newT = std::max( 0.0, newT ); + newT = std::min( newT, end); + // optionally constrain to be a contraction, i.e. so t0/t1 do not cross over + if( operation == SELECTION_CONTRACT ) + newT = bMoveT0 ? std::min( t1, newT ) : std::max( t0, newT ); + + // Actually move + if( bMoveT0 ) + mViewInfo.selectedRegion.setT0( newT ); + else + mViewInfo.selectedRegion.setT1( newT ); + + // Ensure it is visible, and refresh. + GetTrackPanel()->ScrollIntoView(newT); + GetTrackPanel()->Refresh(false); +} + +// Moving a cursor, and collapsed selection. +void AudacityProject::MoveWhenAudioInactive +(double seekStep, TimeUnit timeUnit) +{ + // If TIME_UNIT_SECONDS, snap-to will be off. + int snapToTime = GetSnapTo(); + const double t0 = mViewInfo.selectedRegion.t0(); + const double t1 = mViewInfo.selectedRegion.t1(); + const double end = mTracks->GetEndTime(); + + // Move the cursor + // Already in cursor mode? + if( mViewInfo.selectedRegion.isPoint() ) + { + double newT = OffsetTime(t0, seekStep, timeUnit, snapToTime); + // constrain. + newT = std::max(0.0, newT); + newT = std::min(newT, end); + // Move + mViewInfo.selectedRegion.setT0( + newT, + false); // do not swap selection boundaries + mViewInfo.selectedRegion.collapseToT0(); + + // Move the visual cursor, avoiding an unnecessary complete redraw + GetTrackPanel()->DrawOverlays(false); + GetRulerPanel()->DrawOverlays(false); + + // This updates the selection shown on the selection bar, and the play region + TP_DisplaySelection(); + } else + { + // Transition to cursor mode. + if( seekStep < 0 ) + mViewInfo.selectedRegion.collapseToT0(); + else + mViewInfo.selectedRegion.collapseToT1(); + GetTrackPanel()->Refresh(false); + } + + // Make sure NEW position is in view + GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); + return; } double AudacityProject::OffsetTime @@ -9211,111 +9249,17 @@ double AudacityProject::GridMove(double t, int minPix) return result; } -void AudacityProject::OnBoundaryMove(bool left, bool boundaryContract) -{ - // Move the left/right selection boundary, to either expand or contract the selection - // left=true: operate on left boundary; left=false: operate on right boundary - // boundaryContract=true: contract region; boundaryContract=false: expand region. - - // If the last adjustment was very recent, we are - // holding the key down and should move faster. - wxLongLong curtime = ::wxGetLocalTimeMillis(); - int pixels = 1; - if( curtime - mLastSelectionAdjustment < 50 ) - { - pixels = 4; - } - mLastSelectionAdjustment = curtime; - - if (IsAudioActive()) - { - double indicator = gAudioIO->GetStreamTime(); - if (left) - mViewInfo.selectedRegion.setT0(indicator, false); - else - mViewInfo.selectedRegion.setT1(indicator); - - ModifyState(false); - GetTrackPanel()->Refresh(false); - } - else - { - // BOUNDARY MOVEMENT - // Contract selection from the right to the left - if( boundaryContract ) - { - if (left) { - // Reduce and constrain left boundary (counter-intuitive) - // Move the left boundary by at most the desired number of pixels, - // but not past the right - mViewInfo.selectedRegion.setT0( - std::min(mViewInfo.selectedRegion.t1(), - mViewInfo.OffsetTimeByPixels( - mViewInfo.selectedRegion.t0(), - pixels))); - - // Make sure it's visible - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t0()); - } - else - { - // Reduce and constrain right boundary (counter-intuitive) - // Move the right boundary by at most the desired number of pixels, - // but not past the left - mViewInfo.selectedRegion.setT1( - std::max(mViewInfo.selectedRegion.t0(), - mViewInfo.OffsetTimeByPixels( - mViewInfo.selectedRegion.t1(), - -pixels))); - - // Make sure it's visible - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); - } - } - // BOUNDARY MOVEMENT - // Extend selection toward the left - else - { - if (left) { - // Expand and constrain left boundary - mViewInfo.selectedRegion.setT0( - std::max(0.0, - mViewInfo.OffsetTimeByPixels( - mViewInfo.selectedRegion.t0(), - -pixels))); - - // Make sure it's visible - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t0()); - } - else - { - // Expand and constrain right boundary - const double end = mTracks->GetEndTime(); - mViewInfo.selectedRegion.setT1( - std::min(end, - mViewInfo.OffsetTimeByPixels( - mViewInfo.selectedRegion.t1(), - pixels))); - - // Make sure it's visible - GetTrackPanel()->ScrollIntoView(mViewInfo.selectedRegion.t1()); - } - } - GetTrackPanel()->Refresh( false ); - ModifyState(false); - } -} // Move the cursor forward or backward, while paused or while playing. void AudacityProject::OnCursorMove(double seekStep) { if (IsAudioActive()) { - SeekAudio(seekStep); + SeekWhenAudioActive(seekStep); } else { mLastSelectionAdjustment = ::wxGetLocalTimeMillis(); - SeekQuiet(seekStep, TIME_UNIT_SECONDS, SNAP_OFF, CURSOR_MOVE); + MoveWhenAudioInactive(seekStep, TIME_UNIT_SECONDS); } ModifyState(false); diff --git a/src/Menus.h b/src/Menus.h index 657bc89d3..af32e1941 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -550,25 +550,32 @@ enum SelectionOperation { CURSOR_MOVE }; +enum CursorDirection { + DIRECTION_LEFT = -1, + DIRECTION_RIGHT = +1 +}; + enum TimeUnit { TIME_UNIT_SECONDS, TIME_UNIT_PIXELS }; -void OnCursorLeft(SelectionOperation operation, bool keyup = false); -void OnCursorRight(SelectionOperation operation, bool keyup = false); +bool OnlyHandleKeyUp( const CommandContext &context ); void OnCursorMove(double seekStep); -void OnBoundaryMove(bool left, bool boundaryContract); +void OnBoundaryMove(int step); // Handle small cursor and play head movements void SeekLeftOrRight -(double direction, SelectionOperation operation, bool keyup); +(double direction, SelectionOperation operation); -void SeekAudio(double seekStep); - -void SeekQuiet -(double seekStep, TimeUnit timeUnit, int snapToTime, +void SeekWhenAudioActive(double seekStep); +void SeekWhenAudioInactive +(double seekStep, TimeUnit timeUnit, SelectionOperation operation); +void MoveWhenAudioInactive +(double seekStep, TimeUnit timeUnit); + + double OffsetTime(double t, double offset, TimeUnit timeUnit, int snapToTime);