]> git.saurik.com Git - wxWidgets.git/blame - src/generic/wizard.cpp
Added GSocket/wxSocket alias to socket.h to prevent us from using GSocket
[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;
41435ed2
MB
194
195#if wxUSE_STATLINE
66cd017c
VZ
196 (void)new wxStaticLine(this, -1, wxPoint(x, y),
197 wxSize(m_x + m_width - x, 2));
41435ed2
MB
198#endif
199
66cd017c
VZ
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);
203
204 x += sizeBtn.x;
205 m_btnNext = new wxButton(this, -1, _("&Next >"), wxPoint(x, y), sizeBtn);
206
207 x += sizeBtn.x + BUTTON_MARGIN;
208 (void)new wxButton(this, wxID_CANCEL, _("Cancel"), wxPoint(x, y), sizeBtn);
209
210 // position and size the dialog
211 // ----------------------------
212
213 if ( size == wxDefaultSize )
214 {
215 SetClientSize(m_x + m_width + X_MARGIN,
216 m_y + m_height + BITMAP_Y_MARGIN +
217 SEPARATOR_LINE_MARGIN + sizeBtn.y + Y_MARGIN);
218 }
219
220 if ( pos == wxDefaultPosition )
221 {
222 Centre();
223 }
224}
225
226bool wxWizardGeneric::ShowPage(size_t page)
227{
228 wxCHECK_MSG( page < m_pages.GetCount(), FALSE,
229 _T("invalid wizard page index") );
230
231 wxASSERT_MSG( page != (size_t)m_page, _T("this is useless") );
232
233 size_t last = m_pages.GetCount() - 1;
234 bool mustChangeNextBtnLabel = (size_t)m_page == last || page == last;
235
236 if ( m_page != -1 )
237 {
238 wxPanel *panel = DoGetCurrentPage();
239 if ( !panel->TransferDataFromWindow() )
240 return FALSE;
241
242 panel->Hide();
243 }
244
245 m_page = page;
246 DoGetCurrentPage()->Show();
247
248 // update the buttons state
249 m_btnPrev->Enable(m_page != 0);
250 if ( mustChangeNextBtnLabel )
251 {
252 m_btnNext->SetLabel((size_t)m_page == last ? _("&Finish")
253 : _("&Next >"));
254 }
255
256 return TRUE;
257}
258
259void wxWizardGeneric::DoAddPage(wxPanel *page)
260{
261 page->Hide();
262 page->SetSize(m_x, m_y, m_width, m_height);
263}
264
265void wxWizardGeneric::AddPage(wxPanel *page)
266{
267 m_pages.Add(page);
268
269 DoAddPage(page);
270}
271
272void wxWizardGeneric::InsertPage(int nPage, wxPanel *page)
273{
274 m_pages.Insert(page, nPage);
275 if ( nPage < m_page )
276 {
277 // the indices of all pages after the inserted one are shifted by 1
278 m_page++;
279 }
280
281 DoAddPage(page);
282}
283
284bool wxWizardGeneric::RunWizard()
285{
286 wxCHECK_MSG( m_pages.GetCount() != 0, FALSE, _T("can't run empty wizard") );
287
288 // can't return FALSE here because there is no old page
289 (void)ShowPage(0u);
290
291 return ShowModal() == wxID_OK;
292}
293
294wxPanel *wxWizardGeneric::GetCurrentPage() const
295{
296 return IsRunning() ? DoGetCurrentPage() : (wxPanel *)NULL;
297}
298
299void wxWizardGeneric::OnCancel(wxCommandEvent& WXUNUSED(event))
300{
301 wxWizardEvent event(wxEVT_WIZARD_CANCEL, GetId());
302 if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
303 {
304 // no objections - close the dialog
305 EndModal(wxID_CANCEL);
306 }
307 //else: request to Cancel ignored
308}
309
310void wxWizardGeneric::OnBackOrNext(wxCommandEvent& event)
311{
312 wxASSERT_MSG( (event.GetEventObject() == m_btnNext) ||
313 (event.GetEventObject() == m_btnPrev),
314 _T("unknown button") );
315
316 int delta = event.GetEventObject() == m_btnNext ? 1 : -1;
317 int page = m_page + delta;
318
319 wxASSERT_MSG( page >= 0, _T("'Back' button should have been disabled!") );
320
321 if ( (size_t)page == m_pages.GetCount() )
322 {
323 // check that we have valid data in the last page too
324 if ( m_pages.Last()->TransferDataFromWindow() )
325 {
326 // that's all, folks!
327 EndModal(wxID_OK);
328 }
329 }
330 else
331 {
332 // just pass to the next page (or may be not - but we don't care here)
333 (void)ShowPage(page);
334 }
335}
336
337// ----------------------------------------------------------------------------
338// our public interface
339// ----------------------------------------------------------------------------
340
341/* static */ wxWizard *wxWizard::Create(wxWindow *parent,
342 int id,
343 const wxString& title,
344 const wxBitmap& bitmap,
345 const wxPoint& pos,
346 const wxSize& size)
347{
348 return new wxWizardGeneric(parent, id, title, bitmap, pos, size);
349}
350
351// ----------------------------------------------------------------------------
352// wxWizardEvent
353// ----------------------------------------------------------------------------
354
355wxWizardEvent::wxWizardEvent(wxEventType type, int id)
356 : wxNotifyEvent(type, id)
357{
358 m_page = m_pageOld = -1;
359}