mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-14 09:03:54 +01:00
Control scrub with motion, click, drag, wheel almost anywhere in main window...
... if the event is not handled and skipped by sub-windows first, such as for toolbar button clicks. (But track panel clicks are skipped even after doing something, so they may also cause seeking besides other responses. So click can seek AND set cursor.) This is meant to make drag to seek and wheel for change of speed easier, without needing to keep the mouse in the narrow time ruler. Also lets you click in the ruler, then move in any direction, and not miss the motion event that should start the scrub playback. The event handling is a bit of a hack, using propagation. It does not use capture.
This commit is contained in:
@@ -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(this);
|
||||
}
|
||||
|
||||
Scrubber::~Scrubber()
|
||||
{
|
||||
mProject->PopEventHandler();
|
||||
if (wxTheApp)
|
||||
wxTheApp->Disconnect
|
||||
(wxEVT_ACTIVATE_APP,
|
||||
@@ -180,6 +183,7 @@ namespace {
|
||||
}
|
||||
|
||||
void Scrubber::MarkScrubStart(
|
||||
// Assume xx is relative to the left edge of TrackPanel!
|
||||
wxCoord xx
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
, bool smoothScrolling
|
||||
@@ -207,7 +211,8 @@ void Scrubber::MarkScrubStart(
|
||||
}
|
||||
|
||||
#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;
|
||||
@@ -222,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();
|
||||
@@ -450,6 +455,40 @@ void Scrubber::OnActivateOrDeactivateApp(wxActivateEvent &event)
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void Scrubber::OnMouse(wxMouseEvent &event)
|
||||
{
|
||||
auto isScrubbing = IsScrubbing();
|
||||
if (!isScrubbing && HasStartedScrubbing()) {
|
||||
if (!event.HasAnyModifiers() &&
|
||||
event.GetEventType() == wxEVT_MOTION) {
|
||||
|
||||
// Really start scrub if motion is far enough
|
||||
auto ruler = mProject->GetRulerPanel();
|
||||
auto xx = ruler->ScreenToClient(::wxGetMousePosition()).x;
|
||||
MaybeStartScrubbing(xx
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (isScrubbing && !event.HasAnyModifiers()) {
|
||||
if(event.LeftDown() ||
|
||||
(event.LeftIsDown() && event.Dragging())) {
|
||||
mScrubSeekPress = true;
|
||||
auto ruler = 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);
|
||||
HandleScrollWheel(steps);
|
||||
}
|
||||
else
|
||||
event.Skip();
|
||||
}
|
||||
else
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// class ScrubbingOverlay is responsible for drawing the speed numbers
|
||||
|
||||
@@ -661,6 +700,9 @@ BEGIN_EVENT_TABLE(Scrubber, wxEvtHandler)
|
||||
EVT_MENU(CMD_ID + 1, Scrubber::OnScrollScrub)
|
||||
EVT_MENU(CMD_ID + 2, Scrubber::OnSeek)
|
||||
EVT_MENU(CMD_ID + 3, Scrubber::OnScrollSeek)
|
||||
|
||||
EVT_MOUSE_EVENTS(Scrubber::OnMouse)
|
||||
|
||||
END_EVENT_TABLE()
|
||||
|
||||
static_assert(nMenuItems == 4, "wrong number of items");
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
Scrubber(AudacityProject *project);
|
||||
~Scrubber();
|
||||
|
||||
// Assume xx is relative to the left edge of TrackPanel!
|
||||
void MarkScrubStart(
|
||||
wxCoord xx
|
||||
#ifdef EXPERIMENTAL_SCRUBBING_SMOOTH_SCROLL
|
||||
@@ -35,8 +36,11 @@ public:
|
||||
, 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
|
||||
@@ -61,7 +65,6 @@ public:
|
||||
|
||||
void HandleScrollWheel(int steps);
|
||||
|
||||
void SetSeeking() { mScrubSeekPress = true; }
|
||||
bool PollIsSeeking();
|
||||
|
||||
// This returns the same as the enabled state of the menu items:
|
||||
@@ -88,6 +91,7 @@ private:
|
||||
void OnActivateOrDeactivateApp(wxActivateEvent & event);
|
||||
void UncheckAllMenuItems();
|
||||
void CheckMenuItem();
|
||||
void OnMouse(wxMouseEvent &event);
|
||||
|
||||
private:
|
||||
int mScrubToken;
|
||||
|
||||
Reference in New Issue
Block a user