]> git.saurik.com Git - wxWidgets.git/blame - src/generic/wizard.cpp
tiny fixes
[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
66cd017c
VZ
47// ----------------------------------------------------------------------------
48// event tables and such
49// ----------------------------------------------------------------------------
50
74b31181
VZ
51BEGIN_EVENT_TABLE(wxWizard, wxDialog)
52 EVT_BUTTON(wxID_CANCEL, wxWizard::OnCancel)
53 EVT_BUTTON(-1, wxWizard::OnBackOrNext)
66cd017c
VZ
54END_EVENT_TABLE()
55
74b31181
VZ
56IMPLEMENT_DYNAMIC_CLASS(wxWizard, wxDialog)
57IMPLEMENT_ABSTRACT_CLASS(wxWizardPage, wxPanel)
58IMPLEMENT_DYNAMIC_CLASS(wxWizardPageSimple, wxWizardPage)
66cd017c
VZ
59IMPLEMENT_DYNAMIC_CLASS(wxWizardEvent, wxNotifyEvent)
60
61// ============================================================================
62// implementation
63// ============================================================================
64
74b31181
VZ
65// ----------------------------------------------------------------------------
66// wxWizardPage
67// ----------------------------------------------------------------------------
68
69wxWizardPage::wxWizardPage(wxWizard *parent) : wxPanel(parent)
70{
71 // initially the page is hidden, it's shown only when it becomes current
72 Hide();
73}
74
75// ----------------------------------------------------------------------------
76// wxWizardPageSimple
77// ----------------------------------------------------------------------------
78
79wxWizardPage *wxWizardPageSimple::GetPrev() const
80{
81 return m_prev;
82}
83
84wxWizardPage *wxWizardPageSimple::GetNext() const
85{
86 return m_next;
87}
66cd017c
VZ
88// ----------------------------------------------------------------------------
89// generic wxWizard implementation
90// ----------------------------------------------------------------------------
91
74b31181
VZ
92wxWizard::wxWizard(wxWindow *parent,
93 int id,
94 const wxString& title,
95 const wxBitmap& bitmap,
96 const wxPoint& pos,
97 const wxSize& size)
66cd017c
VZ
98{
99 // constants defining the dialog layout
100 // ------------------------------------
101
102 // these constants define the position of the upper left corner of the
103 // bitmap or the page in the wizard
104 static const int X_MARGIN = 10;
105 static const int Y_MARGIN = 10;
106
107 // margin between the bitmap and the panel
108 static const int BITMAP_X_MARGIN = 15;
109
110 // margin between the bitmap and the static line
111 static const int BITMAP_Y_MARGIN = 15;
112
113 // margin between the static line and the buttons
114 static const int SEPARATOR_LINE_MARGIN = 15;
115
116 // margin between "Next >" and "Cancel" buttons
117 static const int BUTTON_MARGIN = 10;
118
119 // default width and height of the page
120 static const int DEFAULT_PAGE_WIDTH = 270;
121 static const int DEFAULT_PAGE_HEIGHT = 290;
122
123 // init members
124 // ------------
125
74b31181 126 m_page = (wxWizardPage *)NULL;
66cd017c
VZ
127
128 // create controls
129 // ---------------
130
131 wxSize sizeBtn = wxButton::GetDefaultSize();
132
133 (void)wxDialog::Create(parent, id, title, pos, size);
134
135 // the global dialog layout is: a row of buttons at the bottom (aligned to
136 // the right), the static line above them, the bitmap (if any) on the left
137 // of the upper part of the dialog and the panel in the remaining space
138 m_x = X_MARGIN;
139 m_y = Y_MARGIN;
140 if ( bitmap.Ok() )
141 {
142 (void)new wxStaticBitmap(this, -1, bitmap, wxPoint(m_x, m_y));
143
144 m_x += bitmap.GetWidth() + BITMAP_X_MARGIN;
145 m_height = bitmap.GetHeight();
146 }
147 else
148 {
149 m_height = DEFAULT_PAGE_HEIGHT;
150 }
151
152 m_width = DEFAULT_PAGE_WIDTH;
153
154 int x = X_MARGIN;
155 int y = m_y + m_height + BITMAP_Y_MARGIN;
74b31181
VZ
156
157#if wxUSE_STATLINE
66cd017c
VZ
158 (void)new wxStaticLine(this, -1, wxPoint(x, y),
159 wxSize(m_x + m_width - x, 2));
41435ed2 160#endif
74b31181 161
66cd017c
VZ
162 x = m_x + m_width - 3*sizeBtn.x - BUTTON_MARGIN;
163 y += SEPARATOR_LINE_MARGIN;
164 m_btnPrev = new wxButton(this, -1, _("< &Back"), wxPoint(x, y), sizeBtn);
165
166 x += sizeBtn.x;
167 m_btnNext = new wxButton(this, -1, _("&Next >"), wxPoint(x, y), sizeBtn);
168
169 x += sizeBtn.x + BUTTON_MARGIN;
170 (void)new wxButton(this, wxID_CANCEL, _("Cancel"), wxPoint(x, y), sizeBtn);
171
172 // position and size the dialog
173 // ----------------------------
174
175 if ( size == wxDefaultSize )
176 {
177 SetClientSize(m_x + m_width + X_MARGIN,
178 m_y + m_height + BITMAP_Y_MARGIN +
179 SEPARATOR_LINE_MARGIN + sizeBtn.y + Y_MARGIN);
180 }
181
182 if ( pos == wxDefaultPosition )
183 {
184 Centre();
185 }
186}
187
74b31181 188bool wxWizard::ShowPage(wxWizardPage *page, bool goingForward)
66cd017c 189{
e90c1d2a 190 wxASSERT_MSG( page != m_page, T("this is useless") );
66cd017c 191
74b31181
VZ
192 // we'll use this to decide whether we have to change the label of this
193 // button or not (initially the label is "Next")
194 bool btnLabelWasNext = TRUE;
66cd017c 195
74b31181 196 if ( m_page )
66cd017c 197 {
74b31181
VZ
198 // ask the current page first
199 if ( !m_page->TransferDataFromWindow() )
200 {
201 // the page data is incorrect
202 return FALSE;
203 }
204
205 // send the event to the old page
206 wxWizardEvent event(wxEVT_WIZARD_PAGE_CHANGING, GetId(), goingForward);
207 if ( m_page->GetEventHandler()->ProcessEvent(event) &&
208 !event.IsAllowed() )
209 {
210 // vetoed by the page
66cd017c 211 return FALSE;
74b31181 212 }
66cd017c 213
74b31181
VZ
214 m_page->Hide();
215
216 btnLabelWasNext = m_page->GetNext() != (wxWizardPage *)NULL;
66cd017c
VZ
217 }
218
74b31181 219 // set the new one
66cd017c 220 m_page = page;
66cd017c 221
74b31181
VZ
222 // is this the end?
223 if ( !m_page )
66cd017c 224 {
74b31181
VZ
225 // terminate successfully
226 EndModal(wxID_OK);
66cd017c 227
74b31181
VZ
228 return TRUE;
229 }
66cd017c 230
74b31181
VZ
231 // send the event to the new page now
232 wxWizardEvent event(wxEVT_WIZARD_PAGE_CHANGED, GetId(), goingForward);
233 (void)m_page->GetEventHandler()->ProcessEvent(event);
66cd017c 234
74b31181
VZ
235 // position and show the new page
236 (void)m_page->TransferDataToWindow();
237 m_page->SetSize(m_x, m_y, m_width, m_height);
238 m_page->Show();
66cd017c 239
74b31181
VZ
240 // and update the buttons state
241 m_btnPrev->Enable(m_page->GetPrev() != (wxWizardPage *)NULL);
66cd017c 242
74b31181 243 if ( btnLabelWasNext != (m_page->GetNext() != (wxWizardPage *)NULL) )
66cd017c 244 {
74b31181
VZ
245 // need to update
246 m_btnNext->SetLabel(btnLabelWasNext ? _("&Finish") : _("&Next >"));
66cd017c 247 }
74b31181 248 // nothing to do: the label was already correct
66cd017c 249
74b31181 250 return TRUE;
66cd017c
VZ
251}
252
74b31181 253bool wxWizard::RunWizard(wxWizardPage *firstPage)
66cd017c 254{
e90c1d2a 255 wxCHECK_MSG( firstPage, FALSE, T("can't run empty wizard") );
66cd017c
VZ
256
257 // can't return FALSE here because there is no old page
74b31181 258 (void)ShowPage(firstPage, TRUE /* forward */);
66cd017c
VZ
259
260 return ShowModal() == wxID_OK;
261}
262
74b31181 263wxWizardPage *wxWizard::GetCurrentPage() const
66cd017c 264{
74b31181 265 return m_page;
66cd017c
VZ
266}
267
74b31181 268void wxWizard::OnCancel(wxCommandEvent& WXUNUSED(event))
66cd017c 269{
74b31181
VZ
270 // this function probably can never be called when we don't have an active
271 // page, but a small extra check won't hurt
272 wxWindow *win = m_page ? (wxWindow *)m_page : (wxWindow *)this;
273
66cd017c 274 wxWizardEvent event(wxEVT_WIZARD_CANCEL, GetId());
74b31181 275 if ( !win->GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
66cd017c
VZ
276 {
277 // no objections - close the dialog
278 EndModal(wxID_CANCEL);
279 }
280 //else: request to Cancel ignored
281}
282
74b31181 283void wxWizard::OnBackOrNext(wxCommandEvent& event)
66cd017c
VZ
284{
285 wxASSERT_MSG( (event.GetEventObject() == m_btnNext) ||
286 (event.GetEventObject() == m_btnPrev),
e90c1d2a 287 T("unknown button") );
66cd017c 288
74b31181 289 bool forward = event.GetEventObject() == m_btnNext;
66cd017c 290
74b31181
VZ
291 wxWizardPage *page;
292 if ( forward )
66cd017c 293 {
74b31181 294 page = m_page->GetNext();
66cd017c 295 }
74b31181 296 else // back
66cd017c 297 {
74b31181
VZ
298 page = m_page->GetPrev();
299
e90c1d2a 300 wxASSERT_MSG( page, T("\"<Back\" button should have been disabled") );
66cd017c 301 }
74b31181
VZ
302
303 // just pass to the new page (or may be not - but we don't care here)
304 (void)ShowPage(page, forward);
66cd017c
VZ
305}
306
307// ----------------------------------------------------------------------------
308// our public interface
309// ----------------------------------------------------------------------------
310
74b31181
VZ
311/* static */
312wxWizard *wxWizardBase::Create(wxWindow *parent,
313 int id,
314 const wxString& title,
315 const wxBitmap& bitmap,
316 const wxPoint& pos,
317 const wxSize& size)
66cd017c 318{
74b31181 319 return new wxWizard(parent, id, title, bitmap, pos, size);
66cd017c
VZ
320}
321
322// ----------------------------------------------------------------------------
323// wxWizardEvent
324// ----------------------------------------------------------------------------
325
74b31181 326wxWizardEvent::wxWizardEvent(wxEventType type, int id, bool direction)
66cd017c
VZ
327 : wxNotifyEvent(type, id)
328{
74b31181 329 m_direction = direction;
66cd017c 330}
74b31181 331