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 "ShuttleGui.h"
98 
99 #include "MemoryX.h"
100 #include <wx/wx.h>
101 #include <wx/wxprec.h>
102 #include <wx/listctrl.h>
103 #include <wx/notebook.h>
104 #include <wx/treectrl.h>
105 #include <wx/spinctrl.h>
106 #include <wx/bmpbuttn.h>
107 #include "Internat.h"
108 #include "Experimental.h"
109 #include "Shuttle.h"
110 #include "WrappedType.h"
111 #include "widgets/wxPanelWrapper.h"
112 #include "AllThemeResources.h"
113 
114 ShuttleGuiBase::ShuttleGuiBase(wxWindow * pParent, teShuttleMode ShuttleMode )
115 {
116  wxASSERT( (pParent != NULL ) || ( ShuttleMode != eIsCreating));
117 
118  mpParent = pParent;
119  mShuttleMode = ShuttleMode;
120  mpDlg = pParent;
121  Init();
122 }
123 
125 {
126 }
127 
129 {
130  mpShuttle = NULL;
131  mpSizer = NULL;
132  mpWind = NULL;
133  mpSubSizer = NULL;
134 
135  mSettingName = wxT("");
136  mRadioCount = -1;
137 
138  miBorder = 5;
139  miStyle = 0;
140  miProp=0;
141  miPropSetByUser=-1;
142  miSizerProp=0;
143  mSizerDepth=-1;
144 
145  miIdSetByUser = -1;
146  miId = -1;
147  miIdNext = 3000;
148 
149  miNoMatchSelector = 0;
150 
151  if( mShuttleMode != eIsCreating )
152  return;
153 
154  mpSizer = mpParent->GetSizer();
155 
156 #if 0
157  if( mpSizer == NULL )
158  {
159  wxWindow * pGrandParent = mpParent->GetParent();
160  if( pGrandParent )
161  {
162  mpSizer = pGrandParent->GetSizer();
163  }
164  }
165 #endif
166 
167  if( !mpSizer )
168  {
169  mpParent->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
170  }
171  PushSizer();
172  mpSizer->SetMinSize(250,100);
173 }
174 
175 void ShuttleGuiBase::EnableCtrl( bool bEnable )
176 {
177  if( mShuttleMode != eIsCreating )
178  return;
179  mpLastWind->Enable( bEnable );
180 }
181 
183 void ShuttleGuiBase::SetSizeHints( int minX, int minY )
184 {
185  if( mShuttleMode != eIsCreating )
186  return;
187  mpLastWind->SetSizeHints( minX, minY );
188 }
189 
190 
193 {
194  if( mShuttleMode != eIsCreating )
195  return;
196  wxFlexGridSizer *pSizer = wxDynamicCast(mpSizer, wxFlexGridSizer);
197  wxASSERT( pSizer );
198  pSizer->AddGrowableCol( i, 1 );
199 }
200 
203 {
204  if( mShuttleMode != eIsCreating )
205  return;
206  wxFlexGridSizer *pSizer = wxDynamicCast(mpSizer, wxFlexGridSizer);
207  wxASSERT( pSizer );
208  pSizer->AddGrowableRow( i, 1 );
209 }
210 
211 
212 //---- Add Functions.
213 
215 void ShuttleGuiBase::AddPrompt(const wxString &Prompt)
216 {
217  if( Prompt.IsEmpty() )
218  return;
219  if( mShuttleMode != eIsCreating )
220  return;
221  miProp=1;
222  mpWind = safenew wxStaticText(GetParent(), -1, Prompt, wxDefaultPosition, wxDefaultSize,
223  Style( wxALIGN_RIGHT ));
224  mpWind->SetName(wxStripMenuCodes(Prompt)); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
225  UpdateSizersCore( false, wxALL | wxALIGN_CENTRE_VERTICAL );
226 }
227 
229 void ShuttleGuiBase::AddUnits(const wxString &Prompt)
230 {
231  if( Prompt.IsEmpty() )
232  return;
233  if( mShuttleMode != eIsCreating )
234  return;
235  miProp=1;
236  mpWind = safenew wxStaticText(GetParent(), -1, Prompt, wxDefaultPosition, wxDefaultSize,
237  Style( wxALIGN_LEFT ));
238  mpWind->SetName(Prompt); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
239  UpdateSizersCore( false, wxALL | wxALIGN_CENTRE_VERTICAL );
240 }
241 
243 void ShuttleGuiBase::AddTitle(const wxString &Prompt)
244 {
245  if( Prompt.IsEmpty() )
246  return;
247  if( mShuttleMode != eIsCreating )
248  return;
249  mpWind = safenew wxStaticText(GetParent(), -1, Prompt, wxDefaultPosition, wxDefaultSize,
250  Style( wxALIGN_CENTRE ));
251  mpWind->SetName(Prompt); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
252  UpdateSizers();
253 }
254 
257 wxWindow * ShuttleGuiBase::AddWindow(wxWindow * pWindow, int Flags )
258 {
259  if( mShuttleMode != eIsCreating )
260  return pWindow;
261  mpWind = pWindow;
262  SetProportions( 0 );
263  UpdateSizersCore(false, Flags);
264  return pWindow;
265 }
266 
267 wxCheckBox * ShuttleGuiBase::AddCheckBox( const wxString &Prompt, const wxString &Selected)
268 {
269  UseUpId();
270  if( mShuttleMode != eIsCreating )
271  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxCheckBox);
272  wxCheckBox * pCheckBox;
273  miProp=0;
274  mpWind = pCheckBox = safenew wxCheckBox(GetParent(), miId, Prompt, wxDefaultPosition, wxDefaultSize,
275  Style( 0 ));
276  pCheckBox->SetValue(Selected == wxT("true"));
277  pCheckBox->SetName(wxStripMenuCodes(Prompt));
278  UpdateSizers();
279  return pCheckBox;
280 }
281 
285 wxCheckBox * ShuttleGuiBase::AddCheckBoxOnRight( const wxString &Prompt, const wxString &Selected)
286 {
287  UseUpId();
288  if( mShuttleMode != eIsCreating )
289  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxCheckBox);
290  wxCheckBox * pCheckBox;
291  miProp=0;
292  AddPrompt( Prompt );
293  mpWind = pCheckBox = safenew wxCheckBox(GetParent(), miId, wxT(""), wxDefaultPosition, wxDefaultSize,
294  Style( 0 ));
295  pCheckBox->SetValue(Selected==wxT("true"));
296  pCheckBox->SetName(wxStripMenuCodes(Prompt));
297  UpdateSizers();
298  return pCheckBox;
299 }
300 
301 wxButton * ShuttleGuiBase::AddButton(const wxString &Text, int PositionFlags)
302 {
303  UseUpId();
304  if( mShuttleMode != eIsCreating )
305  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxButton);
306  wxButton * pBtn;
307  mpWind = pBtn = safenew wxButton(GetParent(), miId, Text, wxDefaultPosition, wxDefaultSize,
308  Style( 0 ) );
309  mpWind->SetName(wxStripMenuCodes(Text));
310  miProp=0;
311  UpdateSizersCore(false, PositionFlags | wxALL);
312  return pBtn;
313 }
314 
315 wxBitmapButton * ShuttleGuiBase::AddBitmapButton(const wxBitmap &Bitmap, int PositionFlags)
316 {
317  UseUpId();
318  if( mShuttleMode != eIsCreating )
319  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxBitmapButton);
320  wxBitmapButton * pBtn;
321  mpWind = pBtn = safenew wxBitmapButton(GetParent(), miId, Bitmap,
322  wxDefaultPosition, wxDefaultSize, Style( wxNO_BORDER ) );
323  pBtn->SetBackgroundColour(
324  wxColour( 246,246,243));
325 // wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
326  miProp=0;
327  UpdateSizersCore(false, PositionFlags | wxALL);
328  return pBtn;
329 }
330 
331 wxChoice * ShuttleGuiBase::AddChoice( const wxString &Prompt, const wxString &Selected, const wxArrayString * pChoices )
332 {
333  UseUpId();
334  if( mShuttleMode != eIsCreating )
335  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxChoice);
336  wxChoice * pChoice;
337  miProp=0;
338 
339  AddPrompt( Prompt );
340  mpWind = pChoice = safenew wxChoice(
341  GetParent(),
342  miId,
343  wxDefaultPosition,
344  wxDefaultSize,
345  *pChoices,
346  Style( 0 ) );
347 
348  pChoice->SetSizeHints( 180,-1);// Use -1 for 'default size' - Platform specific.
349  pChoice->SetName(wxStripMenuCodes(Prompt));
350  pChoice->SetStringSelection( Selected );
351 
352  UpdateSizers();
353  return pChoice;
354 }
355 
356 void ShuttleGuiBase::AddFixedText(const wxString &Str, bool bCenter)
357 {
358  UseUpId();
359  if( mShuttleMode != eIsCreating )
360  return;
361  mpWind = safenew wxStaticText(GetParent(), miId, Str, wxDefaultPosition, wxDefaultSize,
362  Style( wxALIGN_LEFT ));
363  mpWind->SetName(wxStripMenuCodes(Str)); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
364  if( bCenter )
365  {
366  miProp=1;
367  UpdateSizersC();
368  }
369  else
370  UpdateSizers();
371 }
372 
373 wxStaticText * ShuttleGuiBase::AddVariableText(const wxString &Str, bool bCenter, int PositionFlags)
374 {
375  UseUpId();
376  if( mShuttleMode != eIsCreating )
377  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxStaticText);
378 
379  wxStaticText *pStatic;
380  mpWind = pStatic = safenew wxStaticText(GetParent(), miId, Str, wxDefaultPosition, wxDefaultSize,
381  Style( wxALIGN_LEFT ));
382  mpWind->SetName(wxStripMenuCodes(Str)); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
383  if( bCenter )
384  {
385  miProp=1;
386  if( PositionFlags )
387  UpdateSizersCore( false, PositionFlags );
388  else
389  UpdateSizersC();
390  }
391  else
392  if( PositionFlags )
393  UpdateSizersCore( false, PositionFlags );
394  else
395  UpdateSizers();
396  return pStatic;
397 }
398 
399 wxComboBox * ShuttleGuiBase::AddCombo( const wxString &Prompt, const wxString &Selected,const wxArrayString * pChoices, long style )
400 {
401  UseUpId();
402  if( mShuttleMode != eIsCreating )
403  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxComboBox);
404  wxComboBox * pCombo;
405  miProp=0;
406 
407  int n = pChoices->GetCount();
408  if( n>50 ) n=50;
409  int i;
410  wxString Choices[50];
411  for(i=0;i<n;i++)
412  {
413  Choices[i] = (*pChoices)[i];
414  }
415 
416  AddPrompt( Prompt );
417 
418  mpWind = pCombo = safenew wxComboBox(GetParent(), miId, Selected, wxDefaultPosition, wxDefaultSize,
419  n, Choices, Style( style ));
420  mpWind->SetName(wxStripMenuCodes(Prompt));
421 
422  UpdateSizers();
423  return pCombo;
424 }
425 
426 
427 wxRadioButton * ShuttleGuiBase::AddRadioButton(const wxString &Prompt)
428 {
431  UseUpId();
432  if( mShuttleMode != eIsCreating )
433  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxRadioButton);
434  wxRadioButton * pRad;
435  mpWind = pRad = safenew wxRadioButton(GetParent(), miId, Prompt,
436  wxDefaultPosition, wxDefaultSize, Style( wxRB_GROUP ) );
437  mpWind->SetName(wxStripMenuCodes(Prompt));
438  pRad->SetValue(true );
439  UpdateSizers();
440  return pRad;
441 }
442 
443 wxRadioButton * ShuttleGuiBase::AddRadioButtonToGroup(const wxString &Prompt)
444 {
445  UseUpId();
446  if( mShuttleMode != eIsCreating )
447  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxRadioButton);
448  wxRadioButton * pRad;
449  mpWind = pRad = safenew wxRadioButton(GetParent(), miId, Prompt,
450  wxDefaultPosition, wxDefaultSize, Style( 0 ) );
451  mpWind->SetName(wxStripMenuCodes(Prompt));
452  UpdateSizers();
453  return pRad;
454 }
455 
456 wxSlider * ShuttleGuiBase::AddSlider(const wxString &Prompt, int pos, int Max, int Min)
457 {
458  UseUpId();
459  if( mShuttleMode != eIsCreating )
460  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxSlider);
461  AddPrompt( Prompt );
462  wxSlider * pSlider;
463  mpWind = pSlider = safenew wxSlider(GetParent(), miId,
464  pos, Min, Max,
465  wxDefaultPosition, wxDefaultSize,
466  Style( wxSL_HORIZONTAL | wxSL_LABELS | wxSL_AUTOTICKS )
467  );
468  mpWind->SetName(wxStripMenuCodes(Prompt));
469  miProp=1;
470  UpdateSizers();
471  return pSlider;
472 }
473 
474 wxSpinCtrl * ShuttleGuiBase::AddSpinCtrl(const wxString &Prompt, int Value, int Max, int Min)
475 {
476  UseUpId();
477  if( mShuttleMode != eIsCreating )
478  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxSpinCtrl);
479  AddPrompt( Prompt );
480  wxSpinCtrl * pSpinCtrl;
481  mpWind = pSpinCtrl = safenew wxSpinCtrl(GetParent(), miId,
482  wxEmptyString,
483  wxDefaultPosition, wxDefaultSize,
484  Style( wxSP_VERTICAL | wxSP_ARROW_KEYS ),
485  Min, Max, Value
486  );
487  mpWind->SetName(wxStripMenuCodes(Prompt));
488  miProp=1;
489  UpdateSizers();
490  return pSpinCtrl;
491 }
492 
493 wxTextCtrl * ShuttleGuiBase::AddTextBox(const wxString &Caption, const wxString &Value, const int nChars)
494 {
495  UseUpId();
496  if( mShuttleMode != eIsCreating )
497  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTextCtrl);
498  wxTextCtrl * pTextCtrl;
499  wxSize Size(wxDefaultSize);
500  if( nChars > 0 )
501  {
502  Size.SetWidth( nChars *5 );
503  }
504  AddPrompt( Caption );
505  miProp=0;
506 
507 #ifdef EXPERIMENTAL_RIGHT_ALIGNED_TEXTBOXES
508  long flags = wxTE_RIGHT;
509 #else
510  long flags = wxTE_LEFT;
511 #endif
512 
513  mpWind = pTextCtrl = safenew wxTextCtrl(GetParent(), miId, Value,
514  wxDefaultPosition, Size, Style( flags ));
515  mpWind->SetName(wxStripMenuCodes(Caption));
516  UpdateSizers();
517  return pTextCtrl;
518 }
519 
520 wxTextCtrl * ShuttleGuiBase::AddNumericTextBox(const wxString &Caption, const wxString &Value, const int nChars)
521 {
522  UseUpId();
523  if( mShuttleMode != eIsCreating )
524  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTextCtrl);
525  wxTextCtrl * pTextCtrl;
526  wxSize Size(wxDefaultSize);
527  if( nChars > 0 )
528  {
529  Size.SetWidth( nChars *5 );
530  }
531  AddPrompt( Caption );
532  miProp=0;
533 
534 #ifdef EXPERIMENTAL_RIGHT_ALIGNED_TEXTBOXES
535  long flags = wxTE_RIGHT;
536 #else
537  long flags = wxTE_LEFT;
538 #endif
539 
540  wxTextValidator Validator(wxFILTER_NUMERIC);
541  mpWind = pTextCtrl = safenew wxTextCtrl(GetParent(), miId, Value,
542  wxDefaultPosition, Size, Style( flags ),
543  Validator // It's OK to pass this. It will be cloned.
544  );
545  mpWind->SetName(wxStripMenuCodes(Caption));
546  UpdateSizers();
547  return pTextCtrl;
548 }
549 
551 wxTextCtrl * ShuttleGuiBase::AddTextWindow(const wxString &Value)
552 {
553  UseUpId();
554  if( mShuttleMode != eIsCreating )
555  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTextCtrl);
556  wxTextCtrl * pTextCtrl;
557  SetProportions( 1 );
558  mpWind = pTextCtrl = safenew wxTextCtrl(GetParent(), miId, Value,
559  wxDefaultPosition, wxDefaultSize, Style( wxTE_MULTILINE ));
560  UpdateSizers();
561  // Start off at start of window...
562  pTextCtrl->SetInsertionPoint( 0 );
563  pTextCtrl->ShowPosition( 0 );
564  return pTextCtrl;
565 }
566 
568 void ShuttleGuiBase::AddConstTextBox(const wxString &Prompt, const wxString &Value)
569 {
570  UseUpId();
571  if( mShuttleMode != eIsCreating )
572  return;
573 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wx);
574  miProp=0;
575  AddPrompt( Prompt );
576  UpdateSizers();
577  miProp=0;
578  mpWind = safenew wxStaticText(GetParent(), miId, Value, wxDefaultPosition, wxDefaultSize,
579  Style( 0 ));
580  mpWind->SetName(Value); // fix for bug 577 (NVDA/Narrator screen readers do not read static text in dialogs)
581  UpdateSizers();
582 }
583 
584 wxListBox * ShuttleGuiBase::AddListBox(const wxArrayString * pChoices, long style)
585 {
586  UseUpId();
587  if( mShuttleMode != eIsCreating )
588  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxListBox);
589  wxListBox * pListBox;
590  SetProportions( 1 );
591  mpWind = pListBox = safenew wxListBox(GetParent(), miId,
592  wxDefaultPosition, wxDefaultSize,*pChoices, style);
593  pListBox->SetMinSize( wxSize( 120,150 ));
594  UpdateSizers();
595  return pListBox;
596 }
597 
598 
600 {
601  UseUpId();
602  if( mShuttleMode != eIsCreating )
603  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxListCtrl);
604  wxListCtrl * pListCtrl;
605  SetProportions( 1 );
606  mpWind = pListCtrl = safenew wxListCtrl(GetParent(), miId,
607  wxDefaultPosition, wxDefaultSize, Style( wxLC_ICON ));
608  pListCtrl->SetMinSize( wxSize( 120,150 ));
609  UpdateSizers();
610  return pListCtrl;
611 }
612 
614 {
615  UseUpId();
616  if( mShuttleMode != eIsCreating )
617  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxGrid);
618  wxGrid * pGrid;
619  SetProportions( 1 );
620  mpWind = pGrid = safenew wxGrid(GetParent(), miId, wxDefaultPosition,
621  wxDefaultSize, Style( wxWANTS_CHARS ));
622  pGrid->SetMinSize( wxSize( 120, 150 ));
623  UpdateSizers();
624  return pGrid;
625 }
626 
628 {
629  UseUpId();
630  if( mShuttleMode != eIsCreating )
631  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxListCtrl);
632  wxListCtrl * pListCtrl;
633  SetProportions( 1 );
634  mpWind = pListCtrl = safenew wxListCtrl(GetParent(), miId,
635  wxDefaultPosition, wxSize(230,120),//wxDefaultSize,
636  Style( wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxSUNKEN_BORDER ));
637 // pListCtrl->SetMinSize( wxSize( 120,150 ));
638  UpdateSizers();
639  return pListCtrl;
640 }
641 
643 {
644  UseUpId();
645  if( mShuttleMode != eIsCreating )
646  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxTreeCtrl);
647  wxTreeCtrl * pTreeCtrl;
648  SetProportions( 1 );
649  mpWind = pTreeCtrl = safenew wxTreeCtrl(GetParent(), miId, wxDefaultPosition, wxDefaultSize,
650  Style( wxTR_HAS_BUTTONS ));
651  pTreeCtrl->SetMinSize( wxSize( 120,650 ));
652  UpdateSizers();
653  return pTreeCtrl;
654 }
655 
656 void ShuttleGuiBase::AddIcon(wxBitmap *pBmp)
657 {
658  UseUpId();
659  if( mShuttleMode != eIsCreating )
660 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wx);
661  return;
662  wxBitmapButton * pBtn;
663  mpWind = pBtn = safenew wxBitmapButton(GetParent(), miId, *pBmp,
664  wxDefaultPosition, wxDefaultSize, Style( wxBU_AUTODRAW ) );
665  pBtn->SetWindowStyle( 0 );
666  UpdateSizersC();
667 }
668 
670 {
671  miPropSetByUser = iProp;
672  return *this;
673 }
674 
676 {
677  auto menuBar = std::make_unique<wxMenuBar>();
678  mpMenuBar = menuBar.get();
679 
680  wxFrame * pFrame = (wxFrame*)mpParent;
681  pFrame->SetThemeEnabled( true );
682  mpMenuBar->SetThemeEnabled( true );
683  pFrame->SetMenuBar(menuBar.release());
684 
685  return mpMenuBar;
686 }
687 
688 wxMenu * ShuttleGuiBase::AddMenu( const wxString & Title )
689 {
690  mpMenuBar->Append( (mpMenu = safenew wxMenu), Title );
691  return mpMenu;
692 }
693 
694 
695 
701 wxStaticBox * ShuttleGuiBase::StartStatic(const wxString &Str, int iProp)
702 {
703  UseUpId();
704  if( mShuttleMode != eIsCreating )
705  return NULL;
706  wxStaticBox * pBox = safenew wxStaticBox(GetParent(), miId,
707  Str );
708  pBox->SetLabel( Str );
709  pBox->SetName(wxStripMenuCodes(Str));
710  mpSubSizer = std::make_unique<wxStaticBoxSizer>(
711  pBox,
712  wxVERTICAL );
713  miSizerProp = iProp;
714  UpdateSizers();
715  return pBox;
716 }
717 
719 {
720  if( mShuttleMode != eIsCreating )
721  return;
722  PopSizer();
723 }
724 
733 wxScrolledWindow * ShuttleGuiBase::StartScroller(int iStyle)
734 {
735  UseUpId();
736  if( mShuttleMode != eIsCreating )
737  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxScrolledWindow);
738 
739  wxScrolledWindow * pScroller;
740  mpWind = pScroller = safenew wxScrolledWindow(GetParent(), miId, wxDefaultPosition, wxDefaultSize,
741  Style( wxSUNKEN_BORDER ) );
742  pScroller->SetScrollRate( 20,20 );
743 
744  // This fools NVDA into not saying "Panel" when the dialog gets focus
745  pScroller->SetName(wxT("\a"));
746  pScroller->SetLabel(wxT("\a"));
747 
748  SetProportions( 1 );
749  if( iStyle==2 )
750  {
752  }
753  else
754  {
755  mpWind->SetBackgroundColour(
756  iStyle==0
757  ? wxColour( 245,244,240) :
758  wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)
759  );
760  UpdateSizers(); // adds window in to current sizer.
761  }
762 
763  // create a sizer within the window...
764  mpParent = pScroller;
765  pScroller->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
766  PushSizer();
767  return pScroller;
768 }
769 
771 {
772  if( mShuttleMode != eIsCreating )
773  return;
774  wxSize ScrollSize = mpSizer->GetMinSize();
775  int yMin = ScrollSize.y+4;
776  int xMin = ScrollSize.x+4;
777  if( yMin > 400)
778  {
779  yMin = 400;
780  xMin+=50;// extra space for vertical scrollbar.
781  }
782 
783  mpParent->SetMinSize( wxSize(xMin, yMin) );
784 
785  PopSizer();
786  mpParent = mpParent->GetParent();
787 }
788 
789 wxPanel * ShuttleGuiBase::StartPanel(int iStyle)
790 {
791  UseUpId();
792  if( mShuttleMode != eIsCreating )
793  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxPanel);
794  wxPanel * pPanel;
795  mpWind = pPanel = safenew wxPanelWrapper( GetParent(), miId, wxDefaultPosition, wxDefaultSize,
796  Style( wxNO_BORDER ));
797 
798  if( iStyle != 0 )
799  {
800  mpWind->SetBackgroundColour(
801  iStyle==1
802  ? wxColour( 190,200,230) :
803  wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)
804  );
805  }
806  SetProportions(0);
807  miBorder=2;
808  UpdateSizers(); // adds window in to current sizer.
809 
810  // create a sizer within the window...
811  mpParent = pPanel;
812  pPanel->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
813  PushSizer();
814  return pPanel;
815 }
816 
818 {
819  if( mShuttleMode != eIsCreating )
820  return;
821  PopSizer();
822  mpParent = mpParent->GetParent();
823 }
824 
826 {
827  UseUpId();
828  if( mShuttleMode != eIsCreating )
829  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxNotebook);
830  wxNotebook * pNotebook;
831  mpWind = pNotebook = safenew wxNotebook(GetParent(),
832  miId, wxDefaultPosition, wxDefaultSize, Style( 0 ));
833  SetProportions( 1 );
834  UpdateSizers();
835  mpParent = pNotebook;
836  return pNotebook;
837 }
838 
840 {
841  //PopSizer();
842  mpParent = mpParent->GetParent();
843 }
844 
845 
847 {
848  if( mShuttleMode != eIsCreating )
849  return NULL;
850 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wx);
851  wxNotebook * pNotebook = (wxNotebook*)mpParent;
853  pPage->SetName(Name);
854 
855  pNotebook->AddPage(
856  pPage,
857  Name);
858  PushSizer();
859 
860  SetProportions( 1 );
861  mpParent = pPage;
862  pPage->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
863  mpSizer->SetMinSize(250, 500);
864  // UpdateSizers();
865  return pPage;
866 }
867 
868 void ShuttleGuiBase::StartNotebookPage( const wxString & Name, wxNotebookPage * pPage )
869 {
870  if( mShuttleMode != eIsCreating )
871  return;
872 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wx);
873  wxNotebook * pNotebook = (wxNotebook*)mpParent;
874 // wxNotebookPage * pPage = safenew wxPanelWrapper(GetParent());
875  pPage->Create( mpParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, wxT("panel"));
876  pPage->SetName(Name);
877 
878  pNotebook->AddPage(
879  pPage,
880  Name);
881  PushSizer();
882 
883  SetProportions( 1 );
884  mpParent = pPage;
885  pPage->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
886  mpSizer->SetMinSize(250, 500);
887  // UpdateSizers();
888 }
889 
891 {
892  if( mShuttleMode != eIsCreating )
893  return;
894  PopSizer();
895  mpParent = mpParent->GetParent();
896 }
897 
898 // Doxygen description is at the start of the file
899 // this is a wxPanel with erase background disabled.
900 class InvisiblePanel final : public wxPanelWrapper
901 {
902 public:
904  wxWindow* parent,
905  wxWindowID id = -1,
906  const wxPoint& pos = wxDefaultPosition,
907  const wxSize& size = wxDefaultSize,
908  long style = wxTAB_TRAVERSAL ) :
909  wxPanelWrapper( parent, id, pos, size, style )
910  {
911  };
913  void OnPaint( wxPaintEvent &event );
914  void OnErase(wxEraseEvent &/*evt*/){;};
915  DECLARE_EVENT_TABLE()
916 };
917 
918 
919 BEGIN_EVENT_TABLE(InvisiblePanel, wxPanelWrapper)
920 // EVT_PAINT(InvisiblePanel::OnPaint)
921  EVT_ERASE_BACKGROUND( InvisiblePanel::OnErase)
923 
924 void InvisiblePanel::OnPaint( wxPaintEvent & WXUNUSED(event))
925 {
926  // Don't repaint my background.
927  wxPaintDC dc(this);
928  // event.Skip(); // swallow the paint event.
929 }
930 
932 {
933  UseUpId();
934  if( mShuttleMode != eIsCreating )
935  return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), wxPanel);
936  wxPanel * pPanel;
937  mpWind = pPanel = safenew wxPanelWrapper(GetParent(), miId, wxDefaultPosition, wxDefaultSize,
938  wxNO_BORDER);
939 
940  mpWind->SetBackgroundColour(
941  wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)
942  );
943  SetProportions( 1 );
944  miBorder=0;
945  UpdateSizers(); // adds window in to current sizer.
946 
947  // create a sizer within the window...
948  mpParent = pPanel;
949  pPanel->SetSizer(mpSizer = safenew wxBoxSizer(wxVERTICAL));
950  PushSizer();
951  return pPanel;
952 }
953 
955 {
956  EndPanel();
957 }
958 
959 
966 void ShuttleGuiBase::StartHorizontalLay( int PositionFlags, int iProp)
967 {
968  if( mShuttleMode != eIsCreating )
969  return;
970  miSizerProp=iProp;
971  mpSubSizer = std::make_unique<wxBoxSizer>( wxHORIZONTAL );
972  UpdateSizersCore( false, PositionFlags | wxALL );
973 }
974 
976 {
977  if( mShuttleMode != eIsCreating )
978  return;
979  PopSizer();
980 }
981 
983 {
984  if( mShuttleMode != eIsCreating )
985  return;
986  miSizerProp=iProp;
987  mpSubSizer = std::make_unique<wxBoxSizer>( wxVERTICAL );
988  UpdateSizers();
989 }
990 
992 {
993  if( mShuttleMode != eIsCreating )
994  return;
995  PopSizer();
996 }
997 
998 void ShuttleGuiBase::StartMultiColumn(int nCols, int PositionFlags)
999 {
1000  if( mShuttleMode != eIsCreating )
1001  return;
1002  mpSubSizer = std::make_unique<wxFlexGridSizer>( nCols );
1003  UpdateSizersCore( false, PositionFlags | wxALL );
1004 }
1005 
1007 {
1008  if( mShuttleMode != eIsCreating )
1009  return;
1010  PopSizer();
1011 }
1012 
1015 void ShuttleGuiBase::DoDataShuttle( const wxString &Name, WrappedType & WrappedRef )
1016 {
1017  wxASSERT( mpShuttle );
1018  mpShuttle->TransferWrappedType( Name, WrappedRef );
1019 }
1020 
1021 //-----------------------------------------------------------------------//
1022 
1023 // We now have a group of tie functions which are generic in the type
1024 // they bind to (i.e. WrappedType).
1025 // The type specific versions are much shorter and are later
1026 // in this file.
1027 wxCheckBox * ShuttleGuiBase::TieCheckBox(const wxString &Prompt, WrappedType & WrappedRef)
1028 {
1029  // The Add function does a UseUpId(), so don't do it here in that case.
1030  if( mShuttleMode == eIsCreating )
1031  return AddCheckBox( Prompt, WrappedRef.ReadAsString());
1032 
1033  UseUpId();
1034 
1035  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1036  wxCheckBox * pCheckBox = wxDynamicCast(pWnd, wxCheckBox);
1037 
1038  switch( mShuttleMode )
1039  {
1040  // IF setting internal storage from the controls.
1041  case eIsGettingFromDialog:
1042  {
1043  wxASSERT( pCheckBox );
1044  WrappedRef.WriteToAsBool( pCheckBox->GetValue() );
1045  }
1046  break;
1047  case eIsSettingToDialog:
1048  {
1049  wxASSERT( pCheckBox );
1050  pCheckBox->SetValue( WrappedRef.ReadAsBool() );
1051  }
1052  break;
1053  // IF Saving settings to external storage...
1054  // or IF Getting settings from external storage.
1055  case eIsSavingViaShuttle:
1056  case eIsGettingViaShuttle:
1057  DoDataShuttle( Prompt, WrappedRef );
1058  break;
1059  default:
1060  wxASSERT( false );
1061  break;
1062  }
1063  return pCheckBox;
1064 }
1065 
1066 wxCheckBox * ShuttleGuiBase::TieCheckBoxOnRight(const wxString &Prompt, WrappedType & WrappedRef)
1067 {
1068  // The Add function does a UseUpId(), so don't do it here in that case.
1069  if( mShuttleMode == eIsCreating )
1070  return AddCheckBoxOnRight( Prompt, WrappedRef.ReadAsString());
1071 
1072  UseUpId();
1073 
1074  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1075  wxCheckBox * pCheckBox = wxDynamicCast(pWnd, wxCheckBox);
1076 
1077  switch( mShuttleMode )
1078  {
1079  // IF setting internal storage from the controls.
1080  case eIsGettingFromDialog:
1081  {
1082  wxASSERT( pCheckBox );
1083  WrappedRef.WriteToAsBool( pCheckBox->GetValue() );
1084  }
1085  break;
1086  case eIsSettingToDialog:
1087  {
1088  wxASSERT( pCheckBox );
1089  pCheckBox->SetValue( WrappedRef.ReadAsBool() );
1090  }
1091  break;
1092  // IF Saving settings to external storage...
1093  // or IF Getting settings from external storage.
1094  case eIsSavingViaShuttle:
1095  case eIsGettingViaShuttle:
1096  DoDataShuttle( Prompt, WrappedRef );
1097  break;
1098  default:
1099  wxASSERT( false );
1100  break;
1101  }
1102  return pCheckBox;
1103 }
1104 
1105 wxSpinCtrl * ShuttleGuiBase::TieSpinCtrl( const wxString &Prompt, WrappedType & WrappedRef, const int max, const int min )
1106 {
1107  // The Add function does a UseUpId(), so don't do it here in that case.
1108  if( mShuttleMode == eIsCreating )
1109  return AddSpinCtrl( Prompt, WrappedRef.ReadAsInt(), max, min );
1110 
1111  UseUpId();
1112  wxSpinCtrl * pSpinCtrl=NULL;
1113 
1114  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1115  pSpinCtrl = wxDynamicCast(pWnd, wxSpinCtrl);
1116 
1117  switch( mShuttleMode )
1118  {
1119  // IF setting internal storage from the controls.
1120  case eIsGettingFromDialog:
1121  {
1122  wxASSERT( pSpinCtrl );
1123  WrappedRef.WriteToAsInt( pSpinCtrl->GetValue() );
1124  }
1125  break;
1126  case eIsSettingToDialog:
1127  {
1128  wxASSERT( pSpinCtrl );
1129  pSpinCtrl->SetValue( WrappedRef.ReadAsInt() );
1130  }
1131  break;
1132  // IF Saving settings to external storage...
1133  // or IF Getting settings from external storage.
1134  case eIsGettingViaShuttle:
1135  case eIsSavingViaShuttle:
1136  DoDataShuttle( Prompt, WrappedRef );
1137  break;
1138  default:
1139  wxASSERT( false );
1140  break;
1141  }
1142  return pSpinCtrl;
1143 }
1144 
1145 wxTextCtrl * ShuttleGuiBase::TieTextBox( const wxString &Prompt, WrappedType & WrappedRef, const int nChars)
1146 {
1147  // The Add function does a UseUpId(), so don't do it here in that case.
1148  if( mShuttleMode == eIsCreating )
1149  return AddTextBox( Prompt, WrappedRef.ReadAsString(), nChars );
1150 
1151  UseUpId();
1152  wxTextCtrl * pTextBox=NULL;
1153 
1154  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1155  pTextBox = wxDynamicCast(pWnd, wxTextCtrl);
1156 
1157  switch( mShuttleMode )
1158  {
1159  // IF setting internal storage from the controls.
1160  case eIsGettingFromDialog:
1161  {
1162  wxASSERT( pTextBox );
1163  WrappedRef.WriteToAsString( pTextBox->GetValue() );
1164  }
1165  break;
1166  case eIsSettingToDialog:
1167  {
1168  wxASSERT( pTextBox );
1169  pTextBox->SetValue( WrappedRef.ReadAsString() );
1170  }
1171  break;
1172  // IF Saving settings to external storage...
1173  // or IF Getting settings from external storage.
1174  case eIsGettingViaShuttle:
1175  case eIsSavingViaShuttle:
1176  DoDataShuttle( Prompt, WrappedRef );
1177  break;
1178  default:
1179  wxASSERT( false );
1180  break;
1181  }
1182  return pTextBox;
1183 }
1184 
1185 wxTextCtrl * ShuttleGuiBase::TieNumericTextBox( const wxString &Prompt, WrappedType & WrappedRef, const int nChars)
1186 {
1187  // The Add function does a UseUpId(), so don't do it here in that case.
1188  if( mShuttleMode == eIsCreating )
1189  return AddNumericTextBox( Prompt, WrappedRef.ReadAsString(), nChars );
1190 
1191  UseUpId();
1192  wxTextCtrl * pTextBox=NULL;
1193 
1194  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1195  pTextBox = wxDynamicCast(pWnd, wxTextCtrl);
1196 
1197  switch( mShuttleMode )
1198  {
1199  // IF setting internal storage from the controls.
1200  case eIsGettingFromDialog:
1201  {
1202  wxASSERT( pTextBox );
1203  WrappedRef.WriteToAsString( pTextBox->GetValue() );
1204  }
1205  break;
1206  case eIsSettingToDialog:
1207  {
1208  wxASSERT( pTextBox );
1209  pTextBox->SetValue( WrappedRef.ReadAsString() );
1210  }
1211  break;
1212  // IF Saving settings to external storage...
1213  // or IF Getting settings from external storage.
1214  case eIsGettingViaShuttle:
1215  case eIsSavingViaShuttle:
1216  DoDataShuttle( Prompt, WrappedRef );
1217  break;
1218  default:
1219  wxASSERT( false );
1220  break;
1221  }
1222  return pTextBox;
1223 }
1224 
1225 wxSlider * ShuttleGuiBase::TieSlider( const wxString &Prompt, WrappedType & WrappedRef, const int max, int min )
1226 {
1227  // The Add function does a UseUpId(), so don't do it here in that case.
1228  if( mShuttleMode != eIsCreating )
1229  UseUpId();
1230  wxSlider * pSlider=NULL;
1231  switch( mShuttleMode )
1232  {
1233  case eIsCreating:
1234  {
1235  pSlider = AddSlider( Prompt, WrappedRef.ReadAsInt(), max, min );
1236  }
1237  break;
1238  // IF setting internal storage from the controls.
1239  case eIsGettingFromDialog:
1240  {
1241  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1242  pSlider = wxDynamicCast(pWnd, wxSlider);
1243  wxASSERT( pSlider );
1244  WrappedRef.WriteToAsInt( pSlider->GetValue() );
1245  }
1246  break;
1247  case eIsSettingToDialog:
1248  {
1249  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1250  pSlider = wxDynamicCast(pWnd, wxSlider);
1251  wxASSERT( pSlider );
1252  pSlider->SetValue( WrappedRef.ReadAsInt() );
1253  }
1254  break;
1255  // IF Saving settings to external storage...
1256  // or IF Getting settings from external storage.
1257  case eIsSavingViaShuttle:
1258  case eIsGettingViaShuttle:
1259  DoDataShuttle( Prompt, WrappedRef );
1260  break;
1261  default:
1262  wxASSERT( false );
1263  break;
1264  }
1265  return pSlider;
1266 }
1267 
1268 
1270  const wxString &Prompt,
1271  WrappedType &WrappedRef,
1272  const wxArrayString * pChoices )
1273 {
1274  // The Add function does a UseUpId(), so don't do it here in that case.
1275  if( mShuttleMode != eIsCreating )
1276  UseUpId();
1277  wxChoice * pChoice=NULL;
1278  switch( mShuttleMode )
1279  {
1280  case eIsCreating:
1281  {
1282  if( WrappedRef.IsString() )
1283  pChoice = AddChoice( Prompt, WrappedRef.ReadAsString(), pChoices );
1284  else
1285  {
1286  wxString Temp;
1287  if( pChoices && ( WrappedRef.ReadAsInt() < (int)pChoices->GetCount() ) )
1288  {
1289  Temp = (*pChoices)[WrappedRef.ReadAsInt()];
1290  }
1291  pChoice = AddChoice( Prompt, Temp, pChoices );
1292  }
1293  }
1294  break;
1295  // IF setting internal storage from the controls.
1296  case eIsGettingFromDialog:
1297  {
1298  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1299  pChoice = wxDynamicCast(pWnd, wxChoice);
1300  wxASSERT( pChoice );
1301  if( WrappedRef.IsString())
1302  WrappedRef.WriteToAsString( pChoice->GetStringSelection());
1303  else
1304  WrappedRef.WriteToAsInt( pChoice->GetSelection() );
1305  }
1306  break;
1307  case eIsSettingToDialog:
1308  {
1309  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1310  pChoice = wxDynamicCast(pWnd, wxChoice);
1311  wxASSERT( pChoice );
1312  if( WrappedRef.IsString() )
1313  pChoice->SetStringSelection( WrappedRef.ReadAsString() );
1314  else
1315  pChoice->SetSelection( WrappedRef.ReadAsInt() );
1316  }
1317  break;
1318  // IF Saving settings to external storage...
1319  // or IF Getting settings from external storage.
1320  case eIsSavingViaShuttle:
1321  case eIsGettingViaShuttle:
1322  DoDataShuttle( Prompt, WrappedRef );
1323  break;
1324  default:
1325  wxASSERT( false );
1326  break;
1327  }
1328  return pChoice;
1329 }
1330 
1331 wxRadioButton * ShuttleGuiBase::TieRadioButton(const wxString &Prompt, WrappedType & WrappedRef)
1332 {
1333  wxASSERT( mRadioCount >= 0); // Did you remember to use StartRadioButtonGroup() ?
1334  mRadioCount++;
1335  UseUpId();
1336  wxRadioButton * pRadioButton = NULL;
1337 
1338  switch( mShuttleMode )
1339  {
1340  case eIsCreating:
1341  {
1342  mpWind = pRadioButton = safenew wxRadioButton(GetParent(), miId, Prompt,
1343  wxDefaultPosition, wxDefaultSize,
1344  (mRadioCount==1)?wxRB_GROUP:0);
1345  pRadioButton->SetValue(WrappedRef.ValuesMatch( mRadioValue ));
1346  pRadioButton->SetName(wxStripMenuCodes(Prompt));
1347  UpdateSizers();
1348  }
1349  break;
1350  case eIsGettingFromDialog:
1351  {
1352  wxWindow * pWnd = wxWindow::FindWindowById( miId, mpDlg);
1353  pRadioButton = wxDynamicCast(pWnd, wxRadioButton);
1354  wxASSERT( pRadioButton );
1355  if( pRadioButton->GetValue() )
1356  {
1357  mRadioValue.WriteToAsWrappedType( WrappedRef );
1358  }
1359  }
1360  break;
1361  default:
1362  wxASSERT( false );
1363  break;
1364  }
1365  return pRadioButton;
1366 }
1367 
1371 void ShuttleGuiBase::StartRadioButtonGroup( const wxString & SettingName )
1372 {
1373  wxASSERT( mRadioValue.eWrappedType != eWrappedNotSet );
1374  mSettingName = SettingName;
1375  mRadioCount = 0;
1376  if( mShuttleMode == eIsCreating )
1377  DoDataShuttle( SettingName, mRadioValue );
1378 }
1379 
1383 {
1386  mRadioValue.Init();// Clear it out...
1387  mSettingName = wxT("");
1388  mRadioCount = -1; // So we detect a problem.
1389 }
1390 
1391 //-----------------------------------------------------------------------//
1392 //-- Now we are into type specific Tie() functions.
1393 //-- These are all 'one-step' tie functions.
1394 
1395 wxCheckBox * ShuttleGuiBase::TieCheckBox(const wxString &Prompt, bool &Var)
1396 {
1397  WrappedType WrappedRef( Var );
1398  return TieCheckBox( Prompt, WrappedRef );
1399 }
1400 
1401 // See comment in AddCheckBoxOnRight() for why we have this variant.
1402 wxCheckBox * ShuttleGuiBase::TieCheckBoxOnRight(const wxString &Prompt, bool &Var)
1403 {
1404  // Only odes anything different if it's creating.
1405  WrappedType WrappedRef( Var );
1406  if( mShuttleMode == eIsCreating )
1407  return AddCheckBoxOnRight( Prompt, WrappedRef.ReadAsString() );
1408  return TieCheckBox( Prompt, WrappedRef );
1409 }
1410 
1411 wxSpinCtrl * ShuttleGuiBase::TieSpinCtrl( const wxString &Prompt, int &Value, const int max, const int min )
1412 {
1413  WrappedType WrappedRef(Value);
1414  return TieSpinCtrl( Prompt, WrappedRef, max, min );
1415 }
1416 
1417 wxTextCtrl * ShuttleGuiBase::TieTextBox( const wxString &Prompt, wxString &Selected, const int nChars)
1418 {
1419  WrappedType WrappedRef(Selected);
1420  return TieTextBox( Prompt, WrappedRef, nChars );
1421 }
1422 
1423 wxTextCtrl * ShuttleGuiBase::TieTextBox( const wxString &Prompt, int &Selected, const int nChars)
1424 {
1425  WrappedType WrappedRef( Selected );
1426  return TieTextBox( Prompt, WrappedRef, nChars );
1427 }
1428 
1429 wxTextCtrl * ShuttleGuiBase::TieTextBox( const wxString &Prompt, double &Value, const int nChars)
1430 {
1431  WrappedType WrappedRef( Value );
1432  return TieTextBox( Prompt, WrappedRef, nChars );
1433 }
1434 
1435 wxTextCtrl * ShuttleGuiBase::TieNumericTextBox( const wxString &Prompt, wxString &Selected, const int nChars)
1436 {
1437  WrappedType WrappedRef(Selected);
1438  return TieNumericTextBox( Prompt, WrappedRef, nChars );
1439 }
1440 
1441 wxTextCtrl * ShuttleGuiBase::TieNumericTextBox( const wxString &Prompt, int &Selected, const int nChars)
1442 {
1443  WrappedType WrappedRef( Selected );
1444  return TieNumericTextBox( Prompt, WrappedRef, nChars );
1445 }
1446 
1447 wxTextCtrl * ShuttleGuiBase::TieNumericTextBox( const wxString &Prompt, double &Value, const int nChars)
1448 {
1449  WrappedType WrappedRef( Value );
1450  return TieNumericTextBox( Prompt, WrappedRef, nChars );
1451 }
1452 
1453 wxSlider * ShuttleGuiBase::TieSlider( const wxString &Prompt, int &pos, const int max, const int min )
1454 {
1455  WrappedType WrappedRef( pos );
1456  return TieSlider( Prompt, WrappedRef, max, min );
1457 }
1458 
1459 wxSlider * ShuttleGuiBase::TieSlider( const wxString &Prompt, double &pos, const double max, const double min )
1460 {
1461  WrappedType WrappedRef( pos );
1462  return TieSlider( Prompt, WrappedRef, max, min );
1463 }
1464 
1465 wxSlider * ShuttleGuiBase::TieSlider( const wxString &Prompt, float &pos, const float fMin, const float fMax)
1466 {
1467  const float RoundFix=0.0000001f;
1468  int iVal=(pos-fMin+RoundFix)*100.0/(fMax-fMin);
1469  wxSlider * pWnd = TieSlider( Prompt, iVal, 100 );
1470  pos = iVal*(fMax-fMin)*0.01+fMin;
1471  return pWnd;
1472 }
1473 
1474 wxSlider * ShuttleGuiBase::TieVSlider( const wxString &Prompt, float &pos, const float fMin, const float fMax)
1475 {
1476  int iVal=(pos-fMin)*100.0/(fMax-fMin);
1477 // if( mShuttleMode == eIsCreating )
1478 // {
1479 // return AddVSlider( Prompt, iVal, 100 );
1480 // }
1481  wxSlider * pWnd = TieSlider( Prompt, iVal, 100 );
1482  pos = iVal*(fMax-fMin)*0.01+fMin;
1483  return pWnd;
1484 }
1485 
1487  const wxString &Prompt,
1488  wxString &Selected,
1489  const wxArrayString * pChoices )
1490 {
1491  WrappedType WrappedRef( Selected );
1492  return TieChoice( Prompt, WrappedRef, pChoices );
1493 }
1494 
1496  const wxString &Prompt,
1497  int &Selected,
1498  const wxArrayString * pChoices )
1499 {
1500  WrappedType WrappedRef( Selected );
1501  return TieChoice( Prompt, WrappedRef, pChoices );
1502 }
1503 
1504 //-----------------------------------------------------------------------//
1505 
1506 // ShuttleGui utility functions to look things up in a list.
1507 // If not present, we use the configured default index value.
1508 
1509 //-----------------------------------------------------------------------//
1510 
1512 int ShuttleGuiBase::TranslateToIndex( const wxString &Value, const wxArrayString &Choices )
1513 {
1514  int n = Choices.Index( Value );
1515  if( n== wxNOT_FOUND )
1517  miNoMatchSelector = 0;
1518  return n;
1519 }
1520 
1522 wxString ShuttleGuiBase::TranslateFromIndex( const int nIn, const wxArrayString &Choices )
1523 {
1524  int n = nIn;
1525  if( n== wxNOT_FOUND )
1527  miNoMatchSelector = 0;
1528  if( n < (int)Choices.GetCount() )
1529  {
1530  return Choices[n];
1531  }
1532  return wxT("");
1533 }
1534 
1536 int ShuttleGuiBase::TranslateToIndex( const int Value, const wxArrayInt &Choices )
1537 {
1538  int n = Choices.Index( Value );
1539  if( n== wxNOT_FOUND )
1541  miNoMatchSelector = 0;
1542  return n;
1543 }
1544 
1546 int ShuttleGuiBase::TranslateFromIndex( const int nIn, const wxArrayInt &Choices )
1547 {
1548  int n = nIn;
1549  if( n== wxNOT_FOUND )
1551  miNoMatchSelector = 0;
1552  if( n < (int)Choices.GetCount() )
1553  {
1554  return Choices[n];
1555  }
1556  return 0;
1557 }
1558 
1559 //-----------------------------------------------------------------------//
1560 
1561 
1562 // ShuttleGui code uses the model that you read into program variables
1563 // and write out from program variables.
1564 
1565 // In programs like Audacity which don't use internal program variables
1566 // you have to do both steps in one go, using variants of the standard
1567 // 'Tie' functions which call the underlying Tie functions twice.
1568 
1569 //----------------------------------------------------------------------//
1570 
1571 
1604 bool ShuttleGuiBase::DoStep( int iStep )
1605 {
1606  // Get value and create
1607  if( mShuttleMode == eIsCreating )
1608  {
1609  return (iStep==1) || (iStep==2);
1610  }
1611  // Like creating, get the value and set.
1613  {
1614  return (iStep==1) || (iStep==2);
1615  }
1617  {
1618  return (iStep==2) || (iStep==3);
1619  }
1620  wxASSERT( false );
1621  return false;
1622 }
1623 
1624 
1628  const wxString &Prompt,
1629  const wxString &SettingName,
1630  const bool bDefault)
1631 {
1632  wxCheckBox * pCheck=NULL;
1633 
1634  bool bValue=bDefault;
1635  WrappedType WrappedRef( bValue );
1636  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1637  if( DoStep(2) ) pCheck = TieCheckBox( Prompt, WrappedRef );
1638  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1639 
1640  return pCheck;
1641 }
1642 
1646  const wxString &Prompt,
1647  const wxString &SettingName,
1648  const bool bDefault)
1649 {
1650  wxCheckBox * pCheck=NULL;
1651 
1652  bool bValue=bDefault;
1653  WrappedType WrappedRef( bValue );
1654  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1655  if( DoStep(2) ) pCheck = TieCheckBoxOnRight( Prompt, WrappedRef );
1656  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1657 
1658  return pCheck;
1659 }
1660 
1664  const wxString &Prompt,
1665  const wxString &SettingName,
1666  const int iDefault,
1667  const int max,
1668  const int min)
1669 {
1670  wxSlider * pSlider=NULL;
1671 
1672  int iValue=iDefault;
1673  WrappedType WrappedRef( iValue );
1674  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1675  if( DoStep(2) ) pSlider = TieSlider( Prompt, WrappedRef, max, min );
1676  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1677 
1678  return pSlider;
1679 }
1680 
1684  const wxString &Prompt,
1685  const wxString &SettingName,
1686  const int Value,
1687  const int max,
1688  const int min)
1689 {
1690  wxSpinCtrl * pSpinCtrl=NULL;
1691 
1692  int iValue = Value;
1693  WrappedType WrappedRef( iValue );
1694  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1695  if( DoStep(2) ) pSpinCtrl = TieSpinCtrl( Prompt, WrappedRef, max, min );
1696  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1697 
1698  return pSpinCtrl;
1699 }
1700 
1704  const wxString & Prompt,
1705  const wxString & SettingName,
1706  const wxString & Default,
1707  const int nChars)
1708 {
1709  wxTextCtrl * pText=(wxTextCtrl*)NULL;
1710 
1711  wxString Temp = Default;
1712  WrappedType WrappedRef( Temp );
1713  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1714  if( DoStep(2) ) pText = TieTextBox( Prompt, WrappedRef, nChars );
1715  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1716  return pText;
1717 }
1718 
1722  const wxString & Prompt,
1723  const wxString & SettingName,
1724  const wxString & Default,
1725  const int nChars)
1726 {
1727  wxTextCtrl * pText=(wxTextCtrl*)NULL;
1728 
1729  wxString Temp = Default;
1730  WrappedType WrappedRef( Temp );
1731  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1732  if( DoStep(2) ) pText = TieNumericTextBox( Prompt, WrappedRef, nChars );
1733  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1734  return pText;
1735 }
1740  const wxString & Prompt,
1741  const wxString & SettingName,
1742  const double & Default,
1743  const int nChars)
1744 {
1745  wxTextCtrl * pText=(wxTextCtrl*)NULL;
1746 
1747  double Temp = Default;
1748  WrappedType WrappedRef( Temp );
1749  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1750  if( DoStep(2) ) pText = TieTextBox( Prompt, WrappedRef, nChars );
1751  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1752  return pText;
1753 }
1754 
1759  const wxString & Prompt,
1760  const wxString & SettingName,
1761  const double & Default,
1762  const int nChars)
1763 {
1764  wxTextCtrl * pText=(wxTextCtrl*)NULL;
1765 
1766  double Temp = Default;
1767  WrappedType WrappedRef( Temp );
1768  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef );
1769  if( DoStep(2) ) pText = TieNumericTextBox( Prompt, WrappedRef, nChars );
1770  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef );
1771  return pText;
1772 }
1773 
1782  const wxString &Prompt,
1783  const wxString &SettingName,
1784  const wxString &Default,
1785  const wxArrayString & Choices,
1786  const wxArrayString & TranslatedChoices)
1787 {
1788  wxChoice * pChoice=(wxChoice*)NULL;
1789 
1790  int TempIndex=0;
1791 // int TempIndex = TranslateToIndex( Default, TranslatedChoices );
1792  wxString TempStr = Default;
1793  WrappedType WrappedRef( TempStr );
1794  // Get from prefs does 1 and 2.
1795  // Put to prefs does 2 and 3.
1796  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef ); // Get Index from Prefs.
1797  if( DoStep(1) ) TempIndex = TranslateToIndex( TempStr, TranslatedChoices ); // To an index
1798  if( DoStep(2) ) pChoice = TieChoice( Prompt, TempIndex, &Choices ); // Get/Put index from GUI.
1799  if( DoStep(3) ) TempStr = TranslateFromIndex( TempIndex, TranslatedChoices ); // To a string
1800  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef ); // Put into Prefs.
1801  return pChoice;
1802 }
1803 
1814  const wxString &Prompt,
1815  const wxString &SettingName,
1816  const int Default,
1817  const wxArrayString & Choices,
1818  const wxArrayInt & TranslatedChoices)
1819 {
1820  wxChoice * pChoice=(wxChoice*)NULL;
1821 
1822  int TempIndex=0;
1823  int TranslatedInt = Default;
1824  WrappedType WrappedRef( TranslatedInt );
1825  // Get from prefs does 1 and 2.
1826  // Put to prefs does 2 and 3.
1827  if( DoStep(1) ) DoDataShuttle( SettingName, WrappedRef ); // Get Int from Prefs.
1828  if( DoStep(1) ) TempIndex = TranslateToIndex( TranslatedInt, TranslatedChoices ); // Int to an index.
1829  if( DoStep(2) ) pChoice = TieChoice( Prompt, TempIndex, &Choices ); // Get/Put index from GUI.
1830  if( DoStep(3) ) TranslatedInt = TranslateFromIndex( TempIndex, TranslatedChoices ); // Index to int
1831  if( DoStep(3) ) DoDataShuttle( SettingName, WrappedRef ); // Put into Prefs.
1832  return pChoice;
1833 }
1834 
1837 void ShuttleGuiBase::StartRadioButtonGroup( const wxString & SettingName, const int iDefaultValue )
1838 {
1839  // Configure the generic type mechanism to use OUR integer.
1840  mRadioValueInt = iDefaultValue;
1842  // Now actually start the radio button group.
1843  StartRadioButtonGroup( SettingName );
1844 }
1845 
1848 void ShuttleGuiBase::StartRadioButtonGroup( const wxString & SettingName, const wxString & DefaultValue )
1849 {
1850  // Configure the generic type mechanism to use OUR string.
1851  mRadioValueString = DefaultValue;
1853  // Now actually start the radio button group.
1854  StartRadioButtonGroup( SettingName );
1855 }
1856 
1857 
1860  const wxString &Prompt,
1861  const int iValue)
1862 {
1863  int iTemp = iValue;
1864  WrappedType WrappedRef( iTemp );
1865  return TieRadioButton( Prompt, WrappedRef );
1866 }
1867 
1870  const wxString &Prompt,
1871  const wxString &Value)
1872 {
1873  // In what follows, WrappedRef is used in read only mode, but we
1874  // don't have a 'read-only' version, so we copy to deal with the constness.
1875  wxString Temp = Value;
1876  WrappedType WrappedRef( Temp );
1877  return TieRadioButton( Prompt, WrappedRef );
1878 }
1879 
1880 //------------------------------------------------------------------//
1881 
1882 // We're now into ShuttleGuiBase sizer and misc functions.
1883 
1891 {
1892  if( miIdSetByUser > 0)
1893  {
1894  miId = miIdSetByUser;
1895  miIdSetByUser = -1;
1896  return;
1897  }
1898  miId = miIdNext++;
1899 }
1900 
1902 {
1903  if( miPropSetByUser >=0 )
1904  {
1906  miPropSetByUser =-1;
1907  return;
1908  }
1909  miProp = Default;
1910 }
1911 
1912 
1913 void ShuttleGuiBase::UpdateSizersCore(bool bPrepend, int Flags)
1914 {
1915  if( mpWind && mpParent )
1916  {
1917  if( mpSizer){
1918  if( bPrepend )
1919  {
1920  mpSizer->Prepend(mpWind, miProp, Flags,miBorder);
1921  }
1922  else
1923  {
1924  mpSizer->Add(mpWind, miProp, Flags,miBorder);
1925  }
1926  }
1927  }
1928 
1929  if( mpSubSizer && mpSizer )
1930  {
1931  // When adding sizers into sizers, don't add a border.
1932  // unless it's a static box sizer.
1933  wxSizer *const pSubSizer = mpSubSizer.get();
1934  if (wxDynamicCast(pSubSizer, wxStaticBoxSizer))
1935  {
1936  mpSizer->Add( mpSubSizer.release(), miSizerProp, Flags , miBorder);
1937  }
1938  else
1939  {
1940  mpSizer->Add( mpSubSizer.release(), miSizerProp, Flags ,0);//miBorder);
1941  }
1942  mpSizer = pSubSizer;
1943  PushSizer();
1944  }
1945  mpLastWind = mpWind;
1946  mpWind = NULL;
1947  miProp = 0;
1948  miSizerProp =0;
1949 }
1950 
1951 // Sizer is added into parent sizer, and will expand/shrink.
1953 { UpdateSizersCore( false, wxEXPAND | wxALL );}
1954 
1955 // Sizer is added into parent sizer, centred
1957 { UpdateSizersCore( false, wxALIGN_CENTRE | wxALL );}
1958 
1959 // Sizer is added into parent sizer, and will expand/shrink.
1960 // added to start of sizer list.
1962 { UpdateSizersCore( true, wxEXPAND | wxALL );}
1963 
1965 {
1966  mSizerDepth--;
1967  wxASSERT( mSizerDepth >=0 );
1969 }
1970 
1972 {
1973  mSizerDepth++;
1974  wxASSERT( mSizerDepth < nMaxNestedSizers );
1976 }
1977 
1978 long ShuttleGuiBase::Style( long style )
1979 {
1980  if( miStyle )
1981  style = miStyle;
1982  miStyle = 0;
1983  return style;
1984 }
1985 
1986 // A rarely used helper function that sets a pointer
1987 // ONLY if the value it is to be set to is non NULL.
1988 void SetIfCreated( wxChoice * &Var, wxChoice * Val )
1989 {
1990  if( Val != NULL )
1991  Var = Val;
1992 };
1993 void SetIfCreated( wxTextCtrl * &Var, wxTextCtrl * Val )
1994 {
1995  if( Val != NULL )
1996  Var = Val;
1997 };
1998 void SetIfCreated( wxStaticText *&Var, wxStaticText * Val )
1999 {
2000  if( Val != NULL )
2001  Var = Val;
2002 };
2003 
2004 #ifdef EXPERIMENTAL_TRACK_PANEL
2005 // Additional includes down here, to make it easier to split this into
2006 // two files at some later date.
2007 #include "../extnpanel-src/GuiWaveTrack.h"
2008 #endif
2009 #include "./widgets/Ruler.h"
2011 #include "ShuttlePrefs.h"
2012 
2013 ShuttleGui::ShuttleGui(wxWindow * pParent, teShuttleMode ShuttleMode) :
2014  ShuttleGuiBase( pParent, ShuttleMode )
2015 {
2016  if( ShuttleMode == eIsCreatingFromPrefs )
2017  {
2019  Init(); // Wasn't fully done in base constructor because it is only done when eIsCreating is set.
2020  }
2021  else if( ShuttleMode == eIsSavingToPrefs )
2022  {
2024  }
2025  else
2026  {
2027  return;
2028  }
2029 
2030  mpShuttle = std::make_unique<ShuttlePrefs>();
2031  // In this case the client is the GUI, so if creating we do want to
2032  // store in the client.
2033  mpShuttle->mbStoreInClient = (mShuttleMode == eIsCreating );
2034 };
2035 
2037 {
2038 }
2039 
2040 // Now we have Audacity specific shuttle functions.
2042 {
2043  miIdSetByUser = id;
2044  return *this;
2045 }
2046 
2047 GuiWaveTrack * ShuttleGui::AddGuiWaveTrack( const wxString & WXUNUSED(Name))
2048 {
2049 #ifdef EXPERIMENTAL_TRACK_PANEL
2050  UseUpId();
2051  if( mShuttleMode != eIsCreating )
2052  return (GuiWaveTrack*)NULL;
2053 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), GuiWaveTrack);
2054  GuiWaveTrack * pGuiWaveTrack;
2055  miProp=1;
2056  mpWind = pGuiWaveTrack = safenew GuiWaveTrack(mpParent, miId, Name);
2057  mpWind->SetMinSize(wxSize(100,50));
2058  UpdateSizers();
2059  return pGuiWaveTrack;
2060 #else
2061  return NULL;
2062 #endif
2063 }
2064 
2066 {
2067  UseUpId();
2068  if( mShuttleMode != eIsCreating )
2069  return (AttachableScrollBar*)NULL;
2070 // return wxDynamicCast(wxWindow::FindWindowById( miId, mpDlg), AttachableScrollBar);
2071  AttachableScrollBar * pAttachableScrollBar;
2072  miProp=0;
2073  mpWind = pAttachableScrollBar = safenew AttachableScrollBar(
2074  mpParent,
2075  miId,
2076  wxDefaultPosition,
2077  wxDefaultSize,
2078  style
2079  );
2080  mpWind->SetMinSize(wxSize(10,20));
2081  UpdateSizers();
2082  return pAttachableScrollBar;
2083 }
2084 
2085 std::unique_ptr<wxSizer> CreateStdButtonSizer(wxWindow *parent, long buttons, wxWindow *extra)
2086 {
2087  wxASSERT(parent != NULL); // To justify safenew
2088 
2089  int margin;
2090  {
2091 #if defined(__WXMAC__)
2092  margin = 12;
2093 #elif defined(__WXGTK20__)
2094  margin = 12;
2095 #elif defined(__WXMSW__)
2096  wxButton b(parent, 0, wxEmptyString);
2097  margin = b.ConvertDialogToPixels(wxSize(2, 0)).x;
2098 #else
2099  wxButton b(parent, 0, wxEmptyString);
2100  margin = b->ConvertDialogToPixels(wxSize(4, 0)).x;
2101 #endif
2102  }
2103 
2104  wxButton *b = NULL;
2105  auto bs = std::make_unique<wxStdDialogButtonSizer>();
2106 
2107  if( buttons & eOkButton )
2108  {
2109  b = safenew wxButton(parent, wxID_OK);
2110  b->SetDefault();
2111  bs->AddButton( b );
2112  }
2113 
2114  if( buttons & eCancelButton )
2115  {
2116  bs->AddButton(safenew wxButton(parent, wxID_CANCEL));
2117  }
2118 
2119  if( buttons & eYesButton )
2120  {
2121  b = safenew wxButton(parent, wxID_YES);
2122  b->SetDefault();
2123  bs->AddButton( b );
2124  }
2125 
2126  if( buttons & eNoButton )
2127  {
2128  bs->AddButton(safenew wxButton(parent, wxID_NO));
2129  }
2130 
2131  if( buttons & eApplyButton )
2132  {
2133  b = safenew wxButton(parent, wxID_APPLY);
2134  b->SetDefault();
2135  bs->AddButton( b );
2136  }
2137 
2138  if( buttons & eCloseButton )
2139  {
2140  bs->AddButton(safenew wxButton(parent, wxID_CANCEL, _("&Close")));
2141  }
2142 
2143  if( buttons & eHelpButton )
2144  {
2145  // Replace standard Help button with smaller icon button.
2146  // bs->AddButton(safenew wxButton(parent, wxID_HELP));
2147  b = safenew wxBitmapButton(parent, wxID_HELP, theTheme.Bitmap( bmpHelpIcon ));
2148  b->SetToolTip( _("Help") );
2149  bs->AddButton( b );
2150  }
2151 
2152  if (buttons & ePreviewButton)
2153  {
2154  bs->Add(safenew wxButton(parent, ePreviewID, _("&Preview")), 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin);
2155  }
2156  if (buttons & ePreviewDryButton)
2157  {
2158  bs->Add(safenew wxButton(parent, ePreviewDryID, _("Dry Previe&w")), 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin);
2159  bs->Add( 20, 0 );
2160  }
2161 
2162  if( buttons & eSettingsButton )
2163  {
2164  bs->Add(safenew wxButton(parent, eSettingsID, _("&Settings")), 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin);
2165  bs->Add( 20, 0 );
2166  }
2167 
2168  if( extra )
2169  {
2170  bs->Add( extra, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin );
2171  bs->Add( 40, 0 );
2172  }
2173 
2174  bs->AddStretchSpacer();
2175  bs->Realize();
2176 
2177  // Add any buttons that need to cuddle up to the right hand cluster
2178  if( buttons & eDebugButton )
2179  {
2180  size_t lastLastSpacer = 0;
2181  size_t lastSpacer = 0;
2182  wxSizerItemList & list = bs->GetChildren();
2183  for( size_t i = 0, cnt = list.GetCount(); i < cnt; i++ )
2184  {
2185  if( list[i]->IsSpacer() )
2186  {
2187  lastSpacer = i;
2188  }
2189  else
2190  {
2191  lastLastSpacer = lastSpacer;
2192  }
2193  }
2194 
2195  b = safenew wxButton(parent, eDebugID, _("Debu&g"));
2196  bs->Insert( lastLastSpacer + 1, b, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin );
2197  }
2198 
2199  auto s = std::make_unique<wxBoxSizer>( wxVERTICAL );
2200  s->Add( bs.release(), 1, wxEXPAND | wxALL, 7 );
2201  s->Add( 0, 3 ); // a little extra space
2202 
2203  return std::unique_ptr<wxSizer>{ s.release() };
2204 }
2205 
2206 void ShuttleGui::AddStandardButtons(long buttons, wxButton *extra)
2207 {
2208  if( mShuttleMode != eIsCreating )
2209  return;
2210 
2211  StartVerticalLay( false );
2212 
2213  miSizerProp = false;
2214  mpSubSizer = CreateStdButtonSizer( mpParent, buttons, extra );
2215  UpdateSizers();
2216  PopSizer();
2217 
2218  EndVerticalLay();
2219 }
2220 
2221 wxSizerItem * ShuttleGui::AddSpace( int width, int height )
2222 {
2223  if( mShuttleMode != eIsCreating )
2224  return NULL;
2225 
2226  return mpSizer->Add( width, height, 0);
2227 }
2228 
2229 void ShuttleGui::SetSizeHints( wxWindow *window, const wxArrayString & items )
2230 {
2231  int maxw = 0;
2232 
2233  for( size_t i = 0; i < items.GetCount(); i++ )
2234  {
2235  int x;
2236  int y;
2237 
2238  window->GetTextExtent(items[i], &x, &y );
2239  if( x > maxw )
2240  {
2241  maxw = x;
2242  }
2243  }
2244 
2245  // Would be nice to know the sizes of the button and borders, but this is
2246  // the best we can do for now.
2247 #if defined(__WXMAC__)
2248  maxw += 50;
2249 #elif defined(__WXMSW__)
2250  maxw += 50;
2251 #elif defined(__WXGTK__)
2252  maxw += 50;
2253 #else
2254  maxw += 50;
2255 #endif
2256 
2257  window->SetSizeHints( maxw, -1 );
2258 }
2259 
2260 void ShuttleGui::SetSizeHints( wxWindow *window, const wxArrayInt & items )
2261 {
2262  wxArrayString strs;
2263 
2264  for( size_t i = 0; i < items.GetCount(); i++ )
2265  {
2266  strs.Add( wxString::Format( wxT("%d"), items[i] ) );
2267  }
2268 
2269  SetSizeHints( window, strs );
2270 }
2271 
2272 void ShuttleGui::SetSizeHints( const wxArrayString & items )
2273 {
2274  if( mShuttleMode != eIsCreating )
2275  return;
2276 
2277  SetSizeHints( mpLastWind, items );
2278 }
2279 
2280 void ShuttleGui::SetSizeHints( const wxArrayInt & items )
2281 {
2282  if( mShuttleMode != eIsCreating )
2283  return;
2284 
2285  SetSizeHints( mpLastWind, items );
2286 }
2287 
2288 void ShuttleGui::SetSizeHints( int minX, int minY )
2289 {
2290  ShuttleGuiBase::SetSizeHints( minX, minY );
2291 }
wxChoice * TieChoice(const wxString &Prompt, WrappedType &WrappedRef, const wxArrayString *pChoices)
std::unique_ptr< wxSizer > CreateStdButtonSizer(wxWindow *parent, long buttons, wxWindow *extra)
void SetSizeHints(int minX, int minY)
Used to modify an already placed Window.
Definition: ShuttleGui.cpp:183
void WriteToAsInt(const int InInt)
void SetTo(wxString &InStr)
Definition: WrappedType.h:41
~ShuttleGuiBase(void)
Definition: ShuttleGui.cpp:124
AUDACITY_DLL_API Theme theTheme
Definition: Theme.cpp:215
WrappedType mRadioValue
The index of this radio item. -1 for none.
Definition: ShuttleGui.h:297
void OnErase(wxEraseEvent &)
Definition: ShuttleGui.cpp:914
An InvisiblePanel is a panel which does not repaint its own background.
Definition: ShuttleGui.cpp:900
wxCheckBox * TieCheckBoxOnRight(const wxString &Prompt, WrappedType &WrappedRef)
wxSpinCtrl * AddSpinCtrl(const wxString &Prompt, int Value, int Max, int Min)
Definition: ShuttleGui.cpp:474
wxCheckBox * AddCheckBoxOnRight(const wxString &Prompt, const wxString &Selected)
Definition: ShuttleGui.cpp:285
An AttachableScrollBar is a scroll bar that can be attached to multiple items and so control their sc...
wxMenu * AddMenu(const wxString &Title)
Definition: ShuttleGui.cpp:688
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI...
Definition: ShuttleGui.h:366
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:903
wxSlider * TieSlider(const wxString &Prompt, WrappedType &WrappedRef, const int max, const int min=0)
teWrappedType eWrappedType
Definition: WrappedType.h:64
wxWindow * AddWindow(wxWindow *pWindow, int Flags=wxALIGN_CENTRE|wxALL)
Definition: ShuttleGui.cpp:257
std::unique_ptr< Shuttle > mpShuttle
Definition: ShuttleGui.h:287
void EndNotebook()
Definition: ShuttleGui.cpp:839
void UpdateSizersAtStart()
wxString mRadioValueString
The wrapped value associated with the active radio button.
Definition: ShuttleGui.h:298
void EndMultiColumn()
void EndNotebookPage()
Definition: ShuttleGui.cpp:890
void EnableCtrl(bool bEnable)
Definition: ShuttleGui.cpp:175
wxPanel * StartPanel(int iStyle=0)
Definition: ShuttleGui.cpp:789
wxWindow * mpDlg
Definition: ShuttleGui.h:284
int miSizerProp
Unwrapped integer value.
Definition: ShuttleGui.h:301
wxPanel * StartInvisiblePanel()
Definition: ShuttleGui.cpp:931
void SetIfCreated(wxChoice *&Var, wxChoice *Val)
wxSizer * pSizerStack[nMaxNestedSizers]
Definition: ShuttleGui.h:285
int mRadioValueInt
Unwrapped string value.
Definition: ShuttleGui.h:299
void WriteToAsBool(const bool InBool)
~ShuttleGui(void)
wxTreeCtrl * AddTree()
Definition: ShuttleGui.cpp:642
wxTextCtrl * AddNumericTextBox(const wxString &Caption, const wxString &Value, const int nChars)
Definition: ShuttleGui.cpp:520
wxSpinCtrl * TieSpinCtrl(const wxString &Prompt, WrappedType &WrappedRef, const int max, const int min=0)
void EndScroller()
Definition: ShuttleGui.cpp:770
void OnPaint(wxPaintEvent &event)
Definition: ShuttleGui.cpp:924
wxListCtrl * AddListControl()
Definition: ShuttleGui.cpp:599
GuiWaveTrack * AddGuiWaveTrack(const wxString &Name)
const int nMaxNestedSizers
Definition: ShuttleGui.h:26
#define safenew
Definition: Audacity.h:223
wxString ReadAsString()
ShuttleGui(wxWindow *pParent, teShuttleMode ShuttleMode)
wxMenu * mpMenu
Definition: ShuttleGui.h:319
void EndHorizontalLay()
Definition: ShuttleGui.cpp:975
bool DoStep(int iStep)
wxBitmap & Bitmap(int iIndex)
Definition: Theme.cpp:1233
void AddUnits(const wxString &Prompt)
Left aligned text string.
Definition: ShuttleGui.cpp:229
void AddPrompt(const wxString &Prompt)
Right aligned text string.
Definition: ShuttleGui.cpp:215
ShuttleGuiBase & Prop(int iProp)
Definition: ShuttleGui.cpp:669
wxBitmapButton * AddBitmapButton(const wxBitmap &Bitmap, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:315
void EndVerticalLay()
Definition: ShuttleGui.cpp:991
void SetSizeHints(int minX=-1, int minY=-1)
wxTextCtrl * AddTextBox(const wxString &Caption, const wxString &Value, const int nChars)
Definition: ShuttleGui.cpp:493
wxCheckBox * AddCheckBox(const wxString &Prompt, const wxString &Selected)
Definition: ShuttleGui.cpp:267
void AddIcon(wxBitmap *pBmp)
Definition: ShuttleGui.cpp:656
wxSizer * mpSizer
Definition: ShuttleGui.h:315
wxScrolledWindow * StartScroller(int iStyle=0)
Definition: ShuttleGui.cpp:733
void WriteToAsString(const wxString &InStr)
wxWindow * GetParent()
Definition: ShuttleGui.h:259
void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1)
Definition: ShuttleGui.cpp:966
wxGrid * AddGrid()
Definition: ShuttleGui.cpp:613
wxListCtrl * AddListControlReportMode()
Definition: ShuttleGui.cpp:627
void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT)
Definition: ShuttleGui.cpp:998
wxChoice * AddChoice(const wxString &Prompt, const wxString &Selected, const wxArrayString *pChoices)
Definition: ShuttleGui.cpp:331
ShuttleGui & Id(int id)
bool ReadAsBool()
void UpdateSizersC()
wxWindow * mpParent
Definition: ShuttleGui.h:316
teShuttleMode
Definition: ShuttleGui.h:28
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:568
void AddFixedText(const wxString &Str, bool bCenter=false)
Definition: ShuttleGui.cpp:356
int min(int a, int b)
void AddTitle(const wxString &Prompt)
Centred text string.
Definition: ShuttleGui.cpp:243
ShuttleGuiBase(wxWindow *pParent, teShuttleMode ShuttleMode)
Definition: ShuttleGui.cpp:114
bool ValuesMatch(const WrappedType &W)
Definition: WrappedType.cpp:41
Base class for shuttling data to and from a GUI.
Definition: ShuttleGui.h:73
wxRadioButton * TieRadioButton(const wxString &Prompt, WrappedType &WrappedRef)
bool IsString()
Definition: WrappedType.cpp:34
teShuttleMode mShuttleMode
Used in choices to determine which item to use on no match.
Definition: ShuttleGui.h:291
wxWindow * mpWind
Definition: ShuttleGui.h:317
void UpdateSizersCore(bool bPrepend, int Flags)
_("Move Track &Down")+wxT("\t")+(GetActiveProject() -> GetCommandManager() ->GetKeyFromName(wxT("TrackMoveDown"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveTopID, _("Move Track to &Top")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveTop"))), OnMoveTrack) POPUP_MENU_ITEM(OnMoveBottomID, _("Move Track to &Bottom")+wxT("\t")+(GetActiveProject() ->GetCommandManager() ->GetKeyFromName(wxT("TrackMoveBottom"))), OnMoveTrack) void TrackMenuTable::OnSetName(wxCommandEvent &)
wxComboBox * AddCombo(const wxString &Prompt, const wxString &Selected, const wxArrayString *pChoices, long style=0)
Definition: ShuttleGui.cpp:399
int mRadioCount
The setting controlled by a group.
Definition: ShuttleGui.h:295
int miNoMatchSelector
Definition: ShuttleGui.h:289
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:551
wxListBox * AddListBox(const wxArrayString *pChoices, long style=0)
Definition: ShuttleGui.cpp:584
AttachableScrollBar * AddAttachableScrollBar(long style=wxSB_HORIZONTAL)
wxMenuBar * mpMenuBar
Definition: ShuttleGui.h:318
wxWindow wxNotebookPage
Definition: ShuttleGui.h:55
wxStaticText * AddVariableText(const wxString &Str, bool bCenter=false, int PositionFlags=0)
Definition: ShuttleGui.cpp:373
wxStaticBox * StartStatic(const wxString &Str, int iProp=0)
Definition: ShuttleGui.cpp:701
wxString mSettingName
Definition: ShuttleGui.h:294
wxWindow * mpLastWind
Definition: ShuttleGui.h:283
long Style(long Style)
wxRadioButton * AddRadioButtonToGroup(const wxString &Prompt)
Definition: ShuttleGui.cpp:443
wxNotebook * StartNotebook()
Definition: ShuttleGui.cpp:825
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxButton *extra=NULL)
END_EVENT_TABLE()
wxSizerItem * AddSpace(int width, int height)
void EndInvisiblePanel()
Definition: ShuttleGui.cpp:954
std::unique_ptr< wxSizer > mpSubSizer
Definition: ShuttleGui.h:314
wxNotebookPage * StartNotebookPage(const wxString &Name)
Definition: ShuttleGui.cpp:846
wxMenuBar * AddMenuBar()
Definition: ShuttleGui.cpp:675
wxSlider * TieVSlider(const wxString &Prompt, float &pos, const float fMin, const float fMax)
void StartRadioButtonGroup(const wxString &SettingName)
wxButton * AddButton(const wxString &Text, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:301
void SetStretchyCol(int i)
Used to modify an already placed FlexGridSizer to make a column stretchy.
Definition: ShuttleGui.cpp:192
wxRadioButton * AddRadioButton(const wxString &Prompt)
Definition: ShuttleGui.cpp:427
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:202
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:456
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:982