]>
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
;
194 (void)new wxStaticLine(this, -1, wxPoint(x
, y
),
195 wxSize(m_x
+ m_width
- x
, 2));
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
);
202 m_btnNext
= new wxButton(this, -1, _("&Next >"), wxPoint(x
, y
), sizeBtn
);
204 x
+= sizeBtn
.x
+ BUTTON_MARGIN
;
205 (void)new wxButton(this, wxID_CANCEL
, _("Cancel"), wxPoint(x
, y
), sizeBtn
);
207 // position and size the dialog
208 // ----------------------------
210 if ( size
== wxDefaultSize
)
212 SetClientSize(m_x
+ m_width
+ X_MARGIN
,
213 m_y
+ m_height
+ BITMAP_Y_MARGIN
+
214 SEPARATOR_LINE_MARGIN
+ sizeBtn
.y
+ Y_MARGIN
);
217 if ( pos
== wxDefaultPosition
)
223 bool wxWizardGeneric::ShowPage(size_t page
)
225 wxCHECK_MSG( page
< m_pages
.GetCount(), FALSE
,
226 _T("invalid wizard page index") );
228 wxASSERT_MSG( page
!= (size_t)m_page
, _T("this is useless") );
230 size_t last
= m_pages
.GetCount() - 1;
231 bool mustChangeNextBtnLabel
= (size_t)m_page
== last
|| page
== last
;
235 wxPanel
*panel
= DoGetCurrentPage();
236 if ( !panel
->TransferDataFromWindow() )
243 DoGetCurrentPage()->Show();
245 // update the buttons state
246 m_btnPrev
->Enable(m_page
!= 0);
247 if ( mustChangeNextBtnLabel
)
249 m_btnNext
->SetLabel((size_t)m_page
== last
? _("&Finish")
256 void wxWizardGeneric::DoAddPage(wxPanel
*page
)
259 page
->SetSize(m_x
, m_y
, m_width
, m_height
);
262 void wxWizardGeneric::AddPage(wxPanel
*page
)
269 void wxWizardGeneric::InsertPage(int nPage
, wxPanel
*page
)
271 m_pages
.Insert(page
, nPage
);
272 if ( nPage
< m_page
)
274 // the indices of all pages after the inserted one are shifted by 1
281 bool wxWizardGeneric::RunWizard()
283 wxCHECK_MSG( m_pages
.GetCount() != 0, FALSE
, _T("can't run empty wizard") );
285 // can't return FALSE here because there is no old page
288 return ShowModal() == wxID_OK
;
291 wxPanel
*wxWizardGeneric::GetCurrentPage() const
293 return IsRunning() ? DoGetCurrentPage() : (wxPanel
*)NULL
;
296 void wxWizardGeneric::OnCancel(wxCommandEvent
& WXUNUSED(event
))
298 wxWizardEvent
event(wxEVT_WIZARD_CANCEL
, GetId());
299 if ( !GetEventHandler()->ProcessEvent(event
) || event
.IsAllowed() )
301 // no objections - close the dialog
302 EndModal(wxID_CANCEL
);
304 //else: request to Cancel ignored
307 void wxWizardGeneric::OnBackOrNext(wxCommandEvent
& event
)
309 wxASSERT_MSG( (event
.GetEventObject() == m_btnNext
) ||
310 (event
.GetEventObject() == m_btnPrev
),
311 _T("unknown button") );
313 int delta
= event
.GetEventObject() == m_btnNext
? 1 : -1;
314 int page
= m_page
+ delta
;
316 wxASSERT_MSG( page
>= 0, _T("'Back' button should have been disabled!") );
318 if ( (size_t)page
== m_pages
.GetCount() )
320 // check that we have valid data in the last page too
321 if ( m_pages
.Last()->TransferDataFromWindow() )
323 // that's all, folks!
329 // just pass to the next page (or may be not - but we don't care here)
330 (void)ShowPage(page
);
334 // ----------------------------------------------------------------------------
335 // our public interface
336 // ----------------------------------------------------------------------------
338 /* static */ wxWizard
*wxWizard::Create(wxWindow
*parent
,
340 const wxString
& title
,
341 const wxBitmap
& bitmap
,
345 return new wxWizardGeneric(parent
, id
, title
, bitmap
, pos
, size
);
348 // ----------------------------------------------------------------------------
350 // ----------------------------------------------------------------------------
352 wxWizardEvent::wxWizardEvent(wxEventType type
, int id
)
353 : wxNotifyEvent(type
, id
)
355 m_page
= m_pageOld
= -1;