22#include <wx/stattext.h>
23#include <wx/tooltip.h>
25#include "../ActiveProject.h"
31#include "../KeyboardCapture.h"
33#include "../ProjectWindows.h"
35#include "../prefs/PrefsDialog.h"
36#include "../prefs/DevicePrefs.h"
37#include "../widgets/AButton.h"
38#include "../widgets/BasicMenu.h"
39#include "../widgets/wxWidgetsWindowPlacement.h"
42 static constexpr int kHost = 15000;
111 wxSizeEvent event(GetSize(), GetId());
112 event.SetEventObject(
this);
113 GetEventHandler()->ProcessEvent(event);
133 wxToolTip::Enable(
true);
134 wxToolTip::SetDelay(1000);
145#ifndef USE_AQUA_THEME
146 wxSize s =
mSizer->GetSize();
147 wxPoint p =
mSizer->GetPosition();
149 wxRect bevelRect(p.x, p.y, s.GetWidth() - 1, s.GetHeight() - 1);
156 bool bUseAqua =
false;
158#ifdef EXPERIMENTAL_THEME_PREFS
159 gPrefs->Read(wxT(
"/GUI/ShowMac"), &bUseAqua,
false);
163 bUseAqua = !bUseAqua;
182 bmpRecoloredSetupUpSmall, bmpRecoloredSetupDownSmall,
183 bmpRecoloredSetupUpHiliteSmall, bmpRecoloredSetupHiliteSmall,
184 bmpSetup, bmpSetup, bmpSetup,
195 int flags = wxALIGN_CENTER | wxRIGHT;
201 std::unique_ptr < wxSizer > {
mSizer};
206 auto text =
safenew wxStaticText(
this, wxID_ANY,
"Audio Setup");
210 auto vSizer =
safenew wxBoxSizer(wxVERTICAL);
211 vSizer->AddSpacer(4);
213 vSizer->AddSpacer(4);
214 vSizer->Add(text, 0, flags, 2);
218 mSizer->Add(vSizer, 1, wxEXPAND);
227 SetMinSize(
GetSizer()->GetMinSize());
232 bool isAudioSetupDown =
false;
242 std::unique_ptr < wxSizer > {
mSizer};
248 if (isAudioSetupDown)
271 menu.AppendSeparator();
274 menu.AppendSeparator();
277 menu.AppendSeparator();
280 menu.AppendSeparator();
287 wxRect r = btn->GetRect();
290 { r.GetLeft(), r.GetBottom() }
301 wxString oldHost = selectedHost ? *selectedHost : wxString{};
307 if (oldHost != hostName)
312 if (sourceName.empty())
315 desc = devName + wxT(
": ") + sourceName;
318 if (*selectedInput !=
desc) {
319 if (
auto item =
mInput->FindItem(
desc); item != wxNOT_FOUND) {
320 mInput->FindChildItem(item)->Check();
323 else if (
mInput->GetMenuItemCount()) {
324 for (
size_t i = 0; i < inMaps.size(); i++) {
325 if (inMaps[i].hostString == hostName &&
331 auto item =
mInput->FindChildItem(menuId);
353 if (sourceName.empty())
356 desc = devName + wxT(
": ") + sourceName;
359 if (*selectedOutput !=
desc) {
360 if (
auto item =
mOutput->FindItem(
desc); item != wxNOT_FOUND) {
361 mOutput->FindChildItem(item)->Check();
363 else if (
mOutput->GetMenuItemCount()) {
364 for (
size_t i = 0; i < outMaps.size(); i++) {
365 if (outMaps[i].hostString == hostName &&
371 auto item =
mOutput->FindChildItem(menuId);
393 if (item->IsChecked())
398 if (newChannels > 0 && oldChannels != newChannels)
402 if (!hostName.empty() && selectedHost && selectedHost != hostName) {
403 const auto id =
mHost->FindItem(hostName);
404 if (
id != wxNOT_FOUND) {
405 mHost->FindChildItem(
id)->Check();
434 bool audioStreamActive = gAudioIO->IsStreamActive() && !gAudioIO->IsMonitoring();
436 if (audioStreamActive) {
450 auto pCtrl =
static_cast<AButton*
>(this->FindWindow(iWinID));
455 name = wxT(
"Open Audio Setup");
458 std::vector<ComponentInterfaceSymbol> commands(
491 for (
auto & device : inMaps) {
493 hosts.push_back(device.hostString);
497 for (
auto & device : outMaps) {
499 hosts.push_back(device.hostString);
503 mHost = std::make_unique<wxMenu>();
505 for (
int i = 0; i < hosts.size(); ++i)
516 int foundHostIndex = -1;
520 if (
mHost->FindItem(host) == wxNOT_FOUND) {
524 for (
auto & device : outMaps) {
525 if (device.hostString == host) {
526 foundHostIndex = device.hostIndex;
531 if (foundHostIndex == -1) {
532 for (
auto & device : inMaps) {
533 if (device.hostString == host) {
534 foundHostIndex = device.hostIndex;
541 if (foundHostIndex == -1) {
542 if (outMaps.size()) {
543 foundHostIndex = outMaps[0].hostIndex;
545 else if (inMaps.size()) {
546 foundHostIndex = inMaps[0].hostIndex;
551 mInput = std::make_unique<wxMenu>();
552 mOutput = std::make_unique<wxMenu>();
555 if (foundHostIndex == -1) {
560 for (
int nextMenuId =
kInput, i = 0; i < inMaps.size(); ++i) {
561 auto& device = inMaps[i];
563 if (foundHostIndex == device.hostIndex) {
568 host = device.hostString;
571 const auto id =
mHost->FindItem(host);
572 if (
id != wxNOT_FOUND) {
573 mHost->FindChildItem(
id)->Check();
579 for (
int nextMenuId =
kOutput, i = 0; i < outMaps.size(); ++i) {
580 auto& device = outMaps[i];
582 if (foundHostIndex == device.hostIndex) {
587 host = device.hostString;
591 const auto id =
mHost->FindItem(host);
592 if (
id != wxNOT_FOUND) {
593 mHost->FindChildItem(
id)->Check();
613 for (
auto & dev: inMaps) {
614 if (source == dev.sourceString &&
615 device == dev.deviceString &&
616 host == dev.hostString) {
619 for (
size_t j = 0; j < (
unsigned int)dev.numChannels; j++) {
623 name =
_(
"1 (Mono) Recording Channel");
626 name =
_(
"2 (Stereo) Recording Channels");
629 name = wxString::Format(wxT(
"%d"), (
int)j + 1);
633 newChannels = dev.numChannels;
634 if (oldChannels <= newChannels && oldChannels >= 1) {
635 newChannels = oldChannels;
637 if (newChannels >= 1) {
648 auto clonedMenu = std::make_unique<wxMenu>();
650 for (
const auto& item : menu.GetMenuItems()) {
651 auto cloneMenuItem = clonedMenu->AppendRadioItem(item->GetId(), item->GetItemLabelText());
653 if (item->IsChecked())
654 cloneMenuItem->Check();
663 auto menuItem = menu.AppendSubMenu(clone.release(),
title);
667 menuItem->Enable(
false);
673 const auto& items = menu.GetMenuItems();
675 for (
const auto& item : items) {
676 if (item->IsChecked())
677 return item->GetItemLabelText();
693 auto item =
mHost->FindChildItem(hostId);
701 wxString newHost = item->GetItemLabelText();
703 if (oldHost == newHost)
750 auto item = device->FindChildItem(deviceId);
754 wxString newDevice = item->GetItemLabelText();
756 for (
size_t i = 0; i < maps.size(); ++i) {
758 if (
name == newDevice && maps[i].hostString == host) {
765 wxLogDebug(wxT(
"AudioSetupToolBar::OnMenu(): couldn't find device indices"));
769 SetDevices(isInput ? &maps[newIndex] :
nullptr,
770 isInput ?
nullptr : &maps[newIndex]);
775 int id =
event.GetId();
776 bool audioSettingsChosen =
false;
795 audioSettingsChosen =
true;
813 if (gAudioIO->IsMonitoring())
815 gAudioIO->StopStream();
816 while (gAudioIO->IsBusy()) {
817 using namespace std::chrono;
818 std::this_thread::sleep_for(100ms);
822 if (audioSettingsChosen) {
827 dialog.SetSize(600, 420);
830 if (0 != dialog.ShowModal()) {
835 gAudioIO->HandleDeviceChange();
StringSetting AudioIORecordingSource
StringSetting AudioIOPlaybackSource
StringSetting AudioIOPlaybackDevice
StringSetting AudioIORecordingDevice
StringSetting AudioIOHost
IntSetting AudioIORecordingSourceIndex
IntSetting AudioIORecordChannels
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
wxString MakeDeviceSourceString(const DeviceSourceMap *map)
PrefsPanel * DevicePrefsFactory(wxWindow *parent, wxWindowID winid, AudacityProject *)
const TranslatableString name
const TranslatableString desc
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
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 Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
static void Bevel(wxDC &dc, bool up, const wxRect &r)
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
static AudioIOBase * Get()
void Popup(const BasicUI::WindowPlacement &window, const Point &pos={})
Display the menu at pos, invoke at most one action, then hide it.
size_t size() const
How many attachment pointers are in the Site.
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
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Dialog that shows the current PrefsPanel in a tabbed divider.
static void Broadcast(int id=0)
Call this static function to notify all PrefsListener objects.
virtual void UpdateSelectedPrefs(int id)
std::vector< PrefsPanel::PrefsNode > Factories
bool Write(const T &value)
Write value to config and return true if successful.
bool ReadWithDefault(T *pVar, const T &defaultValue) const
overload of ReadWithDefault returning a boolean that is true if the value was previously defined */
bool Reset()
Reset to the default value.
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined */
wxColour & Colour(int iIndex)
wxSize ImageSize(int iIndex)
Holds a msgid for the translation catalog; may also bind format arguments.
void OnFocus(wxWindow &window, wxFocusEvent &event)
a function useful to implement a focus event handler The window releases the keyboard if the event is...