]> git.saurik.com Git - wxWidgets.git/blob - samples/wizard/wizard.cpp
1. fixes to wxDC deleting logic (should fix ~wxPrinterDC leak), some code
[wxWidgets.git] / samples / wizard / wizard.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wizard.cpp
3 // Purpose: wxWindows sample demonstrating wxWizard control
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 15.08.99
7 // RCS-ID: $Id$
8 // Copyright: (c) Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "wizard.cpp"
22 #pragma interface "wizard.cpp"
23 #endif
24
25 // For compilers that support precompilation, includes "wx/wx.h".
26 #include "wx/wxprec.h"
27
28 #ifdef __BORLANDC__
29 #pragma hdrstop
30 #endif
31
32 // for all others, include the necessary headers (this file is usually all you
33 // need because it includes almost all "standard" wxWindows headers
34 #ifndef WX_PRECOMP
35 #include "wx/wx.h"
36 #endif
37
38 #include "wx/wizard.h"
39
40 #ifndef __WXMSW__
41 #include "wiztest.xpm"
42 #endif
43
44 // ----------------------------------------------------------------------------
45 // constants
46 // ----------------------------------------------------------------------------
47
48 // ids for menu items
49 enum
50 {
51 Wizard_Quit = 100,
52 Wizard_Run,
53 Wizard_About = 1000
54 };
55
56 // ----------------------------------------------------------------------------
57 // ressources
58 // ----------------------------------------------------------------------------
59
60 #ifdef __WXMSW__
61 #define BMP_WIZARD_1 wxBitmap("wiztest.bmp", wxBITMAP_TYPE_BMP)
62 #define BMP_WIZARD_2 wxBitmap("wiztest2.bmp", wxBITMAP_TYPE_BMP)
63 #else
64 #define BMP_WIZARD_1 wxBitmap(wizimage)
65 #define BMP_WIZARD_2 wxBitmap(wizimage)
66 #endif
67
68 // ----------------------------------------------------------------------------
69 // private classes
70 // ----------------------------------------------------------------------------
71
72 // Define a new application type, each program should derive a class from wxApp
73 class MyApp : public wxApp
74 {
75 public:
76 // override base class virtuals
77 virtual bool OnInit();
78 };
79
80 class MyFrame : public wxFrame
81 {
82 public:
83 // ctor(s)
84 MyFrame(const wxString& title);
85
86 // event handlers (these functions should _not_ be virtual)
87 void OnQuit(wxCommandEvent& event);
88 void OnAbout(wxCommandEvent& event);
89 void OnRunWizard(wxCommandEvent& event);
90 void OnWizardCancel(wxWizardEvent& event);
91
92 private:
93 // any class wishing to process wxWindows events must use this macro
94 DECLARE_EVENT_TABLE()
95 };
96
97 // ----------------------------------------------------------------------------
98 // some pages for our wizard
99 // ----------------------------------------------------------------------------
100
101 // this shows how to simply control the validity of the user input by just
102 // overriding TransferDataFromWindow() - of course, in a real program, the
103 // check wouldn't be so trivial and the data will be probably saved somewhere
104 // too
105 //
106 // it also shows how to use a different bitmap for one of the pages
107 class wxValidationPage : public wxWizardPageSimple
108 {
109 public:
110 wxValidationPage(wxWizard *parent) : wxWizardPageSimple(parent)
111 {
112 m_bitmap = BMP_WIZARD_2;
113
114 m_checkbox = new wxCheckBox(this, -1, "&Check me");
115 }
116
117 virtual bool TransferDataFromWindow()
118 {
119 if ( !m_checkbox->GetValue() )
120 {
121 wxMessageBox("Check the checkbox first!", "No way",
122 wxICON_WARNING | wxOK, this);
123
124 return FALSE;
125 }
126
127 return TRUE;
128 }
129
130 private:
131 wxCheckBox *m_checkbox;
132 };
133
134 // This is a more complicated example of validity checking: using events we may
135 // allow to return to the previous page, but not to proceed. It also
136 // demonstrates how to intercept [Cancel] button press.
137 class wxRadioboxPage : public wxWizardPageSimple
138 {
139 public:
140 // directions in which we allow the user to proceed from this page
141 enum
142 {
143 Forward, Backward, Both, Neither
144 };
145
146 wxRadioboxPage(wxWizard *parent) : wxWizardPageSimple(parent)
147 {
148 // should correspond to the enum above
149 // static wxString choices[] = { "forward", "backward", "both", "neither" };
150 // The above syntax can cause an internal compiler error with gcc.
151 wxString choices[4];
152 choices[0] = "forward";
153 choices[1] = "backward";
154 choices[2] = "both";
155 choices[3] = "neither";
156
157 m_radio = new wxRadioBox(this, -1, "Allow to proceed:",
158 wxPoint(5, 5), wxDefaultSize,
159 WXSIZEOF(choices), choices,
160 1, wxRA_SPECIFY_COLS);
161 m_radio->SetSelection(Both);
162 }
163
164 // wizard event handlers
165 void OnWizardCancel(wxWizardEvent& event)
166 {
167 if ( wxMessageBox("Do you really want to cancel?", "Question",
168 wxICON_QUESTION | wxYES_NO, this) != wxYES )
169 {
170 // not confirmed
171 event.Veto();
172 }
173 }
174
175 void OnWizardPageChanging(wxWizardEvent& event)
176 {
177 int sel = m_radio->GetSelection();
178
179 if ( sel == Both )
180 return;
181
182 if ( event.GetDirection() && sel == Forward )
183 return;
184
185 if ( !event.GetDirection() && sel == Backward )
186 return;
187
188 wxMessageBox("You can't go there", "Not allowed",
189 wxICON_WARNING | wxOK, this);
190
191 event.Veto();
192 }
193
194 private:
195 wxRadioBox *m_radio;
196
197 DECLARE_EVENT_TABLE()
198 };
199
200 // this shows how to dynamically (i.e. during run-time) arrange the page order
201 class wxCheckboxPage : public wxWizardPage
202 {
203 public:
204 wxCheckboxPage(wxWizard *parent,
205 wxWizardPage *prev,
206 wxWizardPage *next)
207 : wxWizardPage(parent)
208 {
209 m_prev = prev;
210 m_next = next;
211
212 (void)new wxStaticText(this, -1, "Try checking the box below and\n"
213 "then going back and clearing it");
214
215 m_checkbox = new wxCheckBox(this, -1, "&Skip the next page",
216 wxPoint(5, 30));
217 }
218
219 // implement wxWizardPage functions
220 virtual wxWizardPage *GetPrev() const { return m_prev; }
221 virtual wxWizardPage *GetNext() const
222 {
223 return m_checkbox->GetValue() ? m_next->GetNext() : m_next;
224 }
225
226 private:
227 wxWizardPage *m_prev,
228 *m_next;
229
230 wxCheckBox *m_checkbox;
231 };
232
233 // ============================================================================
234 // implementation
235 // ============================================================================
236
237 // ----------------------------------------------------------------------------
238 // event tables and such
239 // ----------------------------------------------------------------------------
240
241 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
242 EVT_MENU(Wizard_Quit, MyFrame::OnQuit)
243 EVT_MENU(Wizard_About, MyFrame::OnAbout)
244 EVT_MENU(Wizard_Run, MyFrame::OnRunWizard)
245
246 EVT_WIZARD_CANCEL(-1, MyFrame::OnWizardCancel)
247 END_EVENT_TABLE()
248
249 BEGIN_EVENT_TABLE(wxRadioboxPage, wxWizardPageSimple)
250 EVT_WIZARD_PAGE_CHANGING(-1, wxRadioboxPage::OnWizardPageChanging)
251 EVT_WIZARD_CANCEL(-1, wxRadioboxPage::OnWizardCancel)
252 END_EVENT_TABLE()
253
254 IMPLEMENT_APP(MyApp)
255
256 // ----------------------------------------------------------------------------
257 // the application class
258 // ----------------------------------------------------------------------------
259
260 // `Main program' equivalent: the program execution "starts" here
261 bool MyApp::OnInit()
262 {
263 MyFrame *frame = new MyFrame("wxWizard Sample");
264
265 // and show it (the frames, unlike simple controls, are not shown when
266 // created initially)
267 frame->Show(TRUE);
268
269 // we're done
270 return TRUE;
271 }
272
273 // ----------------------------------------------------------------------------
274 // MyFrame
275 // ----------------------------------------------------------------------------
276
277 MyFrame::MyFrame(const wxString& title)
278 : wxFrame((wxFrame *)NULL, -1, title,
279 wxDefaultPosition, wxSize(250, 150)) // small frame
280 {
281 wxMenu *menuFile = new wxMenu;
282 menuFile->Append(Wizard_Run, "&Run wizard...\tCtrl-R");
283 menuFile->AppendSeparator();
284 menuFile->Append(Wizard_Quit, "E&xit\tAlt-X", "Quit this program");
285
286 wxMenu *helpMenu = new wxMenu;
287 helpMenu->Append(Wizard_About, "&About...\tF1", "Show about dialog");
288
289 // now append the freshly created menu to the menu bar...
290 wxMenuBar *menuBar = new wxMenuBar();
291 menuBar->Append(menuFile, "&File");
292 menuBar->Append(helpMenu, "&Help");
293
294 // ... and attach this menu bar to the frame
295 SetMenuBar(menuBar);
296
297 // also create status bar which we use in OnWizardCancel
298 CreateStatusBar();
299 }
300
301 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
302 {
303 // TRUE is to force the frame to close
304 Close(TRUE);
305 }
306
307 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
308 {
309 wxMessageBox("Demo of wxWizard class\n"
310 "© 1999, 2000 Vadim Zeitlin",
311 "About wxWizard sample", wxOK | wxICON_INFORMATION, this);
312 }
313
314 void MyFrame::OnRunWizard(wxCommandEvent& WXUNUSED(event))
315 {
316 wxWizard *wizard = wxWizard::Create(this, -1,
317 "Absolutely Useless Wizard",
318 BMP_WIZARD_1);
319
320 // a wizard page may be either an object of predefined class
321 wxWizardPageSimple *page1 = new wxWizardPageSimple(wizard);
322 wxStaticText *text = new wxStaticText(page1, -1,
323 "This wizard doesn't help you to do anything at all.\n"
324 "\n"
325 "The next pages will present you with more useless controls."
326 );
327 wxSize size = text->GetBestSize();
328
329 // ... or a derived class
330 wxRadioboxPage *page3 = new wxRadioboxPage(wizard);
331 wxValidationPage *page4 = new wxValidationPage(wizard);
332
333 // set the page order using a convenience function - could also use
334 // SetNext/Prev directly as below
335 wxWizardPageSimple::Chain(page3, page4);
336
337 // this page is not a wxWizardPageSimple, so we use SetNext/Prev to insert
338 // it into the chain of pages
339 wxCheckboxPage *page2 = new wxCheckboxPage(wizard, page1, page3);
340 page1->SetNext(page2);
341 page3->SetPrev(page2);
342
343 wizard->SetPageSize(size);
344 if ( wizard->RunWizard(page1) )
345 {
346 wxMessageBox("The wizard successfully completed", "That's all",
347 wxICON_INFORMATION | wxOK);
348 }
349
350 wizard->Destroy();
351 }
352
353 void MyFrame::OnWizardCancel(wxWizardEvent& WXUNUSED(event))
354 {
355 wxLogStatus(this, "The wizard was cancelled.");
356 }