1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-11-23 17:30:17 +01:00

Addition, deletion, sort of Labels communicated by events...

... and LabelTrack listens to its own events, to update certain state.

This is roundabout for now, but that state is view-related and will move into
another class.
This commit is contained in:
Paul Licameli
2018-12-05 14:10:05 -05:00
parent aa5f9550bd
commit 604fbd0a2c
5 changed files with 183 additions and 40 deletions

View File

@@ -76,6 +76,10 @@ for drawing different aspects of the label and its text box.
#include "widgets/AudacityMessageBox.h"
#include "widgets/ErrorDialog.h"
wxDEFINE_EVENT(EVT_LABELTRACK_ADDITION, LabelTrackEvent);
wxDEFINE_EVENT(EVT_LABELTRACK_DELETION, LabelTrackEvent);
wxDEFINE_EVENT(EVT_LABELTRACK_PERMUTED, LabelTrackEvent);
enum
{
OnCutSelectedTextID = 1, // OSX doesn't like a 0 menu id
@@ -131,6 +135,10 @@ LabelTrack::LabelTrack(const std::shared_ptr<DirManager> &projDirManager):
// reset flags
ResetFlags();
Bind( EVT_LABELTRACK_ADDITION, &LabelTrack::OnLabelAdded, this );
Bind( EVT_LABELTRACK_DELETION, &LabelTrack::OnLabelDeleted, this );
Bind( EVT_LABELTRACK_PERMUTED, &LabelTrack::OnLabelPermuted, this );
}
LabelTrack::LabelTrack(const LabelTrack &orig) :
@@ -806,7 +814,7 @@ namespace {
if (target) {
auto handle = dynamic_cast<LabelGlyphHandle*>( target.get() );
if (handle)
return &handle->mHit;
return &*handle->mpHit;
}
return nullptr;
}
@@ -1581,7 +1589,7 @@ bool LabelTrack::HandleGlyphDragRelease
//the NEW size of the label.
*newSel = mLabels[mSelIndex].selectedRegion;
}
SortLabels( &hit );
SortLabels();
}
return false;
@@ -2802,8 +2810,17 @@ int LabelTrackView::AddLabel(const SelectedRegion &selectedRegion,
return pos;
}
void LabelTrack::OnLabelAdded( const wxString &title, int pos )
void LabelTrack::OnLabelAdded( LabelTrackEvent &e )
{
e.Skip();
if ( e.mpTrack.lock().get() != this )
return;
const auto &title = e.mTitle;
const auto pos = e.mPresentPosition;
mInitialCursorPos = mCurrentCursorPos = title.length();
// restoreFocus is -2 e.g. from Nyquist label creation, when we should not
// even lose the focus and open the label to edit in the first place.
// -1 means we don't need to restore it to anywhere.
@@ -2824,8 +2841,6 @@ void LabelTrack::OnLabelAdded( const wxString &title, int pos )
// If the label is added during actions like import, then the
// mDrawCursor flag will be reset once the action is complete.
mDrawCursor = true;
mInitialCursorPos = mCurrentCursorPos = title.length();
}
@@ -2842,7 +2857,10 @@ int LabelTrack::AddLabel(const SelectedRegion &selectedRegion,
mLabels.insert(mLabels.begin() + pos, l);
OnLabelAdded( title, pos );
// wxWidgets will own the event object
QueueEvent( safenew LabelTrackEvent{
EVT_LABELTRACK_ADDITION, SharedPointer<LabelTrack>(), title, -1, pos
} );
return pos;
}
@@ -2850,7 +2868,24 @@ int LabelTrack::AddLabel(const SelectedRegion &selectedRegion,
void LabelTrack::DeleteLabel(int index)
{
wxASSERT((index < (int)mLabels.size()));
mLabels.erase(mLabels.begin() + index);
auto iter = mLabels.begin() + index;
const auto title = iter->title;
mLabels.erase(iter);
// wxWidgets will own the event object
QueueEvent( safenew LabelTrackEvent{
EVT_LABELTRACK_DELETION, SharedPointer<LabelTrack>(), title, index, -1
} );
}
void LabelTrack::OnLabelDeleted( LabelTrackEvent &e )
{
e.Skip();
if ( e.mpTrack.lock().get() != this )
return;
auto index = e.mFormerPosition;
// IF we've deleted the selected label
// THEN set no label selected.
if( mSelIndex== index )
@@ -2866,6 +2901,23 @@ void LabelTrack::DeleteLabel(int index)
}
}
void LabelTrack::OnLabelPermuted( LabelTrackEvent &e )
{
e.Skip();
if ( e.mpTrack.lock().get() != this )
return;
auto former = e.mFormerPosition;
auto present = e.mPresentPosition;
if ( mSelIndex == former )
mSelIndex = present;
else if ( former < mSelIndex && mSelIndex <= present )
-- mSelIndex;
else if ( former > mSelIndex && mSelIndex >= present )
++ mSelIndex;
}
wxBitmap & LabelTrack::GetGlyph( int i)
{
return theTheme.Bitmap( i + bmpLabelGlyph0);
@@ -3013,7 +3065,7 @@ static bool IsGoodLabelEditKey(const wxKeyEvent & evt)
/// This function is called often (whilst dragging a label)
/// We expect them to be very nearly in order, so insertion
/// sort (with a linear search) is a reasonable choice.
void LabelTrack::SortLabels( LabelTrackHit *pHit )
void LabelTrack::SortLabels()
{
const auto begin = mLabels.begin();
const auto nn = (int)mLabels.size();
@@ -3039,20 +3091,12 @@ void LabelTrack::SortLabels( LabelTrackHit *pHit )
begin + i + 1
);
// Various indices need to be updated with the moved items...
auto update = [=](int &index) {
if( index <= i ) {
if( index == i )
index = j;
else if( index >= j)
++index;
}
};
if ( pHit ) {
update( pHit->mMouseOverLabelLeft );
update( pHit->mMouseOverLabelRight );
}
update(mSelIndex);
// Let listeners update their stored indices
// wxWidgets will own the event object
QueueEvent( safenew LabelTrackEvent{
EVT_LABELTRACK_PERMUTED, SharedPointer<LabelTrack>(),
mLabels[j].title, i, j
} );
}
}