TrackFocus is a new attached object...

... removing the need to use TrackPanel to get and set the focused track

ProjectAudioManager loses its direct dependency on TrackPanel
This commit is contained in:
Paul Licameli 2019-07-01 18:32:18 -04:00
parent 02075d5b43
commit acfd2b7010
21 changed files with 240 additions and 157 deletions

View File

@ -29,7 +29,7 @@ Paul Licameli split from ProjectManager.cpp
#include "ProjectSettings.h"
#include "ProjectStatus.h"
#include "TimeTrack.h"
#include "TrackPanel.h"
#include "TrackPanelAx.h"
#include "ViewInfo.h"
#include "WaveTrack.h"
#include "toolbars/ToolManager.h"
@ -685,7 +685,7 @@ bool ProjectAudioManager::DoRecord(AudacityProject &project,
TrackList::Get( *p ).RegisterPendingNewTrack( newTrack );
transportTracks.captureTracks.push_back(newTrack);
// Bug 1548. New track needs the focus.
TrackPanel::Get( *p ).SetFocusedTrack( newTrack.get() );
TrackFocus::Get( *p ).Set( newTrack.get() );
}
TrackList::Get( *p ).GroupChannels(*first, recordingChannels);
}

View File

@ -38,6 +38,7 @@ Paul Licameli split from AudacityProject.cpp
#include "SelectionState.h"
#include "Sequence.h"
#include "Tags.h"
#include "TrackPanelAx.h"
#include "TrackPanel.h"
#include "UndoManager.h"
#include "WaveClip.h"
@ -1347,7 +1348,7 @@ void ProjectFileManager::OpenFile(const FilePath &fileNameArg, bool addtohistory
SelectionBar::Get( project ).SetRate( settings.GetRate() );
ProjectHistory::Get( project ).InitialState();
trackPanel.SetFocusedTrack( *tracks.Any().begin() );
TrackFocus::Get( project ).Set( *tracks.Any().begin() );
window.HandleResize();
trackPanel.Refresh(false);
trackPanel.Update(); // force any repaint to happen now,

View File

@ -18,6 +18,7 @@
#include "ProjectHistory.h"
#include "ProjectSettings.h"
#include "SelectionState.h"
#include "TrackPanelAx.h"
#include "TrackPanel.h"
#include "ViewInfo.h"
#include "WaveTrack.h"
@ -93,7 +94,6 @@ void DoListSelection
(AudacityProject &project, Track *t, bool shift, bool ctrl, bool modifyState)
{
auto &tracks = TrackList::Get( project );
auto &trackPanel = TrackPanel::Get( project );
auto &selectionState = SelectionState::Get( project );
const auto &settings = ProjectSettings::Get( project );
auto &viewInfo = ViewInfo::Get( project );
@ -106,7 +106,7 @@ void DoListSelection
shift, ctrl, isSyncLocked );
if (! ctrl )
trackPanel.SetFocusedTrack(t);
TrackFocus::Get( project ).Set( t );
window.Refresh(false);
if (modifyState)
ProjectHistory::Get( project ).ModifyState(true);

View File

@ -276,13 +276,8 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
return {};
}
);
#if wxUSE_ACCESSIBILITY
// wxWidgets owns the accessible object
SetAccessible(mAx = pAx.release());
#else
// wxWidgets does not own the object, but we need to retain it
mAx = std::move(pAx);
#endif
TrackFocus::Get( *GetProject() ).SetAccessible(
*this, std::move( pAx ) );
}
mRedrawAfterStop = false;
@ -497,7 +492,7 @@ void TrackPanel::OnProjectSettingsChange( wxCommandEvent &event )
void TrackPanel::OnUndoReset( wxCommandEvent &event )
{
event.Skip();
SetFocusedTrack( nullptr );
TrackFocus::Get( *GetProject() ).Set( nullptr );
Refresh( false );
}
@ -691,24 +686,12 @@ void TrackPanel::UpdateSelectionDisplay()
DisplaySelection();
}
void TrackPanel::UpdateAccessibility()
{
if (mAx)
mAx->Updated();
}
// Counts selected tracks, counting stereo tracks as one track.
size_t TrackPanel::GetSelectedTrackCount() const
{
return GetTracks()->SelectedLeaders().size();
}
void TrackPanel::MessageForScreenReader(const wxString& message)
{
if (mAx)
mAx->MessageForScreenReader(message);
}
void TrackPanel::UpdateViewIfNoTracks()
{
if (mTracks->empty())
@ -754,7 +737,7 @@ void TrackPanel::OnTrackListDeletion(wxEvent & e)
// If the focused track disappeared but there are still other tracks,
// this reassigns focus.
GetFocusedTrack();
TrackFocus( *GetProject() ).Get();
UpdateVRulerSize();
@ -986,7 +969,7 @@ void TrackPanel::OnEnsureVisible(TrackListEvent & e)
auto pTrack = e.mpTrack.lock();
auto t = pTrack.get();
SetFocusedTrack(t);
TrackFocus::Get( *GetProject() ).Set( t );
int trackTop = 0;
int trackHeight =0;
@ -1213,7 +1196,8 @@ struct LabeledChannelGroup final : TrackPanelGroup {
// was the focus and no highlight should be drawn. -RBD
const auto artist = TrackArtist::Get( context );
auto &trackPanel = *artist->parent;
if (trackPanel.GetFocusedTrack() == mpTrack.get() &&
auto &trackFocus = TrackFocus::Get( *trackPanel.GetProject() );
if (trackFocus.Get() == mpTrack.get() &&
wxWindow::FindFocus() == &trackPanel ) {
/// Draw a three-level highlight gradient around the focused track.
wxRect theRect = rect;
@ -1366,38 +1350,20 @@ void TrackPanel::DisplaySelection()
TrackPanelCell *TrackPanel::GetFocusedCell()
{
auto pTrack = mAx->GetFocus().get();
if (pTrack)
return &TrackView::Get( *pTrack );
return nullptr;
}
Track *TrackPanel::GetFocusedTrack()
{
auto pView = dynamic_cast<TrackView *>( GetFocusedCell() );
if (pView)
return pView->FindTrack().get();
return nullptr;
auto pTrack = TrackFocus::Get( *GetProject() ).Get();
return pTrack ? &TrackView::Get( *pTrack ) : nullptr;
}
void TrackPanel::SetFocusedCell()
{
SetFocusedTrack( GetFocusedTrack() );
}
void TrackPanel::SetFocusedTrack( Track *t )
{
// Make sure we always have the first linked track of a stereo track
t = *GetTracks()->FindLeader(t);
// This will cause callback to the handler function, defined next
mAx->SetFocus( Track::SharedPointer( t ) );
// This may have a side-effet of assigning a focus if there was none
TrackFocus::Get( *GetProject() ).Get();
}
void TrackPanel::OnTrackFocusChange( wxCommandEvent &event )
{
event.Skip();
auto cell = mAx->GetFocus().get();
auto cell = GetFocusedCell();
if (cell) {
KeyboardCapture::Capture(this);

View File

@ -123,8 +123,6 @@ class AUDACITY_DLL_API TrackPanel final
TrackPanelCell *GetFocusedCell() override;
void SetFocusedCell() override;
Track *GetFocusedTrack();
void SetFocusedTrack(Track *t);
void UpdateVRulers();
void UpdateVRuler(Track *t);
@ -141,9 +139,6 @@ protected:
void UpdateSelectionDisplay();
public:
void UpdateAccessibility();
void MessageForScreenReader(const wxString& message);
void MakeParentRedrawScrollbars();
// Rectangle includes track control panel, and the vertical ruler, and
@ -218,15 +213,6 @@ protected:
friend class TrackPanelAx;
#if wxUSE_ACCESSIBILITY
TrackPanelAx *mAx{};
#else
std::unique_ptr<TrackPanelAx> mAx;
#endif
public:
TrackPanelAx &GetAx() { return *mAx; }
protected:
// The screenshot class needs to access internals

View File

@ -726,3 +726,76 @@ wxAccStatus TrackPanelAx::Select(int childId, wxAccSelectionFlags selectFlags)
}
#endif // wxUSE_ACCESSIBILITY
static const AudacityProject::AttachedObjects::RegisteredFactory key{
[]( AudacityProject &parent ){
return std::make_shared< TrackFocus >( parent );
}
};
TrackFocus &TrackFocus::Get( AudacityProject &project )
{
return project.AttachedObjects::Get< TrackFocus >( key );
}
const TrackFocus &TrackFocus::Get( const AudacityProject &project )
{
return Get( const_cast< AudacityProject & >( project ) );
}
TrackFocus::TrackFocus( AudacityProject &project )
: mProject{ project }
{
}
TrackFocus::~TrackFocus()
{
}
Track *TrackFocus::Get()
{
if (mAx)
return mAx->GetFocus().get();
return nullptr;
}
void TrackFocus::Set( Track *pTrack )
{
if (mAx) {
pTrack = *TrackList::Get( mProject ).FindLeader( pTrack );
mAx->SetFocus( Track::SharedPointer( pTrack ) );
}
}
bool TrackFocus::IsFocused( const Track *pTrack )
{
if (mAx)
return mAx->IsFocused( pTrack );
return false;
}
void TrackFocus::SetAccessible(
wxWindow &owner,
std::unique_ptr< TrackPanelAx > pAx
)
{
#if wxUSE_ACCESSIBILITY
// wxWidgets owns the accessible object
owner.SetAccessible(mAx = pAx.release());
#else
// wxWidgets does not own the object, but we need to retain it
mAx = std::move(pAx);
#endif
}
void TrackFocus::MessageForScreenReader(const wxString& message)
{
if (mAx)
mAx->MessageForScreenReader( message );
}
void TrackFocus::UpdateAccessibility()
{
if (mAx)
mAx->Updated();
}

View File

@ -11,6 +11,8 @@
#ifndef __AUDACITY_TRACK_PANEL_ACCESSIBILITY__
#define __AUDACITY_TRACK_PANEL_ACCESSIBILITY__
#include "Audacity.h"
#include <functional>
#include <memory>
@ -23,6 +25,8 @@
#include "widgets/WindowAccessible.h" // to inherit
#endif
#include "ClientData.h" // to inherit
class wxRect;
class AudacityProject;
@ -152,4 +156,49 @@ private:
int mMessageCount;
};
class TrackFocus final
: public ClientData::Base
{
public:
static TrackFocus &Get( AudacityProject &project );
static const TrackFocus &Get( const AudacityProject &project );
explicit TrackFocus( AudacityProject &project );
~TrackFocus() override;
TrackFocus( const TrackFocus & ) PROHIBITED;
TrackFocus& operator=( const TrackFocus & ) PROHIBITED;
// Report the currently focused track, which may be null, otherwise is
// a leader track
// This function is not const, because it may have a side effect of setting
// a focus if none was already set
Track *Get();
// Set the track focus to a given track or to null
void Set( Track *pTrack );
// Not equivalent to pTrack == this->Get(): may return true also for
// other channels than the leader
// As with Get(), this is not const
bool IsFocused( const Track *pTrack );
void SetAccessible( wxWindow &owner,
std::unique_ptr< TrackPanelAx > pAccessible );
void MessageForScreenReader(const wxString& message);
void UpdateAccessibility();
private:
AudacityProject &mProject;
#if wxUSE_ACCESSIBILITY
TrackPanelAx *mAx{};
#else
std::unique_ptr<TrackPanelAx> mAx;
#endif
};
#endif // __AUDACITY_TRACK_PANEL_ACCESSIBILITY__

View File

@ -14,6 +14,7 @@
#include "ProjectSettings.h"
#include "ProjectWindow.h"
#include "Track.h"
#include "TrackPanelAx.h"
#include "TrackPanel.h"
namespace TrackUtilities {
@ -62,7 +63,6 @@ void DoTrackMute(AudacityProject &project, Track *t, bool exclusive)
{
const auto &settings = ProjectSettings::Get( project );
auto &tracks = TrackList::Get( project );
auto &trackPanel = TrackPanel::Get( project );
// Whatever t is, replace with lead channel
t = *tracks.FindLeader(t);
@ -104,14 +104,13 @@ void DoTrackMute(AudacityProject &project, Track *t, bool exclusive)
}
ProjectHistory::Get( project ).ModifyState(true);
trackPanel.UpdateAccessibility();
TrackFocus::Get( project ).UpdateAccessibility();
}
void DoTrackSolo(AudacityProject &project, Track *t, bool exclusive)
{
const auto &settings = ProjectSettings::Get( project );
auto &tracks = TrackList::Get( project );
auto &trackPanel = TrackPanel::Get( project );
// Whatever t is, replace with lead channel
t = *tracks.FindLeader(t);
@ -156,19 +155,19 @@ void DoTrackSolo(AudacityProject &project, Track *t, bool exclusive)
}
ProjectHistory::Get( project ).ModifyState(true);
trackPanel.UpdateAccessibility();
TrackFocus::Get( project ).UpdateAccessibility();
}
void DoRemoveTrack(AudacityProject &project, Track * toRemove)
{
auto &tracks = TrackList::Get( project );
auto &trackPanel = TrackPanel::Get( project );
auto &trackFocus = TrackFocus::Get( project );
auto &window = ProjectWindow::Get( project );
// If it was focused, then NEW focus is the next or, if
// unavailable, the previous track. (The NEW focus is set
// after the track has been removed.)
bool toRemoveWasFocused = trackPanel.GetFocusedTrack() == toRemove;
bool toRemoveWasFocused = trackFocus.Get() == toRemove;
Track* newFocus{};
if (toRemoveWasFocused) {
auto iterNext = tracks.FindLeader(toRemove), iterPrev = iterNext;
@ -187,7 +186,7 @@ void DoRemoveTrack(AudacityProject &project, Track * toRemove)
tracks.Remove( * iter++ );
if (toRemoveWasFocused)
trackPanel.SetFocusedTrack(newFocus);
trackFocus.Set( newFocus );
ProjectHistory::Get( project ).PushState(
wxString::Format(_("Removed track '%s.'"),
@ -198,7 +197,6 @@ void DoRemoveTrack(AudacityProject &project, Track * toRemove)
void DoMoveTrack
(AudacityProject &project, Track* target, MoveChoice choice)
{
auto &trackPanel = TrackPanel::Get( project );
auto &tracks = TrackList::Get( project );
wxString longDesc, shortDesc;

View File

@ -28,6 +28,7 @@ This class now lists
#include "CommandTargets.h"
#include "../effects/EffectManager.h"
#include "../widgets/Overlay.h"
#include "../TrackPanelAx.h"
#include "../TrackPanel.h"
#include "../WaveClip.h"
#include "../ViewInfo.h"
@ -489,8 +490,8 @@ bool GetInfoCommand::SendTracks(const CommandContext & context)
context.StartArray();
for (auto trk : tracks.Leaders())
{
auto &panel = TrackPanel::Get( context.project );
Track * fTrack = panel.GetFocusedTrack();
auto &trackFocus = TrackFocus::Get( context.project );
Track * fTrack = trackFocus.Get();
context.StartStruct();
context.AddItem( trk->GetName(), "name" );

View File

@ -37,6 +37,7 @@ SetTrackAudioCommand and SetTrackVisualsCommand.
#include "SetTrackInfoCommand.h"
#include "../Project.h"
#include "../TrackPanelAx.h"
#include "../TrackPanel.h"
#include "../WaveTrack.h"
#include "../prefs/WaveformSettings.h"
@ -164,11 +165,11 @@ bool SetTrackStatusCommand::ApplyInner(const CommandContext & context, Track * t
if( !bIsSecondChannel ){
if( bHasFocused )
{
auto &panel = TrackPanel::Get( context.project );
auto &trackFocus = TrackFocus::Get( context.project );
if( bFocused)
panel.SetFocusedTrack( t );
else if( t== panel.GetFocusedTrack() )
panel.SetFocusedTrack( nullptr );
trackFocus.Set( t );
else if( t == trackFocus.Get() )
trackFocus.Set( nullptr );
}
}
return true;

View File

@ -1,7 +1,7 @@
#include "../CommonCommandFlags.h"
#include "../ProjectHistory.h"
#include "../ProjectSettings.h"
#include "../TrackPanel.h"
#include "../TrackPanelAx.h"
#include "../ProjectWindow.h"
#include "../UndoManager.h"
#include "../WaveClip.h"
@ -377,7 +377,7 @@ wxString ClipBoundaryMessage(const std::vector<FoundClipBoundary>& results)
void DoSelectClipBoundary(AudacityProject &project, bool next)
{
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
auto &trackPanel = TrackPanel::Get( project );
auto &trackFocus = TrackFocus::Get( project );
std::vector<FoundClipBoundary> results;
FindClipBoundaries(project, next ? selectedRegion.t1() :
@ -394,7 +394,7 @@ void DoSelectClipBoundary(AudacityProject &project, bool next)
ProjectHistory::Get( project ).ModifyState(false);
wxString message = ClipBoundaryMessage(results);
trackPanel.MessageForScreenReader(message);
trackFocus.MessageForScreenReader(message);
}
}
@ -561,7 +561,7 @@ int FindClips
void DoSelectClip(AudacityProject &project, bool next)
{
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
auto &trackPanel = TrackPanel::Get( project );
auto &trackFocus = TrackFocus::Get( project );
auto &window = ProjectWindow::Get( project );
std::vector<FoundClip> results;
@ -600,7 +600,7 @@ void DoSelectClip(AudacityProject &project, bool next)
else
message = wxString::Format(_("%s, %s"), message, str);
}
trackPanel.MessageForScreenReader(message);
trackFocus.MessageForScreenReader(message);
}
}
@ -608,7 +608,7 @@ void DoCursorClipBoundary
(AudacityProject &project, bool next)
{
auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
auto &trackPanel = TrackPanel::Get( project );
auto &trackFocus = TrackFocus::Get( project );
auto &window = ProjectWindow::Get( project );
std::vector<FoundClipBoundary> results;
@ -624,7 +624,7 @@ void DoCursorClipBoundary
window.ScrollIntoView(selectedRegion.t0());
wxString message = ClipBoundaryMessage(results);
trackPanel.MessageForScreenReader(message);
trackFocus.MessageForScreenReader(message);
}
}
@ -701,14 +701,14 @@ void DoClipLeftOrRight
return;
}
auto &trackPanel = TrackPanel::Get( project );
auto &trackFocus = TrackFocus::Get( project );
auto &viewInfo = ViewInfo::Get( project );
auto &selectedRegion = viewInfo.selectedRegion;
const auto &settings = ProjectSettings::Get( project );
auto &tracks = TrackList::Get( project );
auto isSyncLocked = settings.IsSyncLocked();
auto amount = DoClipMove( viewInfo, trackPanel.GetFocusedTrack(),
auto amount = DoClipMove( viewInfo, trackFocus.Get(),
tracks, isSyncLocked, right );
window.ScrollIntoView(selectedRegion.t0());
@ -726,7 +726,7 @@ void DoClipLeftOrRight
}
if ( amount == 0.0 )
trackPanel.MessageForScreenReader( _("clip not moved"));
trackFocus.MessageForScreenReader( _("clip not moved"));
}
}

View File

@ -7,6 +7,7 @@
#include "../ProjectAudioIO.h"
#include "../ProjectHistory.h"
#include "../ProjectWindow.h"
#include "../TrackPanelAx.h"
#include "../TrackPanel.h"
#include "../ViewInfo.h"
#include "../WaveTrack.h"
@ -23,6 +24,7 @@ int DoAddLabel(
bool preserveFocus = false)
{
auto &tracks = TrackList::Get( project );
auto &trackFocus = TrackFocus::Get( project );
auto &trackPanel = TrackPanel::Get( project );
auto &trackFactory = TrackFactory::Get( project );
auto &window = ProjectWindow::Get( project );
@ -38,7 +40,7 @@ int DoAddLabel(
}
// If the focused track is a label track, use that
Track *const pFocusedTrack = trackPanel.GetFocusedTrack();
const auto pFocusedTrack = trackFocus.Get();
// Look for a label track at or after the focused track
auto iter = pFocusedTrack

View File

@ -87,15 +87,15 @@ void DoPrevTrack(
AudacityProject &project, bool shift, bool circularTrackNavigation )
{
auto &projectHistory = ProjectHistory::Get( project );
auto &trackPanel = TrackPanel::Get( project );
auto &trackFocus = TrackFocus::Get( project );
auto &tracks = TrackList::Get( project );
auto &selectionState = SelectionState::Get( project );
Track* t = trackPanel.GetFocusedTrack();
auto t = trackFocus.Get();
if( t == NULL ) // if there isn't one, focus on last
{
t = *tracks.Any().rbegin();
trackPanel.SetFocusedTrack( t );
trackFocus.Set( t );
if (t)
t->EnsureVisible( true );
return;
@ -127,7 +127,7 @@ void DoPrevTrack(
{
selectionState.SelectTrack
( *t, false, false );
trackPanel.SetFocusedTrack( p ); // move focus to next track up
trackFocus.Set( p ); // move focus to next track up
if (p)
p->EnsureVisible( true );
return;
@ -136,7 +136,7 @@ void DoPrevTrack(
{
selectionState.SelectTrack
( *p, true, false );
trackPanel.SetFocusedTrack( p ); // move focus to next track up
trackFocus.Set( p ); // move focus to next track up
if (p)
p->EnsureVisible( true );
return;
@ -145,7 +145,7 @@ void DoPrevTrack(
{
selectionState.SelectTrack
( *p, false, false );
trackPanel.SetFocusedTrack( p ); // move focus to next track up
trackFocus.Set( p ); // move focus to next track up
if (p)
p->EnsureVisible( true );
return;
@ -154,7 +154,7 @@ void DoPrevTrack(
{
selectionState.SelectTrack
( *t, true, false );
trackPanel.SetFocusedTrack( p ); // move focus to next track up
trackFocus.Set( p ); // move focus to next track up
if (p)
p->EnsureVisible( true );
return;
@ -170,7 +170,7 @@ void DoPrevTrack(
{
auto range = tracks.Leaders();
p = * range.rbegin(); // null if range is empty
trackPanel.SetFocusedTrack( p ); // Wrap to the last track
trackFocus.Set( p ); // Wrap to the last track
if (p)
p->EnsureVisible( true );
return;
@ -183,7 +183,7 @@ void DoPrevTrack(
}
else
{
trackPanel.SetFocusedTrack( p ); // move focus to next track up
trackFocus.Set( p ); // move focus to next track up
p->EnsureVisible( true );
return;
}
@ -197,15 +197,15 @@ void DoNextTrack(
AudacityProject &project, bool shift, bool circularTrackNavigation )
{
auto &projectHistory = ProjectHistory::Get( project );
auto &trackPanel = TrackPanel::Get( project );
auto &trackFocus = TrackFocus::Get( project );
auto &tracks = TrackList::Get( project );
auto &selectionState = SelectionState::Get( project );
auto t = trackPanel.GetFocusedTrack(); // Get currently focused track
auto t = trackFocus.Get(); // Get currently focused track
if( t == NULL ) // if there isn't one, focus on first
{
t = *tracks.Any().begin();
trackPanel.SetFocusedTrack( t );
trackFocus.Set( t );
if (t)
t->EnsureVisible( true );
return;
@ -231,7 +231,7 @@ void DoNextTrack(
{
selectionState.SelectTrack
( *t, false, false );
trackPanel.SetFocusedTrack( n ); // move focus to next track down
trackFocus.Set( n ); // move focus to next track down
if (n)
n->EnsureVisible( true );
return;
@ -240,7 +240,7 @@ void DoNextTrack(
{
selectionState.SelectTrack
( *n, true, false );
trackPanel.SetFocusedTrack( n ); // move focus to next track down
trackFocus.Set( n ); // move focus to next track down
if (n)
n->EnsureVisible( true );
return;
@ -249,7 +249,7 @@ void DoNextTrack(
{
selectionState.SelectTrack
( *n, false, false );
trackPanel.SetFocusedTrack( n ); // move focus to next track down
trackFocus.Set( n ); // move focus to next track down
if (n)
n->EnsureVisible( true );
return;
@ -258,7 +258,7 @@ void DoNextTrack(
{
selectionState.SelectTrack
( *t, true, false );
trackPanel.SetFocusedTrack( n ); // move focus to next track down
trackFocus.Set( n ); // move focus to next track down
if (n)
n->EnsureVisible( true );
return;
@ -273,7 +273,7 @@ void DoNextTrack(
if( circularTrackNavigation )
{
n = *tracks.Any().begin();
trackPanel.SetFocusedTrack( n ); // Wrap to the first track
trackFocus.Set( n ); // Wrap to the first track
if (n)
n->EnsureVisible( true );
return;
@ -286,7 +286,7 @@ void DoNextTrack(
}
else
{
trackPanel.SetFocusedTrack( n ); // move focus to next track down
trackFocus.Set( n ); // move focus to next track down
n->EnsureVisible( true );
return;
}
@ -461,16 +461,16 @@ void OnCursorDown(const CommandContext &context)
void OnFirstTrack(const CommandContext &context)
{
auto &project = context.project;
auto &trackPanel = TrackPanel::Get( project );
auto &trackFocus = TrackFocus::Get( project );
auto &tracks = TrackList::Get( project );
Track *t = trackPanel.GetFocusedTrack();
auto t = trackFocus.Get();
if (!t)
return;
auto f = *tracks.Any().begin();
if (t != f)
trackPanel.SetFocusedTrack(f);
trackFocus.Set(f);
if (f)
f->EnsureVisible( t != f );
}
@ -478,16 +478,16 @@ void OnFirstTrack(const CommandContext &context)
void OnLastTrack(const CommandContext &context)
{
auto &project = context.project;
auto &trackPanel = TrackPanel::Get( project );
auto &trackFocus = TrackFocus::Get( project );
auto &tracks = TrackList::Get( project );
Track *t = trackPanel.GetFocusedTrack();
Track *t = trackFocus.Get();
if (!t)
return;
auto l = *tracks.Any().rbegin();
if (t != l)
trackPanel.SetFocusedTrack(l);
trackFocus.Set(l);
if (l)
l->EnsureVisible( t != l );
}
@ -507,12 +507,12 @@ void OnShiftDown(const CommandContext &context)
void OnToggle(const CommandContext &context)
{
auto &project = context.project;
auto &trackPanel = TrackPanel::Get( project );
auto &trackFocus = TrackFocus::Get( project );
auto &selectionState = SelectionState::Get( project );
Track *t;
t = trackPanel.GetFocusedTrack(); // Get currently focused track
t = trackFocus.Get(); // Get currently focused track
if (!t)
return;
@ -520,7 +520,7 @@ void OnToggle(const CommandContext &context)
( *t, !t->GetSelected(), true );
t->EnsureVisible( true );
trackPanel.GetAx().Updated();
trackFocus.UpdateAccessibility();
return;
}

View File

@ -18,6 +18,7 @@
#include "../SelectUtilities.h"
#include "../ShuttleGui.h"
#include "../TimeTrack.h"
#include "../TrackPanelAx.h"
#include "../TrackPanel.h"
#include "../TrackUtilities.h"
#include "../UndoManager.h"
@ -114,7 +115,7 @@ void DoMixAndRender
}
trackPanel.SetFocus();
trackPanel.SetFocusedTrack(pNewLeft);
TrackFocus::Get( project ).Set( pNewLeft );
pNewLeft->EnsureVisible();
}
}
@ -1049,7 +1050,7 @@ void OnTrackPan(const CommandContext &context)
auto &project = context.project;
auto &trackPanel = TrackPanel::Get( project );
Track *const track = trackPanel.GetFocusedTrack();
const auto track = TrackFocus::Get( project ).Get();
if (track) track->TypeSwitch( [&](WaveTrack *wt) {
LWSlider *slider = WaveTrackControls::PanSlider( trackPanel, *wt );
if (slider->ShowDialog())
@ -1062,7 +1063,7 @@ void OnTrackPanLeft(const CommandContext &context)
auto &project = context.project;
auto &trackPanel = TrackPanel::Get( project );
Track *const track = trackPanel.GetFocusedTrack();
const auto track = TrackFocus::Get( project ).Get();
if (track) track->TypeSwitch( [&](WaveTrack *wt) {
LWSlider *slider = WaveTrackControls::PanSlider( trackPanel, *wt );
slider->Decrease(1);
@ -1075,7 +1076,7 @@ void OnTrackPanRight(const CommandContext &context)
auto &project = context.project;
auto &trackPanel = TrackPanel::Get( project );
Track *const track = trackPanel.GetFocusedTrack();
const auto track = TrackFocus::Get( project ).Get();
if (track) track->TypeSwitch( [&](WaveTrack *wt) {
LWSlider *slider = WaveTrackControls::PanSlider( trackPanel, *wt );
slider->Increase(1);
@ -1089,7 +1090,7 @@ void OnTrackGain(const CommandContext &context)
auto &trackPanel = TrackPanel::Get( project );
/// This will pop up the track gain dialog for specified track
Track *const track = trackPanel.GetFocusedTrack();
const auto track = TrackFocus::Get( project ).Get();
if (track) track->TypeSwitch( [&](WaveTrack *wt) {
LWSlider *slider = WaveTrackControls::GainSlider( trackPanel, *wt );
if (slider->ShowDialog())
@ -1102,7 +1103,7 @@ void OnTrackGainInc(const CommandContext &context)
auto &project = context.project;
auto &trackPanel = TrackPanel::Get( project );
Track *const track = trackPanel.GetFocusedTrack();
const auto track = TrackFocus::Get( project ).Get();
if (track) track->TypeSwitch( [&](WaveTrack *wt) {
LWSlider *slider = WaveTrackControls::GainSlider( trackPanel, *wt );
slider->Increase(1);
@ -1115,7 +1116,7 @@ void OnTrackGainDec(const CommandContext &context)
auto &project = context.project;
auto &trackPanel = TrackPanel::Get( project );
Track *const track = trackPanel.GetFocusedTrack();
const auto track = TrackFocus::Get( project ).Get();
if (track) track->TypeSwitch( [&](WaveTrack *wt) {
LWSlider *slider = WaveTrackControls::GainSlider( trackPanel, *wt );
slider->Decrease(1);
@ -1134,9 +1135,8 @@ void OnTrackMenu(const CommandContext &context)
void OnTrackMute(const CommandContext &context)
{
auto &project = context.project;
auto &trackPanel = TrackPanel::Get( project );
const auto track = trackPanel.GetFocusedTrack();
const auto track = TrackFocus::Get( project ).Get();
if (track) track->TypeSwitch( [&](PlayableTrack *t) {
TrackUtilities::DoTrackMute(project, t, false);
});
@ -1145,9 +1145,8 @@ void OnTrackMute(const CommandContext &context)
void OnTrackSolo(const CommandContext &context)
{
auto &project = context.project;
auto &trackPanel = TrackPanel::Get( project );
const auto track = trackPanel.GetFocusedTrack();
const auto track = TrackFocus::Get( project ).Get();
if (track) track->TypeSwitch( [&](PlayableTrack *t) {
TrackUtilities::DoTrackSolo(project, t, false);
});
@ -1158,7 +1157,7 @@ void OnTrackClose(const CommandContext &context)
auto &project = context.project;
auto &trackPanel = TrackPanel::Get( project );
Track *t = trackPanel.GetFocusedTrack();
const auto t = TrackFocus::Get( project ).Get();
if (!t)
return;
@ -1184,7 +1183,7 @@ void OnTrackMoveUp(const CommandContext &context)
auto &trackPanel = TrackPanel::Get( project );
auto &tracks = TrackList::Get( project );
Track *const focusedTrack = trackPanel.GetFocusedTrack();
const auto focusedTrack = TrackFocus::Get( project ).Get();
if (tracks.CanMoveUp(focusedTrack)) {
DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveUpID);
trackPanel.Refresh(false);
@ -1197,7 +1196,7 @@ void OnTrackMoveDown(const CommandContext &context)
auto &trackPanel = TrackPanel::Get( project );
auto &tracks = TrackList::Get( project );
Track *const focusedTrack = trackPanel.GetFocusedTrack();
const auto focusedTrack = TrackFocus::Get( project ).Get();
if (tracks.CanMoveDown(focusedTrack)) {
DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveDownID);
trackPanel.Refresh(false);
@ -1210,7 +1209,7 @@ void OnTrackMoveTop(const CommandContext &context)
auto &trackPanel = TrackPanel::Get( project );
auto &tracks = TrackList::Get( project );
Track *const focusedTrack = trackPanel.GetFocusedTrack();
const auto focusedTrack = TrackFocus::Get( project ).Get();
if (tracks.CanMoveUp(focusedTrack)) {
DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveTopID);
trackPanel.Refresh(false);
@ -1223,7 +1222,7 @@ void OnTrackMoveBottom(const CommandContext &context)
auto &trackPanel = TrackPanel::Get( project );
auto &tracks = TrackList::Get( project );
Track *const focusedTrack = trackPanel.GetFocusedTrack();
const auto focusedTrack = TrackFocus::Get( project ).Get();
if (tracks.CanMoveDown(focusedTrack)) {
DoMoveTrack(project, focusedTrack, TrackUtilities::OnMoveBottomID);
trackPanel.Refresh(false);

View File

@ -17,6 +17,7 @@
#include "../ProjectWindow.h"
#include "../SoundActivatedRecord.h"
#include "../TimerRecordDialog.h"
#include "../TrackPanelAx.h"
#include "../TrackPanel.h"
#include "../UndoManager.h"
#include "../WaveClip.h"
@ -137,7 +138,7 @@ void DoPlayStop(const CommandContext &context)
void DoMoveToLabel(AudacityProject &project, bool next)
{
auto &tracks = TrackList::Get( project );
auto &trackPanel = TrackPanel::Get( project );
auto &trackFocus = TrackFocus::Get( project );
auto &window = ProjectWindow::Get( project );
// Find the number of label tracks, and ptr to last track found
@ -146,14 +147,14 @@ void DoMoveToLabel(AudacityProject &project, bool next)
auto nLabelTrack = trackRange.size();
if (nLabelTrack == 0 ) {
trackPanel.MessageForScreenReader(_("no label track"));
trackFocus.MessageForScreenReader(_("no label track"));
}
else if (nLabelTrack > 1) {
// find first label track, if any, starting at the focused track
lt =
*tracks.Find(trackPanel.GetFocusedTrack()).Filter<LabelTrack>();
*tracks.Find(trackFocus.Get()).Filter<LabelTrack>();
if (!lt)
trackPanel.MessageForScreenReader(
trackFocus.MessageForScreenReader(
_("no label track at or below focused track"));
}
@ -184,10 +185,10 @@ void DoMoveToLabel(AudacityProject &project, bool next)
wxString message;
message.Printf(
wxT("%s %d of %d"), label->title, i + 1, lt->GetNumLabels() );
trackPanel.MessageForScreenReader(message);
trackFocus.MessageForScreenReader(message);
}
else {
trackPanel.MessageForScreenReader(_("no labels in label track"));
trackFocus.MessageForScreenReader(_("no labels in label track"));
}
}
}

View File

@ -32,6 +32,7 @@ Paul Licameli split from TrackPanel.cpp
#include "../../../RefreshCode.h"
#include "../../../Theme.h"
#include "../../../TrackArtist.h"
#include "../../../TrackPanelAx.h"
#include "../../../TrackPanel.h"
#include "../../../TrackPanelMouseEvent.h"
#include "../../../UndoManager.h"
@ -1084,10 +1085,11 @@ int LabelTrackView::GetSelectedIndex( AudacityProject &project ) const
// may make delayed update of mutable mSelIndex after track selection change
auto track = FindLabelTrack();
if ( track->GetSelected() ||
TrackPanel::Get(
TrackFocus::Get(
// unhappy const_cast because because focus may be set if undefined
const_cast<AudacityProject&>( project )
).GetFocusedTrack() == track.get() )
).Get() == track.get()
)
return mSelIndex = std::max( -1,
std::min<int>( track->GetLabels().size() - 1, mSelIndex ) );
else
@ -1476,7 +1478,7 @@ bool LabelTrackView::DoKeyDown(
auto track = *TrackList::Get( project ).Any()
.begin().advance(mRestoreFocus);
if (track)
TrackPanel::Get( project ).SetFocusedTrack(track);
TrackFocus::Get( project ).Set(track);
mRestoreFocus = -2;
}
mSelIndex = -1;
@ -2058,10 +2060,12 @@ int LabelTrackView::DialogForLabelName(
AudacityProject &project,
const SelectedRegion& region, const wxString& initialValue, wxString& value)
{
auto &trackFocus = TrackFocus::Get( project );
auto &trackPanel = TrackPanel::Get( project );
auto &viewInfo = ViewInfo::Get( project );
wxPoint position = trackPanel.FindTrackRect(trackPanel.GetFocusedTrack()).GetBottomLeft();
wxPoint position =
trackPanel.FindTrackRect( trackFocus.Get() ).GetBottomLeft();
// The start of the text in the text box will be roughly in line with the label's position
// if it's a point label, or the start of its region if it's a region label.
position.x += viewInfo.GetLabelWidth()

View File

@ -17,8 +17,8 @@ Paul Licameli split from TrackPanel.cpp
#include "../../../ProjectSettings.h"
#include "../../../RefreshCode.h"
#include "../../../Track.h"
#include "../../../TrackPanelAx.h"
#include "../../../TrackInfo.h"
#include "../../../TrackPanel.h"
#include "../../../TrackPanelMouseEvent.h"
#include "../../../TrackUtilities.h"
@ -46,7 +46,7 @@ wxString MuteButtonHandle::Tip(const wxMouseState &) const
auto name = _("Mute");
auto project = ::GetActiveProject();
auto focused =
TrackPanel::Get( *project ).GetFocusedTrack() == GetTrack().get();
TrackFocus::Get( *project ).Get() == GetTrack().get();
if (!focused)
return name;
@ -102,7 +102,7 @@ wxString SoloButtonHandle::Tip(const wxMouseState &) const
auto name = _("Solo");
auto project = ::GetActiveProject();
auto focused =
TrackPanel::Get( *project ).GetFocusedTrack() == GetTrack().get();
TrackFocus::Get( *project ).Get() == GetTrack().get();
if (!focused)
return name;

View File

@ -18,13 +18,14 @@ Paul Licameli split from TrackPanel.cpp
#include "../../../ui/TrackView.h"
#include "../../../../AudioIOBase.h"
#include "../../../../CellularPanel.h"
#include "../../../../Menus.h"
#include "../../../../Project.h"
#include "../../../../ProjectAudioIO.h"
#include "../../../../ProjectHistory.h"
#include "../../../../RefreshCode.h"
#include "../../../../ShuttleGui.h"
#include "../../../../TrackPanel.h"
#include "../../../../TrackPanelAx.h"
#include "../../../../TrackPanelMouseEvent.h"
#include "../../../../WaveTrack.h"
#include "../../../../widgets/PopupMenuTable.h"
@ -955,8 +956,8 @@ void WaveTrackMenuTable::OnSwapChannels(wxCommandEvent &)
if (channels.size() != 2)
return;
auto &trackPanel = TrackPanel::Get( *project );
Track *const focused = trackPanel.GetFocusedTrack();
auto &trackFocus = TrackFocus::Get( *project );
Track *const focused = trackFocus.Get();
const bool hasFocus = channels.contains( focused );
auto partner = *channels.rbegin();
@ -968,7 +969,7 @@ void WaveTrackMenuTable::OnSwapChannels(wxCommandEvent &)
tracks.GroupChannels( *partner, 2 );
if (hasFocus)
trackPanel.SetFocusedTrack(partner);
trackFocus.Set(partner);
/* i18n-hint: The string names a track */
ProjectHistory::Get( *project )

View File

@ -110,7 +110,7 @@ void EditCursorOverlay::Draw(OverlayPanel &panel, wxDC &dc)
return;
const auto pTrack = pTrackView->FindTrack();
if (pTrack->GetSelected() ||
trackPanel.GetAx().IsFocused(pTrack.get()))
TrackFocus::Get( *mProject ).IsFocused( pTrack.get() ))
{
// AColor::Line includes both endpoints so use GetBottom()
AColor::Line(dc, mLastCursorX, rect.GetTop(), mLastCursorX, rect.GetBottom());

View File

@ -28,6 +28,7 @@ Paul Licameli split from TrackPanel.cpp
#include "../../SelectUtilities.h"
#include "../../SelectionState.h"
#include "../../TrackArtist.h"
#include "../../TrackPanelAx.h"
#include "../../TrackPanel.h"
#include "../../TrackPanelDrawingContext.h"
#include "../../TrackPanelMouseEvent.h"
@ -534,13 +535,12 @@ UIHandle::Result SelectHandle::Click
wxMouseEvent &event = evt.event;
const auto sTrack = TrackList::Get( *pProject ).Lock(mpTrack);
const auto pTrack = sTrack.get();
auto &trackPanel = TrackPanel::Get( *pProject );
auto &viewInfo = ViewInfo::Get( *pProject );
mMostRecentX = event.m_x;
mMostRecentY = event.m_y;
auto &trackPanel = TrackPanel::Get( *pProject );
bool selectChange = (
event.LeftDown() &&
event.ControlDown() &&
@ -771,7 +771,7 @@ UIHandle::Result SelectHandle::Click
#endif
StartSelection(pProject);
selectionState.SelectTrack( *pTrack, true, true );
trackPanel.SetFocusedTrack(pTrack);
TrackFocus::Get( *pProject ).Set(pTrack);
//On-Demand: check to see if there is an OD thing associated with this track.
pTrack->TypeSwitch( [&](WaveTrack *wt) {
if(ODManager::IsInstanceCreated())
@ -1429,7 +1429,7 @@ void SelectHandle::MoveSnappingFreqSelection
// SelectNone();
// SelectTrack(pTrack, true);
TrackPanel::Get( *pProject ).SetFocusedTrack(pTrack);
TrackFocus::Get( *pProject ).Set(pTrack);
}
}

View File

@ -18,6 +18,7 @@ Paul Licameli split from TrackPanel.cpp
#include "../../SelectUtilities.h"
#include "../../RefreshCode.h"
#include "../../Track.h"
#include "../../TrackPanelAx.h"
#include "../../TrackInfo.h"
#include "../../TrackPanel.h"
#include "../../TrackUtilities.h"
@ -174,7 +175,7 @@ wxString CloseButtonHandle::Tip(const wxMouseState &) const
auto name = _("Close");
auto project = ::GetActiveProject();
auto focused =
TrackPanel::Get( *project ).GetFocusedTrack() == GetTrack().get();
TrackFocus::Get( *project ).Get() == GetTrack().get();
if (!focused)
return name;
@ -234,7 +235,7 @@ wxString MenuButtonHandle::Tip(const wxMouseState &) const
auto name = _("Open menu...");
auto project = ::GetActiveProject();
auto focused =
TrackPanel::Get( *project ).GetFocusedTrack() == GetTrack().get();
TrackFocus::Get( *project ).Get() == GetTrack().get();
if (!focused)
return name;