Audacity  3.0.3
DeviceToolBar.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  DeviceToolBar.cpp
6 
7  Dominic Mazzoni
8 
9 *******************************************************************//*******************************************************************/
15 
16 
17 
18 #include "DeviceToolBar.h"
19 #include "ToolManager.h"
20 
21 // For compilers that support precompilation, includes "wx/wx.h".
22 #include <wx/wxprec.h>
23 
24 #include <wx/setup.h> // for wxUSE_* macros
25 
26 #ifndef WX_PRECOMP
27 #include <wx/choice.h>
28 #include <wx/event.h>
29 #include <wx/intl.h>
30 #include <wx/settings.h>
31 #include <wx/sizer.h>
32 #include <wx/statbmp.h>
33 #include <wx/stattext.h>
34 #include <wx/tooltip.h>
35 #endif
36 
37 #include "../TrackPanel.h"
38 
39 #include "../AColor.h"
40 #include "../AllThemeResources.h"
41 #include "../AudioIOBase.h"
42 #include "../ImageManipulation.h"
43 #include "../KeyboardCapture.h"
44 #include "../Prefs.h"
45 #include "../Project.h"
46 #include "../ShuttleGui.h"
47 #include "../widgets/Grabber.h"
48 #include "../DeviceManager.h"
49 #include "../widgets/AudacityMessageBox.h"
50 #include "../widgets/Grabber.h"
51 
52 #if wxUSE_ACCESSIBILITY
53 #include "../widgets/WindowAccessible.h"
54 #endif
55 
57 
61 
62 BEGIN_EVENT_TABLE(DeviceToolBar, ToolBar)
63  EVT_CHOICE(wxID_ANY, DeviceToolBar::OnChoice)
64  EVT_COMMAND(wxID_ANY, EVT_CAPTURE_KEY, DeviceToolBar::OnCaptureKey)
66 
68 {
69  static int value = wxNewId();
70  return value;
71 }
72 
73 //Standard constructor
75 : ToolBar( project, DeviceBarID, XO("Device"), wxT("Device"), true )
76 {
77  wxTheApp->Bind( EVT_RESCANNED_DEVICES,
79 }
80 
82 {
83 }
84 
86 {
87  auto &toolManager = ToolManager::Get( project );
88  return *static_cast<DeviceToolBar*>( toolManager.GetToolBar(DeviceBarID) );
89 }
90 
92 {
93  return Get( const_cast<AudacityProject&>( project )) ;
94 }
95 
96 void DeviceToolBar::Create(wxWindow *parent)
97 {
98  ToolBar::Create(parent);
99 
100  // Simulate a size event to set initial meter placement/size
101  wxSizeEvent event(GetSize(), GetId());
102  event.SetEventObject(this);
103  GetEventHandler()->ProcessEvent(event);
104 }
105 
107 {
108  mInput = NULL;
109  mOutput = NULL;
110  mInputChannels = NULL;
111  mHost = NULL;
112 }
113 
115 {
116  SetBackgroundColour( theTheme.Colour( clrMedium ) );
117  DeinitChildren();
118 
119  // Hosts
120  mHost = safenew wxChoice(this,
121  wxID_ANY,
122  wxDefaultPosition,
123  wxDefaultSize);
124 #if wxUSE_ACCESSIBILITY
125  // so that name can be set on a standard control
126  mHost->SetAccessible(safenew WindowAccessible(mHost));
127 #endif
128  Add(mHost, 15, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 1);
129 
130  // Input device
132  wxID_ANY,
133  theTheme.Bitmap(bmpMic)), 0, wxALIGN_CENTER_VERTICAL);
134  mInput = safenew wxChoice(this,
135  wxID_ANY,
136  wxDefaultPosition,
137  wxDefaultSize);
138 #if wxUSE_ACCESSIBILITY
139  // so that name can be set on a standard control
140  mInput->SetAccessible(safenew WindowAccessible(mInput));
141 #endif
142  Add(mInput, 30, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 1);
143 
144  // Input channels
145  mInputChannels = safenew wxChoice(this,
146  wxID_ANY,
147  wxDefaultPosition,
148  wxDefaultSize);
149 #if wxUSE_ACCESSIBILITY
150  // so that name can be set on a standard control
152 #endif
153  Add(mInputChannels, 20, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 1);
154 
155  // Output device
157  wxID_ANY,
158  theTheme.Bitmap(bmpSpeaker)), 0, wxALIGN_CENTER_VERTICAL);
159  mOutput = safenew wxChoice(this,
160  wxID_ANY,
161  wxDefaultPosition,
162  wxDefaultSize);
163 #if wxUSE_ACCESSIBILITY
164  // so that name can be set on a standard control
165  mOutput->SetAccessible(safenew WindowAccessible(mOutput));
166 #endif
167  Add(mOutput, 30, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 1);
168 
169 #if defined(__WXGTK3__)
170  // Nothing special
171 #elif defined(__WXGTK__)
172  // Scale the font to fit inside (hopefully)
173  wxFont font = mHost->GetFont();
174  font.Scale((double) toolbarSingle / mHost->GetSize().GetHeight());
175 
176  // Set it
177  mHost->SetFont(font);
178  mInput->SetFont(font);
179  mInputChannels->SetFont(font);
180  mOutput->SetFont(font);
181 #endif
182 
183  mHost->Bind(wxEVT_SET_FOCUS,
185  this);
186  mHost->Bind(wxEVT_KILL_FOCUS,
188  this);
189  mOutput->Bind(wxEVT_SET_FOCUS,
191  this);
192  mOutput->Bind(wxEVT_KILL_FOCUS,
194  this);
195  mInput->Bind(wxEVT_SET_FOCUS,
197  this);
198  mInput->Bind(wxEVT_KILL_FOCUS,
200  this);
201  mInputChannels->Bind(wxEVT_SET_FOCUS,
203  this);
204  mInputChannels->Bind(wxEVT_KILL_FOCUS,
206  this);
207 
208  SetNames();
209 
210  RefillCombos();
211 }
212 
213 void DeviceToolBar::OnFocus(wxFocusEvent &event)
214 {
215  KeyboardCapture::OnFocus( *this, event );
216 }
217 
218 void DeviceToolBar::OnCaptureKey(wxCommandEvent &event)
219 {
220  wxKeyEvent *kevent = (wxKeyEvent *)event.GetEventObject();
221  int keyCode = kevent->GetKeyCode();
222 
223  // Pass UP/DOWN/LEFT/RIGHT through for input/output choice
224  if (FindFocus() == mInput && (keyCode == WXK_LEFT || keyCode == WXK_RIGHT
225  || keyCode == WXK_UP || keyCode == WXK_DOWN)) {
226  return;
227  }
228 
229  if (FindFocus() == mOutput && (keyCode == WXK_LEFT || keyCode == WXK_RIGHT
230  || keyCode == WXK_UP || keyCode == WXK_DOWN)) {
231  return;
232  }
233  event.Skip();
234 
235  return;
236 }
237 
239 {
240  wxString hostName;
241  wxString devName;
242  wxString sourceName;
243  wxString desc;
244  const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
245  const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
246 
247 
248  int hostSelectionIndex = mHost->GetSelection();
249  wxString oldHost = hostSelectionIndex >= 0 ? mHost->GetString(hostSelectionIndex) :
250  wxT("");
251  hostName = gPrefs->Read(wxT("/AudioIO/Host"), wxT(""));
252 
253  // if the prefs host name doesn't match the one displayed, it changed
254  // in another project's DeviceToolBar, so we need to repopulate everything.
255  if (oldHost != hostName)
256  FillHostDevices();
257 
258  devName = gPrefs->Read(wxT("/AudioIO/RecordingDevice"), wxT(""));
259  sourceName = gPrefs->Read(wxT("/AudioIO/RecordingSource"), wxT(""));
260  if (sourceName.empty())
261  desc = devName;
262  else
263  desc = devName + wxT(": ") + sourceName;
264 
265  if (mInput->GetStringSelection() != desc &&
266  mInput->FindString(desc) != wxNOT_FOUND) {
267  mInput->SetStringSelection(desc);
269  } else if (mInput->GetStringSelection() != desc && mInput->GetCount()) {
270  for (size_t i = 0; i < inMaps.size(); i++) {
271  if (inMaps[i].hostString == hostName &&
272  MakeDeviceSourceString(&inMaps[i]) == mInput->GetString(0)) {
273  // use the default. It should exist but check just in case, falling back on the 0 index.
274  DeviceSourceMap *defaultMap = DeviceManager::Instance()->GetDefaultInputDevice(inMaps[i].hostIndex);
275  if (defaultMap) {
276  mInput->SetStringSelection(MakeDeviceSourceString(defaultMap));
277  SetDevices(defaultMap, NULL);
278  } else {
279  //use the first item (0th index) if we have no familiar devices
280  mInput->SetSelection(0);
281  SetDevices(&inMaps[i], NULL);
282  }
283  break;
284  }
285  }
286  }
287 
288  devName = gPrefs->Read(wxT("/AudioIO/PlaybackDevice"), wxT(""));
289  sourceName = gPrefs->Read(wxT("/AudioIO/PlaybackSource"), wxT(""));
290  if (sourceName.empty())
291  desc = devName;
292  else
293  desc = devName + wxT(": ") + sourceName;
294 
295  if (mOutput->GetStringSelection() != desc &&
296  mOutput->FindString(desc) != wxNOT_FOUND) {
297  mOutput->SetStringSelection(desc);
298  } else if (mOutput->GetStringSelection() != desc &&
299  mOutput->GetCount()) {
300  for (size_t i = 0; i < outMaps.size(); i++) {
301  if (outMaps[i].hostString == hostName &&
302  MakeDeviceSourceString(&outMaps[i]) == mOutput->GetString(0)) {
303  // use the default. It should exist but check just in case, falling back on the 0 index.
304  DeviceSourceMap *defaultMap = DeviceManager::Instance()->GetDefaultOutputDevice(outMaps[i].hostIndex);
305  if (defaultMap) {
306  mOutput->SetStringSelection(MakeDeviceSourceString(defaultMap));
307  SetDevices(NULL, defaultMap);
308  } else {
309  //use the first item (0th index) if we have no familiar devices
310  mOutput->SetSelection(0);
311  SetDevices(NULL, &outMaps[i]);
312  }
313  break;
314  }
315  }
316  }
317 
318  long oldChannels, newChannels;
319  oldChannels = mInputChannels->GetSelection() + 1;
320  gPrefs->Read(wxT("/AudioIO/RecordChannels"), &newChannels, 0);
321  if (newChannels > 0 && oldChannels != newChannels)
322  mInputChannels->SetSelection(newChannels - 1);
323 
324  if (!hostName.empty() && mHost->GetStringSelection() != hostName)
325  mHost->SetStringSelection(hostName);
326 
328 
329  // Set label to pull in language change
330  SetLabel(XO("Device"));
331 
332  // Give base class a chance
334 
335  Layout();
336  Refresh();
337 }
338 
340 {
341  if (id == DeviceToolbarPrefsID())
342  UpdatePrefs();
344 }
345 
346 
348 {
349  auto gAudioIO = AudioIOBase::Get();
350  if (gAudioIO) {
351  // we allow changes when monitoring, but not when recording
352  bool audioStreamActive = gAudioIO->IsStreamActive() && !gAudioIO->IsMonitoring();
353 
354  // Here we should relinquish focus
355  if (audioStreamActive) {
356  wxWindow *focus = wxWindow::FindFocus();
357  if (focus == mHost || focus == mInput || focus == mOutput || focus == mInputChannels)
358  TrackPanel::Get( mProject ).SetFocus();
359  }
360 
361  mHost->Enable(!audioStreamActive);
362  mInput->Enable(!audioStreamActive);
363  mOutput->Enable(!audioStreamActive);
364  mInputChannels->Enable(!audioStreamActive);
365  }
366 }
367 
369 {
370  /* i18n-hint: (noun) It's the device used for playback.*/
371  mOutput->SetName(_("Playback Device"));
372  /* i18n-hint: (noun) It's the device used for recording.*/
373  mInput->SetName(_("Recording Device"));
374  mHost->SetName(_("Audio Host"));
375  mInputChannels->SetName(_("Recording Channels"));
376 }
377 
379 {
380 #if wxUSE_TOOLTIPS
381  SetNames();
382  mOutput->SetToolTip(mOutput->GetName() + wxT(" - ") + mOutput->GetStringSelection());
383  mInput->SetToolTip(mInput->GetName() + wxT(" - ") + mInput->GetStringSelection());
384  mHost->SetToolTip(mHost->GetName() + wxT(" - ") + mHost->GetStringSelection());
385  mInputChannels->SetToolTip(mInputChannels->GetName() + wxT(" - ") + mInputChannels->GetStringSelection());
386 #endif
387 }
388 
390 {
391  FillHosts();
392  FillHostDevices();
394  // make the device display selection reflect the prefs if they exist
395  UpdatePrefs();
396 }
397 
399 {
400  const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
401  const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
402 
403  wxArrayString hosts;
404 
405  // go over our lists add the host to the list if it isn't there yet
406 
407  for (auto & device : inMaps) {
408  if (!make_iterator_range(hosts).contains(device.hostString)) {
409  hosts.push_back(device.hostString);
410  }
411  }
412 
413  for (auto & device : outMaps) {
414  if (!make_iterator_range(hosts).contains(device.hostString)) {
415  hosts.push_back(device.hostString);
416  }
417  }
418 
419  mHost->Clear();
420  mHost->Append(hosts);
421 
422  if (hosts.size() == 0) {
423  mHost->Enable(false);
424  }
425 
426  mHost->SetMinSize(wxSize(50, wxDefaultCoord));
427 }
428 
430 {
431  const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
432  const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
433 
434  //read what is in the prefs
435  wxString host = gPrefs->Read(wxT("/AudioIO/Host"), wxT(""));
436  int foundHostIndex = -1;
437 
438  // if the host is not in the hosts combo then we rescanned.
439  // set it to blank so we search for another host.
440  if (mHost->FindString(host) == wxNOT_FOUND) {
441  host = wxT("");
442  }
443 
444  for (auto & device : outMaps) {
445  if (device.hostString == host) {
446  foundHostIndex = device.hostIndex;
447  break;
448  }
449  }
450 
451  if (foundHostIndex == -1) {
452  for (auto & device : inMaps) {
453  if (device.hostString == host) {
454  foundHostIndex = device.hostIndex;
455  break;
456  }
457  }
458  }
459 
460  // If no host was found based on the prefs device host, load the first available one
461  if (foundHostIndex == -1) {
462  if (outMaps.size()) {
463  foundHostIndex = outMaps[0].hostIndex;
464  }
465  else if (inMaps.size()) {
466  foundHostIndex = inMaps[0].hostIndex;
467  }
468  }
469 
470  // Make sure in/out are clear in case no host was found
471  mInput->Clear();
472  mOutput->Clear();
473 
474  // If we still have no host it means no devices, in which case do nothing.
475  if (foundHostIndex == -1) {
476  return;
477  }
478 
479  // Repopulate the Input/Output device list available to the user
480  for (auto & device : inMaps) {
481  if (foundHostIndex == device.hostIndex) {
482  mInput->Append(MakeDeviceSourceString(&device));
483  if (host.empty()) {
484  host = device.hostString;
485  gPrefs->Write(wxT("/AudioIO/Host"), host);
486  mHost->SetStringSelection(host);
487  }
488  }
489  }
490  mInput->Enable(mInput->GetCount() ? true : false);
491 
492  mInput->SetMinSize(wxSize(50, wxDefaultCoord));
493 
494  for (auto & device : outMaps) {
495  if (foundHostIndex == device.hostIndex) {
496  mOutput->Append(MakeDeviceSourceString(&device));
497  if (host.empty()) {
498  host = device.hostString;
499  gPrefs->Write(wxT("/AudioIO/Host"), host);
500  gPrefs->Flush();
501  mHost->SetStringSelection(host);
502  }
503  }
504  }
505  mOutput->Enable(mOutput->GetCount() ? true : false);
506 
507  mOutput->SetMinSize(wxSize(50, wxDefaultCoord));
508 
509  // The setting of the Device is left up to OnChoice
510 }
511 
513 {
514  const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
515  wxString host = gPrefs->Read(wxT("/AudioIO/Host"), wxT(""));
516  wxString device = gPrefs->Read(wxT("/AudioIO/RecordingDevice"), wxT(""));
517  wxString source = gPrefs->Read(wxT("/AudioIO/RecordingSource"), wxT(""));
518  long oldChannels = 2, newChannels;
519 
520  gPrefs->Read(wxT("/AudioIO/RecordChannels"), &oldChannels);
521  mInputChannels->Clear();
522  for (auto & dev: inMaps) {
523  if (source == dev.sourceString &&
524  device == dev.deviceString &&
525  host == dev.hostString) {
526 
527  // add one selection for each channel of this source
528  for (size_t j = 0; j < (unsigned int) dev.numChannels; j++) {
529  wxString name;
530 
531  if (j == 0) {
532  name = _("1 (Mono) Recording Channel");
533  }
534  else if (j == 1) {
535  name = _("2 (Stereo) Recording Channels");
536  }
537  else {
538  name = wxString::Format(wxT("%d"), (int) j + 1);
539  }
540  mInputChannels->Append(name);
541  }
542  newChannels = dev.numChannels;
543  if (oldChannels <= newChannels && oldChannels >= 1) {
544  newChannels = oldChannels;
545  }
546  if (newChannels >= 1) {
547  mInputChannels->SetSelection(newChannels - 1);
548  }
549  gPrefs->Write(wxT("/AudioIO/RecordChannels"), newChannels);
550  break;
551  }
552  }
553  mInputChannels->Enable(mInputChannels->GetCount() ? true : false);
554 
555  mInputChannels->SetMinSize(wxSize(50, wxDefaultCoord));
556 }
557 
558 void DeviceToolBar::OnRescannedDevices( wxCommandEvent &event )
559 {
560  event.Skip();
561  // Hosts may have disappeared or appeared so a complete repopulate is needed.
562  RefillCombos();
563 }
564 
565 //return 1 if host changed, 0 otherwise.
567 {
568  int hostSelectionIndex;
569  hostSelectionIndex = mHost->GetSelection();
570 
571  wxString oldHost = gPrefs->Read(wxT("/AudioIO/Host"), wxT(""));
572  wxString newHost = hostSelectionIndex >= 0 ? mHost->GetString(hostSelectionIndex) :
573  oldHost;
574 
575  if (oldHost == newHost)
576  return 0;
577 
578  //change the host and switch to correct devices.
579  gPrefs->Write(wxT("/AudioIO/Host"), newHost);
580  gPrefs->Flush();
581 
582  // populate the devices
583  FillHostDevices();
584 
585  return 1;
586 }
587 
589 {
590  if (in) {
591  gPrefs->Write(wxT("/AudioIO/RecordingDevice"), in->deviceString);
592  gPrefs->Write(wxT("/AudioIO/RecordingSourceIndex"), in->sourceIndex);
593  if (in->totalSources >= 1) {
594  gPrefs->Write(wxT("/AudioIO/RecordingSource"), in->sourceString);
595  } else {
596  gPrefs->Write(wxT("/AudioIO/RecordingSource"), wxT(""));
597  }
598  gPrefs->Flush();
599 
601  }
602 
603  if (out) {
604  gPrefs->Write(wxT("/AudioIO/PlaybackDevice"), out->deviceString);
605  if (out->totalSources >= 1) {
606  gPrefs->Write(wxT("/AudioIO/PlaybackSource"), out->sourceString);
607  } else {
608  gPrefs->Write(wxT("/AudioIO/PlaybackSource"), wxT(""));
609  }
610  gPrefs->Flush();
611  }
612 }
613 
614 void DeviceToolBar::ChangeDevice(bool isInput)
615 {
616  int newIndex = -1;
617  wxChoice *combo = isInput ? mInput :mOutput;
618  size_t i;
619 
620  int selectionIndex = combo->GetSelection();
621  wxString host = gPrefs->Read(wxT("/AudioIO/Host"), wxT(""));
622  const std::vector<DeviceSourceMap> &maps = isInput ? DeviceManager::Instance()->GetInputDeviceMaps()
624 
625  // Find device indices for input and output
626  if (selectionIndex >= 0 ) {
627  wxString newDevice = combo->GetStringSelection();
628  for (i = 0; i < maps.size(); ++i) {
629  wxString name;
630  name = MakeDeviceSourceString(&maps[i]);
631  if (name == newDevice && maps[i].hostString == host) {
632  newIndex = i;
633  }
634  }
635  }
636 
637  if (newIndex < 0) {
638  wxLogDebug(wxT("DeviceToolBar::OnChoice(): couldn't find device indices"));
639  return;
640  }
641 
642  SetDevices(isInput ? &maps[newIndex] : NULL,
643  isInput ? NULL : &maps[newIndex]);
644 }
645 
646 void DeviceToolBar::OnChoice(wxCommandEvent &event)
647 {
648  wxObject *eventObject = event.GetEventObject();
649  //if we've changed hosts, we've handled the device switching already.
650  if (eventObject == mHost) {
651  ChangeHost();
652  } else if (eventObject == mInputChannels) {
653  int channelsSelectionIndex = mInputChannels->GetSelection();
654  if (channelsSelectionIndex >= 0)
655  gPrefs->Write(wxT("/AudioIO/RecordChannels"),channelsSelectionIndex + 1);
656  } else if (eventObject == mInput) {
657  ChangeDevice(true);
658  }
659  else if (eventObject == mOutput) {
660  ChangeDevice(false);
661  }
662 
663  auto gAudioIO = AudioIOBase::Get();
664  if (gAudioIO) {
665  // We cannot have gotten here if gAudioIO->IsAudioTokenActive(),
666  // per the setting of AudioIONotBusyFlag and AudioIOBusyFlag in
667  // AudacityProject::GetUpdateFlags().
668  // However, we can have an invalid audio token (so IsAudioTokenActive()
669  // is false), but be monitoring.
670  // If monitoring, have to stop the stream, so HandleDeviceChange() can work.
671  // We could disable the Preferences command while monitoring, i.e.,
672  // set AudioIONotBusyFlag/AudioIOBusyFlag according to monitoring, as well.
673  // Instead allow it because unlike recording, for example, monitoring
674  // is not clearly something that should prohibit changing device.
675  // TODO: We *could* be smarter in this method and call HandleDeviceChange()
676  // only when the device choices actually changed. True of lots of prefs!
677  // As is, we always stop monitoring before handling the device change.
678  if (gAudioIO->IsMonitoring())
679  {
680  gAudioIO->StopStream();
681  while (gAudioIO->IsBusy())
682  wxMilliSleep(100);
683  }
684  gAudioIO->HandleDeviceChange();
685  }
686 
687  wxTheApp->AddPendingEvent(wxCommandEvent{
688  EVT_PREFS_UPDATE, DeviceToolbarPrefsID() });
689 }
690 
692 {
693  ShowComboDialog(mInput, XO("Select Recording Device"));
694 }
696 {
697  ShowComboDialog(mOutput, XO("Select Playback Device"));
698 }
700 {
701  ShowComboDialog(mHost, XO("Select Audio Host"));
702 }
704 {
705  ShowComboDialog(mInputChannels, XO("Select Recording Channels"));
706 }
707 
708 void DeviceToolBar::ShowComboDialog(wxChoice *combo, const TranslatableString &title)
709 {
710  if (!combo || combo->GetCount() == 0) {
711  AudacityMessageBox( XO("Device information is not available.") );
712  return;
713  }
714 
715 #if USE_PORTMIXER
716  wxArrayStringEx inputSources = combo->GetStrings();
717 
718  wxDialogWrapper dlg(nullptr, wxID_ANY, title);
719  dlg.SetName();
720  ShuttleGui S(&dlg, eIsCreating);
721  wxChoice *c;
722 
723  S.StartVerticalLay(true);
724  {
725  S.StartHorizontalLay(wxCENTER, false);
726  {
727  c = S.AddChoice( Verbatim( combo->GetName() ),
728  transform_container<TranslatableStrings>( inputSources, Verbatim ),
729  combo->GetSelection());
730  c->SetMinSize(c->GetBestSize());
731  }
732  S.EndHorizontalLay();
733  }
734  S.EndVerticalLay();
735  S.AddStandardButtons();
736 
737  dlg.GetSizer()->SetSizeHints(&dlg);
738  dlg.Center();
739 
740  if (dlg.ShowModal() == wxID_OK)
741  {
742  wxCommandEvent dummyEvent;
743  dummyEvent.SetEventObject(combo);
744  // SetSelection() doesn't send an event, so we call OnChoice explicitly
745  combo->SetSelection(c->GetSelection());
746  OnChoice(dummyEvent);
747  }
748 #endif
749 }
750 
752  []( AudacityProject &project ){
753  return ToolBar::Holder{ safenew DeviceToolBar{ project } }; }
754 };
755 
756 namespace {
758  /* i18n-hint: Clicking this menu item shows the toolbar
759  that manages devices */
760  DeviceBarID, wxT("ShowDeviceTB"), XXO("&Device Toolbar")
761 };
762 }
763 
DeviceToolBar::ChangeHost
int ChangeHost()
Definition: DeviceToolBar.cpp:566
DeviceToolBar::DeinitChildren
void DeinitChildren()
Definition: DeviceToolBar.cpp:106
TranslatableString
Definition: Types.h:290
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:36
ShuttleGuiBase::AddChoice
wxChoice * AddChoice(const TranslatableString &Prompt, const TranslatableStrings &choices, int Selected=-1)
Definition: ShuttleGui.cpp:391
ToolManager.h
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1177
DeviceToolBar::OnRescannedDevices
void OnRescannedDevices(wxCommandEvent &)
Definition: DeviceToolBar.cpp:558
make_iterator_range
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:625
DeviceToolBar::Create
void Create(wxWindow *parent) override
Definition: DeviceToolBar.cpp:96
DeviceToolBar::SetNames
void SetNames()
Definition: DeviceToolBar.cpp:368
DeviceToolBar::FillHosts
void FillHosts()
Definition: DeviceToolBar.cpp:398
IMPLEMENT_CLASS
IMPLEMENT_CLASS(DeviceToolBar, ToolBar)
DeviceToolBar
A toobar to allow easier changing of input and output devices .
Definition: DeviceToolBar.h:24
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:67
DeviceToolBar::Get
static DeviceToolBar & Get(AudacityProject &project)
Definition: DeviceToolBar.cpp:85
DeviceToolBar::ChangeDevice
void ChangeDevice(bool isInput)
Definition: DeviceToolBar.cpp:614
EVT_COMMAND
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
Definition: LabelDialog.cpp:91
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: AudacityMessageBox.h:20
DeviceToolBar::ShowHostDialog
void ShowHostDialog()
Definition: DeviceToolBar.cpp:699
ToolBar::mProject
AudacityProject & mProject
Definition: ToolBar.h:231
DeviceToolBar::SetDevices
void SetDevices(const DeviceSourceMap *in, const DeviceSourceMap *out)
Definition: DeviceToolBar.cpp:588
ToolBar::SetLabel
void SetLabel(const wxString &label) override
Definition: ToolBar.cpp:398
DeviceToolBar::ShowComboDialog
void ShowComboDialog(wxChoice *combo, const TranslatableString &title)
Definition: DeviceToolBar.cpp:708
ToolManager::Get
static ToolManager & Get(AudacityProject &project)
Definition: ToolManager.cpp:355
DeviceBarID
@ DeviceBarID
Definition: ToolBar.h:77
MakeDeviceSourceString
wxString MakeDeviceSourceString(const DeviceSourceMap *map)
Definition: DeviceManager.cpp:66
DeviceToolBar::mHost
wxChoice * mHost
Definition: DeviceToolBar.h:75
DeviceSourceMap::deviceString
wxString deviceString
Definition: DeviceManager.h:44
AStaticBitmap
A widget for bitmaps which ignores the erase event for flicker-free use.
Definition: Grabber.h:150
TrackPanel::Get
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:222
XO
#define XO(s)
Definition: Internat.h:32
DeviceToolBar::ShowChannelsDialog
void ShowChannelsDialog()
Definition: DeviceToolBar.cpp:703
KeyboardCapture::OnFocus
void OnFocus(wxWindow &window, wxFocusEvent &event)
a function useful to implement a focus event handler The window releases the keyboard if the event is...
Definition: KeyboardCapture.cpp:94
ToolBar::Holder
wxWindowPtr< ToolBar > Holder
Definition: ToolBar.h:98
DeviceToolBar::ShowOutputDialog
void ShowOutputDialog()
Definition: DeviceToolBar.cpp:695
DeviceToolBar::OnCaptureKey
void OnCaptureKey(wxCommandEvent &event)
Definition: DeviceToolBar.cpp:218
factory
static RegisteredToolbarFactory factory
Definition: DeviceToolBar.cpp:751
DeviceToolBar.h
wxArrayStringEx
Definition: MemoryX.h:663
AttachedToolBarMenuItem
Definition: ToolManager.h:224
desc
const TranslatableString desc
Definition: ExportPCM.cpp:56
DeviceSourceMap
Definition: DeviceManager.h:37
ThemeBase::Bitmap
wxBitmap & Bitmap(int iIndex)
Definition: Theme.cpp:1211
DeviceToolBar::FillInputChannels
void FillInputChannels()
Definition: DeviceToolBar.cpp:512
DeviceToolBar::ShowInputDialog
void ShowInputDialog()
Definition: DeviceToolBar.cpp:691
PrefsListener::UpdateSelectedPrefs
virtual void UpdateSelectedPrefs(int id)
Definition: Prefs.cpp:99
DeviceToolBar::RefillCombos
void RefillCombos()
Definition: DeviceToolBar.cpp:389
DeviceToolBar::UpdatePrefs
void UpdatePrefs() override
Definition: DeviceToolBar.cpp:238
DeviceToolBar::EnableDisableButtons
void EnableDisableButtons() override
Definition: DeviceToolBar.cpp:347
DeviceManager::GetDefaultOutputDevice
DeviceSourceMap * GetDefaultOutputDevice(int hostIndex)
Definition: DeviceManager.cpp:96
XXO
#define XXO(s)
Definition: Internat.h:45
ShuttleGuiBase::EndHorizontalLay
void EndHorizontalLay()
Definition: ShuttleGui.cpp:1170
DeviceToolBar::~DeviceToolBar
virtual ~DeviceToolBar()
Definition: DeviceToolBar.cpp:81
ShuttleGuiBase::StartHorizontalLay
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:1160
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1196
DeviceToolBar::DeviceToolBar
DeviceToolBar(AudacityProject &project)
Definition: DeviceToolBar.cpp:74
ToolBar::UpdatePrefs
void UpdatePrefs() override
Definition: ToolBar.cpp:605
name
const TranslatableString name
Definition: Distortion.cpp:98
AudioIOBase::Get
static AudioIOBase * Get()
Definition: AudioIOBase.cpp:94
DeviceToolBar::FillHostDevices
void FillHostDevices()
Definition: DeviceToolBar.cpp:429
WindowAccessible
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
DeviceToolBar::Populate
void Populate() override
Definition: DeviceToolBar.cpp:114
wxDialogWrapper::SetName
void SetName(const TranslatableString &title)
Definition: wxPanelWrapper.cpp:76
ToolBar::Create
virtual void Create(wxWindow *parent)
Definition: ToolBar.cpp:475
DeviceSourceMap::totalSources
int totalSources
Definition: DeviceManager.h:41
DeviceSourceMap::sourceIndex
int sourceIndex
Definition: DeviceManager.h:39
DeviceToolBar::RegenerateTooltips
void RegenerateTooltips() override
Definition: DeviceToolBar.cpp:378
RegisteredToolbarFactory
Definition: ToolBar.h:257
wxDialogWrapper
Definition: wxPanelWrapper.h:81
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:151
DeviceToolBar::mInputChannels
wxChoice * mInputChannels
Definition: DeviceToolBar.h:74
_
#define _(s)
Definition: Internat.h:76
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:112
DeviceToolbarPrefsID
static int DeviceToolbarPrefsID()
Methods for DeviceToolBar.
Definition: DeviceToolBar.cpp:67
Verbatim
TranslatableString Verbatim(wxString str)
Definition: Types.h:573
DeviceToolBar::OnChoice
void OnChoice(wxCommandEvent &event)
Definition: DeviceToolBar.cpp:646
DeviceManager::GetDefaultInputDevice
DeviceSourceMap * GetDefaultInputDevice(int hostIndex)
Definition: DeviceManager.cpp:100
DeviceManager::Instance
static DeviceManager * Instance()
Gets the singleton instance.
Definition: DeviceManager.cpp:47
ToolBar
Works with ToolManager and ToolDock to provide a dockable window in which buttons can be placed.
Definition: ToolBar.h:94
anonymous_namespace{DeviceToolBar.cpp}::sAttachment
AttachedToolBarMenuItem sAttachment
Definition: DeviceToolBar.cpp:757
ThemeBase::Colour
wxColour & Colour(int iIndex)
Definition: Theme.cpp:1192
DeviceManager::GetInputDeviceMaps
const std::vector< DeviceSourceMap > & GetInputDeviceMaps()
Definition: DeviceManager.cpp:52
ShuttleGui::AddStandardButtons
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxWindow *extra=NULL)
Definition: ShuttleGui.cpp:2406
DeviceSourceMap::sourceString
wxString sourceString
Definition: DeviceManager.h:43
DeviceManager::GetOutputDeviceMaps
const std::vector< DeviceSourceMap > & GetOutputDeviceMaps()
Definition: DeviceManager.cpp:58
theTheme
AUDACITY_DLL_API Theme theTheme
Definition: Theme.cpp:201
DeviceToolBar::UpdateSelectedPrefs
void UpdateSelectedPrefs(int) override
Definition: DeviceToolBar.cpp:339
DeviceToolBar::OnFocus
void OnFocus(wxFocusEvent &event)
Definition: DeviceToolBar.cpp:213
safenew
#define safenew
Definition: MemoryX.h:8
toolbarSingle
#define toolbarSingle
Definition: ToolBar.h:55
DeviceToolBar::mInput
wxChoice * mInput
Definition: DeviceToolBar.h:72
DeviceToolBar::mOutput
wxChoice * mOutput
Definition: DeviceToolBar.h:73
END_EVENT_TABLE
END_EVENT_TABLE()
ToolBar::Add
void Add(wxWindow *window, int proportion=0, int flag=wxALIGN_TOP, int border=0, wxObject *userData=NULL)
Definition: ToolBar.cpp:686
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:638