1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-10-21 14:02:57 +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 ){ bool SetClipCommand::DefineParams( ShuttleParams & S ){
wxArrayString colours( nColours, kColourStrings ); 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.OptionalY( bHasContainsTime ).Define( mContainsTime, wxT("At"), 0.0, 0.0, 100000.0 );
S.OptionalN( bHasColour ).DefineEnum( mColour, wxT("Color"), kColour0, colours ); S.OptionalN( bHasColour ).DefineEnum( mColour, wxT("Color"), kColour0, colours );
// Allowing a negative start time is not a mistake. // Allowing a negative start time is not a mistake.
@@ -67,8 +65,6 @@ void SetClipCommand::PopulateOrExchange(ShuttleGui & S)
S.StartMultiColumn(3, wxALIGN_CENTER); 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( bHasContainsTime).TieNumericTextBox( _("At:"), mContainsTime );
S.Optional( bHasColour ).TieChoice( _("Colour:"), mColour, &colours ); S.Optional( bHasColour ).TieChoice( _("Colour:"), mColour, &colours );
S.Optional( bHasT0 ).TieNumericTextBox( _("Start:"), mT0 ); S.Optional( bHasT0 ).TieNumericTextBox( _("Start:"), mT0 );
@@ -76,53 +72,33 @@ void SetClipCommand::PopulateOrExchange(ShuttleGui & S)
S.EndMultiColumn(); S.EndMultiColumn();
} }
bool SetClipCommand::Apply(const CommandContext & context) bool SetClipCommand::ApplyInner( const CommandContext & context, Track * t )
{ {
TrackList *tracks = context.GetProject()->GetTracks(); if( t->GetKind() != Track::Wave)
TrackListIterator iter(tracks); return true;
Track *t = iter.First();
WaveClip * pClip = NULL; WaveTrack *waveTrack = static_cast<WaveTrack*>(t);
int i=0; wxASSERT( waveTrack );
int j=0; 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; if( bHasColour )
while (t ) pClip->SetColourIndex(mColour);
{ // No validation of overlap yet. We assume the user is sensible!
bool bThisTrack = if( bHasT0 )
(bHasTrackIndex && (i==mTrackIndex)) || pClip->SetOffset(mT0);
(bHasChannelIndex && (j==mChannelIndex ) ) || // \todo Use SetClip to move a clip between tracks too.
(!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 =
!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; return true;
} }

View File

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

View File

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

View File

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

View File

@@ -48,15 +48,22 @@ SetTrackBase::SetTrackBase(){
mbPromptForTracks = true; 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 ) bool SetTrackBase::DefineParams( ShuttleParams & S )
{ {
#ifdef USE_OWN_TRACK_SELECTION
S.OptionalY( bHasTrackIndex ).Define( mTrackIndex, wxT("Track"), 0, 0, 100 ); S.OptionalY( bHasTrackIndex ).Define( mTrackIndex, wxT("Track"), 0, 0, 100 );
S.OptionalN( bHasChannelIndex ).Define( mChannelIndex, wxT("Channel"), 0, 0, 100 ); S.OptionalN( bHasChannelIndex ).Define( mChannelIndex, wxT("Channel"), 0, 0, 100 );
#endif
return true; return true;
} }
void SetTrackBase::PopulateOrExchange(ShuttleGui & S) void SetTrackBase::PopulateOrExchange(ShuttleGui & S)
{ {
#ifdef USE_OWN_TRACK_SELECTION
if( !mbPromptForTracks ) if( !mbPromptForTracks )
return; return;
S.AddSpace(0, 5); S.AddSpace(0, 5);
@@ -67,6 +74,7 @@ void SetTrackBase::PopulateOrExchange(ShuttleGui & S)
S.Optional( bHasChannelIndex).TieNumericTextBox( _("Channel Index:"), mChannelIndex ); S.Optional( bHasChannelIndex).TieNumericTextBox( _("Channel Index:"), mChannelIndex );
} }
S.EndMultiColumn(); S.EndMultiColumn();
#endif
} }
bool SetTrackBase::Apply(const CommandContext & context ) bool SetTrackBase::Apply(const CommandContext & context )
@@ -79,9 +87,13 @@ bool SetTrackBase::Apply(const CommandContext & context )
while (t ) while (t )
{ {
bool bThisTrack = bool bThisTrack =
#ifdef USE_OWN_TRACK_SELECTION
(bHasTrackIndex && (i==mTrackIndex)) || (bHasTrackIndex && (i==mTrackIndex)) ||
(bHasChannelIndex && (j==mChannelIndex ) ) || (bHasChannelIndex && (j==mChannelIndex ) ) ||
(!bHasTrackIndex && !bHasChannelIndex) ; (!bHasTrackIndex && !bHasChannelIndex) ;
#else
t->GetSelected();
#endif
if( bThisTrack ){ if( bThisTrack ){
ApplyInner( context, t ); ApplyInner( context, t );
@@ -95,8 +107,6 @@ bool SetTrackBase::Apply(const CommandContext & context )
return true; return true;
} }
bool SetTrackStatusCommand::DefineParams( ShuttleParams & S ){ bool SetTrackStatusCommand::DefineParams( ShuttleParams & S ){
SetTrackBase::DefineParams( S ); SetTrackBase::DefineParams( S );
S.OptionalN( bHasTrackName ).Define( mTrackName, wxT("Name"), wxT("Unnamed") ); S.OptionalN( bHasTrackName ).Define( mTrackName, wxT("Name"), wxT("Unnamed") );