mirror of
https://github.com/cookiengineer/audacity
synced 2025-07-15 16:17:41 +02:00
Track does not depend on TrackView, freeing 11 files...
... from the second-largest s.c.c. which shrinks to 9 The 11 are: AutoRecovery Clipboard NoteTrack ODComputeSummaryTask ProjectFileIO ProjectHistory Track TrackControls TrackPanelResizeHandle, TrackPanelResizerCell, TrackView in a small cycle
This commit is contained in:
commit
91a2ff2560
@ -72,7 +72,8 @@ bool AudacityPrintout::OnPrintPage(int WXUNUSED(page))
|
||||
dc->GetSize(&width, &height);
|
||||
|
||||
int rulerScreenHeight = 40;
|
||||
int screenTotalHeight = mTracks->GetHeight() + rulerScreenHeight;
|
||||
int screenTotalHeight =
|
||||
TrackView::GetTotalHeight( *mTracks ) + rulerScreenHeight;
|
||||
|
||||
double scale = height / (double)screenTotalHeight;
|
||||
|
||||
|
@ -29,6 +29,7 @@ Paul Licameli split from AudacityProject.cpp
|
||||
#include "toolbars/ControlToolBar.h"
|
||||
#include "toolbars/ToolManager.h"
|
||||
#include "tracks/ui/Scrubbing.h"
|
||||
#include "tracks/ui/TrackView.h"
|
||||
#include "widgets/wxPanelWrapper.h"
|
||||
#include "widgets/WindowAccessible.h"
|
||||
|
||||
@ -1137,7 +1138,7 @@ void ProjectWindow::FixScrollbars()
|
||||
bool refresh = false;
|
||||
bool rescroll = false;
|
||||
|
||||
int totalHeight = (tracks.GetHeight() + 32);
|
||||
int totalHeight = TrackView::GetTotalHeight( tracks ) + 32;
|
||||
|
||||
int panelWidth, panelHeight;
|
||||
trackPanel.GetTracksUsableArea(&panelWidth, &panelHeight);
|
||||
|
130
src/Track.cpp
130
src/Track.cpp
@ -41,8 +41,6 @@ and TimeTrack.
|
||||
|
||||
#include "InconsistencyException.h"
|
||||
|
||||
#include "tracks/ui/TrackView.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
//Disable truncation warnings
|
||||
#pragma warning( disable : 4786 )
|
||||
@ -115,7 +113,7 @@ Track::Holder Track::Duplicate() const
|
||||
|
||||
if (mpView)
|
||||
// Copy view state that might be important to undo/redo
|
||||
TrackView::Get( *result ).Copy( *mpView );
|
||||
mpView->CopyTo( *result );
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -140,6 +138,26 @@ void Track::SetOwner
|
||||
mNode = node;
|
||||
}
|
||||
|
||||
const std::shared_ptr<CommonTrackCell> &Track::GetTrackView()
|
||||
{
|
||||
return mpView;
|
||||
}
|
||||
|
||||
void Track::SetTrackView( const std::shared_ptr<CommonTrackCell> &pView )
|
||||
{
|
||||
mpView = pView;
|
||||
}
|
||||
|
||||
const std::shared_ptr<CommonTrackCell> &Track::GetTrackControls()
|
||||
{
|
||||
return mpControls;
|
||||
}
|
||||
|
||||
void Track::SetTrackControls( const std::shared_ptr<CommonTrackCell> &pControls )
|
||||
{
|
||||
mpControls = pControls;
|
||||
}
|
||||
|
||||
int Track::GetIndex() const
|
||||
{
|
||||
return mIndex;
|
||||
@ -156,7 +174,6 @@ void Track::SetLinked(bool l)
|
||||
if (pList && !pList->mPendingUpdates.empty()) {
|
||||
auto orig = pList->FindById( GetId() );
|
||||
if (orig && orig != this) {
|
||||
// delegate, and rely on RecalcPositions to copy back
|
||||
orig->SetLinked(l);
|
||||
return;
|
||||
}
|
||||
@ -532,23 +549,17 @@ void TrackList::RecalcPositions(TrackNodePointer node)
|
||||
|
||||
Track *t;
|
||||
int i = 0;
|
||||
int y = 0;
|
||||
|
||||
auto prev = getPrev( node );
|
||||
if ( !isNull( prev ) ) {
|
||||
t = prev.first->get();
|
||||
i = t->GetIndex() + 1;
|
||||
auto &view = TrackView::Get( *t );
|
||||
y = view.GetY() + view.GetHeight();
|
||||
}
|
||||
|
||||
const auto theEnd = end();
|
||||
for (auto n = Find( node.first->get() ); n != theEnd; ++n) {
|
||||
t = *n;
|
||||
auto &view = TrackView::Get( *t );
|
||||
t->SetIndex(i++);
|
||||
view.SetY(y);
|
||||
y += view.GetHeight();
|
||||
}
|
||||
|
||||
UpdatePendingTracks();
|
||||
@ -568,16 +579,21 @@ void TrackList::DataEvent( const std::shared_ptr<Track> &pTrack, int code )
|
||||
safenew TrackListEvent{ EVT_TRACKLIST_TRACK_DATA_CHANGE, pTrack, code } );
|
||||
}
|
||||
|
||||
void TrackList::PermutationEvent()
|
||||
void TrackList::PermutationEvent(TrackNodePointer node)
|
||||
{
|
||||
// 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
|
||||
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)
|
||||
@ -631,7 +647,7 @@ void TrackList::Permute(const std::vector<TrackNodePointer> &permutation)
|
||||
}
|
||||
auto n = getBegin();
|
||||
RecalcPositions(n);
|
||||
PermutationEvent();
|
||||
PermutationEvent(n);
|
||||
}
|
||||
|
||||
Track *TrackList::FindById( TrackId id )
|
||||
@ -738,7 +754,7 @@ auto TrackList::Replace(Track * t, const ListOfTracks::value_type &with) ->
|
||||
pTrack->SetId( t->GetId() );
|
||||
RecalcPositions(node);
|
||||
|
||||
DeletionEvent();
|
||||
DeletionEvent(node);
|
||||
AdditionEvent(node);
|
||||
}
|
||||
return holder;
|
||||
@ -759,7 +775,7 @@ TrackNodePointer TrackList::Remove(Track *t)
|
||||
if ( !isNull( result ) )
|
||||
RecalcPositions(result);
|
||||
|
||||
DeletionEvent();
|
||||
DeletionEvent(result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -842,15 +858,6 @@ Track *TrackList::GetPrev(Track * t, bool linked) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// For mono track height of track
|
||||
/// For stereo track combined height of both channels.
|
||||
int TrackList::GetGroupHeight(const Track * t) const
|
||||
{
|
||||
const auto GetHeight = []( const Track *track )
|
||||
{ return TrackView::Get( *track ).GetHeight(); };
|
||||
return Channels(t).sum( GetHeight );
|
||||
}
|
||||
|
||||
bool TrackList::CanMoveUp(Track * t) const
|
||||
{
|
||||
return GetPrev(t, true) != NULL;
|
||||
@ -921,7 +928,7 @@ void TrackList::SwapNodes(TrackNodePointer s1, TrackNodePointer s2)
|
||||
|
||||
// Now correct the Index in the tracks, and other things
|
||||
RecalcPositions(s1);
|
||||
PermutationEvent();
|
||||
PermutationEvent(s1);
|
||||
}
|
||||
|
||||
bool TrackList::MoveUp(Track * t)
|
||||
@ -970,19 +977,6 @@ size_t TrackList::size() const
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int TrackList::GetHeight() const
|
||||
{
|
||||
int height = 0;
|
||||
|
||||
if (!empty()) {
|
||||
auto track = getPrev( getEnd() ).first->get();
|
||||
auto &view = TrackView::Get( *track );
|
||||
height = view.GetY() + view.GetHeight();
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Abstract the common pattern of the following three member functions
|
||||
inline double Accumulate
|
||||
@ -1073,6 +1067,11 @@ void TrackList::ClearPendingTracks( ListOfTracks *pAdded )
|
||||
if (pAdded)
|
||||
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();
|
||||
it != stop;) {
|
||||
if (it->get()->GetId() == TrackId{}) {
|
||||
@ -1080,13 +1079,23 @@ void TrackList::ClearPendingTracks( ListOfTracks *pAdded )
|
||||
pAdded->push_back( *it );
|
||||
(*it)->SetOwner( {}, {} );
|
||||
it = erase( it );
|
||||
|
||||
if (!findingNode)
|
||||
findingNode = true;
|
||||
if (!foundNode && it != stop)
|
||||
node = (*it)->GetNode();
|
||||
}
|
||||
else
|
||||
else {
|
||||
if ( findingNode )
|
||||
foundNode = true;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty())
|
||||
if (!empty()) {
|
||||
RecalcPositions(getBegin());
|
||||
DeletionEvent( node );
|
||||
}
|
||||
}
|
||||
|
||||
bool TrackList::ApplyPendingTracks()
|
||||
@ -1147,7 +1156,9 @@ bool TrackList::ApplyPendingTracks()
|
||||
}
|
||||
}
|
||||
if (inserted) {
|
||||
RecalcPositions({first, this});
|
||||
TrackNodePointer node{first, this};
|
||||
RecalcPositions(node);
|
||||
AdditionEvent(node);
|
||||
result = true;
|
||||
}
|
||||
|
||||
@ -1198,9 +1209,10 @@ void Track::WriteCommonXMLAttributes(
|
||||
xmlFile.WriteAttr(wxT("name"), GetName());
|
||||
xmlFile.WriteAttr(wxT("isSelected"), this->GetSelected());
|
||||
}
|
||||
auto &view = TrackView::Get( *this );
|
||||
xmlFile.WriteAttr(wxT("height"), view.GetActualHeight());
|
||||
xmlFile.WriteAttr(wxT("minimized"), view.GetMinimized());
|
||||
if ( mpView )
|
||||
mpView->WriteXMLAttributes( xmlFile );
|
||||
if ( mpControls )
|
||||
mpControls->WriteXMLAttributes( xmlFile );
|
||||
}
|
||||
|
||||
// Return true iff the attribute is recognized.
|
||||
@ -1208,21 +1220,15 @@ bool Track::HandleCommonXMLAttribute(const wxChar *attr, const wxChar *value)
|
||||
{
|
||||
long nValue = -1;
|
||||
wxString strValue( value );
|
||||
if (!wxStrcmp(attr, wxT("name")) &&
|
||||
if ( mpView && mpView->HandleXMLAttribute( attr, value ) )
|
||||
;
|
||||
else if ( mpControls && mpControls->HandleXMLAttribute( attr, value ) )
|
||||
;
|
||||
else if (!wxStrcmp(attr, wxT("name")) &&
|
||||
XMLValueChecker::IsGoodString(strValue)) {
|
||||
SetName( strValue );
|
||||
return true;
|
||||
}
|
||||
else if (!wxStrcmp(attr, wxT("height")) &&
|
||||
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue)) {
|
||||
TrackView::Get( *this ).SetHeight(nValue);
|
||||
return true;
|
||||
}
|
||||
else if (!wxStrcmp(attr, wxT("minimized")) &&
|
||||
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue)) {
|
||||
TrackView::Get( *this ).SetMinimized(nValue != 0);
|
||||
return true;
|
||||
}
|
||||
else if (!wxStrcmp(attr, wxT("isSelected")) &&
|
||||
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue)) {
|
||||
this->SetSelected(nValue != 0);
|
||||
@ -1284,13 +1290,3 @@ void TrackFactory::Destroy( AudacityProject &project )
|
||||
{
|
||||
project.AttachedObjects::Assign( key2, nullptr );
|
||||
}
|
||||
|
||||
template<> auto DoGetControls::Implementation() -> Function {
|
||||
return nullptr;
|
||||
}
|
||||
static DoGetControls registerDoGetControls;
|
||||
|
||||
template<> auto DoGetView::Implementation() -> Function {
|
||||
return nullptr;
|
||||
}
|
||||
static DoGetView registerDoGetView;
|
||||
|
49
src/Track.h
49
src/Track.h
@ -261,15 +261,15 @@ class AUDACITY_DLL_API Track /* not final */
|
||||
public:
|
||||
mutable wxSize vrulerSize;
|
||||
|
||||
// Return another, associated TrackPanelCell object that implements
|
||||
// click and drag and keystrokes in the track contents.
|
||||
std::shared_ptr<TrackView> GetTrackView();
|
||||
std::shared_ptr<const TrackView> GetTrackView() const;
|
||||
// These are exposed only for the purposes of the TrackView class, to
|
||||
// initialize the pointer on demand
|
||||
const std::shared_ptr<CommonTrackCell> &GetTrackView();
|
||||
void SetTrackView( const std::shared_ptr<CommonTrackCell> &pView );
|
||||
|
||||
// Return another, associated TrackPanelCell object that implements the
|
||||
// drop-down, close and minimize buttons, etc.
|
||||
std::shared_ptr<TrackPanelCell> GetTrackControls();
|
||||
std::shared_ptr<const TrackPanelCell> GetTrackControls() const;
|
||||
// These are exposed only for the purposes of the TrackControls class, to
|
||||
// initialize the pointer on demand
|
||||
const std::shared_ptr<CommonTrackCell> &GetTrackControls();
|
||||
void SetTrackControls( const std::shared_ptr<CommonTrackCell> &pControls );
|
||||
|
||||
// Return another, associated TrackPanelCell object that implements the
|
||||
|
||||
@ -704,7 +704,7 @@ public:
|
||||
bool HandleCommonXMLAttribute(const wxChar *attr, const wxChar *value);
|
||||
|
||||
protected:
|
||||
std::shared_ptr<TrackView> mpView;
|
||||
std::shared_ptr<CommonTrackCell> mpView;
|
||||
std::shared_ptr<CommonTrackCell> mpControls;
|
||||
};
|
||||
|
||||
@ -1092,6 +1092,7 @@ wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
|
||||
EVT_TRACKLIST_TRACK_DATA_CHANGE, TrackListEvent);
|
||||
|
||||
// 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,
|
||||
EVT_TRACKLIST_PERMUTED, TrackListEvent);
|
||||
|
||||
@ -1105,7 +1106,8 @@ wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
|
||||
EVT_TRACKLIST_ADDITION, TrackListEvent);
|
||||
|
||||
// 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,
|
||||
EVT_TRACKLIST_DELETION, TrackListEvent);
|
||||
|
||||
@ -1360,8 +1362,6 @@ public:
|
||||
/// Make the list empty
|
||||
void Clear(bool sendEvent = true);
|
||||
|
||||
int GetGroupHeight(const Track * t) const;
|
||||
|
||||
bool CanMoveUp(Track * t) const;
|
||||
bool CanMoveDown(Track * t) const;
|
||||
|
||||
@ -1393,7 +1393,6 @@ public:
|
||||
double GetEndTime() const;
|
||||
|
||||
double GetMinOffset() const;
|
||||
int GetHeight() const;
|
||||
|
||||
#if LEGACY_PROJECT_FILE_SUPPORT
|
||||
// File I/O
|
||||
@ -1490,9 +1489,9 @@ private:
|
||||
|
||||
void RecalcPositions(TrackNodePointer node);
|
||||
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 DeletionEvent();
|
||||
void DeletionEvent(TrackNodePointer node = {});
|
||||
void AdditionEvent(TrackNodePointer node);
|
||||
void ResizingEvent(TrackNodePointer node);
|
||||
|
||||
@ -1589,24 +1588,4 @@ class AUDACITY_DLL_API TrackFactory final
|
||||
#endif
|
||||
};
|
||||
|
||||
#include "AttachedVirtualFunction.h"
|
||||
|
||||
struct DoGetControlsTag;
|
||||
|
||||
using DoGetControls =
|
||||
AttachedVirtualFunction<
|
||||
DoGetControlsTag,
|
||||
std::shared_ptr< TrackControls >,
|
||||
Track
|
||||
>;
|
||||
|
||||
struct DoGetViewTag;
|
||||
|
||||
using DoGetView =
|
||||
AttachedVirtualFunction<
|
||||
DoGetViewTag,
|
||||
std::shared_ptr< TrackView >,
|
||||
Track
|
||||
>;
|
||||
|
||||
#endif
|
||||
|
@ -832,10 +832,8 @@ void TrackPanel::RefreshTrack(Track *trk, bool refreshbacking)
|
||||
|
||||
trk = *GetTracks()->FindLeader(trk);
|
||||
auto &view = TrackView::Get( *trk );
|
||||
const auto GetHeight = []( const Track *track )
|
||||
{ return TrackView::Get( *track ).GetHeight(); };
|
||||
auto height =
|
||||
TrackList::Channels(trk).sum( GetHeight )
|
||||
TrackList::Channels(trk).sum( TrackView::GetTrackHeight )
|
||||
- kTopInset - kShadowThickness;
|
||||
|
||||
// subtract insets and shadows from the rectangle, but not border
|
||||
@ -1327,9 +1325,7 @@ void TrackPanel::EnsureVisible(Track * t)
|
||||
trackTop += trackHeight;
|
||||
|
||||
auto channels = TrackList::Channels(it);
|
||||
const auto GetHeight = []( const Track *track )
|
||||
{ return TrackView::Get( *track ).GetHeight(); };
|
||||
trackHeight = channels.sum( GetHeight );
|
||||
trackHeight = channels.sum( TrackView::GetTrackHeight );
|
||||
|
||||
//We have found the track we want to ensure is visible.
|
||||
if (channels.contains(t)) {
|
||||
@ -1363,15 +1359,13 @@ void TrackPanel::VerticalScroll( float fracPosition){
|
||||
int trackHeight = 0;
|
||||
|
||||
auto tracks = GetTracks();
|
||||
const auto GetHeight =
|
||||
[&]( const Track *t ){ return tracks->GetGroupHeight(t); };
|
||||
|
||||
auto range = tracks->Leaders();
|
||||
if (!range.empty()) {
|
||||
trackHeight = GetHeight( *range.rbegin() );
|
||||
trackHeight = TrackView::GetChannelGroupHeight( *range.rbegin() );
|
||||
--range.second;
|
||||
}
|
||||
trackTop = range.sum( GetHeight );
|
||||
trackTop = range.sum( TrackView::GetChannelGroupHeight );
|
||||
|
||||
int delta;
|
||||
|
||||
|
@ -497,7 +497,7 @@ bool GetInfoCommand::SendTracks(const CommandContext & context)
|
||||
context.AddBool( (trk == fTrack), "focused");
|
||||
context.AddBool( trk->GetSelected(), "selected" );
|
||||
//JKC: Possibly add later...
|
||||
//context.AddItem( GetTrackView::Get( *trk ).GetHeight(), "height" );
|
||||
//context.AddItem( TrackView::Get( *trk ).GetHeight(), "height" );
|
||||
trk->TypeSwitch( [&] (const WaveTrack* t ) {
|
||||
float vzmin, vzmax;
|
||||
t->GetDisplayBounds(&vzmin, &vzmax);
|
||||
|
@ -206,10 +206,9 @@ void DoZoomFitV(AudacityProject &project)
|
||||
height -= 28;
|
||||
|
||||
// The height of minimized and non-audio tracks cannot be apportioned
|
||||
const auto GetHeight = []( const Track *track )
|
||||
{ return TrackView::Get( *track ).GetHeight(); };
|
||||
height -=
|
||||
tracks.Any().sum( GetHeight ) - range.sum( GetHeight );
|
||||
tracks.Any().sum( TrackView::GetTrackHeight )
|
||||
- range.sum( TrackView::GetTrackHeight );
|
||||
|
||||
// Give each resized track the average of the remaining height
|
||||
height = height / count;
|
||||
|
@ -97,13 +97,14 @@ void LabelTrackView::UnbindFrom( LabelTrack *pParent )
|
||||
EVT_LABELTRACK_PERMUTED, &LabelTrackView::OnLabelPermuted, this );
|
||||
}
|
||||
|
||||
void LabelTrackView::Copy( const TrackView &other )
|
||||
void LabelTrackView::CopyTo( Track &track ) const
|
||||
{
|
||||
TrackView::Copy( other );
|
||||
TrackView::CopyTo( track );
|
||||
auto &other = TrackView::Get( track );
|
||||
|
||||
if ( const auto pOther = dynamic_cast< const LabelTrackView* >( &other ) ) {
|
||||
// only one field is important to preserve in undo/redo history
|
||||
mSelIndex = pOther->mSelIndex;
|
||||
pOther->mSelIndex = mSelIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ private:
|
||||
std::shared_ptr<TrackVRulerControls> DoGetVRulerControls() override;
|
||||
|
||||
// Preserve some view state too for undo/redo purposes
|
||||
void Copy( const TrackView &other ) override;
|
||||
void CopyTo( Track &track ) const override;
|
||||
|
||||
public:
|
||||
static void DoEditLabels(
|
||||
|
@ -57,6 +57,10 @@ CommonTrackCell::CommonTrackCell( const std::shared_ptr< Track > &parent )
|
||||
|
||||
CommonTrackCell::~CommonTrackCell() = default;
|
||||
|
||||
void CommonTrackCell::CopyTo( Track& ) const
|
||||
{
|
||||
}
|
||||
|
||||
void CommonTrackCell::Reparent( const std::shared_ptr<Track> &parent )
|
||||
{
|
||||
mwTrack = parent;
|
||||
@ -66,3 +70,12 @@ std::shared_ptr<Track> CommonTrackCell::DoFindTrack()
|
||||
{
|
||||
return mwTrack.lock();
|
||||
}
|
||||
|
||||
void CommonTrackCell::WriteXMLAttributes( XMLWriter & ) const
|
||||
{
|
||||
}
|
||||
|
||||
bool CommonTrackCell::HandleXMLAttribute( const wxChar *, const wxChar * )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#include <functional>
|
||||
|
||||
class Track;
|
||||
class XMLWriter;
|
||||
|
||||
class AUDACITY_DLL_API CommonTrackPanelCell /* not final */
|
||||
: public TrackPanelCell
|
||||
@ -61,10 +62,20 @@ public:
|
||||
|
||||
~CommonTrackCell();
|
||||
|
||||
// Copy state, for undo/redo purposes
|
||||
// The default does nothing
|
||||
virtual void CopyTo( Track &track ) const;
|
||||
|
||||
std::shared_ptr<Track> DoFindTrack() override;
|
||||
|
||||
virtual void Reparent( const std::shared_ptr<Track> &parent );
|
||||
|
||||
// default does nothing
|
||||
virtual void WriteXMLAttributes( XMLWriter & ) const;
|
||||
|
||||
// default recognizes no attributes, and returns false
|
||||
virtual bool HandleXMLAttribute( const wxChar *attr, const wxChar *value );
|
||||
|
||||
private:
|
||||
std::weak_ptr< Track > mwTrack;
|
||||
};
|
||||
|
@ -24,11 +24,20 @@ TrackControls::~TrackControls()
|
||||
|
||||
TrackControls &TrackControls::Get( Track &track )
|
||||
{
|
||||
return *static_cast<TrackControls*>( track.GetTrackControls().get() );
|
||||
auto pControls =
|
||||
std::static_pointer_cast<TrackControls>( track.GetTrackControls() );
|
||||
if (!pControls)
|
||||
// create on demand
|
||||
track.SetTrackControls( pControls = DoGetControls::Call( track ) );
|
||||
return *pControls;
|
||||
}
|
||||
|
||||
const TrackControls &TrackControls::Get( const Track &track )
|
||||
{
|
||||
return *static_cast<const TrackControls*>( track.GetTrackControls().get() );
|
||||
return Get( const_cast< Track& >( track ) );
|
||||
}
|
||||
|
||||
template<> auto DoGetControls::Implementation() -> Function {
|
||||
return nullptr;
|
||||
}
|
||||
static DoGetControls registerDoGetControls;
|
||||
|
@ -28,4 +28,15 @@ public:
|
||||
virtual ~TrackControls() = 0;
|
||||
};
|
||||
|
||||
#include "AttachedVirtualFunction.h"
|
||||
|
||||
struct DoGetControlsTag;
|
||||
|
||||
using DoGetControls =
|
||||
AttachedVirtualFunction<
|
||||
DoGetControlsTag,
|
||||
std::shared_ptr< TrackControls >,
|
||||
Track
|
||||
>;
|
||||
|
||||
#endif
|
||||
|
@ -11,6 +11,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#include "../../Audacity.h"
|
||||
#include "TrackSelectHandle.h"
|
||||
|
||||
#include "TrackView.h"
|
||||
#include "../../Menus.h"
|
||||
#include "../../Project.h"
|
||||
#include "../../ProjectAudioIO.h"
|
||||
@ -219,7 +220,7 @@ void TrackSelectHandle::CalculateRearrangingThresholds(const wxMouseEvent & even
|
||||
if (tracks.CanMoveUp(mpTrack.get()))
|
||||
mMoveUpThreshold =
|
||||
event.m_y -
|
||||
tracks.GetGroupHeight(
|
||||
TrackView::GetChannelGroupHeight(
|
||||
* -- tracks.FindLeader( mpTrack.get() ) );
|
||||
else
|
||||
mMoveUpThreshold = INT_MIN;
|
||||
@ -227,7 +228,7 @@ void TrackSelectHandle::CalculateRearrangingThresholds(const wxMouseEvent & even
|
||||
if (tracks.CanMoveDown(mpTrack.get()))
|
||||
mMoveDownThreshold =
|
||||
event.m_y +
|
||||
tracks.GetGroupHeight(
|
||||
TrackView::GetChannelGroupHeight(
|
||||
* ++ tracks.FindLeader( mpTrack.get() ) );
|
||||
else
|
||||
mMoveDownThreshold = INT_MAX;
|
||||
|
@ -14,27 +14,61 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#include "TrackControls.h"
|
||||
#include "../../TrackPanelResizerCell.h"
|
||||
|
||||
#include "../../ClientData.h"
|
||||
#include "../../Project.h"
|
||||
#include "../../xml/XMLTagHandler.h"
|
||||
#include "../../xml/XMLWriter.h"
|
||||
|
||||
TrackView::~TrackView()
|
||||
{
|
||||
}
|
||||
|
||||
void TrackView::Copy( const TrackView &other )
|
||||
int TrackView::GetTrackHeight( const Track *pTrack )
|
||||
{
|
||||
mMinimized = other.mMinimized;
|
||||
return pTrack ? Get( *pTrack ).GetHeight() : 0;
|
||||
}
|
||||
|
||||
// Let mY remain 0 -- TrackList::RecalcPositions corrects it later
|
||||
mY = 0;
|
||||
mHeight = other.mHeight;
|
||||
int TrackView::GetChannelGroupHeight( const Track *pTrack )
|
||||
{
|
||||
return pTrack ? TrackList::Channels( pTrack ).sum( GetTrackHeight ) : 0;
|
||||
}
|
||||
|
||||
int TrackView::GetCumulativeHeight( const Track *pTrack )
|
||||
{
|
||||
if ( !pTrack )
|
||||
return 0;
|
||||
auto &view = Get( *pTrack );
|
||||
return view.GetY() + view.GetHeight();
|
||||
}
|
||||
|
||||
int TrackView::GetTotalHeight( const TrackList &list )
|
||||
{
|
||||
return GetCumulativeHeight( *list.Any().rbegin() );
|
||||
}
|
||||
|
||||
void TrackView::CopyTo( Track &track ) const
|
||||
{
|
||||
auto &other = Get( track );
|
||||
|
||||
other.mMinimized = mMinimized;
|
||||
|
||||
// Let mY remain 0 -- TrackPositioner corrects it later
|
||||
other.mY = 0;
|
||||
other.mHeight = mHeight;
|
||||
}
|
||||
|
||||
TrackView &TrackView::Get( Track &track )
|
||||
{
|
||||
return *track.GetTrackView();
|
||||
auto pView = std::static_pointer_cast<TrackView>( track.GetTrackView() );
|
||||
if (!pView)
|
||||
// create on demand
|
||||
track.SetTrackView( pView = DoGetView::Call( track ) );
|
||||
return *pView;
|
||||
}
|
||||
|
||||
const TrackView &TrackView::Get( const Track &track )
|
||||
{
|
||||
return *track.GetTrackView();
|
||||
return Get( const_cast< Track& >( track ) );
|
||||
}
|
||||
|
||||
void TrackView::SetMinimized(bool isMinimized)
|
||||
@ -48,37 +82,35 @@ void TrackView::SetMinimized(bool isMinimized)
|
||||
leader->AdjustPositions();
|
||||
}
|
||||
|
||||
void TrackView::WriteXMLAttributes( XMLWriter &xmlFile ) const
|
||||
{
|
||||
xmlFile.WriteAttr(wxT("height"), GetActualHeight());
|
||||
xmlFile.WriteAttr(wxT("minimized"), GetMinimized());
|
||||
}
|
||||
|
||||
bool TrackView::HandleXMLAttribute( const wxChar *attr, const wxChar *value )
|
||||
{
|
||||
wxString strValue;
|
||||
long nValue;
|
||||
if (!wxStrcmp(attr, wxT("height")) &&
|
||||
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue)) {
|
||||
SetHeight(nValue);
|
||||
return true;
|
||||
}
|
||||
else if (!wxStrcmp(attr, wxT("minimized")) &&
|
||||
XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue)) {
|
||||
SetMinimized(nValue != 0);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void TrackView::DoSetMinimized(bool isMinimized)
|
||||
{
|
||||
mMinimized = isMinimized;
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackView> Track::GetTrackView()
|
||||
{
|
||||
if (!mpView)
|
||||
// create on demand
|
||||
mpView = DoGetView::Call( *this );
|
||||
return mpView;
|
||||
}
|
||||
|
||||
std::shared_ptr<const TrackView> Track::GetTrackView() const
|
||||
{
|
||||
return const_cast<Track*>(this)->GetTrackView();
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackPanelCell> Track::GetTrackControls()
|
||||
{
|
||||
if (!mpControls)
|
||||
// create on demand
|
||||
mpControls = DoGetControls::Call( *this );
|
||||
return mpControls;
|
||||
}
|
||||
|
||||
std::shared_ptr<const TrackPanelCell> Track::GetTrackControls() const
|
||||
{
|
||||
return const_cast< Track* >( this )->GetTrackControls();
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackVRulerControls> TrackView::GetVRulerControls()
|
||||
{
|
||||
if (!mpVRulerControls)
|
||||
@ -129,3 +161,58 @@ void TrackView::DoSetHeight(int 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 );
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<> auto DoGetView::Implementation() -> Function {
|
||||
return nullptr;
|
||||
}
|
||||
static DoGetView registerDoGetView;
|
||||
|
@ -15,6 +15,7 @@ Paul Licameli split from class Track
|
||||
#include "CommonTrackPanelCell.h" // to inherit
|
||||
|
||||
class Track;
|
||||
class TrackList;
|
||||
class TrackVRulerControls;
|
||||
class TrackPanelResizerCell;
|
||||
|
||||
@ -32,8 +33,16 @@ public:
|
||||
: CommonTrackCell{ pTrack } {}
|
||||
virtual ~TrackView() = 0;
|
||||
|
||||
// some static conveniences, useful for summation over track iterator
|
||||
// ranges
|
||||
static int GetTrackHeight( const Track *pTrack );
|
||||
static int GetChannelGroupHeight( const Track *pTrack );
|
||||
// Total height of the given track and all previous ones (constant time!)
|
||||
static int GetCumulativeHeight( const Track *pTrack );
|
||||
static int GetTotalHeight( const TrackList &list );
|
||||
|
||||
// Copy view state, for undo/redo purposes
|
||||
virtual void Copy( const TrackView &other );
|
||||
void CopyTo( Track &track ) const override;
|
||||
|
||||
static TrackView &Get( Track & );
|
||||
static const TrackView &Get( const Track & );
|
||||
@ -60,6 +69,9 @@ public:
|
||||
std::shared_ptr<TrackPanelCell> GetResizer();
|
||||
std::shared_ptr<const TrackPanelCell> GetResizer() const;
|
||||
|
||||
void WriteXMLAttributes( XMLWriter & ) const override;
|
||||
bool HandleXMLAttribute( const wxChar *attr, const wxChar *value ) override;
|
||||
|
||||
protected:
|
||||
virtual void DoSetMinimized( bool isMinimized );
|
||||
|
||||
@ -81,4 +93,15 @@ private:
|
||||
int mHeight{ DefaultHeight };
|
||||
};
|
||||
|
||||
#include "AttachedVirtualFunction.h"
|
||||
|
||||
struct DoGetViewTag;
|
||||
|
||||
using DoGetView =
|
||||
AttachedVirtualFunction<
|
||||
DoGetViewTag,
|
||||
std::shared_ptr< TrackView >,
|
||||
Track
|
||||
>;
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user