Audacity 3.2.0
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#include <thread>
22
23// For compilers that support precompilation, includes "wx/wx.h".
24#include <wx/wxprec.h>
25
26#include <wx/setup.h> // for wxUSE_* macros
27
28#ifndef WX_PRECOMP
29#include <wx/app.h>
30#include <wx/choice.h>
31#include <wx/event.h>
32#include <wx/intl.h>
33#include <wx/settings.h>
34#include <wx/sizer.h>
35#include <wx/statbmp.h>
36#include <wx/stattext.h>
37#include <wx/tooltip.h>
38#endif
39
40#include "../TrackPanel.h"
41
42#include "AColor.h"
43#include "AllThemeResources.h"
44#include "AudioIOBase.h"
45#include "ImageManipulation.h"
46#include "../KeyboardCapture.h"
47#include "Prefs.h"
48#include "Project.h"
49#include "../ShuttleGui.h"
50#include "../widgets/Grabber.h"
51#include "DeviceManager.h"
52#include "../widgets/AudacityMessageBox.h"
53#include "../widgets/Grabber.h"
54
55#if wxUSE_ACCESSIBILITY
56#include "../widgets/WindowAccessible.h"
57#endif
58
60
64
65BEGIN_EVENT_TABLE(DeviceToolBar, ToolBar)
66 EVT_CHOICE(wxID_ANY, DeviceToolBar::OnChoice)
67 EVT_COMMAND(wxID_ANY, EVT_CAPTURE_KEY, DeviceToolBar::OnCaptureKey)
69
71{
72 static int value = wxNewId();
73 return value;
74}
75
76//Standard constructor
78: ToolBar( project, DeviceBarID, XO("Device"), wxT("Device"), true )
79{
82}
83
85{
86}
87
89{
90 auto &toolManager = ToolManager::Get( project );
91 return *static_cast<DeviceToolBar*>( toolManager.GetToolBar(DeviceBarID) );
92}
93
95{
96 return Get( const_cast<AudacityProject&>( project )) ;
97}
98
99void DeviceToolBar::Create(wxWindow *parent)
100{
101 ToolBar::Create(parent);
102
103 // Simulate a size event to set initial meter placement/size
104 wxSizeEvent event(GetSize(), GetId());
105 event.SetEventObject(this);
106 GetEventHandler()->ProcessEvent(event);
107}
108
110{
111 mInput = NULL;
112 mOutput = NULL;
113 mInputChannels = NULL;
114 mHost = NULL;
115}
116
118{
119 SetBackgroundColour( theTheme.Colour( clrMedium ) );
121
122 // Hosts
123 mHost = safenew wxChoice(this,
124 wxID_ANY,
125 wxDefaultPosition,
126 wxDefaultSize);
127#if wxUSE_ACCESSIBILITY
128 // so that name can be set on a standard control
129 mHost->SetAccessible(safenew WindowAccessible(mHost));
130#endif
131 Add(mHost, 15, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 1);
132
133 // Input device
135 wxID_ANY,
136 theTheme.Bitmap(bmpMic)), 0, wxALIGN_CENTER_VERTICAL);
137 mInput = safenew wxChoice(this,
138 wxID_ANY,
139 wxDefaultPosition,
140 wxDefaultSize);
141#if wxUSE_ACCESSIBILITY
142 // so that name can be set on a standard control
143 mInput->SetAccessible(safenew WindowAccessible(mInput));
144#endif
145 Add(mInput, 30, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 1);
146
147 // Input channels
148 mInputChannels = safenew wxChoice(this,
149 wxID_ANY,
150 wxDefaultPosition,
151 wxDefaultSize);
152#if wxUSE_ACCESSIBILITY
153 // so that name can be set on a standard control
155#endif
156 Add(mInputChannels, 20, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 1);
157
158 // Output device
160 wxID_ANY,
161 theTheme.Bitmap(bmpSpeaker)), 0, wxALIGN_CENTER_VERTICAL);
162 mOutput = safenew wxChoice(this,
163 wxID_ANY,
164 wxDefaultPosition,
165 wxDefaultSize);
166#if wxUSE_ACCESSIBILITY
167 // so that name can be set on a standard control
168 mOutput->SetAccessible(safenew WindowAccessible(mOutput));
169#endif
170 Add(mOutput, 30, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, 1);
171
172#if defined(__WXGTK3__)
173 // Nothing special
174#elif defined(__WXGTK__)
175 // Scale the font to fit inside (hopefully)
176 wxFont font = mHost->GetFont();
177 font.Scale((double) toolbarSingle / mHost->GetSize().GetHeight());
178
179 // Set it
180 mHost->SetFont(font);
181 mInput->SetFont(font);
182 mInputChannels->SetFont(font);
183 mOutput->SetFont(font);
184#endif
185
186 mHost->Bind(wxEVT_SET_FOCUS,
188 this);
189 mHost->Bind(wxEVT_KILL_FOCUS,
191 this);
192 mOutput->Bind(wxEVT_SET_FOCUS,
194 this);
195 mOutput->Bind(wxEVT_KILL_FOCUS,
197 this);
198 mInput->Bind(wxEVT_SET_FOCUS,
200 this);
201 mInput->Bind(wxEVT_KILL_FOCUS,
203 this);
204 mInputChannels->Bind(wxEVT_SET_FOCUS,
206 this);
207 mInputChannels->Bind(wxEVT_KILL_FOCUS,
209 this);
210
211 SetNames();
212
213 RefillCombos();
214}
215
216void DeviceToolBar::OnFocus(wxFocusEvent &event)
217{
218 KeyboardCapture::OnFocus( *this, event );
219}
220
221void DeviceToolBar::OnCaptureKey(wxCommandEvent &event)
222{
223 wxKeyEvent *kevent = (wxKeyEvent *)event.GetEventObject();
224 int keyCode = kevent->GetKeyCode();
225
226 // Pass UP/DOWN/LEFT/RIGHT through for input/output choice
227 if (FindFocus() == mInput && (keyCode == WXK_LEFT || keyCode == WXK_RIGHT
228 || keyCode == WXK_UP || keyCode == WXK_DOWN)) {
229 return;
230 }
231
232 if (FindFocus() == mOutput && (keyCode == WXK_LEFT || keyCode == WXK_RIGHT
233 || keyCode == WXK_UP || keyCode == WXK_DOWN)) {
234 return;
235 }
236 event.Skip();
237
238 return;
239}
240
242{
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 wxString{};
251 auto hostName = AudioIOHost.Read();
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)
257
258 auto devName = AudioIORecordingDevice.Read();
259 auto sourceName = AudioIORecordingSource.Read();
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 = AudioIOPlaybackDevice.Read();
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;
319 oldChannels = mInputChannels->GetSelection() + 1;
320 auto newChannels = AudioIORecordChannels.ReadWithDefault(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();
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 auto host = AudioIOHost.Read();
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 AudioIOHost.Write(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 AudioIOHost.Write(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 auto host = AudioIOHost.Read();
516 auto device = AudioIORecordingDevice.Read();
517 auto source = AudioIORecordingSource.Read();
518 long newChannels;
519
520 auto oldChannels = AudioIORecordChannels.Read();
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 AudioIORecordChannels.Write(newChannels);
550 break;
551 }
552 }
553 mInputChannels->Enable(mInputChannels->GetCount() ? true : false);
554
555 mInputChannels->SetMinSize(wxSize(50, wxDefaultCoord));
556}
557
559{
560 // 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 auto oldHost = AudioIOHost.Read();
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 AudioIOHost.Write(newHost);
580 gPrefs->Flush();
581
582 // populate the devices
584
585 return 1;
586}
587
589{
590 if (in) {
593 if (in->totalSources >= 1)
595 else
597 gPrefs->Flush();
598
600 }
601
602 if (out) {
604 if (out->totalSources >= 1) {
605 gPrefs->Write(wxT("/AudioIO/PlaybackSource"), out->sourceString);
606 } else {
607 gPrefs->Write(wxT("/AudioIO/PlaybackSource"), wxT(""));
608 }
609 gPrefs->Flush();
610 }
611}
612
614{
615 int newIndex = -1;
616 wxChoice *combo = isInput ? mInput :mOutput;
617 size_t i;
618
619 int selectionIndex = combo->GetSelection();
620 auto host = AudioIOHost.Read();
621 const std::vector<DeviceSourceMap> &maps = isInput ? DeviceManager::Instance()->GetInputDeviceMaps()
623
624 // Find device indices for input and output
625 if (selectionIndex >= 0 ) {
626 wxString newDevice = combo->GetStringSelection();
627 for (i = 0; i < maps.size(); ++i) {
628 wxString name;
629 name = MakeDeviceSourceString(&maps[i]);
630 if (name == newDevice && maps[i].hostString == host) {
631 newIndex = i;
632 }
633 }
634 }
635
636 if (newIndex < 0) {
637 wxLogDebug(wxT("DeviceToolBar::OnChoice(): couldn't find device indices"));
638 return;
639 }
640
641 SetDevices(isInput ? &maps[newIndex] : NULL,
642 isInput ? NULL : &maps[newIndex]);
643}
644
645void DeviceToolBar::OnChoice(wxCommandEvent &event)
646{
647 wxObject *eventObject = event.GetEventObject();
648 //if we've changed hosts, we've handled the device switching already.
649 if (eventObject == mHost) {
650 ChangeHost();
651 } else if (eventObject == mInputChannels) {
652 int channelsSelectionIndex = mInputChannels->GetSelection();
653 if (channelsSelectionIndex >= 0)
654 AudioIORecordChannels.Write(channelsSelectionIndex + 1);
655 } else if (eventObject == mInput) {
656 ChangeDevice(true);
657 }
658 else if (eventObject == mOutput) {
659 ChangeDevice(false);
660 }
661
662 auto gAudioIO = AudioIOBase::Get();
663 if (gAudioIO) {
664 // We cannot have gotten here if gAudioIO->IsAudioTokenActive(),
665 // per the setting of AudioIONotBusyFlag and AudioIOBusyFlag in
666 // AudacityProject::GetUpdateFlags().
667 // However, we can have an invalid audio token (so IsAudioTokenActive()
668 // is false), but be monitoring.
669 // If monitoring, have to stop the stream, so HandleDeviceChange() can work.
670 // We could disable the Preferences command while monitoring, i.e.,
671 // set AudioIONotBusyFlag/AudioIOBusyFlag according to monitoring, as well.
672 // Instead allow it because unlike recording, for example, monitoring
673 // is not clearly something that should prohibit changing device.
674 // TODO: We *could* be smarter in this method and call HandleDeviceChange()
675 // only when the device choices actually changed. True of lots of prefs!
676 // As is, we always stop monitoring before handling the device change.
677 if (gAudioIO->IsMonitoring())
678 {
679 gAudioIO->StopStream();
680 while (gAudioIO->IsBusy()) {
681 using namespace std::chrono;
682 std::this_thread::sleep_for(100ms);
683 }
684 }
685 gAudioIO->HandleDeviceChange();
686 }
687
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
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
756namespace {
758 /* i18n-hint: Clicking this menu item shows the toolbar
759 that manages devices */
760 DeviceBarID, wxT("ShowDeviceTB"), XXO("&Device Toolbar")
761};
762}
763
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
StringSetting AudioIORecordingSource
StringSetting AudioIOPlaybackDevice
StringSetting AudioIORecordingDevice
StringSetting AudioIOHost
IntSetting AudioIORecordingSourceIndex
IntSetting AudioIORecordChannels
END_EVENT_TABLE()
DeviceChangeMessage
Definition: DeviceChange.h:16
wxString MakeDeviceSourceString(const DeviceSourceMap *map)
static int DeviceToolbarPrefsID()
Methods for DeviceToolBar.
IMPLEMENT_CLASS(DeviceToolBar, ToolBar)
static RegisteredToolbarFactory factory
const TranslatableString name
Definition: Distortion.cpp:82
const TranslatableString desc
Definition: ExportPCM.cpp:58
#define XXO(s)
Definition: Internat.h:44
#define XO(s)
Definition: Internat.h:31
#define _(s)
Definition: Internat.h:75
EVT_COMMAND(wxID_ANY, EVT_FREQUENCYTEXTCTRL_UPDATED, LabelDialog::OnFreqUpdate) LabelDialog
Definition: LabelDialog.cpp:92
#define safenew
Definition: MemoryX.h:10
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:423
static const auto title
FileConfig * gPrefs
Definition: Prefs.cpp:71
@ eIsCreating
Definition: ShuttleGui.h:39
THEME_API Theme theTheme
Definition: Theme.cpp:82
#define S(N)
Definition: ToChars.cpp:64
#define toolbarSingle
Definition: ToolBar.h:59
@ DeviceBarID
Definition: ToolBar.h:81
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
A widget for bitmaps which ignores the erase event for flicker-free use.
Definition: Grabber.h:150
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
static AudioIOBase * Get()
Definition: AudioIOBase.cpp:89
DeviceSourceMap * GetDefaultInputDevice(int hostIndex)
const std::vector< DeviceSourceMap > & GetInputDeviceMaps()
const std::vector< DeviceSourceMap > & GetOutputDeviceMaps()
static DeviceManager * Instance()
Gets the singleton instance.
DeviceSourceMap * GetDefaultOutputDevice(int hostIndex)
A toobar to allow easier changing of input and output devices .
Definition: DeviceToolBar.h:27
wxChoice * mOutput
Definition: DeviceToolBar.h:76
void FillInputChannels()
void ShowOutputDialog()
void Populate() override
void ShowChannelsDialog()
void OnCaptureKey(wxCommandEvent &event)
void SetDevices(const DeviceSourceMap *in, const DeviceSourceMap *out)
void RegenerateTooltips() override
wxChoice * mHost
Definition: DeviceToolBar.h:78
wxChoice * mInputChannels
Definition: DeviceToolBar.h:77
void EnableDisableButtons() override
void OnFocus(wxFocusEvent &event)
void ShowComboDialog(wxChoice *combo, const TranslatableString &title)
Observer::Subscription mSubscription
Definition: DeviceToolBar.h:80
void ChangeDevice(bool isInput)
void UpdateSelectedPrefs(int) override
void FillHostDevices()
static DeviceToolBar & Get(AudacityProject &project)
void ShowInputDialog()
wxChoice * mInput
Definition: DeviceToolBar.h:75
void OnRescannedDevices(DeviceChangeMessage)
DeviceToolBar(AudacityProject &project)
virtual ~DeviceToolBar()
void UpdatePrefs() override
void Create(wxWindow *parent) override
void OnChoice(wxCommandEvent &event)
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
static void Broadcast(int id=0)
Call this static function to notify all PrefsListener objects.
Definition: Prefs.cpp:98
virtual void UpdateSelectedPrefs(int id)
Definition: Prefs.cpp:128
bool Write(const T &value)
Write value to config and return true if successful.
Definition: Prefs.h:229
bool ReadWithDefault(T *pVar, const T &defaultValue) const
overload of ReadWithDefault returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:191
bool Reset()
Reset to the default value.
Definition: Prefs.h:254
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:185
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
wxColour & Colour(int iIndex)
wxBitmap & Bitmap(int iIndex)
Works with ToolManager and ToolDock to provide a dockable window in which buttons can be placed.
Definition: ToolBar.h:98
AudacityProject & mProject
Definition: ToolBar.h:235
void Add(wxWindow *window, int proportion=0, int flag=wxALIGN_TOP, int border=0, wxObject *userData=NULL)
Definition: ToolBar.cpp:686
void SetLabel(const wxString &label) override
Definition: ToolBar.cpp:398
void UpdatePrefs() override
Definition: ToolBar.cpp:605
virtual void Create(wxWindow *parent)
Definition: ToolBar.cpp:475
wxWindowPtr< ToolBar > Holder
Definition: ToolBar.h:102
static ToolManager & Get(AudacityProject &project)
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:229
Holds a msgid for the translation catalog; may also bind format arguments.
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
void SetName(const TranslatableString &title)
void OnFocus(wxWindow &window, wxFocusEvent &event)
a function useful to implement a focus event handler The window releases the keyboard if the event is...
wxString sourceString
Definition: DeviceManager.h:34
wxString deviceString
Definition: DeviceManager.h:35