]> git.saurik.com Git - wxWidgets.git/commitdiff
added sizers support; allow resizeable wizards (Robert Vazan)
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 20 Jul 2003 20:48:52 +0000 (20:48 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 20 Jul 2003 20:48:52 +0000 (20:48 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22170 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
docs/latex/wx/wizard.tex
include/wx/generic/wizard.h
include/wx/wizard.h
samples/wizard/wizard.cpp
src/generic/wizard.cpp

index a2983ef7a3cd86d007f63dfc8b8199dcd4a68122..c71e3f555a3d0524eacb067023b280e79637cd45 100644 (file)
@@ -74,6 +74,7 @@ All GUI ports:
 - added alpha channel support to wxImage
 - added wxCLOSE_BOX style for dialogs and frames
 - added wxSplitterWindow and wxWizard handlers to XRC
+- wxWizard is now sizer-friendly and may b resizeable (Robert Vazan)
 - added proportion to wxFlexGridSizer::AddGrowableRow/Col (Maxim Babitski)
 - added wxFlexGridSizer::SetFlexibleDirection() (Szczepan Holyszewski)
 - implemented GetEditControl for wxGenericTreeCtrl (Peter Stieber)
index 6ebb199d02e069e9f9db5984efb9a64e97bad625..6b0e715169c855895a8ebc9909af3703c98d6688 100644 (file)
@@ -2,7 +2,7 @@
 %% Name:        wizard.tex
 %% Purpose:     wxWizard class documentation
 %% Author:      Vadim Zeitlin
-%% Modified by:
+%% Modified by: Robert Vazan (sizers)
 %% Created:     02.04.00
 %% RCS-ID:      $Id$
 %% Copyright:   (c) Vadim Zeitlin
@@ -85,7 +85,7 @@ Default constructor. Use this if you wish to derive from wxWizard and then call
 with \helpref{wxWindow::SetExtraStyle}{wxwindowsetextrastyle} between the two
 calls.
 
-\func{}{wxWizard}{\param{wxWindow* }{parent}, \param{int }{id = -1}, \param{const wxString\& }{title = wxEmptyString}, \param{const wxBitmap\& }{bitmap = wxNullBitmap}, \param{const wxPoint\& }{pos = wxDefaultPosition}}
+\func{}{wxWizard}{\param{wxWindow* }{parent}, \param{int }{id = -1}, \param{const wxString\& }{title = wxEmptyString}, \param{const wxBitmap\& }{bitmap = wxNullBitmap}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{long }{style = wxDEFAULT_DIALOG_STYLE}}
 
 Constructor which really creates the wizard -- if you use this constructor, you
 shouldn't call \helpref{Create}{wxwizardcreate}.
@@ -93,7 +93,7 @@ shouldn't call \helpref{Create}{wxwizardcreate}.
 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.
+\helpref{GetPageAreaSizer}{wxwizardgetpageareasizer} function.
 
 \wxheading{Parameters}
 
@@ -109,9 +109,12 @@ also \helpref{GetBitmap}{wxwizardpagegetbitmap}.}
 \docparam{pos}{The position of the dialog, it will be centered on the screen
 by default.}
 
+\docparam{style}{Window style is passed to wxDialog.}
+
+
 \membersection{wxWizard::Create}\label{wxwizardcreate}
 
-\func{bool}{Create}{\param{wxWindow* }{parent}, \param{int }{id = -1}, \param{const wxString\& }{title = wxEmptyString}, \param{const wxBitmap\& }{bitmap = wxNullBitmap}, \param{const wxPoint\& }{pos = wxDefaultPosition}}
+\func{bool}{Create}{\param{wxWindow* }{parent}, \param{int }{id = -1}, \param{const wxString\& }{title = wxEmptyString}, \param{const wxBitmap\& }{bitmap = wxNullBitmap}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{long }{style = wxDEFAULT_DIALOG_STYLE}}
 
 Creates the wizard dialog. Must be called if the default constructor had been
 used to create the object.
@@ -119,7 +122,7 @@ used to create the object.
 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.
+\helpref{GetPageAreaSizer}{wxwizardgetpageareasizer} function.
 
 \wxheading{Parameters}
 
@@ -135,10 +138,16 @@ also \helpref{GetBitmap}{wxwizardpagegetbitmap}.}
 \docparam{pos}{The position of the dialog, it will be centered on the screen
 by default.}
 
+\docparam{style}{Window style is passed to wxDialog.}
+
+
 \membersection{wxWizard::FitToPage}\label{wxwizardfittopage}
 
 \func{void}{FitToPage}{\param{const wxWizardPage* }{firstPage}}
 
+This method is obsolete, use
+\helpref{GetPageAreaSizer}{wxwizardgetpageareasizer} instead.
+
 Sets the page size to be big enough for all the pages accessible via the
 given {\it firstPage}, i.e. this page, its next page and so on.
 
@@ -148,6 +157,7 @@ This is useful if the decision about which pages to show is taken during the
 run-time as in this case, the wizard won't be able to get to all pages starting
 from a single one and you should call {\it Fit} separately for the others.
 
+
 \membersection{wxWizard::GetCurrentPage}\label{wxwizardgetcurrentpage}
 
 \constfunc{wxWizardPage*}{GetCurrentPage}{\void}
@@ -155,12 +165,46 @@ from a single one and you should call {\it Fit} separately for the others.
 Get the current page while the wizard is running. {\tt NULL} is returned if 
 \helpref{RunWizard()}{wxwizardrunwizard} is not being executed now.
 
+
+\membersection{wxWizard::GetPageAreaSizer}\label{wxwizardgetpageareasizer}
+
+\constfunc{virtual wxSizer*}{GetPageAreaSizer}{\void}
+
+Returns pointer to page area sizer. Wizard is laid out using sizers and
+page area sizer is the place holder for the pages. All pages are resized before
+being shown to match the wizard page area.
+
+Page area sizer has minimal size that is maximum of several values. First,
+all pages (or other objects) added to the sizer. Second, all pages reachable
+by repeatedly applying 
+\helpref{wxWizardPage::GetNext}{wxwizardpagegetnext} to
+any page inserted into the sizer. Third,
+minimal size specified using \helpref{SetPageSize}{wxwizardsetpagesize} and 
+\helpref{FitToPage}{wxwizardfittopage}. Fourth, the total wizard height may
+be increased to accomodate the bitmap height. Fifth and finally, wizards are
+never smaller some built-in minimal size to avoid too small wizards.
+
+Caller can use \helpref{wxSizer::SetMinSize}{wxsizersetminsize} to enlarge it
+beyond minimal size. If {\tt wxRESIZE\_BORDER} was passed to constructor, user
+can resize wizard and consequently page area (but not make it smaller than the
+minimal size).
+
+It is recommended to add first page to page area sizer. For simple wizards,
+this will enlarge the wizard to fit biggest page. For non-linear wizards,
+first page of every separate chain should be added. Caller-specified size
+can be accomplished using \helpref{wxSizer::SetMinSize}{wxsizersetminsize}.
+
+Adding pages to page area sizer affects default border width around page
+area that can be altered with \helpref{SetBorder}{wxwizardsetborder}.
+
+
 \membersection{wxWizard::GetPageSize}\label{wxwizardgetpagesize}
 
 \constfunc{wxSize}{GetPageSize}{\void}
 
 Returns the size available for the pages.
 
+
 \membersection{wxWizard::HasNextPage}\label{wxwizardhasnextpage}
 
 \func{virtual bool}{HasNextPage}{\param{wxWizardPage *}{page}}
@@ -174,6 +218,7 @@ for example, the pages are created on demand only.
 
 \helpref{HasPrevPage}{wxwizardhasprevpage}
 
+
 \membersection{wxWizard::HasPrevPage}\label{wxwizardhasprevpage}
 
 \func{virtual bool}{HasPrevPage}{\param{wxWizardPage *}{page}}
@@ -187,6 +232,7 @@ for example, the pages are created on demand only.
 
 \helpref{HasNextPage}{wxwizardhasnextpage}
 
+
 \membersection{wxWizard::RunWizard}\label{wxwizardrunwizard}
 
 \func{bool}{RunWizard}{\param{wxWizardPage* }{firstPage}}
@@ -195,10 +241,14 @@ Executes the wizard starting from the given page, returns {\tt true} if it was
 successfully finished or {\tt false} if user cancelled it. The {\it firstPage} 
 can not be {\tt NULL}.
 
+
 \membersection{wxWizard::SetPageSize}\label{wxwizardsetpagesize}
 
 \func{void}{SetPageSize}{\param{const wxSize\& }{sizePage}}
 
+This method is obsolete, use
+\helpref{GetPageAreaSizer}{wxwizardgetpageareasizer} instead.
+
 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.
@@ -208,3 +258,17 @@ 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().
 
+
+\membersection{wxWizard::SetBorder}\label{wxwizardsetborder}
+
+\func{void}{SetBorder}{\param{int }{border}}
+
+Sets width of border around page area. Default is zero. For backward
+compatibility, if there are no pages in
+\helpref{GetPageAreaSizer}{wxwizardgetpageareasizer}, default is $5$ pixels.
+
+If there is five point border around all controls in a page and border around
+page area is left zero, five point white space along all dialog borders
+will be added to control border to space page controls ten points from dialog
+border and non-page controls.
+
index 43c01a90e6e8d336d3b3ae97d358a178048e682c..712c6796ba452592e2118b90b4924ac12e941c8c 100644 (file)
@@ -2,7 +2,7 @@
 // Name:        generic/wizard.h
 // Purpose:     declaration of generic wxWizard class
 // Author:      Vadim Zeitlin
-// Modified by:
+// Modified by: Robert Vazan (sizers)
 // Created:     28.09.99
 // RCS-ID:      $Id$
 // Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
@@ -20,6 +20,8 @@
 class WXDLLEXPORT wxButton;
 class WXDLLEXPORT wxStaticBitmap;
 class WXDLLEXPORT wxWizardEvent;
+class WXDLLEXPORT wxBoxSizer;
+class WXDLLEXPORT wxWizardSizer;
 
 class WXDLLEXPORT wxWizard : public wxWizardBase
 {
@@ -30,16 +32,18 @@ public:
              int id = -1,
              const wxString& title = wxEmptyString,
              const wxBitmap& bitmap = wxNullBitmap,
-             const wxPoint& pos = wxDefaultPosition)
+             const wxPoint& pos = wxDefaultPosition,
+             long style = wxDEFAULT_DIALOG_STYLE)
     {
         Init();
-        Create(parent, id, title, bitmap, pos);
+        Create(parent, id, title, bitmap, pos, style);
     }
     bool Create(wxWindow *parent,
              int id = -1,
              const wxString& title = wxEmptyString,
              const wxBitmap& bitmap = wxNullBitmap,
-             const wxPoint& pos = wxDefaultPosition);
+             const wxPoint& pos = wxDefaultPosition,
+             long style = wxDEFAULT_DIALOG_STYLE);
     void Init();
 
     // implement base class pure virtuals
@@ -48,6 +52,8 @@ public:
     virtual void SetPageSize(const wxSize& size);
     virtual wxSize GetPageSize() const;
     virtual void FitToPage(const wxWizardPage *firstPage);
+    virtual wxSizer *GetPageAreaSizer() const;
+    virtual void SetBorder(int border);
 
     // implementation only from now on
     // -------------------------------
@@ -75,17 +81,21 @@ private:
 
     void OnWizEvent(wxWizardEvent& event);
 
+    void AddBitmapRow(wxBoxSizer *mainColumn);
+    void AddStaticLine(wxBoxSizer *mainColumn);
+    void AddBackNextPair(wxBoxSizer *buttonRow);
+    void AddButtonRow(wxBoxSizer *mainColumn);
+
+    void FinishLayout();
+    
+    wxSize GetManualPageSize() const;
+    
     // 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
-                 m_height;      // (total width is m_width + m_x)
-
     // wizard state
     wxWizardPage *m_page;       // the current page or NULL
     wxBitmap      m_bitmap;     // the default bitmap to show
@@ -95,6 +105,22 @@ private:
                 *m_btnNext;     // the "Next>" or "Finish" button
     wxStaticBitmap *m_statbmp;  // the control for the bitmap
 
+    // Whether user called SetBorder()
+    bool m_calledSetBorder;
+    // Border around page area sizer requested using SetBorder()
+    int m_border;
+    
+    // Whether RunWizard() was called
+    bool m_started;
+    
+    // Page area sizer will be inserted here with padding
+    wxBoxSizer *m_sizerBmpAndPage;
+    
+    // Actual position and size of pages
+    wxWizardSizer *m_sizerPage;
+    
+    friend class wxWizardSizer;
+    
     DECLARE_DYNAMIC_CLASS(wxWizard)
     DECLARE_EVENT_TABLE()
     DECLARE_NO_COPY_CLASS(wxWizard)
index d61b12e3a49d22591207fc014dfdfc5ab572352e..4ff5fad252b1201a096017acac1aa227045608e9 100644 (file)
@@ -7,6 +7,7 @@
 // Modified by: Robert Cavanaugh
 //              Added capability to use .WXR resource files in Wizard pages
 //              Added wxWIZARD_HELP event
+//              Robert Vazan (sizers)
 // Created:     15.08.99
 // RCS-ID:      $Id$
 // Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
@@ -167,7 +168,8 @@ public:
                  int id = -1,
                  const wxString& title = wxEmptyString,
                  const wxBitmap& bitmap = wxNullBitmap,
-                 const wxPoint& pos = wxDefaultPosition);
+                 const wxPoint& pos = wxDefaultPosition,
+                 long style = wxDEFAULT_DIALOG_STYLE);
     */
 
     // executes the wizard starting from the given page, returns TRUE if it was
@@ -182,8 +184,7 @@ public:
     // 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
+    // get the size available for the page
     virtual wxSize GetPageSize() const = 0;
 
     // set the best size for the wizard, i.e. make it big enough to contain all
@@ -195,6 +196,13 @@ public:
     // default)
     virtual void FitToPage(const wxWizardPage *firstPage) = 0;
 
+    // Adding pages to page area sizer enlarges wizard
+    virtual wxSizer *GetPageAreaSizer() const = 0;
+    
+    // Set border around page area. Default is 0 if you add at least one
+    // page to GetPageAreaSizer and 5 if you don't.
+    virtual void SetBorder(int border) = 0;
+    
     // wxWizard should be created using "new wxWizard" now, not with Create()
 #ifdef WXWIN_COMPATIBILITY_2_2
     static wxWizard *Create(wxWindow *parent,
index b5f798734bbe9411e4b0f5c176d6e74c86fb4baa..1cd0ac9831523318c38e5d5df6115457f511a3b5 100644 (file)
@@ -2,7 +2,7 @@
 // Name:        wizard.cpp
 // Purpose:     wxWindows sample demonstrating wxWizard control
 // Author:      Vadim Zeitlin
-// Modified by:
+// Modified by: Robert Vazan (sizers)
 // Created:     15.08.99
 // RCS-ID:      $Id$
 // Copyright:   (c) Vadim Zeitlin
 // headers
 // ----------------------------------------------------------------------------
 
-#if defined(__GNUG__) && !defined(__APPLE__)
-    #pragma implementation "wizard.cpp"
-    #pragma interface "wizard.cpp"
-#endif
-
 // For compilers that support precompilation, includes "wx/wx.h".
 #include "wx/wxprec.h"
 
     #pragma hdrstop
 #endif
 
-// for all others, include the necessary headers (this file is usually all you
-// need because it includes almost all "standard" wxWindows headers
+// for all others, include the necessary headers
 #ifndef WX_PRECOMP
-    #include "wx/wx.h"
+    #include "wx/stattext.h"
+    #include "wx/log.h"
+    #include "wx/app.h"
+    #include "wx/checkbox.h"
+    #include "wx/msgdlg.h"
+    #include "wx/radiobox.h"
+    #include "wx/menu.h"
+    #include "wx/sizer.h"
 #endif
 
 #include "wx/wizard.h"
@@ -101,6 +102,25 @@ public:
         m_bitmap = wxBITMAP(wiztest2);
 
         m_checkbox = new wxCheckBox(this, -1, _T("&Check me"));
+        
+        wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
+        mainSizer->Add(
+            new wxStaticText(this, -1,
+                             _T("You need to check the checkbox\n")
+                             _T("below before going to the next page\n")),
+            0,
+            wxALL,
+            5
+        );
+
+        mainSizer->Add(
+            m_checkbox,
+            0, // No stretching
+            wxALL,
+            5 // Border
+        );
+        SetSizer(mainSizer);
+        mainSizer->Fit(this);
     }
 
     virtual bool TransferDataFromWindow()
@@ -144,10 +164,20 @@ public:
         choices[3] = _T("neither");
 
         m_radio = new wxRadioBox(this, -1, _T("Allow to proceed:"),
-                                 wxPoint(5, 5), wxDefaultSize,
+                                 wxDefaultPosition, wxDefaultSize,
                                  WXSIZEOF(choices), choices,
                                  1, wxRA_SPECIFY_COLS);
         m_radio->SetSelection(Both);
+        
+        wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
+        mainSizer->Add(
+            m_radio,
+            0, // No stretching
+            wxALL,
+            5 // Border
+        );
+        SetSizer(mainSizer);
+        mainSizer->Fit(this);
     }
 
     // wizard event handlers
@@ -197,12 +227,27 @@ public:
     {
         m_prev = prev;
         m_next = next;
+        
+        wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
+
+        mainSizer->Add(
+            new wxStaticText(this, -1, _T("Try checking the box below and\n")
+                                       _T("then going back and clearing it")),
+            0, // No vertical stretching
+            wxALL,
+            5 // Border width
+        );
 
-        (void)new wxStaticText(this, -1, _T("Try checking the box below and\n")
-                                         _T("then going back and clearing it"));
-
-        m_checkbox = new wxCheckBox(this, -1, _T("&Skip the next page"),
-                                    wxPoint(5, 30));
+        m_checkbox = new wxCheckBox(this, -1, _T("&Skip the next page"));
+        mainSizer->Add(
+            m_checkbox,
+            0, // No vertical stretching
+            wxALL,
+            5 // Border width
+        );
+        
+        SetSizer(mainSizer);
+        mainSizer->Fit(this);
     }
 
     // implement wxWizardPage functions
@@ -304,14 +349,17 @@ void MyFrame::OnRunWizard(wxCommandEvent& WXUNUSED(event))
 {
     wxWizard *wizard = new wxWizard(this, -1,
                     _T("Absolutely Useless Wizard"),
-                    wxBITMAP(wiztest));
+                    wxBITMAP(wiztest),
+                    wxDefaultPosition,
+                    wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
 
     // a wizard page may be either an object of predefined class
     wxWizardPageSimple *page1 = new wxWizardPageSimple(wizard);
     wxStaticText *text = new wxStaticText(page1, -1,
-             _T("This wizard doesn't help you to do anything at all.\n")
+             _T("This wizard doesn't help you\nto do anything at all.\n")
              _T("\n")
-             _T("The next pages will present you with more useless controls.")
+             _T("The next pages will present you\nwith more useless controls."),
+             wxPoint(5,5)
         );
     wxSize size = text->GetBestSize();
 
@@ -330,6 +378,8 @@ void MyFrame::OnRunWizard(wxCommandEvent& WXUNUSED(event))
     page3->SetPrev(page2);
 
     wizard->SetPageSize(size);
+    wizard->GetPageAreaSizer()->Add(page1);
+    
     if ( wizard->RunWizard(page1) )
     {
         wxMessageBox(_T("The wizard successfully completed"), _T("That's all"),
index 91a35840b35cfd0e10e48faef3b159949bec0213..158b7708e37f7881adcc694850b5861e3b736a83 100644 (file)
@@ -6,6 +6,7 @@
 //              1) Added capability for wxWizardPage to accept resources
 //              2) Added "Help" button handler stub
 //              3) Fixed ShowPage() bug on displaying bitmaps
+//              Robert Vazan (sizers)
 // Created:     15.08.99
 // RCS-ID:      $Id$
 // Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
@@ -41,6 +42,7 @@
 #endif //WX_PRECOMP
 
 #include "wx/statline.h"
+#include "wx/sizer.h"
 
 #include "wx/wizard.h"
 
@@ -132,6 +134,126 @@ wxWizardPage *wxWizardPageSimple::GetNext() const
 {
     return m_next;
 }
+
+// ----------------------------------------------------------------------------
+// wxWizardSizer
+// ----------------------------------------------------------------------------
+
+class wxWizardSizer : public wxSizer
+{
+public:
+    wxWizardSizer(wxWizard *owner);
+
+    void RecalcSizes();
+    wxSize CalcMin();
+
+    wxSize GetMaxChildSize();
+    int Border() const;
+    
+private:
+    wxSize SiblingSize(wxSizerItem *child);
+    
+    wxWizard *m_owner;
+    bool m_childSizeValid;
+    wxSize m_childSize;
+
+    DECLARE_CLASS(wxWizardSizer);
+};
+
+IMPLEMENT_CLASS(wxWizardSizer, wxSizer)
+
+wxWizardSizer::wxWizardSizer(wxWizard *owner)
+    : m_owner(owner)
+{
+    m_childSizeValid = false;
+}
+
+void wxWizardSizer::RecalcSizes()
+{
+    // Effect of this function depends on m_owner->m_page and
+    // it should be called whenever it changes (wxWizard::ShowPage)
+    if ( m_owner->m_page )
+    {
+        m_owner->m_page->SetSize(m_position.x,m_position.y, m_size.x,m_size.y);
+    }
+}
+
+wxSize wxWizardSizer::CalcMin()
+{
+    return m_owner->GetPageSize();
+}
+
+wxSize wxWizardSizer::GetMaxChildSize()
+{
+#if !defined(__WXDEBUG__)
+    if ( m_childSizeValid )
+        return m_childSize;
+#endif
+
+    wxSize maxOfMin;
+    wxSizerItemList::Node *childNode;
+
+    for(childNode = m_children.GetFirst(); childNode;
+        childNode = childNode->GetNext())
+    {
+        wxSizerItem *child = childNode->GetData();
+        maxOfMin.IncTo(child->CalcMin());
+        maxOfMin.IncTo(SiblingSize(child));
+    }
+
+#ifdef __WXDEBUG__
+    if ( m_childSizeValid && m_childSize != maxOfMin )
+    {
+        wxFAIL_MSG( _T("Size changed in wxWizard::GetPageAreaSizer()")
+                    _T("after RunWizard().\n")
+                    _T("Did you forget to call GetSizer()->Fit(this) ")
+                    _T("for some page?")) ;
+
+        return m_childSize;
+    }
+#endif // __WXDEBUG__
+
+    if ( m_owner->m_started )
+    {
+        m_childSizeValid = true;
+        m_childSize = maxOfMin;
+    }
+    
+    return maxOfMin;
+}
+
+int wxWizardSizer::Border() const
+{
+    if ( m_owner->m_calledSetBorder )
+        return m_owner->m_border;
+
+    return m_children.IsEmpty() ? 5 : 0;
+}
+
+wxSize wxWizardSizer::SiblingSize(wxSizerItem *child)
+{
+    wxSize maxSibling;
+    
+    if ( child->IsWindow() )
+    {
+        wxWizardPage *page = wxDynamicCast(child->GetWindow(), wxWizardPage);
+        if ( page )
+        {
+            for ( wxWizardPage *sibling = page->GetNext();
+                  sibling;
+                  sibling = sibling->GetNext() )
+            {
+                if ( sibling->GetSizer() )
+                {
+                    maxSibling.IncTo(sibling->GetSizer()->CalcMin());
+                }
+            }
+        }
+    }
+    
+    return maxSibling;
+}
+
 // ----------------------------------------------------------------------------
 // generic wxWizard implementation
 // ----------------------------------------------------------------------------
@@ -142,175 +264,194 @@ void wxWizard::Init()
     m_page = (wxWizardPage *)NULL;
     m_btnPrev = m_btnNext = NULL;
     m_statbmp = NULL;
+    m_sizerPage = NULL;
+    m_calledSetBorder = false;
+    m_border = 0;
+    m_started = false;
 }
 
 bool wxWizard::Create(wxWindow *parent,
                    int id,
                    const wxString& title,
                    const wxBitmap& bitmap,
-                   const wxPoint& pos)
+                   const wxPoint& pos,
+                   long style)
 {
+    bool result = wxDialog::Create(parent,id,title,pos,wxDefaultSize,style);
+    
     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;
-
-    return wxDialog::Create(parent, id, title, pos);
+    DoCreateControls();
+    
+    return result;
 }
 
-void wxWizard::DoCreateControls()
+void wxWizard::AddBitmapRow(wxBoxSizer *mainColumn)
 {
-    // do nothing if the controls were already created
-    if ( WasCreated() )
-        return;
-
-    // constants defining the dialog layout
-    // ------------------------------------
-
-    // these constants define the position of the upper left corner of the
-    // bitmap or the page in the wizard
-    static const int X_MARGIN = 10;
-    static const int Y_MARGIN = 10;
-
-    // margin between the bitmap and the panel
-    static const int BITMAP_X_MARGIN = 15;
-
-    // margin between the bitmap and the static line
-    static const int BITMAP_Y_MARGIN = 15;
-
-    // margin between the static line and the buttons
-    static const int SEPARATOR_LINE_MARGIN = 15;
-
-    // margin between "Next >" and "Cancel" buttons
-    static const int BUTTON_MARGIN = 10;
+    m_sizerBmpAndPage = new wxBoxSizer(wxHORIZONTAL);
+    mainColumn->Add(
+        m_sizerBmpAndPage,
+        1, // Vertically stretchable
+        wxEXPAND // Horizonal stretching, no border
+    );
+    mainColumn->Add(0,5,
+        0, // No vertical stretching
+        wxEXPAND // No border, (mostly useless) horizontal stretching
+    );
 
-    // margin between Back and Next buttons
-#ifdef __WXMAC__
-    static const int BACKNEXT_MARGIN = 10;
-#else
-    static const int BACKNEXT_MARGIN = 0;
-#endif
-
-    // default width and height of the page
-    static const int DEFAULT_PAGE_WIDTH = 270;
-    static const int DEFAULT_PAGE_HEIGHT = 290;
-
-    // create controls
-    // ---------------
-
-    wxSize sizeBtn = wxButton::GetDefaultSize();
-
-    // 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;
-
-    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();
+        m_statbmp = new wxStaticBitmap(this, -1, m_bitmap);
+        m_sizerBmpAndPage->Add(
+            m_statbmp,
+            0, // No horizontal stretching
+            wxALL, // Border all around, top alignment
+            5 // Border width
+        );
+        m_sizerBmpAndPage->Add(
+            5,0,
+            0, // No horizontal stretching
+            wxEXPAND // No border, (mostly useless) vertical stretching
+        );
     }
     else
-    {
         m_statbmp = (wxStaticBitmap *)NULL;
 
-        defaultHeight = DEFAULT_PAGE_HEIGHT;
-    }
-
-    // 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;
+    // Added to m_sizerBmpAndPage in FinishLayout
+    m_sizerPage = new wxWizardSizer(this);
+}
 
+void wxWizard::AddStaticLine(wxBoxSizer *mainColumn)
+{
 #if wxUSE_STATLINE
-    (void)new wxStaticLine(this, -1, wxPoint(x, y),
-                           wxSize(m_x + m_width - x, 2));
+    mainColumn->Add(
+        new wxStaticLine(this, -1),
+        0, // Vertically unstretchable
+        wxEXPAND | wxALL, // Border all around, horizontally stretchable
+        5 // Border width
+    );
+    mainColumn->Add(0,5,
+        0, // No vertical stretching
+        wxEXPAND // No border, (mostly useless) horizontal stretching
+    );
+#else
+    (void)mainColumn;
 #endif // wxUSE_STATLINE
+}
 
-    x = m_x + m_width - 3*sizeBtn.x - BUTTON_MARGIN - BACKNEXT_MARGIN;
-    y += SEPARATOR_LINE_MARGIN;
-
-    if (GetExtraStyle() & wxWIZARD_EX_HELPBUTTON)
-    {
-        x -= sizeBtn.x;
-        x -= BUTTON_MARGIN ;
-
-        (void)new wxButton(this, wxID_HELP, _("&Help"), wxPoint(x, y), sizeBtn);
-        x += sizeBtn.x;
-        x += BUTTON_MARGIN ;
-    }
-
-    m_btnPrev = new wxButton(this, wxID_BACKWARD, _("< &Back"), wxPoint(x, y), sizeBtn);
-
-    x += sizeBtn.x;
-    x += BACKNEXT_MARGIN;
-
-    m_btnNext = new wxButton(this, wxID_FORWARD, _("&Next >"), wxPoint(x, y), sizeBtn);
+void wxWizard::AddBackNextPair(wxBoxSizer *buttonRow)
+{
+    // margin between Back and Next buttons
+#ifdef __WXMAC__
+    static const int BACKNEXT_MARGIN = 10;
+#else
+    static const int BACKNEXT_MARGIN = 0;
+#endif
 
-    x += sizeBtn.x + BUTTON_MARGIN;
-    (void)new wxButton(this, wxID_CANCEL, _("&Cancel"), wxPoint(x, y), sizeBtn);
+    wxBoxSizer *backNextPair = new wxBoxSizer(wxHORIZONTAL);
+    buttonRow->Add(
+        backNextPair,
+        0, // No horizontal stretching
+        wxALL, // Border all around
+        5 // Border width
+    );
+    
+    m_btnPrev = new wxButton(this, wxID_BACKWARD, _("< &Back"));
+    backNextPair->Add(m_btnPrev);
+    backNextPair->Add(BACKNEXT_MARGIN,0,
+        0, // No horizontal stretching
+        wxEXPAND // No border, (mostly useless) vertical stretching
+    );
+    m_btnNext = new wxButton(this, wxID_FORWARD, _("&Next >"));
+    backNextPair->Add(m_btnNext);
+}
 
-    // position and size the dialog
-    // ----------------------------
+void wxWizard::AddButtonRow(wxBoxSizer *mainColumn)
+{
+    wxBoxSizer *buttonRow = new wxBoxSizer(wxHORIZONTAL);
+    mainColumn->Add(
+        buttonRow,
+        0, // Vertically unstretchable
+        wxALIGN_RIGHT // Right aligned, no border
+    );
 
-    SetClientSize(m_x + m_width + X_MARGIN,
-                  m_y + m_height + BITMAP_Y_MARGIN +
-                    SEPARATOR_LINE_MARGIN + sizeBtn.y + Y_MARGIN);
+    if (GetExtraStyle() & wxWIZARD_EX_HELPBUTTON)
+        buttonRow->Add(
+            new wxButton(this, wxID_HELP, _("&Help")),
+            0, // Horizontally unstretchable
+            wxALL, // Border all around, top aligned
+            5 // Border width
+        );
+
+    AddBackNextPair(buttonRow);
+    
+    buttonRow->Add(
+        new wxButton(this, wxID_CANCEL, _("&Cancel")),
+        0, // Horizontally unstretchable
+        wxALL, // Border all around, top aligned
+        5 // Border width
+    );
+}
 
-    if ( m_posWizard == wxDefaultPosition )
-    {
-        CentreOnScreen();
-    }
+void wxWizard::DoCreateControls()
+{
+    // do nothing if the controls were already created
+    if ( WasCreated() )
+        return;
+    
+    // wxWindow::SetSizer will be called at end
+    wxBoxSizer *windowSizer = new wxBoxSizer(wxVERTICAL);
+    
+    wxBoxSizer *mainColumn = new wxBoxSizer(wxVERTICAL);
+    windowSizer->Add(
+        mainColumn,
+        1, // Vertical stretching
+        wxALL | wxEXPAND, // Border all around, horizontal stretching
+        5 // Border width
+    );
+    
+    AddBitmapRow(mainColumn);
+    AddStaticLine(mainColumn);
+    AddButtonRow(mainColumn);
+    
+    // wxWindow::SetSizer should be followed by wxWindow::Fit, but
+    // this is done in FinishLayout anyway so why duplicate it
+    SetSizer(windowSizer);
 }
 
 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()!") );
-
+    wxCHECK_RET(!m_started,wxT("wxWizard::SetPageSize after RunWizard"));
     m_sizePage = size;
 }
 
-void wxWizard::FitToPage(const wxWizardPage *page)
+void wxWizard::FinishLayout()
 {
-    // otherwise it will have no effect now as it's too late...
-    wxASSERT_MSG( !WasCreated(), _T("should be called before RunWizard()!") );
+    m_sizerBmpAndPage->Add(
+        m_sizerPage,
+        1, // Horizontal stretching
+        wxEXPAND | wxALL, // Vertically stretchable
+        m_sizerPage->Border()
+    );
+    
+    GetSizer()->SetSizeHints(this);
+    if ( m_posWizard == wxDefaultPosition )
+        CentreOnScreen();
+}
 
-    wxSize sizeMax;
+void wxWizard::FitToPage(const wxWizardPage *page)
+{
+    wxCHECK_RET(!m_started,wxT("wxWizard::FitToPage after RunWizard"));
+    
     while ( page )
     {
         wxSize size = page->GetBestSize();
 
-        if ( size.x > sizeMax.x )
-            sizeMax.x = size.x;
-
-        if ( size.y > sizeMax.y )
-            sizeMax.y = size.y;
+        m_sizePage.IncTo(size);
 
         page = page->GetNext();
     }
-
-    if ( sizeMax.x > m_sizePage.x )
-        m_sizePage.x = sizeMax.x;
-
-    if ( sizeMax.y > m_sizePage.y )
-        m_sizePage.y = sizeMax.y;
 }
 
 bool wxWizard::ShowPage(wxWizardPage *page, bool goingForward)
@@ -373,7 +514,9 @@ bool wxWizard::ShowPage(wxWizardPage *page, bool goingForward)
 
     // position and show the new page
     (void)m_page->TransferDataToWindow();
-    m_page->SetSize(m_x, m_y, m_width, m_height);
+    
+    // wxWizardSizer::RecalcSizes wants to be called when m_page changes
+    m_sizerPage->RecalcSizes();
 
     // check if bitmap needs to be updated
     // update default flag as well
@@ -425,9 +568,14 @@ bool wxWizard::ShowPage(wxWizardPage *page, bool goingForward)
 bool wxWizard::RunWizard(wxWizardPage *firstPage)
 {
     wxCHECK_MSG( firstPage, FALSE, wxT("can't run empty wizard") );
-
-    DoCreateControls();
-
+    
+    // Set before FinishLayout to enable wxWizardSizer::GetMaxChildSize
+    m_started = true;
+    
+    // This cannot be done sooner, because user can change layout options
+    // up to this moment
+    FinishLayout();
+    
     // can't return FALSE here because there is no old page
     (void)ShowPage(firstPage, TRUE /* forward */);
 
@@ -441,11 +589,37 @@ wxWizardPage *wxWizard::GetCurrentPage() const
 
 wxSize wxWizard::GetPageSize() const
 {
-    // make sure that the controls are created because otherwise m_width and
-    // m_height would be both still -1
-    wxConstCast(this, wxWizard)->DoCreateControls();
+    wxSize pageSize(GetManualPageSize());
+    pageSize.IncTo(m_sizerPage->GetMaxChildSize());
+    return pageSize;
+}
+
+wxSizer *wxWizard::GetPageAreaSizer() const
+{
+    return m_sizerPage;
+}
+
+void wxWizard::SetBorder(int border)
+{
+    wxCHECK_RET(!m_started,wxT("wxWizard::SetBorder after RunWizard"));
+    m_calledSetBorder = true;
+    m_border = border;
+}
+
+wxSize wxWizard::GetManualPageSize() const
+{
+    // default width and height of the page
+    static const int DEFAULT_PAGE_WIDTH = 270;
+    static const int DEFAULT_PAGE_HEIGHT = 290;
 
-    return wxSize(m_width, m_height);
+    wxSize totalPageSize(DEFAULT_PAGE_WIDTH,DEFAULT_PAGE_HEIGHT);
+    
+    totalPageSize.IncTo(m_sizePage);
+    
+    if(m_statbmp)
+        totalPageSize.IncTo(wxSize(0,m_bitmap.GetHeight()));
+    
+    return totalPageSize;
 }
 
 void wxWizard::OnCancel(wxCommandEvent& WXUNUSED(eventUnused))