mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-05 08:33:53 +01:00
weak_ptr not events to avoid dangling track pointers in UIHandles
This commit is contained in:
@@ -82,7 +82,7 @@ UIHandle::Result TrackPanelResizeHandle::Click
|
||||
if (!track)
|
||||
return RefreshCode::Cancelled;
|
||||
|
||||
mpTrack = track;
|
||||
mpTrack = Track::Pointer( track );
|
||||
|
||||
/// ButtonDown means they just clicked and haven't released yet.
|
||||
/// We use this opportunity to save which track they clicked on,
|
||||
@@ -153,7 +153,8 @@ UIHandle::Result TrackPanelResizeHandle::Click
|
||||
UIHandle::Result TrackPanelResizeHandle::Drag
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||
{
|
||||
if ( !mpTrack )
|
||||
auto pTrack = mpTrack.lock();
|
||||
if ( !pTrack )
|
||||
return RefreshCode::Cancelled;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
@@ -166,11 +167,11 @@ UIHandle::Result TrackPanelResizeHandle::Drag
|
||||
//
|
||||
// This used to be in HandleResizeClick(), but simply clicking
|
||||
// on a resize border would switch the minimized state.
|
||||
if (mpTrack->GetMinimized()) {
|
||||
Track *link = mpTrack->GetLink();
|
||||
if (pTrack->GetMinimized()) {
|
||||
Track *link = pTrack->GetLink();
|
||||
|
||||
mpTrack->SetHeight(mpTrack->GetHeight());
|
||||
mpTrack->SetMinimized(false);
|
||||
pTrack->SetHeight(pTrack->GetHeight());
|
||||
pTrack->SetMinimized(false);
|
||||
|
||||
if (link) {
|
||||
link->SetHeight(link->GetHeight());
|
||||
@@ -178,7 +179,7 @@ UIHandle::Result TrackPanelResizeHandle::Drag
|
||||
// Initial values must be reset since they weren't based on the
|
||||
// minimized heights.
|
||||
mInitialUpperTrackHeight = link->GetHeight();
|
||||
mInitialTrackHeight = mpTrack->GetHeight();
|
||||
mInitialTrackHeight = pTrack->GetHeight();
|
||||
}
|
||||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
else if (MONO_WAVE_PAN(mpTrack)){
|
||||
@@ -201,12 +202,12 @@ UIHandle::Result TrackPanelResizeHandle::Drag
|
||||
(mInitialUpperTrackHeight + delta * (1.0 - proportion));
|
||||
|
||||
//make sure neither track is smaller than its minimum height
|
||||
if (newTrackHeight < mpTrack->GetMinimizedHeight())
|
||||
newTrackHeight = mpTrack->GetMinimizedHeight();
|
||||
if (newTrackHeight < pTrack->GetMinimizedHeight())
|
||||
newTrackHeight = pTrack->GetMinimizedHeight();
|
||||
if (newUpperTrackHeight < prev->GetMinimizedHeight())
|
||||
newUpperTrackHeight = prev->GetMinimizedHeight();
|
||||
|
||||
mpTrack->SetHeight(newTrackHeight
|
||||
pTrack->SetHeight(newTrackHeight
|
||||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
, vStereo
|
||||
#endif
|
||||
@@ -224,10 +225,10 @@ UIHandle::Result TrackPanelResizeHandle::Drag
|
||||
newUpperTrackHeight =
|
||||
mInitialUpperTrackHeight + mInitialTrackHeight - next->GetMinimizedHeight();
|
||||
}
|
||||
if (newUpperTrackHeight < mpTrack->GetMinimizedHeight()) {
|
||||
newUpperTrackHeight = mpTrack->GetMinimizedHeight();
|
||||
if (newUpperTrackHeight < pTrack->GetMinimizedHeight()) {
|
||||
newUpperTrackHeight = pTrack->GetMinimizedHeight();
|
||||
newTrackHeight =
|
||||
mInitialUpperTrackHeight + mInitialTrackHeight - mpTrack->GetMinimizedHeight();
|
||||
mInitialUpperTrackHeight + mInitialTrackHeight - pTrack->GetMinimizedHeight();
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
@@ -239,7 +240,7 @@ UIHandle::Result TrackPanelResizeHandle::Drag
|
||||
}
|
||||
#endif
|
||||
|
||||
mpTrack->SetHeight(newUpperTrackHeight);
|
||||
pTrack->SetHeight(newUpperTrackHeight);
|
||||
next->SetHeight(newTrackHeight
|
||||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
, vStereo
|
||||
@@ -249,9 +250,9 @@ UIHandle::Result TrackPanelResizeHandle::Drag
|
||||
|
||||
auto doResize = [&] {
|
||||
int newTrackHeight = mInitialTrackHeight + delta;
|
||||
if (newTrackHeight < mpTrack->GetMinimizedHeight())
|
||||
newTrackHeight = mpTrack->GetMinimizedHeight();
|
||||
mpTrack->SetHeight(newTrackHeight);
|
||||
if (newTrackHeight < pTrack->GetMinimizedHeight())
|
||||
newTrackHeight = pTrack->GetMinimizedHeight();
|
||||
pTrack->SetHeight(newTrackHeight);
|
||||
};
|
||||
|
||||
//STM: We may be dragging one or two (stereo) tracks.
|
||||
@@ -291,13 +292,13 @@ UIHandle::Result TrackPanelResizeHandle::Drag
|
||||
{
|
||||
case IsResizingBelowLinkedTracks:
|
||||
{
|
||||
Track *prev = tracks->GetPrev(mpTrack);
|
||||
Track *prev = tracks->GetPrev(pTrack.get());
|
||||
doResizeBelow(prev, false);
|
||||
break;
|
||||
}
|
||||
case IsResizingBetweenLinkedTracks:
|
||||
{
|
||||
Track *next = tracks->GetNext(mpTrack);
|
||||
Track *next = tracks->GetNext(pTrack.get());
|
||||
doResizeBetween(next, false);
|
||||
break;
|
||||
}
|
||||
@@ -337,7 +338,8 @@ UIHandle::Result TrackPanelResizeHandle::Release
|
||||
|
||||
UIHandle::Result TrackPanelResizeHandle::Cancel(AudacityProject *pProject)
|
||||
{
|
||||
if ( !mpTrack )
|
||||
auto pTrack = mpTrack.lock();
|
||||
if ( !pTrack )
|
||||
return RefreshCode::Cancelled;
|
||||
|
||||
TrackList *const tracks = pProject->GetTracks();
|
||||
@@ -345,15 +347,15 @@ UIHandle::Result TrackPanelResizeHandle::Cancel(AudacityProject *pProject)
|
||||
switch (mMode) {
|
||||
case IsResizing:
|
||||
{
|
||||
mpTrack->SetHeight(mInitialActualHeight);
|
||||
mpTrack->SetMinimized(mInitialMinimized);
|
||||
pTrack->SetHeight(mInitialActualHeight);
|
||||
pTrack->SetMinimized(mInitialMinimized);
|
||||
}
|
||||
break;
|
||||
case IsResizingBetweenLinkedTracks:
|
||||
{
|
||||
Track *const next = tracks->GetNext(mpTrack);
|
||||
mpTrack->SetHeight(mInitialUpperActualHeight);
|
||||
mpTrack->SetMinimized(mInitialMinimized);
|
||||
Track *const next = tracks->GetNext(pTrack.get());
|
||||
pTrack->SetHeight(mInitialUpperActualHeight);
|
||||
pTrack->SetMinimized(mInitialMinimized);
|
||||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
if( !MONO_WAVE_PAN(mpTrack) )
|
||||
#endif
|
||||
@@ -365,9 +367,9 @@ UIHandle::Result TrackPanelResizeHandle::Cancel(AudacityProject *pProject)
|
||||
break;
|
||||
case IsResizingBelowLinkedTracks:
|
||||
{
|
||||
Track *const prev = tracks->GetPrev(mpTrack);
|
||||
mpTrack->SetHeight(mInitialActualHeight);
|
||||
mpTrack->SetMinimized(mInitialMinimized);
|
||||
Track *const prev = tracks->GetPrev(pTrack.get());
|
||||
pTrack->SetHeight(mInitialActualHeight);
|
||||
pTrack->SetMinimized(mInitialMinimized);
|
||||
#ifdef EXPERIMENTAL_OUTPUT_DISPLAY
|
||||
if( !MONO_WAVE_PAN(mpTrack) )
|
||||
#endif
|
||||
@@ -382,15 +384,6 @@ UIHandle::Result TrackPanelResizeHandle::Cancel(AudacityProject *pProject)
|
||||
return RefreshCode::RefreshAll;
|
||||
}
|
||||
|
||||
void TrackPanelResizeHandle::OnProjectChange(AudacityProject *pProject)
|
||||
{
|
||||
if (! ::GetActiveProject()->GetTracks()->Contains(mpTrack)) {
|
||||
mpTrack = nullptr;
|
||||
}
|
||||
|
||||
UIHandle::OnProjectChange(pProject);
|
||||
}
|
||||
|
||||
TrackPanelResizerCell &TrackPanelResizerCell::Instance()
|
||||
{
|
||||
static TrackPanelResizerCell instance;
|
||||
|
||||
@@ -12,6 +12,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#define __AUDACITY_TRACK_PANEL_RESIZE_HANDLE__
|
||||
|
||||
#include "tracks/ui/CommonTrackPanelCell.h"
|
||||
#include "MemoryX.h"
|
||||
#include "UIHandle.h"
|
||||
|
||||
struct HitTestResult;
|
||||
@@ -46,8 +47,6 @@ public:
|
||||
|
||||
Result Cancel(AudacityProject *pProject) override;
|
||||
|
||||
void OnProjectChange(AudacityProject *pProject) override;
|
||||
|
||||
private:
|
||||
enum Mode {
|
||||
IsResizing,
|
||||
@@ -56,7 +55,7 @@ private:
|
||||
};
|
||||
Mode mMode{ IsResizing };
|
||||
|
||||
Track *mpTrack{};
|
||||
std::weak_ptr<Track> mpTrack;
|
||||
|
||||
bool mInitialMinimized{};
|
||||
int mInitialTrackHeight{};
|
||||
|
||||
@@ -85,11 +85,16 @@ public:
|
||||
|
||||
// Whether to force Release (not Cancel!) of the drag when a
|
||||
// keystroke command is about to be dispatched. Default is always false.
|
||||
// When default is false, any remembered pointers to tracks should be
|
||||
// weak_ptrs.
|
||||
virtual bool StopsOnKeystroke();
|
||||
|
||||
// Notification after a command is dispatched; generally, it will need to
|
||||
// be overridden only in case StopsOnKeystroke() returns false. Default
|
||||
// does nothing.
|
||||
// PRL: all former uses of this are now accomplished with weak_ptr instead
|
||||
// to avoid dangling pointers to tracks. But maybe there will be a future
|
||||
// use?
|
||||
virtual void OnProjectChange(AudacityProject *pProject);
|
||||
};
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ LabelDefaultClickHandle::~LabelDefaultClickHandle()
|
||||
}
|
||||
|
||||
struct LabelDefaultClickHandle::LabelState {
|
||||
std::vector< std::pair< LabelTrack*, LabelTrack::Flags > > mPairs;
|
||||
std::vector< std::pair< std::weak_ptr<LabelTrack>, LabelTrack::Flags > > mPairs;
|
||||
};
|
||||
|
||||
void LabelDefaultClickHandle::SaveState( AudacityProject *pProject )
|
||||
@@ -46,32 +46,21 @@ void LabelDefaultClickHandle::SaveState( AudacityProject *pProject )
|
||||
while (n) {
|
||||
if (n->GetKind() == Track::Label) {
|
||||
LabelTrack *const lt = static_cast<LabelTrack*>(n);
|
||||
pairs.push_back( std::make_pair( lt, lt->SaveFlags() ) );
|
||||
pairs.push_back( std::make_pair(
|
||||
Track::Pointer<LabelTrack>( lt ),
|
||||
lt->SaveFlags() )
|
||||
);
|
||||
}
|
||||
n = iter.Next();
|
||||
}
|
||||
}
|
||||
|
||||
void LabelDefaultClickHandle::UpdateState( AudacityProject *pProject )
|
||||
{
|
||||
if ( mLabelState ) {
|
||||
auto trackList = pProject->GetTracks();
|
||||
auto &pairs = mLabelState->mPairs;
|
||||
auto it = pairs.begin();
|
||||
while ( it != pairs.end() ) {
|
||||
if ( trackList->Contains( it->first ) )
|
||||
++it;
|
||||
else
|
||||
it = pairs.erase( it );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LabelDefaultClickHandle::RestoreState( AudacityProject *pProject )
|
||||
{
|
||||
if ( mLabelState ) {
|
||||
for ( const auto &pair : mLabelState->mPairs )
|
||||
pair.first->RestoreFlags( pair.second );
|
||||
if (auto pLt = pair.first.lock())
|
||||
pLt->RestoreFlags( pair.second );
|
||||
mLabelState.reset();
|
||||
}
|
||||
}
|
||||
@@ -174,7 +163,6 @@ bool LabelDefaultClickHandle::StopsOnKeystroke()
|
||||
|
||||
void LabelDefaultClickHandle::OnProjectChange(AudacityProject *pProject)
|
||||
{
|
||||
UpdateState( pProject );
|
||||
if (mpForward)
|
||||
return mpForward->OnProjectChange(pProject);
|
||||
UIHandle::OnProjectChange(pProject);
|
||||
|
||||
@@ -63,7 +63,6 @@ private:
|
||||
struct LabelState;
|
||||
std::unique_ptr< LabelState > mLabelState;
|
||||
void SaveState( AudacityProject *pProject );
|
||||
void UpdateState( AudacityProject *pProject );
|
||||
void RestoreState( AudacityProject *pProject );
|
||||
};
|
||||
|
||||
|
||||
@@ -54,10 +54,11 @@ UIHandle::Result LabelTextHandle::Click
|
||||
const wxMouseEvent &event = evt.event;
|
||||
ViewInfo &viewInfo = pProject->GetViewInfo();
|
||||
|
||||
mpLT = static_cast<LabelTrack*>(pCell);
|
||||
auto pLT = Track::Pointer<LabelTrack>( static_cast<Track*>(pCell) );
|
||||
mpLT = pLT;
|
||||
mSelectedRegion = viewInfo.selectedRegion;
|
||||
mpLT->HandleTextClick( event, evt.rect, viewInfo, &viewInfo.selectedRegion );
|
||||
wxASSERT(mpLT->IsSelected());
|
||||
pLT->HandleTextClick( event, evt.rect, viewInfo, &viewInfo.selectedRegion );
|
||||
wxASSERT(pLT->IsSelected());
|
||||
|
||||
{
|
||||
// IF the user clicked a label, THEN select all other tracks by Label
|
||||
@@ -68,7 +69,7 @@ UIHandle::Result LabelTextHandle::Click
|
||||
//do nothing if at least one other track is selected
|
||||
bool done = false;
|
||||
while (!done && t) {
|
||||
if (t->GetSelected() && t != mpLT)
|
||||
if (t->GetSelected() && t != pLT.get())
|
||||
done = true;
|
||||
t = iter.Next();
|
||||
}
|
||||
@@ -88,7 +89,7 @@ UIHandle::Result LabelTextHandle::Click
|
||||
// Do this after, for its effect on TrackPanel's memory of last selected
|
||||
// track (which affects shift-click actions)
|
||||
selectionState.SelectTrack
|
||||
( *pProject->GetTracks(), *mpLT, true, true,
|
||||
( *pProject->GetTracks(), *pLT, true, true,
|
||||
pProject->GetMixerBoard() );
|
||||
}
|
||||
|
||||
@@ -107,8 +108,9 @@ UIHandle::Result LabelTextHandle::Drag
|
||||
Result result = RefreshNone;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
if(mpLT)
|
||||
mpLT->HandleTextDragRelease(event);
|
||||
auto pLT = mpLT.lock();
|
||||
if(pLT)
|
||||
pLT->HandleTextDragRelease(event);
|
||||
|
||||
// locate the initial mouse position
|
||||
if (event.LeftIsDown()) {
|
||||
@@ -116,10 +118,10 @@ UIHandle::Result LabelTextHandle::Drag
|
||||
mLabelTrackStartXPos = event.m_x;
|
||||
mLabelTrackStartYPos = event.m_y;
|
||||
|
||||
if (mpLT &&
|
||||
(mpLT->getSelectedIndex() != -1) &&
|
||||
mpLT->OverTextBox(
|
||||
mpLT->GetLabel(mpLT->getSelectedIndex()),
|
||||
if (pLT &&
|
||||
(pLT->getSelectedIndex() != -1) &&
|
||||
pLT->OverTextBox(
|
||||
pLT->GetLabel(pLT->getSelectedIndex()),
|
||||
mLabelTrackStartXPos,
|
||||
mLabelTrackStartYPos))
|
||||
mLabelTrackStartYPos = -1;
|
||||
@@ -152,8 +154,9 @@ UIHandle::Result LabelTextHandle::Release
|
||||
}
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
if (mpLT)
|
||||
mpLT->HandleTextDragRelease(event);
|
||||
auto pLT = mpLT.lock();
|
||||
if (pLT)
|
||||
pLT->HandleTextDragRelease(event);
|
||||
|
||||
// handle mouse left button up
|
||||
if (event.LeftUp())
|
||||
@@ -172,13 +175,3 @@ UIHandle::Result LabelTextHandle::Cancel( AudacityProject *pProject )
|
||||
viewInfo.selectedRegion = mSelectedRegion;
|
||||
return RefreshCode::RefreshAll;
|
||||
}
|
||||
|
||||
void LabelTextHandle::OnProjectChange(AudacityProject *pProject)
|
||||
{
|
||||
if (! pProject->GetTracks()->Contains(mpLT)) {
|
||||
mpLT = nullptr;
|
||||
mRect = {};
|
||||
}
|
||||
|
||||
UIHandle::OnProjectChange(pProject);
|
||||
}
|
||||
|
||||
@@ -49,11 +49,8 @@ public:
|
||||
|
||||
Result Cancel(AudacityProject *pProject) override;
|
||||
|
||||
void OnProjectChange(AudacityProject *pProject) override;
|
||||
|
||||
private:
|
||||
LabelTrack *mpLT {};
|
||||
wxRect mRect {};
|
||||
std::weak_ptr<LabelTrack> mpLT {};
|
||||
int mLabelTrackStartXPos { -1 };
|
||||
int mLabelTrackStartYPos { -1 };
|
||||
SelectedRegion mSelectedRegion{};
|
||||
|
||||
@@ -57,9 +57,7 @@ protected:
|
||||
|
||||
virtual Result Cancel(AudacityProject *pProject);
|
||||
|
||||
void OnProjectChange(AudacityProject *pProject) override;
|
||||
|
||||
NoteTrack *mpTrack{};
|
||||
std::weak_ptr<NoteTrack> mpTrack;
|
||||
wxRect mRect{};
|
||||
};
|
||||
|
||||
@@ -86,7 +84,7 @@ HitTestResult NoteTrackClickHandle::HitTest
|
||||
return {};
|
||||
if (pTrack->GetKind() == Track::Note &&
|
||||
midiRect.Contains(event.m_x, event.m_y)) {
|
||||
Instance().mpTrack = static_cast<NoteTrack*>(pTrack);
|
||||
Instance().mpTrack = Track::Pointer<NoteTrack>( pTrack );
|
||||
Instance().mRect = midiRect;
|
||||
return {
|
||||
HitTestPreview(),
|
||||
@@ -121,11 +119,12 @@ UIHandle::Result NoteTrackClickHandle::Release
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
|
||||
if (!mpTrack)
|
||||
return RefreshNone;
|
||||
auto pTrack = mpTrack.lock();
|
||||
if (!pTrack)
|
||||
return Cancelled;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
if (mpTrack->LabelClick(mRect, event.m_x, event.m_y,
|
||||
if (pTrack->LabelClick(mRect, event.m_x, event.m_y,
|
||||
event.Button(wxMOUSE_BTN_RIGHT))) {
|
||||
// No undo items needed??
|
||||
pProject->ModifyState(false);
|
||||
@@ -139,16 +138,6 @@ UIHandle::Result NoteTrackClickHandle::Cancel(AudacityProject *)
|
||||
return RefreshCode::RefreshNone;
|
||||
}
|
||||
|
||||
void NoteTrackClickHandle::OnProjectChange(AudacityProject *pProject)
|
||||
{
|
||||
if (! pProject->GetTracks()->Contains(mpTrack)) {
|
||||
mpTrack = nullptr;
|
||||
mRect = {};
|
||||
}
|
||||
|
||||
UIHandle::OnProjectChange(pProject);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
NoteTrackControls::NoteTrackControls()
|
||||
{
|
||||
|
||||
@@ -67,17 +67,15 @@ public:
|
||||
(DrawingPass pass,
|
||||
wxDC * dc, const wxRegion &updateRegion, const wxRect &panelRect);
|
||||
|
||||
void OnProjectChange(AudacityProject *pProject) override;
|
||||
|
||||
private:
|
||||
NoteTrack *mpTrack;
|
||||
std::weak_ptr<NoteTrack> mpTrack;
|
||||
|
||||
int mZoomStart, mZoomEnd;
|
||||
wxRect mRect;
|
||||
};
|
||||
|
||||
NoteTrackVZoomHandle::NoteTrackVZoomHandle()
|
||||
: mpTrack(NULL), mZoomStart(0), mZoomEnd(0), mRect()
|
||||
: mZoomStart(0), mZoomEnd(0), mRect()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -111,9 +109,8 @@ NoteTrackVZoomHandle::~NoteTrackVZoomHandle()
|
||||
UIHandle::Result NoteTrackVZoomHandle::Click
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||
{
|
||||
mpTrack = static_cast<NoteTrack*>(
|
||||
static_cast<NoteTrackVRulerControls*>(evt.pCell)->GetTrack()
|
||||
);
|
||||
mpTrack = Track::Pointer<NoteTrack>(
|
||||
static_cast<NoteTrackVRulerControls*>(evt.pCell)->GetTrack() );
|
||||
mRect = evt.rect;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
@@ -129,9 +126,12 @@ UIHandle::Result NoteTrackVZoomHandle::Click
|
||||
UIHandle::Result NoteTrackVZoomHandle::Drag
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *pProject)
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
if (!mpTrack.lock())
|
||||
return Cancelled;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
mZoomEnd = event.m_y;
|
||||
using namespace RefreshCode;
|
||||
if (IsDragZooming(mZoomStart, mZoomEnd)) {
|
||||
// changed Note track to work like audio track
|
||||
// mpTrack->VScroll(mZoomStart, mZoomEnd);
|
||||
@@ -151,18 +151,19 @@ UIHandle::Result NoteTrackVZoomHandle::Release
|
||||
wxWindow *pParent)
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
if (!mpTrack)
|
||||
auto pTrack = mpTrack.lock();
|
||||
if (!pTrack)
|
||||
return RefreshNone;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
if (IsDragZooming(mZoomStart, mZoomEnd)) {
|
||||
mpTrack->ZoomTo(evt.rect, mZoomStart, mZoomEnd);
|
||||
pTrack->ZoomTo(evt.rect, mZoomStart, mZoomEnd);
|
||||
}
|
||||
else if (event.ShiftDown() || event.RightUp()) {
|
||||
mpTrack->ZoomOut(evt.rect, mZoomEnd);
|
||||
pTrack->ZoomOut(evt.rect, mZoomEnd);
|
||||
}
|
||||
else {
|
||||
mpTrack->ZoomIn(evt.rect, mZoomEnd);
|
||||
pTrack->ZoomIn(evt.rect, mZoomEnd);
|
||||
}
|
||||
|
||||
// TODO: shift-right click as in audio track?
|
||||
@@ -183,22 +184,15 @@ UIHandle::Result NoteTrackVZoomHandle::Cancel(AudacityProject *pProject)
|
||||
void NoteTrackVZoomHandle::DrawExtras
|
||||
(DrawingPass pass, wxDC * dc, const wxRegion &, const wxRect &panelRect)
|
||||
{
|
||||
if (!mpTrack.lock())
|
||||
return;
|
||||
|
||||
if ( pass == UIHandle::Cells &&
|
||||
IsDragZooming( mZoomStart, mZoomEnd ) )
|
||||
TrackVRulerControls::DrawZooming
|
||||
( dc, mRect, panelRect, mZoomStart, mZoomEnd );
|
||||
}
|
||||
|
||||
void NoteTrackVZoomHandle::OnProjectChange(AudacityProject *pProject)
|
||||
{
|
||||
if (! pProject->GetTracks()->Contains(mpTrack)) {
|
||||
mpTrack = nullptr;
|
||||
mRect = {};
|
||||
}
|
||||
|
||||
UIHandle::OnProjectChange(pProject);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
NoteTrackVRulerControls::NoteTrackVRulerControls()
|
||||
: TrackVRulerControls()
|
||||
|
||||
@@ -8,6 +8,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "../../../Audacity.h"
|
||||
#include "PlayableTrackButtonHandles.h"
|
||||
|
||||
#include "../../../HitTestResult.h"
|
||||
@@ -35,8 +36,9 @@ MuteButtonHandle &MuteButtonHandle::Instance()
|
||||
UIHandle::Result MuteButtonHandle::CommitChanges
|
||||
(const wxMouseEvent &event, AudacityProject *pProject, wxWindow *)
|
||||
{
|
||||
if ( dynamic_cast< PlayableTrack* >( mpTrack ) )
|
||||
pProject->DoTrackMute(mpTrack, event.ShiftDown());
|
||||
auto pTrack = mpTrack.lock();
|
||||
if ( dynamic_cast< PlayableTrack* >( pTrack.get() ) )
|
||||
pProject->DoTrackMute(pTrack.get(), event.ShiftDown());
|
||||
|
||||
return RefreshCode::RefreshNone;
|
||||
}
|
||||
@@ -83,8 +85,9 @@ SoloButtonHandle &SoloButtonHandle::Instance()
|
||||
UIHandle::Result SoloButtonHandle::CommitChanges
|
||||
(const wxMouseEvent &event, AudacityProject *pProject, wxWindow *pParent)
|
||||
{
|
||||
if ( dynamic_cast< PlayableTrack* >( mpTrack ) )
|
||||
pProject->DoTrackSolo(mpTrack, event.ShiftDown());
|
||||
auto pTrack = mpTrack.lock();
|
||||
if ( dynamic_cast< PlayableTrack* >( pTrack.get() ) )
|
||||
pProject->DoTrackSolo(pTrack.get(), event.ShiftDown());
|
||||
|
||||
return RefreshCode::RefreshNone;
|
||||
}
|
||||
|
||||
@@ -518,10 +518,8 @@ public:
|
||||
(DrawingPass pass,
|
||||
wxDC * dc, const wxRegion &updateRegion, const wxRect &panelRect);
|
||||
|
||||
void OnProjectChange(AudacityProject *pProject) override;
|
||||
|
||||
private:
|
||||
WaveTrack *mpTrack{};
|
||||
std::weak_ptr<WaveTrack> mpTrack;
|
||||
|
||||
int mZoomStart{}, mZoomEnd{};
|
||||
wxRect mRect{};
|
||||
@@ -561,9 +559,8 @@ WaveTrackVZoomHandle::~WaveTrackVZoomHandle()
|
||||
UIHandle::Result WaveTrackVZoomHandle::Click
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *)
|
||||
{
|
||||
mpTrack = static_cast<WaveTrack*>(
|
||||
static_cast<WaveTrackVRulerControls*>(evt.pCell)->GetTrack()
|
||||
);
|
||||
mpTrack = Track::Pointer<WaveTrack>(
|
||||
static_cast<WaveTrackVRulerControls*>(evt.pCell)->GetTrack() );
|
||||
mRect = evt.rect;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
@@ -576,9 +573,12 @@ UIHandle::Result WaveTrackVZoomHandle::Click
|
||||
UIHandle::Result WaveTrackVZoomHandle::Drag
|
||||
(const TrackPanelMouseEvent &evt, AudacityProject *)
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
if (!mpTrack.lock())
|
||||
return Cancelled;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
mZoomEnd = event.m_y;
|
||||
using namespace RefreshCode;
|
||||
if (IsDragZooming(mZoomStart, mZoomEnd))
|
||||
return RefreshAll;
|
||||
return RefreshNone;
|
||||
@@ -595,7 +595,8 @@ UIHandle::Result WaveTrackVZoomHandle::Release
|
||||
wxWindow *pParent)
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
if (!mpTrack)
|
||||
auto pTrack = mpTrack.lock();
|
||||
if (!pTrack)
|
||||
return RefreshNone;
|
||||
|
||||
const wxMouseEvent &event = evt.event;
|
||||
@@ -608,11 +609,11 @@ UIHandle::Result WaveTrackVZoomHandle::Release
|
||||
!(event.ShiftDown() || event.CmdDown()))
|
||||
{
|
||||
InitMenuData data {
|
||||
mpTrack, mRect, RefreshCode::RefreshNone, event.m_y
|
||||
pTrack.get(), mRect, RefreshCode::RefreshNone, event.m_y
|
||||
};
|
||||
|
||||
PopupMenuTable *const pTable =
|
||||
(mpTrack->GetDisplay() == WaveTrack::Spectrum)
|
||||
(pTrack->GetDisplay() == WaveTrack::Spectrum)
|
||||
? (PopupMenuTable *) &SpectrumVRulerMenuTable::Instance()
|
||||
: (PopupMenuTable *) &WaveformVRulerMenuTable::Instance();
|
||||
std::unique_ptr<PopupMenuTable::Menu>
|
||||
@@ -623,7 +624,7 @@ UIHandle::Result WaveTrackVZoomHandle::Release
|
||||
return data.result;
|
||||
}
|
||||
else
|
||||
HandleWaveTrackVZoom(pProject, mpTrack, shiftDown, rightUp,
|
||||
HandleWaveTrackVZoom(pProject, pTrack.get(), shiftDown, rightUp,
|
||||
mRect, mZoomStart, mZoomEnd, false);
|
||||
|
||||
return UpdateVRuler | RefreshAll;
|
||||
@@ -639,22 +640,15 @@ UIHandle::Result WaveTrackVZoomHandle::Cancel(AudacityProject*)
|
||||
void WaveTrackVZoomHandle::DrawExtras
|
||||
(DrawingPass pass, wxDC * dc, const wxRegion &, const wxRect &panelRect)
|
||||
{
|
||||
if (!mpTrack.lock())
|
||||
return;
|
||||
|
||||
if ( pass == UIHandle::Cells &&
|
||||
IsDragZooming( mZoomStart, mZoomEnd ) )
|
||||
TrackVRulerControls::DrawZooming
|
||||
( dc, mRect, panelRect, mZoomStart, mZoomEnd );
|
||||
}
|
||||
|
||||
void WaveTrackVZoomHandle::OnProjectChange(AudacityProject *pProject)
|
||||
{
|
||||
if (! pProject->GetTracks()->Contains(mpTrack)) {
|
||||
mpTrack = nullptr;
|
||||
mRect = {};
|
||||
}
|
||||
|
||||
UIHandle::OnProjectChange(pProject);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
WaveTrackVRulerControls::WaveTrackVRulerControls()
|
||||
: TrackVRulerControls()
|
||||
|
||||
@@ -45,7 +45,8 @@ UIHandle::Result ButtonHandle::Click
|
||||
|
||||
// Come here for left click or double click
|
||||
if (mRect.Contains(event.m_x, event.m_y)) {
|
||||
mpTrack = static_cast<TrackControls*>(evt.pCell)->GetTrack();
|
||||
mpTrack = Track::Pointer(
|
||||
static_cast<TrackControls*>(evt.pCell)->GetTrack() );
|
||||
TrackControls::gCaptureState = mDragCode;
|
||||
// Toggle visible button state
|
||||
return RefreshCell;
|
||||
@@ -59,6 +60,9 @@ UIHandle::Result ButtonHandle::Drag
|
||||
{
|
||||
const wxMouseEvent &event = evt.event;
|
||||
using namespace RefreshCode;
|
||||
if (!mpTrack.lock())
|
||||
return Cancelled;
|
||||
|
||||
const int newState =
|
||||
mRect.Contains(event.m_x, event.m_y) ? mDragCode : 0;
|
||||
if (TrackControls::gCaptureState == newState)
|
||||
@@ -81,13 +85,17 @@ UIHandle::Result ButtonHandle::Release
|
||||
wxWindow *pParent)
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
auto pTrack = mpTrack.lock();
|
||||
if (!pTrack)
|
||||
return Cancelled;
|
||||
|
||||
Result result = RefreshNone;
|
||||
const wxMouseEvent &event = evt.event;
|
||||
if (TrackControls::gCaptureState) {
|
||||
TrackControls::gCaptureState = 0;
|
||||
result = RefreshCell;
|
||||
}
|
||||
if (mpTrack && mRect.Contains(event.m_x, event.m_y))
|
||||
if (pTrack && mRect.Contains(event.m_x, event.m_y))
|
||||
result |= CommitChanges(event, pProject, pParent);
|
||||
return result;
|
||||
}
|
||||
@@ -102,14 +110,3 @@ UIHandle::Result ButtonHandle::Cancel(AudacityProject *pProject)
|
||||
else
|
||||
return RefreshNone;
|
||||
}
|
||||
|
||||
void ButtonHandle::OnProjectChange(AudacityProject *pProject)
|
||||
{
|
||||
if (! pProject->GetTracks()->Contains(mpTrack)) {
|
||||
mpTrack = nullptr;
|
||||
mRect = {};
|
||||
}
|
||||
|
||||
UIHandle::OnProjectChange(pProject);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ Paul Licameli
|
||||
#define __AUDACITY_BUTTON_HANDLE__
|
||||
|
||||
#include "../../UIHandle.h"
|
||||
#include "../../MemoryX.h"
|
||||
|
||||
class wxMouseEvent;
|
||||
#include <wx/gdicmn.h>
|
||||
@@ -53,10 +54,8 @@ protected:
|
||||
|
||||
Result Cancel(AudacityProject *pProject) override;
|
||||
|
||||
void OnProjectChange(AudacityProject *pProject) override;
|
||||
|
||||
wxRect mRect {};
|
||||
Track *mpTrack {};
|
||||
std::weak_ptr<Track> mpTrack;
|
||||
const int mDragCode;
|
||||
};
|
||||
|
||||
|
||||
@@ -50,8 +50,7 @@ enum {
|
||||
// #define SPECTRAL_EDITING_ESC_KEY
|
||||
|
||||
SelectHandle::SelectHandle()
|
||||
: mpTrack(0)
|
||||
, mRect()
|
||||
: mRect()
|
||||
, mInitialSelection()
|
||||
|
||||
, mSnapManager()
|
||||
@@ -64,7 +63,6 @@ SelectHandle::SelectHandle()
|
||||
, mSelectionBoundary(0)
|
||||
|
||||
, mFreqSelMode(FREQ_SEL_INVALID)
|
||||
, mFreqSelTrack(NULL)
|
||||
, mFreqSelPin(-1.0)
|
||||
, mFrequencySnapper(new SpectrumAnalyst)
|
||||
|
||||
@@ -559,7 +557,7 @@ UIHandle::Result SelectHandle::Click
|
||||
else if (!event.LeftDown())
|
||||
return Cancelled;
|
||||
|
||||
mpTrack = pTrack;
|
||||
mpTrack = Track::Pointer( pTrack );
|
||||
mRect = evt.rect;
|
||||
mInitialSelection = viewInfo.selectedRegion;
|
||||
|
||||
@@ -599,7 +597,7 @@ UIHandle::Result SelectHandle::Click
|
||||
double value;
|
||||
// Shift-click, choose closest boundary
|
||||
SelectionBoundary boundary =
|
||||
ChooseBoundary(viewInfo, event, mpTrack, mRect, false, false, &value);
|
||||
ChooseBoundary(viewInfo, event, pTrack, mRect, false, false, &value);
|
||||
mSelectionBoundary = boundary;
|
||||
switch (boundary) {
|
||||
case SBLeft:
|
||||
@@ -612,14 +610,14 @@ UIHandle::Result SelectHandle::Click
|
||||
#endif
|
||||
mSelStartValid = true;
|
||||
mSelStart = value;
|
||||
AdjustSelection(viewInfo, event.m_x, mRect.x, mpTrack);
|
||||
AdjustSelection(viewInfo, event.m_x, mRect.x, pTrack);
|
||||
break;
|
||||
}
|
||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||
case SBBottom:
|
||||
case SBTop:
|
||||
{
|
||||
mFreqSelTrack = static_cast<const WaveTrack*>(mpTrack);
|
||||
mFreqSelTrack = Track::Pointer<const WaveTrack>( pTrack );
|
||||
mFreqSelPin = value;
|
||||
mFreqSelMode =
|
||||
(boundary == SBBottom)
|
||||
@@ -627,7 +625,9 @@ UIHandle::Result SelectHandle::Click
|
||||
|
||||
// Drag frequency only, not time:
|
||||
mSelStartValid = false;
|
||||
AdjustFreqSelection(viewInfo, event.m_y, mRect.y, mRect.height);
|
||||
AdjustFreqSelection(
|
||||
static_cast<WaveTrack*>(pTrack),
|
||||
viewInfo, event.m_y, mRect.y, mRect.height);
|
||||
break;
|
||||
}
|
||||
case SBCenter:
|
||||
@@ -656,13 +656,13 @@ UIHandle::Result SelectHandle::Click
|
||||
|
||||
//Make sure you are within the selected track
|
||||
bool startNewSelection = true;
|
||||
if (mpTrack && mpTrack->GetSelected()) {
|
||||
if (pTrack && pTrack->GetSelected()) {
|
||||
// Adjusting selection edges can be turned off in the
|
||||
// preferences now
|
||||
if (viewInfo.bAdjustSelectionEdges) {
|
||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||
if (mFreqSelMode == FREQ_SEL_SNAPPING_CENTER &&
|
||||
isSpectralSelectionTrack(mpTrack)) {
|
||||
isSpectralSelectionTrack(pTrack)) {
|
||||
// This code is no longer reachable, but it had a place in the
|
||||
// spectral selection prototype. It used to be that you could be
|
||||
// in a center-frequency-snapping mode that was not a mouse drag
|
||||
@@ -672,11 +672,13 @@ UIHandle::Result SelectHandle::Click
|
||||
// Ignore whether we are inside the time selection.
|
||||
// Exit center-snapping, start dragging the width.
|
||||
mFreqSelMode = FREQ_SEL_PINNED_CENTER;
|
||||
mFreqSelTrack = static_cast<WaveTrack*>(mpTrack);
|
||||
mFreqSelTrack = Track::Pointer<const WaveTrack>( pTrack );
|
||||
mFreqSelPin = viewInfo.selectedRegion.fc();
|
||||
// Do not adjust time boundaries
|
||||
mSelStartValid = false;
|
||||
AdjustFreqSelection(viewInfo, event.m_y, mRect.y, mRect.height);
|
||||
AdjustFreqSelection(
|
||||
static_cast<WaveTrack*>(pTrack),
|
||||
viewInfo, event.m_y, mRect.y, mRect.height);
|
||||
// For persistence of the selection change:
|
||||
pProject->ModifyState(false);
|
||||
mSelectionBoundary = SBWidth;
|
||||
@@ -688,7 +690,7 @@ UIHandle::Result SelectHandle::Click
|
||||
// Not shift-down, choose boundary only within snapping
|
||||
double value;
|
||||
SelectionBoundary boundary =
|
||||
ChooseBoundary(viewInfo, event, mpTrack, mRect, true, true, &value);
|
||||
ChooseBoundary(viewInfo, event, pTrack, mRect, true, true, &value);
|
||||
mSelectionBoundary = boundary;
|
||||
switch (boundary) {
|
||||
case SBNone:
|
||||
@@ -711,7 +713,7 @@ UIHandle::Result SelectHandle::Click
|
||||
startNewSelection = false;
|
||||
// Disable time selection
|
||||
mSelStartValid = false;
|
||||
mFreqSelTrack = static_cast<const WaveTrack*>(mpTrack);
|
||||
mFreqSelTrack = Track::Pointer<const WaveTrack>( pTrack );
|
||||
mFreqSelPin = value;
|
||||
mFreqSelMode =
|
||||
(boundary == SBWidth) ? FREQ_SEL_PINNED_CENTER :
|
||||
@@ -739,17 +741,17 @@ UIHandle::Result SelectHandle::Click
|
||||
// If we didn't move a selection boundary, start a NEW selection
|
||||
selectionState.SelectNone( *trackList, pMixerBoard );
|
||||
#ifdef EXPERIMENTAL_SPECTRAL_EDITING
|
||||
StartFreqSelection (viewInfo, event.m_y, mRect.y, mRect.height, mpTrack);
|
||||
StartFreqSelection (viewInfo, event.m_y, mRect.y, mRect.height, pTrack);
|
||||
#endif
|
||||
StartSelection(pProject, event.m_x, mRect.x);
|
||||
selectionState.SelectTrack
|
||||
( *trackList, *mpTrack, true, true, pMixerBoard );
|
||||
trackPanel->SetFocusedTrack(mpTrack);
|
||||
( *trackList, *pTrack, true, true, pMixerBoard );
|
||||
trackPanel->SetFocusedTrack(pTrack);
|
||||
//On-Demand: check to see if there is an OD thing associated with this track.
|
||||
if (mpTrack->GetKind() == Track::Wave) {
|
||||
if (pTrack->GetKind() == Track::Wave) {
|
||||
if(ODManager::IsInstanceCreated())
|
||||
ODManager::Instance()->DemandTrackUpdate
|
||||
(static_cast<WaveTrack*>(mpTrack),mSelStart);
|
||||
(static_cast<WaveTrack*>(pTrack),mSelStart);
|
||||
}
|
||||
|
||||
Connect(pProject);
|
||||
@@ -787,7 +789,8 @@ UIHandle::Result SelectHandle::Drag
|
||||
}
|
||||
|
||||
// Also fuhggeddaboudit if not in a track.
|
||||
if (!mpTrack)
|
||||
auto pTrack = mpTrack.lock();
|
||||
if (!pTrack)
|
||||
return RefreshNone;
|
||||
|
||||
// JKC: Logic to prevent a selection smaller than 5 pixels to
|
||||
@@ -809,7 +812,7 @@ UIHandle::Result SelectHandle::Drag
|
||||
static_cast<CommonTrackPanelCell*>(evt.pCell)->FindTrack();
|
||||
|
||||
// Handle which tracks are selected
|
||||
Track *sTrack = mpTrack;
|
||||
Track *sTrack = pTrack.get();
|
||||
Track *eTrack = clickedTrack;
|
||||
auto trackList = pProject->GetTracks();
|
||||
auto pMixerBoard = pProject->GetMixerBoard();
|
||||
@@ -824,11 +827,13 @@ UIHandle::Result SelectHandle::Drag
|
||||
if (mFreqSelMode == FREQ_SEL_SNAPPING_CENTER &&
|
||||
!viewInfo.selectedRegion.isPoint())
|
||||
MoveSnappingFreqSelection
|
||||
(pProject, viewInfo, y, mRect.y, mRect.height, mpTrack);
|
||||
(pProject, viewInfo, y, mRect.y, mRect.height, pTrack.get());
|
||||
else
|
||||
#endif
|
||||
if (mFreqSelTrack == mpTrack)
|
||||
AdjustFreqSelection(viewInfo, y, mRect.y, mRect.height);
|
||||
if (mFreqSelTrack.lock() == pTrack)
|
||||
AdjustFreqSelection(
|
||||
static_cast<WaveTrack*>(pTrack.get()),
|
||||
viewInfo, y, mRect.y, mRect.height);
|
||||
#endif
|
||||
|
||||
AdjustSelection(viewInfo, x, mRect.x, clickedTrack);
|
||||
@@ -902,20 +907,6 @@ void SelectHandle::DrawExtras
|
||||
}
|
||||
}
|
||||
|
||||
void SelectHandle::OnProjectChange(AudacityProject *pProject)
|
||||
{
|
||||
if (! pProject->GetTracks()->Contains(mpTrack)) {
|
||||
mpTrack = nullptr;
|
||||
mRect = {};
|
||||
}
|
||||
|
||||
if (! pProject->GetTracks()->Contains(mFreqSelTrack)) {
|
||||
mFreqSelTrack = nullptr;
|
||||
}
|
||||
|
||||
UIHandle::OnProjectChange(pProject);
|
||||
}
|
||||
|
||||
void SelectHandle::Connect(AudacityProject *pProject)
|
||||
{
|
||||
mConnectedProject = pProject;
|
||||
@@ -934,8 +925,8 @@ void SelectHandle::Disconnect()
|
||||
this);
|
||||
mConnectedProject = NULL;
|
||||
|
||||
mpTrack = 0;
|
||||
mFreqSelTrack = nullptr;
|
||||
mpTrack.reset();
|
||||
mFreqSelTrack.reset();
|
||||
|
||||
mSnapManager.reset(NULL);
|
||||
|
||||
@@ -994,7 +985,8 @@ void SelectHandle::OnTimer(wxCommandEvent &event)
|
||||
}
|
||||
}
|
||||
|
||||
if (mAutoScrolling && mpTrack) {
|
||||
auto pTrack = mpTrack.lock();
|
||||
if (mAutoScrolling && pTrack) {
|
||||
// AS: To keep the selection working properly as we scroll,
|
||||
// we fake a mouse event (remember, this method is called
|
||||
// from a timer tick).
|
||||
@@ -1002,7 +994,7 @@ void SelectHandle::OnTimer(wxCommandEvent &event)
|
||||
// AS: For some reason, GCC won't let us pass this directly.
|
||||
wxMouseEvent evt(wxEVT_MOTION);
|
||||
const auto size = trackPanel->GetSize();
|
||||
Drag(TrackPanelMouseEvent{ evt, mRect, size, mpTrack }, project);
|
||||
Drag(TrackPanelMouseEvent{ evt, mRect, size, pTrack.get() }, project);
|
||||
mAutoScrolling = false;
|
||||
mConnectedProject->GetTrackPanel()->Refresh(false);
|
||||
}
|
||||
@@ -1022,7 +1014,8 @@ void SelectHandle::StartSelection
|
||||
mSnapLeft = -1;
|
||||
mSnapRight = -1;
|
||||
bool snappedPoint, snappedTime;
|
||||
if (mSnapManager->Snap(mpTrack, mSelStart, false,
|
||||
auto pTrack = mpTrack.lock();
|
||||
if (mSnapManager->Snap(pTrack.get(), mSelStart, false,
|
||||
&s, &snappedPoint, &snappedTime)) {
|
||||
if (snappedPoint)
|
||||
mSnapLeft = viewInfo.TimeToPosition(s, trackLeftEdge);
|
||||
@@ -1041,7 +1034,7 @@ void SelectHandle::StartSelection
|
||||
/// Extend or contract the existing selection
|
||||
void SelectHandle::AdjustSelection
|
||||
(ViewInfo &viewInfo, int mouseXCoordinate, int trackLeftEdge,
|
||||
Track *pTrack)
|
||||
Track *track)
|
||||
{
|
||||
if (!mSelStartValid)
|
||||
// Must be dragging frequency bounds only.
|
||||
@@ -1052,8 +1045,9 @@ void SelectHandle::AdjustSelection
|
||||
double origSel0, origSel1;
|
||||
double sel0, sel1;
|
||||
|
||||
if (pTrack == NULL && mpTrack != NULL)
|
||||
pTrack = mpTrack;
|
||||
auto pTrack = Track::Pointer( track );
|
||||
if (!pTrack)
|
||||
pTrack = mpTrack.lock();
|
||||
|
||||
if (mSelStart < selend) {
|
||||
sel0 = mSelStart;
|
||||
@@ -1071,14 +1065,14 @@ void SelectHandle::AdjustSelection
|
||||
mSnapLeft = -1;
|
||||
mSnapRight = -1;
|
||||
bool snappedPoint, snappedTime;
|
||||
if (mpTrack &&
|
||||
mSnapManager->Snap(mpTrack, sel0, false,
|
||||
if (pTrack &&
|
||||
mSnapManager->Snap(pTrack.get(), sel0, false,
|
||||
&sel0, &snappedPoint, &snappedTime)) {
|
||||
if (snappedPoint)
|
||||
mSnapLeft = viewInfo.TimeToPosition(sel0, trackLeftEdge);
|
||||
}
|
||||
if (mpTrack &&
|
||||
mSnapManager->Snap(mpTrack, sel1, true,
|
||||
if (pTrack &&
|
||||
mSnapManager->Snap(pTrack.get(), sel1, true,
|
||||
&sel1, &snappedPoint, &snappedTime)) {
|
||||
if (snappedPoint)
|
||||
mSnapRight = viewInfo.TimeToPosition(sel1, trackLeftEdge);
|
||||
@@ -1100,29 +1094,31 @@ void SelectHandle::AdjustSelection
|
||||
//On-Demand: check to see if there is an OD thing associated with this track. If so we want to update the focal point for the task.
|
||||
if (pTrack && (pTrack->GetKind() == Track::Wave) && ODManager::IsInstanceCreated())
|
||||
ODManager::Instance()->DemandTrackUpdate
|
||||
(static_cast<WaveTrack*>(pTrack),sel0); //sel0 is sometimes less than mSelStart
|
||||
(static_cast<WaveTrack*>(pTrack.get()),sel0); //sel0 is sometimes less than mSelStart
|
||||
}
|
||||
|
||||
void SelectHandle::StartFreqSelection(ViewInfo &viewInfo,
|
||||
int mouseYCoordinate, int trackTopEdge,
|
||||
int trackHeight, Track *pTrack)
|
||||
{
|
||||
mFreqSelTrack = NULL;
|
||||
mFreqSelTrack.reset();
|
||||
mFreqSelMode = FREQ_SEL_INVALID;
|
||||
mFreqSelPin = SelectedRegion::UndefinedFrequency;
|
||||
|
||||
if (isSpectralSelectionTrack(pTrack)) {
|
||||
// Spectral selection track is always wave
|
||||
mFreqSelTrack = static_cast<WaveTrack*>(pTrack);
|
||||
auto shTrack = Track::Pointer<const WaveTrack>( pTrack );
|
||||
mFreqSelTrack = shTrack;
|
||||
mFreqSelMode = FREQ_SEL_FREE;
|
||||
mFreqSelPin =
|
||||
PositionToFrequency(mFreqSelTrack, false, mouseYCoordinate,
|
||||
PositionToFrequency(shTrack.get(), false, mouseYCoordinate,
|
||||
trackTopEdge, trackHeight);
|
||||
viewInfo.selectedRegion.setFrequencies(mFreqSelPin, mFreqSelPin);
|
||||
}
|
||||
}
|
||||
|
||||
void SelectHandle::AdjustFreqSelection(ViewInfo &viewInfo,
|
||||
void SelectHandle::AdjustFreqSelection(
|
||||
const WaveTrack *wt, ViewInfo &viewInfo,
|
||||
int mouseYCoordinate, int trackTopEdge,
|
||||
int trackHeight)
|
||||
{
|
||||
@@ -1133,7 +1129,6 @@ void SelectHandle::AdjustFreqSelection(ViewInfo &viewInfo,
|
||||
// Extension happens only when dragging in the same track in which we
|
||||
// started, and that is of a spectrogram display type.
|
||||
|
||||
const WaveTrack *const wt = mFreqSelTrack;
|
||||
const double rate = wt->GetRate();
|
||||
const double frequency =
|
||||
PositionToFrequency(wt, true, mouseYCoordinate,
|
||||
@@ -1211,7 +1206,7 @@ void SelectHandle::HandleCenterFrequencyClick
|
||||
if (shiftDown) {
|
||||
// Disable time selection
|
||||
mSelStartValid = false;
|
||||
mFreqSelTrack = pTrack;
|
||||
mFreqSelTrack = Track::Pointer<const WaveTrack>( pTrack );
|
||||
mFreqSelPin = value;
|
||||
mFreqSelMode = FREQ_SEL_DRAG_CENTER;
|
||||
}
|
||||
@@ -1310,7 +1305,7 @@ void SelectHandle::MoveSnappingFreqSelection
|
||||
// A change here would affect what AdjustFreqSelection() does
|
||||
// in the prototype version where you switch from moving center to
|
||||
// dragging width with a click. No effect now.
|
||||
mFreqSelTrack = wt;
|
||||
mFreqSelTrack = Track::Pointer<const WaveTrack>( wt );
|
||||
|
||||
// SelectNone();
|
||||
// SelectTrack(pTrack, true);
|
||||
|
||||
@@ -63,8 +63,6 @@ public:
|
||||
(DrawingPass pass,
|
||||
wxDC * dc, const wxRegion &updateRegion, const wxRect &panelRect);
|
||||
|
||||
void OnProjectChange(AudacityProject *pProject) override;
|
||||
|
||||
// Receives timer event notifications, to implement auto-scroll
|
||||
void OnTimer(wxCommandEvent &event);
|
||||
|
||||
@@ -82,7 +80,8 @@ private:
|
||||
(ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge,
|
||||
int trackHeight, Track *pTrack);
|
||||
void AdjustFreqSelection
|
||||
(ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge,
|
||||
(const WaveTrack *wt,
|
||||
ViewInfo &viewInfo, int mouseYCoordinate, int trackTopEdge,
|
||||
int trackHeight);
|
||||
|
||||
void HandleCenterFrequencyClick
|
||||
@@ -103,7 +102,7 @@ private:
|
||||
// (const ViewInfo &viewInfo, double hintFrequency, bool logF);
|
||||
|
||||
|
||||
Track *mpTrack;
|
||||
std::weak_ptr<Track> mpTrack;
|
||||
wxRect mRect;
|
||||
SelectedRegion mInitialSelection;
|
||||
|
||||
@@ -131,7 +130,7 @@ private:
|
||||
FREQ_SEL_TOP_FREE,
|
||||
FREQ_SEL_BOTTOM_FREE,
|
||||
} mFreqSelMode;
|
||||
const WaveTrack *mFreqSelTrack {};
|
||||
std::weak_ptr<const WaveTrack> mFreqSelTrack;
|
||||
// Following holds:
|
||||
// the center for FREQ_SEL_PINNED_CENTER,
|
||||
// the ratio of top to center (== center to bottom) for FREQ_SEL_DRAG_CENTER,
|
||||
|
||||
@@ -37,11 +37,12 @@ UIHandle::Result MinimizeButtonHandle::CommitChanges
|
||||
{
|
||||
using namespace RefreshCode;
|
||||
|
||||
if (mpTrack)
|
||||
auto pTrack = mpTrack.lock();
|
||||
if (pTrack)
|
||||
{
|
||||
mpTrack->SetMinimized(!mpTrack->GetMinimized());
|
||||
if (mpTrack->GetLink())
|
||||
mpTrack->GetLink()->SetMinimized(mpTrack->GetMinimized());
|
||||
pTrack->SetMinimized(!pTrack->GetMinimized());
|
||||
if (pTrack->GetLink())
|
||||
pTrack->GetLink()->SetMinimized(pTrack->GetMinimized());
|
||||
pProject->ModifyState(true);
|
||||
|
||||
// Redraw all tracks when any one of them expands or contracts
|
||||
@@ -93,12 +94,13 @@ UIHandle::Result CloseButtonHandle::CommitChanges
|
||||
using namespace RefreshCode;
|
||||
Result result = RefreshNone;
|
||||
|
||||
if (mpTrack)
|
||||
auto pTrack = mpTrack.lock();
|
||||
if (pTrack)
|
||||
{
|
||||
pProject->StopIfPaused();
|
||||
if (!pProject->IsAudioActive()) {
|
||||
// This pushes an undo item:
|
||||
pProject->RemoveTrack(mpTrack);
|
||||
pProject->RemoveTrack(pTrack.get());
|
||||
// Redraw all tracks when any one of them closes
|
||||
// (Could we invent a return code that draws only those at or below
|
||||
// the affected track?)
|
||||
|
||||
Reference in New Issue
Block a user