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