1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-08-09 08:31:13 +02:00

Move the scrub mouse event handler into ScrubUI...

... Making Scrubbing independent of AdornedRulerPanel.cpp
This commit is contained in:
Paul Licameli 2019-07-04 09:39:44 -04:00
parent 8414ebffa5
commit a3b434be1c
3 changed files with 73 additions and 63 deletions

View File

@ -15,6 +15,7 @@
#include "../../ClientData.h"
#include "../../AdornedRulerPanel.h"
#include "../../Project.h"
#include "../../ProjectWindow.h"
#include "../../TrackPanel.h"
#include <wx/dcclient.h>
@ -207,3 +208,70 @@ static const AudacityProject::AttachedObjects::RegisteredFactory sOverlayKey{
return result;
}
};
///////////////////////////////////////////////////////////////////////////////
// class ScrubForwarder intercepts some mouse events of the main window
// I need this because I can't push the scrubber as an event handler
// in two places at once.
struct ScrubForwarder
: public wxEvtHandler
, public ClientData::Base
{
ScrubForwarder( AudacityProject &project ) : mProject{ project } {}
AudacityProject &mProject;
void OnMouse(wxMouseEvent &event);
DECLARE_EVENT_TABLE()
};
void ScrubForwarder::OnMouse(wxMouseEvent &event)
{
auto &scrubber = Scrubber::Get( mProject );
auto &ruler = AdornedRulerPanel::Get( mProject );
const auto &state = ::wxGetMouseState();
const auto &position = state.GetPosition();
scrubber.SetMayDragToSeek(
ruler.GetScreenRect().Contains(position) );
/*
auto trackPanel = mProject->GetTrackPanel();
if (trackPanel &&
trackPanel->GetScreenRect().Contains(position))
return true;
*/
//auto ruler = scrubber.mProject->GetRulerPanel();
auto isScrubbing = scrubber.IsScrubbing();
if (isScrubbing && !event.HasAnyModifiers()) {
if(event.LeftDown() && scrubber.MayDragToSeek()) {
// This event handler may catch mouse transitions that are missed
// by the polling of mouse state by the timer.
scrubber.SetSeekPress( true );
}
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();
}
BEGIN_EVENT_TABLE(ScrubForwarder, wxEvtHandler)
EVT_MOUSE_EVENTS(ScrubForwarder::OnMouse)
END_EVENT_TABLE()
static const AudacityProject::AttachedObjects::RegisteredFactory sForwarderKey{
[]( AudacityProject &parent ){
auto result = std::make_shared< ScrubForwarder >( parent );
auto &window = ProjectWindow::Get( parent );
window.PushEventHandler( result.get() );
return result;
}
};

View File

@ -15,7 +15,6 @@ Paul Licameli split from TrackPanel.cpp
#include <functional>
#include "../../AdornedRulerPanel.h"
#include "../../AudioIO.h"
#include "../../CommonCommandFlags.h"
#include "../../Menus.h"
@ -231,8 +230,6 @@ Scrubber::Scrubber(AudacityProject *project)
wxTheApp->Bind
(wxEVT_ACTIVATE_APP,
&Scrubber::OnActivateOrDeactivateApp, this);
if (mWindow)
mWindow->PushEventHandler(&mForwarder);
UpdatePrefs();
}
@ -779,27 +776,6 @@ bool Scrubber::ChoseSeeking() const
mSeeking;
}
bool Scrubber::MayDragToSeek() const
{
// Return true only if the pointer is in the
// ruler or the track panel
const auto &state = ::wxGetMouseState();
const auto &position = state.GetPosition();
auto &ruler = AdornedRulerPanel::Get( *mProject );
if (ruler.GetScreenRect().Contains(position))
return true;
/*
auto trackPanel = mProject->GetTrackPanel();
if (trackPanel &&
trackPanel->GetScreenRect().Contains(position))
return true;
*/
return false;
}
bool Scrubber::TemporarilySeeks() const
{
return mScrubSeekPress ||
@ -891,28 +867,6 @@ void Scrubber::OnActivateOrDeactivateApp(wxActivateEvent &event)
event.Skip();
}
void Scrubber::Forwarder::OnMouse(wxMouseEvent &event)
{
//auto ruler = scrubber.mProject->GetRulerPanel();
auto isScrubbing = scrubber.IsScrubbing();
if (isScrubbing && !event.HasAnyModifiers()) {
if(event.LeftDown() && scrubber.MayDragToSeek()) {
// This event handler may catch mouse transitions that are missed
// by the polling of mouse state by the timer.
scrubber.mScrubSeekPress = true;
}
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();
}
void Scrubber::DoScrub(bool seek)
{
if( !CanScrub() )
@ -1005,10 +959,6 @@ BEGIN_EVENT_TABLE(Scrubber, wxEvtHandler)
EVT_MENU(CMD_ID + 2, THUNK(OnToggleScrubRuler))
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(Scrubber::Forwarder, wxEvtHandler)
EVT_MOUSE_EVENTS(Scrubber::Forwarder::OnMouse)
END_EVENT_TABLE()
static_assert(nMenuItems == 3, "wrong number of items");
static wxString sPlayAtSpeedStatus = XO("Playing at Speed");

View File

@ -88,7 +88,8 @@ public:
{ mSmoothScrollingScrub = value; }
bool ChoseSeeking() const;
bool MayDragToSeek() const;
void SetMayDragToSeek( bool value ) { mMayDragToSeek = value; }
bool MayDragToSeek() const { return mMayDragToSeek; }
bool TemporarilySeeks() const;
bool Seeks() const;
bool Scrubs() const;
@ -132,6 +133,8 @@ public:
bool IsTransportingPinned() const;
void SetSeekPress( bool value ) { mScrubSeekPress = value; }
private:
void UpdatePrefs() override;
@ -140,18 +143,6 @@ private:
void DoScrub(bool seek);
void OnActivateOrDeactivateApp(wxActivateEvent & event);
// 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;
int mScrubSpeedDisplayCountdown;
@ -192,6 +183,7 @@ private:
double mMaxSpeed { 1.0 };
bool mShowScrubbing { false };
bool mMayDragToSeek{ false };
};
#endif