Audacity  3.0.3
WaveTrackControls.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 WaveTrackControls.cpp
6 
7 Paul Licameli split from TrackPanel.cpp
8 
9 **********************************************************************/
10 
11 
12 #include "WaveTrackControls.h"
13 
14 #include "../../ui/PlayableTrackButtonHandles.h"
15 #include "WaveTrackSliderHandles.h"
16 
17 #include "WaveTrackView.h"
18 #include "WaveTrackViewConstants.h"
19 #include "../../../../AudioIOBase.h"
20 #include "../../../../CellularPanel.h"
21 #include "../../../../Project.h"
22 #include "../../../../ProjectAudioIO.h"
23 #include "../../../../ProjectHistory.h"
24 #include "../../../../RefreshCode.h"
25 #include "../../../../ShuttleGui.h"
26 #include "../../../../TrackArtist.h"
27 #include "../../../../TrackPanel.h"
28 #include "../../../../TrackPanelAx.h"
29 #include "../../../../TrackPanelMouseEvent.h"
30 #include "../../../../WaveTrack.h"
31 #include "../../../../effects/RealtimeEffectManager.h"
32 #include "../../../../prefs/PrefsDialog.h"
33 #include "../../../../prefs/ThemePrefs.h"
34 #include "../../../../widgets/AudacityMessageBox.h"
35 #include "widgets/ProgressDialog.h"
36 #include "UserException.h"
37 #include "Identifier.h"
38 
39 #include <wx/app.h>
40 #include <wx/combobox.h>
41 #include <wx/frame.h>
42 #include <wx/sizer.h>
43 
45 {
46 }
47 
48 
49 std::vector<UIHandlePtr> WaveTrackControls::HitTest
50 (const TrackPanelMouseState & st,
51  const AudacityProject *pProject)
52 {
53  // Hits are mutually exclusive, results single
54  const wxMouseState &state = st.state;
55  const wxRect &rect = st.rect;
56  if (state.ButtonIsDown(wxMOUSE_BTN_LEFT)) {
57  auto track = FindTrack();
58  std::vector<UIHandlePtr> results;
59  auto result = [&]{
60  UIHandlePtr result;
61  if (NULL != (result = MuteButtonHandle::HitTest(
62  mMuteHandle, state, rect, pProject, track)))
63  return result;
64 
65  if (NULL != (result = SoloButtonHandle::HitTest(
66  mSoloHandle, state, rect, pProject, track)))
67  return result;
68 
69  if (NULL != (result = GainSliderHandle::HitTest(
70  mGainHandle, state, rect, track)))
71  return result;
72 
73  if (NULL != (result = PanSliderHandle::HitTest(
74  mPanHandle, state, rect, track)))
75  return result;
76 
77  return result;
78  }();
79  if (result) {
80  results.push_back(result);
81  return results;
82  }
83  }
84 
85  return PlayableTrackControls::HitTest(st, pProject);
86 }
87 
89 {
90  return *static_cast< WaveTrack* >( mpData->pTrack );
91 };
92 
93 enum {
95 
96  OnRate8ID = 30000, // <---
97  OnRate11ID, // |
98  OnRate16ID, // |
99  OnRate22ID, // |
101  OnRate48ID, // | Leave these in order
109  // |
110  On16BitID, // |
111  On24BitID, // |
112  OnFloatID, // <---
113 
115 
117 
121 
123 
127 
129 
130  // Range of ids for registered items -- keep this last!
132 };
133 
134 
135 namespace {
136 using ValueFinder = std::function< int( WaveTrack& ) >;
137 
138 // A function that makes functions that check and enable sub-menu items,
139 // parametrized by how you get the relevant value from a track's settings
140 template< typename Table >
142 {
143  return [findValue]( PopupMenuHandler &handler, wxMenu &menu, int id ){
144  auto pData = static_cast<Table&>( handler ).mpData;
145  const auto pTrack = static_cast<WaveTrack*>(pData->pTrack);
146  auto &project = pData->project;
147  bool unsafe = ProjectAudioIO::Get( project ).IsAudioActive();
148 
149  menu.Check( id, id == findValue( *pTrack ) );
150  menu.Enable( id, !unsafe );
151  };
152 };
153 }
154 
155 
156 //=============================================================================
157 // Table class for a sub-menu
159 {
161  : PopupMenuTable{ "SampleFormat", XO("&Format") }
162  {}
164 
165  static FormatMenuTable &Instance();
166 
167  void InitUserData(void *pUserData) override;
168 
169  void DestroyMenu() override
170  {
171  mpData = NULL;
172  }
173 
175 
176  static int IdOfFormat(int format);
177 
178  void OnFormatChange(wxCommandEvent & event);
179 };
180 
182 {
183  static FormatMenuTable instance;
184  return instance;
185 }
186 
187 void FormatMenuTable::InitUserData(void *pUserData)
188 {
189  mpData = static_cast<PlayableTrackControls::InitMenuData*>(pUserData);
190 }
191 
192 
194  static const auto fn = initFn< FormatMenuTable >(
195  []( WaveTrack &track ){
196  return IdOfFormat( track.GetSampleFormat() );
197  }
198  );
199 
201  GetSampleFormatStr(int16Sample), POPUP_MENU_FN( OnFormatChange ), fn );
203  GetSampleFormatStr( int24Sample), POPUP_MENU_FN( OnFormatChange ), fn );
205  GetSampleFormatStr(floatSample), POPUP_MENU_FN( OnFormatChange ), fn );
206 
208 
209 int FormatMenuTable::IdOfFormat(int format)
211 {
212  switch (format) {
213  case int16Sample:
214  return On16BitID;
215  case int24Sample:
216  return On24BitID;
217  case floatSample:
218  return OnFloatID;
219  default:
220  // ERROR -- should not happen
221  wxASSERT(false);
222  break;
223  }
224  return OnFloatID;// Compiler food.
225 }
226 
229 void FormatMenuTable::OnFormatChange(wxCommandEvent & event)
230 {
231  int id = event.GetId();
232  wxASSERT(id >= On16BitID && id <= OnFloatID);
233  const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
234 
235  sampleFormat newFormat = int16Sample;
236 
237  switch (id) {
238  case On16BitID:
239  newFormat = int16Sample;
240  break;
241  case On24BitID:
242  newFormat = int24Sample;
243  break;
244  case OnFloatID:
245  newFormat = floatSample;
246  break;
247  default:
248  // ERROR -- should not happen
249  wxASSERT(false);
250  break;
251  }
252  if (newFormat == pTrack->GetSampleFormat())
253  return; // Nothing to do.
254 
255  AudacityProject *const project = &mpData->project;
256 
257  ProgressDialog progress{ XO("Changing sample format"),
258  XO("Processing... 0%%"),
260 
261  sampleCount totalSamples{ 0 };
262  for (const auto& channel : TrackList::Channels(pTrack))
263  totalSamples += channel->GetNumSamples();
264  sampleCount processedSamples{ 0 };
265 
266  // Below is the lambda function that is passed along the call chain to
267  // the Sequence::ConvertToSampleFormat. This callback function is used
268  // to report the conversion progress and update the progress dialog.
269  auto progressUpdate = [&progress, &totalSamples, &processedSamples]
270  (size_t newlyProcessedCount)->void
271  {
272  processedSamples += newlyProcessedCount;
273  double d_processed = processedSamples.as_double();
274  double d_total = totalSamples.as_double();
275  int percentage{ static_cast<int>((d_processed / d_total) * 100) };
276 
277  auto progressStatus = progress.Update(d_processed, d_total,
278  XO("Processing... %i%%").Format(percentage));
279 
280  if (progressStatus != ProgressResult::Success)
281  throw UserException{};
282  };
283 
284  for (auto channel : TrackList::Channels(pTrack))
285  channel->ConvertToSampleFormat(
286  newFormat, progressUpdate);
287 
288  ProjectHistory::Get( *project )
289  /* i18n-hint: The strings name a track and a format */
290  .PushState(XO("Changed '%s' to %s")
291  .Format( pTrack->GetName(), GetSampleFormatStr(newFormat) ),
292  XO("Format Change"));
293 
294  using namespace RefreshCode;
296 }
297 
298 
299 //=============================================================================
300 // Table class for a sub-menu
302 {
304  : PopupMenuTable{ "SampleRate", XO("Rat&e") }
305  {}
307 
308  static RateMenuTable &Instance();
309 
310  void InitUserData(void *pUserData) override;
311 
312  void DestroyMenu() override
313  {
314  mpData = NULL;
315  }
316 
318 
319  static int IdOfRate(int rate);
320  void SetRate(WaveTrack * pTrack, double rate);
321 
322  void OnRateChange(wxCommandEvent & event);
323  void OnRateOther(wxCommandEvent & event);
324 };
325 
327 {
328  static RateMenuTable instance;
329  return instance;
330 }
331 
332 void RateMenuTable::InitUserData(void *pUserData)
333 {
334  mpData = static_cast<PlayableTrackControls::InitMenuData*>(pUserData);
335 }
336 
337 // Because of Bug 1780 we can't use AppendRadioItem
338 // If we did, we'd get no message when clicking on Other...
339 // when it is already selected.
341  static const auto fn = initFn< RateMenuTable >(
342  []( WaveTrack &track ){
343  return IdOfRate( (int)track.GetRate() );
344  }
345  );
346 
347  AppendCheckItem( "8000", OnRate8ID, XXO("8000 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
348  AppendCheckItem( "11025", OnRate11ID, XXO("11025 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
349  AppendCheckItem( "16000", OnRate16ID, XXO("16000 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
350  AppendCheckItem( "22050", OnRate22ID, XXO("22050 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
351  AppendCheckItem( "44100", OnRate44ID, XXO("44100 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
352  AppendCheckItem( "48000", OnRate48ID, XXO("48000 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
353  AppendCheckItem( "88200", OnRate88ID, XXO("88200 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
354  AppendCheckItem( "96000", OnRate96ID, XXO("96000 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
355  AppendCheckItem( "176400", OnRate176ID, XXO("176400 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
356  AppendCheckItem( "192000", OnRate192ID, XXO("192000 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
357  AppendCheckItem( "352800", OnRate352ID, XXO("352800 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
358  AppendCheckItem( "384000", OnRate384ID, XXO("384000 Hz"), POPUP_MENU_FN( OnRateChange ), fn );
359  AppendCheckItem( "Other", OnRateOtherID, XXO("&Other..."), POPUP_MENU_FN( OnRateOther ), fn );
360 
362 
363 const int nRates = 12;
364 
367 static int gRates[nRates] = { 8000, 11025, 16000, 22050, 44100, 48000, 88200, 96000,
368 176400, 192000, 352800, 384000 };
369 
372 {
373  for (int i = 0; i<nRates; i++) {
374  if (gRates[i] == rate)
375  return i + OnRate8ID;
376  }
377  return OnRateOtherID;
378 }
379 
382 void RateMenuTable::SetRate(WaveTrack * pTrack, double rate)
383 {
384  AudacityProject *const project = &mpData->project;
385  for (auto channel : TrackList::Channels(pTrack))
386  channel->SetRate(rate);
387 
388  // Separate conversion of "rate" enables changing the decimals without affecting i18n
389  wxString rateString = wxString::Format(wxT("%.3f"), rate);
390  ProjectHistory::Get( *project )
391  /* i18n-hint: The string names a track */
392  .PushState(XO("Changed '%s' to %s Hz")
393  .Format( pTrack->GetName(), rateString),
394  XO("Rate Change"));
395 }
396 
399 void RateMenuTable::OnRateChange(wxCommandEvent & event)
400 {
401  int id = event.GetId();
402  wxASSERT(id >= OnRate8ID && id <= OnRate384ID);
403  const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
404 
405  SetRate(pTrack, gRates[id - OnRate8ID]);
406 
407  using namespace RefreshCode;
409 }
410 
411 void RateMenuTable::OnRateOther(wxCommandEvent &)
412 {
413  const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
414 
415  int newRate;
416 
419  while (true)
420  {
421  wxDialogWrapper dlg(mpData->pParent, wxID_ANY, XO("Set Rate"));
422  dlg.SetName();
423  ShuttleGui S(&dlg, eIsCreating);
424  wxString rate;
425  wxComboBox *cb;
426 
427  rate.Printf(wxT("%ld"), lrint(pTrack->GetRate()));
428 
429  wxArrayStringEx rates{
430  wxT("8000") ,
431  wxT("11025") ,
432  wxT("16000") ,
433  wxT("22050") ,
434  wxT("44100") ,
435  wxT("48000") ,
436  wxT("88200") ,
437  wxT("96000") ,
438  wxT("176400") ,
439  wxT("192000") ,
440  wxT("352800") ,
441  wxT("384000") ,
442  };
443 
444  S.StartVerticalLay(true);
445  {
446  S.SetBorder(10);
447  S.StartHorizontalLay(wxEXPAND, false);
448  {
449  cb = S.AddCombo(XXO("New sample rate (Hz):"),
450  rate,
451  rates);
452 #if defined(__WXMAC__)
453  // As of wxMac-2.8.12, setting manually is required
454  // to handle rates not in the list. See: Bug #427
455  cb->SetValue(rate);
456 #endif
457  }
458  S.EndHorizontalLay();
459  S.AddStandardButtons();
460  }
461  S.EndVerticalLay();
462 
463  dlg.SetClientSize(dlg.GetSizer()->CalcMin());
464  dlg.Center();
465 
466  if (dlg.ShowModal() != wxID_OK)
467  {
468  return; // user cancelled dialog
469  }
470 
471  long lrate;
472  if (cb->GetValue().ToLong(&lrate) && lrate >= 1 && lrate <= 1000000)
473  {
474  newRate = (int)lrate;
475  break;
476  }
477 
479  XO("The entered value is invalid"),
480  XO("Error"),
481  wxICON_ERROR,
482  mpData->pParent);
483  }
484 
485  SetRate(pTrack, newRate);
486 
487  using namespace RefreshCode;
489 }
490 
491 static const auto MenuPathStart = wxT("WaveTrackMenu");
492 
493 //=============================================================================
494 // Class defining common command handlers for mono and stereo tracks
496  : ComputedPopupMenuTable< WaveTrackMenuTable, WaveTrackPopupMenuTable >
497 {
498  static WaveTrackMenuTable &Instance();
499 
502  MenuPathStart }
503  {
504  mNextId = FirstAttachedItemId;
505  }
506 
507  void InitUserData(void *pUserData) override;
508 
509  void DestroyMenu() override
510  {
511  //mpData = nullptr;
512  }
513 
515 
516  void OnMultiView(wxCommandEvent & event);
517  void OnSetDisplay(wxCommandEvent & event);
518 
519  void OnChannelChange(wxCommandEvent & event);
520  void OnMergeStereo(wxCommandEvent & event);
521 
522  // TODO: more-than-two-channels
523  // How should we define generalized channel manipulation operations?
524  void SplitStereo(bool stereo);
525 
526  void OnSwapChannels(wxCommandEvent & event);
527  void OnSplitStereo(wxCommandEvent & event);
528  void OnSplitStereoMono(wxCommandEvent & event);
529 };
530 
532 {
533  static WaveTrackMenuTable instance;
534  return instance;
535 }
536 
537 void WaveTrackMenuTable::InitUserData(void *pUserData)
538 {
539  mpData = static_cast<PlayableTrackControls::InitMenuData*>(pUserData);
540 }
541 
542 static std::vector<WaveTrackSubViewType> AllTypes()
543 {
544  auto result = WaveTrackSubViewType::All();
545  if ( result.size() > reserveDisplays ) {
546  wxASSERT( false );
547  result.resize( reserveDisplays );
548  }
549  return result;
550 }
551 
553  // Functions usable in callbacks to check and disable items
554  static const auto isMono =
555  []( PopupMenuHandler &handler ) -> bool {
556  auto &track =
557  static_cast< WaveTrackMenuTable& >( handler ).FindWaveTrack();
558  return 1 == TrackList::Channels( &track ).size();
559  };
560 
561  static const auto isUnsafe =
562  []( PopupMenuHandler &handler ) -> bool {
563  auto &project =
564  static_cast< WaveTrackMenuTable& >( handler ).mpData->project;
566  ProjectAudioIO::Get( project ).IsAudioActive();
567  };
568 
569  BeginSection( "SubViews" );
570  // Multi-view check mark item, if more than one track sub-view type is
571  // known
572  Append( []( My &table ) -> Registry::BaseItemPtr {
573  if ( WaveTrackSubViews::slots() > 1 )
574  return std::make_unique<Entry>(
575  "MultiView", Entry::CheckItem, OnMultiViewID, XXO("&Multi-view"),
576  POPUP_MENU_FN( OnMultiView ),
577  table,
578  []( PopupMenuHandler &handler, wxMenu &menu, int id ){
579  auto &table = static_cast< WaveTrackMenuTable& >( handler );
580  auto &track = table.FindWaveTrack();
581  const auto &view = WaveTrackView::Get( track );
582  menu.Check( id, view.GetMultiView() );
583  } );
584  else
585  return nullptr;
586  } );
587 
588  // Append either a checkbox or radio item for each sub-view.
589  // Radio buttons if in single-view mode, else checkboxes
590  int id = OnSetDisplayId;
591  for ( const auto &type : AllTypes() ) {
592  static const auto initFn = []( bool radio ){ return
593  [radio]( PopupMenuHandler &handler, wxMenu &menu, int id ){
594  // Find all known sub-view types
595  const auto allTypes = AllTypes();
596 
597  // How to convert a type to a menu item id
598  const auto IdForType =
599  [&allTypes]( const WaveTrackSubViewType &type ) -> int {
600  const auto begin = allTypes.begin();
601  return OnSetDisplayId +
602  (std::find( begin, allTypes.end(), type ) - begin);
603  };
604 
605  auto &table = static_cast< WaveTrackMenuTable& >( handler );
606  auto &track = table.FindWaveTrack();
607 
608  const auto &view = WaveTrackView::Get( track );
609 
610  const auto displays = view.GetDisplays();
611  const auto end = displays.end();
612  bool check = (end !=
613  std::find_if( displays.begin(), end,
614  [&]( const WaveTrackSubViewType &type ){
615  return id == IdForType( type ); } ) );
616  menu.Check( id, check );
617 
618  // Bug2275 residual
619  // Disable the checking-off of the only sub-view
620  if ( !radio && displays.size() == 1 && check )
621  menu.Enable( id, false );
622  };
623  };
624  Append( [type, id]( My &table ) -> Registry::BaseItemPtr {
625  const auto pTrack = &table.FindWaveTrack();
626  const auto &view = WaveTrackView::Get( *pTrack );
627  const auto itemType =
628  view.GetMultiView() ? Entry::CheckItem : Entry::RadioItem;
629  return std::make_unique<Entry>( type.name.Internal(), itemType,
630  id, type.name.Msgid(),
631  POPUP_MENU_FN( OnSetDisplay ), table,
632  initFn( !view.GetMultiView() ) );
633  } );
634  ++id;
635  }
636  BeginSection( "Extra" );
638  EndSection();
639 
640  BeginSection( "Channels" );
641  // If these are enabled again, choose a hot key for Mono that does not conflict
642  // with Multi View
643  // AppendRadioItem(OnChannelMonoID, XXO("&Mono"),
644  // POPUP_MENU_FN( OnChannelChange ),
645  // []( PopupMenuHandler &handler, wxMenu &menu, int id ){
646  // menu.Enable( id, isMono( handler ) );
647  // menu.Check( id, findTrack( handler ).GetChannel() == Track::MonoChannel );
648  // }
649  // );
650  // AppendRadioItem(OnChannelLeftID, XXO("&Left Channel"),
651  // POPUP_MENU_FN( OnChannelChange ),
652  // []( PopupMenuHandler &handler, wxMenu &menu, int id ){
653  // menu.Enable( id, isMono( handler ) );
654  // menu.Check( id, findTrack( handler ).GetChannel() == Track::LeftChannel );
655  // }
656  // );
657  // AppendRadioItem(OnChannelRightID, XXO("R&ight Channel"),
658  // POPUP_MENU_FN( OnChannelChange ),
659  // []( PopupMenuHandler &handler, wxMenu &menu, int id ){
660  // menu.Enable( id, isMono( handler ) );
661  // menu.Check( id, findTrack( handler ).GetChannel() == Track::RightChannel );
662  // }
663  // );
664  AppendItem( "MakeStereo", OnMergeStereoID, XXO("Ma&ke Stereo Track"),
665  POPUP_MENU_FN( OnMergeStereo ),
666  []( PopupMenuHandler &handler, wxMenu &menu, int id ){
667  bool canMakeStereo = !isUnsafe( handler ) && isMono( handler );
668  if ( canMakeStereo ) {
669  AudacityProject &project =
670  static_cast< WaveTrackMenuTable& >( handler ).mpData->project;
671  auto &tracks = TrackList::Get( project );
672  auto &table = static_cast< WaveTrackMenuTable& >( handler );
673  auto &track = table.FindWaveTrack();
674  auto next = * ++ tracks.Find(&track);
675  canMakeStereo =
676  (next &&
677  TrackList::Channels(next).size() == 1 &&
678  track_cast<WaveTrack*>(next));
679  }
680  menu.Enable( id, canMakeStereo );
681  }
682  );
683 
684  AppendItem( "Swap", OnSwapChannelsID, XXO("Swap Stereo &Channels"),
685  POPUP_MENU_FN( OnSwapChannels ),
686  []( PopupMenuHandler &handler, wxMenu &menu, int id ){
687  auto &track =
688  static_cast< WaveTrackMenuTable& >( handler ).FindWaveTrack();
689  bool isStereo =
690  2 == TrackList::Channels( &track ).size();
691  menu.Enable( id, isStereo && !isUnsafe( handler ) );
692  }
693  );
694 
695  static const auto enableSplitStereo =
696  []( PopupMenuHandler &handler, wxMenu &menu, int id ){
697  menu.Enable( id, !isMono( handler ) && !isUnsafe( handler ) );
698  };
699 
700  AppendItem( "Split", OnSplitStereoID, XXO("Spl&it Stereo Track"),
701  POPUP_MENU_FN( OnSplitStereo ), enableSplitStereo );
702  // DA: Uses split stereo track and then drag pan sliders for split-stereo-to-mono
703  #ifndef EXPERIMENTAL_DA
705  XXO("Split Stereo to Mo&no"), POPUP_MENU_FN( OnSplitStereoMono ),
707  #endif
708  EndSection();
709 
710  BeginSection( "Format" );
712  EndSection();
713 
714  BeginSection( "Rate" );
716  EndSection();
718 
719 
720 void WaveTrackMenuTable::OnMultiView(wxCommandEvent & event)
721 {
722  const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
723  const auto &view = WaveTrackView::Get( *pTrack );
724  bool multi = !view.GetMultiView();
725  const auto &displays = view.GetDisplays();
726  const auto display = displays.empty()
727  ? WaveTrackViewConstants::Waveform : displays.begin()->id;
728  for (const auto channel : TrackList::Channels(pTrack)) {
729  auto &channelView = WaveTrackView::Get( *channel );
730  channelView.SetMultiView( multi );
731 
732  // Whichever sub-view was on top stays on top
733  // If going into Multi-view, it will be 1/nth the height.
734  // If exiting multi-view, it will be full height.
735  channelView.SetDisplay(display, !multi);
736  }
737 }
738 
740 void WaveTrackMenuTable::OnSetDisplay(wxCommandEvent & event)
741 {
742  int idInt = event.GetId();
743  wxASSERT(idInt >= OnSetDisplayId &&
744  idInt <= lastDisplayId);
745  const auto pTrack = static_cast<WaveTrack*>(mpData->pTrack);
746 
747  auto id = AllTypes()[ idInt - OnSetDisplayId ].id;
748 
749  auto &view = WaveTrackView::Get( *pTrack );
750  if ( view.GetMultiView() ) {
751  for (auto channel : TrackList::Channels(pTrack)) {
752  if ( !WaveTrackView::Get( *channel )
753  .ToggleSubView( WaveTrackView::Display{ id } ) ) {
754  // Trying to toggle off the last sub-view. It was refused.
755  // Decide what to do here. Turn off multi-view instead?
756  // PRL: I don't agree that it makes sense
757  }
758  else
760  }
761  }
762  else {
763  const auto displays = view.GetDisplays();
764  const bool wrongType =
765  !(displays.size() == 1 && displays[0].id == id);
766  if (wrongType) {
767  for (auto channel : TrackList::Channels(pTrack)) {
768  WaveTrackView::Get( *channel )
770  }
771 
772  AudacityProject *const project = &mpData->project;
773  ProjectHistory::Get( *project ).ModifyState(true);
774 
775  using namespace RefreshCode;
777  }
778  }
779 }
780 
781 #if 0
782 void WaveTrackMenuTable::OnChannelChange(wxCommandEvent & event)
783 {
784  int id = event.GetId();
785  wxASSERT(id >= OnChannelLeftID && id <= OnChannelMonoID);
786  WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
787  wxASSERT(pTrack);
788  Track::ChannelType channel;
789  TranslatableString channelmsg;
790  switch (id) {
791  default:
792  case OnChannelMonoID:
793  channel = Track::MonoChannel;
794  channelmsg = XO("Mono");
795  break;
796  case OnChannelLeftID:
797  channel = Track::LeftChannel;
798  channelmsg = XO("Left Channel");
799  break;
800  case OnChannelRightID:
801  channel = Track::RightChannel;
802  channelmsg = XO("Right Channel");
803  break;
804  }
805  pTrack->SetChannel(channel);
806  AudacityProject *const project = &mpData->project;
807  ProjectHistory::Get( *project )
808  .PushState(
809 /* i18n-hint: The strings name a track and a channel choice (mono, left, or right) */
810  XO("Changed '%s' to %s").Format( pTrack->GetName(), channelmsg ),
811  XO("Channel"));
813 }
814 #endif
815 
817 void WaveTrackMenuTable::OnMergeStereo(wxCommandEvent &)
818 {
819  AudacityProject *const project = &mpData->project;
820  auto &tracks = TrackList::Get( *project );
821 
822  WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
823  wxASSERT(pTrack);
824 
825  auto partner = static_cast< WaveTrack * >
826  ( *tracks.Find( pTrack ).advance( 1 ) );
827 
828  bool bBothMinimizedp =
829  ((TrackView::Get( *pTrack ).GetMinimized()) &&
830  (TrackView::Get( *partner ).GetMinimized()));
831 
832  tracks.GroupChannels( *pTrack, 2 );
833 
834  // Set partner's parameters to match target.
835  partner->Merge(*pTrack);
836 
837  pTrack->SetPan( 0.0f );
838  partner->SetPan( 0.0f );
839 
840  // Set NEW track heights and minimized state
841  auto
842  &view = WaveTrackView::Get( *pTrack ),
843  &partnerView = WaveTrackView::Get( *partner );
844  view.SetMinimized(false);
845  partnerView.SetMinimized(false);
846  int AverageHeight = (view.GetHeight() + partnerView.GetHeight()) / 2;
847  view.SetHeight(AverageHeight);
848  partnerView.SetHeight(AverageHeight);
849  view.SetMinimized(bBothMinimizedp);
850  partnerView.SetMinimized(bBothMinimizedp);
851 
852  partnerView.RestorePlacements( view.SavePlacements() );
853  partnerView.SetMultiView( view.GetMultiView() );
854 
855  ProjectHistory::Get( *project ).PushState(
856  /* i18n-hint: The string names a track */
857  XO("Made '%s' a stereo track").Format( pTrack->GetName() ),
858  XO("Make Stereo"));
859 
860  using namespace RefreshCode;
862 }
863 
866 {
867  WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
868  wxASSERT(pTrack);
869  AudacityProject *const project = &mpData->project;
870  auto channels = TrackList::Channels( pTrack );
871 
872  int totalHeight = 0;
873  int nChannels = 0;
874  for (auto channel : channels) {
875  // Keep original stereo track name.
876  channel->SetName(pTrack->GetName());
877  auto &view = TrackView::Get( *channel );
878  if (stereo)
879  channel->SetPanFromChannelType();
880 
881  //make sure no channel is smaller than its minimum height
882  if (view.GetHeight() < view.GetMinimizedHeight())
883  view.SetHeight(view.GetMinimizedHeight());
884  totalHeight += view.GetHeight();
885  ++nChannels;
886  }
887 
888  TrackList::Get( *project ).GroupChannels( *pTrack, 1 );
889  int averageHeight = totalHeight / nChannels;
890 
891  for (auto channel : channels)
892  // Make tracks the same height
893  TrackView::Get( *channel ).SetHeight( averageHeight );
894 }
895 
898 {
899  AudacityProject *const project = &mpData->project;
900 
901  WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
902  auto channels = TrackList::Channels( pTrack );
903  if (channels.size() != 2)
904  return;
905 
906  auto &trackFocus = TrackFocus::Get( *project );
907  Track *const focused = trackFocus.Get();
908  const bool hasFocus = channels.contains( focused );
909 
910  auto partner = *channels.rbegin();
911 
912  SplitStereo(false);
913 
914  auto &tracks = TrackList::Get( *project );
915  tracks.MoveUp( partner );
916  tracks.GroupChannels( *partner, 2 );
917 
918  if (hasFocus)
919  trackFocus.Set(partner);
920 
921  ProjectHistory::Get( *project ).PushState(
922  /* i18n-hint: The string names a track */
923  XO("Swapped Channels in '%s'").Format( pTrack->GetName() ),
924  XO("Swap Channels"));
925 
927 }
928 
930 void WaveTrackMenuTable::OnSplitStereo(wxCommandEvent &)
931 {
932  SplitStereo(true);
933  WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
934  AudacityProject *const project = &mpData->project;
935  ProjectHistory::Get( *project ).PushState(
936  /* i18n-hint: The string names a track */
937  XO("Split stereo track '%s'").Format( pTrack->GetName() ),
938  XO("Split"));
939 
940  using namespace RefreshCode;
942 }
943 
946 {
947  SplitStereo(false);
948  WaveTrack *const pTrack = static_cast<WaveTrack*>(mpData->pTrack);
949  AudacityProject *const project = &mpData->project;
950  ProjectHistory::Get( *project ).PushState(
951  /* i18n-hint: The string names a track */
952  XO("Split Stereo to Mono '%s'").Format( pTrack->GetName() ),
953  XO("Split to Mono"));
954 
955  using namespace RefreshCode;
957 }
958 
959 //=============================================================================
961 {
964  {
965  {wxT("/SubViews/Extra"), wxT("WaveColor,SpectrogramSettings")},
966  }
967  };
968 
970  return &result;
971 }
972 
974 {
976 }
977 
978 // drawing related
979 #include "../../../../widgets/ASlider.h"
980 #include "../../../../TrackInfo.h"
981 #include "../../../../TrackPanelDrawingContext.h"
982 #include "../../../../ViewInfo.h"
983 
984 namespace {
985 
987 ( LWSlider *(*Selector)
988  (const wxRect &sliderRect, const WaveTrack *t, bool captured, wxWindow*),
989  wxDC *dc, const wxRect &rect, const Track *pTrack,
990  wxWindow *pParent,
991  bool captured, bool highlight )
992 {
993  wxRect sliderRect = rect;
994  TrackInfo::GetSliderHorizontalBounds( rect.GetTopLeft(), sliderRect );
995  auto wt = static_cast<const WaveTrack*>( pTrack );
996  Selector( sliderRect, wt, captured, pParent )->OnPaint(*dc, highlight);
997 }
998 
1000 ( TrackPanelDrawingContext &context,
1001  const wxRect &rect, const Track *pTrack )
1002 {
1003  auto target = dynamic_cast<PanSliderHandle*>( context.target.get() );
1004  auto dc = &context.dc;
1005  bool hit = target && target->GetTrack().get() == pTrack;
1006  bool captured = hit && target->IsClicked();
1007 
1008  const auto artist = TrackArtist::Get( context );
1009  auto pParent = FindProjectFrame( artist->parent->GetProject() );
1010 
1012  &WaveTrackControls::PanSlider, dc, rect, pTrack,
1013  pParent, captured, hit);
1014 }
1015 
1017 ( TrackPanelDrawingContext &context,
1018  const wxRect &rect, const Track *pTrack )
1019 {
1020  auto target = dynamic_cast<GainSliderHandle*>( context.target.get() );
1021  auto dc = &context.dc;
1022  bool hit = target && target->GetTrack().get() == pTrack;
1023  if( hit )
1024  hit=hit;
1025  bool captured = hit && target->IsClicked();
1026 
1027  const auto artist = TrackArtist::Get( context );
1028  auto pParent = FindProjectFrame( artist->parent->GetProject() );
1029 
1031  &WaveTrackControls::GainSlider, dc, rect, pTrack,
1032  pParent, captured, hit);
1033 }
1034 
1036  ( const TranslatableString &string, wxDC *dc, const wxRect &rect )
1037 {
1038  static const int offset = 3;
1039  dc->DrawText(string.Translation(), rect.x + offset, rect.y);
1040 }
1041 
1043 ( TrackPanelDrawingContext &context,
1044  const wxRect &rect, const Track *pTrack )
1045 {
1046  auto dc = &context.dc;
1047  auto wt = static_cast<const WaveTrack*>(pTrack);
1048 
1052  auto rate = wt ? wt->GetRate() : 44100.0;
1054  if (!pTrack || TrackList::Channels(pTrack).size() > 1)
1055  // TODO: more-than-two-channels-message
1056  // more appropriate strings
1057  s = XO("Stereo, %dHz");
1058  else {
1059  if (wt->GetChannel() == Track::MonoChannel)
1060  s = XO("Mono, %dHz");
1061  else if (wt->GetChannel() == Track::LeftChannel)
1062  s = XO("Left, %dHz");
1063  else if (wt->GetChannel() == Track::RightChannel)
1064  s = XO("Right, %dHz");
1065  }
1066  s.Format( (int) (rate + 0.5) );
1067 
1068  StatusDrawFunction( s, dc, rect );
1069 }
1070 
1072 ( TrackPanelDrawingContext &context,
1073  const wxRect &rect, const Track *pTrack )
1074 {
1075  auto dc = &context.dc;
1076  auto wt = static_cast<const WaveTrack*>(pTrack);
1077  auto format = wt ? wt->GetSampleFormat() : floatSample;
1078  auto s = GetSampleFormatStr(format);
1079  StatusDrawFunction( s, dc, rect );
1080 }
1081 
1082 }
1083 
1085 
1086 static const struct WaveTrackTCPLines
1088  (TCPLines&)*this =
1090  insert( end(), {
1091 
1096 
1097 #ifdef EXPERIMENTAL_DA
1098  // DA: Does not have status information for a track.
1099 #else
1100  { TCPLine::kItemStatusInfo1, 12, 0,
1102  { TCPLine::kItemStatusInfo2, 12, 0,
1104 #endif
1105 
1106  } );
1108 
1109 void WaveTrackControls::GetGainRect(const wxPoint &topleft, wxRect & dest)
1110 {
1111  TrackInfo::GetSliderHorizontalBounds( topleft, dest );
1112  auto results = CalcItemY( waveTrackTCPLines, TCPLine::kItemGain );
1113  dest.y = topleft.y + results.first;
1114  dest.height = results.second;
1115 }
1116 
1117 void WaveTrackControls::GetPanRect(const wxPoint &topleft, wxRect & dest)
1118 {
1119  GetGainRect( topleft, dest );
1120  auto results = CalcItemY( waveTrackTCPLines, TCPLine::kItemPan );
1121  dest.y = topleft.y + results.first;
1122 }
1123 
1125 {
1127 }
1128 
1130 {
1131  return waveTrackTCPLines;
1132 }
1133 
1134 namespace
1135 {
1136 std::unique_ptr<LWSlider>
1140  , gPan;
1141 }
1142 
1144  CellularPanel &panel, const WaveTrack &wt )
1145 {
1146  auto &controls = TrackControls::Get( wt );
1147  auto rect = panel.FindRect( controls );
1148  wxRect sliderRect;
1149  GetGainRect( rect.GetTopLeft(), sliderRect );
1150  return GainSlider( sliderRect, &wt, false, &panel );
1151 }
1152 
1154 (const wxRect &sliderRect, const WaveTrack *t, bool captured, wxWindow *pParent)
1155 {
1156  static std::once_flag flag;
1157  std::call_once( flag, [] {
1158  wxCommandEvent dummy;
1159  ReCreateGainSlider( dummy );
1160  wxTheApp->Bind(EVT_THEME_CHANGE, ReCreateGainSlider);
1161  } );
1162 
1163  wxPoint pos = sliderRect.GetPosition();
1164  float gain = t ? t->GetGain() : 1.0;
1165 
1166  gGain->Move(pos);
1167  gGain->Set(gain);
1168  gGainCaptured->Move(pos);
1169  gGainCaptured->Set(gain);
1170 
1171  auto slider = (captured ? gGainCaptured : gGain).get();
1172  slider->SetParent( pParent );
1173  return slider;
1174 }
1175 
1177 {
1178  event.Skip();
1179 
1180  const wxPoint point{ 0, 0 };
1181  wxRect sliderRect;
1182  GetGainRect(point, sliderRect);
1183 
1184  float defPos = 1.0;
1185  /* i18n-hint: Title of the Gain slider, used to adjust the volume */
1186  gGain = std::make_unique<LWSlider>(nullptr, XO("Gain"),
1187  wxPoint(sliderRect.x, sliderRect.y),
1188  wxSize(sliderRect.width, sliderRect.height),
1189  DB_SLIDER);
1190  gGain->SetDefaultValue(defPos);
1191 
1192  gGainCaptured = std::make_unique<LWSlider>(nullptr, XO("Gain"),
1193  wxPoint(sliderRect.x, sliderRect.y),
1194  wxSize(sliderRect.width, sliderRect.height),
1195  DB_SLIDER);
1196  gGainCaptured->SetDefaultValue(defPos);
1197 }
1198 
1200  CellularPanel &panel, const WaveTrack &wt )
1201 {
1202  auto &controls = TrackControls::Get( wt );
1203  auto rect = panel.FindRect( controls );
1204  wxRect sliderRect;
1205  GetPanRect( rect.GetTopLeft(), sliderRect );
1206  return PanSlider( sliderRect, &wt, false, &panel );
1207 }
1208 
1210 (const wxRect &sliderRect, const WaveTrack *t, bool captured, wxWindow *pParent)
1211 {
1212  static std::once_flag flag;
1213  std::call_once( flag, [] {
1214  wxCommandEvent dummy;
1215  ReCreatePanSlider( dummy );
1216  wxTheApp->Bind(EVT_THEME_CHANGE, ReCreatePanSlider);
1217  } );
1218 
1219  wxPoint pos = sliderRect.GetPosition();
1220  float pan = t ? t->GetPan() : 0.0;
1221 
1222  gPan->Move(pos);
1223  gPan->Set(pan);
1224  gPanCaptured->Move(pos);
1225  gPanCaptured->Set(pan);
1226 
1227  auto slider = (captured ? gPanCaptured : gPan).get();
1228  slider->SetParent( pParent );
1229  return slider;
1230 }
1231 
1233 {
1234  event.Skip();
1235 
1236  const wxPoint point{ 0, 0 };
1237  wxRect sliderRect;
1238  GetPanRect(point, sliderRect);
1239 
1240  float defPos = 0.0;
1241  /* i18n-hint: Title of the Pan slider, used to move the sound left or right */
1242  gPan = std::make_unique<LWSlider>(nullptr, XO("Pan"),
1243  wxPoint(sliderRect.x, sliderRect.y),
1244  wxSize(sliderRect.width, sliderRect.height),
1245  PAN_SLIDER);
1246  gPan->SetDefaultValue(defPos);
1247 
1248  gPanCaptured = std::make_unique<LWSlider>(nullptr, XO("Pan"),
1249  wxPoint(sliderRect.x, sliderRect.y),
1250  wxSize(sliderRect.width, sliderRect.height),
1251  PAN_SLIDER);
1252  gPanCaptured->SetDefaultValue(defPos);
1253 }
1254 
1256 template<> template<> auto DoGetWaveTrackControls::Implementation() -> Function {
1257  return [](WaveTrack &track) {
1258  return std::make_shared<WaveTrackControls>( track.SharedPointer() );
1259  };
1260 }
1262 
1264 template<> template<>
1265 auto GetDefaultWaveTrackHeight::Implementation() -> Function {
1266  return [](WaveTrack &) {
1268  };
1269 }
1271 
FormatMenuTable::mpData
PlayableTrackControls::InitMenuData * mpData
Definition: WaveTrackControls.cpp:174
GainSliderHandle::HitTest
static UIHandlePtr HitTest(std::weak_ptr< GainSliderHandle > &holder, const wxMouseState &state, const wxRect &rect, const std::shared_ptr< Track > &pTrack)
Definition: WaveTrackSliderHandles.cpp:89
ProjectHistory::ModifyState
void ModifyState(bool bWantsAutoSave)
Definition: ProjectHistory.cpp:124
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
WaveTrackMenuTable::WaveTrackMenuTable
WaveTrackMenuTable()
Definition: WaveTrackControls.cpp:500
RefreshCode::FixScrollbars
@ FixScrollbars
Definition: RefreshCode.h:27
WaveTrackControls::~WaveTrackControls
~WaveTrackControls()
Definition: WaveTrackControls.cpp:44
anonymous_namespace{WaveTrackControls.cpp}::gGainCaptured
std::unique_ptr< LWSlider > gGainCaptured
Definition: WaveTrackControls.cpp:1138
anonymous_namespace{WaveTrackControls.cpp}::Status2DrawFunction
void Status2DrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
Definition: WaveTrackControls.cpp:1072
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:38
WaveTrackMenuTable::OnSetDisplay
void OnSetDisplay(wxCommandEvent &event)
Set the Display mode based on the menu choice in the Track Menu.
Definition: WaveTrackControls.cpp:740
MuteButtonHandle::HitTest
static UIHandlePtr HitTest(std::weak_ptr< MuteButtonHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< Track > &pTrack)
Definition: PlayableTrackButtonHandles.cpp:59
WaveTrackMenuTable::OnSwapChannels
void OnSwapChannels(wxCommandEvent &event)
Swap the left and right channels of a stero track...
Definition: WaveTrackControls.cpp:897
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1184
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
OnRate352ID
@ OnRate352ID
Definition: WaveTrackControls.cpp:106
RateMenuTable::OnRateOther
void OnRateOther(wxCommandEvent &event)
Definition: WaveTrackControls.cpp:411
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption=XO("Message"), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: AudacityMessageBox.h:20
BasicUI::ProgressResult::Success
@ Success
Track::RightChannel
static const auto RightChannel
Definition: Track.h:267
kTrackInfoSliderHeight
@ kTrackInfoSliderHeight
Definition: ViewInfo.h:113
ClientData::Site::slots
static size_t slots()
How many static factories have been registered with this specialization of Site.
Definition: ClientData.h:258
OnRate176ID
@ OnRate176ID
Definition: WaveTrackControls.cpp:104
WaveTrackControls::ReCreatePanSlider
static void ReCreatePanSlider(wxEvent &)
Definition: WaveTrackControls.cpp:1232
OnChannelRightID
@ OnChannelRightID
Definition: WaveTrackControls.cpp:119
OnRate11ID
@ OnRate11ID
Definition: WaveTrackControls.cpp:97
TCPLines
TrackInfo::TCPLines TCPLines
Definition: TrackInfo.cpp:101
RefreshCode::RefreshAll
@ RefreshAll
Definition: RefreshCode.h:26
OnRateOtherID
@ OnRateOtherID
Definition: WaveTrackControls.cpp:108
TrackView::Get
static TrackView & Get(Track &)
Definition: TrackView.cpp:63
nRates
const int nRates
Definition: WaveTrackControls.cpp:363
flag
static std::once_flag flag
Definition: WaveformView.cpp:1125
ClientData::Site::Find
Subclass * Find(const RegisteredFactory &key)
Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand...
Definition: ClientData.h:333
UserException
Can be thrown when user cancels operations, as with a progress dialog. Delayed handler does nothing.
Definition: UserException.h:17
TrackView::GetMinimized
bool GetMinimized() const
Definition: TrackView.h:49
FormatMenuTable::Instance
static FormatMenuTable & Instance()
Definition: WaveTrackControls.cpp:181
Track::GetName
wxString GetName() const
Definition: Track.h:410
OnSplitStereoMonoID
@ OnSplitStereoMonoID
Definition: WaveTrackControls.cpp:126
WaveTrackMenuTable::OnChannelChange
void OnChannelChange(wxCommandEvent &event)
PopupMenuTable
Definition: PopupMenuTable.h:104
FormatMenuTable::DECLARE_POPUP_MENU
DECLARE_POPUP_MENU(FormatMenuTable)
ClientData::Site::Get
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
TrackControls::Get
static TrackControls & Get(Track &track)
Definition: TrackControls.cpp:25
PopupMenuTableEntry::InitFunction
std::function< void(PopupMenuHandler &handler, wxMenu &menu, int id) > InitFunction
Definition: PopupMenuTable.h:38
CommonTrackPanelCell::FindTrack
std::shared_ptr< Track > FindTrack()
Definition: CommonTrackPanelCell.h:44
pdlgHideStopButton
@ pdlgHideStopButton
Definition: ProgressDialog.h:38
TrackPanelDrawingContext
Definition: TrackPanelDrawingContext.h:22
TrackList::Channels
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1468
Format
Abstract base class used in importing a file.
OnFloatID
@ OnFloatID
Definition: WaveTrackControls.cpp:112
TrackInfo::TCPLine::kItemGain
@ kItemGain
Definition: TrackInfo.h:43
WaveTrackControls::mPanHandle
std::weak_ptr< PanSliderHandle > mPanHandle
Definition: WaveTrackControls.h:68
On24BitID
@ On24BitID
Definition: WaveTrackControls.cpp:111
OnChannelMonoID
@ OnChannelMonoID
Definition: WaveTrackControls.cpp:120
PopupMenuTable::EndSection
void EndSection()
Definition: PopupMenuTable.cpp:177
Track::SharedPointer
std::shared_ptr< Subclass > SharedPointer()
Definition: Track.h:280
On16BitID
@ On16BitID
Definition: WaveTrackControls.cpp:110
anonymous_namespace{WaveTrackControls.cpp}::Status1DrawFunction
void Status1DrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
Definition: WaveTrackControls.cpp:1043
enableSplitStereo
static const auto enableSplitStereo
Definition: WaveTrackControls.cpp:695
TrackView::SetHeight
void SetHeight(int height)
Definition: TrackView.cpp:164
OnSplitStereoID
@ OnSplitStereoID
Definition: WaveTrackControls.cpp:125
AllTypes
static std::vector< WaveTrackSubViewType > AllTypes()
Definition: WaveTrackControls.cpp:542
TrackInfo::CalcItemY
AUDACITY_DLL_API std::pair< int, int > CalcItemY(const TCPLines &lines, unsigned iItem)
Definition: TrackInfo.cpp:145
XO
#define XO(s)
Definition: Internat.h:31
OnRate384ID
@ OnRate384ID
Definition: WaveTrackControls.cpp:107
int24Sample
@ int24Sample
Definition: SampleFormat.h:33
WaveTrackControls::DefaultWaveTrackHeight
static unsigned DefaultWaveTrackHeight()
Definition: WaveTrackControls.cpp:1124
OnRate8ID
@ OnRate8ID
Definition: WaveTrackControls.cpp:96
ProgressDialog.h
TrackPanelDrawingContext::dc
wxDC & dc
Definition: TrackPanelDrawingContext.h:23
anonymous_namespace{WaveTrackControls.cpp}::ValueFinder
std::function< int(WaveTrack &) > ValueFinder
Definition: WaveTrackControls.cpp:136
CommonTrackControls::InitMenuData::result
unsigned result
Definition: CommonTrackControls.h:39
lastDisplayId
@ lastDisplayId
Definition: WaveTrackControls.cpp:116
RateMenuTable::Instance
static RateMenuTable & Instance()
Definition: WaveTrackControls.cpp:326
CellularPanel::FindRect
wxRect FindRect(const TrackPanelCell &cell)
Definition: CellularPanel.cpp:1068
OnMergeStereoID
@ OnMergeStereoID
Definition: WaveTrackControls.cpp:122
POPUP_MENU_SUB_MENU
#define POPUP_MENU_SUB_MENU(stringId, classname, pUserData)
Definition: PopupMenuTable.h:315
WaveTrackViewConstants::Display
Display
Definition: WaveTrackViewConstants.h:18
ProjectAudioIO::Get
static ProjectAudioIO & Get(AudacityProject &project)
Definition: ProjectAudioIO.cpp:23
PopupMenuTableEntry::RadioItem
@ RadioItem
Definition: PopupMenuTable.h:36
PanSliderHandle
Definition: WaveTrackSliderHandles.h:56
wxArrayStringEx
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Definition: wxArrayStringEx.h:18
TrackPanelMouseState::rect
const wxRect & rect
Definition: TrackPanelMouseEvent.h:39
PopupMenuTable::BeginSection
void BeginSection(const Identifier &name)
Definition: PopupMenuTable.cpp:169
GetWaveTrackMenuTable
WaveTrackPopupMenuTable & GetWaveTrackMenuTable()
Definition: WaveTrackControls.cpp:973
ProjectAudioIO::IsAudioActive
bool IsAudioActive() const
Definition: ProjectAudioIO.cpp:52
PAN_SLIDER
#define PAN_SLIDER
Definition: ASlider.h:34
gRates
static int gRates[nRates]
Definition: WaveTrackControls.cpp:367
ChannelMenuID
@ ChannelMenuID
Definition: WaveTrackControls.cpp:128
OnRate22ID
@ OnRate22ID
Definition: WaveTrackControls.cpp:99
CommonTrackControls::InitMenuData::project
AudacityProject & project
Definition: CommonTrackControls.h:36
WaveTrackControls::GetGainRect
static void GetGainRect(const wxPoint &topLeft, wxRect &dest)
Definition: WaveTrackControls.cpp:1109
WaveTrackView.h
WaveTrack::Merge
void Merge(const Track &orig) override
Definition: WaveTrack.cpp:184
FormatMenuTable::DestroyMenu
void DestroyMenu() override
Definition: WaveTrackControls.cpp:169
floatSample
@ floatSample
Definition: SampleFormat.h:34
RateMenuTable
Definition: WaveTrackControls.cpp:302
anonymous_namespace{WaveTrackControls.cpp}::SliderDrawFunction
void SliderDrawFunction(LWSlider *(*Selector)(const wxRect &sliderRect, const WaveTrack *t, bool captured, wxWindow *), wxDC *dc, const wxRect &rect, const Track *pTrack, wxWindow *pParent, bool captured, bool highlight)
Definition: WaveTrackControls.cpp:987
WaveTrackControls::GetPanRect
static void GetPanRect(const wxPoint &topLeft, wxRect &dest)
Definition: WaveTrackControls.cpp:1117
AttachedVirtualFunction::Override::Implementation
static Function Implementation()
A function returning a std::function that must be defined so that the program links.
Definition: LabelTrackControls.cpp:182
RateMenuTable::InitUserData
void InitUserData(void *pUserData) override
Definition: WaveTrackControls.cpp:332
OnRate96ID
@ OnRate96ID
Definition: WaveTrackControls.cpp:103
isUnsafe
static const auto isUnsafe
Definition: WaveTrackControls.cpp:561
fn
static const auto fn
Definition: WaveTrackControls.cpp:194
TrackArtist::Get
static TrackArtist * Get(TrackPanelDrawingContext &)
Definition: TrackArtist.cpp:78
XXO
#define XXO(s)
Definition: Internat.h:44
Registry::BaseItemPtr
std::unique_ptr< BaseItem > BaseItemPtr
Definition: Registry.h:71
ShuttleGuiBase::EndHorizontalLay
void EndHorizontalLay()
Definition: ShuttleGui.cpp:1177
ProgressDialog
ProgressDialog Class.
Definition: ProgressDialog.h:51
TrackInfo::TCPLine::kItemStatusInfo2
@ kItemStatusInfo2
Definition: TrackInfo.h:49
sampleCount::as_double
double as_double() const
Definition: SampleCount.h:45
RateMenuTable::DECLARE_POPUP_MENU
DECLARE_POPUP_MENU(RateMenuTable)
WaveTrackSubViewType
Definition: WaveTrackViewConstants.h:91
WaveTrackControls::mGainHandle
std::weak_ptr< GainSliderHandle > mGainHandle
Definition: WaveTrackControls.h:67
LWSlider
Lightweight version of ASlider. In other words it does not have a window permanently associated with ...
Definition: ASlider.h:62
ShuttleGuiBase::StartHorizontalLay
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:1167
CommonTrackControls::HitTest
virtual std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *) override=0
Definition: CommonTrackControls.cpp:35
anonymous_namespace{SpectrumView.cpp}::findValue
static float findValue(const float *spectrum, float bin0, float bin1, unsigned nBins, bool autocorrelation, int gain, int range)
Definition: SpectrumView.cpp:95
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1203
int16Sample
@ int16Sample
Definition: SampleFormat.h:32
RateMenuTable::SetRate
void SetRate(WaveTrack *pTrack, double rate)
Definition: WaveTrackControls.cpp:382
WaveTrackMenuTable::DECLARE_POPUP_MENU
DECLARE_POPUP_MENU(WaveTrackMenuTable)
Track::MonoChannel
static const auto MonoChannel
Definition: Track.h:268
RateMenuTable::RateMenuTable
RateMenuTable()
Definition: WaveTrackControls.cpp:303
FindProjectFrame
wxFrame * FindProjectFrame(AudacityProject *project)
Get a pointer to the window associated with a project, or null if the given pointer is null.
Definition: Project.h:173
WaveTrackMenuTable::SplitStereo
void SplitStereo(bool stereo)
Split a stereo track (or more-than-stereo?) into two (or more) tracks...
Definition: WaveTrackControls.cpp:865
PopupMenuTable::AppendItem
void AppendItem(const Identifier &stringId, int id, const TranslatableString &string, wxCommandEventFunction memFn, const PopupMenuTableEntry::InitFunction &init={})
Definition: PopupMenuTable.h:191
PopupMenuTable::AppendCheckItem
void AppendCheckItem(const Identifier &stringId, int id, const TranslatableString &string, wxCommandEventFunction memFn, const PopupMenuTableEntry::InitFunction &init={})
Definition: PopupMenuTable.h:203
anonymous_namespace{WaveTrackControls.cpp}::gGain
std::unique_ptr< LWSlider > gGain
Definition: WaveTrackControls.cpp:1140
Identifier.h
OnMultiViewID
@ OnMultiViewID
Definition: WaveTrackControls.cpp:114
PanSliderHandle::HitTest
static UIHandlePtr HitTest(std::weak_ptr< PanSliderHandle > &holder, const wxMouseState &state, const wxRect &rect, const std::shared_ptr< Track > &pTrack)
Definition: WaveTrackSliderHandles.cpp:200
OnRate44ID
@ OnRate44ID
Definition: WaveTrackControls.cpp:100
UIHandlePtr
std::shared_ptr< UIHandle > UIHandlePtr
Definition: CellularPanel.h:28
FormatMenuTable
Definition: WaveTrackControls.cpp:159
anonymous_namespace{WaveTrackControls.cpp}::gPan
std::unique_ptr< LWSlider > gPan
Definition: WaveTrackControls.cpp:1140
format
int format
Definition: ExportPCM.cpp:56
WaveTrackSubViewType::All
static const std::vector< WaveTrackSubViewType > & All()
Discover all registered types.
Definition: WaveTrackViewConstants.cpp:90
WaveTrackControls::GainSlider
static LWSlider * GainSlider(CellularPanel &panel, const WaveTrack &wt)
Definition: WaveTrackControls.cpp:1143
WaveTrackControls::mSoloHandle
std::weak_ptr< SoloButtonHandle > mSoloHandle
Definition: WaveTrackControls.h:66
TrackInfo::TCPLine::kItemStatusInfo1
@ kItemStatusInfo1
Definition: TrackInfo.h:40
DB_SLIDER
#define DB_SLIDER
Definition: ASlider.h:33
Track::LeftChannel
static const auto LeftChannel
Definition: Track.h:266
TrackFocus::Get
Track * Get()
Definition: TrackPanelAx.cpp:755
RefreshCode::UpdateVRuler
@ UpdateVRuler
Definition: RefreshCode.h:30
WaveTrackControls::ReCreateGainSlider
static void ReCreateGainSlider(wxEvent &)
Definition: WaveTrackControls.cpp:1176
PopupMenuTableEntry::CheckItem
@ CheckItem
Definition: PopupMenuTable.h:36
WaveTrack::GetGain
float GetGain() const
Definition: WaveTrack.cpp:375
anonymous_namespace{WaveTrackControls.cpp}::PanSliderDrawFunction
void PanSliderDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
Definition: WaveTrackControls.cpp:1000
CommonTrackControls::InitMenuData
Definition: CommonTrackControls.h:34
anonymous_namespace{WaveTrackControls.cpp}::gPanCaptured
std::unique_ptr< LWSlider > gPanCaptured
Definition: WaveTrackControls.cpp:1139
Track::SetChannel
void SetChannel(ChannelType c)
Definition: Track.h:377
WaveTrackMenuTable::OnSplitStereoMono
void OnSplitStereoMono(wxCommandEvent &event)
Split a stereo track into two mono tracks...
Definition: WaveTrackControls.cpp:945
wxDialogWrapper::SetName
void SetName(const TranslatableString &title)
Definition: wxPanelWrapper.cpp:76
RealtimeEffectManager::RealtimeIsActive
bool RealtimeIsActive()
Definition: RealtimeEffectManager.cpp:103
WaveTrackTCPLines
Definition: WaveTrackControls.cpp:1087
POPUP_MENU_FN
#define POPUP_MENU_FN(memFn)
Definition: PopupMenuTable.h:313
RealtimeEffectManager::Get
static RealtimeEffectManager & Get()
Definition: RealtimeEffectManager.cpp:43
PlayableTrackControls::StaticTCPLines
static const TCPLines & StaticTCPLines()
Definition: PlayableTrackControls.cpp:198
CommonTrackControls::InitMenuData::pParent
wxWindow * pParent
Definition: CommonTrackControls.h:38
FormatMenuTable::OnFormatChange
void OnFormatChange(wxCommandEvent &event)
Definition: WaveTrackControls.cpp:229
UserException.h
An AudacityException with no visible message.
WaveTrackMenuTable::InitUserData
void InitUserData(void *pUserData) override
Definition: WaveTrackControls.cpp:537
kTrackInfoSliderExtra
@ kTrackInfoSliderExtra
Definition: ViewInfo.h:116
WaveTrackMenuTable::DestroyMenu
void DestroyMenu() override
Definition: WaveTrackControls.cpp:509
waveTrackTCPLines
WaveTrackTCPLines waveTrackTCPLines
sampleFormat
sampleFormat
Definition: SampleFormat.h:29
BEGIN_POPUP_MENU
#define BEGIN_POPUP_MENU(HandlerClass)
Definition: PopupMenuTable.h:305
id
int id
Definition: WaveTrackControls.cpp:590
ProjectHistory::PushState
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
Definition: ProjectHistory.cpp:90
wxDialogWrapper
Definition: wxPanelWrapper.h:81
TrackInfo::TCPLine::kItemPan
@ kItemPan
Definition: TrackInfo.h:44
WaveTrackTCPLines::WaveTrackTCPLines
WaveTrackTCPLines()
Definition: WaveTrackControls.cpp:1087
anonymous_namespace{WaveTrackControls.cpp}::initFn
PopupMenuTableEntry::InitFunction initFn(const ValueFinder &findValue)
Definition: WaveTrackControls.cpp:141
SoloButtonHandle::HitTest
static UIHandlePtr HitTest(std::weak_ptr< SoloButtonHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, const std::shared_ptr< Track > &pTrack)
Definition: PlayableTrackButtonHandles.cpp:115
TrackList::GroupChannels
void GroupChannels(Track &track, size_t groupSize, bool resetChannels=true)
Define a group of channels starting at the given track.
Definition: Track.cpp:707
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:495
AppendRadioItem
AppendRadioItem("16Bit", On16BitID, GetSampleFormatStr(int16Sample), POPUP_MENU_FN(OnFormatChange), fn)
PopupMenuHandler
Definition: PopupMenuTable.h:82
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:239
GainSliderHandle
Definition: WaveTrackSliderHandles.h:20
RateMenuTable::OnRateChange
void OnRateChange(wxCommandEvent &event)
Definition: WaveTrackControls.cpp:399
TrackInfo::DefaultTrackHeight
AUDACITY_DLL_API unsigned DefaultTrackHeight(const TCPLines &topLines)
Definition: TrackInfo.cpp:565
isMono
static const auto isMono
Definition: WaveTrackControls.cpp:554
WaveTrack::SetPan
void SetPan(float newPan) override
Definition: WaveTrack.cpp:393
OnRate88ID
@ OnRate88ID
Definition: WaveTrackControls.cpp:102
XMLValueChecker::ChannelType
ChannelType
Definition: XMLTagHandler.h:67
WaveTrackControls::HitTest
std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &state, const AudacityProject *pProject) override
Definition: WaveTrackControls.cpp:50
sampleCount
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:18
WaveTrackControls::GetMenuExtension
PopupMenuTable * GetMenuExtension(Track *pTrack) override
Definition: WaveTrackControls.cpp:960
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:113
WaveTrackViewConstants.h
TrackInfo::TCPLine
Definition: TrackInfo.h:36
reserveDisplays
@ reserveDisplays
Definition: WaveTrackControls.cpp:94
WaveTrackMenuTable::OnSplitStereo
void OnSplitStereo(wxCommandEvent &event)
Split a stereo track into two tracks...
Definition: WaveTrackControls.cpp:930
FormatMenuTable::InitUserData
void InitUserData(void *pUserData) override
Definition: WaveTrackControls.cpp:187
WaveTrackView::Get
static WaveTrackView & Get(WaveTrack &track)
Definition: WaveTrackView.cpp:771
PopupMenuTable::Append
void Append(Registry::BaseItemPtr pItem)
Definition: PopupMenuTable.cpp:155
CellularPanel
Formerly part of TrackPanel, this abstract base class has no special knowledge of Track objects and i...
Definition: CellularPanel.h:34
FormatMenuTable::FormatMenuTable
FormatMenuTable()
Definition: WaveTrackControls.cpp:160
OnSetDisplayId
@ OnSetDisplayId
Definition: WaveTrackControls.cpp:116
WaveTrackControls::PanSlider
static LWSlider * PanSlider(CellularPanel &panel, const WaveTrack &wt)
Definition: WaveTrackControls.cpp:1199
registerDoGetWaveTrackControls
static DoGetWaveTrackControls registerDoGetWaveTrackControls
Definition: WaveTrackControls.cpp:1261
TrackPanelMouseState
Definition: TrackPanelMouseEvent.h:28
TrackPanelDrawingContext::target
UIHandlePtr target
Definition: TrackPanelDrawingContext.h:24
ComputedPopupMenuTable
Definition: PopupMenuTable.h:223
WaveTrackMenuTable::OnMergeStereo
void OnMergeStereo(wxCommandEvent &event)
Merge two tracks into one stereo track ??
Definition: WaveTrackControls.cpp:817
AttachedVirtualFunction::Override
For defining overrides of the method.
Definition: AttachedVirtualFunction.h:190
anonymous_namespace{WaveTrackControls.cpp}::StatusDrawFunction
void StatusDrawFunction(const TranslatableString &string, wxDC *dc, const wxRect &rect)
Definition: WaveTrackControls.cpp:1036
TrackInfo::GetSliderHorizontalBounds
AUDACITY_DLL_API void GetSliderHorizontalBounds(const wxPoint &topleft, wxRect &dest)
Definition: TrackInfo.cpp:487
WaveTrackPopupMenuTable::FindWaveTrack
WaveTrack & FindWaveTrack() const
Definition: WaveTrackControls.cpp:88
ShuttleGui::AddStandardButtons
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxWindow *extra=NULL)
Definition: ShuttleGui.cpp:2432
OnRate16ID
@ OnRate16ID
Definition: WaveTrackControls.cpp:98
WaveTrackControls::GetTCPLines
const TCPLines & GetTCPLines() const override
Definition: WaveTrackControls.cpp:1129
WaveTrackControls.h
GetSampleFormatStr
TranslatableString GetSampleFormatStr(sampleFormat format)
Definition: SampleFormat.cpp:60
WaveTrackMenuTable::Instance
static WaveTrackMenuTable & Instance()
Definition: WaveTrackControls.cpp:531
ShuttleGuiBase::SetBorder
void SetBorder(int Border)
Definition: ShuttleGui.h:489
RateMenuTable::IdOfRate
static int IdOfRate(int rate)
Converts a sampling rate to a wxWidgets menu item id.
Definition: WaveTrackControls.cpp:371
WaveTrack::GetPan
float GetPan() const
Definition: WaveTrack.cpp:388
TranslatableString::Format
TranslatableString & Format(Args &&...args) &
Capture variadic format arguments (by copy) when there is no plural.
Definition: TranslatableString.h:103
MenuPathStart
static const auto MenuPathStart
Definition: WaveTrackControls.cpp:491
registerGetDefaultWaveTrackHeight
static GetDefaultWaveTrackHeight registerGetDefaultWaveTrackHeight
Definition: WaveTrackControls.cpp:1270
WaveTrackPopupMenuTable
Definition: WaveTrackControls.h:74
OnRate192ID
@ OnRate192ID
Definition: WaveTrackControls.cpp:105
RateMenuTable::DestroyMenu
void DestroyMenu() override
Definition: WaveTrackControls.cpp:312
RefreshCode
Namespace containing an enum 'what to do on a refresh?'.
Definition: RefreshCode.h:16
CommonTrackControls::InitMenuData::pTrack
Track * pTrack
Definition: CommonTrackControls.h:37
lrint
#define lrint(dbl)
Definition: float_cast.h:169
OnSwapChannelsID
@ OnSwapChannelsID
Definition: WaveTrackControls.cpp:124
WaveTrackView::SetDisplay
void SetDisplay(Display display, bool exclusive=true)
Definition: WaveTrackView.cpp:871
FormatMenuTable::IdOfFormat
static int IdOfFormat(int format)
Converts a format enumeration to a wxWidgets menu item Id.
Definition: WaveTrackControls.cpp:210
WaveTrackMenuTable
Definition: WaveTrackControls.cpp:497
WaveTrackPopupMenuTable::mpData
PlayableTrackControls::InitMenuData * mpData
Definition: WaveTrackControls.h:76
OnChannelLeftID
@ OnChannelLeftID
Definition: WaveTrackControls.cpp:118
anonymous_namespace{WaveTrackControls.cpp}::GainSliderDrawFunction
void GainSliderDrawFunction(TrackPanelDrawingContext &context, const wxRect &rect, const Track *pTrack)
Definition: WaveTrackControls.cpp:1017
ShuttleGuiBase::AddCombo
wxComboBox * AddCombo(const TranslatableString &Prompt, const wxString &Selected, const wxArrayStringEx &choices)
Definition: ShuttleGui.cpp:517
FirstAttachedItemId
@ FirstAttachedItemId
Definition: WaveTrackControls.cpp:131
TCPLine
TrackInfo::TCPLine TCPLine
Definition: WaveTrackControls.cpp:1084
TrackPanelMouseState::state
wxMouseState & state
Definition: TrackPanelMouseEvent.h:38
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
WaveTrackViewConstants::Waveform
@ Waveform
Definition: WaveTrackViewConstants.h:24
OnRate48ID
@ OnRate48ID
Definition: WaveTrackControls.cpp:101
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
WaveTrackControls::mMuteHandle
std::weak_ptr< MuteButtonHandle > mMuteHandle
Definition: WaveTrackControls.h:65
WaveTrackSliderHandles.h
Registry::OrderingPreferenceInitializer
Definition: Registry.h:273
END_POPUP_MENU
#define END_POPUP_MENU()
Definition: PopupMenuTable.h:320
WaveTrack::GetRate
double GetRate() const
Definition: WaveTrack.cpp:358