mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
Implement drag-scrub, compatibly with the existing move-scrub...
Also fix scroll-scrub and remove obsolete mouse preferences messages
This commit is contained in:
commit
9f8e34ad0f
@ -402,6 +402,14 @@ struct AudioIO::ScrubQueue
|
||||
}
|
||||
~ScrubQueue() {}
|
||||
|
||||
double LastTimeInQueue() const
|
||||
{
|
||||
// Needed by the main thread sometimes
|
||||
wxCriticalSectionLocker locker(mUpdating);
|
||||
const Entry &previous = mEntries[(mLeadingIdx + Size - 1) % Size];
|
||||
return previous.mS1 / mRate;
|
||||
}
|
||||
|
||||
bool Producer(double end, double maxSpeed, bool bySpeed, bool maySkip)
|
||||
{
|
||||
// Main thread indicates a scrubbing interval
|
||||
@ -670,7 +678,7 @@ private:
|
||||
const double mRate;
|
||||
const long mMinStutter;
|
||||
wxLongLong mLastScrubTimeMillis;
|
||||
wxCriticalSection mUpdating;
|
||||
mutable wxCriticalSection mUpdating;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -2426,6 +2434,15 @@ bool AudioIO::EnqueueScrubBySignedSpeed(double speed, double maxSpeed, bool mayS
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
double AudioIO::GetLastTimeInScrubQueue() const
|
||||
{
|
||||
if (mScrubQueue)
|
||||
return mScrubQueue->LastTimeInQueue();
|
||||
else
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool AudioIO::IsBusy()
|
||||
|
@ -208,6 +208,10 @@ class AUDACITY_DLL_API AudioIO final {
|
||||
* Return true if some work was really enqueued.
|
||||
*/
|
||||
bool EnqueueScrubBySignedSpeed(double speed, double maxSpeed, bool maySkip);
|
||||
|
||||
/** \brief return the ending time of the last enqueued scrub interval.
|
||||
*/
|
||||
double GetLastTimeInScrubQueue() const;
|
||||
#endif
|
||||
|
||||
/** \brief Returns true if audio i/o is busy starting, stopping, playing,
|
||||
|
@ -173,7 +173,6 @@
|
||||
// The following enable parts of the scrubbing user interface.
|
||||
#define EXPERIMENTAL_SCRUBBING_BASIC
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
||||
#define EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
#define EXPERIMENTAL_SCRUBBING_SCROLL_WHEEL
|
||||
#endif
|
||||
#endif
|
||||
|
@ -2281,8 +2281,13 @@ void AudacityProject::OnRecordAppend()
|
||||
GetControlToolBar()->OnRecord(evt);
|
||||
}
|
||||
|
||||
// The code for "OnPlayStopSelect" is simply the code of "OnPlayStop" and "OnStopSelect" merged.
|
||||
void AudacityProject::OnPlayStopSelect()
|
||||
{
|
||||
DoPlayStopSelect(false, false);
|
||||
}
|
||||
|
||||
// The code for "OnPlayStopSelect" is simply the code of "OnPlayStop" and "OnStopSelect" merged.
|
||||
void AudacityProject::DoPlayStopSelect(bool click, bool shift)
|
||||
{
|
||||
wxCommandEvent evt;
|
||||
ControlToolBar *toolbar = GetControlToolBar();
|
||||
@ -2291,7 +2296,36 @@ void AudacityProject::OnPlayStopSelect()
|
||||
if (gAudioIO->IsStreamActive(GetAudioIOToken())) {
|
||||
toolbar->SetPlay(false); //Pops
|
||||
toolbar->SetStop(true); //Pushes stop down
|
||||
mViewInfo.selectedRegion.setT0(gAudioIO->GetStreamTime(), false);
|
||||
|
||||
// change the selection
|
||||
auto time = gAudioIO->GetStreamTime();
|
||||
auto &selection = mViewInfo.selectedRegion;
|
||||
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)
|
||||
// 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);
|
||||
|
||||
ModifyState(false); // without bWantsAutoSave
|
||||
toolbar->OnStop(evt);
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ void OnSeekRightLong();
|
||||
|
||||
bool MakeReadyToPlay(bool loop = false, bool cutpreview = false); // Helper function that sets button states etc.
|
||||
void OnPlayStop();
|
||||
void DoPlayStopSelect(bool click, bool shift);
|
||||
void OnPlayStopSelect();
|
||||
void OnPlayOneSecond();
|
||||
void OnPlayToSelection();
|
||||
|
@ -5364,7 +5364,6 @@ void AudacityProject::PlaybackScroller::OnTimer(wxCommandEvent &event)
|
||||
// Let other listeners get the notification
|
||||
event.Skip();
|
||||
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
if (mActive && mProject->IsAudioActive())
|
||||
{
|
||||
// Pan the view, so that we center the play indicator.
|
||||
@ -5382,5 +5381,4 @@ void AudacityProject::PlaybackScroller::OnTimer(wxCommandEvent &event)
|
||||
viewInfo.h = std::max(0.0, viewInfo.h);
|
||||
trackPanel->Refresh(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -5472,12 +5472,9 @@ void TrackPanel::HandleWheelRotation(wxMouseEvent & event)
|
||||
(event.m_wheelDelta > 0 ? (double)event.m_wheelDelta : 120.0);
|
||||
|
||||
if (event.ShiftDown()
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
// Don't pan during smooth scrolling. That would conflict with keeping
|
||||
// the play indicator centered.
|
||||
&& !GetProject()->GetScrubber().IsScrollScrubbing()
|
||||
#endif
|
||||
)
|
||||
&& !GetProject()->GetScrubber().IsScrollScrubbing())
|
||||
{
|
||||
// MM: Scroll left/right when used with Shift key down
|
||||
mListener->TP_ScrollWindow(
|
||||
@ -5506,15 +5503,12 @@ void TrackPanel::HandleWheelRotation(wxMouseEvent & event)
|
||||
// Time corresponding to mouse position
|
||||
wxCoord xx;
|
||||
double center_h;
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
if (GetProject()->GetScrubber().IsScrollScrubbing()) {
|
||||
// Expand or contract about the center, ignoring mouse position
|
||||
center_h = mViewInfo->h + (GetScreenEndTime() - mViewInfo->h) / 2.0;
|
||||
xx = mViewInfo->TimeToPosition(center_h, trackLeftEdge);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
else {
|
||||
xx = event.m_x;
|
||||
center_h = mViewInfo->PositionToTime(xx, trackLeftEdge);
|
||||
}
|
||||
|
@ -110,13 +110,6 @@ void MousePrefs::CreateList()
|
||||
AddItem(_("Left-Drag"), _("Select"), _("Set Selection Range"));
|
||||
AddItem(_("Shift-Left-Click"), _("Select"), _("Extend Selection Range"));
|
||||
AddItem(_("Left-Double-Click"), _("Select"), _("Select Clip or Entire Track"));
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
||||
AddItem(CTRL + _("-Left-Click"), _("Select"), _("Scrub"));
|
||||
AddItem(CTRL + _("-Left-Drag"), _("Select"), _("Seek"));
|
||||
#endif
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
AddItem(CTRL + _("-Left-Double-Click"), _("Select"), _("Scroll-scrub"));
|
||||
#endif
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SCROLL_WHEEL
|
||||
AddItem(_("Wheel-Rotate"), _("Select"), _("Change scrub speed"));
|
||||
#endif
|
||||
|
@ -188,11 +188,7 @@ namespace {
|
||||
|
||||
void Scrubber::MarkScrubStart(
|
||||
// Assume xx is relative to the left edge of TrackPanel!
|
||||
wxCoord xx
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
, bool smoothScrolling
|
||||
#endif
|
||||
, bool alwaysSeeking
|
||||
wxCoord xx, bool smoothScrolling, bool alwaysSeeking
|
||||
)
|
||||
{
|
||||
UncheckAllMenuItems();
|
||||
@ -200,9 +196,7 @@ void Scrubber::MarkScrubStart(
|
||||
// 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
|
||||
SetScrollScrubbing (smoothScrolling);
|
||||
#endif
|
||||
mSmoothScrollingScrub = smoothScrolling;
|
||||
mAlwaysSeeking = alwaysSeeking;
|
||||
|
||||
ControlToolBar * const ctb = mProject->GetControlToolBar();
|
||||
@ -236,6 +230,9 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
|
||||
if (IsScrubbing())
|
||||
return false;
|
||||
else {
|
||||
const auto state = ::wxGetMouseState();
|
||||
mDragging = state.LeftIsDown();
|
||||
|
||||
const bool busy = gAudioIO->IsBusy();
|
||||
if (busy && gAudioIO->GetNumCaptureChannels() > 0) {
|
||||
// Do not stop recording, and don't try to start scrubbing after
|
||||
@ -265,6 +262,14 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
|
||||
mScrubStartPosition = position;
|
||||
}
|
||||
|
||||
if (mDragging && mSmoothScrollingScrub) {
|
||||
auto delta = time0 - time1;
|
||||
time0 = std::max(0.0, std::min(maxTime,
|
||||
(viewInfo.h + mProject->GetScreenEndTime()) / 2
|
||||
));
|
||||
time1 = time0 + delta;
|
||||
}
|
||||
|
||||
AudioIOStartStreamOptions options(mProject->GetDefaultPlayOptions());
|
||||
options.timeTrack = NULL;
|
||||
options.scrubDelay = (kTimerInterval / 1000.0);
|
||||
@ -278,8 +283,10 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
|
||||
p->GetTranscriptionToolBar()->GetPlaySpeed();
|
||||
}
|
||||
#else
|
||||
// That idea seems unpopular... just make it one
|
||||
mMaxScrubSpeed = options.maxScrubSpeed = 1.0;
|
||||
// That idea seems unpopular... just make it one for move-scrub,
|
||||
// but big for drag-scrub
|
||||
mMaxScrubSpeed = options.maxScrubSpeed =
|
||||
mDragging ? AudioIO::GetMaxScrubSpeed() : 1.0;
|
||||
#endif
|
||||
options.maxScrubTime = mProject->GetTracks()->GetEndTime();
|
||||
ControlToolBar::PlayAppearance appearance =
|
||||
@ -303,8 +310,11 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
|
||||
// Wait to test again
|
||||
mScrubStartClockTimeMillis = ::wxGetLocalTimeMillis();
|
||||
|
||||
if (IsScrubbing())
|
||||
if (IsScrubbing()) {
|
||||
mProject->GetPlaybackScroller().Activate(mSmoothScrollingScrub);
|
||||
mScrubHasFocus = true;
|
||||
mLastScrubPosition = xx;
|
||||
}
|
||||
|
||||
// Return true whether we started scrub, or are still waiting to decide.
|
||||
return true;
|
||||
@ -313,13 +323,19 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx)
|
||||
|
||||
void Scrubber::ContinueScrubbing()
|
||||
{
|
||||
const wxMouseState state(::wxGetMouseState());
|
||||
|
||||
if (mDragging && !state.LeftIsDown()) {
|
||||
// Stop and set cursor
|
||||
mProject->DoPlayStopSelect(true, state.ShiftDown());
|
||||
return;
|
||||
}
|
||||
|
||||
// Thus scrubbing relies mostly on periodic polling of mouse and keys,
|
||||
// not event notifications. But there are a few event handlers that
|
||||
// leave messages for this routine, in mScrubSeekPress and in mScrubHasFocus.
|
||||
|
||||
// Seek only when the pointer is in the panel. Else, scrub.
|
||||
const wxMouseState state(::wxGetMouseState());
|
||||
TrackPanel *const trackPanel = mProject->GetTrackPanel();
|
||||
|
||||
// Decide whether to skip play, because either mouse is down now,
|
||||
@ -337,26 +353,32 @@ void Scrubber::ContinueScrubbing()
|
||||
}
|
||||
|
||||
const wxPoint position = trackPanel->ScreenToClient(state.GetPosition());
|
||||
// When we don't have focus, enqueue silent scrubs until we regain focus.
|
||||
const auto &viewInfo = mProject->GetViewInfo();
|
||||
|
||||
bool result = false;
|
||||
if (!mScrubHasFocus)
|
||||
// When we don't have focus, enqueue silent scrubs until we regain focus.
|
||||
result = gAudioIO->EnqueueScrubBySignedSpeed(0, mMaxScrubSpeed, false);
|
||||
else if (mDragging && mSmoothScrollingScrub) {
|
||||
const auto lastTime = gAudioIO->GetLastTimeInScrubQueue();
|
||||
const auto delta = mLastScrubPosition - position.x;
|
||||
const double time = viewInfo.OffsetTimeByPixels(lastTime, delta);
|
||||
result = gAudioIO->EnqueueScrubByPosition(time, mMaxScrubSpeed, false);
|
||||
mLastScrubPosition = position.x;
|
||||
}
|
||||
else {
|
||||
const double time = mProject->GetViewInfo().PositionToTime(position.x, trackPanel->GetLeftOffset());
|
||||
|
||||
const double time = viewInfo.PositionToTime(position.x, trackPanel->GetLeftOffset());
|
||||
if (seek)
|
||||
// Cause OnTimer() to suppress the speed display
|
||||
mScrubSpeedDisplayCountdown = 1;
|
||||
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
if (mSmoothScrollingScrub) {
|
||||
const double speed = FindScrubSpeed(seek, time);
|
||||
result = gAudioIO->EnqueueScrubBySignedSpeed(speed, mMaxScrubSpeed, seek);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
result = gAudioIO->EnqueueScrubByPosition
|
||||
(time, seek ? 1.0 : mMaxScrubSpeed, seek);
|
||||
(time, seek ? 1.0 : mMaxScrubSpeed, seek);
|
||||
}
|
||||
|
||||
if (result)
|
||||
@ -364,12 +386,9 @@ void Scrubber::ContinueScrubbing()
|
||||
// else, if seek requested, try again at a later time when we might
|
||||
// enqueue a long enough stutter
|
||||
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
if (mSmoothScrollingScrub)
|
||||
;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
else {
|
||||
if (mScrubSpeedDisplayCountdown > 0)
|
||||
--mScrubSpeedDisplayCountdown;
|
||||
}
|
||||
@ -380,7 +399,8 @@ void Scrubber::StopScrubbing()
|
||||
UncheckAllMenuItems();
|
||||
|
||||
mScrubStartPosition = -1;
|
||||
SetScrollScrubbing (false);
|
||||
mProject->GetPlaybackScroller().Activate(false);
|
||||
mDragging = false;
|
||||
|
||||
if (!IsScrubbing())
|
||||
{
|
||||
@ -391,12 +411,11 @@ void Scrubber::StopScrubbing()
|
||||
}
|
||||
|
||||
mProject->GetRulerPanel()->HideQuickPlayIndicator();
|
||||
}
|
||||
|
||||
void Scrubber::SetScrollScrubbing(bool scrollScrubbing)
|
||||
{
|
||||
mSmoothScrollingScrub = scrollScrubbing;
|
||||
mProject->GetPlaybackScroller().Activate(scrollScrubbing);
|
||||
// Need this in case ruler gets the mouse-up event after escaping scrubbing:
|
||||
// prevent reappearance of the
|
||||
// quick play guideline
|
||||
mProject->GetRulerPanel()->IgnoreMouseUp();
|
||||
}
|
||||
|
||||
bool Scrubber::IsScrubbing() const
|
||||
@ -408,24 +427,22 @@ bool Scrubber::IsScrubbing() const
|
||||
else {
|
||||
const_cast<Scrubber&>(*this).mScrubToken = -1;
|
||||
const_cast<Scrubber&>(*this).mScrubStartPosition = -1;
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
// Don't call SetScrollScrubbing
|
||||
const_cast<Scrubber&>(*this).mSmoothScrollingScrub = false;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Scrubber::ShouldDrawScrubSpeed()
|
||||
{
|
||||
if (mDragging)
|
||||
return false;
|
||||
|
||||
return IsScrubbing() &&
|
||||
mScrubHasFocus && (
|
||||
// Draw for (non-scroll) scrub, sometimes, but never for seek
|
||||
(!PollIsSeeking() && mScrubSpeedDisplayCountdown > 0)
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
// Draw always for scroll-scrub and for scroll-seek
|
||||
|| mSmoothScrollingScrub
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
@ -439,6 +456,10 @@ double Scrubber::FindScrubSpeed(bool seeking, double time) const
|
||||
|
||||
void Scrubber::HandleScrollWheel(int steps)
|
||||
{
|
||||
if (mDragging)
|
||||
// Not likely you would spin it with the left button down, but...
|
||||
return;
|
||||
|
||||
const int newLogMaxScrubSpeed = mLogMaxScrubSpeed + steps;
|
||||
static const double maxScrubSpeedBase =
|
||||
pow(2.0, 1.0 / ScrubSpeedStepsPerOctave);
|
||||
@ -447,9 +468,7 @@ void Scrubber::HandleScrollWheel(int steps)
|
||||
newSpeed <= AudioIO::GetMaxScrubSpeed()) {
|
||||
mLogMaxScrubSpeed = newLogMaxScrubSpeed;
|
||||
mMaxScrubSpeed = newSpeed;
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
if (!mSmoothScrollingScrub)
|
||||
#endif
|
||||
// Show the speed for one second
|
||||
mScrubSpeedDisplayCountdown = kOneSecondCountdown + 1;
|
||||
}
|
||||
@ -472,7 +491,8 @@ void Scrubber::Forwarder::OnMouse(wxMouseEvent &event)
|
||||
if (isScrubbing && !event.HasAnyModifiers()) {
|
||||
if(event.LeftDown() ||
|
||||
(event.LeftIsDown() && event.Dragging())) {
|
||||
scrubber.mScrubSeekPress = true;
|
||||
if (!scrubber.mDragging)
|
||||
scrubber.mScrubSeekPress = true;
|
||||
auto xx = ruler->ScreenToClient(::wxGetMousePosition()).x;
|
||||
ruler->UpdateQuickPlayPos(xx);
|
||||
ruler->ShowQuickPlayIndicator();
|
||||
@ -544,11 +564,9 @@ void ScrubbingOverlay::Draw(OverlayPanel &, wxDC &dc)
|
||||
// (b) Error alerts
|
||||
// So they were changed to 'orange' and 'lime'.
|
||||
static const wxColour clrNoScroll(215, 162, 0), clrScroll(0, 204, 153);
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
if (scrubber.IsScrollScrubbing())
|
||||
dc.SetTextForeground(clrScroll);
|
||||
else
|
||||
#endif
|
||||
dc.SetTextForeground(clrNoScroll);
|
||||
|
||||
dc.DrawText(mLastScrubSpeedText, mLastScrubRect.GetX(), mLastScrubRect.GetY());
|
||||
@ -565,12 +583,13 @@ void ScrubbingOverlay::OnTimer(wxCommandEvent &event)
|
||||
auto position = ::wxGetMousePosition();
|
||||
|
||||
{
|
||||
auto xx = ruler->ScreenToClient(position).x;
|
||||
ruler->UpdateQuickPlayPos(xx);
|
||||
if(scrubber.HasStartedScrubbing()) {
|
||||
auto xx = ruler->ScreenToClient(position).x;
|
||||
ruler->UpdateQuickPlayPos(xx);
|
||||
|
||||
if(!isScrubbing && scrubber.HasStartedScrubbing()) {
|
||||
// Really start scrub if motion is far enough
|
||||
scrubber.MaybeStartScrubbing(xx);
|
||||
if (!isScrubbing)
|
||||
// Really start scrub if motion is far enough
|
||||
scrubber.MaybeStartScrubbing(xx);
|
||||
}
|
||||
|
||||
if (!isScrubbing) {
|
||||
@ -603,23 +622,17 @@ void ScrubbingOverlay::OnTimer(wxCommandEvent &event)
|
||||
// Find the text
|
||||
const double maxScrubSpeed = GetScrubber().GetMaxScrubSpeed();
|
||||
const double speed =
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
scrubber.IsScrollScrubbing()
|
||||
? scrubber.FindScrubSpeed
|
||||
(seeking, mProject->GetViewInfo().PositionToTime(position.x, trackPanel->GetLeftOffset()))
|
||||
:
|
||||
#endif
|
||||
maxScrubSpeed;
|
||||
: maxScrubSpeed;
|
||||
|
||||
const wxChar *format =
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
scrubber.IsScrollScrubbing()
|
||||
? seeking
|
||||
? wxT("%+.2fX")
|
||||
: wxT("%+.2f")
|
||||
:
|
||||
#endif
|
||||
wxT("%.2f");
|
||||
: wxT("%.2f");
|
||||
|
||||
mNextScrubSpeedText = wxString::Format(format, speed);
|
||||
|
||||
@ -657,7 +670,7 @@ Scrubber &ScrubbingOverlay::GetScrubber()
|
||||
|
||||
bool Scrubber::PollIsSeeking()
|
||||
{
|
||||
return mAlwaysSeeking || ::wxGetMouseState().LeftIsDown();
|
||||
return !mDragging && (mAlwaysSeeking || ::wxGetMouseState().LeftIsDown());
|
||||
}
|
||||
|
||||
void Scrubber::DoScrub(bool scroll, bool seek)
|
||||
@ -677,7 +690,8 @@ void Scrubber::DoScrub(bool scroll, bool seek)
|
||||
MarkScrubStart(xx, scroll, seek);
|
||||
}
|
||||
else if(!match) {
|
||||
SetScrollScrubbing(scroll);
|
||||
mSmoothScrollingScrub = scroll;
|
||||
mProject->GetPlaybackScroller().Activate(scroll);
|
||||
mAlwaysSeeking = seek;
|
||||
UncheckAllMenuItems();
|
||||
CheckMenuItem();
|
||||
|
@ -29,11 +29,8 @@ public:
|
||||
|
||||
// Assume xx is relative to the left edge of TrackPanel!
|
||||
void MarkScrubStart(
|
||||
wxCoord xx
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
, bool smoothScrolling
|
||||
#endif
|
||||
, bool alwaysSeeking // if false, can switch seeking or scrubbing
|
||||
wxCoord xx, bool smoothScrolling,
|
||||
bool alwaysSeeking // if false, can switch seeking or scrubbing
|
||||
// by mouse button state
|
||||
);
|
||||
|
||||
@ -57,7 +54,6 @@ public:
|
||||
|
||||
bool IsScrollScrubbing() const // If true, implies HasStartedScrubbing()
|
||||
{ return mSmoothScrollingScrub; }
|
||||
void SetScrollScrubbing(bool scrollScrubbing);
|
||||
|
||||
bool IsAlwaysSeeking() const
|
||||
{ return mAlwaysSeeking; }
|
||||
@ -113,10 +109,12 @@ private:
|
||||
bool mScrubHasFocus;
|
||||
int mScrubSpeedDisplayCountdown;
|
||||
wxCoord mScrubStartPosition;
|
||||
wxCoord mLastScrubPosition {};
|
||||
double mMaxScrubSpeed;
|
||||
bool mScrubSeekPress;
|
||||
bool mSmoothScrollingScrub;
|
||||
bool mAlwaysSeeking{};
|
||||
bool mAlwaysSeeking {};
|
||||
bool mDragging {};
|
||||
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SCROLL_WHEEL
|
||||
int mLogMaxScrubSpeed;
|
||||
|
@ -2326,6 +2326,17 @@ bool AdornedRulerPanel::IsWithinMarker(int mousePosX, double markerTime)
|
||||
|
||||
void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
||||
{
|
||||
if (mIgnoreMouseUp) {
|
||||
if (evt.Dragging())
|
||||
return;
|
||||
else if (evt.ButtonUp()) {
|
||||
mIgnoreMouseUp = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
mIgnoreMouseUp = false;
|
||||
}
|
||||
|
||||
// PRL: why do I need these two lines on Windows but not on Mac?
|
||||
if (evt.ButtonDown(wxMOUSE_BTN_ANY))
|
||||
SetFocus();
|
||||
@ -2654,10 +2665,12 @@ void AdornedRulerPanel::HandleQPRelease(wxMouseEvent &evt)
|
||||
if (mDoubleClick)
|
||||
return;
|
||||
|
||||
HideQuickPlayIndicator();
|
||||
|
||||
if (HasCapture())
|
||||
ReleaseMouse();
|
||||
else
|
||||
return;
|
||||
|
||||
HideQuickPlayIndicator();
|
||||
|
||||
mCaptureState = CaptureState{};
|
||||
|
||||
|
@ -350,6 +350,7 @@ public:
|
||||
void ShowQuickPlayIndicator();
|
||||
void HideQuickPlayIndicator();
|
||||
void UpdateQuickPlayPos(wxCoord &mousPosX);
|
||||
void IgnoreMouseUp() { mIgnoreMouseUp = true; }
|
||||
|
||||
private:
|
||||
void OnCapture(wxCommandEvent & evt);
|
||||
@ -531,6 +532,7 @@ private:
|
||||
mutable wxFont mButtonFont;
|
||||
|
||||
bool mDoubleClick {};
|
||||
bool mIgnoreMouseUp {};
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user