]> git.saurik.com Git - wxWidgets.git/blame - src/generic/wizard.cpp
Minor corrections to be able to compile with VC++ 1.5C and VC++ 4.1
[wxWidgets.git] / src / generic / wizard.cpp
CommitLineData
66cd017c
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: generic/wizard.cpp
3// Purpose: generic implementation of wxWizard class
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 15.08.99
7// RCS-ID: $Id$
8// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows license
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#ifdef __GNUG__
21 #pragma implementation ".h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32 #include "wx/dynarray.h"
33 #include "wx/intl.h"
b87654f3 34 #include "wx/statbmp.h"
66cd017c
VZ
35#endif //WX_PRECOMP
36
37#include "wx/statline.h"
38
39#include "wx/wizard.h"
40
41// ----------------------------------------------------------------------------
42// simple types
43// ----------------------------------------------------------------------------
44
45WX_DEFINE_ARRAY(wxPanel *, wxArrayPages);
46
47// ----------------------------------------------------------------------------
48// wxWizardGeneric - generic implementation of wxWizard
49// ----------------------------------------------------------------------------
50
51class wxWizardGeneric : public wxWizard
52{
53public:
54 // ctor
55 wxWizardGeneric(wxWindow *parent,
56 int id,
57 const wxString& title,
58 const wxBitmap& bitmap,
59 const wxPoint& pos,
60 const wxSize& size);
61
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;
67
68 // implementation only from now on
69 // -------------------------------
70
71 // is the wizard running?
72 bool IsRunning() const { return m_page != -1; }
73
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);
77
78 // get the current page assuming the wizard is running
79 wxPanel *DoGetCurrentPage() const
80 {
81 wxASSERT_MSG( IsRunning(), _T("no current page!") );
82
83 return m_pages[(size_t)m_page];
84 }
85
86 // place the given page correctly and hide it
87 void DoAddPage(wxPanel *page);
88
89private:
90 // event handlers
91 void OnCancel(wxCommandEvent& event);
92 void OnBackOrNext(wxCommandEvent& event);
93
94 // wizard dimensions
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)
98
99 // wizard state
100 int m_page; // the current page or -1
101 wxArrayPages m_pages; // the array with all wizards pages
102
103 // wizard controls
104 wxButton *m_btnPrev, // the "<Back" button
105 *m_btnNext; // the "Next>" or "Finish" button
106
107 DECLARE_EVENT_TABLE()
108};
109
110// ----------------------------------------------------------------------------
111// event tables and such
112// ----------------------------------------------------------------------------
113
114BEGIN_EVENT_TABLE(wxWizardGeneric, wxDialog)
f3b8ef89
RS
115 EVT_BUTTON(wxID_CANCEL, wxWizardGeneric::OnCancel)
116 EVT_BUTTON(-1, wxWizardGeneric::OnBackOrNext)
66cd017c
VZ
117END_EVENT_TABLE()
118
119IMPLEMENT_ABSTRACT_CLASS(wxWizard, wxDialog)
120IMPLEMENT_DYNAMIC_CLASS(wxWizardEvent, wxNotifyEvent)
121
122// ============================================================================
123// implementation
124// ============================================================================
125
126// ----------------------------------------------------------------------------
127// generic wxWizard implementation
128// ----------------------------------------------------------------------------
129
130wxWizardGeneric::wxWizardGeneric(wxWindow *parent,
131 int id,
132 const wxString& title,
133 const wxBitmap& bitmap,
134 const wxPoint& pos,
135 const wxSize& size)
136{
137 // constants defining the dialog layout
138 // ------------------------------------
139
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;
144
145 // margin between the bitmap and the panel
146 static const int BITMAP_X_MARGIN = 15;
147
148 // margin between the bitmap and the static line
149 static const int BITMAP_Y_MARGIN = 15;
150
151 // margin between the static line and the buttons
152 static const int SEPARATOR_LINE_MARGIN = 15;
153
154 // margin between "Next >" and "Cancel" buttons
155 static const int BUTTON_MARGIN = 10;
156
157 // default width and height of the page
158 static const int DEFAULT_PAGE_WIDTH = 270;
159 static const int DEFAULT_PAGE_HEIGHT = 290;
160
161 // init members
162 // ------------
163
164 m_page = -1;
165
166 // create controls
167 // ---------------
168
169 wxSize sizeBtn = wxButton::GetDefaultSize();
170
171 (void)wxDialog::Create(parent, id, title, pos, size);
172
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
176 m_x = X_MARGIN;
177 m_y = Y_MARGIN;
178 if ( bitmap.Ok() )
179 {
180 (void)new wxStaticBitmap(this, -1, bitmap, wxPoint(m_x, m_y));
181
182 m_x += bitmap.GetWidth() + BITMAP_X_MARGIN;
183 m_height = bitmap.GetHeight();
184 }
185 else
186 {
187 m_height = DEFAULT_PAGE_HEIGHT;
188 }
189
190 m_width = DEFAULT_PAGE_WIDTH;
191
192 int x = X_MARGIN;
193 int y = m_y + m_height + BITMAP_Y_MARGIN;
194 (void)new wxStaticLine(this, -1, wxPoint(x, y),
195 wxSize(m_x + m_width - x, 2));
196
197 x = m_x + m_width - 3*sizeBtn.x - BUTTON_MARGIN;
198 y += SEPARATOR_LINE_MARGIN;
199 m_btnPrev = new wxButton(this, -1, _("< &Back"), wxPoint(x, y), sizeBtn);
200
201 x += sizeBtn.x;
202 m_btnNext = new wxButton(this, -1, _("&Next >"), wxPoint(x, y), sizeBtn);
203
204 x += sizeBtn.x + BUTTON_MARGIN;
205 (void)new wxButton(this, wxID_CANCEL, _("Cancel"), wxPoint(x, y), sizeBtn);
206
207 // position and size the dialog
208 // ----------------------------
209
210 if ( size == wxDefaultSize )
211 {
212 SetClientSize(m_x + m_width + X_MARGIN,
213 m_y + m_height + BITMAP_Y_MARGIN +
214 SEPARATOR_LINE_MARGIN + sizeBtn.y + Y_MARGIN);
215 }
216
217 if ( pos == wxDefaultPosition )
218 {
219 Centre();
220 }
221}
222
223bool wxWizardGeneric::ShowPage(size_t page)
224{
225 wxCHECK_MSG( page < m_pages.GetCount(), FALSE,
226 _T("invalid wizard page index") );
227
228 wxASSERT_MSG( page != (size_t)m_page, _T("this is useless") );
229
230 size_t last = m_pages.GetCount() - 1;
231 bool mustChangeNextBtnLabel = (size_t)m_page == last || page == last;
232
233 if ( m_page != -1 )
234 {
235 wxPanel *panel = DoGetCurrentPage();
236 if ( !panel->TransferDataFromWindow() )
237 return FALSE;
238
239 panel->Hide();
240 }
241
242 m_page = page;
243 DoGetCurrentPage()->Show();
244
245 // update the buttons state
246 m_btnPrev->Enable(m_page != 0);
247 if ( mustChangeNextBtnLabel )
248 {
249 m_btnNext->SetLabel((size_t)m_page == last ? _("&Finish")
250 : _("&Next >"));
251 }
252
253 return TRUE;
254}
255
256void wxWizardGeneric::DoAddPage(wxPanel *page)
257{
258 page->Hide();
259 page->SetSize(m_x, m_y, m_width, m_height);
260}
261
262void wxWizardGeneric::AddPage(wxPanel *page)
263{
264 m_pages.Add(page);
265
266 DoAddPage(page);
267}
268
269void wxWizardGeneric::InsertPage(int nPage, wxPanel *page)
270{
271 m_pages.Insert(page, nPage);
272 if ( nPage < m_page )
273 {
274 // the indices of all pages after the inserted one are shifted by 1
275 m_page++;
276 }
277
278 DoAddPage(page);
279}
280
281bool wxWizardGeneric::RunWizard()
282{
283 wxCHECK_MSG( m_pages.GetCount() != 0, FALSE, _T("can't run empty wizard") );
284
285 // can't return FALSE here because there is no old page
286 (void)ShowPage(0u);
287
288 return ShowModal() == wxID_OK;
289}
290
291wxPanel *wxWizardGeneric::GetCurrentPage() const
292{
293 return IsRunning() ? DoGetCurrentPage() : (wxPanel *)NULL;
294}
295
296void wxWizardGeneric::OnCancel(wxCommandEvent& WXUNUSED(event))
297{
298 wxWizardEvent event(wxEVT_WIZARD_CANCEL, GetId());
299 if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
300 {
301 // no objections - close the dialog
302 EndModal(wxID_CANCEL);
303 }
304 //else: request to Cancel ignored
305}
306
307void wxWizardGeneric::OnBackOrNext(wxCommandEvent& event)
308{
309 wxASSERT_MSG( (event.GetEventObject() == m_btnNext) ||
310 (event.GetEventObject() == m_btnPrev),
311 _T("unknown button") );
312
313 int delta = event.GetEventObject() == m_btnNext ? 1 : -1;
314 int page = m_page + delta;
315
316 wxASSERT_MSG( page >= 0, _T("'Back' button should have been disabled!") );
317
318 if ( (size_t)page == m_pages.GetCount() )
319 {
320 // check that we have valid data in the last page too
321 if ( m_pages.Last()->TransferDataFromWindow() )
322 {
323 // that's all, folks!
324 EndModal(wxID_OK);
325 }
326 }
327 else
328 {
329 // just pass to the next page (or may be not - but we don't care here)
330 (void)ShowPage(page);
331 }
332}
333
334// ----------------------------------------------------------------------------
335// our public interface
336// ----------------------------------------------------------------------------
337
338/* static */ wxWizard *wxWizard::Create(wxWindow *parent,
339 int id,
340 const wxString& title,
341 const wxBitmap& bitmap,
342 const wxPoint& pos,
343 const wxSize& size)
344{
345 return new wxWizardGeneric(parent, id, title, bitmap, pos, size);
346}
347
348// ----------------------------------------------------------------------------
349// wxWizardEvent
350// ----------------------------------------------------------------------------
351
352wxWizardEvent::wxWizardEvent(wxEventType type, int id)
353 : wxNotifyEvent(type, id)
354{
355 m_page = m_pageOld = -1;
356}