1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-01 07:33:44 +02:00

Use weak_ptr to remember focused track, don't ask for trouble

This commit is contained in:
Paul Licameli 2017-06-24 14:02:35 -04:00
parent bd5d2bf114
commit 321919301e
3 changed files with 58 additions and 55 deletions

View File

@ -1000,10 +1000,9 @@ void TrackPanel::OnTrackListDeletion(wxCommandEvent & e)
if (mUIHandle)
mUIHandle->OnProjectChange(GetProject());
// Tracks may have been deleted, so check to see if the focused track was on of them.
if (!mTracks->Contains(GetFocusedTrack())) {
SetFocusedTrack(NULL);
}
// If the focused track disappeared but there are still other tracks,
// this reassigns focus.
GetFocusedTrack();
UpdateVRulerSize();
@ -2573,7 +2572,7 @@ void TrackPanel::DisplaySelection()
Track *TrackPanel::GetFocusedTrack()
{
return mAx->GetFocus();
return mAx->GetFocus().get();
}
void TrackPanel::SetFocusedTrack( Track *t )
@ -2590,7 +2589,7 @@ void TrackPanel::SetFocusedTrack( Track *t )
AudacityProject::CaptureKeyboard(this);
}
mAx->SetFocus( t );
mAx->SetFocus( Track::Pointer( t ) );
Refresh( false );
}

View File

@ -36,7 +36,6 @@ TrackPanelAx::TrackPanelAx( wxWindow *window )
#endif
{
mTrackPanel = wxDynamicCast( window, TrackPanel );
mFocusedTrack = NULL;
mTrackName = true;
mMessageCount = 0;
@ -47,56 +46,56 @@ TrackPanelAx::~TrackPanelAx()
}
// 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 ) )
{
mFocusedTrack = NULL;
}
return( mFocusedTrack );
return( focusedTrack );
}
// Changes focus to a specified track
void TrackPanelAx::SetFocus( Track *track )
std::shared_ptr<Track> TrackPanelAx::SetFocus( std::shared_ptr<Track> track )
{
mTrackName = true;
#if wxUSE_ACCESSIBILITY
if( mFocusedTrack != NULL && !mFocusedTrack->GetSelected() )
auto focusedTrack = mFocusedTrack.lock();
if( focusedTrack && !focusedTrack->GetSelected() )
{
NotifyEvent( wxACC_EVENT_OBJECT_SELECTIONREMOVE,
mTrackPanel,
wxOBJID_CLIENT,
TrackNum( mFocusedTrack ) );
TrackNum( focusedTrack ) );
}
#endif
if( track == NULL )
if( !track )
{
TrackListIterator iter( mTrackPanel->GetTracks() );
track = iter.First();
track = Track::Pointer( iter.First() );
}
mFocusedTrack = track;
#if wxUSE_ACCESSIBILITY
if( mFocusedTrack != NULL )
if( track )
{
int num = TrackNum( mFocusedTrack );
int num = TrackNum( track );
NotifyEvent( wxACC_EVENT_OBJECT_FOCUS,
mTrackPanel,
wxOBJID_CLIENT,
num );
if( mFocusedTrack->GetSelected() )
if( track->GetSelected() )
{
NotifyEvent( wxACC_EVENT_OBJECT_SELECTION,
mTrackPanel,
@ -106,19 +105,20 @@ void TrackPanelAx::SetFocus( Track *track )
}
#endif
return;
mFocusedTrack = track;
return track;
}
// Returns TRUE if passed track has the focus
bool TrackPanelAx::IsFocused( Track *track )
{
if( !mFocusedTrack )
{
SetFocus( NULL );
}
auto focusedTrack = mFocusedTrack.lock();
if( !focusedTrack )
focusedTrack = SetFocus();
if( ( track == mFocusedTrack ) ||
( track == mFocusedTrack->GetLink() ) )
if( ( track == focusedTrack.get() ) ||
( track == focusedTrack->GetLink() ) )
{
return true;
}
@ -126,7 +126,7 @@ bool TrackPanelAx::IsFocused( Track *track )
return false;
}
int TrackPanelAx::TrackNum( Track *target )
int TrackPanelAx::TrackNum( const std::shared_ptr<Track> &target )
{
TrackListIterator iter( mTrackPanel->GetTracks() );
Track *t = iter.First();
@ -135,7 +135,7 @@ int TrackPanelAx::TrackNum( Track *target )
while( t != NULL )
{
ndx++;
if( t == target )
if( t == target.get() )
{
return ndx;
}
@ -146,7 +146,7 @@ int TrackPanelAx::TrackNum( Track *target )
return 0;
}
Track *TrackPanelAx::FindTrack( int num )
std::shared_ptr<Track> TrackPanelAx::FindTrack( int num )
{
TrackListIterator iter( mTrackPanel->GetTracks() );
Track *t = iter.First();
@ -163,13 +163,13 @@ Track *TrackPanelAx::FindTrack( int num )
t = iter.Next( true );
}
return t;
return Track::Pointer( t );
}
void TrackPanelAx::Updated()
{
#if wxUSE_ACCESSIBILITY
Track *t = GetFocus();
auto t = GetFocus();
mTrackName = true;
// 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 (mTrackPanel == wxWindow::FindFocus())
{
Track *t = GetFocus();
auto t = GetFocus();
int childId = t ? TrackNum(t) : 0;
mMessage = message;
@ -299,14 +299,14 @@ wxAccStatus TrackPanelAx::GetLocation( wxRect& rect, int elementId )
}
else
{
Track *t = FindTrack( elementId );
auto t = FindTrack( elementId );
if( t == NULL )
{
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
// yellow focus rectangle.
#ifdef __WXMAC__
@ -334,7 +334,7 @@ wxAccStatus TrackPanelAx::GetName( int childId, wxString* name )
}
else
{
Track *t = FindTrack( childId );
auto t = FindTrack( childId );
if( t == NULL )
{
@ -371,7 +371,7 @@ wxAccStatus TrackPanelAx::GetName( int childId, wxString* name )
#endif
// LLL: Remove these during "refactor"
auto pt = dynamic_cast<PlayableTrack *>(t);
auto pt = dynamic_cast<PlayableTrack *>(t.get());
if( pt && pt->GetMute() )
{
// The following comment also applies to the solo, selected,
@ -475,7 +475,7 @@ wxAccStatus TrackPanelAx::GetState( int childId, long* state )
#if defined(__WXMSW__)
if( childId > 0 )
{
Track *t = FindTrack( childId );
auto t = FindTrack( childId );
*state = wxACC_STATE_SYSTEM_FOCUSABLE | wxACC_STATE_SYSTEM_SELECTABLE;
if (t)
@ -502,11 +502,11 @@ wxAccStatus TrackPanelAx::GetState( int childId, long* state )
if( childId > 0 )
{
Track *t = FindTrack( childId );
auto t = FindTrack( childId );
if (t)
{
if( t == mFocusedTrack )
if( t == mFocusedTrack.lock() )
{
*state |= wxACC_STATE_SYSTEM_FOCUSED;
}
@ -541,7 +541,7 @@ wxAccStatus TrackPanelAx::GetValue( int WXUNUSED(childId), wxString* WXUNUSED(st
}
else
{
Track *t = FindTrack( childId );
auto t = FindTrack( childId );
if( t == NULL )
{
@ -556,7 +556,7 @@ wxAccStatus TrackPanelAx::GetValue( int WXUNUSED(childId), wxString* WXUNUSED(st
}
// LLL: Remove these during "refactor"
auto pt = dynamic_cast<PlayableTrack *>(t);
auto pt = dynamic_cast<PlayableTrack *>(t.get());
if( pt && pt->GetMute() )
{
strValue->Append( _( " Mute On" ) );
@ -602,14 +602,15 @@ wxAccStatus TrackPanelAx::GetFocus( int *childId, wxAccessible **child )
#if defined(__WXMAC__)
if( GetWindow() == wxWindow::FindFocus() )
{
if( mFocusedTrack )
auto focusedTrack = mFocusedTrack.lock();
if( focusedTrack )
{
*childId = TrackNum( mFocusedTrack );
*childId = TrackNum( focusedTrack );
}
else
{
*childId = wxACC_SELF;
}
}
return wxACC_OK;
}

View File

@ -32,10 +32,12 @@ public:
virtual ~ TrackPanelAx();
// Returns currently focused track or first one if none focused
Track *GetFocus();
std::shared_ptr<Track> GetFocus();
// 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
bool IsFocused( Track *track );
@ -107,11 +109,12 @@ public:
private:
int TrackNum( Track *track );
Track *FindTrack( int num );
int TrackNum( const std::shared_ptr<Track> &track );
std::shared_ptr<Track> FindTrack( int num );
TrackPanel *mTrackPanel;
Track *mFocusedTrack;
std::weak_ptr<Track> mFocusedTrack;
wxString mMessage;
bool mTrackName;