mirror of
https://github.com/cookiengineer/audacity
synced 2025-05-06 23:02:42 +02:00
Merge branch 'master' into scrubbing
This commit is contained in:
commit
d8fd3dd09b
@ -689,8 +689,6 @@ struct Final_action {
|
||||
Final_action(F f) : clean{ f } {}
|
||||
~Final_action() { clean(); }
|
||||
F clean;
|
||||
Final_action(const Final_action&) PROHIBITED;
|
||||
Final_action& operator= (const Final_action&) PROHIBITED;
|
||||
};
|
||||
|
||||
// Function template with type deduction lets you construct Final_action
|
||||
|
@ -1613,7 +1613,7 @@ void AudacityProject::TP_ScrollWindow(double scrollto)
|
||||
// handler in Track Panel. A positive argument makes the window
|
||||
// scroll down, while a negative argument scrolls up.
|
||||
//
|
||||
void AudacityProject::TP_ScrollUpDown(int delta)
|
||||
bool AudacityProject::TP_ScrollUpDown(int delta)
|
||||
{
|
||||
int oldPos = mVsbar->GetThumbPosition();
|
||||
int pos = oldPos + delta;
|
||||
@ -1634,7 +1634,10 @@ void AudacityProject::TP_ScrollUpDown(int delta)
|
||||
|
||||
wxScrollEvent dummy;
|
||||
OnScroll(dummy);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void AudacityProject::FixScrollbars()
|
||||
|
@ -430,7 +430,7 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame,
|
||||
void TP_ScrollLeft() override;
|
||||
void TP_ScrollRight() override;
|
||||
void TP_ScrollWindow(double scrollto) override;
|
||||
void TP_ScrollUpDown(int delta) override;
|
||||
bool TP_ScrollUpDown(int delta) override;
|
||||
void TP_HandleResize() override;
|
||||
|
||||
// ToolBar
|
||||
|
@ -1525,13 +1525,7 @@ void TrackPanel::SetCursorAndTipWhenSelectTool( Track * t,
|
||||
// If not shift-down and not snapping center, then
|
||||
// choose boundaries only in snapping tolerance,
|
||||
// and may choose center.
|
||||
// But don't change the cursor when scrubbing.
|
||||
SelectionBoundary boundary =
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
||||
GetProject()->GetScrubber().IsScrubbing()
|
||||
? SBNone
|
||||
:
|
||||
#endif
|
||||
ChooseBoundary(event, t, rect, !bShiftDown, !bShiftDown);
|
||||
|
||||
#ifdef USE_MIDI
|
||||
@ -1705,14 +1699,7 @@ void TrackPanel::HandleCursor(const wxMouseEvent & event)
|
||||
|
||||
tip = ttb->GetMessageForTool(tool);
|
||||
|
||||
const auto &scrubber = GetProject()->GetScrubber();
|
||||
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 )
|
||||
if( tool != selectTool )
|
||||
{
|
||||
// We don't include the select tool in
|
||||
// SetCursorAndTipByTool() because it's more complex than
|
||||
@ -1773,11 +1760,7 @@ void TrackPanel::HandleSelect(wxMouseEvent & event)
|
||||
mFreqSelMode = FREQ_SEL_INVALID;
|
||||
#endif
|
||||
|
||||
} else if (event.LeftDClick() && !event.ShiftDown()
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
&& !event.CmdDown()
|
||||
#endif
|
||||
) {
|
||||
} else if (event.LeftDClick() && !event.ShiftDown()) {
|
||||
if (!mCapturedTrack) {
|
||||
wxRect rect;
|
||||
mCapturedTrack =
|
||||
@ -1950,29 +1933,9 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event,
|
||||
#endif
|
||||
) {
|
||||
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
||||
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
|
||||
|
||||
// Used to jump the play head, but it is redundant with timeline quick play
|
||||
// StartOrJumpPlayback(event);
|
||||
|
||||
#endif
|
||||
|
||||
// Not starting a drag
|
||||
SetCapturedTrack(NULL, IsUncaptured);
|
||||
return;
|
||||
@ -2693,14 +2656,6 @@ void TrackPanel::Stretch(int mouseXCoordinate, int trackLeftEdge,
|
||||
/// handle it here.
|
||||
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
|
||||
// the SelectionHandleClick above), fuhggeddaboudit.
|
||||
if (mMouseCapture!=IsSelecting)
|
||||
@ -5518,6 +5473,13 @@ void TrackPanel::HandleResize(wxMouseEvent & event)
|
||||
/// Handle mouse wheel rotation (for zoom in/out, vertical and horizontal scrolling)
|
||||
void TrackPanel::HandleWheelRotation(wxMouseEvent & event)
|
||||
{
|
||||
if(!event.HasAnyModifiers()) {
|
||||
// We will later un-skip if we do anything, but if we don't,
|
||||
// propagate the event up for the sake of the scrubber
|
||||
event.Skip();
|
||||
event.ResumePropagation(wxEVENT_PROPAGATE_MAX);
|
||||
}
|
||||
|
||||
if (GetTracks()->IsEmpty())
|
||||
// Scrolling and Zoom in and out commands are disabled when there are no tracks.
|
||||
// This should be disabled too for consistency. Otherwise
|
||||
@ -5530,6 +5492,9 @@ void TrackPanel::HandleWheelRotation(wxMouseEvent & event)
|
||||
Track *const pTrack = FindTrack(event.m_x, event.m_y, true, false, &rect);
|
||||
if (pTrack && event.m_x >= GetVRulerOffset()) {
|
||||
HandleWheelRotationInVRuler(event, pTrack, rect);
|
||||
// Always stop propagation even if the ruler didn't change. The ruler
|
||||
// is a narrow enough target.
|
||||
event.Skip(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -5619,7 +5584,8 @@ void TrackPanel::HandleWheelRotation(wxMouseEvent & event)
|
||||
double lines = steps * 4 + mVertScrollRemainder;
|
||||
mVertScrollRemainder = lines - floor(lines);
|
||||
lines = floor(lines);
|
||||
mListener->TP_ScrollUpDown((int)-lines);
|
||||
const bool didSomething = mListener->TP_ScrollUpDown((int)-lines);
|
||||
event.Skip(!didSomething);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5907,6 +5873,13 @@ void TrackPanel::OnMouseEvent(wxMouseEvent & event)
|
||||
if (event.m_wheelRotation != 0)
|
||||
HandleWheelRotation(event);
|
||||
|
||||
if (event.LeftDown() || event.LeftIsDown() || event.Moving()) {
|
||||
// Skip, even if we do something, so that the left click or drag
|
||||
// may have an additional effect in the scrubber.
|
||||
event.Skip();
|
||||
event.ResumePropagation(wxEVENT_PROPAGATE_MAX);
|
||||
}
|
||||
|
||||
if (!mAutoScrolling) {
|
||||
mMouseMostRecentX = event.m_x;
|
||||
mMouseMostRecentY = event.m_y;
|
||||
@ -6366,20 +6339,6 @@ void TrackPanel::HandleTrackSpecificMouseEvent(wxMouseEvent & event)
|
||||
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;
|
||||
|
||||
if (pTrack && (pTrack->GetKind() == Track::Wave) &&
|
||||
|
@ -34,7 +34,7 @@ class AUDACITY_DLL_API TrackPanelListener /* not final */ {
|
||||
virtual void TP_ScrollLeft() = 0;
|
||||
virtual void TP_ScrollRight() = 0;
|
||||
virtual void TP_ScrollWindow(double scrollto) = 0;
|
||||
virtual void TP_ScrollUpDown(int delta) = 0;
|
||||
virtual bool TP_ScrollUpDown(int delta) = 0;
|
||||
virtual void TP_HandleResize() = 0;
|
||||
};
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define __AUDACITY_COMMAND_FUNCTORS__
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <wx/event.h>
|
||||
#include "../MemoryX.h"
|
||||
|
||||
class wxEvent;
|
||||
@ -61,6 +62,24 @@ private:
|
||||
const audCommandKeyFunction<OBJ> mCommandKeyFunction;
|
||||
};
|
||||
|
||||
// This allows functions to be used either by command manager or by a wxMenu popup,
|
||||
// but the functions MUST ignore the argument!
|
||||
template<typename OBJ>
|
||||
using audCommandPopupFunction = void (OBJ::*)(wxCommandEvent&);
|
||||
|
||||
template<typename OBJ>
|
||||
class PopupFunctor final : public CommandFunctor
|
||||
{
|
||||
public:
|
||||
explicit PopupFunctor(OBJ *This, audCommandPopupFunction<OBJ> pfn)
|
||||
: mThis{ This }, mCommandPopupFunction{ pfn } {}
|
||||
void operator () (int, const wxEvent *) override
|
||||
{ wxCommandEvent dummy; (mThis->*mCommandPopupFunction) (dummy); }
|
||||
private:
|
||||
OBJ *const mThis;
|
||||
const audCommandPopupFunction<OBJ> mCommandPopupFunction;
|
||||
};
|
||||
|
||||
template<typename OBJ>
|
||||
using audCommandListFunction = void (OBJ::*)(int);
|
||||
|
||||
@ -108,6 +127,11 @@ inline CommandFunctorPointer MakeFunctor(OBJ *This,
|
||||
audCommandKeyFunction<OBJ> pfn)
|
||||
{ return CommandFunctorPointer{ safenew KeyFunctor<OBJ>{ This, pfn } }; }
|
||||
|
||||
template<typename OBJ>
|
||||
inline CommandFunctorPointer MakeFunctor(OBJ *This,
|
||||
audCommandPopupFunction<OBJ> pfn)
|
||||
{ return CommandFunctorPointer{ safenew PopupFunctor<OBJ>{ This, pfn } }; }
|
||||
|
||||
template<typename OBJ>
|
||||
inline CommandFunctorPointer MakeFunctor(OBJ *This,
|
||||
audCommandListFunction<OBJ> pfn)
|
||||
|
@ -276,6 +276,7 @@ DEFINE_EVENT_TYPE(EVT_TOOLBAR_UPDATED)
|
||||
BEGIN_EVENT_TABLE( ToolBar, wxPanel )
|
||||
EVT_PAINT( ToolBar::OnPaint )
|
||||
EVT_ERASE_BACKGROUND( ToolBar::OnErase )
|
||||
EVT_MOUSE_EVENTS( ToolBar::OnMouseEvents )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
//
|
||||
@ -841,6 +842,13 @@ void ToolBar::OnPaint( wxPaintEvent & event )
|
||||
#endif
|
||||
}
|
||||
|
||||
void ToolBar::OnMouseEvents(wxMouseEvent &event)
|
||||
{
|
||||
// Do this hack so scrubber can detect mouse drags anywhere
|
||||
event.ResumePropagation(wxEVENT_PROPAGATE_MAX);
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
int ToolBar::GetResizeGrabberWidth()
|
||||
{
|
||||
return RWIDTH;
|
||||
|
@ -188,6 +188,7 @@ class ToolBar /* not final */ : public wxPanel
|
||||
|
||||
void OnErase(wxEraseEvent & event);
|
||||
void OnPaint(wxPaintEvent & event);
|
||||
void OnMouseEvents(wxMouseEvent &event);
|
||||
|
||||
protected:
|
||||
wxString mLabel;
|
||||
|
@ -64,6 +64,7 @@ BEGIN_EVENT_TABLE( ToolDock, wxPanel )
|
||||
EVT_ERASE_BACKGROUND( ToolDock::OnErase )
|
||||
EVT_PAINT( ToolDock::OnPaint )
|
||||
EVT_SIZE( ToolDock::OnSize )
|
||||
EVT_MOUSE_EVENTS( ToolDock::OnMouseEvents )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
//
|
||||
@ -556,3 +557,10 @@ void ToolDock::OnPaint( wxPaintEvent & WXUNUSED(event) )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ToolDock::OnMouseEvents(wxMouseEvent &event)
|
||||
{
|
||||
// Do this hack so scrubber can detect mouse drags anywhere
|
||||
event.ResumePropagation(wxEVENT_PROPAGATE_MAX);
|
||||
event.Skip();
|
||||
}
|
||||
|
@ -70,6 +70,7 @@ class ToolDock final : public wxPanel
|
||||
void OnSize( wxSizeEvent & event );
|
||||
void OnPaint( wxPaintEvent & event );
|
||||
void OnGrabber( GrabberEvent & event );
|
||||
void OnMouseEvents(wxMouseEvent &event);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -55,9 +55,6 @@
|
||||
#include "../Theme.h"
|
||||
|
||||
#include "../Experimental.h"
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
||||
#include "../tracks/ui/Scrubbing.h"
|
||||
#endif
|
||||
|
||||
#include "../widgets/AButton.h"
|
||||
|
||||
@ -87,21 +84,7 @@ ToolsToolBar::ToolsToolBar()
|
||||
wxASSERT( drawTool == drawTool - firstTool );
|
||||
wxASSERT( multiTool == multiTool - firstTool );
|
||||
|
||||
{
|
||||
#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[selectTool] = _("Click and drag to select audio");
|
||||
|
||||
mMessageOfTool[envelopeTool] = _("Click and drag to edit the amplitude envelope");
|
||||
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
|
||||
//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 =
|
||||
IsDown(multiTool) && show && tool != multiTool;
|
||||
|
||||
@ -290,14 +265,6 @@ void ToolsToolBar::OnTool(wxCommandEvent & evt)
|
||||
else
|
||||
mTool[i]->PopUp();
|
||||
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_BASIC
|
||||
if (0 != mCurrentTool) {
|
||||
AudacityProject *const p = GetActiveProject();
|
||||
if (p)
|
||||
p->GetScrubber().StopScrubbing();
|
||||
}
|
||||
#endif
|
||||
|
||||
RedrawAllProjects();
|
||||
|
||||
gPrefs->Write(wxT("/GUI/ToolBars/Tools/MultiToolActive"),
|
||||
|
@ -19,6 +19,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#include "../../TrackPanelCellIterator.h"
|
||||
#include "../../commands/CommandFunctors.h"
|
||||
#include "../../toolbars/ControlToolBar.h"
|
||||
#include "../../widgets/Ruler.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -126,10 +127,12 @@ Scrubber::Scrubber(AudacityProject *project)
|
||||
wxTheApp->Connect
|
||||
(wxEVT_ACTIVATE_APP,
|
||||
wxActivateEventHandler(Scrubber::OnActivateOrDeactivateApp), NULL, this);
|
||||
mProject->PushEventHandler(&mForwarder);
|
||||
}
|
||||
|
||||
Scrubber::~Scrubber()
|
||||
{
|
||||
mProject->PopEventHandler();
|
||||
if (wxTheApp)
|
||||
wxTheApp->Disconnect
|
||||
(wxEVT_ACTIVATE_APP,
|
||||
@ -141,7 +144,7 @@ namespace {
|
||||
wxString name;
|
||||
wxString label;
|
||||
wxString status;
|
||||
void (Scrubber::*memFn)();
|
||||
void (Scrubber::*memFn)(wxCommandEvent&);
|
||||
bool scroll;
|
||||
bool seek;
|
||||
|
||||
@ -180,7 +183,8 @@ namespace {
|
||||
}
|
||||
|
||||
void Scrubber::MarkScrubStart(
|
||||
const wxMouseEvent &event
|
||||
// Assume xx is relative to the left edge of TrackPanel!
|
||||
wxCoord xx
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
, bool smoothScrolling
|
||||
#endif
|
||||
@ -189,8 +193,6 @@ void Scrubber::MarkScrubStart(
|
||||
{
|
||||
UncheckAllMenuItems();
|
||||
|
||||
const wxCoord xx = event.m_x;
|
||||
|
||||
// Don't actually start scrubbing, but collect some information
|
||||
// needed for the decision to start scrubbing later when handling
|
||||
// drag events.
|
||||
@ -204,13 +206,13 @@ void Scrubber::MarkScrubStart(
|
||||
ControlToolBar * const ctb = mProject->GetControlToolBar();
|
||||
ctb->SetPlay(true, ControlToolBar::PlayAppearance::Scrub);
|
||||
ctb->UpdateStatusBar(mProject);
|
||||
mProject->GetTrackPanel()->HandleCursor(event);
|
||||
|
||||
CheckMenuItem();
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
|
||||
bool Scrubber::MaybeStartScrubbing(const wxMouseEvent &event)
|
||||
// Assume xx is relative to the left edge of TrackPanel!
|
||||
bool Scrubber::MaybeStartScrubbing(wxCoord xx)
|
||||
{
|
||||
if (mScrubStartPosition < 0)
|
||||
return false;
|
||||
@ -225,7 +227,7 @@ bool Scrubber::MaybeStartScrubbing(const wxMouseEvent &event)
|
||||
return false;
|
||||
}
|
||||
|
||||
wxCoord position = event.m_x;
|
||||
wxCoord position = xx;
|
||||
if (abs(mScrubStartPosition - position) >= SCRUBBING_PIXEL_TOLERANCE) {
|
||||
const ViewInfo &viewInfo = mProject->GetViewInfo();
|
||||
TrackPanel *const trackPanel = mProject->GetTrackPanel();
|
||||
@ -299,9 +301,11 @@ void Scrubber::ContinueScrubbing()
|
||||
// Seek only when the pointer is in the panel. Else, scrub.
|
||||
const wxMouseState state(::wxGetMouseState());
|
||||
TrackPanel *const trackPanel = mProject->GetTrackPanel();
|
||||
const wxPoint position = trackPanel->ScreenToClient(state.GetPosition());
|
||||
const bool inPanel = trackPanel->GetRect().Contains(position);
|
||||
const bool seek = inPanel && (mScrubSeekPress || PollIsSeeking());
|
||||
|
||||
// Decide whether to skip play, because either mouse is down now,
|
||||
// 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.
|
||||
@ -312,6 +316,7 @@ void Scrubber::ContinueScrubbing()
|
||||
mAlwaysSeeking = backup;
|
||||
}
|
||||
|
||||
const wxPoint position = trackPanel->ScreenToClient(state.GetPosition());
|
||||
// When we don't have focus, enqueue silent scrubs until we regain focus.
|
||||
bool result = false;
|
||||
if (!mScrubHasFocus)
|
||||
@ -450,6 +455,39 @@ void Scrubber::OnActivateOrDeactivateApp(wxActivateEvent &event)
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void Scrubber::Forwarder::OnMouse(wxMouseEvent &event)
|
||||
{
|
||||
auto isScrubbing = scrubber.IsScrubbing();
|
||||
if (!isScrubbing && scrubber.HasStartedScrubbing()) {
|
||||
if (!event.HasAnyModifiers() &&
|
||||
event.GetEventType() == wxEVT_MOTION) {
|
||||
|
||||
// Really start scrub if motion is far enough
|
||||
auto ruler = scrubber.mProject->GetRulerPanel();
|
||||
auto xx = ruler->ScreenToClient(::wxGetMousePosition()).x;
|
||||
scrubber.MaybeStartScrubbing(xx);
|
||||
}
|
||||
}
|
||||
else if (isScrubbing && !event.HasAnyModifiers()) {
|
||||
if(event.LeftDown() ||
|
||||
(event.LeftIsDown() && event.Dragging())) {
|
||||
scrubber.mScrubSeekPress = true;
|
||||
auto ruler = scrubber.mProject->GetRulerPanel();
|
||||
auto xx = ruler->ScreenToClient(::wxGetMousePosition()).x;
|
||||
ruler->UpdateQuickPlayPos(xx);
|
||||
}
|
||||
else if (event.m_wheelRotation) {
|
||||
double steps = event.m_wheelRotation /
|
||||
(event.m_wheelDelta > 0 ? (double)event.m_wheelDelta : 120.0);
|
||||
scrubber.HandleScrollWheel(steps);
|
||||
}
|
||||
else
|
||||
event.Skip();
|
||||
}
|
||||
else
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// class ScrubbingOverlay is responsible for drawing the speed numbers
|
||||
|
||||
@ -615,9 +653,7 @@ void Scrubber::DoScrub(bool scroll, bool seek)
|
||||
if (!wasScrubbing) {
|
||||
auto tp = mProject->GetTrackPanel();
|
||||
wxCoord xx = tp->ScreenToClient(::wxGetMouseState().GetPosition()).x;
|
||||
wxMouseEvent evt;
|
||||
evt.SetX(xx);
|
||||
MarkScrubStart(evt, scroll, seek);
|
||||
MarkScrubStart(xx, scroll, seek);
|
||||
}
|
||||
else if(!match) {
|
||||
mSmoothScrollingScrub = scroll;
|
||||
@ -636,26 +672,41 @@ void Scrubber::DoScrub(bool scroll, bool seek)
|
||||
}
|
||||
}
|
||||
|
||||
void Scrubber::OnScrub()
|
||||
void Scrubber::OnScrub(wxCommandEvent&)
|
||||
{
|
||||
DoScrub(false, false);
|
||||
}
|
||||
|
||||
void Scrubber::OnScrollScrub()
|
||||
void Scrubber::OnScrollScrub(wxCommandEvent&)
|
||||
{
|
||||
DoScrub(true, false);
|
||||
}
|
||||
|
||||
void Scrubber::OnSeek()
|
||||
void Scrubber::OnSeek(wxCommandEvent&)
|
||||
{
|
||||
DoScrub(false, true);
|
||||
}
|
||||
|
||||
void Scrubber::OnScrollSeek()
|
||||
void Scrubber::OnScrollSeek(wxCommandEvent&)
|
||||
{
|
||||
DoScrub(true, true);
|
||||
}
|
||||
|
||||
enum { CMD_ID = 8000 };
|
||||
|
||||
BEGIN_EVENT_TABLE(Scrubber, wxEvtHandler)
|
||||
EVT_MENU(CMD_ID, Scrubber::OnScrub)
|
||||
EVT_MENU(CMD_ID + 1, Scrubber::OnScrollScrub)
|
||||
EVT_MENU(CMD_ID + 2, Scrubber::OnSeek)
|
||||
EVT_MENU(CMD_ID + 3, Scrubber::OnScrollSeek)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
BEGIN_EVENT_TABLE(Scrubber::Forwarder, wxEvtHandler)
|
||||
EVT_MOUSE_EVENTS(Scrubber::Forwarder::OnMouse)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
static_assert(nMenuItems == 4, "wrong number of items");
|
||||
|
||||
const wxString &Scrubber::GetUntranslatedStateString() const
|
||||
{
|
||||
static wxString empty;
|
||||
@ -677,6 +728,12 @@ std::vector<wxString> Scrubber::GetAllUntranslatedStatusStrings()
|
||||
return move(results);
|
||||
}
|
||||
|
||||
bool Scrubber::CanScrub() const
|
||||
{
|
||||
auto cm = mProject->GetCommandManager();
|
||||
return cm->GetEnabled(menuItems[0].name);
|
||||
}
|
||||
|
||||
void Scrubber::AddMenuItems()
|
||||
{
|
||||
auto cm = mProject->GetCommandManager();
|
||||
@ -693,6 +750,17 @@ void Scrubber::AddMenuItems()
|
||||
CheckMenuItem();
|
||||
}
|
||||
|
||||
void Scrubber::PopulateMenu(wxMenu &menu)
|
||||
{
|
||||
int id = CMD_ID;
|
||||
auto cm = mProject->GetCommandManager();
|
||||
for (const auto &item : menuItems) {
|
||||
if (cm->GetEnabled(item.name))
|
||||
menu.Append(id, item.label);
|
||||
++id;
|
||||
}
|
||||
}
|
||||
|
||||
void Scrubber::UncheckAllMenuItems()
|
||||
{
|
||||
auto cm = mProject->GetCommandManager();
|
||||
|
@ -27,16 +27,20 @@ public:
|
||||
Scrubber(AudacityProject *project);
|
||||
~Scrubber();
|
||||
|
||||
// Assume xx is relative to the left edge of TrackPanel!
|
||||
void MarkScrubStart(
|
||||
const wxMouseEvent &event
|
||||
wxCoord xx
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
, bool smoothScrolling
|
||||
#endif
|
||||
, bool alwaysSeeking // if false, can switch seeking or scrubbing
|
||||
// by mouse button state
|
||||
);
|
||||
|
||||
// Returns true iff the event should be considered consumed by this:
|
||||
bool MaybeStartScrubbing(const wxMouseEvent &event);
|
||||
// Assume xx is relative to the left edge of TrackPanel!
|
||||
bool MaybeStartScrubbing(wxCoord xx);
|
||||
|
||||
void ContinueScrubbing();
|
||||
|
||||
// This is meant to be called only from ControlToolBar
|
||||
@ -52,6 +56,8 @@ public:
|
||||
bool IsScrubbing() const;
|
||||
bool IsScrollScrubbing() const // If true, implies HasStartedScrubbing()
|
||||
{ return mSmoothScrollingScrub; }
|
||||
bool IsAlwaysSeeking() const
|
||||
{ return mAlwaysSeeking; }
|
||||
|
||||
bool ShouldDrawScrubSpeed();
|
||||
double FindScrubSpeed(bool seeking, double time) const;
|
||||
@ -59,15 +65,20 @@ public:
|
||||
|
||||
void HandleScrollWheel(int steps);
|
||||
|
||||
void SetSeeking() { mScrubSeekPress = true; }
|
||||
bool PollIsSeeking();
|
||||
|
||||
void AddMenuItems();
|
||||
// This returns the same as the enabled state of the menu items:
|
||||
bool CanScrub() const;
|
||||
|
||||
void OnScrub();
|
||||
void OnScrollScrub();
|
||||
void OnSeek();
|
||||
void OnScrollSeek();
|
||||
// For the toolbar
|
||||
void AddMenuItems();
|
||||
// For popup
|
||||
void PopulateMenu(wxMenu &menu);
|
||||
|
||||
void OnScrub(wxCommandEvent&);
|
||||
void OnScrollScrub(wxCommandEvent&);
|
||||
void OnSeek(wxCommandEvent&);
|
||||
void OnScrollSeek(wxCommandEvent&);
|
||||
|
||||
// A string to put in the leftmost part of the status bar.
|
||||
const wxString &GetUntranslatedStateString() const;
|
||||
@ -81,6 +92,18 @@ private:
|
||||
void UncheckAllMenuItems();
|
||||
void CheckMenuItem();
|
||||
|
||||
// I need this because I can't push the scrubber as an event handler
|
||||
// in two places at once.
|
||||
struct Forwarder : public wxEvtHandler {
|
||||
Forwarder(Scrubber &scrubber_) : scrubber{ scrubber_ } {}
|
||||
|
||||
Scrubber &scrubber;
|
||||
|
||||
void OnMouse(wxMouseEvent &event);
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
Forwarder mForwarder{ *this };
|
||||
|
||||
private:
|
||||
int mScrubToken;
|
||||
wxLongLong mScrubStartClockTimeMillis;
|
||||
@ -97,6 +120,8 @@ private:
|
||||
#endif
|
||||
|
||||
AudacityProject *mProject;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
// Specialist in drawing the scrub speed, and listening for certain events
|
||||
|
@ -452,6 +452,8 @@ void AButton::OnMouseEvent(wxMouseEvent & event)
|
||||
GetActiveProject()->TP_DisplayStatusMessage(wxT(""));
|
||||
}
|
||||
}
|
||||
else
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void AButton::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(event))
|
||||
|
@ -96,6 +96,8 @@ using std::max;
|
||||
|
||||
#define kTopInset 4
|
||||
|
||||
wxColour Ruler::mTickColour{ 153, 153, 153 };
|
||||
|
||||
//
|
||||
// Ruler
|
||||
//
|
||||
@ -120,7 +122,6 @@ Ruler::Ruler()
|
||||
mBottom = -1;
|
||||
mbTicksOnly = true;
|
||||
mbTicksAtExtremes = false;
|
||||
mTickColour = wxColour(153,153,153);
|
||||
mPen.SetColour(mTickColour);
|
||||
|
||||
// Note: the font size is now adjusted automatically whenever
|
||||
@ -1572,7 +1573,7 @@ void Ruler::Label::Draw(wxDC&dc, bool twoTone) const
|
||||
|
||||
#ifdef EXPERIMENTAL_THEMING
|
||||
// TODO: handle color distinction
|
||||
mDC->SetTextForeground(mTickColour);
|
||||
dc.SetTextForeground(mTickColour);
|
||||
#else
|
||||
dc.SetTextForeground(altColor ? *wxBLUE : *wxBLACK);
|
||||
#endif
|
||||
@ -1717,8 +1718,6 @@ void QuickPlayIndicatorOverlay::Draw
|
||||
if (mOldQPIndicatorPos >= 0) {
|
||||
mOldPreviewingScrub
|
||||
? AColor::IndicatorColor(&dc, true) // Draw green line for preview.
|
||||
// Drawing during actual scrub not by this class,
|
||||
// but by PlayIndicatorOverlay
|
||||
: mOldQPIndicatorSnapped
|
||||
? AColor::SnapGuidePen(&dc)
|
||||
: AColor::Light(&dc, false)
|
||||
@ -2061,14 +2060,61 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
||||
if (mIsRecording)
|
||||
return;
|
||||
|
||||
const bool inScrubZone =
|
||||
// only if scrubbing is allowed now
|
||||
mProject->GetScrubber().CanScrub() &&
|
||||
evt.m_y < IndicatorBigHeight();
|
||||
|
||||
const bool changeInScrubZone = (inScrubZone != mPrevInScrubZone);
|
||||
mPrevInScrubZone = inScrubZone;
|
||||
|
||||
auto &scrubber = mProject->GetScrubber();
|
||||
|
||||
// Handle status bar messages
|
||||
if(evt.Leaving()) {
|
||||
mProject->TP_DisplayStatusMessage(wxT(""));
|
||||
UpdateStatusBar (
|
||||
evt.Leaving()
|
||||
? StatusChoice::Leaving
|
||||
: evt.Entering() || changeInScrubZone
|
||||
? inScrubZone
|
||||
? StatusChoice::EnteringScrubZone
|
||||
: StatusChoice::EnteringQP
|
||||
: StatusChoice::NoChange
|
||||
);
|
||||
|
||||
|
||||
double t0 = mTracks->GetStartTime();
|
||||
double t1 = mTracks->GetEndTime();
|
||||
double sel0 = mProject->GetSel0();
|
||||
double sel1 = mProject->GetSel1();
|
||||
|
||||
wxCoord mousePosX = evt.GetX();
|
||||
UpdateQuickPlayPos(mousePosX);
|
||||
|
||||
// If not looping, restrict selection to end of project
|
||||
if (!inScrubZone && !evt.ShiftDown()) {
|
||||
mQuickPlayPos = std::min(t1, mQuickPlayPos);
|
||||
}
|
||||
else if(evt.Entering()) {
|
||||
// Insert timeline status bar messages here
|
||||
mProject->TP_DisplayStatusMessage
|
||||
(wxT(""));
|
||||
|
||||
if (scrubber.HasStartedScrubbing()) {
|
||||
// If already clicked for scrub, preempt the usual event handling,
|
||||
// no matter what the y coordinate.
|
||||
|
||||
// Do this hack so scrubber can detect mouse drags anywhere
|
||||
evt.ResumePropagation(wxEVENT_PROPAGATE_MAX);
|
||||
|
||||
if (scrubber.IsScrubbing())
|
||||
evt.Skip();
|
||||
else if (evt.LeftDClick())
|
||||
// On the second button down, switch the pending scrub to scrolling
|
||||
scrubber.MarkScrubStart(evt.m_x, true, false);
|
||||
else
|
||||
evt.Skip();
|
||||
|
||||
mQuickPlayInd = true;
|
||||
wxClientDC dc(this);
|
||||
DrawQuickPlayIndicator(&dc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Store the initial play region state
|
||||
@ -2078,34 +2124,18 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
||||
mPlayRegionLock = mProject->IsPlayRegionLocked();
|
||||
}
|
||||
|
||||
// Keep Quick-Play within usable track area.
|
||||
TrackPanel *tp = mProject->GetTrackPanel();
|
||||
int mousePosX, width;
|
||||
tp->GetTracksUsableArea(&width, NULL);
|
||||
mousePosX = std::max(evt.GetX(), tp->GetLeftOffset());
|
||||
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 t1 = mTracks->GetEndTime();
|
||||
double sel0 = mProject->GetSel0();
|
||||
double sel1 = mProject->GetSel1();
|
||||
|
||||
mLastMouseX = mousePosX;
|
||||
mQuickPlayPos = Pos2Time(mousePosX);
|
||||
// If not looping, restrict selection to end of project
|
||||
if (!evt.ShiftDown()) {
|
||||
mQuickPlayPos = std::min(t1, mQuickPlayPos);
|
||||
}
|
||||
|
||||
if (evt.Leaving()) {
|
||||
mQuickPlayInd = false;
|
||||
DrawQuickPlayIndicator(NULL);
|
||||
Refresh();
|
||||
// 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
|
||||
HideQuickPlayIndicator();
|
||||
}
|
||||
|
||||
SetCursor(mCursorDefault);
|
||||
mIsWE = false;
|
||||
@ -2114,19 +2144,37 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
||||
delete mSnapManager;
|
||||
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);
|
||||
mQuickPlayInd = false;
|
||||
DrawQuickPlayIndicator(NULL);
|
||||
HideQuickPlayIndicator();
|
||||
return;
|
||||
}
|
||||
|
||||
if (evt.RightDown() && !(evt.LeftIsDown())) {
|
||||
ShowMenu(evt.GetPosition());
|
||||
if(inScrubZone)
|
||||
ShowScrubMenu(evt.GetPosition());
|
||||
else
|
||||
ShowMenu(evt.GetPosition());
|
||||
|
||||
// dismiss and clear Quick-Play indicator
|
||||
HideQuickPlayIndicator();
|
||||
|
||||
if (HasCapture())
|
||||
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)
|
||||
@ -2277,8 +2325,7 @@ void AdornedRulerPanel::OnMouseEvents(wxMouseEvent &evt)
|
||||
|
||||
if (evt.LeftUp())
|
||||
{
|
||||
mQuickPlayInd = false;
|
||||
DrawQuickPlayIndicator(NULL);
|
||||
HideQuickPlayIndicator();
|
||||
|
||||
if (HasCapture())
|
||||
ReleaseMouse();
|
||||
@ -2377,6 +2424,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))
|
||||
{
|
||||
DrawQuickPlayIndicator(NULL);
|
||||
@ -2386,52 +2472,68 @@ void AdornedRulerPanel::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(evt))
|
||||
OnMouseEvents(e);
|
||||
}
|
||||
|
||||
// Pop-up menu
|
||||
void AdornedRulerPanel::UpdateQuickPlayPos(wxCoord &mousePosX)
|
||||
{
|
||||
// Keep Quick-Play within usable track area.
|
||||
TrackPanel *tp = mProject->GetTrackPanel();
|
||||
int width;
|
||||
tp->GetTracksUsableArea(&width, NULL);
|
||||
mousePosX = std::max(mousePosX, tp->GetLeftOffset());
|
||||
mousePosX = std::min(mousePosX, tp->GetLeftOffset() + width - 1);
|
||||
|
||||
mLastMouseX = mousePosX;
|
||||
mQuickPlayPos = Pos2Time(mousePosX);
|
||||
}
|
||||
|
||||
// Pop-up menus
|
||||
|
||||
void AdornedRulerPanel::ShowMenu(const wxPoint & pos)
|
||||
{
|
||||
{
|
||||
wxMenu rulerMenu;
|
||||
wxMenu rulerMenu;
|
||||
|
||||
if (mQuickPlayEnabled)
|
||||
rulerMenu.Append(OnToggleQuickPlayID, _("Disable Quick-Play"));
|
||||
else
|
||||
rulerMenu.Append(OnToggleQuickPlayID, _("Enable Quick-Play"));
|
||||
if (mQuickPlayEnabled)
|
||||
rulerMenu.Append(OnToggleQuickPlayID, _("Disable Quick-Play"));
|
||||
else
|
||||
rulerMenu.Append(OnToggleQuickPlayID, _("Enable Quick-Play"));
|
||||
|
||||
wxMenuItem *dragitem;
|
||||
if (mPlayRegionDragsSelection && !mProject->IsPlayRegionLocked())
|
||||
dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Disable dragging selection"));
|
||||
else
|
||||
dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Enable dragging selection"));
|
||||
dragitem->Enable(mQuickPlayEnabled && !mProject->IsPlayRegionLocked());
|
||||
wxMenuItem *dragitem;
|
||||
if (mPlayRegionDragsSelection && !mProject->IsPlayRegionLocked())
|
||||
dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Disable dragging selection"));
|
||||
else
|
||||
dragitem = rulerMenu.Append(OnSyncQuickPlaySelID, _("Enable dragging selection"));
|
||||
dragitem->Enable(mQuickPlayEnabled && !mProject->IsPlayRegionLocked());
|
||||
|
||||
#if wxUSE_TOOLTIPS
|
||||
if (mTimelineToolTip)
|
||||
rulerMenu.Append(OnTimelineToolTipID, _("Disable Timeline Tooltips"));
|
||||
else
|
||||
rulerMenu.Append(OnTimelineToolTipID, _("Enable Timeline Tooltips"));
|
||||
if (mTimelineToolTip)
|
||||
rulerMenu.Append(OnTimelineToolTipID, _("Disable Timeline Tooltips"));
|
||||
else
|
||||
rulerMenu.Append(OnTimelineToolTipID, _("Enable Timeline Tooltips"));
|
||||
#endif
|
||||
|
||||
if (mViewInfo->bUpdateTrackIndicator)
|
||||
rulerMenu.Append(OnAutoScrollID, _("Do not scroll while playing"));
|
||||
else
|
||||
rulerMenu.Append(OnAutoScrollID, _("Update display while playing"));
|
||||
if (mViewInfo->bUpdateTrackIndicator)
|
||||
rulerMenu.Append(OnAutoScrollID, _("Do not scroll while playing"));
|
||||
else
|
||||
rulerMenu.Append(OnAutoScrollID, _("Update display while playing"));
|
||||
|
||||
wxMenuItem *prlitem;
|
||||
if (!mProject->IsPlayRegionLocked())
|
||||
prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Lock Play Region"));
|
||||
else
|
||||
prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Unlock Play Region"));
|
||||
prlitem->Enable(mProject->IsPlayRegionLocked() || (mPlayRegionStart != mPlayRegionEnd));
|
||||
wxMenuItem *prlitem;
|
||||
if (!mProject->IsPlayRegionLocked())
|
||||
prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Lock Play Region"));
|
||||
else
|
||||
prlitem = rulerMenu.Append(OnLockPlayRegionID, _("Unlock Play Region"));
|
||||
prlitem->Enable(mProject->IsPlayRegionLocked() || (mPlayRegionStart != mPlayRegionEnd));
|
||||
|
||||
PopupMenu(&rulerMenu, pos);
|
||||
}
|
||||
PopupMenu(&rulerMenu, pos);
|
||||
}
|
||||
|
||||
// dismiss and clear Quick-Play indicator
|
||||
mQuickPlayInd = false;
|
||||
DrawQuickPlayIndicator(NULL);
|
||||
void AdornedRulerPanel::ShowScrubMenu(const wxPoint & pos)
|
||||
{
|
||||
auto &scrubber = mProject->GetScrubber();
|
||||
PushEventHandler(&scrubber);
|
||||
auto cleanup = finally([this]{ PopEventHandler(); });
|
||||
|
||||
Refresh();
|
||||
wxMenu rulerMenu;
|
||||
mProject->GetScrubber().PopulateMenu(rulerMenu);
|
||||
PopupMenu(&rulerMenu, pos);
|
||||
}
|
||||
|
||||
void AdornedRulerPanel::OnToggleQuickPlay(wxCommandEvent&)
|
||||
@ -2745,7 +2847,10 @@ void AdornedRulerPanel::DrawQuickPlayIndicator(wxDC * dc)
|
||||
}
|
||||
|
||||
const int x = Time2Pos(mQuickPlayPos);
|
||||
GetOverlay()->Update(x, mIsSnapped, mPrevInScrubZone);
|
||||
bool previewScrub =
|
||||
mPrevInScrubZone &&
|
||||
!mProject->GetScrubber().IsScrubbing();
|
||||
GetOverlay()->Update(x, mIsSnapped, previewScrub);
|
||||
|
||||
DoEraseIndicator(dc, mLastQuickPlayX);
|
||||
mLastQuickPlayX = x;
|
||||
|
@ -168,7 +168,7 @@ public:
|
||||
wxRect mRect;
|
||||
|
||||
private:
|
||||
wxColour mTickColour;
|
||||
static wxColour mTickColour;
|
||||
wxPen mPen;
|
||||
|
||||
int mMaxWidth, mMaxHeight;
|
||||
@ -312,11 +312,22 @@ public:
|
||||
void RegenerateTooltips();
|
||||
void HideQuickPlayIndicator();
|
||||
|
||||
void UpdateQuickPlayPos(wxCoord &mousPosX);
|
||||
|
||||
private:
|
||||
void OnCapture(wxCommandEvent & evt);
|
||||
void OnPaint(wxPaintEvent &evt);
|
||||
void OnSize(wxSizeEvent &evt);
|
||||
void OnMouseEvents(wxMouseEvent &evt);
|
||||
|
||||
enum class StatusChoice {
|
||||
EnteringQP,
|
||||
EnteringScrubZone,
|
||||
Leaving,
|
||||
NoChange
|
||||
};
|
||||
void UpdateStatusBar(StatusChoice choice);
|
||||
|
||||
void OnCaptureLost(wxMouseCaptureLostEvent &evt);
|
||||
|
||||
void DoDrawBorder(wxDC * dc);
|
||||
@ -381,6 +392,7 @@ private:
|
||||
// Pop-up menu
|
||||
//
|
||||
void ShowMenu(const wxPoint & pos);
|
||||
void ShowScrubMenu(const wxPoint & pos);
|
||||
void DragSelection();
|
||||
void HandleSnapping();
|
||||
void OnToggleQuickPlay(wxCommandEvent &evt);
|
||||
|
Loading…
x
Reference in New Issue
Block a user