mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-16 08:34:10 +02:00
Reuse SelectHandle object during movement, as with other handle types
This commit is contained in:
parent
d148c39c2d
commit
308d89b0e6
@ -32,6 +32,8 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#include "../../toolbars/ToolsToolBar.h"
|
#include "../../toolbars/ToolsToolBar.h"
|
||||||
#include "../../../images/Cursors.h"
|
#include "../../../images/Cursors.h"
|
||||||
|
|
||||||
|
#include <wx/event.h>
|
||||||
|
|
||||||
// Only for definition of SonifyBeginModifyState:
|
// Only for definition of SonifyBeginModifyState:
|
||||||
//#include "../../NoteTrack.h"
|
//#include "../../NoteTrack.h"
|
||||||
|
|
||||||
@ -423,21 +425,21 @@ UIHandlePtr SelectHandle::HitTest
|
|||||||
const TrackPanelMouseState &st, const AudacityProject *pProject,
|
const TrackPanelMouseState &st, const AudacityProject *pProject,
|
||||||
const std::shared_ptr<Track> &pTrack)
|
const std::shared_ptr<Track> &pTrack)
|
||||||
{
|
{
|
||||||
// This handle is a little special, not following the pattern of calling
|
// This handle is a little special because there may be some state to
|
||||||
// AssignUIHandlePtr(); there may be some state to preserve during movement
|
// preserve during movement before the click.
|
||||||
// before the click.
|
|
||||||
auto old = holder.lock();
|
auto old = holder.lock();
|
||||||
std::unique_ptr<SnapManager> oldSnapManager;
|
std::shared_ptr<SnapManager> oldSnapManager;
|
||||||
wxInt64 oldSnapLeft = -1, oldSnapRight = -1;
|
wxInt64 oldSnapLeft = -1, oldSnapRight = -1;
|
||||||
if (old) {
|
if (old) {
|
||||||
// It should not have started listening to timer events
|
// It should not have started listening to timer events
|
||||||
wxASSERT( !old->mConnectedProject );
|
wxASSERT( !old->mTimerHandler );
|
||||||
oldSnapManager = std::move(old->mSnapManager);
|
oldSnapManager = std::move(old->mSnapManager);
|
||||||
oldSnapLeft = old->mSnapLeft;
|
oldSnapLeft = old->mSnapLeft;
|
||||||
oldSnapRight = old->mSnapRight;
|
oldSnapRight = old->mSnapRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = std::make_shared<SelectHandle>( pTrack );
|
auto result = std::make_shared<SelectHandle>( pTrack );
|
||||||
|
result = AssignUIHandlePtr(holder, result);
|
||||||
|
|
||||||
// Copy the pre-dragging state
|
// Copy the pre-dragging state
|
||||||
result->mSnapManager = std::move( oldSnapManager );
|
result->mSnapManager = std::move( oldSnapManager );
|
||||||
@ -561,14 +563,14 @@ UIHandle::Result SelectHandle::Click
|
|||||||
mInitialSelection = viewInfo.selectedRegion;
|
mInitialSelection = viewInfo.selectedRegion;
|
||||||
|
|
||||||
TrackList *const trackList = pProject->GetTracks();
|
TrackList *const trackList = pProject->GetTracks();
|
||||||
mSelectionStateChanger = std::make_unique< SelectionStateChanger >
|
mSelectionStateChanger = std::make_shared< SelectionStateChanger >
|
||||||
( selectionState, *trackList );
|
( selectionState, *trackList );
|
||||||
|
|
||||||
mSelectionBoundary = 0;
|
mSelectionBoundary = 0;
|
||||||
|
|
||||||
if (!mSnapManager) {
|
if (!mSnapManager) {
|
||||||
// We create a NEW snap manager in case any snap-points have changed
|
// We create a NEW snap manager in case any snap-points have changed
|
||||||
mSnapManager = std::make_unique<SnapManager>(trackList, &viewInfo);
|
mSnapManager = std::make_shared<SnapManager>(trackList, &viewInfo);
|
||||||
mSnapLeft = -1;
|
mSnapLeft = -1;
|
||||||
mSnapRight = -1;
|
mSnapRight = -1;
|
||||||
}
|
}
|
||||||
@ -954,7 +956,6 @@ UIHandle::Result SelectHandle::Release
|
|||||||
wxWindow *)
|
wxWindow *)
|
||||||
{
|
{
|
||||||
using namespace RefreshCode;
|
using namespace RefreshCode;
|
||||||
Disconnect();
|
|
||||||
pProject->ModifyState(false);
|
pProject->ModifyState(false);
|
||||||
mFrequencySnapper.reset();
|
mFrequencySnapper.reset();
|
||||||
mSnapManager.reset();
|
mSnapManager.reset();
|
||||||
@ -971,8 +972,6 @@ UIHandle::Result SelectHandle::Release
|
|||||||
|
|
||||||
UIHandle::Result SelectHandle::Cancel(AudacityProject *pProject)
|
UIHandle::Result SelectHandle::Cancel(AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
Disconnect();
|
|
||||||
|
|
||||||
mSelectionStateChanger.reset();
|
mSelectionStateChanger.reset();
|
||||||
pProject->GetViewInfo().selectedRegion = mInitialSelection;
|
pProject->GetViewInfo().selectedRegion = mInitialSelection;
|
||||||
|
|
||||||
@ -995,31 +994,41 @@ void SelectHandle::DrawExtras
|
|||||||
|
|
||||||
void SelectHandle::Connect(AudacityProject *pProject)
|
void SelectHandle::Connect(AudacityProject *pProject)
|
||||||
{
|
{
|
||||||
mConnectedProject = pProject;
|
mTimerHandler = std::make_shared<TimerHandler>( this, pProject );
|
||||||
|
}
|
||||||
|
|
||||||
|
class SelectHandle::TimerHandler : public wxEvtHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TimerHandler( SelectHandle *pParent, AudacityProject *pProject )
|
||||||
|
: mParent{ pParent }
|
||||||
|
, mConnectedProject{ pProject }
|
||||||
|
{
|
||||||
|
if (mConnectedProject)
|
||||||
mConnectedProject->Connect(EVT_TRACK_PANEL_TIMER,
|
mConnectedProject->Connect(EVT_TRACK_PANEL_TIMER,
|
||||||
wxCommandEventHandler(SelectHandle::OnTimer),
|
wxCommandEventHandler(SelectHandle::TimerHandler::OnTimer),
|
||||||
NULL,
|
NULL,
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectHandle::Disconnect()
|
~TimerHandler()
|
||||||
{
|
{
|
||||||
if (mConnectedProject)
|
if (mConnectedProject)
|
||||||
mConnectedProject->Disconnect(EVT_TRACK_PANEL_TIMER,
|
mConnectedProject->Disconnect(EVT_TRACK_PANEL_TIMER,
|
||||||
wxCommandEventHandler(SelectHandle::OnTimer),
|
wxCommandEventHandler(SelectHandle::TimerHandler::OnTimer),
|
||||||
NULL,
|
NULL,
|
||||||
this);
|
this);
|
||||||
mConnectedProject = NULL;
|
|
||||||
|
|
||||||
mpTrack.reset();
|
|
||||||
mFreqSelTrack.reset();
|
|
||||||
|
|
||||||
mSnapManager.reset(NULL);
|
|
||||||
|
|
||||||
mFreqSelMode = FREQ_SEL_INVALID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectHandle::OnTimer(wxCommandEvent &event)
|
// Receives timer event notifications, to implement auto-scroll
|
||||||
|
void OnTimer(wxCommandEvent &event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SelectHandle *mParent;
|
||||||
|
AudacityProject *mConnectedProject;
|
||||||
|
};
|
||||||
|
|
||||||
|
void SelectHandle::TimerHandler::OnTimer(wxCommandEvent &event)
|
||||||
{
|
{
|
||||||
event.Skip();
|
event.Skip();
|
||||||
|
|
||||||
@ -1042,12 +1051,12 @@ void SelectHandle::OnTimer(wxCommandEvent &event)
|
|||||||
|
|
||||||
const auto project = mConnectedProject;
|
const auto project = mConnectedProject;
|
||||||
const auto trackPanel = project->GetTrackPanel();
|
const auto trackPanel = project->GetTrackPanel();
|
||||||
if (mMostRecentX >= mRect.x + mRect.width) {
|
if (mParent->mMostRecentX >= mParent->mRect.x + mParent->mRect.width) {
|
||||||
mAutoScrolling = true;
|
mParent->mAutoScrolling = true;
|
||||||
project->TP_ScrollRight();
|
project->TP_ScrollRight();
|
||||||
}
|
}
|
||||||
else if (mMostRecentX < mRect.x) {
|
else if (mParent->mMostRecentX < mParent->mRect.x) {
|
||||||
mAutoScrolling = true;
|
mParent->mAutoScrolling = true;
|
||||||
project->TP_ScrollLeft();
|
project->TP_ScrollLeft();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1055,24 +1064,24 @@ void SelectHandle::OnTimer(wxCommandEvent &event)
|
|||||||
// extreme x coordinate of the screen, even if that is still within the
|
// extreme x coordinate of the screen, even if that is still within the
|
||||||
// track area.
|
// track area.
|
||||||
|
|
||||||
int xx = mMostRecentX, yy = 0;
|
int xx = mParent->mMostRecentX, yy = 0;
|
||||||
trackPanel->ClientToScreen(&xx, &yy);
|
trackPanel->ClientToScreen(&xx, &yy);
|
||||||
if (xx == 0) {
|
if (xx == 0) {
|
||||||
mAutoScrolling = true;
|
mParent->mAutoScrolling = true;
|
||||||
project->TP_ScrollLeft();
|
project->TP_ScrollLeft();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int width, height;
|
int width, height;
|
||||||
::wxDisplaySize(&width, &height);
|
::wxDisplaySize(&width, &height);
|
||||||
if (xx == width - 1) {
|
if (xx == width - 1) {
|
||||||
mAutoScrolling = true;
|
mParent->mAutoScrolling = true;
|
||||||
project->TP_ScrollRight();
|
project->TP_ScrollRight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pTrack = mpTrack.lock(); // TrackList::Lock() ?
|
auto pTrack = mParent->mpTrack.lock(); // TrackList::Lock() ?
|
||||||
if (mAutoScrolling && pTrack) {
|
if (mParent->mAutoScrolling && pTrack) {
|
||||||
// AS: To keep the selection working properly as we scroll,
|
// AS: To keep the selection working properly as we scroll,
|
||||||
// we fake a mouse event (remember, this method is called
|
// we fake a mouse event (remember, this method is called
|
||||||
// from a timer tick).
|
// from a timer tick).
|
||||||
@ -1080,8 +1089,8 @@ void SelectHandle::OnTimer(wxCommandEvent &event)
|
|||||||
// AS: For some reason, GCC won't let us pass this directly.
|
// AS: For some reason, GCC won't let us pass this directly.
|
||||||
wxMouseEvent evt(wxEVT_MOTION);
|
wxMouseEvent evt(wxEVT_MOTION);
|
||||||
const auto size = trackPanel->GetSize();
|
const auto size = trackPanel->GetSize();
|
||||||
Drag(TrackPanelMouseEvent{ evt, mRect, size, pTrack }, project);
|
mParent->Drag(TrackPanelMouseEvent{ evt, mParent->mRect, size, pTrack }, project);
|
||||||
mAutoScrolling = false;
|
mParent->mAutoScrolling = false;
|
||||||
mConnectedProject->GetTrackPanel()->Refresh(false);
|
mConnectedProject->GetTrackPanel()->Refresh(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1304,7 +1313,7 @@ void SelectHandle::HandleCenterFrequencyClick
|
|||||||
mFreqSelMode = FREQ_SEL_SNAPPING_CENTER;
|
mFreqSelMode = FREQ_SEL_SNAPPING_CENTER;
|
||||||
// Disable time selection
|
// Disable time selection
|
||||||
mSelStartValid = false;
|
mSelStartValid = false;
|
||||||
mFrequencySnapper = std::make_unique<SpectrumAnalyst>();
|
mFrequencySnapper = std::make_shared<SpectrumAnalyst>();
|
||||||
StartSnappingFreqSelection(*mFrequencySnapper, viewInfo, pTrack);
|
StartSnappingFreqSelection(*mFrequencySnapper, viewInfo, pTrack);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#include "../../MemoryX.h"
|
#include "../../MemoryX.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <wx/event.h>
|
|
||||||
#include <wx/gdicmn.h>
|
#include <wx/gdicmn.h>
|
||||||
|
|
||||||
class SelectionStateChanger;
|
class SelectionStateChanger;
|
||||||
@ -27,10 +26,9 @@ class Track;
|
|||||||
class ViewInfo;
|
class ViewInfo;
|
||||||
class WaveTrack;
|
class WaveTrack;
|
||||||
|
|
||||||
class SelectHandle : public wxEvtHandler, public UIHandle
|
class SelectHandle : public UIHandle
|
||||||
{
|
{
|
||||||
SelectHandle(const SelectHandle&);
|
SelectHandle(const SelectHandle&);
|
||||||
SelectHandle &operator=(const SelectHandle&);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SelectHandle( const std::shared_ptr<Track> &pTrack );
|
explicit SelectHandle( const std::shared_ptr<Track> &pTrack );
|
||||||
@ -42,6 +40,8 @@ public:
|
|||||||
const TrackPanelMouseState &state, const AudacityProject *pProject,
|
const TrackPanelMouseState &state, const AudacityProject *pProject,
|
||||||
const std::shared_ptr<Track> &pTrack);
|
const std::shared_ptr<Track> &pTrack);
|
||||||
|
|
||||||
|
SelectHandle &operator=(const SelectHandle&) = default;
|
||||||
|
|
||||||
virtual ~SelectHandle();
|
virtual ~SelectHandle();
|
||||||
|
|
||||||
bool IsClicked() const;
|
bool IsClicked() const;
|
||||||
@ -67,12 +67,8 @@ public:
|
|||||||
wxDC * dc, const wxRegion &updateRegion, const wxRect &panelRect)
|
wxDC * dc, const wxRegion &updateRegion, const wxRect &panelRect)
|
||||||
override;
|
override;
|
||||||
|
|
||||||
// Receives timer event notifications, to implement auto-scroll
|
|
||||||
void OnTimer(wxCommandEvent &event);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Connect(AudacityProject *pProject);
|
void Connect(AudacityProject *pProject);
|
||||||
void Disconnect();
|
|
||||||
|
|
||||||
void StartSelection
|
void StartSelection
|
||||||
(AudacityProject *pProject, int mouseXCoordinate, int trackLeftEdge);
|
(AudacityProject *pProject, int mouseXCoordinate, int trackLeftEdge);
|
||||||
@ -117,7 +113,7 @@ private:
|
|||||||
// line up with existing tracks or labels. mSnapLeft and mSnapRight
|
// line up with existing tracks or labels. mSnapLeft and mSnapRight
|
||||||
// are the horizontal index of pixels to display user feedback
|
// are the horizontal index of pixels to display user feedback
|
||||||
// guidelines so the user knows when such snapping is taking place.
|
// guidelines so the user knows when such snapping is taking place.
|
||||||
std::unique_ptr<SnapManager> mSnapManager;
|
std::shared_ptr<SnapManager> mSnapManager;
|
||||||
wxInt64 mSnapLeft{ -1 };
|
wxInt64 mSnapLeft{ -1 };
|
||||||
wxInt64 mSnapRight{ -1 };
|
wxInt64 mSnapRight{ -1 };
|
||||||
|
|
||||||
@ -145,14 +141,16 @@ private:
|
|||||||
// FREQ_SEL_BOTTOM_FREE,
|
// FREQ_SEL_BOTTOM_FREE,
|
||||||
// and is ignored otherwise.
|
// and is ignored otherwise.
|
||||||
double mFreqSelPin{ -1.0 };
|
double mFreqSelPin{ -1.0 };
|
||||||
std::unique_ptr<SpectrumAnalyst> mFrequencySnapper;
|
std::shared_ptr<SpectrumAnalyst> mFrequencySnapper;
|
||||||
|
|
||||||
int mMostRecentX{ -1 }, mMostRecentY{ -1 };
|
int mMostRecentX{ -1 }, mMostRecentY{ -1 };
|
||||||
|
|
||||||
bool mAutoScrolling{};
|
bool mAutoScrolling{};
|
||||||
|
|
||||||
AudacityProject *mConnectedProject{};
|
std::shared_ptr<SelectionStateChanger> mSelectionStateChanger;
|
||||||
|
|
||||||
std::unique_ptr<SelectionStateChanger> mSelectionStateChanger;
|
class TimerHandler;
|
||||||
|
friend TimerHandler;
|
||||||
|
std::shared_ptr<TimerHandler> mTimerHandler;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user