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