Audacity  2.2.2
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 #include "Audacity.h"
97 #include "Experimental.h"
98 #include "Prefs.h"
99 #include "Shuttle.h"
100 #include "ShuttleGui.h"
101 
102 #include "MemoryX.h"
103 #include <wx/wx.h>
104 #include <wx/wxprec.h>
105 #include <wx/listctrl.h>
106 #include <wx/notebook.h>
107 #include <wx/treectrl.h>
108 #include <wx/spinctrl.h>
109 #include <wx/bmpbuttn.h>
110 #include "../include/audacity/IdentInterface.h"
111 #include "Internat.h"
112 #include "WrappedType.h"
113 #include "widgets/wxPanelWrapper.h"
114 #include "AllThemeResources.h"
115 
116 #if wxUSE_ACCESSIBILITY
118 #endif
119 
120 ShuttleGuiBase::ShuttleGuiBase(wxWindow * pParent, teShuttleMode ShuttleMode )
121 {
122  wxASSERT( (pParent != NULL ) || ( ShuttleMode != eIsCreating));
123  mpbOptionalFlag = nullptr;
124  mpParent = pParent;
125  mShuttleMode = ShuttleMode;
126  mpDlg = pParent;
127  Init();
128 }
129 
131 {
132 }
133 
135 {
136  mpShuttle = NULL;
137  mpSizer = NULL;
138  mpWind = NULL;
139  mpSubSizer = NULL;
140 
141  mSettingName = wxT("");
142  mRadioCount = -1;
143 
144  miBorder = 5;
145  miStyle = 0;
146  miProp=0;
147  miPropSetByUser=-1;
148  miSizerProp=0;
149  mSizerDepth=-1;
150 
151  ResetId();
152 
153  miNoMatchSelector = 0;
154 
155  if( mShuttleMode != eIsCreating )
156  return;
157 
158  mpSizer = mpParent->GetSizer();
159 
160 #if 0
161  if( mpSizer == NULL )
162  {
163  wxWindow * pGrandParent = mpParent->GetParent();
164  if( pGrandParent )
165  {
166  mpSizer = pGrandParent->GetSizer();
167  }
168  }
169 #endif
170 
171  if( !mpSizer )
172  {
173  mpParent->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
174  }
175  PushSizer();
176  mpSizer->SetMinSize(250,100);
177 }
178 
180 {
181  miIdSetByUser = -1;
182  miId = -1;
183  miIdNext = 3000;
184 }
185 
186 void ShuttleGuiBase::EnableCtrl( bool bEnable )
187 {
188  if( mShuttleMode != eIsCreating )
189  return;
190  mpLastWind->Enable( bEnable );
191 }
192 
194 void ShuttleGuiBase::SetSizeHints( int minX, int minY )
195 {
196  if( mShuttleMode != eIsCreating )
197  return;
198  mpLastWind->SetSizeHints( minX, minY );
199 }
200 
201 
204 {
205  if( mShuttleMode != eIsCreating )
206  return;
207  wxFlexGridSizer *pSizer = wxDynamicCast(mpSizer, wxFlexGridSizer);
208  wxASSERT( pSizer );
209  pSizer->AddGrowableCol( i, 1 );
210 }
211 
214 {
215  if( mShuttleMode != eIsCreating )
216  return;
217  wxFlexGridSizer *pSizer = wxDynamicCast(mpSizer, wxFlexGridSizer);
218  wxASSERT( pSizer );
219  pSizer->AddGrowableRow( i, 1 );
220 }
221 
222 
223 //---- Add Functions.
224 
225 void ShuttleGuiBase::HandleOptionality(const wxString &Prompt)
226 {
227  // If creating, will be handled by an AddPrompt.
228  if( mShuttleMode == eIsCreating )
229  return;
230  //wxLogDebug( "Optionality: [%s] Id:%i (%i)", Prompt.c_str(), miId, miIdSetByUser ) ;
231  if( mpbOptionalFlag ){
232  bool * pVar = mpbOptionalFlag;
233  mpbOptionalFlag = nullptr;
234  TieCheckBox( Prompt, *pVar);
235  }
236 }
237 
239 void ShuttleGuiBase::AddPrompt(const wxString &Prompt)
240 {
241  if( mShuttleMode != eIsCreating )
242  return;
243  //wxLogDebug( "Prompt: [%s] Id:%i (%i)", Prompt.c_str(), miId, miIdSetByUser ) ;
244  if( mpbOptionalFlag ){
245  bool * pVar = mpbOptionalFlag;
246  mpbOptionalFlag = nullptr;
247  TieCheckBox( "", *pVar);
248  //return;
249  }
250  if( Prompt.IsEmpty() )
251  return;
252  miProp=1;
253  mpWind = safenew wxStaticText(GetParent(), -1, Prompt, wxDefaultPosition, wxDefaultSize,
254  Style( wxALIGN_RIGHT ));
255  mpWind->SetName(wxStripMenuCodes(Prompt)); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
256  UpdateSizersCore( false, wxALL | wxALIGN_CENTRE_VERTICAL );
257 }
258 
260 void ShuttleGuiBase::AddUnits(const wxString &Prompt)
261 {
262  if( Prompt.IsEmpty() )
263  return;
264  if( mShuttleMode != eIsCreating )
265  return;
266  miProp=1;
267  mpWind = safenew wxStaticText(GetParent(), -1, Prompt, wxDefaultPosition, wxDefaultSize,
268  Style( wxALIGN_LEFT ));
269  mpWind->SetName(Prompt); // 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 wxString &Prompt)
275 {
276  if( Prompt.IsEmpty() )
277  return;
278  if( mShuttleMode != eIsCreating )
279  return;
280  mpWind = safenew wxStaticText(GetParent(), -1, Prompt, wxDefaultPosition, wxDefaultSize,
281  Style( wxALIGN_CENTRE ));
282  mpWind->SetName(Prompt); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
283  UpdateSizers();
284 }
285 
288 wxWindow * ShuttleGuiBase::AddWindow(wxWindow * pWindow, int Flags )
289 {
290  if( mShuttleMode != eIsCreating )
291  return pWindow;
292  mpWind = pWindow;
293  SetProportions( 0 );
294  UpdateSizersCore(false, Flags);
295  return pWindow;
296 }
297 
298 wxCheckBox * ShuttleGuiBase::AddCheckBox( const wxString &Prompt, const wxString &Selected)
299 {
300  HandleOptionality( Prompt );
301  wxString realPrompt = Prompt;
302  if( mpbOptionalFlag )
303  {
304  AddPrompt( "");
305  //realPrompt = wxT("");
306  }
307 
308  UseUpId();
309  if( mShuttleMode != eIsCreating )
310  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxCheckBox);
311  wxCheckBox * pCheckBox;
312  miProp=0;
313  mpWind = pCheckBox = safenew wxCheckBox(GetParent(), miId, realPrompt, wxDefaultPosition, wxDefaultSize,
314  Style( 0 ));
315  pCheckBox->SetValue(Selected == wxT("true"));
316  pCheckBox->SetName(wxStripMenuCodes(Prompt));
317  UpdateSizers();
318  return pCheckBox;
319 }
320 
324 wxCheckBox * ShuttleGuiBase::AddCheckBoxOnRight( const wxString &Prompt, const wxString &Selected)
325 {
326  HandleOptionality( Prompt );
327  AddPrompt( Prompt );
328  UseUpId();
329  if( mShuttleMode != eIsCreating )
330  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxCheckBox);
331  wxCheckBox * pCheckBox;
332  miProp=0;
333  mpWind = pCheckBox = safenew wxCheckBox(GetParent(), miId, wxT(""), wxDefaultPosition, wxDefaultSize,
334  Style( 0 ));
335  pCheckBox->SetValue(Selected==wxT("true"));
336  pCheckBox->SetName(wxStripMenuCodes(Prompt));
337  UpdateSizers();
338  return pCheckBox;
339 }
340 
341 wxButton * ShuttleGuiBase::AddButton(const wxString &Text, int PositionFlags)
342 {
343  UseUpId();
344  if( mShuttleMode != eIsCreating )
345  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxButton);
346  wxButton * pBtn;
347  mpWind = pBtn = safenew wxButton(GetParent(), miId, Text, wxDefaultPosition, wxDefaultSize,
348  Style( 0 ) );
349  mpWind->SetName(wxStripMenuCodes(Text));
350  miProp=0;
351  UpdateSizersCore(false, PositionFlags | wxALL);
352  return pBtn;
353 }
354 
355 wxBitmapButton * ShuttleGuiBase::AddBitmapButton(const wxBitmap &Bitmap, int PositionFlags)
356 {
357  UseUpId();
358  if( mShuttleMode != eIsCreating )
359  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxBitmapButton);
360  wxBitmapButton * pBtn;
361  mpWind = pBtn = safenew wxBitmapButton(GetParent(), miId, Bitmap,
362  wxDefaultPosition, wxDefaultSize, Style( wxNO_BORDER ) );
363  pBtn->SetBackgroundColour(
364  wxColour( 246,246,243));
365 // wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
366  miProp=0;
367  UpdateSizersCore(false, PositionFlags | wxALL);
368  return pBtn;
369 }
370 
371 wxChoice * ShuttleGuiBase::AddChoice( const wxString &Prompt, const wxString &Selected, const wxArrayString * pChoices )
372 {
373  HandleOptionality( Prompt );
374  AddPrompt( Prompt );
375  UseUpId();
376  if( mShuttleMode != eIsCreating )
377  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxChoice);
378  wxChoice * pChoice;
379  miProp=0;
380 
381  mpWind = pChoice = safenew wxChoice(
382  GetParent(),
383  miId,
384  wxDefaultPosition,
385  wxDefaultSize,
386  *pChoices,
387  Style( 0 ) );
388 
389  pChoice->SetSizeHints( 180,-1);// Use -1 for 'default size' - Platform specific.
390  pChoice->SetName(wxStripMenuCodes(Prompt));
391  pChoice->SetStringSelection( Selected );
392 
393  UpdateSizers();
394  return pChoice;
395 }
396 
397 void ShuttleGuiBase::AddFixedText(const wxString &Str, bool bCenter)
398 {
399  UseUpId();
400  if( mShuttleMode != eIsCreating )
401  return;
402  mpWind = safenew wxStaticText(GetParent(), miId, Str, wxDefaultPosition, wxDefaultSize,
403  Style( wxALIGN_LEFT ));
404  mpWind->SetName(wxStripMenuCodes(Str)); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
405  if( bCenter )
406  {
407  miProp=1;
408  UpdateSizersC();
409  }
410  else
411  UpdateSizers();
412 }
413 
414 wxStaticText * ShuttleGuiBase::AddVariableText(const wxString &Str, bool bCenter, int PositionFlags)
415 {
416  UseUpId();
417  if( mShuttleMode != eIsCreating )
418  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxStaticText);
419 
420  wxStaticText *pStatic;
421  mpWind = pStatic = safenew wxStaticText(GetParent(), miId, Str, wxDefaultPosition, wxDefaultSize,
422  Style( wxALIGN_LEFT ));
423  mpWind->SetName(wxStripMenuCodes(Str)); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
424  if( bCenter )
425  {
426  miProp=1;
427  if( PositionFlags )
428  UpdateSizersCore( false, PositionFlags );
429  else
430  UpdateSizersC();
431  }
432  else
433  if( PositionFlags )
434  UpdateSizersCore( false, PositionFlags );
435  else
436  UpdateSizers();
437  return pStatic;
438 }
439 
440 wxComboBox * ShuttleGuiBase::AddCombo( const wxString &Prompt, const wxString &Selected,const wxArrayString * pChoices, long style )
441 {
442  HandleOptionality( Prompt );
443  AddPrompt( Prompt );
444  UseUpId();
445  if( mShuttleMode != eIsCreating )
446  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxComboBox);
447  wxComboBox * pCombo;
448  miProp=0;
449 
450  int n = pChoices->GetCount();
451  if( n>50 ) n=50;
452  int i;
453  wxString Choices[50];
454  for(i=0;i<n;i++)
455  {
456  Choices[i] = (*pChoices)[i];
457  }
458 
459  mpWind = pCombo = safenew wxComboBox(GetParent(), miId, Selected, wxDefaultPosition, wxDefaultSize,
460  n, Choices, Style( style ));
461  mpWind->SetName(wxStripMenuCodes(Prompt));
462 
463  UpdateSizers();
464  return pCombo;
465 }
466 
467 
468 wxRadioButton * ShuttleGuiBase::AddRadioButton(const wxString &Prompt)
469 {
472  UseUpId();
473  if( mShuttleMode != eIsCreating )
474  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxRadioButton);
475  wxRadioButton * pRad;
476  mpWind = pRad = safenew wxRadioButton(GetParent(), miId, Prompt,
477  wxDefaultPosition, wxDefaultSize, Style( wxRB_GROUP ) );
478  mpWind->SetName(wxStripMenuCodes(Prompt));
479  pRad->SetValue(true );
480  UpdateSizers();
481  return pRad;
482 }
483 
484 wxRadioButton * ShuttleGuiBase::AddRadioButtonToGroup(const wxString &Prompt)
485 {
486  UseUpId();
487  if( mShuttleMode != eIsCreating )
488  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxRadioButton);
489  wxRadioButton * pRad;
490  mpWind = pRad = safenew wxRadioButton(GetParent(), miId, Prompt,
491  wxDefaultPosition, wxDefaultSize, Style( 0 ) );
492  mpWind->SetName(wxStripMenuCodes(Prompt));
493  UpdateSizers();
494  return pRad;
495 }
496 
497 wxSlider * ShuttleGuiBase::AddSlider(const wxString &Prompt, int pos, int Max, int Min)
498 {
499  HandleOptionality( Prompt );
500  AddPrompt( Prompt );
501  UseUpId();
502  if( mShuttleMode != eIsCreating )
503  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxSlider);
504  wxSlider * pSlider;
505  mpWind = pSlider = safenew wxSlider(GetParent(), miId,
506  pos, Min, Max,
507  wxDefaultPosition, wxDefaultSize,
508  Style( wxSL_HORIZONTAL | wxSL_LABELS | wxSL_AUTOTICKS )
509  );
510 #if wxUSE_ACCESSIBILITY
511  // so that name can be set on a standard control
512  mpWind->SetAccessible(safenew WindowAccessible(mpWind));
513 #endif
514  mpWind->SetName(wxStripMenuCodes(Prompt));
515  miProp=1;
516  UpdateSizers();
517  return pSlider;
518 }
519 
520 wxSpinCtrl * ShuttleGuiBase::AddSpinCtrl(const wxString &Prompt, int Value, int Max, int Min)
521 {
522  HandleOptionality( Prompt );
523  AddPrompt( Prompt );
524  UseUpId();
525  if( mShuttleMode != eIsCreating )
526  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxSpinCtrl);
527  wxSpinCtrl * pSpinCtrl;
528  mpWind = pSpinCtrl = safenew wxSpinCtrl(GetParent(), miId,
529  wxEmptyString,
530  wxDefaultPosition, wxDefaultSize,
531  Style( wxSP_VERTICAL | wxSP_ARROW_KEYS ),
532  Min, Max, Value
533  );
534  mpWind->SetName(wxStripMenuCodes(Prompt));
535  miProp=1;
536  UpdateSizers();
537  return pSpinCtrl;
538 }
539 
540 wxTextCtrl * ShuttleGuiBase::AddTextBox(const wxString &Caption, const wxString &Value, const int nChars)
541 {
542  HandleOptionality( Caption );
543  AddPrompt( Caption );
544  UseUpId();
545  if( mShuttleMode != eIsCreating )
546  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTextCtrl);
547  wxTextCtrl * pTextCtrl;
548  wxSize Size(wxDefaultSize);
549  if( nChars > 0 )
550  {
551  Size.SetWidth( nChars *5 );
552  }
553  miProp=0;
554 
555 #ifdef EXPERIMENTAL_RIGHT_ALIGNED_TEXTBOXES
556  long flags = wxTE_RIGHT;
557 #else
558  long flags = wxTE_LEFT;
559 #endif
560 
561  mpWind = pTextCtrl = safenew wxTextCtrl(GetParent(), miId, Value,
562  wxDefaultPosition, Size, Style( flags ));
563 #if wxUSE_ACCESSIBILITY
564  // so that name can be set on a standard control
565  mpWind->SetAccessible(safenew WindowAccessible(mpWind));
566 #endif
567  mpWind->SetName(wxStripMenuCodes(Caption));
568  UpdateSizers();
569  return pTextCtrl;
570 }
571 
572 wxTextCtrl * ShuttleGuiBase::AddNumericTextBox(const wxString &Caption, const wxString &Value, const int nChars)
573 {
574  HandleOptionality( Caption );
575  AddPrompt( Caption );
576  UseUpId();
577  if( mShuttleMode != eIsCreating )
578  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTextCtrl);
579  wxTextCtrl * pTextCtrl;
580  wxSize Size(wxDefaultSize);
581  if( nChars > 0 )
582  {
583  Size.SetWidth( nChars *5 );
584  }
585  miProp=0;
586 
587 #ifdef EXPERIMENTAL_RIGHT_ALIGNED_TEXTBOXES
588  long flags = wxTE_RIGHT;
589 #else
590  long flags = wxTE_LEFT;
591 #endif
592 
593  wxTextValidator Validator(wxFILTER_NUMERIC);
594  mpWind = pTextCtrl = safenew wxTextCtrl(GetParent(), miId, Value,
595  wxDefaultPosition, Size, Style( flags ),
596  Validator // It's OK to pass this. It will be cloned.
597  );
598 #if wxUSE_ACCESSIBILITY
599  // so that name can be set on a standard control
600  mpWind->SetAccessible(safenew WindowAccessible(mpWind));
601 #endif
602  mpWind->SetName(wxStripMenuCodes(Caption));
603  UpdateSizers();
604  return pTextCtrl;
605 }
606 
608 wxTextCtrl * ShuttleGuiBase::AddTextWindow(const wxString &Value)
609 {
610  UseUpId();
611  if( mShuttleMode != eIsCreating )
612  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTextCtrl);
613  wxTextCtrl * pTextCtrl;
614  SetProportions( 1 );
615  mpWind = pTextCtrl = safenew wxTextCtrl(GetParent(), miId, Value,
616  wxDefaultPosition, wxDefaultSize, Style( wxTE_MULTILINE ));
617 #if wxUSE_ACCESSIBILITY
618  // so that name can be set on a standard control
619  mpWind->SetAccessible(safenew WindowAccessible(mpWind));
620 #endif
621  UpdateSizers();
622  // Start off at start of window...
623  pTextCtrl->SetInsertionPoint( 0 );
624  pTextCtrl->ShowPosition( 0 );
625  return pTextCtrl;
626 }
627 
629 void ShuttleGuiBase::AddConstTextBox(const wxString &Prompt, const wxString &Value)
630 {
631  HandleOptionality( Prompt );
632  AddPrompt( Prompt );
633  UseUpId();
634  if( mShuttleMode != eIsCreating )
635  return;
636 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wx);
637  miProp=0;
638  UpdateSizers();
639  miProp=0;
640  mpWind = safenew wxStaticText(GetParent(), miId, Value, wxDefaultPosition, wxDefaultSize,
641  Style( 0 ));
642  mpWind->SetName(Value); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
643  UpdateSizers();
644 }
645 
646 wxListBox * ShuttleGuiBase::AddListBox(const wxArrayString * pChoices, long style)
647 {
648  UseUpId();
649  if( mShuttleMode != eIsCreating )
650  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxListBox);
651  wxListBox * pListBox;
652  SetProportions( 1 );
653  mpWind = pListBox = safenew wxListBox(GetParent(), miId,
654  wxDefaultPosition, wxDefaultSize,*pChoices, style);
655  pListBox->SetMinSize( wxSize( 120,150 ));
656  UpdateSizers();
657  return pListBox;
658 }
659 
660 
662 {
663  UseUpId();
664  if( mShuttleMode != eIsCreating )
665  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxListCtrl);
666  wxListCtrl * pListCtrl;
667  SetProportions( 1 );
668  mpWind = pListCtrl = safenew wxListCtrl(GetParent(), miId,
669  wxDefaultPosition, wxDefaultSize, Style( wxLC_ICON ));
670  pListCtrl->SetMinSize( wxSize( 120,150 ));
671  UpdateSizers();
672  return pListCtrl;
673 }
674 
676 {
677  UseUpId();
678  if( mShuttleMode != eIsCreating )
679  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxGrid);
680  wxGrid * pGrid;
681  SetProportions( 1 );
682  mpWind = pGrid = safenew wxGrid(GetParent(), miId, wxDefaultPosition,
683  wxDefaultSize, Style( wxWANTS_CHARS ));
684  pGrid->SetMinSize( wxSize( 120, 150 ));
685  UpdateSizers();
686  return pGrid;
687 }
688 
690 {
691  UseUpId();
692  if( mShuttleMode != eIsCreating )
693  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxListCtrl);
694  wxListCtrl * pListCtrl;
695  SetProportions( 1 );
696  mpWind = pListCtrl = safenew wxListCtrl(GetParent(), miId,
697  wxDefaultPosition, wxSize(230,120),//wxDefaultSize,
698  Style( wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxSUNKEN_BORDER ));
699 // pListCtrl->SetMinSize( wxSize( 120,150 ));
700  UpdateSizers();
701  return pListCtrl;
702 }
703 
705 {
706  UseUpId();
707  if( mShuttleMode != eIsCreating )
708  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTreeCtrl);
709  wxTreeCtrl * pTreeCtrl;
710  SetProportions( 1 );
711  mpWind = pTreeCtrl = safenew wxTreeCtrl(GetParent(), miId, wxDefaultPosition, wxDefaultSize,
712  Style( wxTR_HAS_BUTTONS ));
713  pTreeCtrl->SetMinSize( wxSize( 120,650 ));
714  UpdateSizers();
715  return pTreeCtrl;
716 }
717 
718 void ShuttleGuiBase::AddIcon(wxBitmap *pBmp)
719 {
720  UseUpId();
721  if( mShuttleMode != eIsCreating )
722 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wx);
723  return;
724  wxBitmapButton * pBtn;
725  mpWind = pBtn = safenew wxBitmapButton(GetParent(), miId, *pBmp,
726  wxDefaultPosition, wxDefaultSize, Style( wxBU_AUTODRAW ) );
727  pBtn->SetWindowStyle( 0 );
728  UpdateSizersC();
729 }
730 
732 {
733  miPropSetByUser = iProp;
734  return *this;
735 }
736 
738 {
739  auto menuBar = std::make_unique<wxMenuBar>();
740  mpMenuBar = menuBar.get();
741 
742  wxFrame * pFrame = (wxFrame*)mpParent;
743  pFrame->SetThemeEnabled( true );
744  mpMenuBar->SetThemeEnabled( true );
745  pFrame->SetMenuBar(menuBar.release());
746 
747  return mpMenuBar;
748 }
749 
750 wxMenu * ShuttleGuiBase::AddMenu( const wxString & Title )
751 {
752  mpMenuBar->Append( (mpMenu = safenew wxMenu), Title );
753  return mpMenu;
754 }
755 
756 
757 
763 wxStaticBox * ShuttleGuiBase::StartStatic(const wxString &Str, int iProp)
764 {
765  UseUpId();
766  if( mShuttleMode != eIsCreating )
767  return NULL;
768  wxStaticBox * pBox = safenew wxStaticBox(GetParent(), miId,
769  Str );
770  pBox->SetLabel( Str );
771  pBox->SetName(wxStripMenuCodes(Str));
772  mpSubSizer = std::make_unique<wxStaticBoxSizer>(
773  pBox,
774  wxVERTICAL );
775  miSizerProp = iProp;
776  UpdateSizers();
777  return pBox;
778 }
779 
781 {
782  if( mShuttleMode != eIsCreating )
783  return;
784  PopSizer();
785 }
786 
795 wxScrolledWindow * ShuttleGuiBase::StartScroller(int iStyle)
796 {
797  UseUpId();
798  if( mShuttleMode != eIsCreating )
799  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxScrolledWindow);
800 
801  wxScrolledWindow * pScroller;
802  mpWind = pScroller = safenew wxScrolledWindow(GetParent(), miId, wxDefaultPosition, wxDefaultSize,
803  Style( wxSUNKEN_BORDER ) );
804  pScroller->SetScrollRate( 20,20 );
805 
806  // This fools NVDA into not saying "Panel" when the dialog gets focus
807  pScroller->SetName(wxT("\a"));
808  pScroller->SetLabel(wxT("\a"));
809 
810  SetProportions( 1 );
811  if( iStyle==2 )
812  {
814  }
815  else
816  {
817  // mpWind->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_MENUBAR));
818  UpdateSizers(); // adds window in to current sizer.
819  }
820 
821  // create a sizer within the window...
822  mpParent = pScroller;
823  pScroller->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
824  PushSizer();
825  return pScroller;
826 }
827 
829 {
830  if( mShuttleMode != eIsCreating )
831  return;
832  wxSize ScrollSize = mpSizer->GetMinSize();
833  int yMin = ScrollSize.y+4;
834  int xMin = ScrollSize.x+4;
835  if( yMin > 400)
836  {
837  yMin = 400;
838  xMin+=50;// extra space for vertical scrollbar.
839  }
840 
841  mpParent->SetMinSize( wxSize(xMin, yMin) );
842 
843  PopSizer();
844  mpParent = mpParent->GetParent();
845 }
846 
847 wxPanel * ShuttleGuiBase::StartPanel(int iStyle)
848 {
849  UseUpId();
850  if( mShuttleMode != eIsCreating )
851  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxPanel);
852  wxPanel * pPanel;
853  mpWind = pPanel = safenew wxPanelWrapper( GetParent(), miId, wxDefaultPosition, wxDefaultSize,
854  Style( wxNO_BORDER ));
855 
856  if( iStyle != 0 )
857  {
858  mpWind->SetBackgroundColour(
859  iStyle==1
860  ? wxColour( 190,200,230) :
861  wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)
862  );
863  }
864  SetProportions(0);
865  miBorder=2;
866  UpdateSizers(); // adds window in to current sizer.
867 
868  // create a sizer within the window...
869  mpParent = pPanel;
870  pPanel->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
871  PushSizer();
872  return pPanel;
873 }
874 
876 {
877  if( mShuttleMode != eIsCreating )
878  return;
879  PopSizer();
880  mpParent = mpParent->GetParent();
881 }
882 
884 {
885  UseUpId();
886  if( mShuttleMode != eIsCreating )
887  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxNotebook);
888  wxNotebook * pNotebook;
889  mpWind = pNotebook = safenew wxNotebook(GetParent(),
890  miId, wxDefaultPosition, wxDefaultSize, Style( 0 ));
891  SetProportions( 1 );
892  UpdateSizers();
893  mpParent = pNotebook;
894  return pNotebook;
895 }
896 
898 {
899  //PopSizer();
900  mpParent = mpParent->GetParent();
901 }
902 
903 
905 {
906  if( mShuttleMode != eIsCreating )
907  return NULL;
908 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wx);
909  wxNotebook * pNotebook = (wxNotebook*)mpParent;
911  pPage->SetName(Name);
912 
913  pNotebook->AddPage(
914  pPage,
915  Name);
916  PushSizer();
917 
918  SetProportions( 1 );
919  mpParent = pPage;
920  pPage->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
921  mpSizer->SetMinSize(250, 500);
922  // UpdateSizers();
923  return pPage;
924 }
925 
926 void ShuttleGuiBase::StartNotebookPage( const wxString & Name, wxNotebookPage * pPage )
927 {
928  if( mShuttleMode != eIsCreating )
929  return;
930 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wx);
931  wxNotebook * pNotebook = (wxNotebook*)mpParent;
932 // wxNotebookPage * pPage = safenew wxPanelWrapper(GetParent());
933  pPage->Create( mpParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, wxT("panel"));
934  pPage->SetName(Name);
935 
936  pNotebook->AddPage(
937  pPage,
938  Name);
939  PushSizer();
940 
941  SetProportions( 1 );
942  mpParent = pPage;
943  pPage->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
944  mpSizer->SetMinSize(250, 500);
945  // UpdateSizers();
946 }
947 
949 {
950  if( mShuttleMode != eIsCreating )
951  return;
952  PopSizer();
953  mpParent = mpParent->GetParent();
954 }
955 
956 // Doxygen description is at the start of the file
957 // this is a wxPanel with erase background disabled.
958 class InvisiblePanel final : public wxPanelWrapper
959 {
960 public:
962  wxWindow* parent,
963  wxWindowID id = -1,
964  const wxPoint& pos = wxDefaultPosition,
965  const wxSize& size = wxDefaultSize,
966  long style = wxTAB_TRAVERSAL ) :
967  wxPanelWrapper( parent, id, pos, size, style )
968  {
969  };
971  void OnPaint( wxPaintEvent &event );
972  void OnErase(wxEraseEvent &/*evt*/){;};
973  DECLARE_EVENT_TABLE()
974 };
975 
976 
977 BEGIN_EVENT_TABLE(InvisiblePanel, wxPanelWrapper)
978 // EVT_PAINT(InvisiblePanel::OnPaint)
979  EVT_ERASE_BACKGROUND( InvisiblePanel::OnErase)
981 
982 void InvisiblePanel::OnPaint( wxPaintEvent & WXUNUSED(event))
983 {
984  // Don't repaint my background.
985  wxPaintDC dc(this);
986  // event.Skip(); // swallow the paint event.
987 }
988 
990 {
991  UseUpId();
992  if( mShuttleMode != eIsCreating )
993  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxPanel);
994  wxPanel * pPanel;
995  mpWind = pPanel = safenew wxPanelWrapper(GetParent(), miId, wxDefaultPosition, wxDefaultSize,
996  wxNO_BORDER);
997 
998  mpWind->SetBackgroundColour(
999  wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)
1000  );
1001  SetProportions( 1 );
1002  miBorder=0;
1003  UpdateSizers(); // adds window in to current sizer.
1004 
1005  // create a sizer within the window...
1006  mpParent = pPanel;
1007  pPanel->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
1008  PushSizer();
1009  return pPanel;
1010 }
1011 
1013 {
1014  EndPanel();
1015 }
1016 
1017 
1024 void ShuttleGuiBase::StartHorizontalLay( int PositionFlags, int iProp)
1025 {
1026  if( mShuttleMode != eIsCreating )
1027  return;
1028  miSizerProp=iProp;
1029  mpSubSizer = std::make_unique<wxBoxSizer>( wxHORIZONTAL );
1030  UpdateSizersCore( false, PositionFlags | wxALL );
1031 }
1032 
1034 {
1035  if( mShuttleMode != eIsCreating )
1036  return;
1037  PopSizer();
1038 }
1039 
1041 {
1042  if( mShuttleMode != eIsCreating )
1043  return;
1044  miSizerProp=iProp;
1045  mpSubSizer = std::make_unique<wxBoxSizer>( wxVERTICAL );
1046  UpdateSizers();
1047 }
1048 
1049 void ShuttleGuiBase::StartVerticalLay(int PositionFlags, int iProp)
1050 {
1051  if( mShuttleMode != eIsCreating )
1052  return;
1053  miSizerProp=iProp;
1054  mpSubSizer = std::make_unique<wxBoxSizer>( wxVERTICAL );
1055  UpdateSizersCore( false, PositionFlags | wxALL );
1056 }
1057 
1059 {
1060  if( mShuttleMode != eIsCreating )
1061  return;
1062  PopSizer();
1063 }
1064 
1065 void ShuttleGuiBase::StartMultiColumn(int nCols, int PositionFlags)
1066 {
1067  if( mShuttleMode != eIsCreating )
1068  return;
1069  mpSubSizer = std::make_unique<wxFlexGridSizer>( nCols );
1070  UpdateSizersCore( false, PositionFlags | wxALL );
1071 }
1072 
1074 {
1075  if( mShuttleMode != eIsCreating )
1076  return;
1077  PopSizer();
1078 }
1079 
1082 void ShuttleGuiBase::DoDataShuttle( const wxString &Name, WrappedType & WrappedRef )
1083 {
1084  wxASSERT( mpShuttle );
1085  mpShuttle->TransferWrappedType( Name, WrappedRef );
1086 }
1087 
1088 //-----------------------------------------------------------------------//
1089 
1090 // We now have a group of tie functions which are generic in the type
1091 // they bind to (i.e. WrappedType).
1092 // The type specific versions are much shorter and are later
1093 // in this file.
1094 wxCheckBox * ShuttleGuiBase::TieCheckBox(const wxString &Prompt, WrappedType & WrappedRef)
1095 {
1096  HandleOptionality( Prompt );
1097  // The Add function does a UseUpId(), so don't do it here in that case.
1098  if( mShuttleMode == eIsCreating )
1099  return AddCheckBox( Prompt, WrappedRef.ReadAsString());
1100 
1101  UseUpId();
1102 
1103  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1104  wxCheckBox * pCheckBox = wxDynamicCast(pWnd, wxCheckBox);
1105 
1106  switch( mShuttleMode )
1107  {
1108  // IF setting internal storage from the controls.
1109  case eIsGettingMetadata:
1110  break;
1111  case eIsGettingFromDialog:
1112  {
1113  wxASSERT( pCheckBox );
1114  WrappedRef.WriteToAsBool( pCheckBox->GetValue() );
1115  }
1116  break;
1117  case eIsSettingToDialog:
1118  {
1119  wxASSERT( pCheckBox );
1120  pCheckBox->SetValue( WrappedRef.ReadAsBool() );
1121  }
1122  break;
1123  // IF Saving settings to external storage...
1124  // or IF Getting settings from external storage.
1125  case eIsSavingViaShuttle:
1126  case eIsGettingViaShuttle:
1127  DoDataShuttle( Prompt, WrappedRef );
1128  break;
1129  default:
1130  wxASSERT( false );
1131  break;
1132  }
1133  return pCheckBox;
1134 }
1135 
1136 wxCheckBox * ShuttleGuiBase::TieCheckBoxOnRight(const wxString &Prompt, WrappedType & WrappedRef)
1137 {
1138  HandleOptionality( Prompt );
1139  // The Add function does a UseUpId(), so don't do it here in that case.
1140  if( mShuttleMode == eIsCreating )
1141  return AddCheckBoxOnRight( Prompt, WrappedRef.ReadAsString());
1142  UseUpId();
1143 
1144  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1145  wxCheckBox * pCheckBox = wxDynamicCast(pWnd, wxCheckBox);
1146 
1147  switch( mShuttleMode )
1148  {
1149  // IF setting internal storage from the controls.
1150  case eIsGettingMetadata:
1151  break;
1152  case eIsGettingFromDialog:
1153  {
1154  wxASSERT( pCheckBox );
1155  WrappedRef.WriteToAsBool( pCheckBox->GetValue() );
1156  }
1157  break;
1158  case eIsSettingToDialog:
1159  {
1160  wxASSERT( pCheckBox );
1161  pCheckBox->SetValue( WrappedRef.ReadAsBool() );
1162  }
1163  break;
1164  // IF Saving settings to external storage...
1165  // or IF Getting settings from external storage.
1166  case eIsSavingViaShuttle:
1167  case eIsGettingViaShuttle:
1168  DoDataShuttle( Prompt, WrappedRef );
1169  break;
1170  default:
1171  wxASSERT( false );
1172  break;
1173  }
1174  return pCheckBox;
1175 }
1176 
1177 wxSpinCtrl * ShuttleGuiBase::TieSpinCtrl( const wxString &Prompt, WrappedType & WrappedRef, const int max, const int min )
1178 {
1179  HandleOptionality( Prompt );
1180  // The Add function does a UseUpId(), so don't do it here in that case.
1181  if( mShuttleMode == eIsCreating )
1182  return AddSpinCtrl( Prompt, WrappedRef.ReadAsInt(), max, min );
1183 
1184  UseUpId();
1185  wxSpinCtrl * pSpinCtrl=NULL;
1186 
1187  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1188  pSpinCtrl = wxDynamicCast(pWnd, wxSpinCtrl);
1189 
1190  switch( mShuttleMode )
1191  {
1192  // IF setting internal storage from the controls.
1193  case eIsGettingMetadata:
1194  break;
1195  case eIsGettingFromDialog:
1196  {
1197  wxASSERT( pSpinCtrl );
1198  WrappedRef.WriteToAsInt( pSpinCtrl->GetValue() );
1199  }
1200  break;
1201  case eIsSettingToDialog:
1202  {
1203  wxASSERT( pSpinCtrl );
1204  pSpinCtrl->SetValue( WrappedRef.ReadAsInt() );
1205  }
1206  break;
1207  // IF Saving settings to external storage...
1208  // or IF Getting settings from external storage.
1209  case eIsGettingViaShuttle:
1210  case eIsSavingViaShuttle:
1211  DoDataShuttle( Prompt, WrappedRef );
1212  break;
1213  default:
1214  wxASSERT( false );
1215  break;
1216  }
1217  return pSpinCtrl;
1218 }
1219 
1220 wxTextCtrl * ShuttleGuiBase::TieTextBox( const wxString &Prompt, WrappedType & WrappedRef, const int nChars)
1221 {
1222  HandleOptionality( Prompt );
1223  // The Add function does a UseUpId(), so don't do it here in that case.
1224  if( mShuttleMode == eIsCreating )
1225  return AddTextBox( Prompt, WrappedRef.ReadAsString(), nChars );
1226 
1227  UseUpId();
1228  wxTextCtrl * pTextBox=NULL;
1229 
1230  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1231  pTextBox = wxDynamicCast(pWnd, wxTextCtrl);
1232 
1233  switch( mShuttleMode )
1234  {
1235  // IF setting internal storage from the controls.
1236  case eIsGettingMetadata:
1237  break;
1238  case eIsGettingFromDialog:
1239  {
1240  wxASSERT( pTextBox );
1241  WrappedRef.WriteToAsString( pTextBox->GetValue() );
1242  }
1243  break;
1244  case eIsSettingToDialog:
1245  {
1246  wxASSERT( pTextBox );
1247  pTextBox->SetValue( WrappedRef.ReadAsString() );
1248  }
1249  break;
1250  // IF Saving settings to external storage...
1251  // or IF Getting settings from external storage.
1252  case eIsGettingViaShuttle:
1253  case eIsSavingViaShuttle:
1254  DoDataShuttle( Prompt, WrappedRef );
1255  break;
1256  default:
1257  wxASSERT( false );
1258  break;
1259  }
1260  return pTextBox;
1261 }
1262 
1263 wxTextCtrl * ShuttleGuiBase::TieNumericTextBox( const wxString &Prompt, WrappedType & WrappedRef, const int nChars)
1264 {
1265  HandleOptionality( Prompt );
1266  // The Add function does a UseUpId(), so don't do it here in that case.
1267  if( mShuttleMode == eIsCreating )
1268  return AddNumericTextBox( Prompt, WrappedRef.ReadAsString(), nChars );
1269 
1270  UseUpId();
1271  wxTextCtrl * pTextBox=NULL;
1272 
1273  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1274  pTextBox = wxDynamicCast(pWnd, wxTextCtrl);
1275 
1276  switch( mShuttleMode )
1277  {
1278  // IF setting internal storage from the controls.
1279  case eIsGettingMetadata:
1280  break;
1281  case eIsGettingFromDialog:
1282  {
1283  wxASSERT( pTextBox );
1284  WrappedRef.WriteToAsString( pTextBox->GetValue() );
1285  }
1286  break;
1287  case eIsSettingToDialog:
1288  {
1289  wxASSERT( pTextBox );
1290  pTextBox->SetValue( WrappedRef.ReadAsString() );
1291  }
1292  break;
1293  // IF Saving settings to external storage...
1294  // or IF Getting settings from external storage.
1295  case eIsGettingViaShuttle:
1296  case eIsSavingViaShuttle:
1297  DoDataShuttle( Prompt, WrappedRef );
1298  break;
1299  default:
1300  wxASSERT( false );
1301  break;
1302  }
1303  return pTextBox;
1304 }
1305 
1306 wxSlider * ShuttleGuiBase::TieSlider( const wxString &Prompt, WrappedType & WrappedRef, const int max, int min )
1307 {
1308  HandleOptionality( Prompt );
1309  // The Add function does a UseUpId(), so don't do it here in that case.
1310  if( mShuttleMode != eIsCreating )
1311  UseUpId();
1312  wxSlider * pSlider=NULL;
1313  switch( mShuttleMode )
1314  {
1315  case eIsCreating:
1316  {
1317  pSlider = AddSlider( Prompt, WrappedRef.ReadAsInt(), max, min );
1318  }
1319  break;
1320  // IF setting internal storage from the controls.
1321  case eIsGettingMetadata:
1322  break;
1323  case eIsGettingFromDialog:
1324  {
1325  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1326  pSlider = wxDynamicCast(pWnd, wxSlider);
1327  wxASSERT( pSlider );
1328  WrappedRef.WriteToAsInt( pSlider->GetValue() );
1329  }
1330  break;
1331  case eIsSettingToDialog:
1332  {
1333  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1334  pSlider = wxDynamicCast(pWnd, wxSlider);
1335  wxASSERT( pSlider );
1336  pSlider->SetValue( WrappedRef.ReadAsInt() );
1337  }
1338  break;
1339  // IF Saving settings to external storage...
1340  // or IF Getting settings from external storage.
1341  case eIsSavingViaShuttle:
1342  case eIsGettingViaShuttle:
1343  DoDataShuttle( Prompt, WrappedRef );
1344  break;
1345  default:
1346  wxASSERT( false );
1347  break;
1348  }
1349  return pSlider;
1350 }
1351 
1352 
1354  const wxString &Prompt,
1355  WrappedType &WrappedRef,
1356  const wxArrayString * pChoices )
1357 {
1358  HandleOptionality( Prompt );
1359 
1360  // The Add function does a UseUpId(), so don't do it here in that case.
1361  if( mShuttleMode != eIsCreating )
1362  UseUpId();
1363 
1364  wxChoice * pChoice=NULL;
1365  switch( mShuttleMode )
1366  {
1367  case eIsCreating:
1368  {
1369  if( WrappedRef.IsString() )
1370  pChoice = AddChoice( Prompt, WrappedRef.ReadAsString(), pChoices );
1371  else
1372  {
1373  wxString Temp;
1374  if( pChoices && ( WrappedRef.ReadAsInt() < (int)pChoices->GetCount() ) )
1375  {
1376  Temp = (*pChoices)[WrappedRef.ReadAsInt()];
1377  }
1378  pChoice = AddChoice( Prompt, Temp, pChoices );
1379  }
1380  }
1381  break;
1382  // IF setting internal storage from the controls.
1383  case eIsGettingMetadata:
1384  break;
1385  case eIsGettingFromDialog:
1386  {
1387  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1388  pChoice = wxDynamicCast(pWnd, wxChoice);
1389  wxASSERT( pChoice );
1390  if( WrappedRef.IsString())
1391  WrappedRef.WriteToAsString( pChoice->GetStringSelection());
1392  else
1393  WrappedRef.WriteToAsInt( pChoice->GetSelection() );
1394  }
1395  break;
1396  case eIsSettingToDialog:
1397  {
1398  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1399  pChoice = wxDynamicCast(pWnd, wxChoice);
1400  wxASSERT( pChoice );
1401  if( WrappedRef.IsString() )
1402  pChoice->SetStringSelection( WrappedRef.ReadAsString() );
1403  else
1404  pChoice->SetSelection( WrappedRef.ReadAsInt() );
1405  }
1406  break;
1407  // IF Saving settings to external storage...
1408  // or IF Getting settings from external storage.
1409  case eIsSavingViaShuttle:
1410  case eIsGettingViaShuttle:
1411  DoDataShuttle( Prompt, WrappedRef );
1412  break;
1413  default:
1414  wxASSERT( false );
1415  break;
1416  }
1417  SetSizeHints(*pChoices);
1418  return pChoice;
1419 }
1420 
1421 wxRadioButton * ShuttleGuiBase::TieRadioButton(const wxString &Prompt, WrappedType & WrappedRef)
1422 {
1423  wxASSERT( mRadioCount >= 0); // Did you remember to use StartRadioButtonGroup() ?
1424  mRadioCount++;
1425  UseUpId();
1426  wxRadioButton * pRadioButton = NULL;
1427 
1428  switch( mShuttleMode )
1429  {
1430  case eIsCreating:
1431  {
1432  mpWind = pRadioButton = safenew wxRadioButton(GetParent(), miId, Prompt,
1433  wxDefaultPosition, wxDefaultSize,
1434  (mRadioCount==1)?wxRB_GROUP:0);
1435  pRadioButton->SetValue(WrappedRef.ValuesMatch( mRadioValue ));
1436  pRadioButton->SetName(wxStripMenuCodes(Prompt));
1437  UpdateSizers();
1438  }
1439  break;
1440  case eIsGettingMetadata:
1441  break;
1442  case eIsGettingFromDialog:
1443  {
1444  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1445  pRadioButton = wxDynamicCast(pWnd, wxRadioButton);
1446  wxASSERT( pRadioButton );
1447  if( pRadioButton->GetValue() )
1448  {
1449  mRadioValue.WriteToAsWrappedType( WrappedRef );
1450  }
1451  }
1452  break;
1453  default:
1454  wxASSERT( false );
1455  break;
1456  }
1457  return pRadioButton;
1458 }
1459 
1463 void ShuttleGuiBase::StartRadioButtonGroup( const wxString & SettingName )
1464 {
1465  wxASSERT( mRadioValue.eWrappedType != eWrappedNotSet );
1466  mSettingName = SettingName;
1467  mRadioCount = 0;
1468  if( mShuttleMode == eIsCreating )
1469  DoDataShuttle( SettingName, mRadioValue );
1470 }
1471 
1475 {
1478  mRadioValue.Init();// Clear it out...
1479  mSettingName = wxT("");
1480  mRadioCount = -1; // So we detect a problem.
1481 }
1482 
1483 //-----------------------------------------------------------------------//
1484 //-- Now we are into type specific Tie() functions.
1485 //-- These are all 'one-step' tie functions.
1486 
1487 wxCheckBox * ShuttleGuiBase::TieCheckBox(const wxString &Prompt, bool &Var)
1488 {
1489  WrappedType WrappedRef( Var );
1490  return TieCheckBox( Prompt, WrappedRef );
1491 }
1492 
1493 // See comment in AddCheckBoxOnRight() for why we have this variant.
1494 wxCheckBox * ShuttleGuiBase::TieCheckBoxOnRight(const wxString &Prompt, bool &Var)
1495 {
1496  // Only odes anything different if it's creating.
1497  WrappedType WrappedRef( Var );
1498  if( mShuttleMode == eIsCreating )
1499  return AddCheckBoxOnRight( Prompt, WrappedRef.ReadAsString() );
1500  return TieCheckBox( Prompt, WrappedRef );
1501 }
1502 
1503 wxSpinCtrl * ShuttleGuiBase::TieSpinCtrl( const wxString &Prompt, int &Value, const int max, const int min )
1504 {
1505  WrappedType WrappedRef(Value);
1506  return TieSpinCtrl( Prompt, WrappedRef, max, min );
1507 }
1508 
1509 wxTextCtrl * ShuttleGuiBase::TieTextBox( const wxString &Prompt, wxString &Selected, const int nChars)
1510 {
1511  WrappedType WrappedRef(Selected);
1512  return TieTextBox( Prompt, WrappedRef, nChars );
1513 }
1514 
1515 wxTextCtrl * ShuttleGuiBase::TieTextBox( const wxString &Prompt, int &Selected, const int nChars)
1516 {
1517  WrappedType WrappedRef( Selected );
1518  return TieTextBox( Prompt, WrappedRef, nChars );
1519 }
1520 
1521 wxTextCtrl * ShuttleGuiBase::TieTextBox( const wxString &Prompt, double &Value, const int nChars)
1522 {
1523  WrappedType WrappedRef( Value );
1524  return TieTextBox( Prompt, WrappedRef, nChars );
1525 }
1526 
1527 wxTextCtrl * ShuttleGuiBase::TieNumericTextBox( const wxString &Prompt, wxString &Selected, const int nChars)
1528 {
1529  WrappedType WrappedRef(Selected);
1530  return TieNumericTextBox( Prompt, WrappedRef, nChars );
1531 }
1532 
1533 wxTextCtrl * ShuttleGuiBase::TieNumericTextBox( const wxString &Prompt, int &Selected, const int nChars)
1534 {
1535  WrappedType WrappedRef( Selected );
1536  return TieNumericTextBox( Prompt, WrappedRef, nChars );
1537 }
1538 
1539 wxTextCtrl * ShuttleGuiBase::TieNumericTextBox( const wxString &Prompt, double &Value, const int nChars)
1540 {
1541  WrappedType WrappedRef( Value );
1542  return TieNumericTextBox( Prompt, WrappedRef, nChars );
1543 }
1544 
1545 wxSlider * ShuttleGuiBase::TieSlider( const wxString &Prompt, int &pos, const int max, const int min )
1546 {
1547  WrappedType WrappedRef( pos );
1548  return TieSlider( Prompt, WrappedRef, max, min );
1549 }
1550 
1551 wxSlider * ShuttleGuiBase::TieSlider( const wxString &Prompt, double &pos, const double max, const double min )
1552 {
1553  WrappedType WrappedRef( pos );
1554  return TieSlider( Prompt, WrappedRef, max, min );
1555 }
1556 
1557 wxSlider * ShuttleGuiBase::TieSlider( const wxString &Prompt, float &pos, const float fMin, const float fMax)
1558 {
1559  const float RoundFix=0.0000001f;
1560  int iVal=(pos-fMin+RoundFix)*100.0/(fMax-fMin);
1561  wxSlider * pWnd = TieSlider( Prompt, iVal, 100 );
1562  pos = iVal*(fMax-fMin)*0.01+fMin;
1563  return pWnd;
1564 }
1565 
1566 wxSlider * ShuttleGuiBase::TieVSlider( const wxString &Prompt, float &pos, const float fMin, const float fMax)
1567 {
1568  int iVal=(pos-fMin)*100.0/(fMax-fMin);
1569 // if( mShuttleMode == eIsCreating )
1570 // {
1571 // return AddVSlider( Prompt, iVal, 100 );
1572 // }
1573  wxSlider * pWnd = TieSlider( Prompt, iVal, 100 );
1574  pos = iVal*(fMax-fMin)*0.01+fMin;
1575  return pWnd;
1576 }
1577 
1579  const wxString &Prompt,
1580  wxString &Selected,
1581  const wxArrayString * pChoices )
1582 {
1583  WrappedType WrappedRef( Selected );
1584  return TieChoice( Prompt, WrappedRef, pChoices );
1585 }
1586 
1588  const wxString &Prompt,
1589  int &Selected,
1590  const wxArrayString * pChoices )
1591 {
1592  WrappedType WrappedRef( Selected );
1593  return TieChoice( Prompt, WrappedRef, pChoices );
1594 }
1595 
1596 //-----------------------------------------------------------------------//
1597 
1598 // ShuttleGui utility functions to look things up in a list.
1599 // If not present, we use the configured default index value.
1600 
1601 //-----------------------------------------------------------------------//
1602 
1604 int ShuttleGuiBase::TranslateToIndex( const wxString &Value, const wxArrayString &Choices )
1605 {
1606  int n = Choices.Index( Value );
1607  if( n== wxNOT_FOUND )
1609  miNoMatchSelector = 0;
1610  return n;
1611 }
1612 
1614 wxString ShuttleGuiBase::TranslateFromIndex( const int nIn, const wxArrayString &Choices )
1615 {
1616  int n = nIn;
1617  if( n== wxNOT_FOUND )
1619  miNoMatchSelector = 0;
1620  if( n < (int)Choices.GetCount() )
1621  {
1622  return Choices[n];
1623  }
1624  return wxT("");
1625 }
1626 
1628 int ShuttleGuiBase::TranslateToIndex( const int Value, const std::vector<int> &Choices )
1629 {
1630  int n = make_iterator_range(Choices).index( Value );
1631  if( n == wxNOT_FOUND )
1633  miNoMatchSelector = 0;
1634  return n;
1635 }
1636 
1638 int ShuttleGuiBase::TranslateFromIndex( const int nIn, const std::vector<int> &Choices )
1639 {
1640  int n = nIn;
1641  if( n== wxNOT_FOUND )
1643  miNoMatchSelector = 0;
1644  if( n < (int)Choices.size() )
1645  {
1646  return Choices[n];
1647  }
1648  return 0;
1649 }
1650 
1651 //-----------------------------------------------------------------------//
1652 
1653 
1654 // ShuttleGui code uses the model that you read into program variables
1655 // and write out from program variables.
1656 
1657 // In programs like Audacity which don't use internal program variables
1658 // you have to do both steps in one go, using variants of the standard
1659 // 'Tie' functions which call the underlying Tie functions twice.
1660 
1661 //----------------------------------------------------------------------//
1662 
1663 
1696 bool ShuttleGuiBase::DoStep( int iStep )
1697 {
1698  // Get value and create
1699  if( mShuttleMode == eIsCreating )
1700  {
1701  return (iStep==1) || (iStep==2);
1702  }
1703  // Like creating, get the value and set.
1705  {
1706  return (iStep==1) || (iStep==2);
1707  }
1709  {
1710  return (iStep==2) || (iStep==3);
1711  }
1713  return iStep ==2;
1714  wxASSERT( false );
1715  return false;
1716 }
1717 
1718 
1722  const wxString &Prompt,
1723  const wxString &SettingName,
1724  const bool bDefault)
1725 {
1726  wxCheckBox * pCheck=NULL;
1727 
1728  bool bValue=bDefault;
1729  WrappedType WrappedRef( bValue );
1730  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1731  if( DoStep(2) ) pCheck = TieCheckBox( Prompt, WrappedRef );
1732  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1733 
1734  return pCheck;
1735 }
1736 
1740  const wxString &Prompt,
1741  const wxString &SettingName,
1742  const bool bDefault)
1743 {
1744  wxCheckBox * pCheck=NULL;
1745 
1746  bool bValue=bDefault;
1747  WrappedType WrappedRef( bValue );
1748  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1749  if( DoStep(2) ) pCheck = TieCheckBoxOnRight( Prompt, WrappedRef );
1750  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1751 
1752  return pCheck;
1753 }
1754 
1758  const wxString &Prompt,
1759  const wxString &SettingName,
1760  const int iDefault,
1761  const int max,
1762  const int min)
1763 {
1764  wxSlider * pSlider=NULL;
1765 
1766  int iValue=iDefault;
1767  WrappedType WrappedRef( iValue );
1768  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1769  if( DoStep(2) ) pSlider = TieSlider( Prompt, WrappedRef, max, min );
1770  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1771 
1772  return pSlider;
1773 }
1774 
1778  const wxString &Prompt,
1779  const wxString &SettingName,
1780  const int Value,
1781  const int max,
1782  const int min)
1783 {
1784  wxSpinCtrl * pSpinCtrl=NULL;
1785 
1786  int iValue = Value;
1787  WrappedType WrappedRef( iValue );
1788  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1789  if( DoStep(2) ) pSpinCtrl = TieSpinCtrl( Prompt, WrappedRef, max, min );
1790  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1791 
1792  return pSpinCtrl;
1793 }
1794 
1798  const wxString & Prompt,
1799  const wxString & SettingName,
1800  const wxString & Default,
1801  const int nChars)
1802 {
1803  wxTextCtrl * pText=(wxTextCtrl*)NULL;
1804 
1805  wxString Temp = Default;
1806  WrappedType WrappedRef( Temp );
1807  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1808  if( DoStep(2) ) pText = TieTextBox( Prompt, WrappedRef, nChars );
1809  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1810  return pText;
1811 }
1812 
1816  const wxString & Prompt,
1817  const wxString & SettingName,
1818  const wxString & Default,
1819  const int nChars)
1820 {
1821  wxTextCtrl * pText=(wxTextCtrl*)NULL;
1822 
1823  wxString Temp = Default;
1824  WrappedType WrappedRef( Temp );
1825  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1826  if( DoStep(2) ) pText = TieNumericTextBox( Prompt, WrappedRef, nChars );
1827  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1828  return pText;
1829 }
1834  const wxString & Prompt,
1835  const wxString & SettingName,
1836  const double & Default,
1837  const int nChars)
1838 {
1839  wxTextCtrl * pText=(wxTextCtrl*)NULL;
1840 
1841  double Temp = Default;
1842  WrappedType WrappedRef( Temp );
1843  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1844  if( DoStep(2) ) pText = TieTextBox( Prompt, WrappedRef, nChars );
1845  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1846  return pText;
1847 }
1848 
1853  const wxString & Prompt,
1854  const wxString & SettingName,
1855  const double & Default,
1856  const int nChars)
1857 {
1858  wxTextCtrl * pText=(wxTextCtrl*)NULL;
1859 
1860  double Temp = Default;
1861  WrappedType WrappedRef( Temp );
1862  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1863  if( DoStep(2) ) pText = TieNumericTextBox( Prompt, WrappedRef, nChars );
1864  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1865  return pText;
1866 }
1867 
1875  const wxString &Prompt,
1876  EnumSetting &enumSetting )
1877 {
1878  // Do this to force any needed migrations first
1879  enumSetting.Read();
1880 
1881  wxArrayString visibleChoices, internalChoices;
1882  for (const auto &ident : enumSetting) {
1883  visibleChoices.push_back( ident.Translation() );
1884  internalChoices.push_back( ident.Internal() );
1885  }
1886  return TieChoice(
1887  Prompt, enumSetting.Key(), enumSetting.Default().Internal(),
1888  visibleChoices, internalChoices );
1889 }
1890 
1899  const wxString &Prompt,
1900  const wxString &SettingName,
1901  const wxString &Default,
1902  const wxArrayString & Choices,
1903  const wxArrayString & InternalChoices)
1904 {
1905  wxChoice * pChoice=(wxChoice*)NULL;
1906 
1907  int TempIndex=0;
1908 // int TempIndex = TranslateToIndex( Default, InternalChoices );
1909  wxString TempStr = Default;
1910  WrappedType WrappedRef( TempStr );
1911  // Get from prefs does 1 and 2.
1912  // Put to prefs does 2 and 3.
1913  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef ); // Get Index from Prefs.
1914  if( DoStep(1) ) TempIndex = TranslateToIndex( TempStr, InternalChoices ); // To an index
1915  if( DoStep(2) ) pChoice = TieChoice( Prompt, TempIndex, &Choices ); // Get/Put index from GUI.
1916  if( DoStep(3) ) TempStr = TranslateFromIndex( TempIndex, InternalChoices ); // To a string
1917  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef ); // Put into Prefs.
1918  return pChoice;
1919 }
1920 
1931  const wxString &Prompt,
1932  const wxString &SettingName,
1933  const int Default,
1934  const wxArrayString & Choices,
1935  const std::vector<int> & InternalChoices)
1936 {
1937  wxChoice * pChoice=(wxChoice*)NULL;
1938 
1939  int TempIndex=0;
1940  int TranslatedInt = Default;
1941  WrappedType WrappedRef( TranslatedInt );
1942  // Get from prefs does 1 and 2.
1943  // Put to prefs does 2 and 3.
1944  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef ); // Get Int from Prefs.
1945  if( DoStep(1) ) TempIndex = TranslateToIndex( TranslatedInt, InternalChoices ); // Int to an index.
1946  if( DoStep(2) ) pChoice = TieChoice( Prompt, TempIndex, &Choices ); // Get/Put index from GUI.
1947  if( DoStep(3) ) TranslatedInt = TranslateFromIndex( TempIndex, InternalChoices ); // Index to int
1948  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef ); // Put into Prefs.
1949  return pChoice;
1950 }
1951 
1963  const wxString &Prompt,
1964  const wxString &SettingName,
1965  const int Default,
1966  const wxArrayString & Choices,
1967  const std::vector<int> & InternalChoices)
1968 {
1970  Prompt, SettingName, Default, Choices, InternalChoices );
1971 }
1972 
1975 void ShuttleGuiBase::StartRadioButtonGroup( const wxString & SettingName, const int iDefaultValue )
1976 {
1977  // Configure the generic type mechanism to use OUR integer.
1978  mRadioValueInt = iDefaultValue;
1980  // Now actually start the radio button group.
1981  StartRadioButtonGroup( SettingName );
1982 }
1983 
1986 void ShuttleGuiBase::StartRadioButtonGroup( const wxString & SettingName, const wxString & DefaultValue )
1987 {
1988  // Configure the generic type mechanism to use OUR string.
1989  mRadioValueString = DefaultValue;
1991  // Now actually start the radio button group.
1992  StartRadioButtonGroup( SettingName );
1993 }
1994 
1995 
1998  const wxString &Prompt,
1999  const int iValue)
2000 {
2001  int iTemp = iValue;
2002  WrappedType WrappedRef( iTemp );
2003  return TieRadioButton( Prompt, WrappedRef );
2004 }
2005 
2008  const wxString &Prompt,
2009  const wxString &Value)
2010 {
2011  // In what follows, WrappedRef is used in read only mode, but we
2012  // don't have a 'read-only' version, so we copy to deal with the constness.
2013  wxString Temp = Value;
2014  WrappedType WrappedRef( Temp );
2015  return TieRadioButton( Prompt, WrappedRef );
2016 }
2017 
2018 //------------------------------------------------------------------//
2019 
2020 // We're now into ShuttleGuiBase sizer and misc functions.
2021 
2029 {
2030  if( miIdSetByUser > 0)
2031  {
2032  miId = miIdSetByUser;
2033  miIdSetByUser = -1;
2034  return;
2035  }
2036  miId = miIdNext++;
2037 }
2038 
2040 {
2041  if( miPropSetByUser >=0 )
2042  {
2044  miPropSetByUser =-1;
2045  return;
2046  }
2047  miProp = Default;
2048 }
2049 
2050 
2051 void ShuttleGuiBase::UpdateSizersCore(bool bPrepend, int Flags)
2052 {
2053  if( mpWind && mpParent )
2054  {
2055  if( mpSizer){
2056  if( bPrepend )
2057  {
2058  mpSizer->Prepend(mpWind, miProp, Flags,miBorder);
2059  }
2060  else
2061  {
2062  mpSizer->Add(mpWind, miProp, Flags,miBorder);
2063  }
2064  }
2065  }
2066 
2067  if( mpSubSizer && mpSizer )
2068  {
2069  // When adding sizers into sizers, don't add a border.
2070  // unless it's a static box sizer.
2071  wxSizer *const pSubSizer = mpSubSizer.get();
2072  if (wxDynamicCast(pSubSizer, wxStaticBoxSizer))
2073  {
2074  mpSizer->Add( mpSubSizer.release(), miSizerProp, Flags , miBorder);
2075  }
2076  else
2077  {
2078  mpSizer->Add( mpSubSizer.release(), miSizerProp, Flags ,0);//miBorder);
2079  }
2080  mpSizer = pSubSizer;
2081  PushSizer();
2082  }
2083  mpLastWind = mpWind;
2084  mpWind = NULL;
2085  miProp = 0;
2086  miSizerProp =0;
2087 }
2088 
2089 // Sizer is added into parent sizer, and will expand/shrink.
2091 { UpdateSizersCore( false, wxEXPAND | wxALL );}
2092 
2093 // Sizer is added into parent sizer, centred
2095 { UpdateSizersCore( false, wxALIGN_CENTRE | wxALL );}
2096 
2097 // Sizer is added into parent sizer, and will expand/shrink.
2098 // added to start of sizer list.
2100 { UpdateSizersCore( true, wxEXPAND | wxALL );}
2101 
2103 {
2104  mSizerDepth--;
2105  wxASSERT( mSizerDepth >=0 );
2107 }
2108 
2110 {
2111  mSizerDepth++;
2112  wxASSERT( mSizerDepth < nMaxNestedSizers );
2114 }
2115 
2116 long ShuttleGuiBase::Style( long style )
2117 {
2118  if( miStyle )
2119  style = miStyle;
2120  miStyle = 0;
2121  return style;
2122 }
2123 
2124 // A rarely used helper function that sets a pointer
2125 // ONLY if the value it is to be set to is non NULL.
2126 void SetIfCreated( wxChoice * &Var, wxChoice * Val )
2127 {
2128  if( Val != NULL )
2129  Var = Val;
2130 };
2131 void SetIfCreated( wxTextCtrl * &Var, wxTextCtrl * Val )
2132 {
2133  if( Val != NULL )
2134  Var = Val;
2135 };
2136 void SetIfCreated( wxStaticText *&Var, wxStaticText * Val )
2137 {
2138  if( Val != NULL )
2139  Var = Val;
2140 };
2141 
2142 #ifdef EXPERIMENTAL_TRACK_PANEL
2143 // Additional includes down here, to make it easier to split this into
2144 // two files at some later date.
2145 #include "../extnpanel-src/GuiWaveTrack.h"
2146 #endif
2147 #include "./widgets/Ruler.h"
2149 #include "ShuttlePrefs.h"
2150 
2151 ShuttleGui::ShuttleGui(wxWindow * pParent, teShuttleMode ShuttleMode) :
2152  ShuttleGuiBase( pParent, ShuttleMode )
2153 {
2154  if( ShuttleMode == eIsCreatingFromPrefs )
2155  {
2157  Init(); // Wasn't fully done in base constructor because it is only done when eIsCreating is set.
2158  }
2159  else if( ShuttleMode == eIsSavingToPrefs )
2160  {
2162  }
2163  else
2164  {
2165  return;
2166  }
2167 
2168  mpShuttle = std::make_unique<ShuttlePrefs>();
2169  // In this case the client is the GUI, so if creating we do want to
2170  // store in the client.
2171  mpShuttle->mbStoreInClient = (mShuttleMode == eIsCreating );
2172 };
2173 
2175 {
2176 }
2177 
2178 // Now we have Audacity specific shuttle functions.
2180 {
2181  miIdSetByUser = id;
2182  return *this;
2183 }
2184 
2186  mpbOptionalFlag = &bVar;
2187  return *this;
2188 };
2189 
2190 
2191 GuiWaveTrack * ShuttleGui::AddGuiWaveTrack( const wxString & WXUNUSED(Name))
2192 {
2193 #ifdef EXPERIMENTAL_TRACK_PANEL
2194  UseUpId();
2195  if( mShuttleMode != eIsCreating )
2196  return (GuiWaveTrack*)NULL;
2197 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), GuiWaveTrack);
2198  GuiWaveTrack * pGuiWaveTrack;
2199  miProp=1;
2200  mpWind = pGuiWaveTrack = safenew GuiWaveTrack(mpParent, miId, Name);
2201  mpWind->SetMinSize(wxSize(100,50));
2202  UpdateSizers();
2203  return pGuiWaveTrack;
2204 #else
2205  return NULL;
2206 #endif
2207 }
2208 
2210 {
2211  UseUpId();
2212  if( mShuttleMode != eIsCreating )
2213  return (AttachableScrollBar*)NULL;
2214 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), AttachableScrollBar);
2215  AttachableScrollBar * pAttachableScrollBar;
2216  miProp=0;
2217  mpWind = pAttachableScrollBar = safenew AttachableScrollBar(
2218  mpParent,
2219  miId,
2220  wxDefaultPosition,
2221  wxDefaultSize,
2222  style
2223  );
2224  mpWind->SetMinSize(wxSize(10,20));
2225  UpdateSizers();
2226  return pAttachableScrollBar;
2227 }
2228 
2229 std::unique_ptr<wxSizer> CreateStdButtonSizer(wxWindow *parent, long buttons, wxWindow *extra)
2230 {
2231  wxASSERT(parent != NULL); // To justify safenew
2232 
2233  int margin;
2234  {
2235 #if defined(__WXMAC__)
2236  margin = 12;
2237 #elif defined(__WXGTK20__)
2238  margin = 12;
2239 #elif defined(__WXMSW__)
2240  wxButton b(parent, 0, wxEmptyString);
2241  margin = b.ConvertDialogToPixels(wxSize(2, 0)).x;
2242 #else
2243  wxButton b(parent, 0, wxEmptyString);
2244  margin = b->ConvertDialogToPixels(wxSize(4, 0)).x;
2245 #endif
2246  }
2247 
2248  wxButton *b = NULL;
2249  auto bs = std::make_unique<wxStdDialogButtonSizer>();
2250 
2251  if( buttons & eOkButton )
2252  {
2253  b = safenew wxButton(parent, wxID_OK);
2254  b->SetDefault();
2255  bs->AddButton( b );
2256  }
2257 
2258  if( buttons & eCancelButton )
2259  {
2260  bs->AddButton(safenew wxButton(parent, wxID_CANCEL));
2261  }
2262 
2263  if( buttons & eYesButton )
2264  {
2265  b = safenew wxButton(parent, wxID_YES);
2266  b->SetDefault();
2267  bs->AddButton( b );
2268  }
2269 
2270  if( buttons & eNoButton )
2271  {
2272  bs->AddButton(safenew wxButton(parent, wxID_NO));
2273  }
2274 
2275  if( buttons & eApplyButton )
2276  {
2277  b = safenew wxButton(parent, wxID_APPLY);
2278  b->SetDefault();
2279  bs->AddButton( b );
2280  }
2281 
2282  if( buttons & eCloseButton )
2283  {
2284  bs->AddButton(safenew wxButton(parent, wxID_CANCEL, _("&Close")));
2285  }
2286 
2287  if( buttons & eHelpButton )
2288  {
2289  // Replace standard Help button with smaller icon button.
2290  // bs->AddButton(safenew wxButton(parent, wxID_HELP));
2291  b = safenew wxBitmapButton(parent, wxID_HELP, theTheme.Bitmap( bmpHelpIcon ));
2292  b->SetToolTip( _("Help") );
2293  b->SetLabel(_("Help")); // for screen readers
2294  bs->AddButton( b );
2295  }
2296 
2297  if (buttons & ePreviewButton)
2298  {
2299  bs->Add(safenew wxButton(parent, ePreviewID, _("&Preview")), 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin);
2300  }
2301  if (buttons & ePreviewDryButton)
2302  {
2303  bs->Add(safenew wxButton(parent, ePreviewDryID, _("Dry Previe&w")), 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin);
2304  bs->Add( 20, 0 );
2305  }
2306 
2307  if( buttons & eSettingsButton )
2308  {
2309  bs->Add(safenew wxButton(parent, eSettingsID, _("&Settings")), 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin);
2310  bs->Add( 20, 0 );
2311  }
2312 
2313  if( extra )
2314  {
2315  bs->Add( extra, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin );
2316  bs->Add( 40, 0 );
2317  }
2318 
2319  bs->AddStretchSpacer();
2320  bs->Realize();
2321 
2322  // Add any buttons that need to cuddle up to the right hand cluster
2323  if( buttons & eDebugButton )
2324  {
2325  size_t lastLastSpacer = 0;
2326  size_t lastSpacer = 0;
2327  wxSizerItemList & list = bs->GetChildren();
2328  for( size_t i = 0, cnt = list.GetCount(); i < cnt; i++ )
2329  {
2330  if( list[i]->IsSpacer() )
2331  {
2332  lastSpacer = i;
2333  }
2334  else
2335  {
2336  lastLastSpacer = lastSpacer;
2337  }
2338  }
2339 
2340  b = safenew wxButton(parent, eDebugID, _("Debu&g"));
2341  bs->Insert( lastLastSpacer + 1, b, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin );
2342  }
2343 
2344  auto s = std::make_unique<wxBoxSizer>( wxVERTICAL );
2345  s->Add( bs.release(), 1, wxEXPAND | wxALL, 7 );
2346  s->Add( 0, 3 ); // a little extra space
2347 
2348  return std::unique_ptr<wxSizer>{ s.release() };
2349 }
2350 
2351 void ShuttleGui::AddStandardButtons(long buttons, wxButton *extra)
2352 {
2353  if( mShuttleMode != eIsCreating )
2354  return;
2355 
2356  StartVerticalLay( false );
2357 
2358  miSizerProp = false;
2359  mpSubSizer = CreateStdButtonSizer( mpParent, buttons, extra );
2360  UpdateSizers();
2361  PopSizer();
2362 
2363  EndVerticalLay();
2364 }
2365 
2366 wxSizerItem * ShuttleGui::AddSpace( int width, int height )
2367 {
2368  if( mShuttleMode != eIsCreating )
2369  return NULL;
2370  SetProportions(0);
2371  return mpSizer->Add( width, height, miProp);
2372 }
2373 
2374 void ShuttleGuiBase::SetSizeHints( wxWindow *window, const wxArrayString & items )
2375 {
2376  int maxw = 0;
2377 
2378  for( size_t i = 0; i < items.GetCount(); i++ )
2379  {
2380  int x;
2381  int y;
2382 
2383  window->GetTextExtent(items[i], &x, &y );
2384  if( x > maxw )
2385  {
2386  maxw = x;
2387  }
2388  }
2389 
2390  // Would be nice to know the sizes of the button and borders, but this is
2391  // the best we can do for now.
2392 #if defined(__WXMAC__)
2393  maxw += 50;
2394 #elif defined(__WXMSW__)
2395  maxw += 50;
2396 #elif defined(__WXGTK__)
2397  maxw += 50;
2398 #else
2399  maxw += 50;
2400 #endif
2401 
2402  window->SetSizeHints( maxw, -1 );
2403 }
2404 
2405 void ShuttleGuiBase::SetSizeHints( const wxArrayString & items )
2406 {
2407  if( mShuttleMode != eIsCreating )
2408  return;
2409 
2410  SetSizeHints( mpLastWind, items );
2411 }
2412 
2413 /********************************* GetDefinition ******************************/
2414 
2416  wxWindow * pParent,CommandMessageTarget & target )
2417 : ShuttleGui( pParent, eIsGettingMetadata ),
2419 {
2420 
2421 }
2423 {
2424 }
2425 
2427  const wxString &Prompt,
2428  const wxString &SettingName,
2429  const bool bDefault)
2430 {
2431  StartStruct();
2432  AddItem( SettingName, "id" );
2433  AddItem( Prompt, "prompt" );
2434  AddItem( "bool", "type" );
2435  AddBool( bDefault, "default" );
2436  EndStruct();
2437  return ShuttleGui::TieCheckBox( Prompt, SettingName, bDefault );
2438 }
2440  const wxString &Prompt,
2441  const wxString &SettingName,
2442  const bool bDefault)
2443 {
2444  StartStruct();
2445  AddItem( SettingName, "id" );
2446  AddItem( Prompt, "prompt" );
2447  AddItem( "bool", "type" );
2448  AddBool( bDefault, "default" );
2449  EndStruct();
2450  return ShuttleGui::TieCheckBoxOnRight( Prompt, SettingName, bDefault );
2451 }
2453  const wxString &Prompt,
2454  const wxString &SettingName,
2455  const wxString &Default,
2456  const wxArrayString &Choices,
2457  const wxArrayString & InternalChoices )
2458 {
2459  StartStruct();
2460  AddItem( SettingName, "id" );
2461  AddItem( Prompt, "prompt" );
2462  AddItem( "enum", "type" );
2463  AddItem( Default, "default" );
2464  StartField( "enum" );
2465  StartArray();
2466  for( size_t i=0;i<Choices.Count(); i++ )
2467  AddItem( InternalChoices[i] );
2468  EndArray();
2469  EndField();
2470  EndStruct();
2471  return ShuttleGui::TieChoice( Prompt, SettingName, Default, Choices, InternalChoices );
2472 }
2474  const wxString &Prompt,
2475  const wxString &SettingName,
2476  const int Default,
2477  const wxArrayString & Choices,
2478  const std::vector<int> & InternalChoices)
2479 {
2480  // Should no longer come here!
2481  // Choice controls in Preferences that really are exhaustive choices among
2482  // non-numerical options must now encode the internal choices as strings,
2483  // not numbers.
2484  wxASSERT(false);
2485 
2486  // But if we do get here anyway, proceed sub-optimally as before.
2487  StartStruct();
2488  AddItem( SettingName, "id" );
2489  AddItem( Prompt, "prompt" );
2490  AddItem( "enum", "type" );
2491  AddItem( Default, "default" );
2492  StartField( "enum" );
2493  StartArray();
2494  for( size_t i=0;i<Choices.Count(); i++ )
2495  AddItem( Choices[i] );
2496  EndArray();
2497  EndField();
2498  EndStruct();
2499  return ShuttleGui::TieChoice( Prompt, SettingName, Default, Choices, InternalChoices );
2500 }
2502  const wxString &Prompt,
2503  const wxString &SettingName,
2504  const int Default,
2505  const wxArrayString & Choices,
2506  const std::vector<int> & InternalChoices)
2507 {
2508  // Come here for controls that present non-exhaustive choices among some
2509  // numbers, with an associated control that allows arbitrary entry of an
2510  // "Other..."
2511  StartStruct();
2512  AddItem( SettingName, "id" );
2513  AddItem( Prompt, "prompt" );
2514  AddItem( "number", "type" ); // not "enum" !
2515  AddItem( Default, "default" );
2516  EndStruct();
2518  Prompt, SettingName, Default, Choices, InternalChoices );
2519 }
2521  const wxString &Prompt,
2522  const wxString &SettingName,
2523  const wxString &Default,
2524  const int nChars)
2525 {
2526  StartStruct();
2527  AddItem( SettingName, "id" );
2528  AddItem( Prompt, "prompt" );
2529  AddItem( "string", "type" );
2530  AddItem( Default, "default" );
2531  EndStruct();
2532  return ShuttleGui::TieTextBox( Prompt, SettingName, Default, nChars );
2533 }
2535  const wxString & Prompt,
2536  const wxString & SettingName,
2537  const double & Default,
2538  const int nChars)
2539 {
2540  StartStruct();
2541  AddItem( SettingName, "id" );
2542  AddItem( Prompt, "prompt" );
2543  AddItem( "string", "type" );
2544  AddItem( Default, "default" );
2545  EndStruct();
2546  return ShuttleGui::TieTextBox( Prompt, SettingName, Default, nChars );
2547 }
2549  const wxString &Prompt,
2550  const wxString &SettingName,
2551  const wxString &Default,
2552  const int nChars)
2553 {
2554  StartStruct();
2555  AddItem( SettingName, "id" );
2556  AddItem( Prompt, "prompt" );
2557  AddItem( "number", "type" );
2558  AddItem( Default, "default" );
2559  EndStruct();
2560  return ShuttleGui::TieNumericTextBox( Prompt, SettingName, Default, nChars );
2561 }
2563  const wxString & Prompt,
2564  const wxString & SettingName,
2565  const double & Default,
2566  const int nChars)
2567 {
2568  StartStruct();
2569  AddItem( SettingName, "id" );
2570  AddItem( Prompt, "prompt" );
2571  AddItem( "number", "type" );
2572  AddItem( Default, "default" );
2573  EndStruct();
2574  return ShuttleGui::TieNumericTextBox( Prompt, SettingName, Default, nChars );
2575 }
2577  const wxString & Prompt,
2578  const wxString & SettingName,
2579  const int iDefault,
2580  const int max,
2581  const int min)
2582 {
2583  StartStruct();
2584  AddItem( SettingName, "id" );
2585  AddItem( Prompt, "prompt" );
2586  AddItem( "number", "type" );
2587  AddItem( iDefault, "default" );
2588  EndStruct();
2589  return ShuttleGui::TieSlider( Prompt, SettingName, iDefault, max, min );
2590 }
2592  const wxString &Prompt,
2593  const wxString &SettingName,
2594  const int Value,
2595  const int max,
2596  const int min)
2597 {
2598  StartStruct();
2599  AddItem( SettingName, "id" );
2600  AddItem( Prompt, "prompt" );
2601  AddItem( "number", "type" );
2602  AddItem( Value, "default" );
2603  EndStruct();
2604  return ShuttleGui::TieSpinCtrl( Prompt, SettingName, Value, max, min );
2605 }
2606 
void HandleOptionality(const wxString &Prompt)
Definition: ShuttleGui.cpp:225
wxChoice * TieChoice(const wxString &Prompt, WrappedType &WrappedRef, const wxArrayString *pChoices)
ShuttleGuiGetDefinition(wxWindow *pParent, CommandMessageTarget &target)
std::unique_ptr< wxSizer > CreateStdButtonSizer(wxWindow *parent, long buttons, wxWindow *extra)
ShuttleGui & Optional(bool &bVar)
void SetSizeHints(int minX, int minY)
Used to modify an already placed Window.
Definition: ShuttleGui.cpp:194
void WriteToAsInt(const int InInt)
void SetTo(wxString &InStr)
Definition: WrappedType.h:41
AUDACITY_DLL_API Theme theTheme
Definition: Theme.cpp:209
WrappedType mRadioValue
The index of this radio item. -1 for none.
Definition: ShuttleGui.h:338
static CommandHandlerObject & ident(AudacityProject &project)
Definition: Menus.cpp:298
void OnErase(wxEraseEvent &)
Definition: ShuttleGui.cpp:972
An InvisiblePanel is a panel which does not repaint its own background.
Definition: ShuttleGui.cpp:958
wxCheckBox * TieCheckBoxOnRight(const wxString &Prompt, WrappedType &WrappedRef)
wxSpinCtrl * AddSpinCtrl(const wxString &Prompt, int Value, int Max, int Min)
Definition: ShuttleGui.cpp:520
wxCheckBox * AddCheckBoxOnRight(const wxString &Prompt, const wxString &Selected)
Definition: ShuttleGui.cpp:324
An AttachableScrollBar is a scroll bar that can be attached to multiple items and so control their sc...
virtual ~ShuttleGuiGetDefinition()
wxMenu * AddMenu(const wxString &Title)
Definition: ShuttleGui.cpp:750
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:409
int TranslateToIndex(const wxString &Value, const wxArrayString &Choices)
String-to-Index.
void WriteToAsWrappedType(const WrappedType &W)
Definition: WrappedType.cpp:78
void EndRadioButtonGroup()
wxString TranslateFromIndex(const int nIn, const wxArrayString &Choices)
Index-to-String.
InvisiblePanel(wxWindow *parent, wxWindowID id=-1, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL)
Definition: ShuttleGui.cpp:961
wxSlider * TieSlider(const wxString &Prompt, WrappedType &WrappedRef, const int max, const int min=0)
wxCheckBox * TieCheckBoxOnRight(const wxString &Prompt, const wxString &SettingName, const bool bDefault) override
teWrappedType eWrappedType
Definition: WrappedType.h:64
wxWindow * AddWindow(wxWindow *pWindow, int Flags=wxALIGN_CENTRE|wxALL)
Definition: ShuttleGui.cpp:288
std::unique_ptr< Shuttle > mpShuttle
Definition: ShuttleGui.h:328
void EndNotebook()
Definition: ShuttleGui.cpp:897
wxString Read() const
Definition: Prefs.cpp:379
void UpdateSizersAtStart()
wxString mRadioValueString
The wrapped value associated with the active radio button.
Definition: ShuttleGui.h:339
void EndMultiColumn()
void AddBool(const bool value, const wxString &name="") override
CommandMessageTargetDecorator is a CommandOutputTarget that forwards its work on to another one...
void EndNotebookPage()
Definition: ShuttleGui.cpp:948
void EnableCtrl(bool bEnable)
Definition: ShuttleGui.cpp:186
wxPanel * StartPanel(int iStyle=0)
Definition: ShuttleGui.cpp:847
wxWindow * mpDlg
Definition: ShuttleGui.h:325
int miSizerProp
Unwrapped integer value.
Definition: ShuttleGui.h:342
wxPanel * StartInvisiblePanel()
Definition: ShuttleGui.cpp:989
void SetIfCreated(wxChoice *&Var, wxChoice *Val)
wxSizer * pSizerStack[nMaxNestedSizers]
Definition: ShuttleGui.h:326
int mRadioValueInt
Unwrapped string value.
Definition: ShuttleGui.h:340
void WriteToAsBool(const bool InBool)
~ShuttleGui(void)
wxTreeCtrl * AddTree()
Definition: ShuttleGui.cpp:704
wxTextCtrl * AddNumericTextBox(const wxString &Caption, const wxString &Value, const int nChars)
Definition: ShuttleGui.cpp:572
wxSpinCtrl * TieSpinCtrl(const wxString &Prompt, WrappedType &WrappedRef, const int max, const int min=0)
virtual ~ShuttleGuiBase()
Definition: ShuttleGui.cpp:130
void EndScroller()
Definition: ShuttleGui.cpp:828
void OnPaint(wxPaintEvent &event)
Definition: ShuttleGui.cpp:982
wxListCtrl * AddListControl()
Definition: ShuttleGui.cpp:661
wxChoice * TieNumberAsChoice(const wxString &Prompt, const wxString &SettingName, const int Default, const wxArrayString &Choices, const std::vector< int > &InternalChoices) override
GuiWaveTrack * AddGuiWaveTrack(const wxString &Name)
const int nMaxNestedSizers
Definition: ShuttleGui.h:33
#define safenew
Definition: Audacity.h:230
wxString ReadAsString()
ShuttleGui(wxWindow *pParent, teShuttleMode ShuttleMode)
wxMenu * mpMenu
Definition: ShuttleGui.h:362
void EndHorizontalLay()
bool DoStep(int iStep)
wxBitmap & Bitmap(int iIndex)
Definition: Theme.cpp:1244
void AddUnits(const wxString &Prompt)
Left aligned text string.
Definition: ShuttleGui.cpp:260
void AddPrompt(const wxString &Prompt)
Right aligned text string.
Definition: ShuttleGui.cpp:239
wxTextCtrl * TieTextBox(const wxString &Prompt, const wxString &SettingName, const wxString &Default, const int nChars) override
ShuttleGuiBase & Prop(int iProp)
Definition: ShuttleGui.cpp:731
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
wxBitmapButton * AddBitmapButton(const wxBitmap &Bitmap, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:355
void EndVerticalLay()
wxTextCtrl * AddTextBox(const wxString &Caption, const wxString &Value, const int nChars)
Definition: ShuttleGui.cpp:540
wxCheckBox * AddCheckBox(const wxString &Prompt, const wxString &Selected)
Definition: ShuttleGui.cpp:298
void AddIcon(wxBitmap *pBmp)
Definition: ShuttleGui.cpp:718
wxSizer * mpSizer
Definition: ShuttleGui.h:358
wxScrolledWindow * StartScroller(int iStyle=0)
Definition: ShuttleGui.cpp:795
void WriteToAsString(const wxString &InStr)
wxWindow * GetParent()
Definition: ShuttleGui.h:294
bool * mpbOptionalFlag
Definition: ShuttleGui.h:355
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
wxGrid * AddGrid()
Definition: ShuttleGui.cpp:675
wxListCtrl * AddListControlReportMode()
Definition: ShuttleGui.cpp:689
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
wxChoice * AddChoice(const wxString &Prompt, const wxString &Selected, const wxArrayString *pChoices)
Definition: ShuttleGui.cpp:371
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:1079
ShuttleGui & Id(int id)
wxSlider * TieSlider(const wxString &Prompt, const wxString &SettingName, const int iDefault, const int max, const int min=0) override
bool ReadAsBool()
void UpdateSizersC()
wxWindow * mpParent
Definition: ShuttleGui.h:359
teShuttleMode
Definition: ShuttleGui.h:35
wxTextCtrl * TieNumericTextBox(const wxString &Prompt, WrappedType &WrappedRef, const int nChars)
void AddConstTextBox(const wxString &Caption, const wxString &Value)
Single line text box of fixed size.
Definition: ShuttleGui.cpp:629
void AddFixedText(const wxString &Str, bool bCenter=false)
Definition: ShuttleGui.cpp:397
int min(int a, int b)
Interface for objects that can receive (string) messages from a command.
void AddTitle(const wxString &Prompt)
Centred text string.
Definition: ShuttleGui.cpp:274
void StartField(const wxString &name="") override
ShuttleGuiBase(wxWindow *pParent, teShuttleMode ShuttleMode)
Definition: ShuttleGui.cpp:120
bool ValuesMatch(const WrappedType &W)
Definition: WrappedType.cpp:41
Base class for shuttling data to and from a GUI.
Definition: ShuttleGui.h:80
wxRadioButton * TieRadioButton(const wxString &Prompt, WrappedType &WrappedRef)
bool IsString()
Definition: WrappedType.cpp:34
void AddItem(const wxString &value, const wxString &name="") override
teShuttleMode mShuttleMode
Used in choices to determine which item to use on no match.
Definition: ShuttleGui.h:332
wxTextCtrl * TieNumericTextBox(const wxString &Prompt, const wxString &SettingName, const wxString &Default, const int nChars) override
wxWindow * mpWind
Definition: ShuttleGui.h:360
void UpdateSizersCore(bool bPrepend, int Flags)
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop")).Raw()), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom")).Raw()), OnMoveTrack)#define SET_TRACK_NAME_PLUGIN_SYMBOLclass SetTrackNameCommand:public AudacityCommand
wxComboBox * AddCombo(const wxString &Prompt, const wxString &Selected, const wxArrayString *pChoices, long style=0)
Definition: ShuttleGui.cpp:440
int mRadioCount
The setting controlled by a group.
Definition: ShuttleGui.h:336
wxChoice * TieChoice(const wxString &Prompt, const wxString &SettingName, const wxString &Default, const wxArrayString &Choices, const wxArrayString &InternalChoices) override
int miNoMatchSelector
Definition: ShuttleGui.h:330
virtual wxChoice * TieNumberAsChoice(const wxString &Prompt, const wxString &SettingName, const int Default, const wxArrayString &Choices, const std::vector< int > &InternalChoices)
void DoDataShuttle(const wxString &Name, WrappedType &WrappedRef)
wxCheckBox * TieCheckBox(const wxString &Prompt, WrappedType &WrappedRef)
void SetProportions(int Default)
wxTextCtrl * AddTextWindow(const wxString &Value)
Multiline text box that grows.
Definition: ShuttleGui.cpp:608
wxListBox * AddListBox(const wxArrayString *pChoices, long style=0)
Definition: ShuttleGui.cpp:646
AttachableScrollBar * AddAttachableScrollBar(long style=wxSB_HORIZONTAL)
wxMenuBar * mpMenuBar
Definition: ShuttleGui.h:361
wxWindow wxNotebookPage
Definition: ShuttleGui.h:62
wxSpinCtrl * TieSpinCtrl(const wxString &Prompt, const wxString &SettingName, const int Value, const int max, const int min) override
wxStaticText * AddVariableText(const wxString &Str, bool bCenter=false, int PositionFlags=0)
Definition: ShuttleGui.cpp:414
wxStaticBox * StartStatic(const wxString &Str, int iProp=0)
Definition: ShuttleGui.cpp:763
wxString mSettingName
Definition: ShuttleGui.h:335
wxWindow * mpLastWind
Definition: ShuttleGui.h:324
long Style(long Style)
wxRadioButton * AddRadioButtonToGroup(const wxString &Prompt)
Definition: ShuttleGui.cpp:484
wxNotebook * StartNotebook()
Definition: ShuttleGui.cpp:883
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxButton *extra=NULL)
END_EVENT_TABLE()
wxSizerItem * AddSpace(int width, int height)
void EndInvisiblePanel()
std::unique_ptr< wxSizer > mpSubSizer
Definition: ShuttleGui.h:357
wxNotebookPage * StartNotebookPage(const wxString &Name)
Definition: ShuttleGui.cpp:904
wxMenuBar * AddMenuBar()
Definition: ShuttleGui.cpp:737
wxSlider * TieVSlider(const wxString &Prompt, float &pos, const float fMin, const float fMax)
wxCheckBox * TieCheckBox(const wxString &Prompt, const wxString &SettingName, const bool bDefault) override
void StartRadioButtonGroup(const wxString &SettingName)
wxButton * AddButton(const wxString &Text, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:341
void SetStretchyCol(int i)
Used to modify an already placed FlexGridSizer to make a column stretchy.
Definition: ShuttleGui.cpp:203
wxRadioButton * AddRadioButton(const wxString &Prompt)
Definition: ShuttleGui.cpp:468
wxTextCtrl * TieTextBox(const wxString &Prompt, WrappedType &WrappedRef, const int nChars)
Used in type conversions, this wrapper for ints, strings, doubles and enums provides conversions betw...
Definition: WrappedType.h:31
void SetStretchyRow(int i)
Used to modify an already placed FlexGridSizer to make a row stretchy.
Definition: ShuttleGui.cpp:213
A Validator is an object which checks whether a wxVariant satisfies a certain criterion. This is a base validator which allows anything.
Definition: Validators.h:48
wxSlider * AddSlider(const wxString &Prompt, int pos, int Max, int Min=0)
Definition: ShuttleGui.cpp:497
void StartVerticalLay(int iProp=1)