Audacity 3.2.0
AudioSetupToolBar.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 AudioSetupToolBar.cpp
6
7*******************************************************************//*******************************************************************/
13
14#include "AudioSetupToolBar.h"
15#include "ToolManager.h"
16
17#include <thread>
18
19#include <wx/log.h>
20#include <wx/sizer.h>
21#include <wx/tooltip.h>
22
23#include "../ActiveProject.h"
24
25#include "AColor.h"
26#include "AllThemeResources.h"
27#include "AudioIOBase.h"
28#include "DeviceToolBar.h"
29#include "../KeyboardCapture.h"
30#include "Project.h"
31#include "../ProjectWindows.h"
32#include "DeviceManager.h"
33#include "../prefs/PrefsDialog.h"
34#include "../prefs/DevicePrefs.h"
35#include "../widgets/AButton.h"
36#include "../widgets/BasicMenu.h"
38
39namespace {
41 {
42 public:
43 ViewDeviceSettingsDialog(wxWindow* parent, AudacityProject& project,
45 int page)
46 : PrefsDialog(parent, &project, title, factories)
47 , mPage(page)
48 {
49 }
50
51 long GetPreferredPage() override
52 {
53 return mPage;
54 }
55
56 void SavePreferredPage() override
57 {
58 }
59
60 private:
61 const int mPage;
62 };
63}
64
66
70
71BEGIN_EVENT_TABLE(AudioSetupToolBar, ToolBar)
72 EVT_BUTTON(ID_AUDIO_SETUP_BUTTON, AudioSetupToolBar::OnAudioSetup)
74
76{
77 return wxT("Audio Setup");
78}
79
80//Standard constructor
82: ToolBar( project, XO("Audio Setup"), ID() )
83{
86}
87
89{
90}
91
93{
94 auto &toolManager = ToolManager::Get( project );
95 return *static_cast<AudioSetupToolBar*>(toolManager.GetToolBar(ID()));
96}
97
99{
100 return Get( const_cast<AudacityProject&>( project )) ;
101}
102
103void AudioSetupToolBar::Create(wxWindow *parent)
104{
105 ToolBar::Create(parent);
106
107 // Simulate a size event to set initial meter placement/size
108 wxSizeEvent event(GetSize(), GetId());
109 event.SetEventObject(this);
110 GetEventHandler()->ProcessEvent(event);
111}
112
114{
115 mInput.Clear();
116 mOutput.Clear();
118 mHost.Clear();
119}
120
122{
124 SetBackgroundColour( theTheme.Colour( clrMedium ) );
126
128
129#if wxUSE_TOOLTIPS
131 wxToolTip::Enable(true);
132 wxToolTip::SetDelay(1000);
133#endif
134
135 // Set default order and mode
137
139}
140
142{
143#ifndef USE_AQUA_THEME
144 wxSize s = mSizer->GetSize();
145 wxPoint p = mSizer->GetPosition();
146
147 wxRect bevelRect(p.x, p.y, s.GetWidth() - 1, s.GetHeight() - 1);
148 AColor::Bevel(*dc, true, bevelRect);
149#endif
150}
151
153{
155 //i18n-hint: Audio setup button text, keep as short as possible
156 mAudioSetup->SetLabel(XO("Audio Setup"));
159 theTheme.Image(bmpRecoloredUpSmall),
160 theTheme.Image(bmpRecoloredUpHiliteSmall),
161 theTheme.Image(bmpRecoloredDownSmall),
162 theTheme.Image(bmpRecoloredHiliteSmall),
163 theTheme.Image(bmpRecoloredUpSmall));
164 mAudioSetup->SetIcon(theTheme.Image(bmpSetup));
165 mAudioSetup->SetForegroundColour(theTheme.Colour(clrTrackPanelText));
166}
167
169{
170 int flags = wxALIGN_CENTER | wxRIGHT;
171
172 // (Re)allocate the button sizer
173 if (mSizer)
174 {
175 Detach(mSizer);
176 std::unique_ptr < wxSizer > {mSizer}; // DELETE it
177 }
178
179 Add((mSizer = safenew wxBoxSizer(wxHORIZONTAL)), 1, wxEXPAND);
180 mSizer->Add(mAudioSetup, 1, wxEXPAND);
181
182 // Layout the sizer
183 mSizer->Layout();
184
185 // Layout the toolbar
186 Layout();
187
188 SetMinSize(GetSizer()->GetMinSize());
189}
190
192{
193 bool isAudioSetupDown = false;
194
195 // ToolBar::ReCreateButtons() will get rid of its sizer and
196 // since we've attached our sizer to it, ours will get deleted too
197 // so clean ours up first.
198 if (mSizer)
199 {
200 isAudioSetupDown = mAudioSetup->IsDown();
201 Detach(mSizer);
202
203 std::unique_ptr < wxSizer > {mSizer}; // DELETE it
204 mSizer = nullptr;
205 }
206
208
209 if (isAudioSetupDown)
210 {
212 }
213
215
217}
218
219void AudioSetupToolBar::OnFocus(wxFocusEvent &event)
220{
221 KeyboardCapture::OnFocus( *this, event );
222}
223
224void AudioSetupToolBar::OnAudioSetup(wxCommandEvent& WXUNUSED(evt))
225{
226 wxMenu menu;
227
228 //i18n-hint: Audio setup menu
229 mHost.AppendSubMenu(*this, menu, &AudioSetupToolBar::OnHost, _("&Host"));
230 menu.AppendSeparator();
231
232 //i18n-hint: Audio setup menu
233 mOutput.AppendSubMenu(*this, menu,
234 &AudioSetupToolBar::OnOutput, _("&Playback Device"));
235 menu.AppendSeparator();
236
237 //i18n-hint: Audio setup menu
238 mInput.AppendSubMenu(*this, menu,
239 &AudioSetupToolBar::OnInput, _("&Recording Device"));
240 menu.AppendSeparator();
241
242 //i18n-hint: Audio setup menu
244 menu, &AudioSetupToolBar::OnChannels, _("Recording &Channels"));
245 menu.AppendSeparator();
246 menu.Append(kAudioSettings, _("&Audio Settings..."));
247
248 menu.Bind(wxEVT_MENU_CLOSE, [this](auto&) { mAudioSetup->PopUp(); });
249 menu.Bind(wxEVT_MENU, &AudioSetupToolBar::OnSettings, this, kAudioSettings);
250
251 wxWindow* btn = FindWindow(ID_AUDIO_SETUP_BUTTON);
252 wxRect r = btn->GetRect();
253 BasicMenu::Handle{ &menu }.Popup(
255 { r.GetLeft(), r.GetBottom() }
256 );
257}
258
260{
261 wxString desc;
262 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
263 const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
264
265 auto selectedHost = mHost.Get();
266 wxString oldHost = selectedHost ? *selectedHost : wxString{};
267
268 auto hostName = AudioIOHost.Read();
269
270 // if the prefs host name doesn't match the one displayed, it changed
271 // in another project's AudioSetupToolBar, so we need to repopulate everything.
272 if (oldHost != hostName)
273 // updates mHost and mOutput
275
276 auto devName = AudioIORecordingDevice.Read();
277 auto sourceName = AudioIORecordingSource.Read();
278 if (sourceName.empty())
279 desc = devName;
280 else
281 desc = devName + wxT(": ") + sourceName;
282
283 if (mInput.Get() && *mInput.Get() != desc) {
284 if (mInput.Set(desc))
285 // updates mInputChannels
287 else if (!mInput.Empty()) {
288 for (size_t i = 0; i < inMaps.size(); i++) {
289 if (inMaps[i].hostString == hostName &&
290 MakeDeviceSourceString(&inMaps[i]) == mInput.GetFirst()) {
291 // use the default. It should exist but check just in case, falling back on the 0 index.
292 DeviceSourceMap* defaultMap = DeviceManager::Instance()->GetDefaultInputDevice(inMaps[i].hostIndex);
293 if (defaultMap) {
294 mInput.Set(MakeDeviceSourceString(defaultMap));
295 SetDevices(defaultMap, nullptr);
296 }
297 else {
298 //use the first item (0th index) if we have no familiar devices
299 mInput.Set(0);
300 SetDevices(&inMaps[i], nullptr);
301 }
302 break;
303 }
304 }
305 }
306 }
307
308 devName = AudioIOPlaybackDevice.Read();
309 sourceName = AudioIOPlaybackSource.Read();
310 if (sourceName.empty())
311 desc = devName;
312 else
313 desc = devName + wxT(": ") + sourceName;
314
315 if (mOutput.Get() && *mOutput.Get() != desc) {
316 if (!mOutput.Set(desc) && !mOutput.Empty()) {
317 for (size_t i = 0; i < outMaps.size(); i++) {
318 if (outMaps[i].hostString == hostName &&
319 MakeDeviceSourceString(&outMaps[i]) == mOutput.GetFirst()) {
320 // use the default. It should exist but check just in case, falling back on the 0 index.
321 DeviceSourceMap* defaultMap = DeviceManager::Instance()->GetDefaultInputDevice(outMaps[i].hostIndex);
322 if (defaultMap) {
324 SetDevices(nullptr, defaultMap);
325 }
326 else {
327 //use the first item (0th index) if we have no familiar devices
328 mOutput.Set(0);
329 SetDevices(nullptr, &outMaps[i]);
330 }
331 break;
332 }
333 }
334 }
335 }
336
337 // 0 based choice id is one less than the number of channels
338 long oldChannels = 1 + mInputChannels.GetSmallIntegerId();
339
340 // Preferences store the actual number of channels
341 auto newChannels = AudioIORecordChannels.ReadWithDefault(0);
342 if (newChannels > 0 && oldChannels != newChannels)
343 mInputChannels.Set(newChannels - 1);
344
345 selectedHost = mHost.Get();
346 if (!hostName.empty() && selectedHost && *selectedHost != hostName)
347 mHost.Set(hostName);
348
350
351 // Set label to pull in language change
352 SetLabel(XO("Audio Setup"));
353
354 // Give base class a chance
356
357 Layout();
358 Refresh();
359}
360
362{
363 if (id == DeviceToolbarPrefsID())
364 UpdatePrefs();
366}
367
368
370{
371 auto gAudioIO = AudioIOBase::Get();
372 if (gAudioIO) {
373 // we allow changes when monitoring, but not when recording
374 bool audioStreamActive = gAudioIO->IsStreamActive() && !gAudioIO->IsMonitoring();
375
376 if (audioStreamActive) {
378 }
379 else {
381 }
382 }
383}
384
386{
387#if wxUSE_TOOLTIPS
388 for (long iWinID = ID_AUDIO_SETUP_BUTTON; iWinID < BUTTON_COUNT; iWinID++)
389 {
390 auto pCtrl = static_cast<AButton*>(this->FindWindow(iWinID));
392 switch (iWinID)
393 {
395 name = wxT("Open Audio Setup");
396 break;
397 }
398 std::vector<ComponentInterfaceSymbol> commands(
399 1u, { name, Verbatim(pCtrl->GetLabel()) });
400
401 // Some have a second
402 switch (iWinID)
403 {
405 break;
406 }
408 mProject, *pCtrl, commands.data(), commands.size());
409 }
410#endif
411}
412
414{
415 FillHosts();
418 // make the device display selection reflect the prefs if they exist
419 UpdatePrefs();
420}
421
423{
424 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
425 const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
426
427 wxArrayString hosts;
428
429 // go over our lists add the host to the list if it isn't there yet
430
431 for (auto & device : inMaps) {
432 if (!make_iterator_range(hosts).contains(device.hostString)) {
433 hosts.push_back(device.hostString);
434 }
435 }
436
437 for (auto & device : outMaps) {
438 if (!make_iterator_range(hosts).contains(device.hostString)) {
439 hosts.push_back(device.hostString);
440 }
441 }
442
443 mHost.Set(std::move(hosts));
444}
445
447{
448 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
449 const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
450
451 //read what is in the prefs
452 auto host = AudioIOHost.Read();
453 int foundHostIndex = -1;
454
455 // if the host is not in the hosts combo then we rescanned.
456 // set it to blank so we search for another host.
457 if (mHost.Find(host) < 0)
458 host = wxT("");
459
460 // Try to find a hostIndex, among either inputs or outputs, assumed to be
461 // unique among the union of the set of input and output devices
462 for (auto & device : outMaps) {
463 if (device.hostString == host) {
464 foundHostIndex = device.hostIndex;
465 break;
466 }
467 }
468
469 if (foundHostIndex == -1) {
470 for (auto & device : inMaps) {
471 if (device.hostString == host) {
472 foundHostIndex = device.hostIndex;
473 break;
474 }
475 }
476 }
477
478 // If no host was found based on the prefs device host, load the first available one
479 if (foundHostIndex == -1) {
480 if (outMaps.size()) {
481 foundHostIndex = outMaps[0].hostIndex;
482 }
483 else if (inMaps.size()) {
484 foundHostIndex = inMaps[0].hostIndex;
485 }
486 }
487
488 // Make sure in/out are clear in case no host was found
489 mInput.Clear();
490 mOutput.Clear();
491
492 // If we still have no host it means no devices, in which case do nothing.
493 if (foundHostIndex == -1) {
494 return;
495 }
496
497 // Repopulate the Input/Output device list available to the user
498 wxArrayStringEx mInputDeviceNames;
499 for (size_t i = 0; i < inMaps.size(); ++i) {
500 auto& device = inMaps[i];
501 if (foundHostIndex == device.hostIndex) {
502 mInputDeviceNames.push_back(MakeDeviceSourceString(&device));
503 if (host.empty()) {
504 host = device.hostString;
505 AudioIOHost.Write(host);
506 mHost.Set(host);
507 }
508 }
509 }
510 mInput.Set(std::move(mInputDeviceNames));
511
512 wxArrayStringEx mOutputDeviceNames;
513 for (size_t i = 0; i < outMaps.size(); ++i) {
514 auto& device = outMaps[i];
515 if (foundHostIndex == device.hostIndex) {
516 mOutputDeviceNames.push_back(MakeDeviceSourceString(&device));
517 if (host.empty()) {
518 host = device.hostString;
519 AudioIOHost.Write(host);
520 mHost.Set(host);
521 }
522 }
523 }
524 mOutput.Set(std::move(mOutputDeviceNames));
525
526 gPrefs->Flush();
527
528 // The setting of the Device is left up to menu handlers
529}
530
532{
533 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
534 auto host = AudioIOHost.Read();
535 auto device = AudioIORecordingDevice.Read();
536 auto source = AudioIORecordingSource.Read();
537 long newChannels = 0;
538
539 auto oldChannels = AudioIORecordChannels.Read();
541
543 for (auto & dev: inMaps) {
544 if (source == dev.sourceString &&
545 device == dev.deviceString &&
546 host == dev.hostString) {
547
548 // add one selection for each channel of this source
549 for (size_t j = 0; j < (unsigned int)dev.numChannels; j++) {
550 wxString name;
551
552 if (j == 0) {
553 name = _("1 (Mono) Recording Channel");
554 }
555 else if (j == 1) {
556 name = _("2 (Stereo) Recording Channels");
557 }
558 else {
559 name = wxString::Format(wxT("%d"), (int)j + 1);
560 }
561 names.push_back(name);
562 }
563 newChannels = dev.numChannels;
564 if (oldChannels <= newChannels && oldChannels >= 1) {
565 newChannels = oldChannels;
566 }
567 AudioIORecordChannels.Write(newChannels);
568 break;
569 }
570 }
571 mInputChannels.Set(std::move(names));
572 if (newChannels >= 1)
573 // Correct to 0-based index in choice
574 mInputChannels.Set(newChannels - 1);
575}
576
578 wxMenu& menu, const wxArrayString &labels, int checkedItem,
579 Callback callback, const wxString& title)
580{
581 auto subMenu = std::make_unique<wxMenu>();
582 int ii = 0;
583 for (const auto &label : labels) {
584 // Assign fresh ID with wxID_ANY
585 auto subMenuItem = subMenu->AppendRadioItem(wxID_ANY, label);
586 if (ii == checkedItem)
587 subMenuItem->Check();
588 subMenu->Bind(wxEVT_MENU,
589 [&toolbar, callback, ii](wxCommandEvent &){ (toolbar.*callback)(ii); },
590 subMenuItem->GetId());
591 ++ii;
592 }
593 auto menuItem = menu.AppendSubMenu(subMenu.release(), title);
594 if (checkedItem < 0)
595 menuItem->Enable(false);
596}
597
599 wxMenu &menu, Callback callback, const wxString &title)
600{
602 AppendSubMenu(toolBar, menu, mStrings, mIndex, callback, title);
603}
604
606{
607 // Hosts may have disappeared or appeared so a complete repopulate is needed.
610}
611
612//return true if host changed, false otherwise.
614{
615 // Update cache with selected host
616 if (!mHost.Set(hostId))
617 return false;
618 auto name = mHost.Get();
619 assert(name); // should not be nullopt if Set succeeded
620
621 auto oldHost = AudioIOHost.Read();
622 const auto newHost = *name;
623
624 if (oldHost == newHost)
625 return false;
626
627 //change the host and switch to correct devices.
628 AudioIOHost.Write(newHost);
629 gPrefs->Flush();
630
631 // populate the devices and reassign mHost
633
634 return true;
635}
636
638{
639 if (in) {
642 if (in->totalSources >= 1)
644 else
646 gPrefs->Flush();
647
648 // updates mInputChannels
650 }
651
652 if (out) {
654 if (out->totalSources >= 1) {
656 } else {
658 }
659 gPrefs->Flush();
660 }
661}
662
664 int deviceId, Choices &choices, bool isInput)
665{
666 int newIndex = -1;
667
668 auto host = AudioIOHost.Read();
669 const std::vector<DeviceSourceMap>& maps = isInput ? DeviceManager::Instance()->GetInputDeviceMaps()
671
672 if (choices.Set(deviceId)) {
673 // Update cache with the chosen device
674 wxString newDevice = *choices.Get();
675 for (size_t i = 0; i < maps.size(); ++i) {
676 const auto name = MakeDeviceSourceString(&maps[i]);
677 if (name == newDevice && maps[i].hostString == host)
678 newIndex = i;
679 }
680 }
681
682 if (newIndex < 0) {
683 wxLogDebug(wxT("AudioSetupToolBar::ChangeDeviceLabel(): couldn't find device indices"));
684 return;
685 }
686
687 SetDevices(isInput ? &maps[newIndex] : nullptr,
688 isInput ? nullptr : &maps[newIndex]);
689}
690
692{
693 ChangeHost(id);
694 CommonMenuItemSteps(false);
695}
696
698{
700 // Remember 1-based value in preferences
702 CommonMenuItemSteps(false);
703}
704
706{
707 ChangeDeviceLabel(id, mInput, true);
708 CommonMenuItemSteps(false);
709}
710
712{
713 ChangeDeviceLabel(id, mOutput, false);
714 CommonMenuItemSteps(false);
715}
716
717void AudioSetupToolBar::OnSettings(wxCommandEvent& event)
718{
720}
721
722void AudioSetupToolBar::CommonMenuItemSteps(bool audioSettingsChosen)
723{
724 auto gAudioIO = AudioIOBase::Get();
725 if (gAudioIO) {
726 // We cannot have gotten here if gAudioIO->IsAudioTokenActive(),
727 // per the setting of AudioIONotBusyFlag and AudioIOBusyFlag in
728 // AudacityProject::GetUpdateFlags().
729 // However, we can have an invalid audio token (so IsAudioTokenActive()
730 // is false), but be monitoring.
731 // If monitoring, have to stop the stream, so HandleDeviceChange() can work.
732 // We could disable the Preferences command while monitoring, i.e.,
733 // set AudioIONotBusyFlag/AudioIOBusyFlag according to monitoring, as well.
734 // Instead allow it because unlike recording, for example, monitoring
735 // is not clearly something that should prohibit changing device.
736 // TODO: We *could* be smarter in this method and call HandleDeviceChange()
737 // only when the device choices actually changed. True of lots of prefs!
738 // As is, we always stop monitoring before handling the device change.
739 if (gAudioIO->IsMonitoring())
740 {
741 gAudioIO->StopStream();
742 while (gAudioIO->IsBusy()) {
743 using namespace std::chrono;
744 std::this_thread::sleep_for(100ms);
745 }
746 }
747
748 if (audioSettingsChosen) {
749 PrefsPanel::Factories factories;
750 factories.push_back(PrefsPanel::PrefsNode(DevicePrefsFactory));
751
752 ViewDeviceSettingsDialog dialog(
753 &GetProjectFrame(mProject), mProject, {}, factories, 0);
754 dialog.SetSize(600, 420);
755 dialog.Center();
756
757 if (0 != dialog.ShowModal()) {
759 }
760 }
761 else {
762 gAudioIO->HandleDeviceChange();
764 }
765 }
766}
767
769 []( AudacityProject &project ){
770 return ToolBar::Holder{ safenew AudioSetupToolBar{ project } };
771 }
772};
773
774namespace {
776 /* i18n-hint: Clicking this menu item shows the toolbar
777 that manages the audio devices */
778 AudioSetupToolBar::ID(), wxT("ShowAudioSetupTB"), XXO("&Audio Setup Toolbar")
779};
780}
781
wxT("CloseDown"))
StringSetting AudioIORecordingSource
StringSetting AudioIOPlaybackSource
StringSetting AudioIOPlaybackDevice
StringSetting AudioIORecordingDevice
StringSetting AudioIOHost
IntSetting AudioIORecordingSourceIndex
IntSetting AudioIORecordChannels
static RegisteredToolbarFactory factory
IMPLEMENT_CLASS(AudioSetupToolBar, ToolBar)
END_EVENT_TABLE()
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
DeviceChangeMessage
Definition: DeviceChange.h:16
wxString MakeDeviceSourceString(const DeviceSourceMap *map)
PrefsPanel * DevicePrefsFactory(wxWindow *parent, wxWindowID winid, AudacityProject *project)
int DeviceToolbarPrefsID()
Methods for DeviceToolBar.
const TranslatableString name
Definition: Distortion.cpp:76
const TranslatableString desc
Definition: ExportPCM.cpp:55
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define _(s)
Definition: Internat.h:73
#define safenew
Definition: MemoryX.h:10
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:448
static const auto title
FileConfig * gPrefs
Definition: Prefs.cpp:70
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
TranslatableString label
Definition: TagsEditor.cpp:164
static TranslatableStrings names
Definition: TagsEditor.cpp:152
THEME_API Theme theTheme
Definition: Theme.cpp:82
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
A wxButton with mouse-over behaviour.
Definition: AButton.h:104
void SetButtonType(Type type)
Definition: AButton.cpp:147
void SetImages(const wxImage &up, const wxImage &over, const wxImage &down, const wxImage &overDown, const wxImage &dis)
Definition: AButton.cpp:205
void PushDown()
Definition: AButton.cpp:577
bool IsDown()
Definition: AButton.h:208
void Disable()
Definition: AButton.cpp:560
void Enable()
Definition: AButton.cpp:551
void PopUp()
Definition: AButton.cpp:585
@ FrameButton
Definition: AButton.h:114
void SetIcon(const wxImage &icon)
Definition: AButton.cpp:226
void SetLabel(const TranslatableString &label)
Definition: AButton.cpp:189
static void Bevel(wxDC &dc, bool up, const wxRect &r)
Definition: AColor.cpp:266
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static AudioIOBase * Get()
Definition: AudioIOBase.cpp:93
bool Set(const wxString &name)
std::optional< wxString > Get() const
void AppendSubMenu(AudioSetupToolBar &toolBar, wxMenu &menu, Callback callback, const wxString &title)
int Find(const wxString &name) const
A toolbar to allow easier changing of input and output devices .
void(AudioSetupToolBar::*)(int id) Callback
void SetDevices(const DeviceSourceMap *in, const DeviceSourceMap *out)
void UpdateSelectedPrefs(int) override
void CommonMenuItemSteps(bool audioSettingsChosen)
void RegenerateTooltips() override
void Populate() override
void OnAudioSetup(wxCommandEvent &event)
static AudioSetupToolBar & Get(AudacityProject &project)
static void AppendSubMenu(AudioSetupToolBar &toolbar, wxMenu &menu, const wxArrayString &labels, int checkedItem, Callback callback, const wxString &title)
void EnableDisableButtons() override
void Repaint(wxDC *dc) override
static constexpr int kAudioSettings
void OnRescannedDevices(DeviceChangeMessage)
void OnSettings(wxCommandEvent &event)
void Create(wxWindow *parent) override
void ChangeDeviceLabel(int deviceId, Choices &choices, bool isInput)
Observer::Subscription mSubscription
void ReCreateButtons() override
static Identifier ID()
Methods for AudioSetupToolBar.
bool ChangeHost(int hostId)
void OnFocus(wxFocusEvent &event)
AudioSetupToolBar(AudacityProject &project)
void UpdatePrefs() override
void Popup(const BasicUI::WindowPlacement &window, const Point &pos={})
Display the menu at pos, invoke at most one action, then hide it.
Definition: BasicMenu.cpp:209
size_t size() const
How many attachment pointers are in the Site.
Definition: ClientData.h:251
DeviceSourceMap * GetDefaultInputDevice(int hostIndex)
const std::vector< DeviceSourceMap > & GetInputDeviceMaps()
const std::vector< DeviceSourceMap > & GetOutputDeviceMaps()
static DeviceManager * Instance()
Gets the singleton instance.
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
An explicitly nonlocalized string, not meant for the user to see.
Definition: Identifier.h:22
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
Dialog that shows the current PrefsPanel in a tabbed divider.
Definition: PrefsDialog.h:29
static void Broadcast(int id=0)
Call this static function to notify all PrefsListener objects.
Definition: Prefs.cpp:97
virtual void UpdateSelectedPrefs(int id)
Definition: Prefs.cpp:127
std::vector< PrefsPanel::PrefsNode > Factories
Definition: PrefsPanel.h:72
bool Write(const T &value)
Write value to config and return true if successful.
Definition: Prefs.h:252
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:206
bool Reset()
Reset to the default value.
Definition: Prefs.h:277
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:200
wxColour & Colour(int iIndex)
wxImage & Image(int iIndex)
Works with ToolManager and ToolDock to provide a dockable window in which buttons can be placed.
Definition: ToolBar.h:74
AudacityProject & mProject
Definition: ToolBar.h:248
void Add(wxWindow *window, int proportion=0, int flag=wxALIGN_TOP, int border=0, wxObject *userData=NULL)
Definition: ToolBar.cpp:709
virtual void ReCreateButtons()
Definition: ToolBar.cpp:533
void SetLabel(const wxString &label) override
Definition: ToolBar.cpp:408
static void MakeButtonBackgroundsSmall()
Definition: ToolBar.cpp:837
wxBoxSizer * GetSizer()
Definition: ToolBar.cpp:701
void UpdatePrefs() override
Definition: ToolBar.cpp:622
virtual void Create(wxWindow *parent)
Definition: ToolBar.cpp:492
void Detach(wxWindow *window)
Definition: ToolBar.cpp:775
wxWindowPtr< ToolBar > Holder
Definition: ToolBar.h:78
static void SetButtonToolTip(AudacityProject &project, AButton &button, const ComponentInterfaceSymbol commands[], size_t nCommands)
Definition: ToolBar.cpp:970
static ToolManager & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
ViewDeviceSettingsDialog(wxWindow *parent, AudacityProject &project, const TranslatableString &title, PrefsPanel::Factories &factories, int page)
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
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
Window placement information for wxWidgetsBasicUI can be constructed from a wxWindow pointer.