mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-29 16:53:51 +01:00
Use weak_ptr to remember focused track, don't ask for trouble
This commit is contained in:
@@ -1000,10 +1000,9 @@ void TrackPanel::OnTrackListDeletion(wxCommandEvent & e)
|
|||||||
if (mUIHandle)
|
if (mUIHandle)
|
||||||
mUIHandle->OnProjectChange(GetProject());
|
mUIHandle->OnProjectChange(GetProject());
|
||||||
|
|
||||||
// Tracks may have been deleted, so check to see if the focused track was on of them.
|
// If the focused track disappeared but there are still other tracks,
|
||||||
if (!mTracks->Contains(GetFocusedTrack())) {
|
// this reassigns focus.
|
||||||
SetFocusedTrack(NULL);
|
GetFocusedTrack();
|
||||||
}
|
|
||||||
|
|
||||||
UpdateVRulerSize();
|
UpdateVRulerSize();
|
||||||
|
|
||||||
@@ -2573,7 +2572,7 @@ void TrackPanel::DisplaySelection()
|
|||||||
|
|
||||||
Track *TrackPanel::GetFocusedTrack()
|
Track *TrackPanel::GetFocusedTrack()
|
||||||
{
|
{
|
||||||
return mAx->GetFocus();
|
return mAx->GetFocus().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackPanel::SetFocusedTrack( Track *t )
|
void TrackPanel::SetFocusedTrack( Track *t )
|
||||||
@@ -2590,7 +2589,7 @@ void TrackPanel::SetFocusedTrack( Track *t )
|
|||||||
AudacityProject::CaptureKeyboard(this);
|
AudacityProject::CaptureKeyboard(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
mAx->SetFocus( t );
|
mAx->SetFocus( Track::Pointer( t ) );
|
||||||
Refresh( false );
|
Refresh( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ TrackPanelAx::TrackPanelAx( wxWindow *window )
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
mTrackPanel = wxDynamicCast( window, TrackPanel );
|
mTrackPanel = wxDynamicCast( window, TrackPanel );
|
||||||
mFocusedTrack = NULL;
|
|
||||||
|
|
||||||
mTrackName = true;
|
mTrackName = true;
|
||||||
mMessageCount = 0;
|
mMessageCount = 0;
|
||||||
@@ -47,56 +46,56 @@ TrackPanelAx::~TrackPanelAx()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns currently focused track or first one if none focused
|
// Returns currently focused track or first one if none focused
|
||||||
Track *TrackPanelAx::GetFocus()
|
std::shared_ptr<Track> TrackPanelAx::GetFocus()
|
||||||
{
|
{
|
||||||
if( !mFocusedTrack )
|
auto focusedTrack = mFocusedTrack.lock();
|
||||||
|
if( !focusedTrack )
|
||||||
|
focusedTrack = SetFocus();
|
||||||
|
|
||||||
|
if( !TrackNum( focusedTrack ) )
|
||||||
{
|
{
|
||||||
SetFocus( NULL );
|
mFocusedTrack.reset();
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !TrackNum( mFocusedTrack ) )
|
return( focusedTrack );
|
||||||
{
|
|
||||||
mFocusedTrack = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return( mFocusedTrack );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Changes focus to a specified track
|
// Changes focus to a specified track
|
||||||
void TrackPanelAx::SetFocus( Track *track )
|
std::shared_ptr<Track> TrackPanelAx::SetFocus( std::shared_ptr<Track> track )
|
||||||
{
|
{
|
||||||
mTrackName = true;
|
mTrackName = true;
|
||||||
|
|
||||||
#if wxUSE_ACCESSIBILITY
|
#if wxUSE_ACCESSIBILITY
|
||||||
|
|
||||||
if( mFocusedTrack != NULL && !mFocusedTrack->GetSelected() )
|
auto focusedTrack = mFocusedTrack.lock();
|
||||||
|
if( focusedTrack && !focusedTrack->GetSelected() )
|
||||||
{
|
{
|
||||||
NotifyEvent( wxACC_EVENT_OBJECT_SELECTIONREMOVE,
|
NotifyEvent( wxACC_EVENT_OBJECT_SELECTIONREMOVE,
|
||||||
mTrackPanel,
|
mTrackPanel,
|
||||||
wxOBJID_CLIENT,
|
wxOBJID_CLIENT,
|
||||||
TrackNum( mFocusedTrack ) );
|
TrackNum( focusedTrack ) );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( track == NULL )
|
if( !track )
|
||||||
{
|
{
|
||||||
TrackListIterator iter( mTrackPanel->GetTracks() );
|
TrackListIterator iter( mTrackPanel->GetTracks() );
|
||||||
track = iter.First();
|
track = Track::Pointer( iter.First() );
|
||||||
}
|
}
|
||||||
|
|
||||||
mFocusedTrack = track;
|
|
||||||
|
|
||||||
#if wxUSE_ACCESSIBILITY
|
#if wxUSE_ACCESSIBILITY
|
||||||
if( mFocusedTrack != NULL )
|
if( track )
|
||||||
{
|
{
|
||||||
int num = TrackNum( mFocusedTrack );
|
int num = TrackNum( track );
|
||||||
|
|
||||||
NotifyEvent( wxACC_EVENT_OBJECT_FOCUS,
|
NotifyEvent( wxACC_EVENT_OBJECT_FOCUS,
|
||||||
mTrackPanel,
|
mTrackPanel,
|
||||||
wxOBJID_CLIENT,
|
wxOBJID_CLIENT,
|
||||||
num );
|
num );
|
||||||
|
|
||||||
if( mFocusedTrack->GetSelected() )
|
if( track->GetSelected() )
|
||||||
{
|
{
|
||||||
NotifyEvent( wxACC_EVENT_OBJECT_SELECTION,
|
NotifyEvent( wxACC_EVENT_OBJECT_SELECTION,
|
||||||
mTrackPanel,
|
mTrackPanel,
|
||||||
@@ -106,19 +105,20 @@ void TrackPanelAx::SetFocus( Track *track )
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return;
|
mFocusedTrack = track;
|
||||||
|
|
||||||
|
return track;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns TRUE if passed track has the focus
|
// Returns TRUE if passed track has the focus
|
||||||
bool TrackPanelAx::IsFocused( Track *track )
|
bool TrackPanelAx::IsFocused( Track *track )
|
||||||
{
|
{
|
||||||
if( !mFocusedTrack )
|
auto focusedTrack = mFocusedTrack.lock();
|
||||||
{
|
if( !focusedTrack )
|
||||||
SetFocus( NULL );
|
focusedTrack = SetFocus();
|
||||||
}
|
|
||||||
|
|
||||||
if( ( track == mFocusedTrack ) ||
|
if( ( track == focusedTrack.get() ) ||
|
||||||
( track == mFocusedTrack->GetLink() ) )
|
( track == focusedTrack->GetLink() ) )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@ bool TrackPanelAx::IsFocused( Track *track )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TrackPanelAx::TrackNum( Track *target )
|
int TrackPanelAx::TrackNum( const std::shared_ptr<Track> &target )
|
||||||
{
|
{
|
||||||
TrackListIterator iter( mTrackPanel->GetTracks() );
|
TrackListIterator iter( mTrackPanel->GetTracks() );
|
||||||
Track *t = iter.First();
|
Track *t = iter.First();
|
||||||
@@ -135,7 +135,7 @@ int TrackPanelAx::TrackNum( Track *target )
|
|||||||
while( t != NULL )
|
while( t != NULL )
|
||||||
{
|
{
|
||||||
ndx++;
|
ndx++;
|
||||||
if( t == target )
|
if( t == target.get() )
|
||||||
{
|
{
|
||||||
return ndx;
|
return ndx;
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,7 @@ int TrackPanelAx::TrackNum( Track *target )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Track *TrackPanelAx::FindTrack( int num )
|
std::shared_ptr<Track> TrackPanelAx::FindTrack( int num )
|
||||||
{
|
{
|
||||||
TrackListIterator iter( mTrackPanel->GetTracks() );
|
TrackListIterator iter( mTrackPanel->GetTracks() );
|
||||||
Track *t = iter.First();
|
Track *t = iter.First();
|
||||||
@@ -163,13 +163,13 @@ Track *TrackPanelAx::FindTrack( int num )
|
|||||||
t = iter.Next( true );
|
t = iter.Next( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
return t;
|
return Track::Pointer( t );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackPanelAx::Updated()
|
void TrackPanelAx::Updated()
|
||||||
{
|
{
|
||||||
#if wxUSE_ACCESSIBILITY
|
#if wxUSE_ACCESSIBILITY
|
||||||
Track *t = GetFocus();
|
auto t = GetFocus();
|
||||||
mTrackName = true;
|
mTrackName = true;
|
||||||
|
|
||||||
// logically, this should be an OBJECT_NAMECHANGE event, but Window eyes 9.1
|
// logically, this should be an OBJECT_NAMECHANGE event, but Window eyes 9.1
|
||||||
@@ -186,7 +186,7 @@ void TrackPanelAx::MessageForScreenReader(const wxString& message)
|
|||||||
#if wxUSE_ACCESSIBILITY
|
#if wxUSE_ACCESSIBILITY
|
||||||
if (mTrackPanel == wxWindow::FindFocus())
|
if (mTrackPanel == wxWindow::FindFocus())
|
||||||
{
|
{
|
||||||
Track *t = GetFocus();
|
auto t = GetFocus();
|
||||||
int childId = t ? TrackNum(t) : 0;
|
int childId = t ? TrackNum(t) : 0;
|
||||||
|
|
||||||
mMessage = message;
|
mMessage = message;
|
||||||
@@ -299,14 +299,14 @@ wxAccStatus TrackPanelAx::GetLocation( wxRect& rect, int elementId )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Track *t = FindTrack( elementId );
|
auto t = FindTrack( elementId );
|
||||||
|
|
||||||
if( t == NULL )
|
if( t == NULL )
|
||||||
{
|
{
|
||||||
return wxACC_FAIL;
|
return wxACC_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rect = mTrackPanel->FindTrackRect( t, false );
|
rect = mTrackPanel->FindTrackRect( t.get(), false );
|
||||||
// Inflate the screen reader's rectangle so it overpaints Audacity's own
|
// Inflate the screen reader's rectangle so it overpaints Audacity's own
|
||||||
// yellow focus rectangle.
|
// yellow focus rectangle.
|
||||||
#ifdef __WXMAC__
|
#ifdef __WXMAC__
|
||||||
@@ -334,7 +334,7 @@ wxAccStatus TrackPanelAx::GetName( int childId, wxString* name )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Track *t = FindTrack( childId );
|
auto t = FindTrack( childId );
|
||||||
|
|
||||||
if( t == NULL )
|
if( t == NULL )
|
||||||
{
|
{
|
||||||
@@ -371,7 +371,7 @@ wxAccStatus TrackPanelAx::GetName( int childId, wxString* name )
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// LLL: Remove these during "refactor"
|
// LLL: Remove these during "refactor"
|
||||||
auto pt = dynamic_cast<PlayableTrack *>(t);
|
auto pt = dynamic_cast<PlayableTrack *>(t.get());
|
||||||
if( pt && pt->GetMute() )
|
if( pt && pt->GetMute() )
|
||||||
{
|
{
|
||||||
// The following comment also applies to the solo, selected,
|
// The following comment also applies to the solo, selected,
|
||||||
@@ -475,7 +475,7 @@ wxAccStatus TrackPanelAx::GetState( int childId, long* state )
|
|||||||
#if defined(__WXMSW__)
|
#if defined(__WXMSW__)
|
||||||
if( childId > 0 )
|
if( childId > 0 )
|
||||||
{
|
{
|
||||||
Track *t = FindTrack( childId );
|
auto t = FindTrack( childId );
|
||||||
|
|
||||||
*state = wxACC_STATE_SYSTEM_FOCUSABLE | wxACC_STATE_SYSTEM_SELECTABLE;
|
*state = wxACC_STATE_SYSTEM_FOCUSABLE | wxACC_STATE_SYSTEM_SELECTABLE;
|
||||||
if (t)
|
if (t)
|
||||||
@@ -502,11 +502,11 @@ wxAccStatus TrackPanelAx::GetState( int childId, long* state )
|
|||||||
|
|
||||||
if( childId > 0 )
|
if( childId > 0 )
|
||||||
{
|
{
|
||||||
Track *t = FindTrack( childId );
|
auto t = FindTrack( childId );
|
||||||
|
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
if( t == mFocusedTrack )
|
if( t == mFocusedTrack.lock() )
|
||||||
{
|
{
|
||||||
*state |= wxACC_STATE_SYSTEM_FOCUSED;
|
*state |= wxACC_STATE_SYSTEM_FOCUSED;
|
||||||
}
|
}
|
||||||
@@ -541,7 +541,7 @@ wxAccStatus TrackPanelAx::GetValue( int WXUNUSED(childId), wxString* WXUNUSED(st
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Track *t = FindTrack( childId );
|
auto t = FindTrack( childId );
|
||||||
|
|
||||||
if( t == NULL )
|
if( t == NULL )
|
||||||
{
|
{
|
||||||
@@ -556,7 +556,7 @@ wxAccStatus TrackPanelAx::GetValue( int WXUNUSED(childId), wxString* WXUNUSED(st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LLL: Remove these during "refactor"
|
// LLL: Remove these during "refactor"
|
||||||
auto pt = dynamic_cast<PlayableTrack *>(t);
|
auto pt = dynamic_cast<PlayableTrack *>(t.get());
|
||||||
if( pt && pt->GetMute() )
|
if( pt && pt->GetMute() )
|
||||||
{
|
{
|
||||||
strValue->Append( _( " Mute On" ) );
|
strValue->Append( _( " Mute On" ) );
|
||||||
@@ -602,14 +602,15 @@ wxAccStatus TrackPanelAx::GetFocus( int *childId, wxAccessible **child )
|
|||||||
#if defined(__WXMAC__)
|
#if defined(__WXMAC__)
|
||||||
if( GetWindow() == wxWindow::FindFocus() )
|
if( GetWindow() == wxWindow::FindFocus() )
|
||||||
{
|
{
|
||||||
if( mFocusedTrack )
|
auto focusedTrack = mFocusedTrack.lock();
|
||||||
|
if( focusedTrack )
|
||||||
{
|
{
|
||||||
*childId = TrackNum( mFocusedTrack );
|
*childId = TrackNum( focusedTrack );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*childId = wxACC_SELF;
|
*childId = wxACC_SELF;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxACC_OK;
|
return wxACC_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,10 +32,12 @@ public:
|
|||||||
virtual ~ TrackPanelAx();
|
virtual ~ TrackPanelAx();
|
||||||
|
|
||||||
// Returns currently focused track or first one if none focused
|
// Returns currently focused track or first one if none focused
|
||||||
Track *GetFocus();
|
std::shared_ptr<Track> GetFocus();
|
||||||
|
|
||||||
// Changes focus to a specified track
|
// Changes focus to a specified track
|
||||||
void SetFocus( Track *track );
|
// Return is the actual focused track, which may be different from
|
||||||
|
// the argument when that is null
|
||||||
|
std::shared_ptr<Track> SetFocus( std::shared_ptr<Track> track = {} );
|
||||||
|
|
||||||
// Returns TRUE if passed track has the focus
|
// Returns TRUE if passed track has the focus
|
||||||
bool IsFocused( Track *track );
|
bool IsFocused( Track *track );
|
||||||
@@ -107,11 +109,12 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int TrackNum( Track *track );
|
int TrackNum( const std::shared_ptr<Track> &track );
|
||||||
Track *FindTrack( int num );
|
std::shared_ptr<Track> FindTrack( int num );
|
||||||
|
|
||||||
TrackPanel *mTrackPanel;
|
TrackPanel *mTrackPanel;
|
||||||
Track *mFocusedTrack;
|
|
||||||
|
std::weak_ptr<Track> mFocusedTrack;
|
||||||
|
|
||||||
wxString mMessage;
|
wxString mMessage;
|
||||||
bool mTrackName;
|
bool mTrackName;
|
||||||
|
|||||||
Reference in New Issue
Block a user