mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-25 16:48:44 +02:00
Scrubbing phase 2. Scrub starts with click on the indicator in the ruler...
... and works in any of the six tools. Click and drag in select tool during scrub works just as when not scrubbing. Seeks now only if you left-click or drag in the ruler, but this may change. Mouse motion anywhere on the screen controls scrub as before. No mouse clicks in TrackPanel are used by scrubbing. The Ctrl-Click in TrackPanel is now unused. Should 2.1.0 behavior be restored? That was click to quick play, redundant with click in the (lower part of) the ruler.
This commit is contained in:
parent
4deb90c633
commit
cd57e0a26c
@ -1525,13 +1525,7 @@ void TrackPanel::SetCursorAndTipWhenSelectTool( Track * t,
|
|||||||
// If not shift-down and not snapping center, then
|
// If not shift-down and not snapping center, then
|
||||||
// choose boundaries only in snapping tolerance,
|
// choose boundaries only in snapping tolerance,
|
||||||
// and may choose center.
|
// and may choose center.
|
||||||
// But don't change the cursor when scrubbing.
|
|
||||||
SelectionBoundary boundary =
|
SelectionBoundary boundary =
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
|
||||||
GetProject()->GetScrubber().IsScrubbing()
|
|
||||||
? SBNone
|
|
||||||
:
|
|
||||||
#endif
|
|
||||||
ChooseBoundary(event, t, rect, !bShiftDown, !bShiftDown);
|
ChooseBoundary(event, t, rect, !bShiftDown, !bShiftDown);
|
||||||
|
|
||||||
#ifdef USE_MIDI
|
#ifdef USE_MIDI
|
||||||
@ -1705,14 +1699,7 @@ void TrackPanel::HandleCursor(const wxMouseEvent & event)
|
|||||||
|
|
||||||
tip = ttb->GetMessageForTool(tool);
|
tip = ttb->GetMessageForTool(tool);
|
||||||
|
|
||||||
const auto &scrubber = GetProject()->GetScrubber();
|
if( tool != selectTool )
|
||||||
if (scrubber.HasStartedScrubbing()) {
|
|
||||||
if (scrubber.IsScrollScrubbing())
|
|
||||||
tip = _("Move to adjust speed, click to skip, ESC to stop.");
|
|
||||||
else
|
|
||||||
tip = _("Move to scrub, click to seek, ESC to stop.");
|
|
||||||
}
|
|
||||||
else if( tool != selectTool )
|
|
||||||
{
|
{
|
||||||
// We don't include the select tool in
|
// We don't include the select tool in
|
||||||
// SetCursorAndTipByTool() because it's more complex than
|
// SetCursorAndTipByTool() because it's more complex than
|
||||||
@ -1773,11 +1760,7 @@ void TrackPanel::HandleSelect(wxMouseEvent & event)
|
|||||||
mFreqSelMode = FREQ_SEL_INVALID;
|
mFreqSelMode = FREQ_SEL_INVALID;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} else if (event.LeftDClick() && !event.ShiftDown()
|
} else if (event.LeftDClick() && !event.ShiftDown()) {
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
|
||||||
&& !event.CmdDown()
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
if (!mCapturedTrack) {
|
if (!mCapturedTrack) {
|
||||||
wxRect rect;
|
wxRect rect;
|
||||||
mCapturedTrack =
|
mCapturedTrack =
|
||||||
@ -1950,29 +1933,9 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event,
|
|||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
// Used to jump the play head, but it is redundant with timeline quick play
|
||||||
if (
|
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
|
||||||
event.LeftDClick() ||
|
|
||||||
#endif
|
|
||||||
event.LeftDown()) {
|
|
||||||
SetCapturedTrack(nullptr, IsUncaptured);
|
|
||||||
GetProject()->GetScrubber().MarkScrubStart(
|
|
||||||
event
|
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
|
||||||
, event.LeftDClick()
|
|
||||||
#endif
|
|
||||||
, false
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// StartOrJumpPlayback(event);
|
// StartOrJumpPlayback(event);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Not starting a drag
|
// Not starting a drag
|
||||||
SetCapturedTrack(NULL, IsUncaptured);
|
SetCapturedTrack(NULL, IsUncaptured);
|
||||||
return;
|
return;
|
||||||
@ -2693,14 +2656,6 @@ void TrackPanel::Stretch(int mouseXCoordinate, int trackLeftEdge,
|
|||||||
/// handle it here.
|
/// handle it here.
|
||||||
void TrackPanel::SelectionHandleDrag(wxMouseEvent & event, Track *clickedTrack)
|
void TrackPanel::SelectionHandleDrag(wxMouseEvent & event, Track *clickedTrack)
|
||||||
{
|
{
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
|
||||||
Scrubber &scrubber = GetProject()->GetScrubber();
|
|
||||||
if (scrubber.IsScrubbing() ||
|
|
||||||
GetProject()->GetScrubber().MaybeStartScrubbing(event))
|
|
||||||
// Do nothing more, don't change selection
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// AS: If we're not in the process of selecting (set in
|
// AS: If we're not in the process of selecting (set in
|
||||||
// the SelectionHandleClick above), fuhggeddaboudit.
|
// the SelectionHandleClick above), fuhggeddaboudit.
|
||||||
if (mMouseCapture!=IsSelecting)
|
if (mMouseCapture!=IsSelecting)
|
||||||
@ -6366,20 +6321,6 @@ void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
|
||||||
if (GetProject()->GetScrubber().IsScrubbing() &&
|
|
||||||
GetRect().Contains(event.GetPosition()) &&
|
|
||||||
(!pTrack ||
|
|
||||||
pTrack->GetKind() == Track::Wave)) {
|
|
||||||
if (event.LeftDown()) {
|
|
||||||
GetProject()->GetScrubber().SetSeeking();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (event.LeftIsDown())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
|
|
||||||
if (pTrack && (pTrack->GetKind() == Track::Wave) &&
|
if (pTrack && (pTrack->GetKind() == Track::Wave) &&
|
||||||
|
@ -55,9 +55,6 @@
|
|||||||
#include "../Theme.h"
|
#include "../Theme.h"
|
||||||
|
|
||||||
#include "../Experimental.h"
|
#include "../Experimental.h"
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
|
||||||
#include "../tracks/ui/Scrubbing.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../widgets/AButton.h"
|
#include "../widgets/AButton.h"
|
||||||
|
|
||||||
@ -87,21 +84,7 @@ ToolsToolBar::ToolsToolBar()
|
|||||||
wxASSERT( drawTool == drawTool - firstTool );
|
wxASSERT( drawTool == drawTool - firstTool );
|
||||||
wxASSERT( multiTool == multiTool - firstTool );
|
wxASSERT( multiTool == multiTool - firstTool );
|
||||||
|
|
||||||
{
|
mMessageOfTool[selectTool] = _("Click and drag to select audio");
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
|
||||||
|
|
||||||
mMessageOfTool[selectTool] =
|
|
||||||
#if defined(__WXMAC__)
|
|
||||||
_("Click and drag to select audio, Command-Click to scrub, Command-Double-Click to scroll-scrub, Command-drag to seek")
|
|
||||||
#else
|
|
||||||
_("Click and drag to select audio, Ctrl-Click to scrub, Ctrl-Double-Click to scroll-scrub, Ctrl-drag to seek")
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
#else
|
|
||||||
mMessageOfTool[selectTool] = _("Click and drag to select audio");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
mMessageOfTool[envelopeTool] = _("Click and drag to edit the amplitude envelope");
|
mMessageOfTool[envelopeTool] = _("Click and drag to edit the amplitude envelope");
|
||||||
mMessageOfTool[drawTool] = _("Click and drag to edit the samples");
|
mMessageOfTool[drawTool] = _("Click and drag to edit the samples");
|
||||||
@ -219,14 +202,6 @@ void ToolsToolBar::SetCurrentTool(int tool, bool show)
|
|||||||
//In multi-mode the current tool is shown by the
|
//In multi-mode the current tool is shown by the
|
||||||
//cursor icon. The buttons are not updated.
|
//cursor icon. The buttons are not updated.
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
|
||||||
if (tool != selectTool) {
|
|
||||||
AudacityProject *const p = GetActiveProject();
|
|
||||||
if (p)
|
|
||||||
p->GetScrubber().StopScrubbing();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool leavingMulticlipMode =
|
bool leavingMulticlipMode =
|
||||||
IsDown(multiTool) && show && tool != multiTool;
|
IsDown(multiTool) && show && tool != multiTool;
|
||||||
|
|
||||||
@ -290,14 +265,6 @@ void ToolsToolBar::OnTool(wxCommandEvent & evt)
|
|||||||
else
|
else
|
||||||
mTool[i]->PopUp();
|
mTool[i]->PopUp();
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
|
||||||
if (0 != mCurrentTool) {
|
|
||||||
AudacityProject *const p = GetActiveProject();
|
|
||||||
if (p)
|
|
||||||
p->GetScrubber().StopScrubbing();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RedrawAllProjects();
|
RedrawAllProjects();
|
||||||
|
|
||||||
gPrefs->Write(wxT("/GUI/ToolBars/Tools/MultiToolActive"),
|
gPrefs->Write(wxT("/GUI/ToolBars/Tools/MultiToolActive"),
|
||||||
|
@ -180,7 +180,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Scrubber::MarkScrubStart(
|
void Scrubber::MarkScrubStart(
|
||||||
const wxMouseEvent &event
|
wxCoord xx
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||||
, bool smoothScrolling
|
, bool smoothScrolling
|
||||||
#endif
|
#endif
|
||||||
@ -189,8 +189,6 @@ void Scrubber::MarkScrubStart(
|
|||||||
{
|
{
|
||||||
UncheckAllMenuItems();
|
UncheckAllMenuItems();
|
||||||
|
|
||||||
const wxCoord xx = event.m_x;
|
|
||||||
|
|
||||||
// Don't actually start scrubbing, but collect some information
|
// Don't actually start scrubbing, but collect some information
|
||||||
// needed for the decision to start scrubbing later when handling
|
// needed for the decision to start scrubbing later when handling
|
||||||
// drag events.
|
// drag events.
|
||||||
@ -204,7 +202,6 @@ void Scrubber::MarkScrubStart(
|
|||||||
ControlToolBar * const ctb = mProject->GetControlToolBar();
|
ControlToolBar * const ctb = mProject->GetControlToolBar();
|
||||||
ctb->SetPlay(true, ControlToolBar::PlayAppearance::Scrub);
|
ctb->SetPlay(true, ControlToolBar::PlayAppearance::Scrub);
|
||||||
ctb->UpdateStatusBar(mProject);
|
ctb->UpdateStatusBar(mProject);
|
||||||
mProject->GetTrackPanel()->HandleCursor(event);
|
|
||||||
|
|
||||||
CheckMenuItem();
|
CheckMenuItem();
|
||||||
}
|
}
|
||||||
@ -299,9 +296,11 @@ void Scrubber::ContinueScrubbing()
|
|||||||
// Seek only when the pointer is in the panel. Else, scrub.
|
// Seek only when the pointer is in the panel. Else, scrub.
|
||||||
const wxMouseState state(::wxGetMouseState());
|
const wxMouseState state(::wxGetMouseState());
|
||||||
TrackPanel *const trackPanel = mProject->GetTrackPanel();
|
TrackPanel *const trackPanel = mProject->GetTrackPanel();
|
||||||
const wxPoint position = trackPanel->ScreenToClient(state.GetPosition());
|
|
||||||
const bool inPanel = trackPanel->GetRect().Contains(position);
|
// Decide whether to skip play, because either mouse is down now,
|
||||||
const bool seek = inPanel && (mScrubSeekPress || PollIsSeeking());
|
// or there was a left click event. (This is then a delayed reaction, in a
|
||||||
|
// timer callback, to a left click event detected elsewhere.)
|
||||||
|
const bool seek = PollIsSeeking() || mScrubSeekPress;
|
||||||
|
|
||||||
{
|
{
|
||||||
// Show the correct status for seeking.
|
// Show the correct status for seeking.
|
||||||
@ -312,6 +311,7 @@ void Scrubber::ContinueScrubbing()
|
|||||||
mAlwaysSeeking = backup;
|
mAlwaysSeeking = backup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const wxPoint position = trackPanel->ScreenToClient(state.GetPosition());
|
||||||
// When we don't have focus, enqueue silent scrubs until we regain focus.
|
// When we don't have focus, enqueue silent scrubs until we regain focus.
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (!mScrubHasFocus)
|
if (!mScrubHasFocus)
|
||||||
@ -615,9 +615,7 @@ void Scrubber::DoScrub(bool scroll, bool seek)
|
|||||||
if (!wasScrubbing) {
|
if (!wasScrubbing) {
|
||||||
auto tp = mProject->GetTrackPanel();
|
auto tp = mProject->GetTrackPanel();
|
||||||
wxCoord xx = tp->ScreenToClient(::wxGetMouseState().GetPosition()).x;
|
wxCoord xx = tp->ScreenToClient(::wxGetMouseState().GetPosition()).x;
|
||||||
wxMouseEvent evt;
|
MarkScrubStart(xx, scroll, seek);
|
||||||
evt.SetX(xx);
|
|
||||||
MarkScrubStart(evt, scroll, seek);
|
|
||||||
}
|
}
|
||||||
else if(!match) {
|
else if(!match) {
|
||||||
mSmoothScrollingScrub = scroll;
|
mSmoothScrollingScrub = scroll;
|
||||||
@ -677,6 +675,12 @@ std::vector<wxString> Scrubber::GetAllUntranslatedStatusStrings()
|
|||||||
return move(results);
|
return move(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Scrubber::CanScrub() const
|
||||||
|
{
|
||||||
|
auto cm = mProject->GetCommandManager();
|
||||||
|
return cm->GetEnabled(menuItems[0].name);
|
||||||
|
}
|
||||||
|
|
||||||
void Scrubber::AddMenuItems()
|
void Scrubber::AddMenuItems()
|
||||||
{
|
{
|
||||||
auto cm = mProject->GetCommandManager();
|
auto cm = mProject->GetCommandManager();
|
||||||
|
@ -28,7 +28,7 @@ public:
|
|||||||
~Scrubber();
|
~Scrubber();
|
||||||
|
|
||||||
void MarkScrubStart(
|
void MarkScrubStart(
|
||||||
const wxMouseEvent &event
|
wxCoord xx
|
||||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||||
, bool smoothScrolling
|
, bool smoothScrolling
|
||||||
#endif
|
#endif
|
||||||
@ -52,6 +52,8 @@ public:
|
|||||||
bool IsScrubbing() const;
|
bool IsScrubbing() const;
|
||||||
bool IsScrollScrubbing() const // If true, implies HasStartedScrubbing()
|
bool IsScrollScrubbing() const // If true, implies HasStartedScrubbing()
|
||||||
{ return mSmoothScrollingScrub; }
|
{ return mSmoothScrollingScrub; }
|
||||||
|
bool IsAlwaysSeeking() const
|
||||||
|
{ return mAlwaysSeeking; }
|
||||||
|
|
||||||
bool ShouldDrawScrubSpeed();
|
bool ShouldDrawScrubSpeed();
|
||||||
double FindScrubSpeed(bool seeking, double time) const;
|
double FindScrubSpeed(bool seeking, double time) const;
|
||||||
@ -62,6 +64,8 @@ public:
|
|||||||
void SetSeeking() { mScrubSeekPress = true; }
|
void SetSeeking() { mScrubSeekPress = true; }
|
||||||
bool PollIsSeeking();
|
bool PollIsSeeking();
|
||||||
|
|
||||||
|
// This returns the same as the enabled state of the menu items:
|
||||||
|
bool CanScrub() const;
|
||||||
void AddMenuItems();
|
void AddMenuItems();
|
||||||
|
|
||||||
void OnScrub();
|
void OnScrub();
|
||||||
|
@ -1717,8 +1717,6 @@ void QuickPlayIndicatorOverlay::Draw
|
|||||||
if (mOldQPIndicatorPos >= 0) {
|
if (mOldQPIndicatorPos >= 0) {
|
||||||
mOldPreviewingScrub
|
mOldPreviewingScrub
|
||||||
? AColor::IndicatorColor(&dc, true) // Draw green line for preview.
|
? AColor::IndicatorColor(&dc, true) // Draw green line for preview.
|
||||||
// Drawing during actual scrub not by this class,
|
|
||||||
// but by PlayIndicatorOverlay
|
|
||||||
: mOldQPIndicatorSnapped
|
: mOldQPIndicatorSnapped
|
||||||
? AColor::SnapGuidePen(&dc)
|
? AColor::SnapGuidePen(&dc)
|
||||||
: AColor::Light(&dc, false)
|
: AColor::Light(&dc, false)
|
||||||
@ -2061,22 +2059,26 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
|||||||
if (mIsRecording)
|
if (mIsRecording)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Handle status bar messages
|
const bool inScrubZone =
|
||||||
if(evt.Leaving()) {
|
// only if scrubbing is allowed now
|
||||||
mProject->TP_DisplayStatusMessage(wxT(""));
|
mProject->GetScrubber().CanScrub() &&
|
||||||
}
|
evt.m_y < IndicatorBigHeight();
|
||||||
else if(evt.Entering()) {
|
|
||||||
// Insert timeline status bar messages here
|
|
||||||
mProject->TP_DisplayStatusMessage
|
|
||||||
(wxT(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the initial play region state
|
const bool changeInScrubZone = (inScrubZone != mPrevInScrubZone);
|
||||||
if(mMouseEventState == mesNone) {
|
mPrevInScrubZone = inScrubZone;
|
||||||
mOldPlayRegionStart = mPlayRegionStart;
|
|
||||||
mOldPlayRegionEnd = mPlayRegionEnd;
|
auto &scrubber = mProject->GetScrubber();
|
||||||
mPlayRegionLock = mProject->IsPlayRegionLocked();
|
|
||||||
}
|
// Handle status bar messages
|
||||||
|
UpdateStatusBar (
|
||||||
|
evt.Leaving()
|
||||||
|
? StatusChoice::Leaving
|
||||||
|
: evt.Entering() || changeInScrubZone
|
||||||
|
? inScrubZone
|
||||||
|
? StatusChoice::EnteringScrubZone
|
||||||
|
: StatusChoice::EnteringQP
|
||||||
|
: StatusChoice::NoChange
|
||||||
|
);
|
||||||
|
|
||||||
// Keep Quick-Play within usable track area.
|
// Keep Quick-Play within usable track area.
|
||||||
TrackPanel *tp = mProject->GetTrackPanel();
|
TrackPanel *tp = mProject->GetTrackPanel();
|
||||||
@ -2085,11 +2087,6 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
|||||||
mousePosX = std::max(evt.GetX(), tp->GetLeftOffset());
|
mousePosX = std::max(evt.GetX(), tp->GetLeftOffset());
|
||||||
mousePosX = std::min(mousePosX, tp->GetLeftOffset() + width - 1);
|
mousePosX = std::min(mousePosX, tp->GetLeftOffset() + width - 1);
|
||||||
|
|
||||||
bool isWithinStart = IsWithinMarker(mousePosX, mOldPlayRegionStart);
|
|
||||||
bool isWithinEnd = IsWithinMarker(mousePosX, mOldPlayRegionEnd);
|
|
||||||
bool isWithinClick = (mLeftDownClick >= 0) && IsWithinMarker(mousePosX, mLeftDownClick);
|
|
||||||
bool canDragSel = !mPlayRegionLock && mPlayRegionDragsSelection;
|
|
||||||
|
|
||||||
double t0 = mTracks->GetStartTime();
|
double t0 = mTracks->GetStartTime();
|
||||||
double t1 = mTracks->GetEndTime();
|
double t1 = mTracks->GetEndTime();
|
||||||
double sel0 = mProject->GetSel0();
|
double sel0 = mProject->GetSel0();
|
||||||
@ -2098,13 +2095,55 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
|||||||
mLastMouseX = mousePosX;
|
mLastMouseX = mousePosX;
|
||||||
mQuickPlayPos = Pos2Time(mousePosX);
|
mQuickPlayPos = Pos2Time(mousePosX);
|
||||||
// If not looping, restrict selection to end of project
|
// If not looping, restrict selection to end of project
|
||||||
if (!evt.ShiftDown()) {
|
if (!inScrubZone && !evt.ShiftDown()) {
|
||||||
mQuickPlayPos = std::min(t1, mQuickPlayPos);
|
mQuickPlayPos = std::min(t1, mQuickPlayPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evt.Leaving()) {
|
if (scrubber.HasStartedScrubbing()) {
|
||||||
mQuickPlayInd = false;
|
// If already clicked for scrub, preempt the usual event handling,
|
||||||
DrawQuickPlayIndicator(NULL);
|
// no matter what the y coordinate.
|
||||||
|
|
||||||
|
if (scrubber.IsScrubbing()) {
|
||||||
|
if(evt.LeftDown() || evt.Dragging())
|
||||||
|
// Cause scrub in progress to jump
|
||||||
|
scrubber.SetSeeking();
|
||||||
|
}
|
||||||
|
else if (evt.LeftDClick())
|
||||||
|
// On the second button down, switch the pending scrub to scrolling
|
||||||
|
scrubber.MarkScrubStart(evt.m_x, true, false);
|
||||||
|
else if (!evt.Button(wxMOUSE_BTN_ANY)) {
|
||||||
|
// Really start scrub if motion is far enough
|
||||||
|
scrubber.MaybeStartScrubbing(evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
mQuickPlayInd = true;
|
||||||
|
wxClientDC dc(this);
|
||||||
|
DrawQuickPlayIndicator(&dc);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the initial play region state
|
||||||
|
if(mMouseEventState == mesNone) {
|
||||||
|
mOldPlayRegionStart = mPlayRegionStart;
|
||||||
|
mOldPlayRegionEnd = mPlayRegionEnd;
|
||||||
|
mPlayRegionLock = mProject->IsPlayRegionLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWithinStart = IsWithinMarker(mousePosX, mOldPlayRegionStart);
|
||||||
|
bool isWithinEnd = IsWithinMarker(mousePosX, mOldPlayRegionEnd);
|
||||||
|
bool isWithinClick = (mLeftDownClick >= 0) && IsWithinMarker(mousePosX, mLeftDownClick);
|
||||||
|
bool canDragSel = !mPlayRegionLock && mPlayRegionDragsSelection;
|
||||||
|
|
||||||
|
// Handle entering and leaving of the bar, or movement from
|
||||||
|
// one portion (quick play or scrub) to the other
|
||||||
|
if (evt.Leaving() || (changeInScrubZone && inScrubZone)) {
|
||||||
|
if (evt.Leaving()) {
|
||||||
|
// Erase the line
|
||||||
|
mQuickPlayInd = false;
|
||||||
|
DrawQuickPlayIndicator(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
Refresh();
|
Refresh();
|
||||||
|
|
||||||
SetCursor(mCursorDefault);
|
SetCursor(mCursorDefault);
|
||||||
@ -2114,9 +2153,12 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
|||||||
delete mSnapManager;
|
delete mSnapManager;
|
||||||
mSnapManager = NULL;
|
mSnapManager = NULL;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
if(evt.Leaving())
|
||||||
|
return;
|
||||||
|
// else, may detect a scrub click below
|
||||||
}
|
}
|
||||||
else if (evt.Entering()) {
|
else if (evt.Entering() || (changeInScrubZone && !inScrubZone)) {
|
||||||
SetCursor(mCursorHand);
|
SetCursor(mCursorHand);
|
||||||
mQuickPlayInd = false;
|
mQuickPlayInd = false;
|
||||||
DrawQuickPlayIndicator(NULL);
|
DrawQuickPlayIndicator(NULL);
|
||||||
@ -2127,6 +2169,15 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
|||||||
ShowMenu(evt.GetPosition());
|
ShowMenu(evt.GetPosition());
|
||||||
if (HasCapture())
|
if (HasCapture())
|
||||||
ReleaseMouse();
|
ReleaseMouse();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (inScrubZone) {
|
||||||
|
if (evt.LeftDown())
|
||||||
|
scrubber.MarkScrubStart(evt.m_x, false, false);
|
||||||
|
UpdateStatusBar(StatusChoice::EnteringScrubZone);
|
||||||
|
wxClientDC dc(this);
|
||||||
|
DrawQuickPlayIndicator(&dc);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mQuickPlayEnabled)
|
if (!mQuickPlayEnabled)
|
||||||
@ -2377,6 +2428,45 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AdornedRulerPanel::UpdateStatusBar(StatusChoice choice)
|
||||||
|
{
|
||||||
|
if (choice == StatusChoice::NoChange)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto &scrubber = mProject->GetScrubber();
|
||||||
|
const bool scrubbing = scrubber.HasStartedScrubbing();
|
||||||
|
if (scrubbing && choice != StatusChoice::Leaving)
|
||||||
|
// Don't distinguish zones
|
||||||
|
choice = StatusChoice::EnteringScrubZone;
|
||||||
|
wxString message{};
|
||||||
|
|
||||||
|
switch (choice) {
|
||||||
|
case StatusChoice::EnteringQP:
|
||||||
|
{
|
||||||
|
// message = Insert timeline status bar message here
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StatusChoice::EnteringScrubZone:
|
||||||
|
{
|
||||||
|
if (scrubbing) {
|
||||||
|
if(!scrubber.IsAlwaysSeeking())
|
||||||
|
message = _("Click or drag to seek");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
message = _("Click to scrub, Double-Click to scroll, Drag to seek");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StatusChoice::Leaving:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display a message, or empty message
|
||||||
|
mProject->TP_DisplayStatusMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
void AdornedRulerPanel::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(evt))
|
void AdornedRulerPanel::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(evt))
|
||||||
{
|
{
|
||||||
DrawQuickPlayIndicator(NULL);
|
DrawQuickPlayIndicator(NULL);
|
||||||
@ -2745,7 +2835,10 @@ void AdornedRulerPanel::DrawQuickPlayIndicator(wxDC * dc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int x = Time2Pos(mQuickPlayPos);
|
const int x = Time2Pos(mQuickPlayPos);
|
||||||
GetOverlay()->Update(x, mIsSnapped, mPrevInScrubZone);
|
bool previewScrub =
|
||||||
|
mPrevInScrubZone &&
|
||||||
|
!mProject->GetScrubber().IsScrubbing();
|
||||||
|
GetOverlay()->Update(x, mIsSnapped, previewScrub);
|
||||||
|
|
||||||
DoEraseIndicator(dc, mLastQuickPlayX);
|
DoEraseIndicator(dc, mLastQuickPlayX);
|
||||||
mLastQuickPlayX = x;
|
mLastQuickPlayX = x;
|
||||||
|
@ -317,6 +317,15 @@ private:
|
|||||||
void OnPaint(wxPaintEvent &evt);
|
void OnPaint(wxPaintEvent &evt);
|
||||||
void OnSize(wxSizeEvent &evt);
|
void OnSize(wxSizeEvent &evt);
|
||||||
void OnMouseEvents(wxMouseEvent &evt);
|
void OnMouseEvents(wxMouseEvent &evt);
|
||||||
|
|
||||||
|
enum class StatusChoice {
|
||||||
|
EnteringQP,
|
||||||
|
EnteringScrubZone,
|
||||||
|
Leaving,
|
||||||
|
NoChange
|
||||||
|
};
|
||||||
|
void UpdateStatusBar(StatusChoice choice);
|
||||||
|
|
||||||
void OnCaptureLost(wxMouseCaptureLostEvent &evt);
|
void OnCaptureLost(wxMouseCaptureLostEvent &evt);
|
||||||
|
|
||||||
void DoDrawBorder(wxDC * dc);
|
void DoDrawBorder(wxDC * dc);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user