]>
git.saurik.com Git - wxWidgets.git/blob - src/generic/wizard.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: generic/wizard.cpp
3 // Purpose: generic implementation of wxWizard class
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation ".h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
32 #include "wx/dynarray.h"
34 #include "wx/statbmp.h"
37 #include "wx/statline.h"
39 #include "wx/wizard.h"
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 WX_DEFINE_ARRAY(wxPanel
*, wxArrayPages
);
47 // ----------------------------------------------------------------------------
48 // wxWizardGeneric - generic implementation of wxWizard
49 // ----------------------------------------------------------------------------
51 class wxWizardGeneric
: public wxWizard
55 wxWizardGeneric(wxWindow
*parent
,
57 const wxString
& title
,
58 const wxBitmap
& bitmap
,
62 // implement base class pure virtuals
63 virtual void AddPage(wxPanel
*page
);
64 virtual void InsertPage(int nPage
, wxPanel
*page
);
65 virtual bool RunWizard();
66 virtual wxPanel
*GetCurrentPage() const;
68 // implementation only from now on
69 // -------------------------------
71 // is the wizard running?
72 bool IsRunning() const { return m_page
!= -1; }
74 // show the given page calling TransferDataFromWindow - if it returns
75 // FALSE, the old page is not hidden and the function returns FALSE
76 bool ShowPage(size_t page
);
78 // get the current page assuming the wizard is running
79 wxPanel
*DoGetCurrentPage() const
81 wxASSERT_MSG( IsRunning(), _T("no current page!") );
83 return m_pages
[(size_t)m_page
];
86 // place the given page correctly and hide it
87 void DoAddPage(wxPanel
*page
);
91 void OnCancel(wxCommandEvent
& event
);
92 void OnBackOrNext(wxCommandEvent
& event
);
95 int m_x
, m_y
; // the origin for the pages
96 int m_width
, // the size of the page itself
97 m_height
; // (total width is m_width + m_x)
100 int m_page
; // the current page or -1
101 wxArrayPages m_pages
; // the array with all wizards pages
104 wxButton
*m_btnPrev
, // the "<Back" button
105 *m_btnNext
; // the "Next>" or "Finish" button
107 DECLARE_EVENT_TABLE()
110 // ----------------------------------------------------------------------------
111 // event tables and such
112 // ----------------------------------------------------------------------------
114 BEGIN_EVENT_TABLE(wxWizardGeneric
, wxDialog
)
115 EVT_BUTTON(wxID_CANCEL
, wxWizardGeneric::OnCancel
)
116 EVT_BUTTON(-1, wxWizardGeneric::OnBackOrNext
)
119 IMPLEMENT_ABSTRACT_CLASS(wxWizard
, wxDialog
)
120 IMPLEMENT_DYNAMIC_CLASS(wxWizardEvent
, wxNotifyEvent
)
122 // ============================================================================
124 // ============================================================================
126 // ----------------------------------------------------------------------------
127 // generic wxWizard implementation
128 // ----------------------------------------------------------------------------
130 wxWizardGeneric::wxWizardGeneric(wxWindow
*parent
,
132 const wxString
& title
,
133 const wxBitmap
& bitmap
,
137 // constants defining the dialog layout
138 // ------------------------------------
140 // these constants define the position of the upper left corner of the
141 // bitmap or the page in the wizard
142 static const int X_MARGIN
= 10;
143 static const int Y_MARGIN
= 10;
145 // margin between the bitmap and the panel
146 static const int BITMAP_X_MARGIN
= 15;
148 // margin between the bitmap and the static line
149 static const int BITMAP_Y_MARGIN
= 15;
151 // margin between the static line and the buttons
152 static const int SEPARATOR_LINE_MARGIN
= 15;
154 // margin between "Next >" and "Cancel" buttons
155 static const int BUTTON_MARGIN
= 10;
157 // default width and height of the page
158 static const int DEFAULT_PAGE_WIDTH
= 270;
159 static const int DEFAULT_PAGE_HEIGHT
= 290;
169 wxSize sizeBtn
= wxButton::GetDefaultSize();
171 (void)wxDialog::Create(parent
, id
, title
, pos
, size
);
173 // the global dialog layout is: a row of buttons at the bottom (aligned to
174 // the right), the static line above them, the bitmap (if any) on the left
175 // of the upper part of the dialog and the panel in the remaining space
180 (void)new wxStaticBitmap(this, -1, bitmap
, wxPoint(m_x
, m_y
));
182 m_x
+= bitmap
.GetWidth() + BITMAP_X_MARGIN
;
183 m_height
= bitmap
.GetHeight();
187 m_height
= DEFAULT_PAGE_HEIGHT
;
190 m_width
= DEFAULT_PAGE_WIDTH
;
193 int y
= m_y
+ m_height
+ BITMAP_Y_MARGIN
;
196 (void)new wxStaticLine(this, -1, wxPoint(x
, y
),
197 wxSize(m_x
+ m_width
- x
, 2));
200 x
= m_x
+ m_width
- 3*sizeBtn
.x
- BUTTON_MARGIN
;
201 y
+= SEPARATOR_LINE_MARGIN
;
202 m_btnPrev
= new wxButton(this, -1, _("< &Back"), wxPoint(x
, y
), sizeBtn
);
205 m_btnNext
= new wxButton(this, -1, _("&Next >"), wxPoint(x
, y
), sizeBtn
);
207 x
+= sizeBtn
.x
+ BUTTON_MARGIN
;
208 (void)new wxButton(this, wxID_CANCEL
, _("Cancel"), wxPoint(x
, y
), sizeBtn
);
210 // position and size the dialog
211 // ----------------------------
213 if ( size
== wxDefaultSize
)
215 SetClientSize(m_x
+ m_width
+ X_MARGIN
,
216 m_y
+ m_height
+ BITMAP_Y_MARGIN
+
217 SEPARATOR_LINE_MARGIN
+ sizeBtn
.y
+ Y_MARGIN
);
220 if ( pos
== wxDefaultPosition
)
226 bool wxWizardGeneric::ShowPage(size_t page
)
228 wxCHECK_MSG( page
< m_pages
.GetCount(), FALSE
,
229 _T("invalid wizard page index") );
231 wxASSERT_MSG( page
!= (size_t)m_page
, _T("this is useless") );
233 size_t last
= m_pages
.GetCount() - 1;
234 bool mustChangeNextBtnLabel
= (size_t)m_page
== last
|| page
== last
;
238 wxPanel
*panel
= DoGetCurrentPage();
239 if ( !panel
->TransferDataFromWindow() )
246 DoGetCurrentPage()->Show();
248 // update the buttons state
249 m_btnPrev
->Enable(m_page
!= 0);
250 if ( mustChangeNextBtnLabel
)
252 m_btnNext
->SetLabel((size_t)m_page
== last
? _("&Finish")
259 void wxWizardGeneric::DoAddPage(wxPanel
*page
)
262 page
->SetSize(m_x
, m_y
, m_width
, m_height
);
265 void wxWizardGeneric::AddPage(wxPanel
*page
)
272 void wxWizardGeneric::InsertPage(int nPage
, wxPanel
*page
)
274 m_pages
.Insert(page
, nPage
);
275 if ( nPage
< m_page
)
277 // the indices of all pages after the inserted one are shifted by 1
284 bool wxWizardGeneric::RunWizard()
286 wxCHECK_MSG( m_pages
.GetCount() != 0, FALSE
, _T("can't run empty wizard") );
288 // can't return FALSE here because there is no old page
291 return ShowModal() == wxID_OK
;
294 wxPanel
*wxWizardGeneric::GetCurrentPage() const
296 return IsRunning() ? DoGetCurrentPage() : (wxPanel
*)NULL
;
299 void wxWizardGeneric::OnCancel(wxCommandEvent
& WXUNUSED(event
))
301 wxWizardEvent
event(wxEVT_WIZARD_CANCEL
, GetId());
302 if ( !GetEventHandler()->ProcessEvent(event
) || event
.IsAllowed() )
304 // no objections - close the dialog
305 EndModal(wxID_CANCEL
);
307 //else: request to Cancel ignored
310 void wxWizardGeneric::OnBackOrNext(wxCommandEvent
& event
)
312 wxASSERT_MSG( (event
.GetEventObject() == m_btnNext
) ||
313 (event
.GetEventObject() == m_btnPrev
),
314 _T("unknown button") );
316 int delta
= event
.GetEventObject() == m_btnNext
? 1 : -1;
317 int page
= m_page
+ delta
;
319 wxASSERT_MSG( page
>= 0, _T("'Back' button should have been disabled!") );
321 if ( (size_t)page
== m_pages
.GetCount() )
323 // check that we have valid data in the last page too
324 if ( m_pages
.Last()->TransferDataFromWindow() )
326 // that's all, folks!
332 // just pass to the next page (or may be not - but we don't care here)
333 (void)ShowPage(page
);
337 // ----------------------------------------------------------------------------
338 // our public interface
339 // ----------------------------------------------------------------------------
341 /* static */ wxWizard
*wxWizard::Create(wxWindow
*parent
,
343 const wxString
& title
,
344 const wxBitmap
& bitmap
,
348 return new wxWizardGeneric(parent
, id
, title
, bitmap
, pos
, size
);
351 // ----------------------------------------------------------------------------
353 // ----------------------------------------------------------------------------
355 wxWizardEvent::wxWizardEvent(wxEventType type
, int id
)
356 : wxNotifyEvent(type
, id
)
358 m_page
= m_pageOld
= -1;