diff --git a/include/wx/dialog.h b/include/wx/dialog.h index 855ce352c8..17dc6c0ac1 100644 --- a/include/wx/dialog.h +++ b/include/wx/dialog.h @@ -20,6 +20,9 @@ #include "wx/containr.h" #include "wx/toplevel.h" +class WXDLLEXPORT wxSizer; +class WXDLLEXPORT wxStdDialogButtonSizer; + #define wxDIALOG_NO_PARENT 0x0001 // Don't make owned by apps top window #ifdef __WXWINCE__ @@ -56,6 +59,7 @@ public: #if wxUSE_BUTTON // places buttons into a horizontal wxBoxSizer wxSizer *CreateButtonSizer( long flags ); + wxStdDialogButtonSizer *CreateStdDialogButtonSizer( long flags ); #endif // wxUSE_BUTTON protected: diff --git a/include/wx/sizer.h b/include/wx/sizer.h index e13f202903..11915e11b6 100644 --- a/include/wx/sizer.h +++ b/include/wx/sizer.h @@ -18,6 +18,7 @@ #include "wx/defs.h" +#include "wx/button.h" #include "wx/window.h" #include "wx/frame.h" #include "wx/dialog.h" @@ -641,6 +642,48 @@ private: #endif // wxUSE_STATBOX +class WXDLLEXPORT wxStdDialogButtonSizer: public wxBoxSizer +{ +public: + wxStdDialogButtonSizer(); + // Constructor just creates a new wxBoxSizer, not much else. + // Box sizer orientation is automatically determined here: + // vertical for PDAs, horizontal for everything else? + + void AddButton(wxButton *button); + // Checks button ID against system IDs and sets one of the pointers below + // to this button. + // Does not do any sizer-related things here. + + // Question: what to do for non-supported button IDs? assert? + + void Finalise(); + // All platform-specific code here, checks which buttons exist and add + // them to the sizer accordingly. + // Note - one potential hack on Mac we could use here, + // if m_buttonAffirmative is wxID_SAVE then ensure wxID_SAVE + // is set to _("Save") and m_buttonNegative is set to _("Don't Save") + // I wouldn't add any other hacks like that into here, + // but this one I can see being useful. + + wxButton *GetAffirmativeButton() const { return m_buttonAffirmative; } + wxButton *GetApplyButton() const { return m_buttonApply; } + wxButton *GetNegativeButton() const { return m_buttonNegative; } + wxButton *GetCancelButton() const { return m_buttonCancel; } + wxButton *GetHelpButton() const { return m_buttonHelp; } + +protected: + wxButton *m_buttonAffirmative; + // wxID_OK, wxID_YES, wxID_SAVE go here + wxButton *m_buttonApply; + wxButton *m_buttonNegative; // wxID_NO + wxButton *m_buttonCancel; + wxButton *m_buttonHelp; + +private: + DECLARE_CLASS(wxStdDialogButtonSizer) + //DECLARE_NO_COPY_CLASS(wxStdDialogButtonSizer) +}; #if WXWIN_COMPATIBILITY_2_4 // NB: wxBookCtrlSizer and wxNotebookSizer are deprecated, they diff --git a/src/common/dlgcmn.cpp b/src/common/dlgcmn.cpp index b599012aa5..26fa7ab530 100644 --- a/src/common/dlgcmn.cpp +++ b/src/common/dlgcmn.cpp @@ -170,92 +170,45 @@ wxSizer *wxDialogBase::CreateTextSizer( const wxString& message ) wxSizer *wxDialogBase::CreateButtonSizer( long flags ) { - bool is_pda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA); + return CreateStdDialogButtonSizer( flags ); +} - // If we have a PDA screen, put yes/no button over - // all other buttons, otherwise on the left side. - wxBoxSizer *box = is_pda ? new wxBoxSizer( wxVERTICAL ) : new wxBoxSizer( wxHORIZONTAL ); - - wxBoxSizer *inner_yes_no = NULL; - - // Only create sizer containing yes/no - // if it is actually required - if ( (flags & wxYES_NO) != 0 ) - { - inner_yes_no = new wxBoxSizer( wxHORIZONTAL ); - box->Add( inner_yes_no, 0, wxBOTTOM, 10 ); +wxStdDialogButtonSizer *wxDialogBase::CreateStdDialogButtonSizer( long flags ) +{ + wxStdDialogButtonSizer *sizer = new wxStdDialogButtonSizer(); + wxButton *ok = NULL; + wxButton *cancel = NULL; + wxButton *yes = NULL; + wxButton *no = NULL; + wxButton *help = NULL; + + if (flags & wxOK){ + ok = new wxButton(this, wxID_OK, _("OK")); + sizer->AddButton(ok); } - - wxBoxSizer *inner_rest = new wxBoxSizer( wxHORIZONTAL ); - box->Add( inner_rest, 0, 0, 0 ); - -#if defined(__WXMSW__) || defined(__WXMAC__) - static const int margin = 6; -#else - static const int margin = 10; -#endif - - wxButton *ok = (wxButton *) NULL; - wxButton *yes = (wxButton *) NULL; - wxButton *no = (wxButton *) NULL; - - // always show an OK button, unless we have both YES and NO - if ( (flags & wxYES_NO) != wxYES_NO ) - flags |= wxOK; - - if (flags & wxYES) - { - yes = new wxButton(this, wxID_YES, wxEmptyString, - wxDefaultPosition, wxDefaultSize, wxCLIP_SIBLINGS); - inner_yes_no->Add( yes, 0, wxLEFT|wxRIGHT, margin ); + + if (flags & wxCANCEL){ + cancel = new wxButton(this, wxID_CANCEL, _("Cancel")); + sizer->AddButton(cancel); } - if (flags & wxNO) - { - no = new wxButton(this, wxID_NO, wxEmptyString, - wxDefaultPosition, wxDefaultSize, wxCLIP_SIBLINGS); - inner_yes_no->Add( no, 0, wxLEFT|wxRIGHT, margin ); + + if (flags & wxYES){ + yes = new wxButton(this, wxID_YES, _("Yes")); + sizer->AddButton(yes); } - - if (flags & wxOK) - { - ok = new wxButton(this, wxID_OK, wxEmptyString, - wxDefaultPosition, wxDefaultSize, wxCLIP_SIBLINGS); - inner_rest->Add( ok, 0, wxLEFT|wxRIGHT, margin ); + + if (flags & wxNO){ + no = new wxButton(this, wxID_NO, _("No")); + sizer->AddButton(no); } - - if (flags & wxFORWARD) - inner_rest->Add(new wxButton(this, wxID_FORWARD, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - wxCLIP_SIBLINGS), - 0, wxLEFT|wxRIGHT, margin); - - if (flags & wxBACKWARD) - inner_rest->Add(new wxButton(this, wxID_BACKWARD, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - wxCLIP_SIBLINGS), - 0, wxLEFT|wxRIGHT, margin); - - if (flags & wxSETUP) - inner_rest->Add( new wxButton( this, wxID_SETUP, _("Setup"),wxDefaultPosition,wxDefaultSize,wxCLIP_SIBLINGS ), 0, wxLEFT|wxRIGHT, margin ); - - if (flags & wxMORE) - inner_rest->Add( new wxButton( this, wxID_MORE, _("More..."),wxDefaultPosition,wxDefaultSize,wxCLIP_SIBLINGS ), 0, wxLEFT|wxRIGHT, margin ); - - if (flags & wxHELP) - inner_rest->Add(new wxButton(this, wxID_HELP, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - wxCLIP_SIBLINGS), - 0, wxLEFT|wxRIGHT, margin); - - if (flags & wxCANCEL) - { - wxButton *cancel = new wxButton(this, wxID_CANCEL, wxEmptyString, - wxDefaultPosition, wxDefaultSize, - wxCLIP_SIBLINGS); - inner_rest->Add( cancel, 0, wxLEFT|wxRIGHT, margin ); + + if (flags & wxHELP){ + help = new wxButton(this, wxID_HELP, _("Help")); + sizer->AddButton(help); } - - // choose the default button + + sizer->Finalise(); + if (flags & wxNO_DEFAULT) { if (no) @@ -278,7 +231,8 @@ wxSizer *wxDialogBase::CreateButtonSizer( long flags ) } } - return box; + return sizer; } + #endif // wxUSE_BUTTON diff --git a/src/common/sizer.cpp b/src/common/sizer.cpp index 93f988572e..307ab3adc8 100644 --- a/src/common/sizer.cpp +++ b/src/common/sizer.cpp @@ -24,6 +24,7 @@ #include "wx/sizer.h" #include "wx/utils.h" #include "wx/statbox.h" +#include "wx/settings.h" #include "wx/listimpl.cpp" #if WXWIN_COMPATIBILITY_2_4 #include "wx/notebook.h" @@ -43,6 +44,7 @@ IMPLEMENT_CLASS(wxBoxSizer, wxSizer) #if wxUSE_STATBOX IMPLEMENT_CLASS(wxStaticBoxSizer, wxBoxSizer) #endif +IMPLEMENT_CLASS(wxStdDialogButtonSizer, wxBoxSizer) WX_DEFINE_EXPORTED_LIST( wxSizerItemList ); @@ -1639,6 +1641,141 @@ void wxStaticBoxSizer::ShowItems( bool show ) #endif // wxUSE_STATBOX +wxStdDialogButtonSizer::wxStdDialogButtonSizer() + : wxBoxSizer(wxHORIZONTAL) +{ + bool is_pda = (wxSystemSettings::GetScreenType() <= wxSYS_SCREEN_PDA); + + // If we have a PDA screen, put yes/no button over + // all other buttons, otherwise on the left side. + if (is_pda) + m_orient = wxVERTICAL; + + m_buttonAffirmative = NULL; + m_buttonApply = NULL; + m_buttonNegative = NULL; + m_buttonCancel = NULL; + m_buttonHelp = NULL; +} + +void wxStdDialogButtonSizer::AddButton(wxButton *mybutton) +{ + switch (mybutton->GetId()) + { + case wxID_OK: + case wxID_YES: + case wxID_SAVE: + m_buttonAffirmative = mybutton; + break; + case wxID_APPLY: + m_buttonApply = mybutton; + break; + case wxID_NO: + m_buttonNegative = mybutton; + break; + case wxID_CANCEL: + m_buttonCancel = mybutton; + break; + case wxID_HELP: + m_buttonHelp = mybutton; + break; + default: + break; + } +} + +void wxStdDialogButtonSizer::Finalise() +{ +#ifdef __WXMAC__ + Add(0, 0, 0, wxLEFT, 6); + if (m_buttonHelp) + Add((wxWindow*)m_buttonHelp, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 6); + + if (m_buttonNegative){ + // HIG POLICE BULLETIN - destructive buttons need extra padding + // 24 pixels on either side + Add((wxWindow*)m_buttonNegative, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 12); + } + + // extra whitespace between help/negative and cancel/ok buttons + Add(0, 0, 1, wxEXPAND, 0); + + if (m_buttonCancel){ + Add((wxWindow*)m_buttonCancel, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 6); + // Cancel or help should be default + // m_buttonCancel->SetDefaultButton(); + } + + // Ugh, Mac doesn't really have apply dialogs, so I'll just + // figure the best place is between Cancel and OK + if (m_buttonApply) + Add((wxWindow*)m_buttonApply, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 6); + + if (m_buttonAffirmative){ + Add((wxWindow*)m_buttonAffirmative, 0, wxALIGN_CENTRE | wxLEFT, 6); + + if (m_buttonAffirmative->GetId() == wxID_SAVE){ + // these buttons have set labels under Mac so we should use them + m_buttonAffirmative->SetLabel(_("Save")); + m_buttonNegative->SetLabel(_("Don't Save")); + } + } + + // Extra space around and at the right + Add(12, 24); +#elif defined(__WXGTK20__) + Add(0, 0, 0, wxLEFT, 9); + if (m_buttonHelp) + Add((wxWindow*)m_buttonHelp, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 3); + + // extra whitespace between help and cancel/ok buttons + Add(0, 0, 1, wxEXPAND, 0); + + if (m_buttonNegative){ + Add((wxWindow*)m_buttonNegative, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 3); + } + + if (m_buttonCancel){ + Add((wxWindow*)m_buttonCancel, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 3); + // Cancel or help should be default + // m_buttonCancel->SetDefaultButton(); + } + + if (m_buttonApply) + Add((wxWindow*)m_buttonApply, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, 3); + + if (m_buttonAffirmative) + Add((wxWindow*)m_buttonAffirmative, 0, wxALIGN_CENTRE | wxLEFT, 6); +#else + // do the same thing for GTK1 and Windows platforms + // and assume any platform not accounted for here will use + // Windows style + Add(0, 0, 0, wxLEFT, 9); + if (m_buttonHelp) + Add((wxWindow*)m_buttonHelp, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, m_buttonHelp->ConvertDialogToPixels(wxSize(4, 0)).x); + + // extra whitespace between help and cancel/ok buttons + Add(0, 0, 1, wxEXPAND, 0); + + if (m_buttonApply) + Add((wxWindow*)m_buttonApply, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, m_buttonApply->ConvertDialogToPixels(wxSize(4, 0)).x); + + if (m_buttonAffirmative){ + Add((wxWindow*)m_buttonAffirmative, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, m_buttonAffirmative->ConvertDialogToPixels(wxSize(4, 0)).x); + } + + if (m_buttonNegative){ + Add((wxWindow*)m_buttonNegative, 0, wxALIGN_CENTRE | wxLEFT | wxRIGHT, m_buttonNegative->ConvertDialogToPixels(wxSize(4, 0)).x); + } + + if (m_buttonCancel){ + Add((wxWindow*)m_buttonCancel, 0, wxALIGN_CENTRE | wxLEFT, m_buttonCancel->ConvertDialogToPixels(wxSize(4, 0)).x); + // Cancel or help should be default + // m_buttonCancel->SetDefaultButton(); + } + +#endif +} #if WXWIN_COMPATIBILITY_2_4 diff --git a/src/generic/choicdgg.cpp b/src/generic/choicdgg.cpp index bb2a38dc56..2b5b11b2a2 100644 --- a/src/generic/choicdgg.cpp +++ b/src/generic/choicdgg.cpp @@ -292,7 +292,7 @@ bool wxAnyChoiceDialog::Create(wxWindow *parent, #endif // 4) buttons - topsizer->Add( CreateButtonSizer( styleDlg & (wxOK|wxCANCEL) ), 0, wxCENTRE | wxALL, 10 ); + topsizer->Add( CreateButtonSizer( styleDlg & (wxOK|wxCANCEL) ), 0, wxEXPAND | wxALL, 10 ); #endif // !__SMARTPHONE__ diff --git a/src/generic/colrdlgg.cpp b/src/generic/colrdlgg.cpp index a5d264b557..80b13b5337 100644 --- a/src/generic/colrdlgg.cpp +++ b/src/generic/colrdlgg.cpp @@ -295,7 +295,7 @@ void wxGenericColourDialog::CreateWidgets() // 3) buttons wxSizer *buttonsizer = CreateButtonSizer( wxOK|wxCANCEL ); buttonsizer->Add( new wxButton(this, wxID_ADD_CUSTOM, _("Add to custom colours") ), 0, wxLEFT|wxRIGHT, 10 ); - topSizer->Add( buttonsizer, 0, wxCENTRE | wxALL, 10 ); + topSizer->Add( buttonsizer, 0, wxEXPAND | wxALL, 10 ); SetAutoLayout( true ); SetSizer( topSizer ); diff --git a/src/generic/dirdlgg.cpp b/src/generic/dirdlgg.cpp index a07fbd497e..327bcbc81e 100644 --- a/src/generic/dirdlgg.cpp +++ b/src/generic/dirdlgg.cpp @@ -190,17 +190,7 @@ wxGenericDirDialog::wxGenericDirDialog(wxWindow* parent, const wxString& title, #endif // 4) Buttons - buttonsizer = new wxBoxSizer( wxHORIZONTAL ); - - // OK and Cancel button should be at the right bottom - wxButton* okButton = new wxButton(this, wxID_OK); - buttonsizer->Add( okButton, 0, wxLEFT|wxRIGHT, 10 ); - wxButton* cancelButton = new wxButton(this, wxID_CANCEL); - buttonsizer->Add( cancelButton, 0, wxLEFT|wxRIGHT, 10 ); - - topsizer->Add( buttonsizer, 0, wxLEFT|wxTOP|wxBOTTOM | wxALIGN_RIGHT, 10 ); - - okButton->SetDefault(); + topsizer->Add( CreateButtonSizer( wxOK|wxCANCEL ), 0, wxEXPAND | wxALL, 10 ); #endif // !__SMARTPHONE__ diff --git a/src/generic/msgdlgg.cpp b/src/generic/msgdlgg.cpp index 041fe3301a..cc4ed5c81e 100644 --- a/src/generic/msgdlgg.cpp +++ b/src/generic/msgdlgg.cpp @@ -118,7 +118,7 @@ wxGenericMessageDialog::wxGenericMessageDialog( wxWindow *parent, // 4) buttons topsizer->Add( CreateButtonSizer( style & (wxOK|wxCANCEL|wxYES_NO|wxYES_DEFAULT|wxNO_DEFAULT) ), - 0, wxCENTRE | wxALL, 10 ); + 0, wxEXPAND | wxALL, 10 ); SetAutoLayout( true ); SetSizer( topsizer ); diff --git a/src/generic/numdlgg.cpp b/src/generic/numdlgg.cpp index d8a6f2ae5f..a4455a0b92 100644 --- a/src/generic/numdlgg.cpp +++ b/src/generic/numdlgg.cpp @@ -138,7 +138,7 @@ wxNumberEntryDialog::wxNumberEntryDialog(wxWindow *parent, #endif // 4) buttons - topsizer->Add( CreateButtonSizer( wxOK|wxCANCEL ), 0, wxCENTRE | wxALL, 10 ); + topsizer->Add( CreateButtonSizer( wxOK|wxCANCEL ), 0, wxEXPAND | wxALL, 10 ); #endif // !__SMARTPHONE__ diff --git a/src/generic/prntdlgg.cpp b/src/generic/prntdlgg.cpp index 9b9e3846c0..f3995f5d6d 100644 --- a/src/generic/prntdlgg.cpp +++ b/src/generic/prntdlgg.cpp @@ -252,7 +252,7 @@ void wxGenericPrintDialog::Init(wxWindow * WXUNUSED(parent)) // 5) buttons - mainsizer->Add( CreateButtonSizer( wxOK|wxCANCEL), 0, wxCENTER|wxALL, 10 ); + mainsizer->Add( CreateButtonSizer( wxOK|wxCANCEL), 0, wxEXPAND|wxALL, 10 ); SetAutoLayout( true ); SetSizer( mainsizer ); @@ -656,7 +656,7 @@ void wxGenericPrintSetupDialog::Init(wxPrintData* data) // buttons - main_sizer->Add( CreateButtonSizer( wxOK|wxCANCEL), 0, wxCENTER|wxALL, 10 ); + main_sizer->Add( CreateButtonSizer( wxOK|wxCANCEL), 0, wxEXPAND|wxALL, 10 ); SetAutoLayout( true ); SetSizer( main_sizer ); @@ -920,7 +920,7 @@ wxGenericPageSetupDialog::wxGenericPageSetupDialog( wxWindow *parent, // if (m_printData.GetEnableHelp()) // wxButton *helpButton = new wxButton(this, (wxFunction)wxGenericPageSetupHelpProc, _("Help"), wxDefaultCoord, wxDefaultCoord, buttonWidth, buttonHeight); - mainsizer->Add( buttonsizer, 0, wxCENTER|wxALL, 10 ); + mainsizer->Add( buttonsizer, 0, wxEXPAND|wxALL, 10 ); SetAutoLayout( true ); diff --git a/src/generic/textdlgg.cpp b/src/generic/textdlgg.cpp index b89b9d5de3..70d8a220ff 100644 --- a/src/generic/textdlgg.cpp +++ b/src/generic/textdlgg.cpp @@ -125,7 +125,7 @@ wxTextEntryDialog::wxTextEntryDialog(wxWindow *parent, #endif // 4) buttons - topsizer->Add( CreateButtonSizer( style ), 0, wxCENTRE | wxALL, 10 ); + topsizer->Add( CreateButtonSizer( style ), 0, wxEXPAND | wxALL, 10 ); #endif // !__SMARTPHONE__