1 /********************************************************************** 2 3 Audacity: A Digital Audio Editor 4 5 ShuttleGui.h 6 7 James Crook 8 9 Audacity is free software. 10 This file is licensed under the wxWidgets license, see License.txt 11 12 **********************************************************************/ 13 14 #ifndef SHUTTLE_GUI 15 #define SHUTTLE_GUI 16 17 18 #include "Identifier.h" 19 20 #include <vector> 21 #include <wx/slider.h> // to inherit 22 #include "MemoryX.h" 23 #include <wx/listbase.h> // for wxLIST_FORMAT_LEFT 24 25 #include "Prefs.h" 26 #include "WrappedType.h" 27 #include "ComponentInterfaceSymbol.h" 28 29 class ChoiceSetting; 30 31 class wxArrayStringEx; 32 33 34 const int nMaxNestedSizers = 20; 35 36 enum teShuttleMode 37 { 38 eIsCreating, 39 eIsGettingFromDialog, 40 eIsSettingToDialog, 41 eIsGettingMetadata, 42 43 // Next two are only ever seen in constructor. 44 // After that they revert to one of the modes above. 45 // They are used to achieve 'two step' operation, 46 // where we transfer between two shuttles in one go. 47 eIsCreatingFromPrefs, 48 eIsSavingToPrefs 49 }; 50 51 class wxListCtrl; 52 class wxCheckBox; 53 class wxChoice; 54 class wxComboBox; 55 class wxScrolledWindow; 56 class wxStaticText; 57 class wxTreeCtrl; 58 class wxTextCtrl; 59 class wxSlider; 60 class wxNotebook; 61 class wxSimplebook; 62 typedef wxWindow wxNotebookPage; // so far, any window can be a page 63 class wxButton; 64 class wxBitmapButton; 65 class wxRadioButton; 66 class wxBitmap; 67 class wxPanel; 68 class wxSizer; 69 class wxSizerItem; 70 class wxStaticBox; 71 class wxSpinCtrl; 72 class wxListBox; 73 class wxGrid; 74 class Shuttle; 75 class ReadOnlyText; 76 77 class WrappedType; 78 79 #ifdef __WXMAC__ 80 81 #include <wx/statbox.h> // to inherit 82 83 class wxStaticBoxWrapper 84 : public wxStaticBox // inherit to get access to m_container 85 { 86 public: 87 template< typename... Args > wxStaticBoxWrapper(Args &&...args)88 wxStaticBoxWrapper( Args &&...args ) 89 : wxStaticBox( std::forward<Args>(args)... ) 90 { 91 m_container.EnableSelfFocus(); 92 } 93 }; 94 95 /// Fix a defect in TAB key navigation to sliders, known to happen in wxWidgets 96 /// 3.1.1 and maybe in earlier versions 97 class wxSliderWrapper : public wxSlider 98 { 99 public: 100 using wxSlider::wxSlider; 101 void SetFocus() override; 102 }; 103 #else 104 using wxStaticBoxWrapper = wxStaticBox; 105 using wxSliderWrapper = wxSlider; 106 #endif 107 108 namespace DialogDefinition { 109 110 struct Item { 111 Item() = default; 112 113 // Factory is a class that returns a value of some subclass of wxValidator 114 // We must wrap it in another lambda to allow the return type of f to 115 // vary, and avoid the "slicing" problem. 116 // (That is, std::function<wxValidator()> would not work.) 117 template<typename Factory> ValidatorItem118 Item&& Validator( const Factory &f ) && 119 { 120 mValidatorSetter = [f](wxWindow *p){ p->SetValidator(f()); }; 121 return std::move(*this); 122 } 123 124 // This allows further abbreviation of the previous: 125 template<typename V, typename... Args> ValidatorItem126 Item&& Validator( Args&&... args ) && 127 { return std::move(*this).Validator( [args...]{ return V( args... ); } ); } 128 ToolTipItem129 Item&& ToolTip( const TranslatableString &tip ) && 130 { 131 mToolTip = tip; 132 return std::move( *this ); 133 } 134 135 // Menu codes in the translation will be stripped NameItem136 Item&& Name( const TranslatableString &name ) && 137 { 138 mName = name; 139 return std::move( *this ); 140 } 141 142 // Append a space, then the translation of the given string, to control name 143 // (not the title or label: this affects the screen reader behavior) NameSuffixItem144 Item&& NameSuffix( const TranslatableString &suffix ) && 145 { 146 mNameSuffix = suffix; 147 return std::move( *this ); 148 } 149 StyleItem150 Item&& Style( long style ) && 151 { 152 miStyle = style; 153 return std::move( *this ); 154 } 155 156 // Only the last item specified as focused (if more than one) will be 157 Item&& Focus( bool focused = true ) && 158 { 159 mFocused = focused; 160 return std::move( *this ); 161 } 162 163 Item&& Disable( bool disabled = true ) && 164 { 165 mDisabled = disabled; 166 return std::move( *this ); 167 } 168 169 // Dispatch events from the control to the dialog 170 // The template type deduction ensures consistency between the argument type 171 // and the event type. It does not (yet) ensure correctness of the type of 172 // the handler object. 173 template< typename Tag, typename Argument, typename Handler > 174 auto ConnectRoot( 175 wxEventTypeTag<Tag> eventType, 176 void (Handler::*func)(Argument&) 177 ) && 178 -> typename std::enable_if< 179 std::is_base_of<Argument, Tag>::value, 180 Item&& 181 >::type 182 { 183 mRootConnections.push_back({ 184 eventType, 185 (void(wxEvtHandler::*)(wxEvent&)) ( 186 static_cast<void(wxEvtHandler::*)(Argument&)>( func ) 187 ) 188 }); 189 return std::move( *this ); 190 } 191 MinSizeItem192 Item&& MinSize() && // set best size as min size 193 { 194 mUseBestSize = true; 195 return std::move ( *this ); 196 } 197 MinSizeItem198 Item&& MinSize( wxSize sz ) && 199 { 200 mMinSize = sz; mHasMinSize = true; 201 return std::move ( *this ); 202 } 203 PositionItem204 Item&& Position( int flags ) && 205 { 206 mWindowPositionFlags = flags; 207 return std::move( *this ); 208 } 209 SizeItem210 Item&& Size( wxSize size ) && 211 { 212 mWindowSize = size; 213 return std::move( *this ); 214 } 215 216 std::function< void(wxWindow*) > mValidatorSetter; 217 TranslatableString mToolTip; 218 TranslatableString mName; 219 TranslatableString mNameSuffix; 220 221 std::vector<std::pair<wxEventType, wxObjectEventFunction>> mRootConnections; 222 223 long miStyle{}; 224 225 // Applies to windows, not to subsizers 226 int mWindowPositionFlags{ 0 }; 227 228 wxSize mWindowSize{}; 229 230 wxSize mMinSize{ -1, -1 }; 231 bool mHasMinSize{ false }; 232 bool mUseBestSize{ false }; 233 234 bool mFocused { false }; 235 bool mDisabled { false }; 236 237 }; 238 239 } 240 241 class AUDACITY_DLL_API ShuttleGuiBase /* not final */ 242 { 243 public: 244 ShuttleGuiBase( 245 wxWindow * pParent, 246 teShuttleMode ShuttleMode, 247 bool vertical, // Choose layout direction of topmost level sizer 248 wxSize minSize 249 ); 250 virtual ~ShuttleGuiBase(); 251 void Init( bool vertical, wxSize minSize ); 252 void ResetId(); 253 254 //-- Add functions. These only add a widget or 2. 255 void HandleOptionality(const TranslatableString &Prompt); 256 void AddPrompt(const TranslatableString &Prompt, int wrapWidth = 0); 257 void AddUnits(const TranslatableString &Prompt, int wrapWidth = 0); 258 void AddTitle(const TranslatableString &Prompt, int wrapWidth = 0); 259 wxWindow * AddWindow(wxWindow* pWindow, int PositionFlags = wxALIGN_CENTRE); 260 wxSlider * AddSlider( 261 const TranslatableString &Prompt, int pos, int Max, int Min = 0); 262 wxSlider * AddVSlider(const TranslatableString &Prompt, int pos, int Max); 263 wxSpinCtrl * AddSpinCtrl(const TranslatableString &Prompt, 264 int Value, int Max, int Min); 265 wxTreeCtrl * AddTree(); 266 267 // Pass the same initValue to the sequence of calls to AddRadioButton and 268 // AddRadioButtonToGroup. 269 // The radio button is filled if selector == initValue 270 // Spoken name of the button defaults to the same as the prompt 271 // (after stripping menu codes): 272 wxRadioButton * AddRadioButton( 273 const TranslatableString & Prompt, int selector = 0, int initValue = 0 ); 274 wxRadioButton * AddRadioButtonToGroup( 275 const TranslatableString & Prompt, int selector = 1, int initValue = 0 ); 276 277 // Only the last button specified as default (if more than one) will be 278 // Always ORs the flags with wxALL (which affects borders): 279 wxButton * AddButton( 280 const TranslatableString & Text, int PositionFlags = wxALIGN_CENTRE, 281 bool setDefault = false ); 282 // Only the last button specified as default (if more than one) will be 283 // Always ORs the flags with wxALL (which affects borders): 284 wxBitmapButton * AddBitmapButton( 285 const wxBitmap &Bitmap, int PositionFlags = wxALIGN_CENTRE, 286 bool setDefault = false ); 287 // When PositionFlags is 0, applies wxALL (which affects borders), 288 // and either wxALIGN_CENTER (if bCenter) or else wxEXPAND 289 wxStaticText * AddVariableText( 290 const TranslatableString &Str, bool bCenter = false, 291 int PositionFlags = 0, int wrapWidth = 0); 292 ReadOnlyText * AddReadOnlyText( 293 const TranslatableString &Caption, 294 const wxString &Value); 295 wxTextCtrl * AddTextBox( 296 const TranslatableString &Caption, 297 const wxString &Value, const int nChars); 298 wxTextCtrl * AddNumericTextBox( 299 const TranslatableString &Caption, 300 const wxString &Value, const int nChars); 301 wxTextCtrl * AddTextWindow(const wxString &Value); 302 wxListBox * AddListBox(const wxArrayStringEx &choices); 303 304 struct ListControlColumn{ 305 ListControlColumn( 306 const TranslatableString &h, 307 int f = wxLIST_FORMAT_LEFT, int w = wxLIST_AUTOSIZE) headingListControlColumn308 : heading(h), format(f), width(w) 309 {} 310 311 TranslatableString heading; 312 int format; 313 int width; 314 }; 315 wxListCtrl * AddListControl( 316 std::initializer_list<const ListControlColumn> columns = {}, 317 long listControlStyles = 0 318 ); 319 wxListCtrl * AddListControlReportMode( 320 std::initializer_list<const ListControlColumn> columns = {}, 321 long listControlStyles = 0 322 ); 323 324 wxGrid * AddGrid(); 325 wxCheckBox * AddCheckBox( const TranslatableString &Prompt, bool Selected); 326 wxCheckBox * AddCheckBoxOnRight( const TranslatableString &Prompt, bool Selected); 327 328 // These deleted overloads are meant to break compilation of old calls that 329 // passed literal "true" and "false" strings 330 wxCheckBox * AddCheckBox( const TranslatableString &Prompt, const wxChar *) = delete; 331 wxCheckBox * AddCheckBox( const TranslatableString &Prompt, const char *) = delete; 332 wxCheckBox * AddCheckBoxOnRight( const TranslatableString &Prompt, const wxChar *) = delete; 333 wxCheckBox * AddCheckBoxOnRight( const TranslatableString &Prompt, const char *) = delete; 334 335 wxComboBox * AddCombo( const TranslatableString &Prompt, 336 const wxString &Selected, const wxArrayStringEx & choices ); 337 wxChoice * AddChoice( const TranslatableString &Prompt, 338 const TranslatableStrings &choices, int Selected = -1 ); 339 wxChoice * AddChoice( const TranslatableString &Prompt, 340 const TranslatableStrings &choices, const TranslatableString &selected ); 341 void AddIcon( wxBitmap * pBmp); 342 void AddFixedText( 343 const TranslatableString & Str, bool bCenter = false, int wrapWidth = 0 ); 344 void AddConstTextBox( 345 const TranslatableString &Caption, const TranslatableString & Value ); 346 347 //-- Start and end functions. These are used for sizer, or other window containers 348 // and create the appropriate widget. 349 void StartHorizontalLay(int PositionFlags=wxALIGN_CENTRE, int iProp=1); 350 void EndHorizontalLay(); 351 352 void StartVerticalLay(int iProp=1); 353 void StartVerticalLay(int PositionFlags, int iProp); 354 void EndVerticalLay(); 355 356 void StartWrapLay(int PositionFlags=wxEXPAND, int iProp = 0); 357 void EndWrapLay(); 358 359 wxScrolledWindow * StartScroller(int iStyle=0); 360 void EndScroller(); 361 wxPanel * StartPanel(int iStyle=0); 362 void EndPanel(); 363 void StartMultiColumn(int nCols, int PositionFlags=wxALIGN_LEFT); 364 void EndMultiColumn(); 365 StartTwoColumn()366 void StartTwoColumn() {StartMultiColumn(2);}; EndTwoColumn()367 void EndTwoColumn() {EndMultiColumn();}; StartThreeColumn()368 void StartThreeColumn(){StartMultiColumn(3);}; EndThreeColumn()369 void EndThreeColumn(){EndMultiColumn();}; 370 371 wxStaticBox * StartStatic( const TranslatableString & Str, int iProp=0 ); 372 void EndStatic(); 373 374 wxNotebook * StartNotebook(); 375 void EndNotebook(); 376 377 wxSimplebook * StartSimplebook(); 378 void EndSimplebook(); 379 380 // Use within any kind of book control: 381 // IDs of notebook pages cannot be chosen by the caller 382 wxNotebookPage * StartNotebookPage( const TranslatableString & Name ); 383 384 void EndNotebookPage(); 385 386 wxPanel * StartInvisiblePanel(); 387 void EndInvisiblePanel(); 388 389 // SettingName is a key in Preferences. 390 void StartRadioButtonGroup( const ChoiceSetting &Setting ); 391 void EndRadioButtonGroup(); 392 393 bool DoStep( int iStep ); 394 int TranslateToIndex( const wxString &Value, const wxArrayStringEx &Choices ); 395 wxString TranslateFromIndex( const int nIn, const wxArrayStringEx &Choices ); 396 397 //-- Tie functions both add controls and also read/write to them. 398 399 wxTextCtrl * TieTextBox( 400 const TranslatableString &Caption, wxString & Value, const int nChars=0); 401 wxTextCtrl * TieTextBox( 402 const TranslatableString &Prompt, int &Selected, const int nChars=0); 403 wxTextCtrl * TieTextBox( 404 const TranslatableString &Prompt, double &Value, const int nChars=0); 405 406 wxTextCtrl * TieNumericTextBox( const TranslatableString &Prompt, int &Value, const int nChars=0); 407 wxTextCtrl * TieNumericTextBox( const TranslatableString &Prompt, double &Value, const int nChars=0); 408 409 wxCheckBox * TieCheckBox( const TranslatableString &Prompt, bool & Var ); 410 wxCheckBox * TieCheckBoxOnRight( const TranslatableString & Prompt, bool & Var ); 411 412 wxChoice * TieChoice( 413 const TranslatableString &Prompt, 414 TranslatableString &Selected, const TranslatableStrings &choices ); 415 wxChoice * TieChoice( 416 const TranslatableString &Prompt, int &Selected, const TranslatableStrings &choices ); 417 418 wxSlider * TieSlider( 419 const TranslatableString &Prompt, 420 int &pos, const int max, const int min = 0); 421 wxSlider * TieSlider( 422 const TranslatableString &Prompt, 423 double &pos, const double max, const double min = 0.0); 424 wxSlider * TieSlider( 425 const TranslatableString &Prompt, 426 float &pos, const float fMin, const float fMax); 427 wxSlider * TieVSlider( 428 const TranslatableString &Prompt, 429 float &pos, const float fMin, const float fMax); 430 431 // Must be called between a StartRadioButtonGroup / EndRadioButtonGroup pair, 432 // and as many times as there are values in the enumeration. 433 wxRadioButton * TieRadioButton(); 434 435 wxSpinCtrl * TieSpinCtrl( const TranslatableString &Prompt, 436 int &Value, const int max, const int min = 0 ); 437 438 439 //-- Variants of the standard Tie functions which do two step exchange in one go 440 // Note that unlike the other Tie functions, ALL the arguments are const. 441 // That's because the data is being exchanged between the dialog and mpShuttle 442 // so it doesn't need an argument that is writeable. 443 virtual wxCheckBox * TieCheckBox( 444 const TranslatableString &Prompt, 445 const BoolSetting &Setting); 446 virtual wxCheckBox * TieCheckBoxOnRight( 447 const TranslatableString &Prompt, 448 const BoolSetting &Setting); 449 450 virtual wxChoice *TieChoice( 451 const TranslatableString &Prompt, 452 const ChoiceSetting &choiceSetting ); 453 454 // This overload presents what is really a numerical setting as a choice among 455 // commonly used values, but the choice is not necessarily exhaustive. 456 // This behaves just like the previous for building dialogs, but the 457 // behavior is different when the call is intercepted for purposes of 458 // emitting scripting information about Preferences. 459 virtual wxChoice * TieNumberAsChoice( 460 const TranslatableString &Prompt, 461 const IntSetting &Setting, 462 const TranslatableStrings & Choices, 463 const std::vector<int> * pInternalChoices = nullptr, 464 int iNoMatchSelector = 0 ); 465 466 virtual wxTextCtrl * TieTextBox( 467 const TranslatableString &Prompt, 468 const StringSetting &Setting, 469 const int nChars); 470 virtual wxTextCtrl * TieIntegerTextBox( 471 const TranslatableString & Prompt, 472 const IntSetting &Setting, 473 const int nChars); 474 virtual wxTextCtrl * TieNumericTextBox( 475 const TranslatableString & Prompt, 476 const DoubleSetting &Setting, 477 const int nChars); 478 virtual wxSlider * TieSlider( 479 const TranslatableString & Prompt, 480 const IntSetting &Setting, 481 const int max, 482 const int min = 0); 483 virtual wxSpinCtrl * TieSpinCtrl( 484 const TranslatableString &Prompt, 485 const IntSetting &Setting, 486 const int max, 487 const int min); 488 //-- End of variants. SetBorder(int Border)489 void SetBorder( int Border ) {miBorder = Border;}; 490 int GetBorder() const noexcept; SetSizerProportion(int iProp)491 void SetSizerProportion( int iProp ) {miSizerProp = iProp;}; 492 void SetStretchyCol( int i ); 493 void SetStretchyRow( int i ); 494 495 //--Some Additions since June 2007 that don't fit in elsewhere... GetParent()496 wxWindow * GetParent() 497 { 498 // This assertion justifies the use of safenew in many places where GetParent() 499 // is used to construct a window 500 wxASSERT(mpParent != NULL); 501 return mpParent; 502 } 503 ShuttleGuiBase & Prop( int iProp ); 504 void UseUpId(); 505 GetSizer()506 wxSizer * GetSizer() {return mpSizer;} 507 508 static void ApplyItem( int step, const DialogDefinition::Item &item, 509 wxWindow *pWind, wxWindow *pDlg ); 510 511 protected: 512 void SetProportions( int Default ); 513 void PushSizer(); 514 void PopSizer(); 515 516 void UpdateSizersCore( bool bPrepend, int Flags, bool prompt = false ); 517 void UpdateSizers(); 518 void UpdateSizersC(); 519 void UpdateSizersAtStart(); 520 521 long GetStyle( long Style ); 522 523 private: 524 void DoInsertListColumns( 525 wxListCtrl *pListCtrl, 526 long listControlStyles, 527 std::initializer_list<const ListControlColumn> columns ); 528 529 protected: 530 wxWindow *const mpDlg; 531 wxSizer * pSizerStack[ nMaxNestedSizers ]; 532 533 std::unique_ptr<Shuttle> mpShuttle; /*! Controls source/destination of shuttled data. You can 534 leave this NULL if you are shuttling to variables */ 535 int miNoMatchSelector; //! Used in choices to determine which item to use on no match. 536 537 teShuttleMode mShuttleMode; 538 539 int miSizerProp; 540 int mSizerDepth; 541 int miBorder; 542 int miProp; 543 544 // See UseUpId() for explanation of these three. 545 int miId; 546 int miIdNext; 547 int miIdSetByUser; 548 // Proportion set by user rather than default. 549 int miPropSetByUser; 550 551 bool * mpbOptionalFlag; 552 553 std::unique_ptr<wxSizer> mpSubSizer; 554 wxSizer * mpSizer; 555 wxWindow * mpParent; 556 wxWindow * mpWind; 557 558 private: 559 void DoDataShuttle( const wxString &Name, WrappedType & WrappedRef ); 560 wxCheckBox * DoTieCheckBoxOnRight( const TranslatableString & Prompt, WrappedType & WrappedRef ); 561 wxTextCtrl * DoTieTextBox( 562 const TranslatableString &Prompt, 563 WrappedType & WrappedRef, const int nChars); 564 wxTextCtrl * DoTieNumericTextBox( 565 const TranslatableString &Prompt, WrappedType & WrappedRef, const int nChars); 566 wxCheckBox * DoTieCheckBox( const TranslatableString &Prompt, WrappedType & WrappedRef ); 567 wxSlider * DoTieSlider( 568 const TranslatableString &Prompt, 569 WrappedType & WrappedRef, const int max, const int min = 0 ); 570 wxSpinCtrl * DoTieSpinCtrl( const TranslatableString &Prompt, 571 WrappedType & WrappedRef, const int max, const int min = 0 ); 572 573 std::vector<EnumValueSymbol> mRadioSymbols; 574 wxString mRadioSettingName; /// The setting controlled by a group. 575 Optional<WrappedType> mRadioValue; /// The wrapped value associated with the active radio button. 576 int mRadioCount; /// The index of this radio item. -1 for none. 577 wxString mRadioValueString; /// Unwrapped string value. 578 wxRadioButton * DoAddRadioButton( 579 const TranslatableString &Prompt, int style, int selector, int initValue); 580 581 protected: 582 DialogDefinition::Item mItem; 583 }; 584 585 // A rarely used helper function that sets a pointer 586 // ONLY if the value it is to be set to is non NULL. 587 extern void SetIfCreated( wxChoice *&Var, wxChoice * Val ); 588 extern void SetIfCreated( wxTextCtrl *&Var, wxTextCtrl * Val ); 589 extern void SetIfCreated( wxStaticText *&Var, wxStaticText * Val ); 590 591 class GuiWaveTrack; 592 class AttachableScrollBar; 593 class ViewInfo; 594 595 #include <wx/defs.h> // to get wxSB_HORIZONTAL 596 597 // CreateStdButtonSizer defs...should probably move to widgets subdir 598 enum 599 { 600 eOkButton = 0x0001, 601 eCancelButton = 0x0002, 602 eYesButton = 0x0004, 603 eNoButton = 0x0008, 604 eHelpButton = 0x0010, 605 ePreviewButton = 0x0020, 606 eDebugButton = 0x0040, 607 eSettingsButton= 0x0080, 608 ePreviewDryButton = 0x0100, 609 eApplyButton = 0x0200, 610 eCloseButton = 0x0400, 611 }; 612 613 enum 614 { 615 // ePreviewID = wxID_LOWEST - 1, 616 // But there is a wxID_PREVIEW 617 ePreviewID = wxID_PREVIEW, 618 619 eDebugID = wxID_LOWEST - 2, 620 eSettingsID = wxID_LOWEST - 3, 621 ePreviewDryID = wxID_LOWEST - 4, 622 eCloseID = wxID_CANCEL 623 }; 624 625 AUDACITY_DLL_API std::unique_ptr<wxSizer> CreateStdButtonSizer( wxWindow *parent, 626 long buttons = eOkButton | eCancelButton, 627 wxWindow *extra = NULL ); 628 629 // ShuttleGui extends ShuttleGuiBase with Audacity specific extensions. 630 class AUDACITY_DLL_API ShuttleGui /* not final */ : public ShuttleGuiBase 631 { 632 public: 633 ShuttleGui( 634 wxWindow * pParent, teShuttleMode ShuttleMode, 635 bool vertical = true, // Choose layout direction of topmost level sizer 636 wxSize minSize = { 250, 100 } 637 ); 638 ~ShuttleGui(void); 639 public: 640 ShuttleGui & Optional( bool & bVar ); 641 ShuttleGui & Id(int id ); 642 643 // Only the last item specified as focused (if more than one) will be 644 ShuttleGui & Focus( bool focused = true ) 645 { 646 std::move( mItem ).Focus( focused ); 647 return *this; 648 } 649 650 ShuttleGui &Disable( bool disabled = true ) 651 { 652 std::move( mItem ).Disable( disabled ); 653 return *this; 654 } 655 ToolTip(const TranslatableString & tip)656 ShuttleGui & ToolTip( const TranslatableString &tip ) 657 { 658 std::move( mItem ).ToolTip( tip ); 659 return *this; 660 } 661 662 // Menu codes in the translation will be stripped Name(const TranslatableString & name)663 ShuttleGui & Name( const TranslatableString &name ) 664 { 665 std::move( mItem ).Name( name ); 666 return *this; 667 } 668 669 // Append a space, then the translation of the given string, to control name 670 // (not the title or label: this affects the screen reader behavior) NameSuffix(const TranslatableString & suffix)671 ShuttleGui & NameSuffix( const TranslatableString &suffix ) 672 { 673 std::move( mItem ).NameSuffix( suffix ); 674 return *this; 675 } 676 677 template<typename Factory> Validator(const Factory & f)678 ShuttleGui& Validator( const Factory &f ) 679 { 680 if ( GetMode() == eIsCreating ) 681 std::move( mItem ).Validator( f ); 682 return *this; 683 } 684 685 // This allows further abbreviation of the previous: 686 template<typename V, typename...Args> Validator(Args &&...args)687 ShuttleGui& Validator( Args&& ...args ) 688 { 689 if ( GetMode() == eIsCreating ) 690 std::move( mItem ).Validator<V>( std::forward<Args>(args)... ); 691 return *this; 692 } 693 694 // Dispatch events from the control to the dialog 695 // The template type deduction ensures consistency between the argument type 696 // and the event type. It does not (yet) ensure correctness of the type of 697 // the handler object. 698 template< typename Tag, typename Argument, typename Handler > 699 auto ConnectRoot( 700 wxEventTypeTag<Tag> eventType, 701 void (Handler::*func)(Argument&) 702 ) 703 -> typename std::enable_if< 704 std::is_base_of<Argument, Tag>::value, 705 ShuttleGui& 706 >::type 707 { 708 std::move( mItem ).ConnectRoot( eventType, func ); 709 return *this; 710 } 711 Position(int flags)712 ShuttleGui & Position( int flags ) 713 { 714 std::move( mItem ).Position( flags ); 715 return *this; 716 } 717 Size(wxSize size)718 ShuttleGui & Size( wxSize size ) 719 { 720 std::move( mItem ).Size( size ); 721 return *this; 722 } 723 724 // Prop() sets the proportion value, defined as in wxSizer::Add(). Prop(int iProp)725 ShuttleGui & Prop( int iProp ){ ShuttleGuiBase::Prop(iProp); return *this;}; // Has to be here too, to return a ShuttleGui and not a ShuttleGuiBase. 726 Style(long iStyle)727 ShuttleGui & Style( long iStyle ) 728 { 729 std::move( mItem ).Style( iStyle ); 730 return *this; 731 } 732 MinSize()733 ShuttleGui &MinSize() // set best size as min size 734 { std::move( mItem ).MinSize(); return *this; } MinSize(wxSize sz)735 ShuttleGui &MinSize( wxSize sz ) 736 { std::move( mItem ).MinSize( sz ); return *this; } 737 738 // The first of these buttons, if any, that is included will be default: 739 // Apply, Yes, OK 740 void AddStandardButtons( 741 long buttons = eOkButton | eCancelButton, wxWindow *extra = NULL ); 742 743 wxSizerItem * AddSpace( int width, int height, int prop = 0 ); AddSpace(int size)744 wxSizerItem * AddSpace( int size ) { return AddSpace( size, size ); }; 745 746 // Calculate width of a choice control adequate for the items, maybe after 747 // the dialog is created but the items change. 748 static void SetMinSize( wxWindow *window, const TranslatableStrings & items ); 749 static void SetMinSize( wxWindow *window, const wxArrayStringEx & items ); 750 // static void SetMinSize( wxWindow *window, const std::vector<int> & items ); 751 GetMode()752 teShuttleMode GetMode() { return mShuttleMode; }; 753 }; 754 755 //! Convenience function often useful when adding choice controls 756 AUDACITY_DLL_API TranslatableStrings Msgids( 757 const EnumValueSymbol strings[], size_t nStrings); 758 759 //! Convenience function often useful when adding choice controls 760 AUDACITY_DLL_API TranslatableStrings Msgids( const std::vector<EnumValueSymbol> &strings ); 761 762 #endif 763