1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // wxFormBuilder - A Visual Dialog Editor for wxWidgets.
4 // Copyright (C) 2005 José Antonio Hurtado
5 //
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 //
20 // Written by
21 // Andrea Zanellato - zanellato.andrea@gmail.com
22 // based on original wizard.cpp file in wxWidgets source code
23 //
24 ///////////////////////////////////////////////////////////////////////////////
25 #include "wizard.h"
26
27 #include <wx/log.h>
28
29 DEFINE_EVENT_TYPE(wxFB_EVT_WIZARD_PAGE_CHANGED)
DEFINE_EVENT_TYPE(wxFB_EVT_WIZARD_PAGE_CHANGING)30 DEFINE_EVENT_TYPE(wxFB_EVT_WIZARD_PAGE_CHANGING)
31 DEFINE_EVENT_TYPE(wxFB_EVT_WIZARD_CANCEL)
32 DEFINE_EVENT_TYPE(wxFB_EVT_WIZARD_FINISHED)
33 DEFINE_EVENT_TYPE(wxFB_EVT_WIZARD_HELP)
34 #if wxABI_VERSION >= 20811
35 DEFINE_EVENT_TYPE(wxFB_EVT_WIZARD_PAGE_SHOWN)
36 #endif
37 /*
38 BEGIN_EVENT_TABLE( Wizard, wxPanel )
39 EVT_BUTTON( wxID_CANCEL, Wizard::OnCancel )
40 EVT_BUTTON( wxID_BACKWARD, Wizard::OnBackOrNext )
41 EVT_BUTTON( wxID_FORWARD, Wizard::OnBackOrNext )
42 EVT_BUTTON( wxID_HELP, Wizard::OnHelp )
43
44 EVT_WXFB_WIZARD_PAGE_CHANGED( wxID_ANY, Wizard::OnWizEvent )
45 EVT_WXFB_WIZARD_PAGE_CHANGING( wxID_ANY, Wizard::OnWizEvent )
46 EVT_WXFB_WIZARD_CANCEL( wxID_ANY, Wizard::OnWizEvent )
47 EVT_WXFB_WIZARD_FINISHED( wxID_ANY, Wizard::OnWizEvent )
48 EVT_WXFB_WIZARD_HELP( wxID_ANY, Wizard::OnWizEvent )
49 END_EVENT_TABLE()
50 */
51 WizardPageSimple::WizardPageSimple( Wizard *parent )
52 : wxPanel( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 )
53 {
54 }
55
~WizardPageSimple()56 WizardPageSimple::~WizardPageSimple()
57 {
58 }
59
Wizard(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,long style)60 Wizard::Wizard( wxWindow* parent, wxWindowID id,
61 const wxPoint& pos, const wxSize& size, long style )
62 : wxPanel( parent, id, pos, size, style )
63 {
64 m_page = NULL;
65 m_bitmap = wxNullBitmap;
66
67 wxBoxSizer *windowSizer = new wxBoxSizer( wxVERTICAL );
68 wxBoxSizer *mainColumn = new wxBoxSizer( wxVERTICAL );
69 wxBoxSizer *buttonRow = new wxBoxSizer( wxHORIZONTAL );
70 wxBoxSizer *backNextPair = new wxBoxSizer( wxHORIZONTAL );
71 m_sizerBmpAndPage = new wxBoxSizer( wxHORIZONTAL );
72 m_sizerPage = new wxBoxSizer( wxVERTICAL );
73
74 m_statbmp = new wxStaticBitmap( this, wxID_ANY, wxNullBitmap );
75
76 m_sizerBmpAndPage->SetMinSize( wxSize( 270, 270 ) );
77 m_sizerBmpAndPage->Add( m_statbmp, 0, wxALL, 5 );
78 m_sizerBmpAndPage->Add( 5, 0, 0, wxEXPAND, 0 );
79 m_sizerBmpAndPage->Add( m_sizerPage, 1, wxEXPAND, 0 );
80
81 m_btnHelp = new wxButton( this, wxID_HELP, _("&Help") );
82 m_btnPrev = new wxButton( this, wxID_BACKWARD, _("< &Back") );
83 m_btnNext = new wxButton( this, wxID_FORWARD, _("&Next >") );
84 m_btnCancel = new wxButton( this, wxID_CANCEL, _("&Cancel") );
85
86 m_btnPrev->Enable( false );
87 m_btnNext->Enable( false );
88
89 backNextPair->Add( m_btnPrev, 0, wxBOTTOM|wxLEFT|wxTOP, 0 );
90 backNextPair->Add( 10, 0, 0, wxEXPAND, 0 );
91 backNextPair->Add( m_btnNext, 0, wxBOTTOM|wxRIGHT|wxTOP, 0 );
92
93 buttonRow->Add( m_btnHelp, 0, wxALL, 5 );
94
95 m_btnHelp->Hide();
96
97 buttonRow->Add( backNextPair, 0, wxALL, 5 );
98 buttonRow->Add( m_btnCancel, 0, wxALL, 5 );
99
100 mainColumn->Add( m_sizerBmpAndPage, 1, wxEXPAND );
101 mainColumn->Add( 0, 5, 0, wxEXPAND );
102 mainColumn->Add( new wxStaticLine( this ), 0, wxEXPAND | wxALL, 5 );
103 mainColumn->Add( 0, 5, 0, wxEXPAND );
104 mainColumn->Add( buttonRow, 0, wxALIGN_RIGHT );
105
106 windowSizer->Add( mainColumn, 1, wxALL|wxEXPAND, 5 );
107
108 this->SetSizer( windowSizer );
109 this->Layout();
110 windowSizer->Fit( this );
111
112 m_btnHelp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( Wizard::OnHelp ), NULL, this );
113 m_btnPrev->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( Wizard::OnBackOrNext ), NULL, this );
114 m_btnNext->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( Wizard::OnBackOrNext ), NULL, this );
115 m_btnCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( Wizard::OnCancel ), NULL, this );
116
117 this->Connect( wxID_ANY, wxFB_EVT_WIZARD_PAGE_CHANGED, WizardEventHandler( Wizard::OnWizEvent ) );
118 this->Connect( wxID_ANY, wxFB_EVT_WIZARD_PAGE_CHANGING, WizardEventHandler( Wizard::OnWizEvent ) );
119 this->Connect( wxID_ANY, wxFB_EVT_WIZARD_CANCEL, WizardEventHandler( Wizard::OnWizEvent ) );
120 this->Connect( wxID_ANY, wxFB_EVT_WIZARD_FINISHED, WizardEventHandler( Wizard::OnWizEvent ) );
121 this->Connect( wxID_ANY, wxFB_EVT_WIZARD_HELP, WizardEventHandler( Wizard::OnWizEvent ) );
122 }
123
~Wizard()124 Wizard::~Wizard()
125 {
126 m_btnHelp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( Wizard::OnHelp ), NULL, this );
127 m_btnPrev->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( Wizard::OnBackOrNext ), NULL, this );
128 m_btnNext->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( Wizard::OnBackOrNext ), NULL, this );
129 m_btnCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( Wizard::OnCancel ), NULL, this );
130
131 this->Disconnect( wxID_ANY, wxFB_EVT_WIZARD_PAGE_CHANGED, WizardEventHandler( Wizard::OnWizEvent ) );
132 this->Disconnect( wxID_ANY, wxFB_EVT_WIZARD_PAGE_CHANGING, WizardEventHandler( Wizard::OnWizEvent ) );
133 this->Disconnect( wxID_ANY, wxFB_EVT_WIZARD_CANCEL, WizardEventHandler( Wizard::OnWizEvent ) );
134 this->Disconnect( wxID_ANY, wxFB_EVT_WIZARD_FINISHED, WizardEventHandler( Wizard::OnWizEvent ) );
135 this->Disconnect( wxID_ANY, wxFB_EVT_WIZARD_HELP, WizardEventHandler( Wizard::OnWizEvent ) );
136
137 m_statbmp->SetBitmap( wxNullBitmap );
138 m_bitmap = wxNullBitmap;
139 m_page = NULL;
140 m_pages.Clear();
141 }
142
OnHelp(wxCommandEvent & event)143 void Wizard::OnHelp( wxCommandEvent& event )
144 {
145 // this function probably can never be called when we don't have an active
146 // page, but a small extra check won't hurt
147 if( m_page != NULL )
148 {
149 // Create and send the help event to the specific page handler
150 // event data contains the active page so that context-sensitive
151 // help is possible
152 WizardEvent eventHelp( wxFB_EVT_WIZARD_HELP, GetId(), true, m_page );
153 ( void )m_page->GetEventHandler()->ProcessEvent( eventHelp );
154 }
155 }
156
SetSelection(size_t pageIndex)157 void Wizard::SetSelection( size_t pageIndex )
158 {
159 size_t pageCount = m_pages.GetCount(); // Internal page array count
160 if ( pageIndex >= 0 && pageIndex < pageCount ) // Is it a valid index?
161 {
162 bool hasPrev = pageIndex > 0; // Has this page a previous one,
163 bool hasNext = pageIndex < pageCount - 1; // or another after it?
164
165 m_page = m_pages.Item( pageIndex ); // Yes, update current page and
166
167 m_btnPrev->Enable( hasPrev ); // enable 'back' button if a previous page exists,
168
169 wxString label = hasNext ? _("&Next >") : _("&Finish");
170 if ( label != m_btnNext->GetLabel() ) // set the correct label on next button
171 m_btnNext->SetLabel( label );
172
173 m_btnNext->SetDefault(); // and as default one, user needs it ready to go on.
174 }
175 }
176
OnBackOrNext(wxCommandEvent & event)177 void Wizard::OnBackOrNext( wxCommandEvent& event )
178 {
179 int pageIndex = m_pages.Index( m_page ); // Get index of previous selected page
180
181 bool forward = event.GetEventObject() == m_btnNext;
182
183 if ( forward )
184 {
185 pageIndex++; // Update current page index depending
186 }
187 else // ( event.GetEventObject() == m_btnPrev )
188 {
189 pageIndex--; // on which button was pressed.
190 }
191
192 SetSelection( pageIndex );
193
194 WizardEvent eventChanged( wxFB_EVT_WIZARD_PAGE_CHANGED, GetId(), forward, m_page );
195 m_page->GetEventHandler()->ProcessEvent( eventChanged );
196 }
197
OnCancel(wxCommandEvent & event)198 void Wizard::OnCancel( wxCommandEvent& event )
199 {
200 WizardEvent eventCancel( wxFB_EVT_WIZARD_CANCEL, GetId(), false, m_page );
201 GetEventHandler()->ProcessEvent( eventCancel );
202 }
203
OnWizEvent(WizardEvent & event)204 void Wizard::OnWizEvent( WizardEvent& event )
205 {
206 if ( event.IsAllowed() )
207 {
208 wxEventType eventType = event.GetEventType();
209
210 if ( eventType == wxFB_EVT_WIZARD_PAGE_CHANGED )
211 {
212 for ( unsigned int i = 0; i < m_pages.GetCount(); i++ )
213 m_pages.Item( i )->Hide();
214
215 event.GetPage()->Show();
216
217 Layout();
218 }
219 #if 0
220 else if ( eventType == wxFB_EVT_WIZARD_PAGE_CHANGING )
221 {
222 wxLogDebug( wxT("Wizard Page changing.") );
223 }
224 else if ( eventType == wxFB_EVT_WIZARD_CANCEL )
225 {
226 wxLogDebug( wxT("Wizard Cancel button was pressed.") );
227 }
228 else if ( eventType == wxFB_EVT_WIZARD_HELP )
229 {
230 wxLogDebug( wxT("Wizard Help button was pressed.") );
231 }
232 #if wxABI_VERSION >= 20811
233 else if ( eventType == wxFB_EVT_WIZARD_FINISHED )
234 {
235 wxLogDebug( wxT("Wizard Finish button was pressed.") );
236 }
237 #endif
238 else if ( eventType == wxFB_EVT_WIZARD_PAGE_SHOWN )
239 {
240 wxLogDebug( wxT("Wizard Page shown.") );
241 }
242 #endif
243 }
244 }
245
AddPage(WizardPageSimple * page)246 void Wizard::AddPage( WizardPageSimple* page )
247 {
248 m_page = page; // Update current page,
249 m_pages.Add( page ); // add it to internal page array,
250
251 size_t pageCount = m_pages.GetCount(); // Internal page array count
252
253 for ( unsigned int i = 0; i < pageCount; i++ )
254 m_pages.Item( i )->Hide();
255
256 page->Show();
257
258 m_sizerPage->Add( page, 1, wxEXPAND, 0 ); // insert it into the page sizer,
259
260 Layout(); // update layout,
261
262 if ( pageCount == 1 ) // First page: no previous, no next
263 {
264 m_btnNext->Enable( true ); // but enable the next page button
265 m_btnNext->SetLabel(_("&Finish") ); // because it acts as 'finish'
266 }
267 else if ( pageCount == 2 ) // Enable previous page button:
268 { // from now on everything is done in the
269 m_btnPrev->Enable( true ); // OnBackOrNext() event when user clicks on
270 } // 'back' or 'next' buttons.
271 }
272
SetBitmap(const wxBitmap & bitmap)273 void Wizard::SetBitmap( const wxBitmap& bitmap )
274 {
275 m_bitmap = bitmap;
276 if ( m_statbmp )
277 {
278 m_statbmp->SetBitmap( m_bitmap );
279 wxSize pageSize = m_sizerBmpAndPage->GetSize();
280 pageSize.IncTo( wxSize( 0, m_bitmap.GetHeight() ) );
281 m_sizerBmpAndPage->SetMinSize( pageSize );
282 }
283 }
284
285 // ----------------------------------------------------------------------------
286 // WizardEvent
287 // ----------------------------------------------------------------------------
288
WizardEvent(wxEventType type,int id,bool direction,WizardPageSimple * page)289 WizardEvent::WizardEvent( wxEventType type, int id, bool direction, WizardPageSimple *page )
290 : wxNotifyEvent( type, id )
291 {
292 // Modified 10-20-2001 Robert Cavanaugh
293 // add the active page to the event data
294 m_direction = direction;
295 m_page = page;
296 }
297