31#include <wx/listbox.h>
34#include <wx/listbook.h>
36#include <wx/treebook.h>
37#include <wx/treectrl.h>
42#include "../ShuttleGui.h"
43#include "../commands/CommandManager.h"
47#include "../widgets/HelpSystem.h"
49#if wxUSE_ACCESSIBILITY
50#include "../widgets/WindowAccessible.h"
54#if wxUSE_ACCESSIBILITY
65 template<
typename Result,
typename Fn >
69 std::vector< wxTreeItemId > stack;
70 stack.push_back( ctrl.GetRootItem() );
71 unsigned position = 0;
72 while ( !stack.empty() ) {
73 auto itemId = stack.back();
74 auto pair =
fn( itemId, position );
78 wxTreeItemIdValue cookie;
79 auto childId = ctrl.GetFirstChild( itemId, cookie );
81 stack.push_back( childId );
83 auto &
id = stack.back();
84 if ( !!(
id = ctrl.GetNextSibling(
id ) ) )
86 }
while ( stack.pop_back(), !stack.empty() );
93 unsigned FindItemPosition(
const wxTreeCtrl &ctrl, wxTreeItemId
id )
98 return VisitItems<unsigned>( ctrl,
99 [=]( wxTreeItemId itemId,
unsigned position ){
100 return std::make_pair( itemId ==
id, position ); } );
103 wxTreeItemId FindItem(
const wxTreeCtrl &ctrl,
int nn )
106 return VisitItems<wxTreeItemId>( ctrl,
107 [=]( wxTreeItemId itemId,
unsigned position ){
108 return std::make_pair( nn == position, itemId ); } );
113class TreeCtrlAx final
117 TreeCtrlAx(wxTreeCtrl * ctrl);
118 virtual ~ TreeCtrlAx();
120 wxAccStatus GetChild(
int childId, wxAccessible** child)
override;
122 wxAccStatus GetChildCount(
int* childCount)
override;
124 wxAccStatus GetDefaultAction(
int childId, wxString *actionName)
override;
127 wxAccStatus GetDescription(
int childId, wxString *description)
override;
133 wxAccStatus GetFocus(
int *childId, wxAccessible **child)
override;
136 wxAccStatus GetHelpText(
int childId, wxString *helpText)
override;
140 wxAccStatus GetKeyboardShortcut(
int childId, wxString *shortcut)
override;
144 wxAccStatus GetLocation(wxRect& rect,
int elementId)
override;
147 wxAccStatus GetName(
int childId, wxString *
name)
override;
150 wxAccStatus GetRole(
int childId, wxAccRole *role)
override;
164 wxAccStatus GetState(
int childId,
long* state)
override;
168 wxAccStatus GetValue(
int childId, wxString* strValue)
override;
174 wxAccStatus Select(
int childId, wxAccSelectionFlags selectFlags)
override;
177 wxTreeCtrl *GetCtrl() {
return static_cast<wxTreeCtrl*
>( GetWindow() ); }
180TreeCtrlAx::TreeCtrlAx( wxTreeCtrl *ctrl )
185TreeCtrlAx::~TreeCtrlAx() =
default;
187wxAccStatus TreeCtrlAx::GetChild(
int childId, wxAccessible** child )
189 if( childId == wxACC_SELF )
201wxAccStatus TreeCtrlAx::GetChildCount(
int* childCount)
203 auto ctrl = GetCtrl();
207 *childCount = ctrl->GetCount();
211wxAccStatus TreeCtrlAx::GetDefaultAction(
int WXUNUSED(childId), wxString* actionName)
219wxAccStatus TreeCtrlAx::GetDescription(
int WXUNUSED(childId), wxString *description )
221 description->clear();
229wxAccStatus TreeCtrlAx::GetFocus(
int *childId, wxAccessible **child )
231 auto ctrl = GetCtrl();
235 auto item = ctrl->GetFocusedItem();
236 auto id = FindItemPosition( *ctrl, item );
243wxAccStatus TreeCtrlAx::GetHelpText(
int WXUNUSED(childId), wxString *helpText )
252wxAccStatus TreeCtrlAx::GetKeyboardShortcut(
int WXUNUSED(childId), wxString *shortcut )
259wxAccStatus TreeCtrlAx::GetLocation( wxRect& rect,
int elementId )
261 auto ctrl = GetCtrl();
265 if (elementId == wxACC_SELF)
266 rect = ctrl->GetRect();
268 auto item = FindItem( *ctrl, elementId );
269 if ( !( item && ctrl->GetBoundingRect( item, rect ) ) )
270 return wxACC_INVALID_ARG;
272 rect.SetPosition( ctrl->GetParent()->ClientToScreen( rect.GetPosition() ) );
276wxAccStatus TreeCtrlAx::GetName(
int childId, wxString*
name)
278 if ( childId == wxACC_SELF )
279 return WindowAccessible::GetName( childId,
name );
281 auto ctrl = GetCtrl();
285 auto item = FindItem( *ctrl, childId );
287 *
name = ctrl->GetItemText( item );
291 return wxACC_INVALID_ARG;
295wxAccStatus TreeCtrlAx::GetRole(
int childId, wxAccRole* role )
300 childId == wxACC_SELF ? wxROLE_SYSTEM_PANE : wxROLE_SYSTEM_STATICTEXT;
305wxAccStatus TreeCtrlAx::GetState(
int childId,
long* state)
307 auto ctrl = GetCtrl();
311 *state = wxACC_STATE_SYSTEM_FOCUSABLE | wxACC_STATE_SYSTEM_SELECTABLE;
313 if ( childId != wxACC_SELF ) {
314 auto item = FindItem( *ctrl, childId );
316 if( item == ctrl->GetFocusedItem() )
317 *state |= wxACC_STATE_SYSTEM_FOCUSED;
319 if( item == ctrl->GetSelection() )
320 *state |= wxACC_STATE_SYSTEM_SELECTED;
329wxAccStatus TreeCtrlAx::GetValue(
int childId, wxString* strValue)
331 *strValue = wxString{};
342wxAccStatus TreeCtrlAx::Select(
int childId, wxAccSelectionFlags selectFlags)
344 auto ctrl = GetCtrl();
348 if (childId != wxACC_SELF) {
350 GetChildCount( &childCount );
351 if (childId > childCount)
354 auto item = FindItem( *ctrl, childId );
356 if (selectFlags == wxACC_SEL_TAKEFOCUS)
357 ctrl->SetFocusedItem( item );
358 else if (selectFlags == wxACC_SEL_TAKESELECTION)
359 ctrl->SelectItem( item );
361 return wxACC_NOT_IMPLEMENTED;
366 return wxACC_NOT_IMPLEMENTED;
386 wxTreebookExt( wxWindow *parent,
389 , mTitlePrefix(titlePrefix)
392 int ChangeSelection(
size_t n)
override;
393 int SetSelection(
size_t n)
override;
398int wxTreebookExt::ChangeSelection(
size_t n) {
399 int i = wxTreebook::ChangeSelection(n);
400 wxString Temp = GetPageText( n );
401 static_cast<wxDialog*
>(GetParent())->SetTitle( Temp );
402 static_cast<wxDialog*
>(GetParent())->SetName( Temp );
406int wxTreebookExt::SetSelection(
size_t n)
408 int i = wxTreebook::SetSelection(n);
409 auto Temp = mTitlePrefix.Translation() + wxT(
" ") + GetPageText( n );
410 static_cast<wxDialog*
>(GetParent())->SetTitle( Temp );
411 static_cast<wxDialog*
>(GetParent())->SetName( Temp );
416 wxWindow *
const helpButton = wxWindow::FindWindowById(wxID_HELP, GetParent());
417 wxWindow *
const previewButton = wxWindow::FindWindowById(wxID_PREVIEW, GetParent());
422#if defined(__WXMAC__)
425 entries[0].Set(wxACCEL_NORMAL, (
int) WXK_F1, wxID_HELP);
427 wxAcceleratorTable accel(1,
entries);
428 this->SetAcceleratorTable(accel);
431 this->SetAcceleratorTable(wxNullAcceleratorTable);
434 const bool changed = helpButton->Show(showHelp);
436 GetParent()->Layout();
440 const bool changed = previewButton->Show(showPreview);
442 GetParent()->Layout();
455 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
456, mFactories(factories)
457, mTitlePrefix(titlePrefix)
459 wxASSERT(factories.size() > 0);
460 const bool uniquePage = (factories.size() == 1);
461 SetLayoutDirection(wxLayout_LeftToRight);
465 S.StartVerticalLay(
true);
467 wxASSERT(factories.size() > 0);
470#if wxUSE_ACCESSIBILITY
477 S.StartHorizontalLay(wxALIGN_LEFT | wxEXPAND,
true);
484 typedef std::pair<int, int> IntPair;
485 std::vector<IntPair> stack;
487 for (
auto it = factories.begin(),
end = factories.end();
488 it !=
end; ++it, ++iPage)
490 const auto &node = *it;
491 const auto &
factory = node.factory;
497 IntPair &top = *stack.rbegin();
498 mCategories->InsertSubPage(top.first, w, w->GetName(),
false, 0);
499 if (--top.second == 0) {
505 if (node.nChildren > 0)
506 stack.push_back(IntPair(iPage, node.nChildren));
510 S.EndHorizontalLay();
518 const auto &node = factories[0];
519 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);
540 wxWindow *
const previewButton =
541 wxWindow::FindWindowById(wxID_PREVIEW, GetParent());
542 previewButton->Show(
false);
545#if defined(__WXGTK__)
553 wxSize sz = GetSize();
559 for (
auto it = factories.begin(),
end = factories.end();
560 it !=
end; ++it, ++iPage)
571 wxRect screenRect(wxGetClientDisplayRect());
572 wxASSERT_MSG(sz.x <= screenRect.width && sz.y <= screenRect.height, wxT(
"Preferences dialog exceeds max size"));
574 sz.DecTo(screenRect.GetSize());
577 int prefWidth, prefHeight;
578 gPrefs->Read(wxT(
"/Prefs/Width"), &prefWidth, sz.x);
579 gPrefs->Read(wxT(
"/Prefs/Height"), &prefHeight, wxMax(480,sz.y));
581 wxSize prefSize = wxSize(prefWidth, prefHeight);
582 prefSize.DecTo(screenRect.GetSize());
584 InvalidateBestSize();
593 mTransaction = std::make_unique< SettingTransaction >();
609 if (selected < 0 ||
size_t(selected) >=
mCategories->GetPageCount())
620 return wxDialogWrapper::ShowModal();
628 for (
size_t i = 0; i <
mCategories->GetPageCount(); i++) {
637 wxSize sz = GetSize();
638 gPrefs->Write(wxT(
"/Prefs/Width"), sz.x);
639 gPrefs->Write(wxT(
"/Prefs/Height"), sz.y);
672 for (
size_t i = 0; i <
mCategories->GetPageCount(); i++) {
687 if(event.GetKeyCode() == WXK_RETURN)
699 for (
size_t i = 0; i <
mCategories->GetPageCount(); i++) {
703 if (!panel->Validate()) {
720 for (
int i = (
int)
mCategories->GetPageCount()-1; i>= 0; i--) {
733 wxSize sz = GetSize();
734 gPrefs->Write(wxT(
"/Prefs/Width"), sz.x);
735 gPrefs->Write(wxT(
"/Prefs/Height"), sz.y);
757 if (gAudioIO->IsMonitoring())
759 gAudioIO->StopStream();
760 while (gAudioIO->IsBusy()) {
761 using namespace std::chrono;
762 std::this_thread::sleep_for(100ms);
765 gAudioIO->HandleDeviceChange();
791 for (
size_t i = 0; i < n; i++) {
816 :
PrefsDialog(parent, pProject,
XO(
"Preferences:"), factories)
826 long prefscat =
gPrefs->Read(wxT(
"/Prefs/PrefsCategory"), 0L);
843 it !=
end; ++it, ++iPage)
872#if defined(__WXGTK__)
880 wxRect r = window.GetRect();
881 window.SetSize(wxSize(1,1));
882 window.SetSize(r.GetSize());
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
const TranslatableString name
void DoReloadPreferences(AudacityProject &project)
static ProjectFileIORegistry::AttributeReaderEntries entries
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()
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
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 ...
void SetTitle(const TranslatableString &title)
A wxTreebook is a class like wxNotebook, but not yet supported by wxWidgets 2.6.3.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
void VisitItems(Registry::Visitor &visitor, CollectedItems &collection, Path &path, GroupItem *pGroup, const GroupItem *pToMerge, const OrderingHint &hint, bool &doFlush)
static void ReinitializeAll()