1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-05-04 09:39:42 +02:00

TrackList emits more events for certain changes of state of tracks...

... Also rewrote some of the existing event handling so all events from
TrackList are of the same, custom event class, and distinguishing addition
from resizing events, though this distinction is not yet used
This commit is contained in:
Paul Licameli 2018-02-05 17:56:46 -05:00
parent ca4c9b81fc
commit 2741d58880
7 changed files with 140 additions and 39 deletions

View File

@ -643,6 +643,14 @@ void NoteTrack::InsertSilence(double t, double len)
// AddToDuration( len );
}
void NoteTrack::SetVelocity(float velocity)
{
if (mVelocity != velocity) {
mVelocity = velocity;
Notify();
}
}
// Call this function to manipulate the underlying sequence data. This is
// NOT the function that handles horizontal dragging.
bool NoteTrack::Shift(double t) // t is always seconds

View File

@ -114,7 +114,7 @@ class AUDACITY_DLL_API NoteTrack final
#ifdef EXPERIMENTAL_MIDI_OUT
float GetVelocity() const { return mVelocity; }
void SetVelocity(float velocity) { mVelocity = velocity; }
void SetVelocity(float velocity);
#endif
QuantizedTimeAndBeat NearestBeatTime( double time ) const;

View File

@ -91,9 +91,22 @@ void Track::Init(const Track &orig)
mChannel = orig.mChannel;
}
void Track::SetName( const wxString &n )
{
if ( mName != n ) {
mName = n;
Notify();
}
}
void Track::SetSelected(bool s)
{
mSelected = s;
if (mSelected != s) {
mSelected = s;
auto pList = mList.lock();
if (pList)
pList->SelectionEvent( Pointer( this ) );
}
}
void Track::Merge(const Track &orig)
@ -328,6 +341,13 @@ bool Track::IsSyncLockSelected() const
return false;
}
void Track::Notify( int code )
{
auto pList = mList.lock();
if (pList)
pList->DataEvent( Pointer(this), code );
}
void Track::SyncLockAdjust(double oldT1, double newT1)
{
if (newT1 > oldT1) {
@ -367,6 +387,22 @@ void PlayableTrack::Merge( const Track &orig )
AudioTrack::Merge( *pOrig );
}
void PlayableTrack::SetMute( bool m )
{
if ( mMute != m ) {
mMute = m;
Notify();
}
}
void PlayableTrack::SetSolo( bool s )
{
if ( mSolo != s ) {
mSolo = s;
Notify();
}
}
// Serialize, not with tags of its own, but as attributes within a tag.
void PlayableTrack::WriteXMLAttributes(XMLWriter &xmlFile) const
{
@ -513,9 +549,12 @@ std::pair<Track *, Track *> TrackList::FindSyncLockGroup(Track *pMember) const
// is managing. Any other classes that may be interested in get these updates
// should use TrackList::Connect() or TrackList::Bind().
//
wxDEFINE_EVENT(EVT_TRACKLIST_PERMUTED, wxCommandEvent);
wxDEFINE_EVENT(EVT_TRACKLIST_RESIZING, wxCommandEvent);
wxDEFINE_EVENT(EVT_TRACKLIST_DELETION, wxCommandEvent);
wxDEFINE_EVENT(EVT_TRACKLIST_TRACK_DATA_CHANGE, TrackListEvent);
wxDEFINE_EVENT(EVT_TRACKLIST_SELECTION_CHANGE, TrackListEvent);
wxDEFINE_EVENT(EVT_TRACKLIST_PERMUTED, TrackListEvent);
wxDEFINE_EVENT(EVT_TRACKLIST_RESIZING, TrackListEvent);
wxDEFINE_EVENT(EVT_TRACKLIST_ADDITION, TrackListEvent);
wxDEFINE_EVENT(EVT_TRACKLIST_DELETION, TrackListEvent);
// same value as in the default constructed TrackId:
long TrackList::sCounter = -1;
@ -592,26 +631,42 @@ void TrackList::RecalcPositions(TrackNodePointer node)
UpdatePendingTracks();
}
void TrackList::SelectionEvent( const std::shared_ptr<Track> &pTrack )
{
// wxWidgets will own the event object
QueueEvent(
safenew TrackListEvent{ EVT_TRACKLIST_SELECTION_CHANGE, pTrack } );
}
void TrackList::DataEvent( const std::shared_ptr<Track> &pTrack, int code )
{
// wxWidgets will own the event object
QueueEvent(
safenew TrackListEvent{ EVT_TRACKLIST_TRACK_DATA_CHANGE, pTrack, code } );
}
void TrackList::PermutationEvent()
{
auto e = std::make_unique<wxCommandEvent>(EVT_TRACKLIST_PERMUTED);
// wxWidgets will own the event object
QueueEvent(e.release());
QueueEvent( safenew TrackListEvent{ EVT_TRACKLIST_PERMUTED } );
}
void TrackList::DeletionEvent()
{
auto e = std::make_unique<wxCommandEvent>(EVT_TRACKLIST_DELETION);
// wxWidgets will own the event object
QueueEvent(e.release());
QueueEvent( safenew TrackListEvent{ EVT_TRACKLIST_DELETION } );
}
void TrackList::AdditionEvent(TrackNodePointer node)
{
// wxWidgets will own the event object
QueueEvent( safenew TrackListEvent{ EVT_TRACKLIST_ADDITION, *node.first } );
}
void TrackList::ResizingEvent(TrackNodePointer node)
{
auto e = std::make_unique<TrackListEvent>(EVT_TRACKLIST_RESIZING);
e->mpTrack = *node.first;
// wxWidgets will own the event object
QueueEvent(e.release());
QueueEvent( safenew TrackListEvent{ EVT_TRACKLIST_RESIZING, *node.first } );
}
auto TrackList::EmptyRange() const
@ -678,7 +733,7 @@ Track *TrackList::Add(std::unique_ptr<TrackKind> &&t)
pTrack->SetOwner(mSelf, n);
pTrack->SetId( TrackId{ ++sCounter } );
RecalcPositions(n);
ResizingEvent(n);
AdditionEvent(n);
return back().get();
}
@ -700,7 +755,7 @@ Track *TrackList::AddToHead(std::unique_ptr<TrackKind> &&t)
pTrack->SetOwner(mSelf, n);
pTrack->SetId( TrackId{ ++sCounter } );
RecalcPositions(n);
ResizingEvent(n);
AdditionEvent(n);
return front().get();
}
@ -717,7 +772,7 @@ Track *TrackList::Add(std::shared_ptr<TrackKind> &&t)
t->SetOwner(mSelf, n);
t->SetId( TrackId{ ++sCounter } );
RecalcPositions(n);
ResizingEvent(n);
AdditionEvent(n);
return back().get();
}
@ -794,7 +849,7 @@ auto TrackList::Replace(Track * t, ListOfTracks::value_type &&with) ->
RecalcPositions(node);
DeletionEvent();
ResizingEvent(node);
AdditionEvent(node);
}
return holder;
}

View File

@ -205,8 +205,10 @@ class AUDACITY_DLL_API Track /* not final */
wxString mName;
wxString mDefaultName;
private:
bool mSelected;
protected:
bool mLinked;
bool mMinimized;
@ -367,7 +369,7 @@ private:
virtual void Merge(const Track &orig);
wxString GetName() const { return mName; }
void SetName( const wxString &n ) { mName = n; }
void SetName( const wxString &n );
wxString GetDefaultName() const { return mDefaultName; }
void SetDefaultName( const wxString &n ) { mDefaultName = n; }
@ -714,6 +716,11 @@ public:
// Checks if sync-lock is on and any track in its sync-lock group is selected.
bool IsSyncLockSelected() const;
// Send an event to listeners when state of the track changes
// To do: define values for the argument to distinguish different parts
// of the state, perhaps with wxNewId
void Notify( int code = -1 );
// An always-true predicate useful for defining iterators
bool Any() const;
@ -763,8 +770,8 @@ public:
bool GetMute () const { return mMute; }
bool GetSolo () const { return mSolo; }
void SetMute (bool m) { mMute = m; }
void SetSolo (bool s) { mSolo = s; }
void SetMute (bool m);
void SetSolo (bool s);
void Init( const PlayableTrack &init );
void Merge( const Track &init ) override;
@ -1086,31 +1093,50 @@ template <
* Clear, and Contains, plus serialization of the list of tracks.
*/
struct TrackListEvent : public wxCommandEvent
struct TrackListEvent : public wxEvent
{
TrackListEvent(wxEventType commandType = wxEVT_NULL, int winid = 0)
: wxCommandEvent{ commandType, winid } {}
explicit
TrackListEvent(
wxEventType commandType,
const std::weak_ptr<Track> &pTrack = {}, int code = -1)
: wxEvent{ commandType }
, mpTrack{ pTrack }
, mCode{ code }
{}
TrackListEvent( const TrackListEvent& ) = default;
wxEvent *Clone() const override { return new TrackListEvent(*this); }
std::weak_ptr<Track> mpTrack;
int mCode;
};
// Posted when the set of selected tracks changes.
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
EVT_TRACKLIST_SELECTION_CHANGE, TrackListEvent);
// Posted when certain fields of a track change.
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
EVT_TRACKLIST_TRACK_DATA_CHANGE, TrackListEvent);
// Posted when tracks are reordered but otherwise unchanged.
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
EVT_TRACKLIST_PERMUTED, wxCommandEvent);
EVT_TRACKLIST_PERMUTED, TrackListEvent);
// Posted when some track was added or changed its height.
// Cast to TrackListEvent and examine mpTrack to retrieve it.
// Posted when some track changed its height.
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
EVT_TRACKLIST_RESIZING, wxCommandEvent);
EVT_TRACKLIST_RESIZING, TrackListEvent);
// Posted when a track has been added to a tracklist.
// Also posted when one track replaces another
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
wxDECLARE_EXPORTED_EVENT(AUDACITY_DLL_API,
EVT_TRACKLIST_DELETION, wxCommandEvent);
EVT_TRACKLIST_DELETION, TrackListEvent);
class TrackList final : public wxEvtHandler, public ListOfTracks
{
@ -1495,8 +1521,11 @@ private:
}
void RecalcPositions(TrackNodePointer node);
void SelectionEvent( const std::shared_ptr<Track> &pTrack );
void PermutationEvent();
void DataEvent( const std::shared_ptr<Track> &pTrack, int code );
void DeletionEvent();
void AdditionEvent(TrackNodePointer node);
void ResizingEvent(TrackNodePointer node);
void SwapNodes(TrackNodePointer s1, TrackNodePointer s2);

View File

@ -332,6 +332,9 @@ TrackPanel::TrackPanel(wxWindow * parent, wxWindowID id,
mTracks->Bind(EVT_TRACKLIST_RESIZING,
&TrackPanel::OnTrackListResizing,
this);
mTracks->Bind(EVT_TRACKLIST_ADDITION,
&TrackPanel::OnTrackListResizing,
this);
mTracks->Bind(EVT_TRACKLIST_DELETION,
&TrackPanel::OnTrackListDeletion,
this);
@ -781,7 +784,7 @@ void TrackPanel::UpdateViewIfNoTracks()
}
}
void TrackPanel::OnPlayback(wxCommandEvent &e)
void TrackPanel::OnPlayback(wxEvent &e)
{
e.Skip();
// Starting or stopping of play or record affects some cursors.
@ -792,9 +795,9 @@ void TrackPanel::OnPlayback(wxCommandEvent &e)
// The tracks positions within the list have changed, so update the vertical
// ruler size for the track that triggered the event.
void TrackPanel::OnTrackListResizing(wxCommandEvent & e)
void TrackPanel::OnTrackListResizing(TrackListEvent & e)
{
auto t = static_cast<TrackListEvent&>(e).mpTrack.lock();
auto t = e.mpTrack.lock();
// A deleted track can trigger the event. In which case do nothing here.
if( t )
UpdateVRuler(t.get());
@ -802,7 +805,7 @@ void TrackPanel::OnTrackListResizing(wxCommandEvent & e)
}
// Tracks have been removed from the list.
void TrackPanel::OnTrackListDeletion(wxCommandEvent & e)
void TrackPanel::OnTrackListDeletion(wxEvent & e)
{
// copy shared_ptr for safety, as in HandleClick
auto handle = Target();

View File

@ -33,6 +33,7 @@ class LabelTrack;
class SpectrumAnalyst;
class Track;
class TrackList;
class TrackListEvent;
class TrackPanel;
class TrackArtist;
class Ruler;
@ -41,7 +42,6 @@ class AdornedRulerPanel;
class LWSlider;
class ControlToolBar; //Needed because state of controls can affect what gets drawn.
class ToolsToolBar; //Needed because state of controls can affect what gets drawn.
class MixerBoard;
class TrackPanelAx;
class TrackPanelCellIterator;
@ -257,9 +257,9 @@ class AUDACITY_DLL_API TrackPanel final : public CellularPanel {
void OnMouseEvent(wxMouseEvent & event);
void OnKeyDown(wxKeyEvent & event);
void OnPlayback(wxCommandEvent &);
void OnTrackListResizing(wxCommandEvent & event);
void OnTrackListDeletion(wxCommandEvent & event);
void OnPlayback(wxEvent &);
void OnTrackListResizing(TrackListEvent & event);
void OnTrackListDeletion(wxEvent & event);
void UpdateViewIfNoTracks(); // Call this to update mViewInfo, etc, after track(s) removal, before Refresh().
double GetMostRecentXPos();

View File

@ -422,7 +422,10 @@ float WaveTrack::GetGain() const
void WaveTrack::SetGain(float newGain)
{
mGain = newGain;
if (mGain != newGain) {
mGain = newGain;
Notify();
}
}
float WaveTrack::GetPan() const
@ -433,11 +436,14 @@ float WaveTrack::GetPan() const
void WaveTrack::SetPan(float newPan)
{
if (newPan > 1.0)
mPan = 1.0;
newPan = 1.0;
else if (newPan < -1.0)
mPan = -1.0;
else
newPan = -1.0;
if ( mPan != newPan ) {
mPan = newPan;
Notify();
}
}
float WaveTrack::GetChannelGain(int channel) const