1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-31 16:09:28 +02:00

TrackView, not TrackList, updates Y coordinates of views, using events

This commit is contained in:
Paul Licameli 2019-06-22 10:13:31 -04:00
parent 4339c0df68
commit 278509a505
3 changed files with 92 additions and 22 deletions

View File

@ -156,7 +156,6 @@ void Track::SetLinked(bool l)
if (pList && !pList->mPendingUpdates.empty()) { if (pList && !pList->mPendingUpdates.empty()) {
auto orig = pList->FindById( GetId() ); auto orig = pList->FindById( GetId() );
if (orig && orig != this) { if (orig && orig != this) {
// delegate, and rely on RecalcPositions to copy back
orig->SetLinked(l); orig->SetLinked(l);
return; return;
} }
@ -532,23 +531,17 @@ void TrackList::RecalcPositions(TrackNodePointer node)
Track *t; Track *t;
int i = 0; int i = 0;
int y = 0;
auto prev = getPrev( node ); auto prev = getPrev( node );
if ( !isNull( prev ) ) { if ( !isNull( prev ) ) {
t = prev.first->get(); t = prev.first->get();
i = t->GetIndex() + 1; i = t->GetIndex() + 1;
auto &view = TrackView::Get( *t );
y = view.GetY() + view.GetHeight();
} }
const auto theEnd = end(); const auto theEnd = end();
for (auto n = Find( node.first->get() ); n != theEnd; ++n) { for (auto n = Find( node.first->get() ); n != theEnd; ++n) {
t = *n; t = *n;
auto &view = TrackView::Get( *t );
t->SetIndex(i++); t->SetIndex(i++);
view.SetY(y);
y += view.GetHeight();
} }
UpdatePendingTracks(); UpdatePendingTracks();
@ -568,16 +561,21 @@ void TrackList::DataEvent( const std::shared_ptr<Track> &pTrack, int code )
safenew TrackListEvent{ EVT_TRACKLIST_TRACK_DATA_CHANGE, pTrack, code } ); safenew TrackListEvent{ EVT_TRACKLIST_TRACK_DATA_CHANGE, pTrack, code } );
} }
void TrackList::PermutationEvent() void TrackList::PermutationEvent(TrackNodePointer node)
{ {
// wxWidgets will own the event object // wxWidgets will own the event object
QueueEvent( safenew TrackListEvent{ EVT_TRACKLIST_PERMUTED } ); QueueEvent( safenew TrackListEvent{ EVT_TRACKLIST_PERMUTED, *node.first } );
} }
void TrackList::DeletionEvent() void TrackList::DeletionEvent(TrackNodePointer node)
{ {
// wxWidgets will own the event object // wxWidgets will own the event object
QueueEvent( safenew TrackListEvent{ EVT_TRACKLIST_DELETION } ); QueueEvent( safenew TrackListEvent{
EVT_TRACKLIST_DELETION,
node.second && node.first != node.second->end()
? *node.first
: nullptr
} );
} }
void TrackList::AdditionEvent(TrackNodePointer node) void TrackList::AdditionEvent(TrackNodePointer node)
@ -631,7 +629,7 @@ void TrackList::Permute(const std::vector<TrackNodePointer> &permutation)
} }
auto n = getBegin(); auto n = getBegin();
RecalcPositions(n); RecalcPositions(n);
PermutationEvent(); PermutationEvent(n);
} }
Track *TrackList::FindById( TrackId id ) Track *TrackList::FindById( TrackId id )
@ -738,7 +736,7 @@ auto TrackList::Replace(Track * t, const ListOfTracks::value_type &with) ->
pTrack->SetId( t->GetId() ); pTrack->SetId( t->GetId() );
RecalcPositions(node); RecalcPositions(node);
DeletionEvent(); DeletionEvent(node);
AdditionEvent(node); AdditionEvent(node);
} }
return holder; return holder;
@ -759,7 +757,7 @@ TrackNodePointer TrackList::Remove(Track *t)
if ( !isNull( result ) ) if ( !isNull( result ) )
RecalcPositions(result); RecalcPositions(result);
DeletionEvent(); DeletionEvent(result);
} }
} }
return result; return result;
@ -912,7 +910,7 @@ void TrackList::SwapNodes(TrackNodePointer s1, TrackNodePointer s2)
// Now correct the Index in the tracks, and other things // Now correct the Index in the tracks, and other things
RecalcPositions(s1); RecalcPositions(s1);
PermutationEvent(); PermutationEvent(s1);
} }
bool TrackList::MoveUp(Track * t) bool TrackList::MoveUp(Track * t)
@ -1051,6 +1049,11 @@ void TrackList::ClearPendingTracks( ListOfTracks *pAdded )
if (pAdded) if (pAdded)
pAdded->clear(); pAdded->clear();
// To find the first node that remains after the first deleted one
TrackNodePointer node;
bool findingNode = false;
bool foundNode = false;
for (auto it = ListOfTracks::begin(), stop = ListOfTracks::end(); for (auto it = ListOfTracks::begin(), stop = ListOfTracks::end();
it != stop;) { it != stop;) {
if (it->get()->GetId() == TrackId{}) { if (it->get()->GetId() == TrackId{}) {
@ -1058,13 +1061,23 @@ void TrackList::ClearPendingTracks( ListOfTracks *pAdded )
pAdded->push_back( *it ); pAdded->push_back( *it );
(*it)->SetOwner( {}, {} ); (*it)->SetOwner( {}, {} );
it = erase( it ); it = erase( it );
if (!findingNode)
findingNode = true;
if (!foundNode && it != stop)
node = (*it)->GetNode();
} }
else else {
if ( findingNode )
foundNode = true;
++it; ++it;
}
} }
if (!empty()) if (!empty()) {
RecalcPositions(getBegin()); RecalcPositions(getBegin());
DeletionEvent( node );
}
} }
bool TrackList::ApplyPendingTracks() bool TrackList::ApplyPendingTracks()
@ -1125,7 +1138,9 @@ bool TrackList::ApplyPendingTracks()
} }
} }
if (inserted) { if (inserted) {
RecalcPositions({first, this}); TrackNodePointer node{first, this};
RecalcPositions(node);
AdditionEvent(node);
result = true; result = true;
} }

View File

@ -1092,6 +1092,7 @@ wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
EVT_TRACKLIST_TRACK_DATA_CHANGE, TrackListEvent); EVT_TRACKLIST_TRACK_DATA_CHANGE, TrackListEvent);
// Posted when tracks are reordered but otherwise unchanged. // Posted when tracks are reordered but otherwise unchanged.
// mpTrack points to the moved track that is earliest in the New ordering.
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
EVT_TRACKLIST_PERMUTED, TrackListEvent); EVT_TRACKLIST_PERMUTED, TrackListEvent);
@ -1105,7 +1106,8 @@ wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
EVT_TRACKLIST_ADDITION, TrackListEvent); EVT_TRACKLIST_ADDITION, TrackListEvent);
// Posted when a track has been deleted from a tracklist. // Posted when a track has been deleted from a tracklist.
// Also posted when one track replaces another // Also posted when one track replaces another.
// mpTrack points to the first track after the deletion, if there is one.
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API, wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
EVT_TRACKLIST_DELETION, TrackListEvent); EVT_TRACKLIST_DELETION, TrackListEvent);
@ -1487,9 +1489,9 @@ private:
void RecalcPositions(TrackNodePointer node); void RecalcPositions(TrackNodePointer node);
void SelectionEvent( const std::shared_ptr<Track> &pTrack ); void SelectionEvent( const std::shared_ptr<Track> &pTrack );
void PermutationEvent(); void PermutationEvent(TrackNodePointer node);
void DataEvent( const std::shared_ptr<Track> &pTrack, int code ); void DataEvent( const std::shared_ptr<Track> &pTrack, int code );
void DeletionEvent(); void DeletionEvent(TrackNodePointer node = {});
void AdditionEvent(TrackNodePointer node); void AdditionEvent(TrackNodePointer node);
void ResizingEvent(TrackNodePointer node); void ResizingEvent(TrackNodePointer node);

View File

@ -14,6 +14,9 @@ Paul Licameli split from TrackPanel.cpp
#include "TrackControls.h" #include "TrackControls.h"
#include "../../TrackPanelResizerCell.h" #include "../../TrackPanelResizerCell.h"
#include "../../ClientData.h"
#include "../../Project.h"
TrackView::~TrackView() TrackView::~TrackView()
{ {
} }
@ -45,7 +48,7 @@ void TrackView::Copy( const TrackView &other )
{ {
mMinimized = other.mMinimized; mMinimized = other.mMinimized;
// Let mY remain 0 -- TrackList::RecalcPositions corrects it later // Let mY remain 0 -- TrackPositioner corrects it later
mY = 0; mY = 0;
mHeight = other.mHeight; mHeight = other.mHeight;
} }
@ -152,3 +155,53 @@ void TrackView::DoSetHeight(int h)
{ {
mHeight = h; mHeight = h;
} }
namespace {
// Attach an object to each project. It receives track list events and updates
// track Y coordinates
struct TrackPositioner : ClientData::Base, wxEvtHandler
{
AudacityProject &mProject;
explicit TrackPositioner( AudacityProject &project )
: mProject{ project }
{
TrackList::Get( project ).Bind(
EVT_TRACKLIST_ADDITION, &TrackPositioner::OnUpdate, this );
TrackList::Get( project ).Bind(
EVT_TRACKLIST_DELETION, &TrackPositioner::OnUpdate, this );
TrackList::Get( project ).Bind(
EVT_TRACKLIST_PERMUTED, &TrackPositioner::OnUpdate, this );
TrackList::Get( project ).Bind(
EVT_TRACKLIST_RESIZING, &TrackPositioner::OnUpdate, this );
}
void OnUpdate( TrackListEvent & e )
{
e.Skip();
auto iter =
TrackList::Get( mProject ).Find( e.mpTrack.lock().get() );
if ( !*iter )
return;
auto prev = iter;
auto yy = TrackView::GetCumulativeHeight( *--prev );
while( auto pTrack = *iter ) {
auto &view = TrackView::Get( *pTrack );
view.SetY( yy );
yy += view.GetHeight();
++iter;
}
}
};
static const AudacityProject::AttachedObjects::RegisteredFactory key{
[]( AudacityProject &project ){
return std::make_shared< TrackPositioner >( project );
}
};
}