added sizers support; allow resizeable wizards (Robert Vazan)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22170 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2003-07-20 20:48:52 +00:00
parent e066bd132d
commit 07f20d9a63
6 changed files with 489 additions and 166 deletions

View File

@@ -74,6 +74,7 @@ All GUI ports:
- added alpha channel support to wxImage - added alpha channel support to wxImage
- added wxCLOSE_BOX style for dialogs and frames - added wxCLOSE_BOX style for dialogs and frames
- added wxSplitterWindow and wxWizard handlers to XRC - 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 proportion to wxFlexGridSizer::AddGrowableRow/Col (Maxim Babitski)
- added wxFlexGridSizer::SetFlexibleDirection() (Szczepan Holyszewski) - added wxFlexGridSizer::SetFlexibleDirection() (Szczepan Holyszewski)
- implemented GetEditControl for wxGenericTreeCtrl (Peter Stieber) - implemented GetEditControl for wxGenericTreeCtrl (Peter Stieber)

View File

@@ -2,7 +2,7 @@
%% Name: wizard.tex %% Name: wizard.tex
%% Purpose: wxWizard class documentation %% Purpose: wxWizard class documentation
%% Author: Vadim Zeitlin %% Author: Vadim Zeitlin
%% Modified by: %% Modified by: Robert Vazan (sizers)
%% Created: 02.04.00 %% Created: 02.04.00
%% RCS-ID: $Id$ %% RCS-ID: $Id$
%% Copyright: (c) Vadim Zeitlin %% 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 with \helpref{wxWindow::SetExtraStyle}{wxwindowsetextrastyle} between the two
calls. 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 Constructor which really creates the wizard -- if you use this constructor, you
shouldn't call \helpref{Create}{wxwizardcreate}. 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} Notice that unlike almost all other wxWindows classes, there is no {\it size}
parameter in wxWizard constructor because the wizard will have a predefined 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 default size by default. If you want to change this, you should use the
\helpref{SetPageSize}{wxwizardsetpagesize} function. \helpref{GetPageAreaSizer}{wxwizardgetpageareasizer} function.
\wxheading{Parameters} \wxheading{Parameters}
@@ -109,9 +109,12 @@ also \helpref{GetBitmap}{wxwizardpagegetbitmap}.}
\docparam{pos}{The position of the dialog, it will be centered on the screen \docparam{pos}{The position of the dialog, it will be centered on the screen
by default.} by default.}
\docparam{style}{Window style is passed to wxDialog.}
\membersection{wxWizard::Create}\label{wxwizardcreate} \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 Creates the wizard dialog. Must be called if the default constructor had been
used to create the object. 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} Notice that unlike almost all other wxWindows classes, there is no {\it size}
parameter in wxWizard constructor because the wizard will have a predefined 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 default size by default. If you want to change this, you should use the
\helpref{SetPageSize}{wxwizardsetpagesize} function. \helpref{GetPageAreaSizer}{wxwizardgetpageareasizer} function.
\wxheading{Parameters} \wxheading{Parameters}
@@ -135,10 +138,16 @@ also \helpref{GetBitmap}{wxwizardpagegetbitmap}.}
\docparam{pos}{The position of the dialog, it will be centered on the screen \docparam{pos}{The position of the dialog, it will be centered on the screen
by default.} by default.}
\docparam{style}{Window style is passed to wxDialog.}
\membersection{wxWizard::FitToPage}\label{wxwizardfittopage} \membersection{wxWizard::FitToPage}\label{wxwizardfittopage}
\func{void}{FitToPage}{\param{const wxWizardPage* }{firstPage}} \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 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. 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 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. from a single one and you should call {\it Fit} separately for the others.
\membersection{wxWizard::GetCurrentPage}\label{wxwizardgetcurrentpage} \membersection{wxWizard::GetCurrentPage}\label{wxwizardgetcurrentpage}
\constfunc{wxWizardPage*}{GetCurrentPage}{\void} \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 Get the current page while the wizard is running. {\tt NULL} is returned if
\helpref{RunWizard()}{wxwizardrunwizard} is not being executed now. \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} \membersection{wxWizard::GetPageSize}\label{wxwizardgetpagesize}
\constfunc{wxSize}{GetPageSize}{\void} \constfunc{wxSize}{GetPageSize}{\void}
Returns the size available for the pages. Returns the size available for the pages.
\membersection{wxWizard::HasNextPage}\label{wxwizardhasnextpage} \membersection{wxWizard::HasNextPage}\label{wxwizardhasnextpage}
\func{virtual bool}{HasNextPage}{\param{wxWizardPage *}{page}} \func{virtual bool}{HasNextPage}{\param{wxWizardPage *}{page}}
@@ -174,6 +218,7 @@ for example, the pages are created on demand only.
\helpref{HasPrevPage}{wxwizardhasprevpage} \helpref{HasPrevPage}{wxwizardhasprevpage}
\membersection{wxWizard::HasPrevPage}\label{wxwizardhasprevpage} \membersection{wxWizard::HasPrevPage}\label{wxwizardhasprevpage}
\func{virtual bool}{HasPrevPage}{\param{wxWizardPage *}{page}} \func{virtual bool}{HasPrevPage}{\param{wxWizardPage *}{page}}
@@ -187,6 +232,7 @@ for example, the pages are created on demand only.
\helpref{HasNextPage}{wxwizardhasnextpage} \helpref{HasNextPage}{wxwizardhasnextpage}
\membersection{wxWizard::RunWizard}\label{wxwizardrunwizard} \membersection{wxWizard::RunWizard}\label{wxwizardrunwizard}
\func{bool}{RunWizard}{\param{wxWizardPage* }{firstPage}} \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} successfully finished or {\tt false} if user cancelled it. The {\it firstPage}
can not be {\tt NULL}. can not be {\tt NULL}.
\membersection{wxWizard::SetPageSize}\label{wxwizardsetpagesize} \membersection{wxWizard::SetPageSize}\label{wxwizardsetpagesize}
\func{void}{SetPageSize}{\param{const wxSize\& }{sizePage}} \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 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 will take into account the size of the bitmap (if any) itself. Also, the
wizard will never be smaller than the default size. 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 \helpref{wxSizer::CalcMin}{wxsizercalcmin} in a loop to calculate the maximum
of minimal sizes of the pages and pass it to SetPageSize(). 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.

View File

@@ -2,7 +2,7 @@
// Name: generic/wizard.h // Name: generic/wizard.h
// Purpose: declaration of generic wxWizard class // Purpose: declaration of generic wxWizard class
// Author: Vadim Zeitlin // Author: Vadim Zeitlin
// Modified by: // Modified by: Robert Vazan (sizers)
// Created: 28.09.99 // Created: 28.09.99
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
@@ -20,6 +20,8 @@
class WXDLLEXPORT wxButton; class WXDLLEXPORT wxButton;
class WXDLLEXPORT wxStaticBitmap; class WXDLLEXPORT wxStaticBitmap;
class WXDLLEXPORT wxWizardEvent; class WXDLLEXPORT wxWizardEvent;
class WXDLLEXPORT wxBoxSizer;
class WXDLLEXPORT wxWizardSizer;
class WXDLLEXPORT wxWizard : public wxWizardBase class WXDLLEXPORT wxWizard : public wxWizardBase
{ {
@@ -30,16 +32,18 @@ public:
int id = -1, int id = -1,
const wxString& title = wxEmptyString, const wxString& title = wxEmptyString,
const wxBitmap& bitmap = wxNullBitmap, const wxBitmap& bitmap = wxNullBitmap,
const wxPoint& pos = wxDefaultPosition) const wxPoint& pos = wxDefaultPosition,
long style = wxDEFAULT_DIALOG_STYLE)
{ {
Init(); Init();
Create(parent, id, title, bitmap, pos); Create(parent, id, title, bitmap, pos, style);
} }
bool Create(wxWindow *parent, bool Create(wxWindow *parent,
int id = -1, int id = -1,
const wxString& title = wxEmptyString, const wxString& title = wxEmptyString,
const wxBitmap& bitmap = wxNullBitmap, const wxBitmap& bitmap = wxNullBitmap,
const wxPoint& pos = wxDefaultPosition); const wxPoint& pos = wxDefaultPosition,
long style = wxDEFAULT_DIALOG_STYLE);
void Init(); void Init();
// implement base class pure virtuals // implement base class pure virtuals
@@ -48,6 +52,8 @@ public:
virtual void SetPageSize(const wxSize& size); virtual void SetPageSize(const wxSize& size);
virtual wxSize GetPageSize() const; virtual wxSize GetPageSize() const;
virtual void FitToPage(const wxWizardPage *firstPage); virtual void FitToPage(const wxWizardPage *firstPage);
virtual wxSizer *GetPageAreaSizer() const;
virtual void SetBorder(int border);
// implementation only from now on // implementation only from now on
// ------------------------------- // -------------------------------
@@ -75,17 +81,21 @@ private:
void OnWizEvent(wxWizardEvent& event); 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 // the page size requested by user
wxSize m_sizePage; wxSize m_sizePage;
// the dialog position from the ctor // the dialog position from the ctor
wxPoint m_posWizard; 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 // wizard state
wxWizardPage *m_page; // the current page or NULL wxWizardPage *m_page; // the current page or NULL
wxBitmap m_bitmap; // the default bitmap to show wxBitmap m_bitmap; // the default bitmap to show
@@ -95,6 +105,22 @@ private:
*m_btnNext; // the "Next>" or "Finish" button *m_btnNext; // the "Next>" or "Finish" button
wxStaticBitmap *m_statbmp; // the control for the bitmap 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_DYNAMIC_CLASS(wxWizard)
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxWizard) DECLARE_NO_COPY_CLASS(wxWizard)

View File

@@ -7,6 +7,7 @@
// Modified by: Robert Cavanaugh // Modified by: Robert Cavanaugh
// Added capability to use .WXR resource files in Wizard pages // Added capability to use .WXR resource files in Wizard pages
// Added wxWIZARD_HELP event // Added wxWIZARD_HELP event
// Robert Vazan (sizers)
// Created: 15.08.99 // Created: 15.08.99
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
@@ -167,7 +168,8 @@ public:
int id = -1, int id = -1,
const wxString& title = wxEmptyString, const wxString& title = wxEmptyString,
const wxBitmap& bitmap = wxNullBitmap, 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 // 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 // itself and will never be less than some predefined fixed size
virtual void SetPageSize(const wxSize& size) = 0; virtual void SetPageSize(const wxSize& size) = 0;
// get the size available for the page: the wizards are not resizeable, so // get the size available for the page
// this size doesn't change
virtual wxSize GetPageSize() const = 0; virtual wxSize GetPageSize() const = 0;
// set the best size for the wizard, i.e. make it big enough to contain all // set the best size for the wizard, i.e. make it big enough to contain all
@@ -195,6 +196,13 @@ public:
// default) // default)
virtual void FitToPage(const wxWizardPage *firstPage) = 0; 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() // wxWizard should be created using "new wxWizard" now, not with Create()
#ifdef WXWIN_COMPATIBILITY_2_2 #ifdef WXWIN_COMPATIBILITY_2_2
static wxWizard *Create(wxWindow *parent, static wxWizard *Create(wxWindow *parent,

View File

@@ -2,7 +2,7 @@
// Name: wizard.cpp // Name: wizard.cpp
// Purpose: wxWindows sample demonstrating wxWizard control // Purpose: wxWindows sample demonstrating wxWizard control
// Author: Vadim Zeitlin // Author: Vadim Zeitlin
// Modified by: // Modified by: Robert Vazan (sizers)
// Created: 15.08.99 // Created: 15.08.99
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Vadim Zeitlin // Copyright: (c) Vadim Zeitlin
@@ -17,11 +17,6 @@
// headers // headers
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if defined(__GNUG__) && !defined(__APPLE__)
#pragma implementation "wizard.cpp"
#pragma interface "wizard.cpp"
#endif
// For compilers that support precompilation, includes "wx/wx.h". // For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h" #include "wx/wxprec.h"
@@ -29,10 +24,16 @@
#pragma hdrstop #pragma hdrstop
#endif #endif
// for all others, include the necessary headers (this file is usually all you // for all others, include the necessary headers
// need because it includes almost all "standard" wxWindows headers
#ifndef WX_PRECOMP #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 #endif
#include "wx/wizard.h" #include "wx/wizard.h"
@@ -101,6 +102,25 @@ public:
m_bitmap = wxBITMAP(wiztest2); m_bitmap = wxBITMAP(wiztest2);
m_checkbox = new wxCheckBox(this, -1, _T("&Check me")); 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() virtual bool TransferDataFromWindow()
@@ -144,10 +164,20 @@ public:
choices[3] = _T("neither"); choices[3] = _T("neither");
m_radio = new wxRadioBox(this, -1, _T("Allow to proceed:"), m_radio = new wxRadioBox(this, -1, _T("Allow to proceed:"),
wxPoint(5, 5), wxDefaultSize, wxDefaultPosition, wxDefaultSize,
WXSIZEOF(choices), choices, WXSIZEOF(choices), choices,
1, wxRA_SPECIFY_COLS); 1, wxRA_SPECIFY_COLS);
m_radio->SetSelection(Both); 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 // wizard event handlers
@@ -198,11 +228,26 @@ public:
m_prev = prev; m_prev = prev;
m_next = next; m_next = next;
(void)new wxStaticText(this, -1, _T("Try checking the box below and\n") wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
_T("then going back and clearing it"));
m_checkbox = new wxCheckBox(this, -1, _T("&Skip the next page"), mainSizer->Add(
wxPoint(5, 30)); 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
);
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 // implement wxWizardPage functions
@@ -304,14 +349,17 @@ void MyFrame::OnRunWizard(wxCommandEvent& WXUNUSED(event))
{ {
wxWizard *wizard = new wxWizard(this, -1, wxWizard *wizard = new wxWizard(this, -1,
_T("Absolutely Useless Wizard"), _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 // a wizard page may be either an object of predefined class
wxWizardPageSimple *page1 = new wxWizardPageSimple(wizard); wxWizardPageSimple *page1 = new wxWizardPageSimple(wizard);
wxStaticText *text = new wxStaticText(page1, -1, 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("\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(); wxSize size = text->GetBestSize();
@@ -330,6 +378,8 @@ void MyFrame::OnRunWizard(wxCommandEvent& WXUNUSED(event))
page3->SetPrev(page2); page3->SetPrev(page2);
wizard->SetPageSize(size); wizard->SetPageSize(size);
wizard->GetPageAreaSizer()->Add(page1);
if ( wizard->RunWizard(page1) ) if ( wizard->RunWizard(page1) )
{ {
wxMessageBox(_T("The wizard successfully completed"), _T("That's all"), wxMessageBox(_T("The wizard successfully completed"), _T("That's all"),

View File

@@ -6,6 +6,7 @@
// 1) Added capability for wxWizardPage to accept resources // 1) Added capability for wxWizardPage to accept resources
// 2) Added "Help" button handler stub // 2) Added "Help" button handler stub
// 3) Fixed ShowPage() bug on displaying bitmaps // 3) Fixed ShowPage() bug on displaying bitmaps
// Robert Vazan (sizers)
// Created: 15.08.99 // Created: 15.08.99
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
@@ -41,6 +42,7 @@
#endif //WX_PRECOMP #endif //WX_PRECOMP
#include "wx/statline.h" #include "wx/statline.h"
#include "wx/sizer.h"
#include "wx/wizard.h" #include "wx/wizard.h"
@@ -132,6 +134,126 @@ wxWizardPage *wxWizardPageSimple::GetNext() const
{ {
return m_next; 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 // generic wxWizard implementation
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -142,24 +264,134 @@ void wxWizard::Init()
m_page = (wxWizardPage *)NULL; m_page = (wxWizardPage *)NULL;
m_btnPrev = m_btnNext = NULL; m_btnPrev = m_btnNext = NULL;
m_statbmp = NULL; m_statbmp = NULL;
m_sizerPage = NULL;
m_calledSetBorder = false;
m_border = 0;
m_started = false;
} }
bool wxWizard::Create(wxWindow *parent, bool wxWizard::Create(wxWindow *parent,
int id, int id,
const wxString& title, const wxString& title,
const wxBitmap& bitmap, 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_posWizard = pos;
m_bitmap = bitmap ; m_bitmap = bitmap ;
// just create the dialog itself here, the controls will be created in DoCreateControls();
// 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); return result;
}
void wxWizard::AddBitmapRow(wxBoxSizer *mainColumn)
{
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
);
if ( m_bitmap.Ok() )
{
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;
// Added to m_sizerBmpAndPage in FinishLayout
m_sizerPage = new wxWizardSizer(this);
}
void wxWizard::AddStaticLine(wxBoxSizer *mainColumn)
{
#if wxUSE_STATLINE
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
}
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
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);
}
void wxWizard::AddButtonRow(wxBoxSizer *mainColumn)
{
wxBoxSizer *buttonRow = new wxBoxSizer(wxHORIZONTAL);
mainColumn->Add(
buttonRow,
0, // Vertically unstretchable
wxALIGN_RIGHT // Right aligned, no border
);
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
);
} }
void wxWizard::DoCreateControls() void wxWizard::DoCreateControls()
@@ -168,149 +400,58 @@ void wxWizard::DoCreateControls()
if ( WasCreated() ) if ( WasCreated() )
return; return;
// constants defining the dialog layout // wxWindow::SetSizer will be called at end
// ------------------------------------ wxBoxSizer *windowSizer = new wxBoxSizer(wxVERTICAL);
// these constants define the position of the upper left corner of the wxBoxSizer *mainColumn = new wxBoxSizer(wxVERTICAL);
// bitmap or the page in the wizard windowSizer->Add(
static const int X_MARGIN = 10; mainColumn,
static const int Y_MARGIN = 10; 1, // Vertical stretching
wxALL | wxEXPAND, // Border all around, horizontal stretching
5 // Border width
);
// margin between the bitmap and the panel AddBitmapRow(mainColumn);
static const int BITMAP_X_MARGIN = 15; AddStaticLine(mainColumn);
AddButtonRow(mainColumn);
// margin between the bitmap and the static line // wxWindow::SetSizer should be followed by wxWindow::Fit, but
static const int BITMAP_Y_MARGIN = 15; // this is done in FinishLayout anyway so why duplicate it
SetSizer(windowSizer);
// 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;
// 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();
}
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;
#if wxUSE_STATLINE
(void)new wxStaticLine(this, -1, wxPoint(x, y),
wxSize(m_x + m_width - x, 2));
#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);
x += sizeBtn.x + BUTTON_MARGIN;
(void)new wxButton(this, wxID_CANCEL, _("&Cancel"), wxPoint(x, y), sizeBtn);
// position and size the dialog
// ----------------------------
SetClientSize(m_x + m_width + X_MARGIN,
m_y + m_height + BITMAP_Y_MARGIN +
SEPARATOR_LINE_MARGIN + sizeBtn.y + Y_MARGIN);
if ( m_posWizard == wxDefaultPosition )
{
CentreOnScreen();
}
} }
void wxWizard::SetPageSize(const wxSize& size) void wxWizard::SetPageSize(const wxSize& size)
{ {
// otherwise it will have no effect now as it's too late... wxCHECK_RET(!m_started,wxT("wxWizard::SetPageSize after RunWizard"));
wxASSERT_MSG( !WasCreated(), _T("should be called before RunWizard()!") );
m_sizePage = size; m_sizePage = size;
} }
void wxWizard::FinishLayout()
{
m_sizerBmpAndPage->Add(
m_sizerPage,
1, // Horizontal stretching
wxEXPAND | wxALL, // Vertically stretchable
m_sizerPage->Border()
);
GetSizer()->SetSizeHints(this);
if ( m_posWizard == wxDefaultPosition )
CentreOnScreen();
}
void wxWizard::FitToPage(const wxWizardPage *page) void wxWizard::FitToPage(const wxWizardPage *page)
{ {
// otherwise it will have no effect now as it's too late... wxCHECK_RET(!m_started,wxT("wxWizard::FitToPage after RunWizard"));
wxASSERT_MSG( !WasCreated(), _T("should be called before RunWizard()!") );
wxSize sizeMax;
while ( page ) while ( page )
{ {
wxSize size = page->GetBestSize(); wxSize size = page->GetBestSize();
if ( size.x > sizeMax.x ) m_sizePage.IncTo(size);
sizeMax.x = size.x;
if ( size.y > sizeMax.y )
sizeMax.y = size.y;
page = page->GetNext(); 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) bool wxWizard::ShowPage(wxWizardPage *page, bool goingForward)
@@ -373,7 +514,9 @@ bool wxWizard::ShowPage(wxWizardPage *page, bool goingForward)
// position and show the new page // position and show the new page
(void)m_page->TransferDataToWindow(); (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 // check if bitmap needs to be updated
// update default flag as well // update default flag as well
@@ -426,7 +569,12 @@ bool wxWizard::RunWizard(wxWizardPage *firstPage)
{ {
wxCHECK_MSG( firstPage, FALSE, wxT("can't run empty wizard") ); 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 // can't return FALSE here because there is no old page
(void)ShowPage(firstPage, TRUE /* forward */); (void)ShowPage(firstPage, TRUE /* forward */);
@@ -441,11 +589,37 @@ wxWizardPage *wxWizard::GetCurrentPage() const
wxSize wxWizard::GetPageSize() const wxSize wxWizard::GetPageSize() const
{ {
// make sure that the controls are created because otherwise m_width and wxSize pageSize(GetManualPageSize());
// m_height would be both still -1 pageSize.IncTo(m_sizerPage->GetMaxChildSize());
wxConstCast(this, wxWizard)->DoCreateControls(); return pageSize;
}
return wxSize(m_width, m_height); 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;
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)) void wxWizard::OnCancel(wxCommandEvent& WXUNUSED(eventUnused))