1
0
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:
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) 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 );
} }

View File

@@ -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;
} }

View File

@@ -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;