1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-30 15:39:27 +02:00

Use track selection for SetTrack, SetClip and SetEnvelope

These commands now have shorter dialogs.
Also fixed SetEnvelope optionals, which were not being honoured.
This commit is contained in:
James Crook 2018-03-19 11:59:33 +00:00
parent e661c7da49
commit 0a7d0068ec
5 changed files with 61 additions and 112 deletions

View File

@ -49,8 +49,6 @@ static const wxString kColourStrings[nColours] =
bool SetClipCommand::DefineParams( ShuttleParams & S ){
wxArrayString colours( nColours, kColourStrings );
S.OptionalY( bHasTrackIndex ).Define( mTrackIndex, wxT("Track"), 0, 0, 100 );
S.OptionalN( bHasChannelIndex ).Define( mChannelIndex, wxT("Channel"), 0, 0, 100 );
S.OptionalY( bHasContainsTime ).Define( mContainsTime, wxT("At"), 0.0, 0.0, 100000.0 );
S.OptionalN( bHasColour ).DefineEnum( mColour, wxT("Color"), kColour0, colours );
// Allowing a negative start time is not a mistake.
@ -67,8 +65,6 @@ void SetClipCommand::PopulateOrExchange(ShuttleGui & S)
S.StartMultiColumn(3, wxALIGN_CENTER);
{
S.Optional( bHasTrackIndex ).TieNumericTextBox( _("Track Index:"), mTrackIndex );
S.Optional( bHasChannelIndex).TieNumericTextBox( _("Channel Index:"), mChannelIndex );
S.Optional( bHasContainsTime).TieNumericTextBox( _("At:"), mContainsTime );
S.Optional( bHasColour ).TieChoice( _("Colour:"), mColour, &colours );
S.Optional( bHasT0 ).TieNumericTextBox( _("Start:"), mT0 );
@ -76,53 +72,33 @@ void SetClipCommand::PopulateOrExchange(ShuttleGui & S)
S.EndMultiColumn();
}
bool SetClipCommand::Apply(const CommandContext & context)
bool SetClipCommand::ApplyInner( const CommandContext & context, Track * t )
{
TrackList *tracks = context.GetProject()->GetTracks();
TrackListIterator iter(tracks);
Track *t = iter.First();
WaveClip * pClip = NULL;
int i=0;
int j=0;
if( t->GetKind() != Track::Wave)
return true;
WaveTrack *waveTrack = static_cast<WaveTrack*>(t);
wxASSERT( waveTrack );
WaveClipPointers ptrs( waveTrack->SortedClipArray());
for(auto it = ptrs.begin(); (it != ptrs.end()); it++ ){
WaveClip * pClip = *it;
bool bFound =
!bHasContainsTime || (
( pClip->GetStartTime() <= mContainsTime ) &&
( pClip->GetEndTime() >= mContainsTime )
);
if( bFound )
{
// Inside this IF is where we actually apply the command
bool bIsSecondChannel = false;
while (t )
{
bool bThisTrack =
(bHasTrackIndex && (i==mTrackIndex)) ||
(bHasChannelIndex && (j==mChannelIndex ) ) ||
(!bHasTrackIndex && !bHasChannelIndex) ;
if( bHasColour )
pClip->SetColourIndex(mColour);
// No validation of overlap yet. We assume the user is sensible!
if( bHasT0 )
pClip->SetOffset(mT0);
// \todo Use SetClip to move a clip between tracks too.
if( bThisTrack && (t->GetKind() == Track::Wave)) {
bool bFound = false;
WaveTrack *waveTrack = static_cast<WaveTrack*>(t);
WaveClipPointers ptrs( waveTrack->SortedClipArray());
for(auto it = ptrs.begin(); (it != ptrs.end()); it++ ){
pClip = *it;
bFound =
!bHasContainsTime || (
( pClip->GetStartTime() <= mContainsTime ) &&
( pClip->GetEndTime() >= mContainsTime )
);
if( bFound )
{
// Inside this IF is where we actually apply the command
if( bHasColour )
pClip->SetColourIndex(mColour);
// No validation of overlap yet. We assume the user is sensible!
if( bHasT0 )
pClip->SetOffset(mT0);
// \todo Use SetClip to move a clip between tracks too.
}
}
}
bIsSecondChannel = t->GetLinked();
if( !bIsSecondChannel )
++i;
j++;
t = iter.Next();
}
return true;
}

View File

@ -18,10 +18,11 @@
#include "Command.h"
#include "CommandType.h"
#include "SetTrackInfoCommand.h"
#define SET_CLIP_PLUGIN_SYMBOL XO("Set Clip")
class SetClipCommand : public AudacityCommand
class SetClipCommand : public SetTrackBase
{
public:
SetClipCommand();
@ -33,19 +34,14 @@ public:
// AudacityCommand overrides
wxString ManualPage() override {return wxT("Extra_Menu:_Tools#set_clip");};
bool Apply(const CommandContext & context) override;
bool ApplyInner( const CommandContext & context, Track * t ) override;
public:
int mTrackIndex;
int mChannelIndex;
double mContainsTime;
int mColour;
double mT0;
// For tracking optional parameters.
bool bHasTrackIndex;
bool bHasChannelIndex;
bool bHasContainsTime;
bool bHasColour;
bool bHasT0;

View File

@ -32,8 +32,6 @@ SetEnvelopeCommand::SetEnvelopeCommand()
bool SetEnvelopeCommand::DefineParams( ShuttleParams & S ){
S.OptionalY( bHasTrackIndex ).Define( mTrackIndex, wxT("Track"), 0, 0, 100 );
S.OptionalN( bHasChannelIndex ).Define( mChannelIndex, wxT("Channel"), 0, 0, 100 );
S.OptionalY( bHasT ).Define( mT, wxT("Time"), 0.0, 0.0, 100000.0);
S.OptionalY( bHasV ).Define( mV, wxT("Value"), 1.0, 0.0, 2.0);
S.OptionalN( bHasDelete ).Define( mbDelete, wxT("Delete"), false );
@ -46,8 +44,6 @@ void SetEnvelopeCommand::PopulateOrExchange(ShuttleGui & S)
S.StartMultiColumn(3, wxALIGN_CENTER);
{
S.Optional( bHasTrackIndex ).TieNumericTextBox( _("Track Index:"), mTrackIndex );
S.Optional( bHasChannelIndex).TieNumericTextBox( _("Channel Index:"), mChannelIndex );
S.Optional( bHasT ).TieNumericTextBox( _("Time:"), mT );
S.Optional( bHasV ).TieNumericTextBox( _("Value:"), mV );
S.Optional( bHasDelete ).TieCheckBox( _("Delete:"), mbDelete );
@ -55,54 +51,29 @@ void SetEnvelopeCommand::PopulateOrExchange(ShuttleGui & S)
S.EndMultiColumn();
}
bool SetEnvelopeCommand::Apply(const CommandContext & context)
bool SetEnvelopeCommand::ApplyInner( const CommandContext & context, Track * t )
{
// \todo we have similar code for finding the nth Label, Clip, Track etc.
// this code could be put in subroutines/reduced.
if( (t->GetKind() != Track::Wave))
return true;
TrackList *tracks = context.GetProject()->GetTracks();
TrackListIterator iter(tracks);
Track *t = iter.First();
WaveClip * pClip = NULL;
int i=0;
int j=0;
bool bIsSecondChannel = false;
while (t )
{
bool bThisTrack =
(bHasTrackIndex && (i==mTrackIndex)) ||
(bHasChannelIndex && (j==mChannelIndex ) ) ||
(!bHasTrackIndex && !bHasChannelIndex) ;
if( bThisTrack && (t->GetKind() == Track::Wave)) {
bool bFound = false;
WaveTrack *waveTrack = static_cast<WaveTrack*>(t);
WaveClipPointers ptrs( waveTrack->SortedClipArray());
for(auto it = ptrs.begin(); (it != ptrs.end()); it++ ){
pClip = *it;
bFound =
!bHasT || (
( pClip->GetStartTime() <= mT) &&
( pClip->GetEndTime() >= mT )
);
if( bFound )
{
// Inside this IF is where we actually apply the command
Envelope* pEnv = pClip->GetEnvelope();
if( mbDelete )
pEnv->mEnv.clear();
else
pEnv->InsertOrReplace( mT, mV );
}
}
WaveTrack *waveTrack = static_cast<WaveTrack*>(t);
WaveClipPointers ptrs( waveTrack->SortedClipArray());
for(auto it = ptrs.begin(); (it != ptrs.end()); it++ ){
WaveClip * pClip = *it;
bool bFound =
!bHasT || (
( pClip->GetStartTime() <= mT) &&
( pClip->GetEndTime() >= mT )
);
if( bFound )
{
// Inside this IF is where we actually apply the command
Envelope* pEnv = pClip->GetEnvelope();
if( bHasDelete && mbDelete )
pEnv->mEnv.clear();
if( bHasT && bHasV )
pEnv->InsertOrReplace( mT, mV );
}
bIsSecondChannel = t->GetLinked();
if( !bIsSecondChannel )
++i;
j++;
t = iter.Next();
}
return true;

View File

@ -18,10 +18,11 @@
#include "Command.h"
#include "CommandType.h"
#include "SetTrackInfoCommand.h"
#define SET_ENVELOPE_PLUGIN_SYMBOL XO("Set Envelope")
class SetEnvelopeCommand : public AudacityCommand
class SetEnvelopeCommand : public SetTrackBase
{
public:
SetEnvelopeCommand();
@ -33,18 +34,13 @@ public:
// AudacityCommand overrides
wxString ManualPage() override {return wxT("Extra_Menu:_Tools#set_label");};
bool Apply(const CommandContext & context) override;
bool ApplyInner( const CommandContext & context, Track * t ) override;
public:
int mTrackIndex;
int mChannelIndex;
double mT;
double mV;
bool mbDelete;
bool bHasTrackIndex;
bool bHasChannelIndex;
bool bHasT;
bool bHasV;
bool bHasDelete;

View File

@ -48,15 +48,22 @@ SetTrackBase::SetTrackBase(){
mbPromptForTracks = true;
}
//Define for the old scheme, where SetTrack defines its own track selection.
//rather than using the current selection.
//#define USE_OWN_TRACK_SELECTION
bool SetTrackBase::DefineParams( ShuttleParams & S )
{
#ifdef USE_OWN_TRACK_SELECTION
S.OptionalY( bHasTrackIndex ).Define( mTrackIndex, wxT("Track"), 0, 0, 100 );
S.OptionalN( bHasChannelIndex ).Define( mChannelIndex, wxT("Channel"), 0, 0, 100 );
#endif
return true;
}
void SetTrackBase::PopulateOrExchange(ShuttleGui & S)
{
#ifdef USE_OWN_TRACK_SELECTION
if( !mbPromptForTracks )
return;
S.AddSpace(0, 5);
@ -67,6 +74,7 @@ void SetTrackBase::PopulateOrExchange(ShuttleGui & S)
S.Optional( bHasChannelIndex).TieNumericTextBox( _("Channel Index:"), mChannelIndex );
}
S.EndMultiColumn();
#endif
}
bool SetTrackBase::Apply(const CommandContext & context )
@ -79,9 +87,13 @@ bool SetTrackBase::Apply(const CommandContext & context )
while (t )
{
bool bThisTrack =
#ifdef USE_OWN_TRACK_SELECTION
(bHasTrackIndex && (i==mTrackIndex)) ||
(bHasChannelIndex && (j==mChannelIndex ) ) ||
(!bHasTrackIndex && !bHasChannelIndex) ;
#else
t->GetSelected();
#endif
if( bThisTrack ){
ApplyInner( context, t );
@ -95,8 +107,6 @@ bool SetTrackBase::Apply(const CommandContext & context )
return true;
}
bool SetTrackStatusCommand::DefineParams( ShuttleParams & S ){
SetTrackBase::DefineParams( S );
S.OptionalN( bHasTrackName ).Define( mTrackName, wxT("Name"), wxT("Unnamed") );