Audacity 3.2.0
SetTrackInfoCommand.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity - A Digital Audio Editor
4 Copyright 1999-2018 Audacity Team
5 License: wxwidgets
6
7 Dan Horgan
8 James Crook
9
10******************************************************************//*******************************************************************/
35
36
37#include "SetTrackInfoCommand.h"
38
39#include "CommandDispatch.h"
40#include "CommandManager.h"
41#include "../CommonCommandFlags.h"
42#include "LoadCommands.h"
43#include "Project.h"
44#include "../TrackPanelAx.h"
45#include "../TrackPanel.h"
46#include "../WaveTrack.h"
47#include "../prefs/WaveformSettings.h"
48#include "../prefs/SpectrogramSettings.h"
49#include "../Shuttle.h"
50#include "../ShuttleGui.h"
51#include "../tracks/playabletrack/wavetrack/ui/WaveTrackView.h"
52#include "../tracks/playabletrack/wavetrack/ui/WaveTrackViewConstants.h"
53#include "CommandContext.h"
54
56 mbPromptForTracks = true;
57 bIsSecondChannel = false;
58}
59
60//Define for the old scheme, where SetTrack defines its own track selection.
61//rather than using the current selection.
62//#define USE_OWN_TRACK_SELECTION
63
64
66{
67 static_cast<void>(&context);
68 static_cast<void>(&t);
69 return true;
70};
71
72template<bool Const>
74{
75 static_cast<void>(S);
76#ifdef USE_OWN_TRACK_SELECTION
77 S.OptionalY( bHasTrackIndex ).Define( mTrackIndex, wxT("Track"), 0, 0, 100 );
78 S.OptionalN( bHasChannelIndex ).Define( mChannelIndex, wxT("Channel"), 0, 0, 100 );
79#endif
80 return true;
81}
82
84 { return VisitSettings<false>(S); }
85
87 { return VisitSettings<true>(S); }
88
90{
91 static_cast<void>(S);
92#ifdef USE_OWN_TRACK_SELECTION
94 return;
95 S.AddSpace(0, 5);
96 S.StartMultiColumn(3, wxEXPAND);
97 {
98 S.SetStretchyCol( 2 );
99 S.Optional( bHasTrackIndex ).TieNumericTextBox( XO("Track Index:"), mTrackIndex );
100 S.Optional( bHasChannelIndex).TieNumericTextBox( XO("Channel Index:"), mChannelIndex );
101 }
102 S.EndMultiColumn();
103#endif
104}
105
107{
108 long i = 0;// track counter
109 long j = 0;// channel counter
110 auto &tracks = TrackList::Get( context.project );
111 for ( auto t : tracks.Leaders() )
112 {
113 auto channels = TrackList::Channels(t);
114 for ( auto channel : channels ) {
115 bool bThisTrack =
116#ifdef USE_OWN_TRACK_SELECTION
117 (bHasTrackIndex && (i==mTrackIndex)) ||
118 (bHasChannelIndex && (j==mChannelIndex ) ) ||
120#else
121 channel->GetSelected();
122#endif
123
124 if( bThisTrack ){
125 ApplyInner( context, channel );
126 }
127 ++j; // count all channels
128 }
129 ++i; // count groups of channels
130 }
131 return true;
132}
133
135{ XO("Set Track Status") };
136
138
139template<bool Const>
142 S.OptionalN( bHasTrackName ).Define( mTrackName, wxT("Name"), _("Unnamed") );
143 // There is also a select command. This is an alternative.
144 S.OptionalN( bHasSelected ).Define( bSelected, wxT("Selected"), false );
145 S.OptionalN( bHasFocused ).Define( bFocused, wxT("Focused"), false );
146 return true;
147};
148
150 { return VisitSettings<false>(S); }
151
153 { return VisitSettings<true>(S); }
154
156{
158 S.StartMultiColumn(3, wxEXPAND);
159 {
160 S.SetStretchyCol( 2 );
161 S.Optional( bHasTrackName ).TieTextBox( XXO("Name:"), mTrackName );
162 }
163 S.EndMultiColumn();
164 S.StartMultiColumn(2, wxEXPAND);
165 {
166 S.SetStretchyCol( 1 );
167 S.Optional( bHasSelected ).TieCheckBox( XXO("Selected"), bSelected );
168 S.Optional( bHasFocused ).TieCheckBox( XXO("Focused"), bFocused);
169 }
170 S.EndMultiColumn();
171}
172
174{
175 //auto wt = dynamic_cast<WaveTrack *>(t);
176 //auto pt = dynamic_cast<PlayableTrack *>(t);
177
178 // You can get some intriguing effects by setting R and L channels to
179 // different values.
180 if( bHasTrackName )
182
183 // In stereo tracks, both channels need selecting/deselecting.
184 if( bHasSelected )
186
187 // These ones don't make sense on the second channel of a stereo track.
188 if( !bIsSecondChannel ){
189 if( bHasFocused )
190 {
191 auto &trackFocus = TrackFocus::Get( context.project );
192 if( bFocused)
193 trackFocus.Set( t );
194 else if( t == trackFocus.Get() )
195 trackFocus.Set( nullptr );
196 }
197 }
198 return true;
199}
200
201
202
204{ XO("Set Track Audio") };
205
207
208template<bool Const>
211 S.OptionalN( bHasMute ).Define( bMute, wxT("Mute"), false );
212 S.OptionalN( bHasSolo ).Define( bSolo, wxT("Solo"), false );
213
214 S.OptionalN( bHasGain ).Define( mGain, wxT("Gain"), 0.0, -36.0, 36.0);
215 S.OptionalN( bHasPan ).Define( mPan, wxT("Pan"), 0.0, -100.0, 100.0);
216 return true;
217};
218
220 { return VisitSettings<false>(S); }
221
223 { return VisitSettings<true>(S); }
224
226{
228 S.StartMultiColumn(2, wxEXPAND);
229 {
230 S.SetStretchyCol( 1 );
231 S.Optional( bHasMute ).TieCheckBox( XXO("Mute"), bMute);
232 S.Optional( bHasSolo ).TieCheckBox( XXO("Solo"), bSolo);
233 }
234 S.EndMultiColumn();
235 S.StartMultiColumn(3, wxEXPAND);
236 {
237 S.SetStretchyCol( 2 );
238 S.Optional( bHasGain ).TieSlider( XXO("Gain:"), mGain, 36.0,-36.0);
239 S.Optional( bHasPan ).TieSlider( XXO("Pan:"), mPan, 100.0, -100.0);
240 }
241 S.EndMultiColumn();
242}
243
245{
246 static_cast<void>(context);
247 auto wt = dynamic_cast<WaveTrack *>(t);
248 auto pt = dynamic_cast<PlayableTrack *>(t);
249
250 if( wt && bHasGain )
251 wt->SetGain(DB_TO_LINEAR(mGain));
252 if( wt && bHasPan )
253 wt->SetPan(mPan/100.0);
254
255 // These ones don't make sense on the second channel of a stereo track.
256 if( !bIsSecondChannel ){
257 if( pt && bHasSolo )
258 pt->SetSolo(bSolo);
259 if( pt && bHasMute )
260 pt->SetMute(bMute);
261 }
262 return true;
263}
264
265
266
268{ XO("Set Track Visuals") };
269
271
273{
280
282{
283 { wxT("Color0"), XO("Color 0") },
284 { wxT("Color1"), XO("Color 1") },
285 { wxT("Color2"), XO("Color 2") },
286 { wxT("Color3"), XO("Color 3") },
287};
288
289
291{
296
298{
299 // These are acceptable dual purpose internal/visible names
300 { XO("Linear") },
301 /* i18n-hint: abbreviates decibels */
302 { XO("dB") },
303};
304
306{
312
314{
315 { XO("Reset") },
316 { wxT("Times2"), XO("Times 2") },
317 { XO("HalfWave") },
318};
319
321{
322 const auto &types = WaveTrackSubViewType::All();
323 auto result = transform_container< EnumValueSymbols >(
324 types, std::mem_fn( &WaveTrackSubView::Type::name ) );
325 result.push_back( WaveTrackViewConstants::MultiViewSymbol );
326 return result;
327}
328
329template<bool Const>
332 S.OptionalN( bHasHeight ).Define( mHeight, wxT("Height"), 120, 44, 2000 );
333
334 {
335 auto symbols = DiscoverSubViewTypes();
336 S.OptionalN( bHasDisplayType ).DefineEnum( mDisplayType, wxT("Display"), 0, symbols.data(), symbols.size() );
337 }
338
339 S.OptionalN( bHasScaleType ).DefineEnum( mScaleType, wxT("Scale"), kLinear, kScaleTypeStrings, nScaleTypes );
340 S.OptionalN( bHasColour ).DefineEnum( mColour, wxT("Color"), kColour0, kColourStrings, nColours );
341 S.OptionalN( bHasVZoom ).DefineEnum( mVZoom, wxT("VZoom"), kReset, kZoomTypeStrings, nZoomTypes );
342 S.OptionalN( bHasVZoomTop ).Define( mVZoomTop, wxT("VZoomHigh"), 1.0, -2.0, 2.0 );
343 S.OptionalN( bHasVZoomBottom ).Define( mVZoomBottom, wxT("VZoomLow"), -1.0, -2.0, 2.0 );
344
345 S.OptionalN( bHasUseSpecPrefs ).Define( bUseSpecPrefs, wxT("SpecPrefs"), false );
346 S.OptionalN( bHasSpectralSelect ).Define( bSpectralSelect, wxT("SpectralSel"),true );
347
349 S.OptionalN( bHasSpecColorScheme).DefineEnum( mSpecColorScheme,wxT("SpecColor"), SpectrogramSettings::csColorNew, schemes.data(), schemes.size());
350
351 return true;
352};
353
355 { return VisitSettings<false>(S); }
356
358 { return VisitSettings<true>(S); }
359
361{
363 S.StartMultiColumn(3, wxEXPAND);
364 {
365 S.SetStretchyCol( 2 );
366 S.Optional( bHasHeight ).TieNumericTextBox( XXO("Height:"), mHeight );
367 S.Optional( bHasColour ).TieChoice( XXO("Color:"), mColour,
369
370 {
371 auto symbols = DiscoverSubViewTypes();
372 auto typeNames = transform_container<TranslatableStrings>(
373 symbols, std::mem_fn( &EnumValueSymbol::Stripped ) );
374 S.Optional( bHasDisplayType ).TieChoice( XXO("Display:"), mDisplayType,
375 typeNames );
376 }
377
378 S.Optional( bHasScaleType ).TieChoice( XXO("Scale:"), mScaleType,
380 S.Optional( bHasVZoom ).TieChoice( XXO("VZoom:"), mVZoom,
382 S.Optional( bHasVZoomTop ).TieTextBox( XXO("VZoom Top:"), mVZoomTop );
383 S.Optional( bHasVZoomBottom ).TieTextBox( XXO("VZoom Bottom:"), mVZoomBottom );
384 }
385 S.EndMultiColumn();
386 S.StartMultiColumn(2, wxEXPAND);
387 {
388 S.SetStretchyCol( 1 );
389 S.Optional( bHasUseSpecPrefs ).TieCheckBox( XXO("Use Spectral Prefs"), bUseSpecPrefs );
390 S.Optional( bHasSpectralSelect ).TieCheckBox( XXO("Spectral Select"), bSpectralSelect);
391 }
392 S.EndMultiColumn();
393 S.StartMultiColumn(3, wxEXPAND);
394 {
395 S.SetStretchyCol( 2 );
397 S.Optional( bHasSpecColorScheme).TieChoice( XC("Sche&me", "spectrum prefs"), mSpecColorScheme,
398 Msgids( schemes.data(), schemes.size() ) );
399 }
400 S.EndMultiColumn();
401}
402
404{
405 static_cast<void>(context);
406 auto wt = dynamic_cast<WaveTrack *>(t);
407 //auto pt = dynamic_cast<PlayableTrack *>(t);
408 static const double ZOOMLIMIT = 0.001f;
409
410 // You can get some intriguing effects by setting R and L channels to
411 // different values.
412 if( wt && bHasColour )
414
415 if( t && bHasHeight )
417
418 if( wt && bHasDisplayType ) {
419 auto &view = WaveTrackView::Get( *wt );
420 auto &all = WaveTrackSubViewType::All();
421 if (mDisplayType < all.size())
422 view.SetDisplay( all[ mDisplayType ].id );
423 else {
424 view.SetMultiView( true );
425 view.SetDisplay( WaveTrackSubViewType::Default(), false );
426 }
427 }
428 if( wt && bHasScaleType )
429 wt->GetWaveformSettings().scaleType =
430 (mScaleType==kLinear) ?
433
434 if( wt && bHasVZoom ){
435 switch( mVZoom ){
436 default:
437 case kReset: wt->SetDisplayBounds(-1,1); break;
438 case kTimes2: wt->SetDisplayBounds(-2,2); break;
439 case kHalfWave: wt->SetDisplayBounds(0,1); break;
440 }
441 }
442
443 if ( wt && (bHasVZoomTop || bHasVZoomBottom) && !bHasVZoom){
444 float vzmin, vzmax;
445 wt->GetDisplayBounds(&vzmin, &vzmax);
446
447 if ( !bHasVZoomTop ){
448 mVZoomTop = vzmax;
449 }
450 if ( !bHasVZoomBottom ){
451 mVZoomBottom = vzmin;
452 }
453
454 // Can't use std::clamp until C++17
455 mVZoomTop = std::max(-2.0, std::min(mVZoomTop, 2.0));
456 mVZoomBottom = std::max(-2.0, std::min(mVZoomBottom, 2.0));
457
458 if (mVZoomBottom > mVZoomTop){
460 }
461 if ( mVZoomTop - mVZoomBottom < ZOOMLIMIT ){
462 double c = (mVZoomBottom + mVZoomTop) / 2;
463 mVZoomBottom = c - ZOOMLIMIT / 2.0;
464 mVZoomTop = c + ZOOMLIMIT / 2.0;
465 }
466 wt->SetDisplayBounds(mVZoomBottom, mVZoomTop);
467 auto &tp = TrackPanel::Get( context.project );
468 tp.UpdateVRulers();
469 }
470
471 if( wt && bHasUseSpecPrefs ){
472 wt->UseSpectralPrefs( bUseSpecPrefs );
473 }
474 if( wt && bHasSpectralSelect ){
475 wt->GetSpectrogramSettings().spectralSelection = bSpectralSelect;
476 }
477 if (wt && bHasSpecColorScheme) {
478 wt->GetSpectrogramSettings().colorScheme = (SpectrogramSettings::ColorScheme)mSpecColorScheme;
479 }
480
481 return true;
482}
483
484
486{ XO("Set Track") };
487
489
491{
495}
496
498 { return VisitSettings<false>(S); }
500 { return VisitSettings<true>(S); }
501
502namespace {
503using namespace MenuTable;
504
505// Register menu items
506
508 wxT("Optional/Extra/Part2/Scriptables1"),
509 Items( wxT(""),
510 // Note that the PLUGIN_SYMBOL must have a space between words,
511 // whereas the short-form used here must not.
512 // (So if you did write "Compare Audio" for the PLUGIN_SYMBOL name, then
513 // you would have to use "CompareAudio" here.)
514 Command( wxT("SetTrackStatus"), XXO("Set Track Status..."),
516 Command( wxT("SetTrackAudio"), XXO("Set Track Audio..."),
518 Command( wxT("SetTrackVisuals"), XXO("Set Track Visuals..."),
520 )
521};
522
524 wxT("Optional/Extra/Part2/Scriptables2"),
525 // Note that the PLUGIN_SYMBOL must have a space between words,
526 // whereas the short-form used here must not.
527 // (So if you did write "Compare Audio" for the PLUGIN_SYMBOL name, then
528 // you would have to use "CompareAudio" here.)
529 Command( wxT("SetTrack"), XXO("Set Track..."),
531};
532}
wxT("CloseDown"))
AttachedItem sAttachment1
AttachedItem sAttachment2
const ReservedCommandFlag & AudioIONotBusyFlag()
int min(int a, int b)
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define XC(s, c)
Definition: Internat.h:37
#define _(s)
Definition: Internat.h:75
#define DB_TO_LINEAR(x)
Definition: MemoryX.h:543
kColours
static const EnumValueSymbol kScaleTypeStrings[nScaleTypes]
static const EnumValueSymbol kZoomTypeStrings[nZoomTypes]
static EnumValueSymbols DiscoverSubViewTypes()
static const EnumValueSymbol kColourStrings[nColours]
TranslatableStrings Msgids(const EnumValueSymbol strings[], size_t nStrings)
Convenience function often useful when adding choice controls.
#define S(N)
Definition: ToChars.cpp:64
Subclass & Get(const RegisteredFactory &key)
Get reference to an attachment, creating on demand if not present, down-cast it to Subclass.
Definition: ClientData.h:309
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
const TranslatableString Stripped() const
AudioTrack subclass that can also be audibly replayed by the program.
Definition: Track.h:916
static const ComponentInterfaceSymbol Symbol
bool ApplyInner(const CommandContext &context, Track *t) override
bool VisitSettings(SettingsVisitorBase< Const > &S)
void PopulateOrExchange(ShuttleGui &S) override
bool VisitSettings(SettingsVisitorBase< Const > &S)
virtual bool ApplyInner(const CommandContext &context, Track *t)
bool Apply(const CommandContext &context) override
virtual void PopulateOrExchange(ShuttleGui &S) override
SetTrackStatusCommand mSetStatus
static const ComponentInterfaceSymbol Symbol
bool VisitSettings(SettingsVisitorBase< Const > &S)
SetTrackVisualsCommand mSetVisuals
SetTrackAudioCommand mSetAudio
void PopulateOrExchange(ShuttleGui &S) override
static const ComponentInterfaceSymbol Symbol
bool ApplyInner(const CommandContext &context, Track *t) override
bool VisitSettings(SettingsVisitorBase< Const > &S)
static const ComponentInterfaceSymbol Symbol
bool ApplyInner(const CommandContext &context, Track *t) override
void PopulateOrExchange(ShuttleGui &S) override
bool VisitSettings(SettingsVisitorBase< Const > &S)
Visitor of effect or command parameters. This is a base class with lots of virtual functions that do ...
Definition: Shuttle.h:115
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:628
static const EnumValueSymbols & GetColorSchemeNames()
Track * Get()
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:225
virtual void SetPan(float)
Definition: Track.h:485
virtual void SetSelected(bool s)
Definition: Track.cpp:87
void SetName(const wxString &n)
Definition: Track.cpp:79
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:486
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1541
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:230
void SetExpandedHeight(int height)
Definition: TrackView.cpp:172
static TrackView & Get(Track &)
Definition: TrackView.cpp:69
A Track that contains audio waveform data.
Definition: WaveTrack.h:57
void SetWaveColorIndex(int colorIndex)
Definition: WaveTrack.cpp:552
static WaveTrackView & Get(WaveTrack &track)
AUDACITY_DLL_API void OnAudacityCommand(const CommandContext &ctx)
std::unique_ptr< MenuItems > Items(const Identifier &internalName, Args &&... args)
std::unique_ptr< CommandItem > Command(const CommandID &name, const TranslatableString &label_in, void(Handler::*pmf)(const CommandContext &), CommandFlag flags, const CommandManager::Options &options={}, CommandHandlerFinder finder=FinderScope::DefaultFinder())
AUDACITY_DLL_API const EnumValueSymbol MultiViewSymbol
String identifier for a preference for one of each type of view.
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:752
BuiltinCommandsModule::Registration< SetTrackAudioCommand > reg2
BuiltinCommandsModule::Registration< SetTrackCommand > reg4
BuiltinCommandsModule::Registration< SetTrackStatusCommand > reg
BuiltinCommandsModule::Registration< SetTrackVisualsCommand > reg3
static const std::vector< WaveTrackSubViewType > & All()
Discover all registered types.
static Display Default()
Return a preferred type.