25#include <wx/listbox.h>
27#include <wx/listbook.h>
29#include <wx/treebook.h>
30#include <wx/treectrl.h>
42#if wxUSE_ACCESSIBILITY
47#if wxUSE_ACCESSIBILITY
58 template<
typename Result,
typename Fn >
62 std::vector< wxTreeItemId > stack;
63 stack.push_back( ctrl.GetRootItem() );
64 unsigned position = 0;
65 while ( !stack.empty() ) {
66 auto itemId = stack.back();
67 auto pair =
fn( itemId, position );
71 wxTreeItemIdValue cookie;
72 auto childId = ctrl.GetFirstChild( itemId, cookie );
74 stack.push_back( childId );
76 auto &
id = stack.back();
77 if ( !!(
id = ctrl.GetNextSibling(
id ) ) )
79 }
while ( stack.pop_back(), !stack.empty() );
86 unsigned FindItemPosition(
const wxTreeCtrl &ctrl, wxTreeItemId
id )
91 return VisitItems<unsigned>( ctrl,
92 [=]( wxTreeItemId itemId,
unsigned position ){
93 return std::make_pair( itemId ==
id, position ); } );
96 wxTreeItemId FindItem(
const wxTreeCtrl &ctrl,
int nn )
99 return VisitItems<wxTreeItemId>( ctrl,
100 [=]( wxTreeItemId itemId,
unsigned position ){
101 return std::make_pair( nn == position, itemId ); } );
106class TreeCtrlAx final
110 TreeCtrlAx(wxTreeCtrl * ctrl);
111 virtual ~ TreeCtrlAx();
113 wxAccStatus GetChild(
int childId, wxAccessible** child)
override;
115 wxAccStatus GetChildCount(
int* childCount)
override;
117 wxAccStatus GetDefaultAction(
int childId, wxString *actionName)
override;
120 wxAccStatus GetDescription(
int childId, wxString *description)
override;
126 wxAccStatus GetFocus(
int *childId, wxAccessible **child)
override;
129 wxAccStatus GetHelpText(
int childId, wxString *helpText)
override;
133 wxAccStatus GetKeyboardShortcut(
int childId, wxString *shortcut)
override;
137 wxAccStatus GetLocation(wxRect& rect,
int elementId)
override;
140 wxAccStatus GetName(
int childId, wxString *
name)
override;
143 wxAccStatus GetRole(
int childId, wxAccRole *role)
override;
157 wxAccStatus GetState(
int childId,
long* state)
override;
161 wxAccStatus GetValue(
int childId, wxString* strValue)
override;
167 wxAccStatus Select(
int childId, wxAccSelectionFlags selectFlags)
override;
170 wxTreeCtrl *GetCtrl() {
return static_cast<wxTreeCtrl*
>( GetWindow() ); }
173TreeCtrlAx::TreeCtrlAx( wxTreeCtrl *ctrl )
178TreeCtrlAx::~TreeCtrlAx() =
default;
180wxAccStatus TreeCtrlAx::GetChild(
int childId, wxAccessible** child )
182 if( childId == wxACC_SELF )
194wxAccStatus TreeCtrlAx::GetChildCount(
int* childCount)
196 auto ctrl = GetCtrl();
200 *childCount = ctrl->GetCount();
204wxAccStatus TreeCtrlAx::GetDefaultAction(
int WXUNUSED(childId), wxString* actionName)
212wxAccStatus TreeCtrlAx::GetDescription(
int WXUNUSED(childId), wxString *description )
214 description->clear();
222wxAccStatus TreeCtrlAx::GetFocus(
int *childId, wxAccessible **child )
224 auto ctrl = GetCtrl();
228 auto item = ctrl->GetFocusedItem();
229 auto id = FindItemPosition( *ctrl, item );
236wxAccStatus TreeCtrlAx::GetHelpText(
int WXUNUSED(childId), wxString *helpText )
245wxAccStatus TreeCtrlAx::GetKeyboardShortcut(
int WXUNUSED(childId), wxString *shortcut )
252wxAccStatus TreeCtrlAx::GetLocation( wxRect& rect,
int elementId )
254 auto ctrl = GetCtrl();
258 if (elementId == wxACC_SELF)
259 rect = ctrl->GetRect();
261 auto item = FindItem( *ctrl, elementId );
262 if ( !( item && ctrl->GetBoundingRect( item, rect ) ) )
263 return wxACC_INVALID_ARG;
265 rect.SetPosition( ctrl->GetParent()->ClientToScreen( rect.GetPosition() ) );
269wxAccStatus TreeCtrlAx::GetName(
int childId, wxString*
name)
271 if ( childId == wxACC_SELF )
272 return WindowAccessible::GetName( childId,
name );
274 auto ctrl = GetCtrl();
278 auto item = FindItem( *ctrl, childId );
280 *
name = ctrl->GetItemText( item );
284 return wxACC_INVALID_ARG;
288wxAccStatus TreeCtrlAx::GetRole(
int childId, wxAccRole* role )
293 childId == wxACC_SELF ? wxROLE_SYSTEM_PANE : wxROLE_SYSTEM_STATICTEXT;
298wxAccStatus TreeCtrlAx::GetState(
int childId,
long* state)
300 auto ctrl = GetCtrl();
304 *state = wxACC_STATE_SYSTEM_FOCUSABLE | wxACC_STATE_SYSTEM_SELECTABLE;
306 if ( childId != wxACC_SELF ) {
307 auto item = FindItem( *ctrl, childId );
309 if( item == ctrl->GetFocusedItem() )
310 *state |= wxACC_STATE_SYSTEM_FOCUSED;
312 if( item == ctrl->GetSelection() )
313 *state |= wxACC_STATE_SYSTEM_SELECTED;
322wxAccStatus TreeCtrlAx::GetValue(
int childId, wxString* strValue)
324 *strValue = wxString{};
335wxAccStatus TreeCtrlAx::Select(
int childId, wxAccSelectionFlags selectFlags)
337 auto ctrl = GetCtrl();
341 if (childId != wxACC_SELF) {
343 GetChildCount( &childCount );
344 if (childId > childCount)
347 auto item = FindItem( *ctrl, childId );
349 if (selectFlags == wxACC_SEL_TAKEFOCUS)
350 ctrl->SetFocusedItem( item );
351 else if (selectFlags == wxACC_SEL_TAKESELECTION)
352 ctrl->SelectItem( item );
354 return wxACC_NOT_IMPLEMENTED;
359 return wxACC_NOT_IMPLEMENTED;
379 wxTreebookExt( wxWindow *parent,
382 , mTitlePrefix(titlePrefix)
385 int ChangeSelection(
size_t n)
override;
386 int SetSelection(
size_t n)
override;
391int wxTreebookExt::ChangeSelection(
size_t n) {
392 int i = wxTreebook::ChangeSelection(n);
393 wxString Temp = GetPageText( n );
394 static_cast<wxDialog*
>(GetParent())->SetTitle( Temp );
395 static_cast<wxDialog*
>(GetParent())->SetName( Temp );
399int wxTreebookExt::SetSelection(
size_t n)
401 int i = wxTreebook::SetSelection(n);
402 auto Temp = mTitlePrefix.Translation() +
wxT(
" ") + GetPageText( n );
403 static_cast<wxDialog*
>(GetParent())->SetTitle( Temp );
404 static_cast<wxDialog*
>(GetParent())->SetName( Temp );
409 wxWindow *
const helpButton = wxWindow::FindWindowById(wxID_HELP, GetParent());
410 wxWindow *
const previewButton = wxWindow::FindWindowById(wxID_PREVIEW, GetParent());
415#if defined(__WXMAC__)
418 entries[0].Set(wxACCEL_NORMAL, (
int) WXK_F1, wxID_HELP);
420 wxAcceleratorTable accel(1,
entries);
421 this->SetAcceleratorTable(accel);
424 this->SetAcceleratorTable(wxNullAcceleratorTable);
427 const bool changed = helpButton->Show(showHelp);
429 GetParent()->Layout();
433 const bool changed = previewButton->Show(showPreview);
435 GetParent()->Layout();
448 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
449, mFactories(factories)
450, mTitlePrefix(titlePrefix)
452 wxASSERT(factories.size() > 0);
453 const bool uniquePage = (factories.size() == 1);
454 SetLayoutDirection(wxLayout_LeftToRight);
458 S.StartVerticalLay(
true);
460 wxASSERT(factories.size() > 0);
463#if wxUSE_ACCESSIBILITY
470 S.StartHorizontalLay(wxALIGN_LEFT | wxEXPAND,
true);
477 typedef std::pair<int, int> IntPair;
478 std::vector<IntPair> stack;
480 for (
auto it = factories.begin(),
end = factories.end();
481 it !=
end; ++it, ++iPage)
483 const auto &node = *it;
484 const auto &
factory = node.factory;
486 node.enabled = (w !=
nullptr);
493 IntPair &top = *stack.rbegin();
496 w, w->GetName(),
false, 0);
497 if (--top.second == 0) {
503 if (node.nChildren > 0)
504 stack.push_back(IntPair(iPage, node.nChildren));
508 S.EndHorizontalLay();
516 const auto &node = factories[0];
517 const auto &
factory = node.factory;
521 wxWindow * uniquePageWindow =
S.Prop(1)
526#if defined(__WXMAC__)
529 entries[0].Set(wxACCEL_NORMAL, (
int) WXK_F1, wxID_HELP);
531 wxAcceleratorTable accel(1,
entries);
532 uniquePageWindow->SetAcceleratorTable(accel);
541 wxWindow *
const previewButton =
542 wxWindow::FindWindowById(wxID_PREVIEW, GetParent());
543 previewButton->Show(
false);
546#if defined(__WXGTK__)
554 wxSize sz = GetSize();
560 for (
auto it = factories.begin(),
end = factories.end();
574 wxRect screenRect(wxGetClientDisplayRect());
575 wxASSERT_MSG(sz.x <= screenRect.width && sz.y <= screenRect.height,
wxT(
"Preferences dialog exceeds max size"));
577 sz.DecTo(screenRect.GetSize());
580 int prefWidth, prefHeight;
582 gPrefs->
Read(
wxT(
"/Prefs/Height"), &prefHeight, wxMax(480,sz.y));
584 wxSize prefSize = wxSize(prefWidth, prefHeight);
585 prefSize.DecTo(screenRect.GetSize());
587 InvalidateBestSize();
596 mTransaction = std::make_unique< SettingTransaction >();
612 if (selected < 0 ||
size_t(selected) >=
mCategories->GetPageCount())
623 return wxDialogWrapper::ShowModal();
631 for (
size_t i = 0; i <
mCategories->GetPageCount(); i++) {
640 wxSize sz = GetSize();
666 const auto &page = pPanel->HelpPageName();
675 for (
size_t i = 0; i <
mCategories->GetPageCount(); i++) {
691 if(event.GetKeyCode() == WXK_RETURN)
703 for (
size_t i = 0; i <
mCategories->GetPageCount(); i++) {
707 if (!panel->Validate()) {
724 for (
int i = (
int)
mCategories->GetPageCount()-1; i>= 0; i--) {
737 wxSize sz = GetSize();
761 if (gAudioIO->IsMonitoring())
763 gAudioIO->StopStream();
764 while (gAudioIO->IsBusy()) {
765 using namespace std::chrono;
766 std::this_thread::sleep_for(100ms);
769 gAudioIO->HandleDeviceChange();
795 for (
size_t i = 0; i < n; i++) {
820 :
PrefsDialog(parent, pProject,
XO(
"Preferences:"), factories)
830 long prefscat =
gPrefs->
Read(
wxT(
"/Prefs/PrefsCategory"), 0L);
849 it->expanded =
mCategories->IsNodeExpanded(iPage++);
857#include "../MenuCreator.h"
878#if defined(__WXGTK__)
886 wxRect r = window.GetRect();
887 window.SetSize(wxSize(1,1));
888 window.SetSize(r.GetSize());
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
static ProjectFileIORegistry::AttributeReaderEntries entries
audacity::BasicSettings * gPrefs
void DoReloadPreferences(AudacityProject &project)
@ Cancel
Open was cancelled by the extension.
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 ...
accessors for certain important windows associated with each project
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
static AudioIOBase * Get()
GlobalPrefsDialog(wxWindow *parent, AudacityProject *pProject, PrefsPanel::Factories &factories=PrefsPanel::DefaultFactories())
virtual ~GlobalPrefsDialog()
void SavePreferredPage() override
long GetPreferredPage() override
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Dialog that shows the current PrefsPanel in a tabbed divider.
void OnPreview(wxCommandEvent &e)
void ShuttleAll(ShuttleGui &S)
void RecordExpansionState()
void OnHelp(wxCommandEvent &e)
int GetSelectedPage() const
const TranslatableString mTitlePrefix
PrefsPanel * GetCurrentPanel()
void OnTreeKeyDown(wxTreeEvent &e)
void OnCancel(wxCommandEvent &e)
virtual void SavePreferredPage()=0
std::unique_ptr< SettingTransaction > mTransaction
PrefsDialog(wxWindow *parent, AudacityProject *pProject, const TranslatableString &titlePrefix=XO("Preferences:"), PrefsPanel::Factories &factories=PrefsPanel::DefaultFactories())
virtual long GetPreferredPage()=0
void OnOK(wxCommandEvent &e)
void SelectPageByName(const wxString &pageName)
PrefsPanel::Factories & mFactories
static void Broadcast(int id=0)
Call this static function to notify all PrefsListener objects.
Base class for a panel in the PrefsDialog. Classes derived from this class include BatchPrefs,...
virtual ManualPageID HelpPageName()
If not empty string, the Help button is added below the panel.
virtual bool ShowsPreviewButton()
virtual void PopulateOrExchange(ShuttleGui &WXUNUSED(S))
std::vector< PrefsPanel::PrefsNode > Factories
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Holds a msgid for the translation catalog; may also bind format arguments.
TranslatableString & Join(TranslatableString arg, const wxString &separator={}) &
Append another translatable string.
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
virtual bool Read(const wxString &key, bool *value) const =0
void SetTitle(const TranslatableString &title)
A wxTreebook is a class like wxNotebook, but not yet supported by wxWidgets 2.6.3.
void VisitItems(VisitorBase &visitor, CollectedItems &collection, Path &path, const GroupItemBase &group, const GroupItemBase *pToMerge, const OrderingHint &hint, bool &doFlush, void *pComputedItemContext)
const char * end(const char *str) noexcept
static void ReinitializeAll()