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:
@@ -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
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user