Audacity  3.0.3
ShuttleGui.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  ShuttleGui.cpp
6 
7  James Crook
8 
9  Audacity is free software.
10  This file is licensed under the wxWidgets license, see License.txt
11 
12 **********************************************************************//***************************************************************//***************************************************************//***************************************************************//******************************************************************/
94 
95 
96 
97 #include "ShuttleGui.h"
98 
99 
100 
101 #include "Prefs.h"
102 #include "ShuttlePrefs.h"
103 #include "Theme.h"
104 
105 #include <wx/setup.h> // for wxUSE_* macros
106 #include <wx/wx.h>
107 #include <wx/wxprec.h>
108 #include <wx/grid.h>
109 #include <wx/listctrl.h>
110 #include <wx/notebook.h>
111 #include <wx/simplebook.h>
112 #include <wx/treectrl.h>
113 #include <wx/spinctrl.h>
114 #include <wx/stattext.h>
115 #include <wx/bmpbuttn.h>
116 #include "../include/audacity/ComponentInterface.h"
117 #include "widgets/ReadOnlyText.h"
118 #include "widgets/wxPanelWrapper.h"
120 #include "AllThemeResources.h"
121 
122 #if wxUSE_ACCESSIBILITY
124 #endif
125 
127  wxWindow * pParent, teShuttleMode ShuttleMode, bool vertical, wxSize minSize )
128  : mpDlg{ pParent }
129 {
130  wxASSERT( (pParent != NULL ) || ( ShuttleMode != eIsCreating));
131  mpbOptionalFlag = nullptr;
132  mpParent = pParent;
133  mShuttleMode = ShuttleMode;
134  Init( vertical, minSize );
135 }
136 
138 {
139 }
140 
141 void ShuttleGuiBase::Init(bool vertical, wxSize minSize)
142 {
143  mpShuttle = NULL;
144  mpSizer = NULL;
145  mpWind = NULL;
146  mpSubSizer = NULL;
147 
148  mRadioSettingName = wxT("");
149  mRadioCount = -1;
150 
151  miBorder = 5;
152  miProp=0;
153  miPropSetByUser=-1;
154  miSizerProp=0;
155  mSizerDepth=-1;
156 
157  ResetId();
158 
159  miNoMatchSelector = 0;
160 
161  if( mShuttleMode != eIsCreating )
162  return;
163 
164  mpSizer = mpParent->GetSizer();
165 
166 #if 0
167  if( mpSizer == NULL )
168  {
169  wxWindow * pGrandParent = mpParent->GetParent();
170  if( pGrandParent )
171  {
172  mpSizer = pGrandParent->GetSizer();
173  }
174  }
175 #endif
176 
177  if( !mpSizer )
178  {
179  mpParent->SetSizer(
180  mpSizer = safenew wxBoxSizer(vertical ? wxVERTICAL : wxHORIZONTAL));
181  }
182  PushSizer();
183  mpSizer->SetMinSize(minSize);
184 }
185 
187 {
188  miIdSetByUser = -1;
189  miId = -1;
190  miIdNext = 3000;
191 }
192 
193 
196 {
197  if( mShuttleMode != eIsCreating )
198  return;
199  wxFlexGridSizer *pSizer = wxDynamicCast(mpSizer, wxFlexGridSizer);
200  wxASSERT( pSizer );
201  pSizer->AddGrowableCol( i, 1 );
202 }
203 
206 {
207  if( mShuttleMode != eIsCreating )
208  return;
209  wxFlexGridSizer *pSizer = wxDynamicCast(mpSizer, wxFlexGridSizer);
210  wxASSERT( pSizer );
211  pSizer->AddGrowableRow( i, 1 );
212 }
213 
214 
215 //---- Add Functions.
216 
218 {
219  // If creating, will be handled by an AddPrompt.
220  if( mShuttleMode == eIsCreating )
221  return;
222  //wxLogDebug( "Optionality: [%s] Id:%i (%i)", Prompt.c_str(), miId, miIdSetByUser ) ;
223  if( mpbOptionalFlag ){
224  bool * pVar = mpbOptionalFlag;
225  mpbOptionalFlag = nullptr;
226  TieCheckBox( Prompt, *pVar);
227  }
228 }
229 
231 void ShuttleGuiBase::AddPrompt(const TranslatableString &Prompt, int wrapWidth)
232 {
233  if( mShuttleMode != eIsCreating )
234  return;
235  //wxLogDebug( "Prompt: [%s] Id:%i (%i)", Prompt.c_str(), miId, miIdSetByUser ) ;
236  if( mpbOptionalFlag ){
237  bool * pVar = mpbOptionalFlag;
238  mpbOptionalFlag = nullptr;
239  TieCheckBox( {}, *pVar);
240  //return;
241  }
242  if( Prompt.empty() )
243  return;
244  miProp=1;
245  const auto translated = Prompt.Translation();
246  auto text = safenew wxStaticText(GetParent(), -1, translated, wxDefaultPosition, wxDefaultSize,
247  GetStyle( wxALIGN_RIGHT ));
248  mpWind = text;
249  if (wrapWidth > 0)
250  text->Wrap(wrapWidth);
251  mpWind->SetName(wxStripMenuCodes(translated)); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
252  UpdateSizersCore( false, wxALL | wxALIGN_CENTRE_VERTICAL, true );
253 }
254 
256 void ShuttleGuiBase::AddUnits(const TranslatableString &Prompt, int wrapWidth)
257 {
258  if( Prompt.empty() )
259  return;
260  if( mShuttleMode != eIsCreating )
261  return;
262  miProp = 1;
263  const auto translated = Prompt.Translation();
264  auto text = safenew wxStaticText(GetParent(), -1, translated, wxDefaultPosition, wxDefaultSize,
265  GetStyle( wxALIGN_LEFT ));
266  mpWind = text;
267  if (wrapWidth > 0)
268  text->Wrap(wrapWidth);
269  mpWind->SetName(translated); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
270  UpdateSizersCore( false, wxALL | wxALIGN_CENTRE_VERTICAL );
271 }
272 
274 void ShuttleGuiBase::AddTitle(const TranslatableString &Prompt, int wrapWidth)
275 {
276  if( Prompt.empty() )
277  return;
278  if( mShuttleMode != eIsCreating )
279  return;
280  const auto translated = Prompt.Translation();
281  auto text = safenew wxStaticText(GetParent(), -1, translated, wxDefaultPosition, wxDefaultSize,
282  GetStyle( wxALIGN_CENTRE ));
283  mpWind = text;
284  if (wrapWidth > 0)
285  text->Wrap(wrapWidth);
286  mpWind->SetName(translated); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
287  UpdateSizers();
288 }
289 
292 wxWindow * ShuttleGuiBase::AddWindow(wxWindow * pWindow)
293 {
294  if( mShuttleMode != eIsCreating )
295  return pWindow;
296  mpWind = pWindow;
297  SetProportions( 0 );
298  UpdateSizersCore(false, wxALIGN_CENTRE | wxALL);
299  return pWindow;
300 }
301 
302 wxCheckBox * ShuttleGuiBase::AddCheckBox( const TranslatableString &Prompt, bool Selected)
303 {
304  HandleOptionality( Prompt );
305  auto realPrompt = Prompt.Translation();
306  if( mpbOptionalFlag )
307  {
308  AddPrompt( {} );
309  //realPrompt = wxT("");
310  }
311 
312  UseUpId();
313  if( mShuttleMode != eIsCreating )
314  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxCheckBox);
315  wxCheckBox * pCheckBox;
316  miProp=0;
317  mpWind = pCheckBox = safenew wxCheckBox(GetParent(), miId, realPrompt, wxDefaultPosition, wxDefaultSize,
318  GetStyle( 0 ));
319  pCheckBox->SetValue(Selected);
320  if (realPrompt.empty()) {
321  // NVDA 2018.3 does not read controls which are buttons, check boxes or radio buttons which have
322  // an accessibility name which is empty. Bug 1980.
323 #if wxUSE_ACCESSIBILITY
324  // so that name can be set on a standard control
325  pCheckBox->SetAccessible(safenew WindowAccessible(pCheckBox));
326 #endif
327  pCheckBox->SetName(wxT("\a")); // non-empty string which screen readers do not read
328  }
329  UpdateSizers();
330  return pCheckBox;
331 }
332 
336 wxCheckBox * ShuttleGuiBase::AddCheckBoxOnRight( const TranslatableString &Prompt, bool Selected)
337 {
338  HandleOptionality( Prompt );
339  AddPrompt( Prompt );
340  UseUpId();
341  if( mShuttleMode != eIsCreating )
342  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxCheckBox);
343  wxCheckBox * pCheckBox;
344  miProp=0;
345  mpWind = pCheckBox = safenew wxCheckBox(GetParent(), miId, wxT(""), wxDefaultPosition, wxDefaultSize,
346  GetStyle( 0 ));
347  pCheckBox->SetValue(Selected);
348  pCheckBox->SetName(Prompt.Stripped().Translation());
349  UpdateSizers();
350  return pCheckBox;
351 }
352 
354  const TranslatableString &Text, int PositionFlags, bool setDefault)
355 {
356  UseUpId();
357  if( mShuttleMode != eIsCreating )
358  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxButton);
359  wxButton * pBtn;
360  const auto translated = Text.Translation();
361  mpWind = pBtn = safenew wxButton(GetParent(), miId,
362  translated, wxDefaultPosition, wxDefaultSize,
363  GetStyle( 0 ) );
364  mpWind->SetName(wxStripMenuCodes(translated));
365  miProp=0;
366  UpdateSizersCore(false, PositionFlags | wxALL);
367  if (setDefault)
368  pBtn->SetDefault();
369  return pBtn;
370 }
371 
373  const wxBitmap &Bitmap, int PositionFlags, bool setDefault)
374 {
375  UseUpId();
376  if( mShuttleMode != eIsCreating )
377  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxBitmapButton);
378  wxBitmapButton * pBtn;
379  mpWind = pBtn = safenew wxBitmapButton(GetParent(), miId, Bitmap,
380  wxDefaultPosition, wxDefaultSize, GetStyle( wxBU_AUTODRAW ) );
381  pBtn->SetBackgroundColour(
382  wxColour( 246,246,243));
383 // wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
384  miProp=0;
385  UpdateSizersCore(false, PositionFlags | wxALL);
386  if (setDefault)
387  pBtn->SetDefault();
388  return pBtn;
389 }
390 
392  const TranslatableStrings &choices, int Selected )
393 {
394  HandleOptionality( Prompt );
395  AddPrompt( Prompt );
396  UseUpId();
397  if( mShuttleMode != eIsCreating )
398  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxChoice);
399  wxChoice * pChoice;
400  miProp=0;
401 
402  mpWind = pChoice = safenew wxChoice(
403  GetParent(),
404  miId,
405  wxDefaultPosition,
406  wxDefaultSize,
407  transform_container<wxArrayString>(
408  choices, std::mem_fn( &TranslatableString::StrippedTranslation ) ),
409  GetStyle( 0 ) );
410 
411  pChoice->SetMinSize( { 180, -1 } );// Use -1 for 'default size' - Platform specific.
412 #ifdef __WXMAC__
413 #if wxUSE_ACCESSIBILITY
414  // so that name can be set on a standard control
415  mpWind->SetAccessible(safenew WindowAccessible(mpWind));
416 #endif
417 #endif
418  pChoice->SetName(Prompt.Stripped().Translation());
419  if ( Selected >= 0 && Selected < (int)choices.size() )
420  pChoice->SetSelection( Selected );
421 
422  UpdateSizers();
423  return pChoice;
424 }
425 
427  const TranslatableStrings &choices, const TranslatableString &Selected )
428 {
429  return AddChoice(
430  Prompt, choices, make_iterator_range( choices ).index( Selected ) );
431 }
432 
434  const TranslatableString &Str, bool bCenter, int wrapWidth)
435 {
436  const auto translated = Str.Translation();
437  UseUpId();
438  if( mShuttleMode != eIsCreating )
439  return;
440  auto text = safenew wxStaticText(GetParent(),
441  miId, translated, wxDefaultPosition, wxDefaultSize,
442  GetStyle( wxALIGN_LEFT ));
443  mpWind = text;
444  if ( wrapWidth > 0 )
445  text->Wrap( wrapWidth );
446  mpWind->SetName(wxStripMenuCodes(translated)); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
447  if( bCenter )
448  {
449  miProp=1;
450  UpdateSizersC();
451  }
452  else
453  UpdateSizers();
454 }
455 
457  const TranslatableString &Str,
458  bool bCenter, int PositionFlags, int wrapWidth )
459 {
460  const auto translated = Str.Translation();
461  UseUpId();
462  if( mShuttleMode != eIsCreating )
463  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxStaticText);
464 
465  wxStaticText *pStatic;
466  auto text = pStatic = safenew wxStaticText(GetParent(), miId, translated,
467  wxDefaultPosition, wxDefaultSize,
468  GetStyle( wxALIGN_LEFT ));
469  mpWind = text;
470  if ( wrapWidth > 0 )
471  text->Wrap( wrapWidth );
472  mpWind->SetName(wxStripMenuCodes(translated)); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
473  if( bCenter )
474  {
475  miProp=1;
476  if( PositionFlags )
477  UpdateSizersCore( false, PositionFlags );
478  else
479  UpdateSizersC();
480  }
481  else
482  if( PositionFlags )
483  UpdateSizersCore( false, PositionFlags );
484  else
485  UpdateSizers();
486  return pStatic;
487 }
488 
490  const TranslatableString &Caption, const wxString &Value)
491 {
492  const auto translated = Caption.Translation();
493  auto style = GetStyle( wxBORDER_NONE );
494  HandleOptionality( Caption );
495  mItem.miStyle = wxALIGN_CENTER_VERTICAL;
496  AddPrompt( Caption );
497  UseUpId();
498  if( mShuttleMode != eIsCreating )
499  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), ReadOnlyText);
500  ReadOnlyText * pReadOnlyText;
501  miProp=0;
502 
503  mpWind = pReadOnlyText = safenew ReadOnlyText(GetParent(), miId, Value,
504  wxDefaultPosition, wxDefaultSize, GetStyle( style ));
505  mpWind->SetName(wxStripMenuCodes(translated));
506  UpdateSizers();
507  return pReadOnlyText;
508 }
509 
511  const TranslatableString &Prompt,
512  const wxString &Selected, const wxArrayStringEx & choices )
513 {
514  const auto translated = Prompt.Translation();
515  HandleOptionality( Prompt );
516  AddPrompt( Prompt );
517  UseUpId();
518  if( mShuttleMode != eIsCreating )
519  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxComboBox);
520  wxComboBox * pCombo;
521  miProp=0;
522 
523  int n = choices.size();
524  if( n>50 ) n=50;
525  int i;
526  wxString Choices[50];
527  for(i=0;i<n;i++)
528  {
529  Choices[i] = choices[i];
530  }
531 
532  mpWind = pCombo = safenew wxComboBox(GetParent(), miId, Selected, wxDefaultPosition, wxDefaultSize,
533  n, Choices, GetStyle( 0 ));
534  mpWind->SetName(wxStripMenuCodes(translated));
535 
536  UpdateSizers();
537  return pCombo;
538 }
539 
540 
542  const TranslatableString &Prompt, int style, int selector, int initValue)
543 {
544  const auto translated = Prompt.Translation();
547  UseUpId();
548  if( mShuttleMode != eIsCreating )
549  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxRadioButton);
550  wxRadioButton * pRad;
551  mpWind = pRad = safenew wxRadioButton(GetParent(), miId, translated,
552  wxDefaultPosition, wxDefaultSize, GetStyle( style ) );
553  mpWind->SetName(wxStripMenuCodes(translated));
554  if ( style )
555  pRad->SetValue( true );
556  UpdateSizers();
557  pRad->SetValue( selector == initValue );
558  return pRad;
559 }
560 
562  const TranslatableString &Prompt, int selector, int initValue)
563 {
564  return DoAddRadioButton( Prompt, wxRB_GROUP, selector, initValue );
565 }
566 
568  const TranslatableString &Prompt, int selector, int initValue)
569 {
570  return DoAddRadioButton( Prompt, 0, selector, initValue );
571 }
572 
573 #ifdef __WXMAC__
574 void wxSliderWrapper::SetFocus()
575 {
576  // bypassing the override in wxCompositeWindow<wxSliderBase> which ends up
577  // doing nothing
578  return wxSliderBase::SetFocus();
579 }
580 #endif
581 
583  const TranslatableString &Prompt, int pos, int Max, int Min)
584 {
585  HandleOptionality( Prompt );
586  AddPrompt( Prompt );
587  UseUpId();
588  if( mShuttleMode != eIsCreating )
589  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxSlider);
590  wxSlider * pSlider;
592  pos, Min, Max,
593  wxDefaultPosition,
594  // Bug2289: On Linux at least, sliders like to be constructed with the
595  // proper size, not reassigned size later
596  ( ( mItem.mWindowSize == wxSize{} ) ? wxDefaultSize : mItem.mWindowSize ),
597  GetStyle( wxSL_HORIZONTAL | wxSL_LABELS | wxSL_AUTOTICKS )
598  );
599 #if wxUSE_ACCESSIBILITY
600  // so that name can be set on a standard control
601  mpWind->SetAccessible(safenew WindowAccessible(mpWind));
602 #endif
603  mpWind->SetName(wxStripMenuCodes(Prompt.Translation()));
604  miProp=1;
605  UpdateSizers();
606  return pSlider;
607 }
608 
610  const TranslatableString &Prompt, int Value, int Max, int Min)
611 {
612  const auto translated = Prompt.Translation();
613  HandleOptionality( Prompt );
614  AddPrompt( Prompt );
615  UseUpId();
616  if( mShuttleMode != eIsCreating )
617  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxSpinCtrl);
618  wxSpinCtrl * pSpinCtrl;
619  mpWind = pSpinCtrl = safenew wxSpinCtrl(GetParent(), miId,
620  wxEmptyString,
621  wxDefaultPosition, wxDefaultSize,
622  GetStyle( wxSP_VERTICAL | wxSP_ARROW_KEYS ),
623  Min, Max, Value
624  );
625  mpWind->SetName(wxStripMenuCodes(translated));
626  miProp=1;
627  UpdateSizers();
628  return pSpinCtrl;
629 }
630 
632  const TranslatableString &Caption, const wxString &Value, const int nChars)
633 {
634  const auto translated = Caption.Translation();
635  HandleOptionality( Caption );
636  AddPrompt( Caption );
637  UseUpId();
638  if( mShuttleMode != eIsCreating )
639  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTextCtrl);
640  wxTextCtrl * pTextCtrl;
641  wxSize Size(wxDefaultSize);
642  if( nChars > 0 )
643  {
644  int width;
645  mpDlg->GetTextExtent( wxT("9"), &width, nullptr );
646  Size.SetWidth( nChars * width );
647  }
648  miProp=0;
649 
650 #ifdef EXPERIMENTAL_RIGHT_ALIGNED_TEXTBOXES
651  long flags = wxTE_RIGHT;
652 #else
653  long flags = wxTE_LEFT;
654 #endif
655 
656  mpWind = pTextCtrl = safenew wxTextCtrlWrapper(GetParent(), miId, Value,
657  wxDefaultPosition, Size, GetStyle( flags ));
658 #if wxUSE_ACCESSIBILITY
659  // so that name can be set on a standard control
660  mpWind->SetAccessible(safenew WindowAccessible(mpWind));
661 #endif
662  mpWind->SetName(wxStripMenuCodes(translated));
663  UpdateSizers();
664  return pTextCtrl;
665 }
666 
668  const TranslatableString &Caption, const wxString &Value, const int nChars)
669 {
670  const auto translated = Caption.Translation();
671  HandleOptionality( Caption );
672  AddPrompt( Caption );
673  UseUpId();
674  if( mShuttleMode != eIsCreating )
675  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTextCtrl);
676  wxTextCtrl * pTextCtrl;
677  wxSize Size(wxDefaultSize);
678  if( nChars > 0 )
679  {
680  Size.SetWidth( nChars *5 );
681  }
682  miProp=0;
683 
684 #ifdef EXPERIMENTAL_RIGHT_ALIGNED_TEXTBOXES
685  long flags = wxTE_RIGHT;
686 #else
687  long flags = wxTE_LEFT;
688 #endif
689 
690  wxTextValidator Validator(wxFILTER_NUMERIC);
691  mpWind = pTextCtrl = safenew wxTextCtrl(GetParent(), miId, Value,
692  wxDefaultPosition, Size, GetStyle( flags ),
693  Validator // It's OK to pass this. It will be cloned.
694  );
695 #if wxUSE_ACCESSIBILITY
696  // so that name can be set on a standard control
697  mpWind->SetAccessible(safenew WindowAccessible(mpWind));
698 #endif
699  mpWind->SetName(wxStripMenuCodes(translated));
700  UpdateSizers();
701  return pTextCtrl;
702 }
703 
705 wxTextCtrl * ShuttleGuiBase::AddTextWindow(const wxString &Value)
706 {
707  UseUpId();
708  if( mShuttleMode != eIsCreating )
709  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTextCtrl);
710  wxTextCtrl * pTextCtrl;
711  SetProportions( 1 );
712  mpWind = pTextCtrl = safenew wxTextCtrl(GetParent(), miId, Value,
713  wxDefaultPosition, wxDefaultSize, GetStyle( wxTE_MULTILINE ));
714 #if wxUSE_ACCESSIBILITY
715  // so that name can be set on a standard control
716  mpWind->SetAccessible(safenew WindowAccessible(mpWind));
717 #endif
718  UpdateSizers();
719  // Start off at start of window...
720  pTextCtrl->SetInsertionPoint( 0 );
721  pTextCtrl->ShowPosition( 0 );
722  return pTextCtrl;
723 }
724 
727  const TranslatableString &Prompt, const TranslatableString &Value)
728 {
729  HandleOptionality( Prompt );
730  AddPrompt( Prompt );
731  UseUpId();
732  if( mShuttleMode != eIsCreating )
733  return;
734 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wx);
735  miProp=0;
736  UpdateSizers();
737  miProp=0;
738  const auto translatedValue = Value.Translation();
739  mpWind = safenew wxStaticText(GetParent(), miId,
740  translatedValue, wxDefaultPosition, wxDefaultSize,
741  GetStyle( 0 ));
742  mpWind->SetName(translatedValue); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
743  UpdateSizers();
744 }
745 
746 wxListBox * ShuttleGuiBase::AddListBox(const wxArrayStringEx &choices)
747 {
748  UseUpId();
749  if( mShuttleMode != eIsCreating )
750  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxListBox);
751  wxListBox * pListBox;
752  SetProportions( 1 );
753  mpWind = pListBox = safenew wxListBox(GetParent(), miId,
754  wxDefaultPosition, wxDefaultSize, choices, GetStyle(0));
755  pListBox->SetMinSize( wxSize( 120,150 ));
756  UpdateSizers();
757  return pListBox;
758 }
759 
760 
762 {
763  UseUpId();
764  if( mShuttleMode != eIsCreating )
765  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxGrid);
766  wxGrid * pGrid;
767  SetProportions( 1 );
768  mpWind = pGrid = safenew wxGrid(GetParent(), miId, wxDefaultPosition,
769  wxDefaultSize, GetStyle( wxWANTS_CHARS ));
770  pGrid->SetMinSize( wxSize( 120, 150 ));
771  UpdateSizers();
772  return pGrid;
773 }
774 
776  std::initializer_list<const ListControlColumn> columns,
777  long listControlStyles
778 )
779 {
780  UseUpId();
781  if( mShuttleMode != eIsCreating )
782  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxListCtrl);
783  wxListCtrl * pListCtrl;
784  SetProportions( 1 );
785  mpWind = pListCtrl = safenew wxListCtrl(GetParent(), miId,
786  wxDefaultPosition, wxDefaultSize, GetStyle( wxLC_ICON ));
787  pListCtrl->SetMinSize( wxSize( 120,150 ));
788  UpdateSizers();
789 
790  DoInsertListColumns( pListCtrl, listControlStyles, columns );
791 
792  return pListCtrl;
793 }
794 
796  std::initializer_list<const ListControlColumn> columns,
797  long listControlStyles
798 )
799 {
800  UseUpId();
801  if( mShuttleMode != eIsCreating )
802  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxListCtrl);
803  wxListCtrl * pListCtrl;
804  SetProportions( 1 );
805  mpWind = pListCtrl = safenew wxListCtrl(GetParent(), miId,
806  wxDefaultPosition, wxSize(230,120),//wxDefaultSize,
807  GetStyle( wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxSUNKEN_BORDER ));
808 // pListCtrl->SetMinSize( wxSize( 120,150 ));
809  UpdateSizers();
810 
811  DoInsertListColumns( pListCtrl, listControlStyles, columns );
812 
813  return pListCtrl;
814 }
815 
817  wxListCtrl *pListCtrl,
818  long listControlStyles,
819  std::initializer_list<const ListControlColumn> columns )
820 {
821  // Old comment from HistoryWindow.cpp follows
822  // -- is it still correct for wxWidgets 3?
823 
824  // Do this BEFORE inserting the columns. On the Mac at least, the
825  // columns are deleted and later InsertItem()s will cause Audacity to crash.
826  for ( auto style = 1l; style <= listControlStyles; style <<= 1 )
827  if ( (style & listControlStyles) )
828  pListCtrl->SetSingleStyle(style, true);
829 
830  long iCol = 0;
831  bool dummyColumn =
832  columns.size() > 0 && begin(columns)->format == wxLIST_FORMAT_RIGHT;
833 
834  //A dummy first column, which is then deleted, is a workaround -
835  // under Windows the first column can't be right aligned.
836  if (dummyColumn)
837  pListCtrl->InsertColumn( iCol++, wxString{} );
838 
839  for (auto &column : columns)
840  pListCtrl->InsertColumn(
841  iCol++, column.heading.Translation(), column.format, column.width );
842 
843  if (dummyColumn)
844  pListCtrl->DeleteColumn( 0 );
845 }
846 
848 {
849  UseUpId();
850  if( mShuttleMode != eIsCreating )
851  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTreeCtrl);
852  wxTreeCtrl * pTreeCtrl;
853  SetProportions( 1 );
854  mpWind = pTreeCtrl = safenew wxTreeCtrl(GetParent(), miId, wxDefaultPosition, wxDefaultSize,
855  GetStyle( wxTR_HAS_BUTTONS ));
856  pTreeCtrl->SetMinSize( wxSize( 120,650 ));
857  UpdateSizers();
858  return pTreeCtrl;
859 }
860 
861 void ShuttleGuiBase::AddIcon(wxBitmap *pBmp)
862 {
863  UseUpId();
864  if( mShuttleMode != eIsCreating )
865 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wx);
866  return;
867  wxBitmapButton * pBtn;
868  mpWind = pBtn = safenew wxBitmapButton(GetParent(), miId, *pBmp,
869  wxDefaultPosition, wxDefaultSize, GetStyle( wxBU_AUTODRAW ) );
870  pBtn->SetWindowStyle( wxBORDER_NONE );
871  pBtn->SetCanFocus(false);
872  UpdateSizersC();
873 }
874 
876 {
877  miPropSetByUser = iProp;
878  return *this;
879 }
880 
886 wxStaticBox * ShuttleGuiBase::StartStatic(const TranslatableString &Str, int iProp)
887 {
888  UseUpId();
889  if( mShuttleMode != eIsCreating )
890  return NULL;
891  auto translated = Str.Translation();
892  wxStaticBox * pBox = safenew wxStaticBoxWrapper(
893  GetParent(), miId, translated );
894  pBox->SetLabel( translated );
895  if (Str.empty()) {
896  // NVDA 2018.3 or later does not read the controls in a group box which has
897  // an accessibility name which is empty. Bug 2169.
898 #if wxUSE_ACCESSIBILITY
899  // so that name can be set on a standard control
900  pBox->SetAccessible(safenew WindowAccessible(pBox));
901 #endif
902  pBox->SetName(wxT("\a")); // non-empty string which screen readers do not read
903  }
904  else
905  pBox->SetName( wxStripMenuCodes( translated ) );
906  mpSubSizer = std::make_unique<wxStaticBoxSizer>(
907  pBox,
908  wxVERTICAL );
909  miSizerProp = iProp;
910  UpdateSizers();
911  mpParent = pBox;
912  return pBox;
913 }
914 
916 {
917  if( mShuttleMode != eIsCreating )
918  return;
919  PopSizer();
920  mpParent = mpParent->GetParent();
921 }
922 
931 wxScrolledWindow * ShuttleGuiBase::StartScroller(int iStyle)
932 {
933  UseUpId();
934  if( mShuttleMode != eIsCreating )
935  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxScrolledWindow);
936 
937  wxScrolledWindow * pScroller;
938  mpWind = pScroller = safenew wxScrolledWindow(GetParent(), miId, wxDefaultPosition, wxDefaultSize,
939  GetStyle( wxSUNKEN_BORDER ) );
940  pScroller->SetScrollRate( 20,20 );
941 
942  // This fools NVDA into not saying "Panel" when the dialog gets focus
943  pScroller->SetName(wxT("\a"));
944  pScroller->SetLabel(wxT("\a"));
945 
946  SetProportions( 1 );
947  if( iStyle==2 )
948  {
950  }
951  else
952  {
953  // mpWind->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR));
954  UpdateSizers(); // adds window in to current sizer.
955  }
956 
957  // create a sizer within the window...
958  mpParent = pScroller;
959  pScroller->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
960  PushSizer();
961  return pScroller;
962 }
963 
965 {
966  if( mShuttleMode != eIsCreating )
967  return;
968  wxSize ScrollSize = mpSizer->GetMinSize();
969  int yMin = ScrollSize.y+4;
970  int xMin = ScrollSize.x+4;
971  if( yMin > 400)
972  {
973  yMin = 400;
974  xMin+=50;// extra space for vertical scrollbar.
975  }
976 
977  mpParent->SetMinSize( wxSize(xMin, yMin) );
978 
979  PopSizer();
980  mpParent = mpParent->GetParent();
981 }
982 
983 wxPanel * ShuttleGuiBase::StartPanel(int iStyle)
984 {
985  UseUpId();
986  if( mShuttleMode != eIsCreating )
987  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxPanel);
988  wxPanel * pPanel;
989  mpWind = pPanel = safenew wxPanelWrapper( GetParent(), miId, wxDefaultPosition, wxDefaultSize,
990  GetStyle( wxNO_BORDER ));
991 
992  if( iStyle != 0 )
993  {
994  mpWind->SetBackgroundColour(
995  iStyle==1
996  ? wxColour( 190,200,230) :
997  wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)
998  );
999  }
1000  SetProportions(0);
1001  miBorder=2;
1002  UpdateSizers(); // adds window in to current sizer.
1003 
1004  // create a sizer within the window...
1005  mpParent = pPanel;
1006  pPanel->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
1007  PushSizer();
1008  return pPanel;
1009 }
1010 
1012 {
1013  if( mShuttleMode != eIsCreating )
1014  return;
1015  PopSizer();
1016  mpParent = mpParent->GetParent();
1017 }
1018 
1020 {
1021  UseUpId();
1022  if( mShuttleMode != eIsCreating )
1023  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxNotebook);
1024  wxNotebook * pNotebook;
1025  mpWind = pNotebook = safenew wxNotebook(GetParent(),
1026  miId, wxDefaultPosition, wxDefaultSize, GetStyle( 0 ));
1027  SetProportions( 1 );
1028  UpdateSizers();
1029  mpParent = pNotebook;
1030  return pNotebook;
1031 }
1032 
1034 {
1035  //PopSizer();
1036  mpParent = mpParent->GetParent();
1037 }
1038 
1039 
1041 {
1042  UseUpId();
1043  if( mShuttleMode != eIsCreating )
1044  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxSimplebook);
1045  wxSimplebook * pNotebook;
1046  mpWind = pNotebook = safenew wxSimplebook(GetParent(),
1047  miId, wxDefaultPosition, wxDefaultSize, GetStyle( 0 ));
1048  SetProportions( 1 );
1049  UpdateSizers();
1050  mpParent = pNotebook;
1051  return pNotebook;
1052 }
1053 
1055 {
1056  //PopSizer();
1057  mpParent = mpParent->GetParent();
1058 }
1059 
1060 
1062  const TranslatableString & Name )
1063 {
1064  if( mShuttleMode != eIsCreating )
1065  return NULL;
1066 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wx);
1067  auto pNotebook = static_cast< wxBookCtrlBase* >( mpParent );
1069  const auto translated = Name.Translation();
1070  pPage->SetName(translated);
1071 
1072  pNotebook->AddPage(
1073  pPage,
1074  translated);
1075 
1076  SetProportions( 1 );
1077  mpParent = pPage;
1078  pPage->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
1079  PushSizer();
1080  // UpdateSizers();
1081  return pPage;
1082 }
1083 
1085 {
1086  if( mShuttleMode != eIsCreating )
1087  return;
1088  PopSizer();
1089  mpParent = mpParent->GetParent();
1090 }
1091 
1092 // Doxygen description is at the start of the file
1093 // this is a wxPanel with erase background disabled.
1094 class InvisiblePanel final : public wxPanelWrapper
1095 {
1096 public:
1098  wxWindow* parent,
1099  wxWindowID id = -1,
1100  const wxPoint& pos = wxDefaultPosition,
1101  const wxSize& size = wxDefaultSize,
1102  long style = wxTAB_TRAVERSAL ) :
1103  wxPanelWrapper( parent, id, pos, size, style )
1104  {
1105  };
1107  void OnPaint( wxPaintEvent &event );
1108  void OnErase(wxEraseEvent &/*evt*/){;};
1109  DECLARE_EVENT_TABLE()
1110 };
1111 
1112 
1113 BEGIN_EVENT_TABLE(InvisiblePanel, wxPanelWrapper)
1114 // EVT_PAINT(InvisiblePanel::OnPaint)
1115  EVT_ERASE_BACKGROUND( InvisiblePanel::OnErase)
1117 
1118 void InvisiblePanel::OnPaint( wxPaintEvent & WXUNUSED(event))
1119 {
1120  // Don't repaint my background.
1121  wxPaintDC dc(this);
1122  // event.Skip(); // swallow the paint event.
1123 }
1124 
1126 {
1127  UseUpId();
1128  if( mShuttleMode != eIsCreating )
1129  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxPanel);
1130  wxPanel * pPanel;
1131  mpWind = pPanel = safenew wxPanelWrapper(GetParent(), miId, wxDefaultPosition, wxDefaultSize,
1132  wxNO_BORDER);
1133 
1134  mpWind->SetBackgroundColour(
1135  wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)
1136  );
1137  SetProportions( 1 );
1138  miBorder=0;
1139  UpdateSizers(); // adds window in to current sizer.
1140 
1141  // create a sizer within the window...
1142  mpParent = pPanel;
1143  pPanel->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
1144  PushSizer();
1145  return pPanel;
1146 }
1147 
1149 {
1150  EndPanel();
1151 }
1152 
1153 
1160 void ShuttleGuiBase::StartHorizontalLay( int PositionFlags, int iProp)
1161 {
1162  if( mShuttleMode != eIsCreating )
1163  return;
1164  miSizerProp=iProp;
1165  mpSubSizer = std::make_unique<wxBoxSizer>( wxHORIZONTAL );
1166  // PRL: wxALL has no effect because UpdateSizersCore ignores border
1167  UpdateSizersCore( false, PositionFlags | wxALL );
1168 }
1169 
1171 {
1172  if( mShuttleMode != eIsCreating )
1173  return;
1174  PopSizer();
1175 }
1176 
1178 {
1179  if( mShuttleMode != eIsCreating )
1180  return;
1181  miSizerProp=iProp;
1182  mpSubSizer = std::make_unique<wxBoxSizer>( wxVERTICAL );
1183  UpdateSizers();
1184 }
1185 
1186 void ShuttleGuiBase::StartVerticalLay(int PositionFlags, int iProp)
1187 {
1188  if( mShuttleMode != eIsCreating )
1189  return;
1190  miSizerProp=iProp;
1191  mpSubSizer = std::make_unique<wxBoxSizer>( wxVERTICAL );
1192  // PRL: wxALL has no effect because UpdateSizersCore ignores border
1193  UpdateSizersCore( false, PositionFlags | wxALL );
1194 }
1195 
1197 {
1198  if( mShuttleMode != eIsCreating )
1199  return;
1200  PopSizer();
1201 }
1202 
1203 void ShuttleGuiBase::StartMultiColumn(int nCols, int PositionFlags)
1204 {
1205  if( mShuttleMode != eIsCreating )
1206  return;
1207  mpSubSizer = std::make_unique<wxFlexGridSizer>( nCols );
1208  // PRL: wxALL has no effect because UpdateSizersCore ignores border
1209  UpdateSizersCore( false, PositionFlags | wxALL );
1210 }
1211 
1213 {
1214  if( mShuttleMode != eIsCreating )
1215  return;
1216  PopSizer();
1217 }
1218 
1221 void ShuttleGuiBase::DoDataShuttle( const wxString &Name, WrappedType & WrappedRef )
1222 {
1223  wxASSERT( mpShuttle );
1224  mpShuttle->TransferWrappedType( Name, WrappedRef );
1225 }
1226 
1227 //-----------------------------------------------------------------------//
1228 
1229 // We now have a group of tie functions which are generic in the type
1230 // they bind to (i.e. WrappedType).
1231 // The type specific versions are much shorter and are later
1232 // in this file.
1233 wxCheckBox * ShuttleGuiBase::DoTieCheckBox(const TranslatableString &Prompt, WrappedType & WrappedRef)
1234 {
1235  HandleOptionality( Prompt );
1236  // The Add function does a UseUpId(), so don't do it here in that case.
1237  if( mShuttleMode == eIsCreating )
1238  return AddCheckBox( Prompt, WrappedRef.ReadAsString() == wxT("true"));
1239 
1240  UseUpId();
1241 
1242  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1243  wxCheckBox * pCheckBox = wxDynamicCast(pWnd, wxCheckBox);
1244 
1245  switch( mShuttleMode )
1246  {
1247  // IF setting internal storage from the controls.
1248  case eIsGettingMetadata:
1249  break;
1250  case eIsGettingFromDialog:
1251  {
1252  wxASSERT( pCheckBox );
1253  WrappedRef.WriteToAsBool( pCheckBox->GetValue() );
1254  }
1255  break;
1256  case eIsSettingToDialog:
1257  {
1258  wxASSERT( pCheckBox );
1259  pCheckBox->SetValue( WrappedRef.ReadAsBool() );
1260  }
1261  break;
1262  default:
1263  wxASSERT( false );
1264  break;
1265  }
1266  return pCheckBox;
1267 }
1268 
1270 {
1271  HandleOptionality( Prompt );
1272  // The Add function does a UseUpId(), so don't do it here in that case.
1273  if( mShuttleMode == eIsCreating )
1274  return AddCheckBoxOnRight( Prompt, WrappedRef.ReadAsString() == wxT("true"));
1275 
1276  UseUpId();
1277 
1278  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1279  wxCheckBox * pCheckBox = wxDynamicCast(pWnd, wxCheckBox);
1280 
1281  switch( mShuttleMode )
1282  {
1283  // IF setting internal storage from the controls.
1284  case eIsGettingMetadata:
1285  break;
1286  case eIsGettingFromDialog:
1287  {
1288  wxASSERT( pCheckBox );
1289  WrappedRef.WriteToAsBool( pCheckBox->GetValue() );
1290  }
1291  break;
1292  case eIsSettingToDialog:
1293  {
1294  wxASSERT( pCheckBox );
1295  pCheckBox->SetValue( WrappedRef.ReadAsBool() );
1296  }
1297  break;
1298  default:
1299  wxASSERT( false );
1300  break;
1301  }
1302  return pCheckBox;
1303 }
1304 
1306  const TranslatableString &Prompt,
1307  WrappedType & WrappedRef, const int max, const int min )
1308 {
1309  HandleOptionality( Prompt );
1310  // The Add function does a UseUpId(), so don't do it here in that case.
1311  if( mShuttleMode == eIsCreating )
1312  return AddSpinCtrl( Prompt, WrappedRef.ReadAsInt(), max, min );
1313 
1314  UseUpId();
1315  wxSpinCtrl * pSpinCtrl=NULL;
1316 
1317  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1318  pSpinCtrl = wxDynamicCast(pWnd, wxSpinCtrl);
1319 
1320  switch( mShuttleMode )
1321  {
1322  // IF setting internal storage from the controls.
1323  case eIsGettingMetadata:
1324  break;
1325  case eIsGettingFromDialog:
1326  {
1327  wxASSERT( pSpinCtrl );
1328  WrappedRef.WriteToAsInt( pSpinCtrl->GetValue() );
1329  }
1330  break;
1331  case eIsSettingToDialog:
1332  {
1333  wxASSERT( pSpinCtrl );
1334  pSpinCtrl->SetValue( WrappedRef.ReadAsInt() );
1335  }
1336  break;
1337  default:
1338  wxASSERT( false );
1339  break;
1340  }
1341  return pSpinCtrl;
1342 }
1343 
1345  const TranslatableString &Prompt, WrappedType & WrappedRef, const int nChars)
1346 {
1347  HandleOptionality( Prompt );
1348  // The Add function does a UseUpId(), so don't do it here in that case.
1349  if( mShuttleMode == eIsCreating )
1350  return AddTextBox( Prompt, WrappedRef.ReadAsString(), nChars );
1351 
1352  UseUpId();
1353  wxTextCtrl * pTextBox=NULL;
1354 
1355  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1356  pTextBox = wxDynamicCast(pWnd, wxTextCtrl);
1357 
1358  switch( mShuttleMode )
1359  {
1360  // IF setting internal storage from the controls.
1361  case eIsGettingMetadata:
1362  break;
1363  case eIsGettingFromDialog:
1364  {
1365  wxASSERT( pTextBox );
1366  WrappedRef.WriteToAsString( pTextBox->GetValue() );
1367  }
1368  break;
1369  case eIsSettingToDialog:
1370  {
1371  wxASSERT( pTextBox );
1372  pTextBox->SetValue( WrappedRef.ReadAsString() );
1373  }
1374  break;
1375  default:
1376  wxASSERT( false );
1377  break;
1378  }
1379  return pTextBox;
1380 }
1381 
1383  const TranslatableString &Prompt, WrappedType & WrappedRef, const int nChars)
1384 {
1385  HandleOptionality( Prompt );
1386  // The Add function does a UseUpId(), so don't do it here in that case.
1387  if( mShuttleMode == eIsCreating )
1388  return AddNumericTextBox( Prompt, WrappedRef.ReadAsString(), nChars );
1389 
1390  UseUpId();
1391  wxTextCtrl * pTextBox=NULL;
1392 
1393  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1394  pTextBox = wxDynamicCast(pWnd, wxTextCtrl);
1395 
1396  switch( mShuttleMode )
1397  {
1398  // IF setting internal storage from the controls.
1399  case eIsGettingMetadata:
1400  break;
1401  case eIsGettingFromDialog:
1402  {
1403  wxASSERT( pTextBox );
1404  WrappedRef.WriteToAsString( pTextBox->GetValue() );
1405  }
1406  break;
1407  case eIsSettingToDialog:
1408  {
1409  wxASSERT( pTextBox );
1410  pTextBox->SetValue( WrappedRef.ReadAsString() );
1411  }
1412  break;
1413  default:
1414  wxASSERT( false );
1415  break;
1416  }
1417  return pTextBox;
1418 }
1419 
1421  const TranslatableString &Prompt,
1422  WrappedType & WrappedRef, const int max, int min )
1423 {
1424  HandleOptionality( Prompt );
1425  // The Add function does a UseUpId(), so don't do it here in that case.
1426  if( mShuttleMode != eIsCreating )
1427  UseUpId();
1428  wxSlider * pSlider=NULL;
1429  switch( mShuttleMode )
1430  {
1431  case eIsCreating:
1432  {
1433  pSlider = AddSlider( Prompt, WrappedRef.ReadAsInt(), max, min );
1434  }
1435  break;
1436  // IF setting internal storage from the controls.
1437  case eIsGettingMetadata:
1438  break;
1439  case eIsGettingFromDialog:
1440  {
1441  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1442  pSlider = wxDynamicCast(pWnd, wxSlider);
1443  wxASSERT( pSlider );
1444  WrappedRef.WriteToAsInt( pSlider->GetValue() );
1445  }
1446  break;
1447  case eIsSettingToDialog:
1448  {
1449  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1450  pSlider = wxDynamicCast(pWnd, wxSlider);
1451  wxASSERT( pSlider );
1452  pSlider->SetValue( WrappedRef.ReadAsInt() );
1453  }
1454  break;
1455  default:
1456  wxASSERT( false );
1457  break;
1458  }
1459  return pSlider;
1460 }
1461 
1462 
1464  const TranslatableString &Prompt,
1465  int &Selected,
1466  const TranslatableStrings &choices )
1467 {
1468  HandleOptionality( Prompt );
1469 
1470  // The Add function does a UseUpId(), so don't do it here in that case.
1471  if( mShuttleMode != eIsCreating )
1472  UseUpId();
1473 
1474  wxChoice * pChoice=NULL;
1475  switch( mShuttleMode )
1476  {
1477  case eIsCreating:
1478  {
1479  pChoice = AddChoice( Prompt, choices, Selected );
1480  ShuttleGui::SetMinSize(pChoice, choices);
1481  }
1482  break;
1483  // IF setting internal storage from the controls.
1484  case eIsGettingMetadata:
1485  break;
1486  case eIsGettingFromDialog:
1487  {
1488  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1489  pChoice = wxDynamicCast(pWnd, wxChoice);
1490  wxASSERT( pChoice );
1491  Selected = pChoice->GetSelection();
1492  }
1493  break;
1494  case eIsSettingToDialog:
1495  {
1496  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1497  pChoice = wxDynamicCast(pWnd, wxChoice);
1498  wxASSERT( pChoice );
1499  pChoice->SetSelection( Selected );
1500  }
1501  break;
1502  default:
1503  wxASSERT( false );
1504  break;
1505  }
1506  return pChoice;
1507 }
1508 
1511 {
1512  wxASSERT( mRadioCount >= 0); // Did you remember to use StartRadioButtonGroup() ?
1513 
1514  EnumValueSymbol symbol;
1515  if (mRadioCount >= 0 && mRadioCount < (int)mRadioSymbols.size() )
1516  symbol = mRadioSymbols[ mRadioCount ];
1517 
1518  // In what follows, WrappedRef is used in read only mode, but we
1519  // don't have a 'read-only' version, so we copy to deal with the constness.
1520  auto Temp = symbol.Internal();
1521  wxASSERT( !Temp.empty() ); // More buttons than values?
1522 
1523  WrappedType WrappedRef( Temp );
1524 
1525  mRadioCount++;
1526 
1527  UseUpId();
1528  wxRadioButton * pRadioButton = NULL;
1529 
1530  switch( mShuttleMode )
1531  {
1532  case eIsCreating:
1533  {
1534  const auto &Prompt = symbol.Translation();
1535 
1536  mpWind = pRadioButton = safenew wxRadioButton(GetParent(), miId, Prompt,
1537  wxDefaultPosition, wxDefaultSize,
1538  (mRadioCount==1)?wxRB_GROUP:0);
1539 
1540  wxASSERT( WrappedRef.IsString() );
1541  wxASSERT( mRadioValue->IsString() );
1542  const bool value =
1543  (WrappedRef.ReadAsString() == mRadioValue->ReadAsString() );
1544  pRadioButton->SetValue( value );
1545 
1546  pRadioButton->SetName(wxStripMenuCodes(Prompt));
1547  UpdateSizers();
1548  }
1549  break;
1550  case eIsGettingMetadata:
1551  break;
1552  case eIsGettingFromDialog:
1553  {
1554  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1555  pRadioButton = wxDynamicCast(pWnd, wxRadioButton);
1556  wxASSERT( pRadioButton );
1557  if( pRadioButton->GetValue() )
1558  mRadioValue->WriteToAsString( WrappedRef.ReadAsString() );
1559  }
1560  break;
1561  default:
1562  wxASSERT( false );
1563  break;
1564  }
1565  return pRadioButton;
1566 }
1567 
1570 {
1571  mRadioSymbols = Setting.GetSymbols();
1572 
1573  // Configure the generic type mechanism to use OUR string.
1574  mRadioValueString = Setting.Default().Internal();
1576 
1577  // Now actually start the radio button group.
1578  mRadioSettingName = Setting.Key();
1579  mRadioCount = 0;
1580  if( mShuttleMode == eIsCreating )
1581  DoDataShuttle( Setting.Key(), *mRadioValue );
1582 }
1583 
1587 {
1588  // too few buttons?
1589  wxASSERT( mRadioCount == mRadioSymbols.size() );
1590 
1593  mRadioValue.reset();// Clear it out...
1594  mRadioSettingName = wxT("");
1595  mRadioCount = -1; // So we detect a problem.
1596  mRadioSymbols = {};
1597 }
1598 
1599 //-----------------------------------------------------------------------//
1600 //-- Now we are into type specific Tie() functions.
1601 //-- These are all 'one-step' tie functions.
1602 
1603 wxCheckBox * ShuttleGuiBase::TieCheckBox(const TranslatableString &Prompt, bool &Var)
1604 {
1605  WrappedType WrappedRef( Var );
1606  return DoTieCheckBox( Prompt, WrappedRef );
1607 }
1608 
1609 // See comment in AddCheckBoxOnRight() for why we have this variant.
1610 wxCheckBox * ShuttleGuiBase::TieCheckBoxOnRight(const TranslatableString &Prompt, bool &Var)
1611 {
1612  // Only does anything different if it's creating.
1613  WrappedType WrappedRef( Var );
1614  if( mShuttleMode == eIsCreating )
1615  return AddCheckBoxOnRight( Prompt, WrappedRef.ReadAsString() == wxT("true") );
1616  return DoTieCheckBox( Prompt, WrappedRef );
1617 }
1618 
1620  const TranslatableString &Prompt, int &Value, const int max, const int min )
1621 {
1622  WrappedType WrappedRef(Value);
1623  return DoTieSpinCtrl( Prompt, WrappedRef, max, min );
1624 }
1625 
1627  const TranslatableString &Prompt, wxString &Selected, const int nChars)
1628 {
1629  WrappedType WrappedRef(Selected);
1630  return DoTieTextBox( Prompt, WrappedRef, nChars );
1631 }
1632 
1634  const TranslatableString &Prompt, int &Selected, const int nChars)
1635 {
1636  WrappedType WrappedRef( Selected );
1637  return DoTieTextBox( Prompt, WrappedRef, nChars );
1638 }
1639 
1641  const TranslatableString &Prompt, double &Value, const int nChars)
1642 {
1643  WrappedType WrappedRef( Value );
1644  return DoTieTextBox( Prompt, WrappedRef, nChars );
1645 }
1646 
1648  const TranslatableString &Prompt, int &Value, const int nChars)
1649 {
1650  WrappedType WrappedRef( Value );
1651  return DoTieNumericTextBox( Prompt, WrappedRef, nChars );
1652 }
1653 
1655  const TranslatableString &Prompt, double &Value, const int nChars)
1656 {
1657  WrappedType WrappedRef( Value );
1658  return DoTieNumericTextBox( Prompt, WrappedRef, nChars );
1659 }
1660 
1662  const TranslatableString &Prompt, int &pos, const int max, const int min )
1663 {
1664  WrappedType WrappedRef( pos );
1665  return DoTieSlider( Prompt, WrappedRef, max, min );
1666 }
1667 
1669  const TranslatableString &Prompt,
1670  double &pos, const double max, const double min )
1671 {
1672  WrappedType WrappedRef( pos );
1673  return DoTieSlider( Prompt, WrappedRef, max, min );
1674 }
1675 
1677  const TranslatableString &Prompt,
1678  float &pos, const float fMin, const float fMax)
1679 {
1680  const float RoundFix=0.0000001f;
1681  int iVal=(pos-fMin+RoundFix)*100.0/(fMax-fMin);
1682  wxSlider * pWnd = TieSlider( Prompt, iVal, 100 );
1683  pos = iVal*(fMax-fMin)*0.01+fMin;
1684  return pWnd;
1685 }
1686 
1688  const TranslatableString &Prompt,
1689  float &pos, const float fMin, const float fMax)
1690 {
1691  int iVal=(pos-fMin)*100.0/(fMax-fMin);
1692 // if( mShuttleMode == eIsCreating )
1693 // {
1694 // return AddVSlider( Prompt, iVal, 100 );
1695 // }
1696  wxSlider * pWnd = TieSlider( Prompt, iVal, 100 );
1697  pos = iVal*(fMax-fMin)*0.01+fMin;
1698  return pWnd;
1699 }
1700 
1702  const TranslatableString &Prompt,
1703  TranslatableString &Selected,
1704  const TranslatableStrings &choices )
1705 {
1706  int Index = make_iterator_range( choices ).index( Selected );
1707  auto result = TieChoice( Prompt, Index, choices );
1708  if ( Index >= 0 && Index < choices.size() )
1709  Selected = choices[ Index ];
1710  else
1711  Selected = {};
1712  return result;
1713 }
1714 
1715 //-----------------------------------------------------------------------//
1716 
1717 // ShuttleGui utility functions to look things up in a list.
1718 // If not present, we use the configured default index value.
1719 
1720 //-----------------------------------------------------------------------//
1721 
1723 int ShuttleGuiBase::TranslateToIndex( const wxString &Value, const wxArrayStringEx &Choices )
1724 {
1725  int n = make_iterator_range( Choices ).index( Value );
1726  if( n == wxNOT_FOUND )
1728  miNoMatchSelector = 0;
1729  return n;
1730 }
1731 
1733 wxString ShuttleGuiBase::TranslateFromIndex( const int nIn, const wxArrayStringEx &Choices )
1734 {
1735  int n = nIn;
1736  if( n== wxNOT_FOUND )
1738  miNoMatchSelector = 0;
1739  if( n < (int)Choices.size() )
1740  {
1741  return Choices[n];
1742  }
1743  return wxT("");
1744 }
1745 
1746 //-----------------------------------------------------------------------//
1747 
1748 
1749 // ShuttleGui code uses the model that you read into program variables
1750 // and write out from program variables.
1751 
1752 // In programs like Audacity which don't use internal program variables
1753 // you have to do both steps in one go, using variants of the standard
1754 // 'Tie' functions which call the underlying Tie functions twice.
1755 
1756 //----------------------------------------------------------------------//
1757 
1758 
1791 bool ShuttleGuiBase::DoStep( int iStep )
1792 {
1793  // Get value and create
1794  if( mShuttleMode == eIsCreating )
1795  {
1796  return (iStep==1) || (iStep==2);
1797  }
1798  // Like creating, get the value and set.
1800  {
1801  return (iStep==1) || (iStep==2);
1802  }
1804  {
1805  return (iStep==2) || (iStep==3);
1806  }
1808  return iStep ==2;
1809  wxASSERT( false );
1810  return false;
1811 }
1812 
1813 
1817  const TranslatableString &Prompt,
1818  const SettingSpec< bool > &Setting)
1819 {
1820  wxCheckBox * pCheck=NULL;
1821 
1822  auto Value = Setting.GetDefault();
1823  WrappedType WrappedRef( Value );
1824  if( DoStep(1) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1825  if( DoStep(2) ) pCheck = DoTieCheckBox( Prompt, WrappedRef );
1826  if( DoStep(3) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1827 
1828  return pCheck;
1829 }
1830 
1834  const TranslatableString &Prompt,
1835  const SettingSpec< bool > &Setting)
1836 {
1837  wxCheckBox * pCheck=NULL;
1838 
1839  auto Value = Setting.GetDefault();
1840  WrappedType WrappedRef( Value );
1841  if( DoStep(1) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1842  if( DoStep(2) ) pCheck = DoTieCheckBoxOnRight( Prompt, WrappedRef );
1843  if( DoStep(3) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1844 
1845  return pCheck;
1846 }
1847 
1851  const TranslatableString &Prompt,
1852  const SettingSpec< int > &Setting,
1853  const int max,
1854  const int min)
1855 {
1856  wxSlider * pSlider=NULL;
1857 
1858  auto Value = Setting.GetDefault();
1859  WrappedType WrappedRef( Value );
1860  if( DoStep(1) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1861  if( DoStep(2) ) pSlider = DoTieSlider( Prompt, WrappedRef, max, min );
1862  if( DoStep(3) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1863 
1864  return pSlider;
1865 }
1866 
1870  const TranslatableString &Prompt,
1871  const SettingSpec< int > &Setting,
1872  const int max,
1873  const int min)
1874 {
1875  wxSpinCtrl * pSpinCtrl=NULL;
1876 
1877  auto Value = Setting.GetDefault();
1878  WrappedType WrappedRef( Value );
1879  if( DoStep(1) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1880  if( DoStep(2) ) pSpinCtrl = DoTieSpinCtrl( Prompt, WrappedRef, max, min );
1881  if( DoStep(3) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1882 
1883  return pSpinCtrl;
1884 }
1885 
1889  const TranslatableString & Prompt,
1890  const SettingSpec< wxString > &Setting,
1891  const int nChars)
1892 {
1893  wxTextCtrl * pText=(wxTextCtrl*)NULL;
1894 
1895  auto Value = Setting.GetDefault();
1896  WrappedType WrappedRef( Value );
1897  if( DoStep(1) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1898  if( DoStep(2) ) pText = DoTieTextBox( Prompt, WrappedRef, nChars );
1899  if( DoStep(3) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1900  return pText;
1901 }
1902 
1907  const TranslatableString & Prompt,
1908  const SettingSpec< int > &Setting,
1909  const int nChars)
1910 {
1911  wxTextCtrl * pText=(wxTextCtrl*)NULL;
1912 
1913  auto Value = Setting.GetDefault();
1914  WrappedType WrappedRef( Value );
1915  if( DoStep(1) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1916  if( DoStep(2) ) pText = DoTieNumericTextBox( Prompt, WrappedRef, nChars );
1917  if( DoStep(3) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1918  return pText;
1919 }
1920 
1925  const TranslatableString & Prompt,
1926  const SettingSpec< double > &Setting,
1927  const int nChars)
1928 {
1929  wxTextCtrl * pText=(wxTextCtrl*)NULL;
1930 
1931  auto Value = Setting.GetDefault();
1932  WrappedType WrappedRef( Value );
1933  if( DoStep(1) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1934  if( DoStep(2) ) pText = DoTieNumericTextBox( Prompt, WrappedRef, nChars );
1935  if( DoStep(3) ) DoDataShuttle( Setting.GetPath(), WrappedRef );
1936  return pText;
1937 }
1938 
1946  const TranslatableString &Prompt,
1947  const ChoiceSetting &choiceSetting )
1948 {
1949  // Do this to force any needed migrations first
1950  choiceSetting.Read();
1951 
1952  const auto &symbols = choiceSetting.GetSymbols();
1953  const auto &SettingName = choiceSetting.Key();
1954  const auto &Default = choiceSetting.Default().Internal();
1955  const auto &Choices = symbols.GetMsgids();
1956  const auto &InternalChoices = symbols.GetInternals();
1957 
1958  wxChoice * pChoice=(wxChoice*)NULL;
1959 
1960  int TempIndex=0;
1961 // int TempIndex = TranslateToIndex( Default, InternalChoices );
1962  wxString TempStr = Default;
1963  WrappedType WrappedRef( TempStr );
1964  // Get from prefs does 1 and 2.
1965  // Put to prefs does 2 and 3.
1966  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef ); // Get Index from Prefs.
1967  if( DoStep(1) ) TempIndex = TranslateToIndex( TempStr, InternalChoices ); // To an index
1968  if( DoStep(2) ) pChoice = TieChoice( Prompt, TempIndex, Choices );
1969  if( DoStep(3) ) TempStr = TranslateFromIndex( TempIndex, InternalChoices ); // To a string
1970  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef ); // Put into Prefs.
1971  return pChoice;
1972 }
1973 
1986  const TranslatableString &Prompt,
1987  const SettingSpec< int > &Setting,
1988  const TranslatableStrings & Choices,
1989  const std::vector<int> * pInternalChoices,
1990  int iNoMatchSelector)
1991 {
1992  auto fn = [](int arg){ return wxString::Format( "%d", arg ); };
1993 
1994  wxArrayStringEx InternalChoices;
1995  if ( pInternalChoices )
1996  InternalChoices =
1997  transform_container<wxArrayStringEx>(*pInternalChoices, fn);
1998  else
1999  for ( int ii = 0; ii < (int)Choices.size(); ++ii )
2000  InternalChoices.push_back( fn( ii ) );
2001 
2002 
2003  const auto Default = Setting.GetDefault();
2004 
2005  miNoMatchSelector = iNoMatchSelector;
2006 
2007  long defaultIndex;
2008  if ( pInternalChoices )
2009  defaultIndex = make_iterator_range( *pInternalChoices ).index( Default );
2010  else
2011  defaultIndex = Default;
2012  if ( defaultIndex < 0 || defaultIndex >= (int)Choices.size() )
2013  defaultIndex = -1;
2014 
2015  ChoiceSetting choiceSetting{
2016  Setting.GetPath(),
2017  {
2018  ByColumns,
2019  Choices,
2020  InternalChoices,
2021  },
2022  defaultIndex
2023  };
2024 
2025  return ShuttleGuiBase::TieChoice( Prompt, choiceSetting );
2026 }
2027 
2028 //------------------------------------------------------------------//
2029 
2030 // We're now into ShuttleGuiBase sizer and misc functions.
2031 
2039 {
2040  if( miIdSetByUser > 0)
2041  {
2042  miId = miIdSetByUser;
2043  miIdSetByUser = -1;
2044  return;
2045  }
2046  miId = miIdNext++;
2047 }
2048 
2050 {
2051  if( miPropSetByUser >=0 )
2052  {
2054  miPropSetByUser =-1;
2055  return;
2056  }
2057  miProp = Default;
2058 }
2059 
2060 
2062  wxWindow *pWind, wxWindow *pDlg )
2063 {
2064  if ( step == 0 ) {
2065  // Do these steps before adding the window to the sizer
2066  if( item.mUseBestSize )
2067  pWind->SetMinSize( pWind->GetBestSize() );
2068  else if( item.mHasMinSize )
2069  pWind->SetMinSize( item.mMinSize );
2070 
2071  if ( item.mWindowSize != wxSize{} )
2072  pWind->SetSize( item.mWindowSize );
2073  }
2074  else if ( step == 1) {
2075  // Apply certain other optional window attributes here
2076 
2077  if ( item.mValidatorSetter )
2078  item.mValidatorSetter( pWind );
2079 
2080  if ( !item.mToolTip.empty() )
2081  pWind->SetToolTip( item.mToolTip.Translation() );
2082 
2083  if ( !item.mName.empty() ) {
2084  pWind->SetName( item.mName.Stripped().Translation() );
2085 #ifndef __WXMAC__
2086  if (auto pButton = dynamic_cast< wxBitmapButton* >( pWind ))
2087  pButton->SetLabel( item.mName.Translation() );
2088 #endif
2089  }
2090 
2091  if ( !item.mNameSuffix.empty() )
2092  pWind->SetName(
2093  pWind->GetName() + " " + item.mNameSuffix.Translation() );
2094 
2095  if (item.mFocused)
2096  pWind->SetFocus();
2097 
2098  if (item.mDisabled)
2099  pWind->Enable( false );
2100 
2101  for (auto &pair : item.mRootConnections)
2102  pWind->Connect( pair.first, pair.second, nullptr, pDlg );
2103  }
2104 }
2105 
2106 
2107 void ShuttleGuiBase::UpdateSizersCore(bool bPrepend, int Flags, bool prompt)
2108 {
2109  if( mpWind && mpParent )
2110  {
2111  int useFlags = Flags;
2112 
2113  if ( !prompt && mItem.mWindowPositionFlags )
2114  // override the given Flags
2115  useFlags = mItem.mWindowPositionFlags;
2116 
2117  if (!prompt)
2118  ApplyItem( 0, mItem, mpWind, mpDlg );
2119 
2120  if( mpSizer){
2121  if( bPrepend )
2122  {
2123  mpSizer->Prepend(mpWind, miProp, useFlags, miBorder);
2124  }
2125  else
2126  {
2127  mpSizer->Add(mpWind, miProp, useFlags, miBorder);
2128  }
2129  }
2130 
2131  if (!prompt) {
2132  ApplyItem( 1, mItem, mpWind, mpDlg );
2133  // Reset to defaults
2134  mItem = {};
2135  }
2136  }
2137 
2138  if( mpSubSizer && mpSizer )
2139  {
2140  // When adding sizers into sizers, don't add a border.
2141  // unless it's a static box sizer.
2142  wxSizer *const pSubSizer = mpSubSizer.get();
2143  if (wxDynamicCast(pSubSizer, wxStaticBoxSizer))
2144  {
2145  mpSizer->Add( mpSubSizer.release(), miSizerProp, Flags , miBorder);
2146  }
2147  else
2148  {
2149  mpSizer->Add( mpSubSizer.release(), miSizerProp, Flags ,0);//miBorder);
2150  }
2151  mpSizer = pSubSizer;
2152  PushSizer();
2153  }
2154 
2155  mpWind = NULL;
2156  miProp = 0;
2157  miSizerProp =0;
2158 }
2159 
2160 // Sizer is added into parent sizer, and will expand/shrink.
2162 { UpdateSizersCore( false, wxEXPAND | wxALL );}
2163 
2164 // Sizer is added into parent sizer, centred
2166 { UpdateSizersCore( false, wxALIGN_CENTRE | wxALL );}
2167 
2168 // Sizer is added into parent sizer, and will expand/shrink.
2169 // added to start of sizer list.
2171 { UpdateSizersCore( true, wxEXPAND | wxALL );}
2172 
2174 {
2175  mSizerDepth--;
2176  wxASSERT( mSizerDepth >=0 );
2178 }
2179 
2181 {
2182  mSizerDepth++;
2183  wxASSERT( mSizerDepth < nMaxNestedSizers );
2185 }
2186 
2187 long ShuttleGuiBase::GetStyle( long style )
2188 {
2189  if( mItem.miStyle )
2190  style = mItem.miStyle;
2191  mItem.miStyle = 0;
2192  return style;
2193 }
2194 
2195 // A rarely used helper function that sets a pointer
2196 // ONLY if the value it is to be set to is non NULL.
2197 void SetIfCreated( wxChoice * &Var, wxChoice * Val )
2198 {
2199  if( Val != NULL )
2200  Var = Val;
2201 };
2202 void SetIfCreated( wxTextCtrl * &Var, wxTextCtrl * Val )
2203 {
2204  if( Val != NULL )
2205  Var = Val;
2206 };
2207 void SetIfCreated( wxStaticText *&Var, wxStaticText * Val )
2208 {
2209  if( Val != NULL )
2210  Var = Val;
2211 };
2212 
2213 #ifdef EXPERIMENTAL_TRACK_PANEL
2214 // Additional includes down here, to make it easier to split this into
2215 // two files at some later date.
2216 #include "../extnpanel-src/GuiWaveTrack.h"
2217 #endif
2218 
2220  wxWindow * pParent, teShuttleMode ShuttleMode, bool vertical, wxSize minSize)
2221  : ShuttleGuiBase( pParent, ShuttleMode, vertical, minSize )
2222 {
2223  if( ShuttleMode == eIsCreatingFromPrefs )
2224  {
2226  Init( vertical, minSize ); // Wasn't fully done in base constructor because it is only done when eIsCreating is set.
2227  }
2228  else if( ShuttleMode == eIsSavingToPrefs )
2229  {
2231  }
2232  else
2233  {
2234  return;
2235  }
2236 
2237  mpShuttle = std::make_unique<ShuttlePrefs>();
2238  // In this case the client is the GUI, so if creating we do want to
2239  // store in the client.
2240  mpShuttle->mbStoreInClient = (mShuttleMode == eIsCreating );
2241 };
2242 
2244 {
2245 }
2246 
2247 // Now we have Audacity specific shuttle functions.
2249 {
2250  miIdSetByUser = id;
2251  return *this;
2252 }
2253 
2255  mpbOptionalFlag = &bVar;
2256  return *this;
2257 };
2258 
2259 
2260 std::unique_ptr<wxSizer> CreateStdButtonSizer(wxWindow *parent, long buttons, wxWindow *extra)
2261 {
2262  wxASSERT(parent != NULL); // To justify safenew
2263 
2264  int margin;
2265  {
2266 #if defined(__WXMAC__)
2267  margin = 12;
2268 #elif defined(__WXGTK20__)
2269  margin = 12;
2270 #elif defined(__WXMSW__)
2271  wxButton b(parent, 0, wxEmptyString);
2272  margin = b.ConvertDialogToPixels(wxSize(2, 0)).x;
2273 #else
2274  wxButton b(parent, 0, wxEmptyString);
2275  margin = b->ConvertDialogToPixels(wxSize(4, 0)).x;
2276 #endif
2277  }
2278 
2279  wxButton *b = NULL;
2280  auto bs = std::make_unique<wxStdDialogButtonSizer>();
2281 
2282  if( buttons & eOkButton )
2283  {
2284  b = safenew wxButton(parent, wxID_OK);
2285  b->SetDefault();
2286  bs->AddButton( b );
2287  }
2288 
2289  if( buttons & eCancelButton )
2290  {
2291  bs->AddButton(safenew wxButton(parent, wxID_CANCEL));
2292  }
2293 
2294  if( buttons & eYesButton )
2295  {
2296  b = safenew wxButton(parent, wxID_YES);
2297  b->SetDefault();
2298  bs->AddButton( b );
2299  }
2300 
2301  if( buttons & eNoButton )
2302  {
2303  bs->AddButton(safenew wxButton(parent, wxID_NO));
2304  }
2305 
2306  if( buttons & eApplyButton )
2307  {
2308  b = safenew wxButton(parent, wxID_APPLY);
2309  b->SetDefault();
2310  bs->AddButton( b );
2311  }
2312 
2313  if( buttons & eCloseButton )
2314  {
2315  bs->AddButton(safenew wxButton(parent, wxID_CANCEL, XO("&Close").Translation()));
2316  }
2317 
2318 #if defined(__WXMSW__)
2319  // See below for explanation
2320  if( buttons & eHelpButton )
2321  {
2322  // Replace standard Help button with smaller icon button.
2323  // bs->AddButton(safenew wxButton(parent, wxID_HELP));
2324  b = safenew wxBitmapButton(parent, wxID_HELP, theTheme.Bitmap( bmpHelpIcon ));
2325  b->SetToolTip( XO("Help").Translation() );
2326  b->SetLabel(XO("Help").Translation()); // for screen readers
2327  bs->AddButton( b );
2328  }
2329 #endif
2330 
2331  if (buttons & ePreviewButton)
2332  {
2333  bs->Add(safenew wxButton(parent, ePreviewID, XO("&Preview").Translation()), 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin);
2334  }
2335  if (buttons & ePreviewDryButton)
2336  {
2337  bs->Add(safenew wxButton(parent, ePreviewDryID, XO("Dry Previe&w").Translation()), 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin);
2338  bs->Add( 20, 0 );
2339  }
2340 
2341  if( buttons & eSettingsButton )
2342  {
2343  bs->Add(safenew wxButton(parent, eSettingsID, XO("&Settings").Translation()), 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin);
2344  bs->Add( 20, 0 );
2345  }
2346 
2347  if( extra )
2348  {
2349  bs->Add( extra, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin );
2350  bs->Add( 40, 0 );
2351  }
2352 
2353  bs->AddStretchSpacer();
2354  bs->Realize();
2355 
2356  size_t lastLastSpacer = 0;
2357  size_t lastSpacer = 0;
2358  wxSizerItemList & list = bs->GetChildren();
2359  for( size_t i = 0, cnt = list.size(); i < cnt; i++ )
2360  {
2361  if( list[i]->IsSpacer() )
2362  {
2363  lastSpacer = i;
2364  }
2365  else
2366  {
2367  lastLastSpacer = lastSpacer;
2368  }
2369  }
2370 
2371  // Add any buttons that need to cuddle up to the right hand cluster
2372  if( buttons & eDebugButton )
2373  {
2374  b = safenew wxButton(parent, eDebugID, XO("Debu&g").Translation());
2375  bs->Insert( ++lastLastSpacer, b, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin );
2376  }
2377 
2378 #if !defined(__WXMSW__)
2379  // Bug #2432: Couldn't find GTK guidelines, but Mac HIGs state:
2380  //
2381  // View style Help button position
2382  // Dialog with dismissal buttons (like OK and Cancel). Lower-left corner, vertically aligned with the dismissal buttons.
2383  // Dialog without dismissal buttons. Lower-left or lower-right corner.
2384  // Preference window or pane. Lower-left or lower-right corner.
2385  //
2386  // So, we're gonna cheat a little and use the lower-right corner.
2387  if( buttons & eHelpButton )
2388  {
2389  // Replace standard Help button with smaller icon button.
2390  // bs->AddButton(safenew wxButton(parent, wxID_HELP));
2391  b = safenew wxBitmapButton(parent, wxID_HELP, theTheme.Bitmap( bmpHelpIcon ));
2392  b->SetToolTip( XO("Help").Translation() );
2393  b->SetLabel(XO("Help").Translation()); // for screen readers
2394  bs->Add( b, 0, wxALIGN_CENTER );
2395  }
2396 #endif
2397 
2398 
2399  auto s = std::make_unique<wxBoxSizer>( wxVERTICAL );
2400  s->Add( bs.release(), 1, wxEXPAND | wxALL, 7 );
2401  s->Add( 0, 3 ); // a little extra space
2402 
2403  return std::unique_ptr<wxSizer>{ s.release() };
2404 }
2405 
2406 void ShuttleGui::AddStandardButtons(long buttons, wxWindow *extra)
2407 {
2408  if( mShuttleMode != eIsCreating )
2409  return;
2410 
2411  StartVerticalLay( false );
2412 
2413  miSizerProp = false;
2414  mpSubSizer = CreateStdButtonSizer( mpParent, buttons, extra );
2415  UpdateSizers();
2416  PopSizer();
2417 
2418  EndVerticalLay();
2419 }
2420 
2421 wxSizerItem * ShuttleGui::AddSpace( int width, int height, int prop )
2422 {
2423  if( mShuttleMode != eIsCreating )
2424  return NULL;
2425 
2426 // SetProportions(0);
2427  // return mpSizer->Add( width, height, miProp);
2428 
2429  return mpSizer->Add( width, height, prop );
2430 }
2431 
2432 void ShuttleGui::SetMinSize( wxWindow *window, const TranslatableStrings & items )
2433 {
2434  SetMinSize( window,
2435  transform_container<wxArrayStringEx>(
2436  items, std::mem_fn( &TranslatableString::StrippedTranslation ) ) );
2437 }
2438 
2439 void ShuttleGui::SetMinSize( wxWindow *window, const wxArrayStringEx & items )
2440 {
2441  int maxw = 0;
2442 
2443  for( size_t i = 0; i < items.size(); i++ )
2444  {
2445  int x;
2446  int y;
2447 
2448  window->GetTextExtent(items[i], &x, &y );
2449  if( x > maxw )
2450  {
2451  maxw = x;
2452  }
2453  }
2454 
2455  // Would be nice to know the sizes of the button and borders, but this is
2456  // the best we can do for now.
2457 #if defined(__WXMAC__)
2458  maxw += 50;
2459 #elif defined(__WXMSW__)
2460  maxw += 50;
2461 #elif defined(__WXGTK__)
2462  maxw += 50;
2463 #else
2464  maxw += 50;
2465 #endif
2466 
2467  window->SetMinSize( { maxw, -1 } );
2468 }
2469 
2470 /*
2471 void ShuttleGui::SetMinSize( wxWindow *window, const std::vector<int> & items )
2472 {
2473  wxArrayStringEx strs;
2474 
2475  for( size_t i = 0; i < items.size(); i++ )
2476  {
2477  strs.Add( wxString::Format( wxT("%d"), items[i] ) );
2478  }
2479 
2480  SetMinSize( window, strs );
2481 }
2482 */
ReadOnlyText.h
ShuttleGuiBase::StartRadioButtonGroup
void StartRadioButtonGroup(const ChoiceSetting &Setting)
Call this before any TieRadioButton calls.
Definition: ShuttleGui.cpp:1569
ReadOnlyText
Definition: ReadOnlyText.h:60
eYesButton
@ eYesButton
Definition: ShuttleGui.h:609
Optional::emplace
X & emplace(Args &&... args)
Definition: MemoryX.h:259
TranslatableString
Definition: Types.h:290
ShuttleGuiBase::EndSimplebook
void EndSimplebook()
Definition: ShuttleGui.cpp:1054
SettingSpec::GetDefault
const T & GetDefault() const
Definition: ShuttleGui.h:113
ePreviewButton
@ ePreviewButton
Definition: ShuttleGui.h:612
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:36
WrappedType::ReadAsString
wxString ReadAsString()
Definition: WrappedType.cpp:42
ShuttleGuiBase::Init
void Init(bool vertical, wxSize minSize)
Definition: ShuttleGui.cpp:141
TranslatableString::empty
bool empty() const
Definition: Types.h:329
ShuttleGuiBase::mRadioValue
Optional< WrappedType > mRadioValue
The setting controlled by a group.
Definition: ShuttleGui.h:582
ShuttleGuiBase::AddCheckBoxOnRight
wxCheckBox * AddCheckBoxOnRight(const TranslatableString &Prompt, bool Selected)
Definition: ShuttleGui.cpp:336
ShuttleGuiBase::AddChoice
wxChoice * AddChoice(const TranslatableString &Prompt, const TranslatableStrings &choices, int Selected=-1)
Definition: ShuttleGui.cpp:391
ShuttleGuiBase::EndRadioButtonGroup
void EndRadioButtonGroup()
Definition: ShuttleGui.cpp:1586
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1177
wxSliderWrapper
wxSlider wxSliderWrapper
Definition: ShuttleGui.h:103
ShuttleGuiBase::AddCheckBox
wxCheckBox * AddCheckBox(const TranslatableString &Prompt, bool Selected)
Definition: ShuttleGui.cpp:302
make_iterator_range
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:625
ShuttleGuiBase::DoTieSpinCtrl
wxSpinCtrl * DoTieSpinCtrl(const TranslatableString &Prompt, WrappedType &WrappedRef, const int max, const int min=0)
Definition: ShuttleGui.cpp:1305
ShuttleGui::SetMinSize
static void SetMinSize(wxWindow *window, const TranslatableStrings &items)
Definition: ShuttleGui.cpp:2432
ShuttleGuiBase::TieIntegerTextBox
virtual wxTextCtrl * TieIntegerTextBox(const TranslatableString &Prompt, const SettingSpec< int > &Setting, const int nChars)
Definition: ShuttleGui.cpp:1906
ShuttleGuiBase::HandleOptionality
void HandleOptionality(const TranslatableString &Prompt)
Definition: ShuttleGui.cpp:217
eIsGettingFromDialog
@ eIsGettingFromDialog
Definition: ShuttleGui.h:37
ComponentInterfaceSymbol::Translation
const wxString Translation() const
Definition: ComponentInterface.h:91
fn
static const auto fn
Definition: WaveformView.cpp:1102
ShuttleGui::~ShuttleGui
~ShuttleGui(void)
Definition: ShuttleGui.cpp:2243
DialogDefinition::Item::mDisabled
bool mDisabled
Definition: ShuttleGui.h:247
ShuttleGuiBase::AddTitle
void AddTitle(const TranslatableString &Prompt, int wrapWidth=0)
Centred text string.
Definition: ShuttleGui.cpp:274
AllThemeResources.h
wxNotebookPage
wxWindow wxNotebookPage
Definition: ShuttleGui.h:59
ShuttleGuiBase::UpdateSizersAtStart
void UpdateSizersAtStart()
Definition: ShuttleGui.cpp:2170
ChoiceSetting::Key
const wxString & Key() const
Definition: Prefs.h:106
wxPanelWrapper
Definition: wxPanelWrapper.h:41
ShuttleGuiBase::miIdSetByUser
int miIdSetByUser
Definition: ShuttleGui.h:554
SettingSpec::GetPath
const RegistryPath & GetPath() const
Definition: ShuttleGui.h:112
ShuttleGuiBase::DoTieCheckBoxOnRight
wxCheckBox * DoTieCheckBoxOnRight(const TranslatableString &Prompt, WrappedType &WrappedRef)
Definition: ShuttleGui.cpp:1269
ShuttleGuiBase::TieCheckBox
wxCheckBox * TieCheckBox(const TranslatableString &Prompt, bool &Var)
Definition: ShuttleGui.cpp:1603
eApplyButton
@ eApplyButton
Definition: ShuttleGui.h:616
ShuttleGuiBase::ApplyItem
static void ApplyItem(int step, const DialogDefinition::Item &item, wxWindow *pWind, wxWindow *pDlg)
Definition: ShuttleGui.cpp:2061
WrappedType::IsString
bool IsString()
Definition: WrappedType.cpp:35
ShuttleGuiBase::AddRadioButtonToGroup
wxRadioButton * AddRadioButtonToGroup(const TranslatableString &Prompt, int selector=1, int initValue=0)
Definition: ShuttleGui.cpp:567
ShuttleGuiBase::mpShuttle
std::unique_ptr< Shuttle > mpShuttle
Definition: ShuttleGui.h:540
WrappedType::WriteToAsBool
void WriteToAsBool(const bool InBool)
Definition: WrappedType.cpp:233
ShuttleGuiBase::TieSlider
wxSlider * TieSlider(const TranslatableString &Prompt, int &pos, const int max, const int min=0)
Definition: ShuttleGui.cpp:1661
ShuttleGuiBase::ShuttleGuiBase
ShuttleGuiBase(wxWindow *pParent, teShuttleMode ShuttleMode, bool vertical, wxSize minSize)
Definition: ShuttleGui.cpp:126
Validator
A Validator is an object which checks whether a wxVariant satisfies a certain criterion....
Definition: Validators.h:53
ShuttleGuiBase::EndNotebook
void EndNotebook()
Definition: ShuttleGui.cpp:1033
ShuttleGui::AddSpace
wxSizerItem * AddSpace(int width, int height, int prop=0)
Definition: ShuttleGui.cpp:2421
ShuttleGuiBase::TranslateToIndex
int TranslateToIndex(const wxString &Value, const wxArrayStringEx &Choices)
String-to-Index.
Definition: ShuttleGui.cpp:1723
ShuttleGuiBase::pSizerStack
wxSizer * pSizerStack[nMaxNestedSizers]
Definition: ShuttleGui.h:538
XO
#define XO(s)
Definition: Internat.h:32
wxPanelWrapper.h
ShuttleGuiBase::mRadioValueString
wxString mRadioValueString
The index of this radio item. -1 for none.
Definition: ShuttleGui.h:584
WrappedType::ReadAsBool
bool ReadAsBool()
Definition: WrappedType.cpp:124
eCancelButton
@ eCancelButton
Definition: ShuttleGui.h:608
ShuttleGuiBase::EndMultiColumn
void EndMultiColumn()
Definition: ShuttleGui.cpp:1212
eCloseButton
@ eCloseButton
Definition: ShuttleGui.h:617
ShuttleGui::ShuttleGui
ShuttleGui(wxWindow *pParent, teShuttleMode ShuttleMode, bool vertical=true, wxSize minSize={ 250, 100 })
Definition: ShuttleGui.cpp:2219
ShuttleGuiBase::StartNotebookPage
wxNotebookPage * StartNotebookPage(const TranslatableString &Name)
Definition: ShuttleGui.cpp:1061
WrappedType::ReadAsInt
int ReadAsInt()
Definition: WrappedType.cpp:68
ShuttleGuiBase::DoTieTextBox
wxTextCtrl * DoTieTextBox(const TranslatableString &Prompt, WrappedType &WrappedRef, const int nChars)
Definition: ShuttleGui.cpp:1344
ShuttleGuiBase::DoInsertListColumns
void DoInsertListColumns(wxListCtrl *pListCtrl, long listControlStyles, std::initializer_list< const ListControlColumn > columns)
Definition: ShuttleGui.cpp:816
ShuttleGuiBase::EndNotebookPage
void EndNotebookPage()
Definition: ShuttleGui.cpp:1084
ShuttleGuiBase::AddListControl
wxListCtrl * AddListControl(std::initializer_list< const ListControlColumn > columns={}, long listControlStyles=0)
Definition: ShuttleGui.cpp:775
ShuttleGuiBase::mRadioSettingName
wxString mRadioSettingName
Definition: ShuttleGui.h:581
ShuttleGuiBase::StartPanel
wxPanel * StartPanel(int iStyle=0)
Definition: ShuttleGui.cpp:983
DialogDefinition::Item::mToolTip
TranslatableString mToolTip
Definition: ShuttleGui.h:229
ShuttleGuiBase::miSizerProp
int miSizerProp
Definition: ShuttleGui.h:546
eIsSettingToDialog
@ eIsSettingToDialog
Definition: ShuttleGui.h:38
wxArrayStringEx
Definition: MemoryX.h:663
ShuttleGuiBase::EndPanel
void EndPanel()
Definition: ShuttleGui.cpp:1011
ShuttleGuiBase::StartInvisiblePanel
wxPanel * StartInvisiblePanel()
Definition: ShuttleGui.cpp:1125
ePreviewDryID
@ ePreviewDryID
Definition: ShuttleGui.h:628
ComponentInterfaceSymbol
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Definition: ComponentInterface.h:60
Optional::reset
void reset()
Definition: MemoryX.h:287
ShuttleGuiBase::DoTieSlider
wxSlider * DoTieSlider(const TranslatableString &Prompt, WrappedType &WrappedRef, const int max, const int min=0)
Definition: ShuttleGui.cpp:1420
ShuttleGui::Id
ShuttleGui & Id(int id)
Definition: ShuttleGui.cpp:2248
ShuttleGuiBase::TieTextBox
wxTextCtrl * TieTextBox(const TranslatableString &Caption, wxString &Value, const int nChars=0)
Definition: ShuttleGui.cpp:1626
ThemeBase::Bitmap
wxBitmap & Bitmap(int iIndex)
Definition: Theme.cpp:1211
ShuttleGuiBase::DoStep
bool DoStep(int iStep)
Definition: ShuttleGui.cpp:1791
eDebugButton
@ eDebugButton
Definition: ShuttleGui.h:613
ShuttleGuiBase::Prop
ShuttleGuiBase & Prop(int iProp)
Definition: ShuttleGui.cpp:875
ShuttleGuiBase::AddTree
wxTreeCtrl * AddTree()
Definition: ShuttleGui.cpp:847
ShuttleGuiBase::~ShuttleGuiBase
virtual ~ShuttleGuiBase()
Definition: ShuttleGui.cpp:137
ShuttleGuiBase::EndScroller
void EndScroller()
Definition: ShuttleGui.cpp:964
ShuttleGuiBase::miPropSetByUser
int miPropSetByUser
Definition: ShuttleGui.h:556
InvisiblePanel
An InvisiblePanel is a panel which does not repaint its own background.
Definition: ShuttleGui.cpp:1095
ePreviewID
@ ePreviewID
Definition: ShuttleGui.h:624
eOkButton
@ eOkButton
Definition: ShuttleGui.h:607
ShuttleGuiBase::AddSpinCtrl
wxSpinCtrl * AddSpinCtrl(const TranslatableString &Prompt, int Value, int Max, int Min)
Definition: ShuttleGui.cpp:609
ShuttleGuiBase::miBorder
int miBorder
Definition: ShuttleGui.h:548
ChoiceSetting
Definition: Prefs.h:90
DialogDefinition::Item::mWindowPositionFlags
int mWindowPositionFlags
Definition: ShuttleGui.h:238
DialogDefinition::Item::mName
TranslatableString mName
Definition: ShuttleGui.h:230
TranslatableStrings
std::vector< TranslatableString > TranslatableStrings
Definition: Types.h:555
ShuttleGuiBase::AddIcon
void AddIcon(wxBitmap *pBmp)
Definition: ShuttleGui.cpp:861
ShuttleGuiBase::AddConstTextBox
void AddConstTextBox(const TranslatableString &Caption, const TranslatableString &Value)
Single line text box of fixed size.
Definition: ShuttleGui.cpp:726
wxTextCtrlWrapper
Definition: wxTextCtrlWrapper.h:23
eDebugID
@ eDebugID
Definition: ShuttleGui.h:626
eSettingsButton
@ eSettingsButton
Definition: ShuttleGui.h:614
ShuttleGuiBase::AddNumericTextBox
wxTextCtrl * AddNumericTextBox(const TranslatableString &Caption, const wxString &Value, const int nChars)
Definition: ShuttleGui.cpp:667
InvisiblePanel::OnErase
void OnErase(wxEraseEvent &)
Definition: ShuttleGui.cpp:1108
ShuttleGuiBase::mpSizer
wxSizer * mpSizer
Definition: ShuttleGui.h:561
ShuttleGuiBase::StartScroller
wxScrolledWindow * StartScroller(int iStyle=0)
Definition: ShuttleGui.cpp:931
ShuttleGuiBase::EndHorizontalLay
void EndHorizontalLay()
Definition: ShuttleGui.cpp:1170
DialogDefinition::Item::miStyle
long miStyle
Definition: ShuttleGui.h:235
ShuttleGuiBase::StartHorizontalLay
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:1160
wxTextCtrlWrapper.h
ShuttleGuiBase::AddTextBox
wxTextCtrl * AddTextBox(const TranslatableString &Caption, const wxString &Value, const int nChars)
Definition: ShuttleGui.cpp:631
ShuttleGuiBase::StartMultiColumn
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:1203
ShuttlePrefs.h
InvisiblePanel::InvisiblePanel
InvisiblePanel(wxWindow *parent, wxWindowID id=-1, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL)
Definition: ShuttleGui.cpp:1097
WrappedType
Used in type conversions, this wrapper for ints, strings, doubles and enums provides conversions betw...
Definition: WrappedType.h:31
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1196
ShuttleGuiBase::StartSimplebook
wxSimplebook * StartSimplebook()
Definition: ShuttleGui.cpp:1040
ShuttleGuiBase::miIdNext
int miIdNext
Definition: ShuttleGui.h:553
ShuttleGuiBase::ResetId
void ResetId()
Definition: ShuttleGui.cpp:186
eHelpButton
@ eHelpButton
Definition: ShuttleGui.h:611
ShuttleGuiBase::AddUnits
void AddUnits(const TranslatableString &Prompt, int wrapWidth=0)
Left aligned text string.
Definition: ShuttleGui.cpp:256
ShuttleGuiBase::AddFixedText
void AddFixedText(const TranslatableString &Str, bool bCenter=false, int wrapWidth=0)
Definition: ShuttleGui.cpp:433
ShuttleGuiBase::miProp
int miProp
Definition: ShuttleGui.h:549
Theme.h
ShuttleGuiBase::UpdateSizers
void UpdateSizers()
Definition: ShuttleGui.cpp:2161
ShuttleGuiBase::UpdateSizersC
void UpdateSizersC()
Definition: ShuttleGui.cpp:2165
ShuttleGuiBase::mpParent
wxWindow * mpParent
Definition: ShuttleGui.h:562
ShuttleGuiBase::PopSizer
void PopSizer()
Definition: ShuttleGui.cpp:2173
ShuttleGuiBase::PushSizer
void PushSizer()
Definition: ShuttleGui.cpp:2180
ShuttleGuiBase::GetParent
wxWindow * GetParent()
Definition: ShuttleGui.h:503
ShuttleGuiBase::mpbOptionalFlag
bool * mpbOptionalFlag
Definition: ShuttleGui.h:558
DialogDefinition::Item::mNameSuffix
TranslatableString mNameSuffix
Definition: ShuttleGui.h:231
ShuttleGuiBase::AddGrid
wxGrid * AddGrid()
Definition: ShuttleGui.cpp:761
eNoButton
@ eNoButton
Definition: ShuttleGui.h:610
WindowAccessible
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
ShuttleGuiBase::AddRadioButton
wxRadioButton * AddRadioButton(const TranslatableString &Prompt, int selector=0, int initValue=0)
Definition: ShuttleGui.cpp:561
ShuttleGuiBase::TieNumericTextBox
wxTextCtrl * TieNumericTextBox(const TranslatableString &Prompt, int &Value, const int nChars=0)
Definition: ShuttleGui.cpp:1647
ShuttleGui.h
ShuttleGuiBase::TranslateFromIndex
wxString TranslateFromIndex(const int nIn, const wxArrayStringEx &Choices)
Index-to-String.
Definition: ShuttleGui.cpp:1733
ChoiceSetting::GetSymbols
const EnumValueSymbols & GetSymbols() const
Definition: Prefs.h:108
ePreviewDryButton
@ ePreviewDryButton
Definition: ShuttleGui.h:615
ShuttleGuiBase::AddReadOnlyText
ReadOnlyText * AddReadOnlyText(const TranslatableString &Caption, const wxString &Value)
Definition: ShuttleGui.cpp:489
ShuttleGuiBase::AddSlider
wxSlider * AddSlider(const TranslatableString &Prompt, int pos, int Max, int Min=0)
Definition: ShuttleGui.cpp:582
ShuttleGuiBase::TieSpinCtrl
wxSpinCtrl * TieSpinCtrl(const TranslatableString &Prompt, int &Value, const int max, const int min=0)
Definition: ShuttleGui.cpp:1619
ShuttleGuiBase::UpdateSizersCore
void UpdateSizersCore(bool bPrepend, int Flags, bool prompt=false)
Definition: ShuttleGui.cpp:2107
ShuttleGuiBase::AddButton
wxButton * AddButton(const TranslatableString &Text, int PositionFlags=wxALIGN_CENTRE, bool setDefault=false)
Definition: ShuttleGui.cpp:353
ShuttleGuiBase::StartStatic
wxStaticBox * StartStatic(const TranslatableString &Str, int iProp=0)
Definition: ShuttleGui.cpp:886
ChoiceSetting::Read
wxString Read() const
Definition: Prefs.cpp:235
eIsSavingToPrefs
@ eIsSavingToPrefs
Definition: ShuttleGui.h:46
id
int id
Definition: WaveTrackControls.cpp:589
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
ShuttleGuiBase::mRadioCount
int mRadioCount
The wrapped value associated with the active radio button.
Definition: ShuttleGui.h:583
eIsGettingMetadata
@ eIsGettingMetadata
Definition: ShuttleGui.h:39
ShuttleGuiBase::miId
int miId
Definition: ShuttleGui.h:552
ShuttleGuiBase::UseUpId
void UseUpId()
Definition: ShuttleGui.cpp:2038
ShuttleGuiBase::SetProportions
void SetProportions(int Default)
Definition: ShuttleGui.cpp:2049
ShuttleGuiBase::AddWindow
wxWindow * AddWindow(wxWindow *pWindow)
Definition: ShuttleGui.cpp:292
WindowAccessible.h
ChoiceSetting::Default
const EnumValueSymbol & Default() const
Definition: Prefs.cpp:227
ShuttleGuiBase::mShuttleMode
teShuttleMode mShuttleMode
Used in choices to determine which item to use on no match.
Definition: ShuttleGui.h:544
ShuttleGuiBase::TieVSlider
wxSlider * TieVSlider(const TranslatableString &Prompt, float &pos, const float fMin, const float fMax)
Definition: ShuttleGui.cpp:1687
ShuttleGuiBase::mpWind
wxWindow * mpWind
Definition: ShuttleGui.h:563
ShuttleGuiBase::AddListControlReportMode
wxListCtrl * AddListControlReportMode(std::initializer_list< const ListControlColumn > columns={}, long listControlStyles=0)
Definition: ShuttleGui.cpp:795
ShuttleGuiBase::AddBitmapButton
wxBitmapButton * AddBitmapButton(const wxBitmap &Bitmap, int PositionFlags=wxALIGN_CENTRE, bool setDefault=false)
Definition: ShuttleGui.cpp:372
ShuttleGuiBase::DoTieNumericTextBox
wxTextCtrl * DoTieNumericTextBox(const TranslatableString &Prompt, WrappedType &WrappedRef, const int nChars)
Definition: ShuttleGui.cpp:1382
TranslatableString::StrippedTranslation
wxString StrippedTranslation() const
Definition: Types.h:460
DialogDefinition::Item::mUseBestSize
bool mUseBestSize
Definition: ShuttleGui.h:244
ShuttleGuiBase::miNoMatchSelector
int miNoMatchSelector
Definition: ShuttleGui.h:542
ComponentInterfaceSymbol::Internal
const wxString & Internal() const
Definition: ComponentInterface.h:88
ShuttleGuiBase::mSizerDepth
int mSizerDepth
Definition: ShuttleGui.h:547
ShuttleGuiBase::DoDataShuttle
void DoDataShuttle(const wxString &Name, WrappedType &WrappedRef)
Definition: ShuttleGui.cpp:1221
ShuttleGuiBase::TieNumberAsChoice
virtual wxChoice * TieNumberAsChoice(const TranslatableString &Prompt, const SettingSpec< int > &Setting, const TranslatableStrings &Choices, const std::vector< int > *pInternalChoices=nullptr, int iNoMatchSelector=0)
Definition: ShuttleGui.cpp:1985
DialogDefinition::Item
Definition: ShuttleGui.h:122
ShuttleGuiBase::AddTextWindow
wxTextCtrl * AddTextWindow(const wxString &Value)
Multiline text box that grows.
Definition: ShuttleGui.cpp:705
ShuttleGuiBase::GetStyle
long GetStyle(long Style)
Definition: ShuttleGui.cpp:2187
ShuttleGuiBase::mItem
DialogDefinition::Item mItem
Definition: ShuttleGui.h:589
ShuttleGui::AddStandardButtons
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxWindow *extra=NULL)
Definition: ShuttleGui.cpp:2406
WrappedType::WriteToAsString
void WriteToAsString(const wxString &InStr)
Definition: WrappedType.cpp:152
DialogDefinition::Item::mHasMinSize
bool mHasMinSize
Definition: ShuttleGui.h:243
ShuttleGuiBase::mRadioSymbols
std::vector< EnumValueSymbol > mRadioSymbols
Definition: ShuttleGui.h:580
ShuttleGuiBase::TieRadioButton
wxRadioButton * TieRadioButton()
This function must be within a StartRadioButtonGroup - EndRadioButtonGroup pair.
Definition: ShuttleGui.cpp:1510
theTheme
AUDACITY_DLL_API Theme theTheme
Definition: Theme.cpp:201
wxStaticBoxWrapper
wxStaticBox wxStaticBoxWrapper
Definition: ShuttleGui.h:102
Prefs.h
ShuttleGuiBase::AddPrompt
void AddPrompt(const TranslatableString &Prompt, int wrapWidth=0)
Right aligned text string.
Definition: ShuttleGui.cpp:231
TranslatableString::Translation
wxString Translation() const
Definition: Types.h:337
ByColumns
ByColumns_t ByColumns
Definition: Prefs.cpp:373
eIsCreatingFromPrefs
@ eIsCreatingFromPrefs
Definition: ShuttleGui.h:45
ShuttleGuiBase::AddVariableText
wxStaticText * AddVariableText(const TranslatableString &Str, bool bCenter=false, int PositionFlags=0, int wrapWidth=0)
Definition: ShuttleGui.cpp:456
ShuttleGui::Optional
ShuttleGui & Optional(bool &bVar)
Definition: ShuttleGui.cpp:2254
ShuttleGuiBase::DoTieCheckBox
wxCheckBox * DoTieCheckBox(const TranslatableString &Prompt, WrappedType &WrappedRef)
Definition: ShuttleGui.cpp:1233
DialogDefinition::Item::mRootConnections
std::vector< std::pair< wxEventType, wxObjectEventFunction > > mRootConnections
Definition: ShuttleGui.h:233
DialogDefinition::Item::mFocused
bool mFocused
Definition: ShuttleGui.h:246
TranslatableString::Stripped
TranslatableString Stripped(unsigned options=MenuCodes) const
Definition: Types.h:457
ShuttleGuiBase::EndStatic
void EndStatic()
Definition: ShuttleGui.cpp:915
safenew
#define safenew
Definition: MemoryX.h:8
ShuttleGuiBase::StartNotebook
wxNotebook * StartNotebook()
Definition: ShuttleGui.cpp:1019
ShuttleGuiBase::mpDlg
wxWindow *const mpDlg
Definition: ShuttleGui.h:537
ShuttleGuiBase::SetStretchyCol
void SetStretchyCol(int i)
Used to modify an already placed FlexGridSizer to make a column stretchy.
Definition: ShuttleGui.cpp:195
WrappedType::WriteToAsInt
void WriteToAsInt(const int InInt)
Definition: WrappedType.cpp:181
eSettingsID
@ eSettingsID
Definition: ShuttleGui.h:627
DialogDefinition::Item::mMinSize
wxSize mMinSize
Definition: ShuttleGui.h:242
ShuttleGuiBase::AddListBox
wxListBox * AddListBox(const wxArrayStringEx &choices)
Definition: ShuttleGui.cpp:746
ShuttleGuiBase::EndInvisiblePanel
void EndInvisiblePanel()
Definition: ShuttleGui.cpp:1148
ShuttleGuiBase::mpSubSizer
std::unique_ptr< wxSizer > mpSubSizer
Definition: ShuttleGui.h:560
END_EVENT_TABLE
END_EVENT_TABLE()
ShuttleGuiBase::TieChoice
wxChoice * TieChoice(const TranslatableString &Prompt, TranslatableString &Selected, const TranslatableStrings &choices)
Definition: ShuttleGui.cpp:1701
ShuttleGuiBase::SetStretchyRow
void SetStretchyRow(int i)
Used to modify an already placed FlexGridSizer to make a row stretchy.
Definition: ShuttleGui.cpp:205
ShuttleGuiBase::TieCheckBoxOnRight
wxCheckBox * TieCheckBoxOnRight(const TranslatableString &Prompt, bool &Var)
Definition: ShuttleGui.cpp:1610
ShuttleGuiBase::DoAddRadioButton
wxRadioButton * DoAddRadioButton(const TranslatableString &Prompt, int style, int selector, int initValue)
Unwrapped string value.
Definition: ShuttleGui.cpp:541
ShuttleGuiBase::AddCombo
wxComboBox * AddCombo(const TranslatableString &Prompt, const wxString &Selected, const wxArrayStringEx &choices)
Definition: ShuttleGui.cpp:510
ShuttleGuiBase
Base class for shuttling data to and from a GUI.
Definition: ShuttleGui.h:254
DialogDefinition::Item::mWindowSize
wxSize mWindowSize
Definition: ShuttleGui.h:240
teShuttleMode
teShuttleMode
Definition: ShuttleGui.h:35
SetIfCreated
void SetIfCreated(wxChoice *&Var, wxChoice *Val)
Definition: ShuttleGui.cpp:2197
InvisiblePanel::OnPaint
void OnPaint(wxPaintEvent &event)
Definition: ShuttleGui.cpp:1118
DialogDefinition::Item::mValidatorSetter
std::function< void(wxWindow *) > mValidatorSetter
Definition: ShuttleGui.h:228
SettingSpec
Definition: ShuttleGui.h:106
InvisiblePanel::~InvisiblePanel
~InvisiblePanel()
Definition: ShuttleGui.cpp:1106
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:638
CreateStdButtonSizer
std::unique_ptr< wxSizer > CreateStdButtonSizer(wxWindow *parent, long buttons, wxWindow *extra)
Definition: ShuttleGui.cpp:2260
nMaxNestedSizers
const int nMaxNestedSizers
Definition: ShuttleGui.h:32