diff --git a/docs/latex/wx/wizard.tex b/docs/latex/wx/wizard.tex index 190b9a3894..10de3469b7 100644 --- a/docs/latex/wx/wizard.tex +++ b/docs/latex/wx/wizard.tex @@ -63,12 +63,17 @@ the wizard (this event may also be vetoed).} \membersection{wxWizard::Create}\label{wxwizardcreate} -\func{static wxWizard*}{Create}{\param{wxWindow* }{parent}, \param{int }{id = -1}, \param{const wxString\& }{title = wxEmptyString}, \param{const wxBitmap\& }{bitmap = wxNullBitmap}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}} +\func{static wxWizard*}{Create}{\param{wxWindow* }{parent}, \param{int }{id = -1}, \param{const wxString\& }{title = wxEmptyString}, \param{const wxBitmap\& }{bitmap = wxNullBitmap}, \param{const wxPoint\& }{pos = wxDefaultPosition}} Creates the wizard dialog. The returned pointer should not be deleted directly, you should rather call {\tt Destroy()} on it and wxWindows will delete it itself. +Notice that unlike almost all other wxWindows classes, there is no {\it size} +parameter in wxWizard constructor because the wizard will have a predefined +default size by default. If you want to change this, you should use the +\helpref{SetPageSize}{wxwizardsetpagesize} function. + \wxheading{Parameters} \docparam{parent}{The parent window, may be NULL.} @@ -83,9 +88,6 @@ also \helpref{GetBitmap}{wxwizardpagegetbitmap}.} \docparam{pos}{The position of the dialog, it will be centered on the screen by default.} -\docparam{size}{The size of the dialog. Reasonable default size is used if -this parameter is not specified.} - \membersection{wxWizard::RunWizard}\label{wxwizardrunwizard} \func{bool}{RunWizard}{\param{wxWizardPage* }{firstPage}} @@ -107,3 +109,16 @@ Get the current page while the wizard is running. {\tt NULL} is returned if Returns the size available for the pages. +\membersection{wxWizard::SetPageSize}\label{wxwizardsetpagesize} + +\func{void}{SetPageSize}{\param{const wxSize\& }{sizePage}} + +Sets the minimal size to be made available for the wizard pages. The wizard +will take into account the size of the bitmap (if any) itself. Also, the +wizard will never be smaller than the default size. + +The recommended way to use this function is to layout all wizard pages using +the sizers (even though the wizard is not resizeable) and then use +\helpref{wxSizer::CalcMin}{wxsizercalcmin} in a loop to calculate the maximum +of minimal sizes of the pages and pass it to SetPageSize(). + diff --git a/include/wx/generic/wizard.h b/include/wx/generic/wizard.h index 7c26f62b85..32186f6bab 100644 --- a/include/wx/generic/wizard.h +++ b/include/wx/generic/wizard.h @@ -24,12 +24,12 @@ public: int id = -1, const wxString& title = wxEmptyString, const wxBitmap& bitmap = wxNullBitmap, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize); + const wxPoint& pos = wxDefaultPosition); // implement base class pure virtuals virtual bool RunWizard(wxWizardPage *firstPage); virtual wxWizardPage *GetCurrentPage() const; + virtual void SetPageSize(const wxSize& size); virtual wxSize GetPageSize() const; // implementation only from now on @@ -39,15 +39,27 @@ public: bool IsRunning() const { return m_page != NULL; } // show the prev/next page, but call TransferDataFromWindow on the current - // page first and return FALSE without changing the page if it returns - // FALSE + // page first and return FALSE without changing the page if + // TransferDataFromWindow() returns FALSE - otherwise, returns TRUE bool ShowPage(wxWizardPage *page, bool goingForward = TRUE); private: + // was the dialog really created? + bool WasCreated() const { return m_btnPrev != NULL; } + + // do fill the dialog with controls + void DoCreateControls(); + // event handlers void OnCancel(wxCommandEvent& event); void OnBackOrNext(wxCommandEvent& event); + // the page size requested by user + wxSize m_sizePage; + + // the dialog position from the ctor + wxPoint m_posWizard; + // wizard dimensions int m_x, m_y; // the origin for the pages int m_width, // the size of the page itself diff --git a/include/wx/wizard.h b/include/wx/wizard.h index 58eb283c51..ee19faee0f 100644 --- a/include/wx/wizard.h +++ b/include/wx/wizard.h @@ -123,8 +123,7 @@ public: int id = -1, const wxString& title = wxEmptyString, const wxBitmap& bitmap = wxNullBitmap, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize); + const wxPoint& pos = wxDefaultPosition); // executes the wizard starting from the given page, returns TRUE if it was // successfully finished, FALSE if user cancelled it @@ -133,6 +132,11 @@ public: // get the current page (NULL if RunWizard() isn't running) virtual wxWizardPage *GetCurrentPage() const = 0; + // set the min size which should be available for the pages: a + // wizard will take into account the size of the bitmap (if any) + // itself and will never be less than some predefined fixed size + virtual void SetPageSize(const wxSize& size) = 0; + // get the size available for the page: the wizards are not resizeable, so // this size doesn't change virtual wxSize GetPageSize() const = 0; diff --git a/samples/wizard/wizard.cpp b/samples/wizard/wizard.cpp index 52cd493983..c405271857 100644 --- a/samples/wizard/wizard.cpp +++ b/samples/wizard/wizard.cpp @@ -319,12 +319,12 @@ void MyFrame::OnRunWizard(wxCommandEvent& WXUNUSED(event)) // a wizard page may be either an object of predefined class wxWizardPageSimple *page1 = new wxWizardPageSimple(wizard); - (void)new wxStaticText(page1, -1, - "This wizard doesn't help you to do anything at " - "all.\n" - "\n" - "The next pages will present you with more useless " - "controls."); + wxStaticText *text = new wxStaticText(page1, -1, + "This wizard doesn't help you to do anything at all.\n" + "\n" + "The next pages will present you with more useless controls." + ); + wxSize size = text->GetBestSize(); // ... or a derived class wxRadioboxPage *page3 = new wxRadioboxPage(wizard); @@ -340,6 +340,7 @@ void MyFrame::OnRunWizard(wxCommandEvent& WXUNUSED(event)) page1->SetNext(page2); page3->SetPrev(page2); + wizard->SetPageSize(size); if ( wizard->RunWizard(page1) ) { wxMessageBox("The wizard successfully completed", "That's all", diff --git a/src/generic/wizard.cpp b/src/generic/wizard.cpp index fdd9dc7a8c..58f7ecc2fc 100644 --- a/src/generic/wizard.cpp +++ b/src/generic/wizard.cpp @@ -94,10 +94,24 @@ wxWizard::wxWizard(wxWindow *parent, int id, const wxString& title, const wxBitmap& bitmap, - const wxPoint& pos, - const wxSize& size) - : m_bitmap(bitmap) + const wxPoint& pos) + : m_posWizard(pos), m_bitmap(bitmap) { + // just create the dialog itself here, the controls will be created in + // DoCreateControls() called later when we know our final size + m_page = (wxWizardPage *)NULL; + m_btnPrev = m_btnNext = NULL; + m_statbmp = NULL; + + (void)wxDialog::Create(parent, id, title, pos); +} + +void wxWizard::DoCreateControls() +{ + // do nothing if the controls were already created + if ( WasCreated() ) + return; + // constants defining the dialog layout // ------------------------------------ @@ -122,38 +136,41 @@ wxWizard::wxWizard(wxWindow *parent, static const int DEFAULT_PAGE_WIDTH = 270; static const int DEFAULT_PAGE_HEIGHT = 290; - // init members - // ------------ - - m_page = (wxWizardPage *)NULL; - // create controls // --------------- wxSize sizeBtn = wxButton::GetDefaultSize(); - (void)wxDialog::Create(parent, id, title, pos, size); - // the global dialog layout is: a row of buttons at the bottom (aligned to // the right), the static line above them, the bitmap (if any) on the left // of the upper part of the dialog and the panel in the remaining space m_x = X_MARGIN; m_y = Y_MARGIN; - if ( bitmap.Ok() ) - { - m_statbmp = new wxStaticBitmap(this, -1, bitmap, wxPoint(m_x, m_y)); - m_x += bitmap.GetWidth() + BITMAP_X_MARGIN; - m_height = bitmap.GetHeight(); + int defaultHeight; + if ( m_bitmap.Ok() ) + { + m_statbmp = new wxStaticBitmap(this, -1, m_bitmap, wxPoint(m_x, m_y)); + + m_x += m_bitmap.GetWidth() + BITMAP_X_MARGIN; + + defaultHeight = m_bitmap.GetHeight(); } else { m_statbmp = (wxStaticBitmap *)NULL; - m_height = DEFAULT_PAGE_HEIGHT; + defaultHeight = DEFAULT_PAGE_HEIGHT; } - m_width = DEFAULT_PAGE_WIDTH; + // use default size if none given and also make sure that the dialog is + // not less than the default size + m_height = m_sizePage.y == -1 ? defaultHeight : m_sizePage.y; + m_width = m_sizePage.x == -1 ? DEFAULT_PAGE_WIDTH : m_sizePage.x; + if ( m_height < defaultHeight ) + m_height = defaultHeight; + if ( m_width < DEFAULT_PAGE_WIDTH ) + m_width = DEFAULT_PAGE_WIDTH; int x = X_MARGIN; int y = m_y + m_height + BITMAP_Y_MARGIN; @@ -161,7 +178,7 @@ wxWizard::wxWizard(wxWindow *parent, #if wxUSE_STATLINE (void)new wxStaticLine(this, -1, wxPoint(x, y), wxSize(m_x + m_width - x, 2)); -#endif +#endif // wxUSE_STATLINE x = m_x + m_width - 3*sizeBtn.x - BUTTON_MARGIN; y += SEPARATOR_LINE_MARGIN; @@ -176,19 +193,24 @@ wxWizard::wxWizard(wxWindow *parent, // position and size the dialog // ---------------------------- - if ( size == wxDefaultSize ) - { - SetClientSize(m_x + m_width + X_MARGIN, - m_y + m_height + BITMAP_Y_MARGIN + - SEPARATOR_LINE_MARGIN + sizeBtn.y + Y_MARGIN); - } + SetClientSize(m_x + m_width + X_MARGIN, + m_y + m_height + BITMAP_Y_MARGIN + + SEPARATOR_LINE_MARGIN + sizeBtn.y + Y_MARGIN); - if ( pos == wxDefaultPosition ) + if ( m_posWizard == wxDefaultPosition ) { CentreOnScreen(); } } +void wxWizard::SetPageSize(const wxSize& size) +{ + // otherwise it will have no effect now as it's too late... + wxASSERT_MSG( !WasCreated(), _T("should be called before RunWizard()!") ); + + m_sizePage = size; +} + bool wxWizard::ShowPage(wxWizardPage *page, bool goingForward) { wxASSERT_MSG( page != m_page, wxT("this is useless") ); @@ -278,6 +300,8 @@ bool wxWizard::RunWizard(wxWizardPage *firstPage) { wxCHECK_MSG( firstPage, FALSE, wxT("can't run empty wizard") ); + DoCreateControls(); + // can't return FALSE here because there is no old page (void)ShowPage(firstPage, TRUE /* forward */);