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:
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(kAudioDeviceRescan, _("R&escan Audio Devices"));
247 menu.Append(kAudioSettings, _("&Audio Settings..."));
248
249 menu.Bind(wxEVT_MENU_CLOSE, [this](auto&) { mAudioSetup->PopUp(); });
250 menu.Bind(wxEVT_MENU, &AudioSetupToolBar::OnAudioDeviceRescan, this, kAudioDeviceRescan);
251 menu.Bind(wxEVT_MENU, &AudioSetupToolBar::OnSettings, this, kAudioSettings);
252
253 wxWindow* btn = FindWindow(ID_AUDIO_SETUP_BUTTON);
254 wxRect r = btn->GetRect();
255 BasicMenu::Handle{ &menu }.Popup(
257 { r.GetLeft(), r.GetBottom() }
258 );
259}
260
262{
263 wxString desc;
264 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
265 const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
266
267 auto selectedHost = mHost.Get();
268 wxString oldHost = selectedHost ? *selectedHost : wxString{};
269
270 auto hostName = AudioIOHost.Read();
271
272 // if the prefs host name doesn't match the one displayed, it changed
273 // in another project's AudioSetupToolBar, so we need to repopulate everything.
274 if (oldHost != hostName)
275 // updates mHost and mOutput
277
278 auto devName = AudioIORecordingDevice.Read();
279 auto sourceName = AudioIORecordingSource.Read();
280 if (sourceName.empty())
281 desc = devName;
282 else
283 desc = devName + wxT(": ") + sourceName;
284
285 if (mInput.Get() && *mInput.Get() != desc) {
286 if (mInput.Set(desc))
287 // updates mInputChannels
289 else if (!mInput.Empty()) {
290 for (size_t i = 0; i < inMaps.size(); i++) {
291 if (inMaps[i].hostString == hostName &&
292 MakeDeviceSourceString(&inMaps[i]) == mInput.GetFirst()) {
293 // use the default. It should exist but check just in case, falling back on the 0 index.
294 DeviceSourceMap* defaultMap = DeviceManager::Instance()->GetDefaultInputDevice(inMaps[i].hostIndex);
295 if (defaultMap) {
296 mInput.Set(MakeDeviceSourceString(defaultMap));
297 SetDevices(defaultMap, nullptr);
298 }
299 else {
300 //use the first item (0th index) if we have no familiar devices
301 mInput.Set(0);
302 SetDevices(&inMaps[i], nullptr);
303 }
304 break;
305 }
306 }
307 }
308 }
309
310 devName = AudioIOPlaybackDevice.Read();
311 sourceName = AudioIOPlaybackSource.Read();
312 if (sourceName.empty())
313 desc = devName;
314 else
315 desc = devName + wxT(": ") + sourceName;
316
317 if (mOutput.Get() && *mOutput.Get() != desc) {
318 if (!mOutput.Set(desc) && !mOutput.Empty()) {
319 for (size_t i = 0; i < outMaps.size(); i++) {
320 if (outMaps[i].hostString == hostName &&
321 MakeDeviceSourceString(&outMaps[i]) == mOutput.GetFirst()) {
322 // use the default. It should exist but check just in case, falling back on the 0 index.
323 DeviceSourceMap* defaultMap = DeviceManager::Instance()->GetDefaultInputDevice(outMaps[i].hostIndex);
324 if (defaultMap) {
326 SetDevices(nullptr, defaultMap);
327 }
328 else {
329 //use the first item (0th index) if we have no familiar devices
330 mOutput.Set(0);
331 SetDevices(nullptr, &outMaps[i]);
332 }
333 break;
334 }
335 }
336 }
337 }
338
339 // 0 based choice id is one less than the number of channels
340 long oldChannels = 1 + mInputChannels.GetSmallIntegerId();
341
342 // Preferences store the actual number of channels
343 auto newChannels = AudioIORecordChannels.ReadWithDefault(0);
344 if (newChannels > 0 && oldChannels != newChannels)
345 mInputChannels.Set(newChannels - 1);
346
347 selectedHost = mHost.Get();
348 if (!hostName.empty() && selectedHost && *selectedHost != hostName)
349 mHost.Set(hostName);
350
352
353 // Set label to pull in language change
354 SetLabel(XO("Audio Setup"));
355
356 // Give base class a chance
358
359 Layout();
360 Refresh();
361}
362
364{
365 if (id == DeviceToolbarPrefsID())
366 UpdatePrefs();
368}
369
370
372{
373 auto gAudioIO = AudioIOBase::Get();
374 if (gAudioIO) {
375 // we allow changes when monitoring, but not when recording
376 bool audioStreamActive = gAudioIO->IsStreamActive() && !gAudioIO->IsMonitoring();
377
378 if (audioStreamActive) {
380 }
381 else {
383 }
384 }
385}
386
388{
389#if wxUSE_TOOLTIPS
390 for (long iWinID = ID_AUDIO_SETUP_BUTTON; iWinID < BUTTON_COUNT; iWinID++)
391 {
392 auto pCtrl = static_cast<AButton*>(this->FindWindow(iWinID));
394 switch (iWinID)
395 {
397 name = wxT("Open Audio Setup");
398 break;
399 }
400 std::vector<ComponentInterfaceSymbol> commands(
401 1u, { name, Verbatim(pCtrl->GetLabel()) });
402
403 // Some have a second
404 switch (iWinID)
405 {
407 break;
408 }
410 mProject, *pCtrl, commands.data(), commands.size());
411 }
412#endif
413}
414
416{
417 FillHosts();
420 // make the device display selection reflect the prefs if they exist
421 UpdatePrefs();
422}
423
425{
426 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
427 const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
428
429 wxArrayString hosts;
430
431 // go over our lists add the host to the list if it isn't there yet
432
433 for (auto & device : inMaps) {
434 if (!make_iterator_range(hosts).contains(device.hostString)) {
435 hosts.push_back(device.hostString);
436 }
437 }
438
439 for (auto & device : outMaps) {
440 if (!make_iterator_range(hosts).contains(device.hostString)) {
441 hosts.push_back(device.hostString);
442 }
443 }
444
445 mHost.Set(std::move(hosts));
446}
447
449{
450 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
451 const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
452
453 //read what is in the prefs
454 auto host = AudioIOHost.Read();
455 int foundHostIndex = -1;
456
457 // if the host is not in the hosts combo then we rescanned.
458 // set it to blank so we search for another host.
459 if (mHost.Find(host) < 0)
460 host = wxT("");
461
462 // Try to find a hostIndex, among either inputs or outputs, assumed to be
463 // unique among the union of the set of input and output devices
464 for (auto & device : outMaps) {
465 if (device.hostString == host) {
466 foundHostIndex = device.hostIndex;
467 break;
468 }
469 }
470
471 if (foundHostIndex == -1) {
472 for (auto & device : inMaps) {
473 if (device.hostString == host) {
474 foundHostIndex = device.hostIndex;
475 break;
476 }
477 }
478 }
479
480 // If no host was found based on the prefs device host, load the first available one
481 if (foundHostIndex == -1) {
482 if (outMaps.size()) {
483 foundHostIndex = outMaps[0].hostIndex;
484 }
485 else if (inMaps.size()) {
486 foundHostIndex = inMaps[0].hostIndex;
487 }
488 }
489
490 // Make sure in/out are clear in case no host was found
491 mInput.Clear();
492 mOutput.Clear();
493
494 // If we still have no host it means no devices, in which case do nothing.
495 if (foundHostIndex == -1) {
496 return;
497 }
498
499 // Repopulate the Input/Output device list available to the user
500 wxArrayStringEx mInputDeviceNames;
501 for (size_t i = 0; i < inMaps.size(); ++i) {
502 auto& device = inMaps[i];
503 if (foundHostIndex == device.hostIndex) {
504 mInputDeviceNames.push_back(MakeDeviceSourceString(&device));
505 if (host.empty()) {
506 host = device.hostString;
507 AudioIOHost.Write(host);
508 mHost.Set(host);
509 }
510 }
511 }
512 mInput.Set(std::move(mInputDeviceNames));
513
514 wxArrayStringEx mOutputDeviceNames;
515 for (size_t i = 0; i < outMaps.size(); ++i) {
516 auto& device = outMaps[i];
517 if (foundHostIndex == device.hostIndex) {
518 mOutputDeviceNames.push_back(MakeDeviceSourceString(&device));
519 if (host.empty()) {
520 host = device.hostString;
521 AudioIOHost.Write(host);
522 mHost.Set(host);
523 }
524 }
525 }
526 mOutput.Set(std::move(mOutputDeviceNames));
527
528 gPrefs->Flush();
529
530 // The setting of the Device is left up to menu handlers
531}
532
534{
535 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
536 auto host = AudioIOHost.Read();
537 auto device = AudioIORecordingDevice.Read();
538 auto source = AudioIORecordingSource.Read();
539 long newChannels = 0;
540
541 auto oldChannels = AudioIORecordChannels.Read();
543
545 for (auto & dev: inMaps) {
546 if (source == dev.sourceString &&
547 device == dev.deviceString &&
548 host == dev.hostString) {
549
550 // add one selection for each channel of this source
551 for (size_t j = 0; j < (unsigned int)dev.numChannels; j++) {
552 wxString name;
553
554 if (j == 0) {
555 name = _("1 (Mono) Recording Channel");
556 }
557 else if (j == 1) {
558 name = _("2 (Stereo) Recording Channels");
559 }
560 else {
561 name = wxString::Format(wxT("%d"), (int)j + 1);
562 }
563 names.push_back(name);
564 }
565 newChannels = dev.numChannels;
566 if (oldChannels <= newChannels && oldChannels >= 1) {
567 newChannels = oldChannels;
568 }
569 AudioIORecordChannels.Write(newChannels);
570 break;
571 }
572 }
573 mInputChannels.Set(std::move(names));
574 if (newChannels >= 1)
575 // Correct to 0-based index in choice
576 mInputChannels.Set(newChannels - 1);
577}
578
580 wxMenu& menu, const wxArrayString &labels, int checkedItem,
581 Callback callback, const wxString& title)
582{
583 auto subMenu = std::make_unique<wxMenu>();
584 int ii = 0;
585 for (const auto &label : labels) {
586 // Assign fresh ID with wxID_ANY
587 auto subMenuItem = subMenu->AppendRadioItem(wxID_ANY, label);
588 if (ii == checkedItem)
589 subMenuItem->Check();
590 subMenu->Bind(wxEVT_MENU,
591 [&toolbar, callback, ii](wxCommandEvent &){ (toolbar.*callback)(ii); },
592 subMenuItem->GetId());
593 ++ii;
594 }
595 auto menuItem = menu.AppendSubMenu(subMenu.release(), title);
596 if (checkedItem < 0)
597 menuItem->Enable(false);
598}
599
601 wxMenu &menu, Callback callback, const wxString &title)
602{
604 AppendSubMenu(toolBar, menu, mStrings, mIndex, callback, title);
605}
606
608{
609 // Hosts may have disappeared or appeared so a complete repopulate is needed.
612}
613
614//return true if host changed, false otherwise.
616{
617 // Update cache with selected host
618 if (!mHost.Set(hostId))
619 return false;
620 auto name = mHost.Get();
621 assert(name); // should not be nullopt if Set succeeded
622
623 auto oldHost = AudioIOHost.Read();
624 const auto newHost = *name;
625
626 if (oldHost == newHost)
627 return false;
628
629 //change the host and switch to correct devices.
630 AudioIOHost.Write(newHost);
631 gPrefs->Flush();
632
633 // populate the devices and reassign mHost
635
636 return true;
637}
638
640{
641 if (in) {
644 if (in->totalSources >= 1)
646 else
648 gPrefs->Flush();
649
650 // updates mInputChannels
652 }
653
654 if (out) {
656 if (out->totalSources >= 1) {
658 } else {
660 }
661 gPrefs->Flush();
662 }
663}
664
666 int deviceId, Choices &choices, bool isInput)
667{
668 int newIndex = -1;
669
670 auto host = AudioIOHost.Read();
671 const std::vector<DeviceSourceMap>& maps = isInput ? DeviceManager::Instance()->GetInputDeviceMaps()
673
674 if (choices.Set(deviceId)) {
675 // Update cache with the chosen device
676 wxString newDevice = *choices.Get();
677 for (size_t i = 0; i < maps.size(); ++i) {
678 const auto name = MakeDeviceSourceString(&maps[i]);
679 if (name == newDevice && maps[i].hostString == host)
680 newIndex = i;
681 }
682 }
683
684 if (newIndex < 0) {
685 wxLogDebug(wxT("AudioSetupToolBar::ChangeDeviceLabel(): couldn't find device indices"));
686 return;
687 }
688
689 SetDevices(isInput ? &maps[newIndex] : nullptr,
690 isInput ? nullptr : &maps[newIndex]);
691}
692
694{
695 ChangeHost(id);
696 CommonMenuItemSteps(false);
697}
698
700{
702 // Remember 1-based value in preferences
704 CommonMenuItemSteps(false);
705}
706
708{
709 ChangeDeviceLabel(id, mInput, true);
710 CommonMenuItemSteps(false);
711}
712
714{
715 ChangeDeviceLabel(id, mOutput, false);
716 CommonMenuItemSteps(false);
717}
718
720{
722 {
724 });
725}
726
727void AudioSetupToolBar::OnSettings(wxCommandEvent& event)
728{
730}
731
732void AudioSetupToolBar::CommonMenuItemSteps(bool audioSettingsChosen)
733{
734 auto gAudioIO = AudioIOBase::Get();
735 if (gAudioIO) {
736 // We cannot have gotten here if gAudioIO->IsAudioTokenActive(),
737 // per the setting of AudioIONotBusyFlag and AudioIOBusyFlag in
738 // AudacityProject::GetUpdateFlags().
739 // However, we can have an invalid audio token (so IsAudioTokenActive()
740 // is false), but be monitoring.
741 // If monitoring, have to stop the stream, so HandleDeviceChange() can work.
742 // We could disable the Preferences command while monitoring, i.e.,
743 // set AudioIONotBusyFlag/AudioIOBusyFlag according to monitoring, as well.
744 // Instead allow it because unlike recording, for example, monitoring
745 // is not clearly something that should prohibit changing device.
746 // TODO: We *could* be smarter in this method and call HandleDeviceChange()
747 // only when the device choices actually changed. True of lots of prefs!
748 // As is, we always stop monitoring before handling the device change.
749 if (gAudioIO->IsMonitoring())
750 {
751 gAudioIO->StopStream();
752 while (gAudioIO->IsBusy()) {
753 using namespace std::chrono;
754 std::this_thread::sleep_for(100ms);
755 }
756 }
757
758 if (audioSettingsChosen) {
759 PrefsPanel::Factories factories;
760 factories.push_back(PrefsPanel::PrefsNode(DevicePrefsFactory));
761
762 ViewDeviceSettingsDialog dialog(
763 &GetProjectFrame(mProject), mProject, {}, factories, 0);
764 dialog.SetSize(600, 420);
765 dialog.Center();
766
767 if (0 != dialog.ShowModal()) {
769 }
770 }
771 else {
772 gAudioIO->HandleDeviceChange();
774 }
775 }
776}
777
781 }
782};
783
784namespace {
786 /* i18n-hint: Clicking this menu item shows the toolbar
787 that manages the audio devices */
788 AudioSetupToolBar::ID(), wxT("ShowAudioSetupTB"), XXO("&Audio Setup Toolbar")
789};
790}
791
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
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define _(s)
Definition: Internat.h:73
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: IteratorX.h:210
#define safenew
Definition: MemoryX.h:10
static const auto title
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
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:165
static TranslatableStrings names
Definition: TagsEditor.cpp:153
const auto project
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:264
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:94
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)
void OnAudioDeviceRescan(wxCommandEvent &)
static constexpr int kAudioDeviceRescan
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:260
DeviceSourceMap * GetDefaultInputDevice(int hostIndex)
const std::vector< DeviceSourceMap > & GetInputDeviceMaps()
const std::vector< DeviceSourceMap > & GetOutputDeviceMaps()
static DeviceManager * Instance()
Gets the singleton instance.
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:128
virtual void UpdateSelectedPrefs(int id)
Definition: Prefs.cpp:158
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:259
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:213
bool Reset()
Reset to the default value.
Definition: Prefs.h:284
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:207
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)
virtual bool Flush() noexcept=0
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
void CallAfter(Action action)
Schedule an action to be done later, and in the main thread.
Definition: BasicUI.cpp:214
void OnFocus(wxWindow &window, wxFocusEvent &event)
a function useful to implement a focus event handler The window releases the keyboard if the event is...
const TranslatableString desc
Definition: ExportPCM.cpp:51
wxString sourceString
Definition: DeviceManager.h:34
wxString deviceString
Definition: DeviceManager.h:35
Window placement information for wxWidgetsBasicUI can be constructed from a wxWindow pointer.