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 // this was used to draw a bevel and can be removed
144}
145
147{
148 const auto size = wxSize{-1, (toolbarSingle - toolbarMargin ) * 2 };
150 //i18n-hint: Audio setup button text, keep as short as possible
151 mAudioSetup->SetLabel(XO("Audio Setup"));
154 theTheme.Image(bmpRecoloredUpSmall),
155 theTheme.Image(bmpRecoloredUpHiliteSmall),
156 theTheme.Image(bmpRecoloredDownSmall),
157 theTheme.Image(bmpRecoloredHiliteSmall),
158 theTheme.Image(bmpRecoloredUpSmall));
159 mAudioSetup->SetIcon(theTheme.Image(bmpSetup));
160 mAudioSetup->SetForegroundColour(theTheme.Colour(clrTrackPanelText));
161 mAudioSetup->SetMinSize(size);
162 mAudioSetup->SetMaxSize(size);
163}
164
166{
167 Add(mAudioSetup, 0, wxALIGN_CENTER | wxALL, toolbarSpacing);
168 // Layout the toolbar
169 Layout();
170 SetMinSize(GetSizer()->GetMinSize());
171}
172
174{
175 const auto isAudioSetupDown = mAudioSetup != nullptr
177 : false;
178
180
181 if (isAudioSetupDown)
182 {
184 }
185
187
189}
190
191void AudioSetupToolBar::OnFocus(wxFocusEvent &event)
192{
193 KeyboardCapture::OnFocus( *this, event );
194}
195
196void AudioSetupToolBar::OnAudioSetup(wxCommandEvent& WXUNUSED(evt))
197{
198 wxMenu menu;
199
200 //i18n-hint: Audio setup menu
201 mHost.AppendSubMenu(*this, menu, &AudioSetupToolBar::OnHost, _("&Host"));
202 menu.AppendSeparator();
203
204 //i18n-hint: Audio setup menu
205 mOutput.AppendSubMenu(*this, menu,
206 &AudioSetupToolBar::OnOutput, _("&Playback Device"));
207 menu.AppendSeparator();
208
209 //i18n-hint: Audio setup menu
210 mInput.AppendSubMenu(*this, menu,
211 &AudioSetupToolBar::OnInput, _("&Recording Device"));
212 menu.AppendSeparator();
213
214 //i18n-hint: Audio setup menu
216 menu, &AudioSetupToolBar::OnChannels, _("Recording &Channels"));
217 menu.AppendSeparator();
218 menu.Append(kAudioDeviceRescan, _("R&escan Audio Devices"));
219 menu.Append(kAudioSettings, _("&Audio Settings..."));
220
221 menu.Bind(wxEVT_MENU_CLOSE, [this](auto&) { mAudioSetup->PopUp(); });
222 menu.Bind(wxEVT_MENU, &AudioSetupToolBar::OnAudioDeviceRescan, this, kAudioDeviceRescan);
223 menu.Bind(wxEVT_MENU, &AudioSetupToolBar::OnSettings, this, kAudioSettings);
224
225 wxWindow* btn = FindWindow(ID_AUDIO_SETUP_BUTTON);
226 wxRect r = btn->GetRect();
227 BasicMenu::Handle{ &menu }.Popup(
229 { r.GetLeft(), r.GetBottom() }
230 );
231}
232
234{
235 wxString desc;
236 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
237 const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
238
239 auto selectedHost = mHost.Get();
240 wxString oldHost = selectedHost ? *selectedHost : wxString{};
241
242 auto hostName = AudioIOHost.Read();
243
244 // if the prefs host name doesn't match the one displayed, it changed
245 // in another project's AudioSetupToolBar, so we need to repopulate everything.
246 if (oldHost != hostName)
247 // updates mHost and mOutput
249
250 auto devName = AudioIORecordingDevice.Read();
251 auto sourceName = AudioIORecordingSource.Read();
252 if (sourceName.empty())
253 desc = devName;
254 else
255 desc = devName + wxT(": ") + sourceName;
256
257 if (mInput.Get() && *mInput.Get() != desc) {
258 if (mInput.Set(desc))
259 // updates mInputChannels
261 else if (!mInput.Empty()) {
262 for (size_t i = 0; i < inMaps.size(); i++) {
263 if (inMaps[i].hostString == hostName &&
264 MakeDeviceSourceString(&inMaps[i]) == mInput.GetFirst()) {
265 // use the default. It should exist but check just in case, falling back on the 0 index.
266 DeviceSourceMap* defaultMap = DeviceManager::Instance()->GetDefaultInputDevice(inMaps[i].hostIndex);
267 if (defaultMap) {
268 mInput.Set(MakeDeviceSourceString(defaultMap));
269 SetDevices(defaultMap, nullptr);
270 }
271 else {
272 //use the first item (0th index) if we have no familiar devices
273 mInput.Set(0);
274 SetDevices(&inMaps[i], nullptr);
275 }
276 break;
277 }
278 }
279 }
280 }
281
282 devName = AudioIOPlaybackDevice.Read();
283 sourceName = AudioIOPlaybackSource.Read();
284 if (sourceName.empty())
285 desc = devName;
286 else
287 desc = devName + wxT(": ") + sourceName;
288
289 if (mOutput.Get() && *mOutput.Get() != desc) {
290 if (!mOutput.Set(desc) && !mOutput.Empty()) {
291 for (size_t i = 0; i < outMaps.size(); i++) {
292 if (outMaps[i].hostString == hostName &&
293 MakeDeviceSourceString(&outMaps[i]) == mOutput.GetFirst()) {
294 // use the default. It should exist but check just in case, falling back on the 0 index.
295 DeviceSourceMap* defaultMap = DeviceManager::Instance()->GetDefaultInputDevice(outMaps[i].hostIndex);
296 if (defaultMap) {
298 SetDevices(nullptr, defaultMap);
299 }
300 else {
301 //use the first item (0th index) if we have no familiar devices
302 mOutput.Set(0);
303 SetDevices(nullptr, &outMaps[i]);
304 }
305 break;
306 }
307 }
308 }
309 }
310
311 // 0 based choice id is one less than the number of channels
312 long oldChannels = 1 + mInputChannels.GetSmallIntegerId();
313
314 // Preferences store the actual number of channels
315 auto newChannels = AudioIORecordChannels.ReadWithDefault(0);
316 if (newChannels > 0 && oldChannels != newChannels)
317 mInputChannels.Set(newChannels - 1);
318
319 selectedHost = mHost.Get();
320 if (!hostName.empty() && selectedHost && *selectedHost != hostName)
321 mHost.Set(hostName);
322
324
325 // Set label to pull in language change
326 SetLabel(XO("Audio Setup"));
327
328 // Give base class a chance
330
331 Layout();
332 Refresh();
333}
334
336{
337 if (id == DeviceToolbarPrefsID())
338 UpdatePrefs();
340}
341
342
344{
345 auto gAudioIO = AudioIOBase::Get();
346 if (gAudioIO) {
347 // we allow changes when monitoring, but not when recording
348 bool audioStreamActive = gAudioIO->IsStreamActive() && !gAudioIO->IsMonitoring();
349
350 if (audioStreamActive) {
352 }
353 else {
355 }
356 }
357}
358
360{
361#if wxUSE_TOOLTIPS
362 for (long iWinID = ID_AUDIO_SETUP_BUTTON; iWinID < BUTTON_COUNT; iWinID++)
363 {
364 auto pCtrl = static_cast<AButton*>(this->FindWindow(iWinID));
366 switch (iWinID)
367 {
369 name = wxT("Open Audio Setup");
370 break;
371 }
372 std::vector<ComponentInterfaceSymbol> commands(
373 1u, { name, Verbatim(pCtrl->GetLabel()) });
374
375 // Some have a second
376 switch (iWinID)
377 {
379 break;
380 }
382 mProject, *pCtrl, commands.data(), commands.size());
383 }
384#endif
385}
386
388{
389 FillHosts();
392 // make the device display selection reflect the prefs if they exist
393 UpdatePrefs();
394}
395
397{
398 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
399 const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
400
401 wxArrayString hosts;
402
403 // go over our lists add the host to the list if it isn't there yet
404
405 for (auto & device : inMaps) {
406 if (!make_iterator_range(hosts).contains(device.hostString)) {
407 hosts.push_back(device.hostString);
408 }
409 }
410
411 for (auto & device : outMaps) {
412 if (!make_iterator_range(hosts).contains(device.hostString)) {
413 hosts.push_back(device.hostString);
414 }
415 }
416
417 mHost.Set(std::move(hosts));
418}
419
421{
422 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
423 const std::vector<DeviceSourceMap> &outMaps = DeviceManager::Instance()->GetOutputDeviceMaps();
424
425 //read what is in the prefs
426 auto host = AudioIOHost.Read();
427 int foundHostIndex = -1;
428
429 // if the host is not in the hosts combo then we rescanned.
430 // set it to blank so we search for another host.
431 if (mHost.Find(host) < 0)
432 host = wxT("");
433
434 // Try to find a hostIndex, among either inputs or outputs, assumed to be
435 // unique among the union of the set of input and output devices
436 for (auto & device : outMaps) {
437 if (device.hostString == host) {
438 foundHostIndex = device.hostIndex;
439 break;
440 }
441 }
442
443 if (foundHostIndex == -1) {
444 for (auto & device : inMaps) {
445 if (device.hostString == host) {
446 foundHostIndex = device.hostIndex;
447 break;
448 }
449 }
450 }
451
452 // If no host was found based on the prefs device host, load the first available one
453 if (foundHostIndex == -1) {
454 if (outMaps.size()) {
455 foundHostIndex = outMaps[0].hostIndex;
456 }
457 else if (inMaps.size()) {
458 foundHostIndex = inMaps[0].hostIndex;
459 }
460 }
461
462 // Make sure in/out are clear in case no host was found
463 mInput.Clear();
464 mOutput.Clear();
465
466 // If we still have no host it means no devices, in which case do nothing.
467 if (foundHostIndex == -1) {
468 return;
469 }
470
471 // Repopulate the Input/Output device list available to the user
472 wxArrayStringEx mInputDeviceNames;
473 for (size_t i = 0; i < inMaps.size(); ++i) {
474 auto& device = inMaps[i];
475 if (foundHostIndex == device.hostIndex) {
476 mInputDeviceNames.push_back(MakeDeviceSourceString(&device));
477 if (host.empty()) {
478 host = device.hostString;
479 AudioIOHost.Write(host);
480 mHost.Set(host);
481 }
482 }
483 }
484 mInput.Set(std::move(mInputDeviceNames));
485
486 wxArrayStringEx mOutputDeviceNames;
487 for (size_t i = 0; i < outMaps.size(); ++i) {
488 auto& device = outMaps[i];
489 if (foundHostIndex == device.hostIndex) {
490 mOutputDeviceNames.push_back(MakeDeviceSourceString(&device));
491 if (host.empty()) {
492 host = device.hostString;
493 AudioIOHost.Write(host);
494 mHost.Set(host);
495 }
496 }
497 }
498 mOutput.Set(std::move(mOutputDeviceNames));
499
500 gPrefs->Flush();
501
502 // The setting of the Device is left up to menu handlers
503}
504
506{
507 const std::vector<DeviceSourceMap> &inMaps = DeviceManager::Instance()->GetInputDeviceMaps();
508 auto host = AudioIOHost.Read();
509 auto device = AudioIORecordingDevice.Read();
510 auto source = AudioIORecordingSource.Read();
511 long newChannels = 0;
512
513 auto oldChannels = AudioIORecordChannels.Read();
515
517 for (auto & dev: inMaps) {
518 if (source == dev.sourceString &&
519 device == dev.deviceString &&
520 host == dev.hostString) {
521
522 // add one selection for each channel of this source
523 for (size_t j = 0; j < (unsigned int)dev.numChannels; j++) {
524 wxString name;
525
526 if (j == 0) {
527 name = _("1 (Mono) Recording Channel");
528 }
529 else if (j == 1) {
530 name = _("2 (Stereo) Recording Channels");
531 }
532 else {
533 name = wxString::Format(wxT("%d"), (int)j + 1);
534 }
535 names.push_back(name);
536 }
537 newChannels = dev.numChannels;
538 if (oldChannels <= newChannels && oldChannels >= 1) {
539 newChannels = oldChannels;
540 }
541 AudioIORecordChannels.Write(newChannels);
542 break;
543 }
544 }
545 mInputChannels.Set(std::move(names));
546 if (newChannels >= 1)
547 // Correct to 0-based index in choice
548 mInputChannels.Set(newChannels - 1);
549}
550
552 wxMenu& menu, const wxArrayString &labels, int checkedItem,
553 Callback callback, const wxString& title)
554{
555 auto subMenu = std::make_unique<wxMenu>();
556 int ii = 0;
557 for (const auto &label : labels) {
558 // Assign fresh ID with wxID_ANY
559 auto subMenuItem = subMenu->AppendRadioItem(wxID_ANY, label);
560 if (ii == checkedItem)
561 subMenuItem->Check();
562 subMenu->Bind(wxEVT_MENU,
563 [&toolbar, callback, ii](wxCommandEvent &){ (toolbar.*callback)(ii); },
564 subMenuItem->GetId());
565 ++ii;
566 }
567 auto menuItem = menu.AppendSubMenu(subMenu.release(), title);
568 if (checkedItem < 0)
569 menuItem->Enable(false);
570}
571
573 wxMenu &menu, Callback callback, const wxString &title)
574{
576 AppendSubMenu(toolBar, menu, mStrings, mIndex, callback, title);
577}
578
580{
581 // Hosts may have disappeared or appeared so a complete repopulate is needed.
584}
585
586//return true if host changed, false otherwise.
588{
589 // Update cache with selected host
590 if (!mHost.Set(hostId))
591 return false;
592 auto name = mHost.Get();
593 assert(name); // should not be nullopt if Set succeeded
594
595 auto oldHost = AudioIOHost.Read();
596 const auto newHost = *name;
597
598 if (oldHost == newHost)
599 return false;
600
601 //change the host and switch to correct devices.
602 AudioIOHost.Write(newHost);
603 gPrefs->Flush();
604
605 // populate the devices and reassign mHost
607
608 return true;
609}
610
612{
613 if (in) {
616 if (in->totalSources >= 1)
618 else
620 gPrefs->Flush();
621
622 // updates mInputChannels
624 }
625
626 if (out) {
628 if (out->totalSources >= 1) {
630 } else {
632 }
633 gPrefs->Flush();
634 }
635}
636
638 int deviceId, Choices &choices, bool isInput)
639{
640 int newIndex = -1;
641
642 auto host = AudioIOHost.Read();
643 const std::vector<DeviceSourceMap>& maps = isInput ? DeviceManager::Instance()->GetInputDeviceMaps()
645
646 if (choices.Set(deviceId)) {
647 // Update cache with the chosen device
648 wxString newDevice = *choices.Get();
649 for (size_t i = 0; i < maps.size(); ++i) {
650 const auto name = MakeDeviceSourceString(&maps[i]);
651 if (name == newDevice && maps[i].hostString == host)
652 newIndex = i;
653 }
654 }
655
656 if (newIndex < 0) {
657 wxLogDebug(wxT("AudioSetupToolBar::ChangeDeviceLabel(): couldn't find device indices"));
658 return;
659 }
660
661 SetDevices(isInput ? &maps[newIndex] : nullptr,
662 isInput ? nullptr : &maps[newIndex]);
663}
664
666{
667 ChangeHost(id);
668 CommonMenuItemSteps(false);
669}
670
672{
674 // Remember 1-based value in preferences
676 CommonMenuItemSteps(false);
677}
678
680{
681 ChangeDeviceLabel(id, mInput, true);
682 CommonMenuItemSteps(false);
683}
684
686{
687 ChangeDeviceLabel(id, mOutput, false);
688 CommonMenuItemSteps(false);
689}
690
692{
694 {
696 });
697}
698
699void AudioSetupToolBar::OnSettings(wxCommandEvent& event)
700{
702}
703
704void AudioSetupToolBar::CommonMenuItemSteps(bool audioSettingsChosen)
705{
706 auto gAudioIO = AudioIOBase::Get();
707 if (gAudioIO) {
708 // We cannot have gotten here if gAudioIO->IsAudioTokenActive(),
709 // per the setting of AudioIONotBusyFlag and AudioIOBusyFlag in
710 // AudacityProject::GetUpdateFlags().
711 // However, we can have an invalid audio token (so IsAudioTokenActive()
712 // is false), but be monitoring.
713 // If monitoring, have to stop the stream, so HandleDeviceChange() can work.
714 // We could disable the Preferences command while monitoring, i.e.,
715 // set AudioIONotBusyFlag/AudioIOBusyFlag according to monitoring, as well.
716 // Instead allow it because unlike recording, for example, monitoring
717 // is not clearly something that should prohibit changing device.
718 // TODO: We *could* be smarter in this method and call HandleDeviceChange()
719 // only when the device choices actually changed. True of lots of prefs!
720 // As is, we always stop monitoring before handling the device change.
721 if (gAudioIO->IsMonitoring())
722 {
723 gAudioIO->StopStream();
724 while (gAudioIO->IsBusy()) {
725 using namespace std::chrono;
726 std::this_thread::sleep_for(100ms);
727 }
728 }
729
730 if (audioSettingsChosen) {
731 PrefsPanel::Factories factories;
732 factories.push_back(PrefsPanel::PrefsNode(DevicePrefsFactory));
733
734 ViewDeviceSettingsDialog dialog(
735 &GetProjectFrame(mProject), mProject, {}, factories, 0);
736 dialog.SetSize(600, 420);
737 dialog.Center();
738
739 if (0 != dialog.ShowModal()) {
741 }
742 }
743 else {
744 gAudioIO->HandleDeviceChange();
746 }
747 }
748}
749
753 }
754};
755
756namespace {
758 /* i18n-hint: Clicking this menu item shows the toolbar
759 that manages the audio devices */
760 AudioSetupToolBar::ID(), wxT("ShowAudioSetupTB"), XXO("&Audio Setup Toolbar")
761};
762}
763
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.
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 ...
wxString name
Definition: TagsEditor.cpp:166
TranslatableString label
Definition: TagsEditor.cpp:165
static TranslatableStrings names
Definition: TagsEditor.cpp:153
const auto project
THEME_API Theme theTheme
Definition: Theme.cpp:82
static constexpr auto toolbarSpacing
Preferred spacing between inner toolbar elements.
Definition: ToolBar.h:57
static constexpr auto toolbarSingle
Height of a single line toolbar.
Definition: ToolBar.h:53
static constexpr auto toolbarMargin
Preferred inner toolbar margin.
Definition: ToolBar.h:55
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:148
void SetImages(const wxImage &up, const wxImage &over, const wxImage &down, const wxImage &overDown, const wxImage &dis)
Definition: AButton.cpp:221
void PushDown()
Definition: AButton.cpp:664
bool IsDown()
Definition: AButton.h:227
void Disable()
Definition: AButton.cpp:647
void Enable()
Definition: AButton.cpp:638
void PopUp()
Definition: AButton.cpp:672
@ FrameTextVButton
Definition: AButton.h:115
void SetIcon(const wxImage &icon)
Definition: AButton.cpp:242
void SetLabel(const TranslatableString &label)
Definition: AButton.cpp:205
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:73
AudacityProject & mProject
Definition: ToolBar.h:247
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:819
wxBoxSizer * GetSizer()
Definition: ToolBar.cpp:701
void UpdatePrefs() override
Definition: ToolBar.cpp:622
virtual void Create(wxWindow *parent)
Definition: ToolBar.cpp:492
wxWindowPtr< ToolBar > Holder
Definition: ToolBar.h:77
static void SetButtonToolTip(AudacityProject &project, AButton &button, const ComponentInterfaceSymbol commands[], size_t nCommands)
Definition: ToolBar.cpp:934
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.