added more files (unchanged) from wxUniv branch
[wxWidgets.git] / samples / widgets / notebook.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Program: wxWindows Widgets Sample
3 // Name: notebook.cpp
4 // Purpose: Part of the widgets sample showing wxNotebook
5 // Author: Vadim Zeitlin
6 // Created: 06.04.01
7 // Id: $Id$
8 // Copyright: (c) 2001 Vadim Zeitlin
9 // License: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // for compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 // for all others, include the necessary headers
28 #ifndef WX_PRECOMP
29 #include "wx/app.h"
30 #include "wx/log.h"
31
32 #include "wx/button.h"
33 #include "wx/checkbox.h"
34 #include "wx/combobox.h"
35 #include "wx/radiobox.h"
36 #include "wx/statbox.h"
37 #include "wx/textctrl.h"
38
39 #include "wx/dynarray.h"
40 #endif
41
42 #include "wx/sizer.h"
43 #include "wx/notebook.h"
44
45 #include "widgets.h"
46
47 #include "icons/notebook.xpm"
48
49 // ----------------------------------------------------------------------------
50 // constants
51 // ----------------------------------------------------------------------------
52
53 // control ids
54 enum
55 {
56 NotebookPage_Reset = 100,
57 NotebookPage_SelectPage,
58 NotebookPage_AddPage,
59 NotebookPage_InsertPage,
60 NotebookPage_RemovePage,
61 NotebookPage_DeleteAll,
62 NotebookPage_InsertText,
63 NotebookPage_RemoveText,
64 NotebookPage_SelectText,
65 NotebookPage_NumPagesText,
66 NotebookPage_CurSelectText,
67 NotebookPage_Notebook
68 };
69
70 // notebook orientations
71 enum Orient
72 {
73 Orient_Top,
74 Orient_Bottom,
75 Orient_Left,
76 Orient_Right,
77 Orient_Max
78 };
79
80 // old versions of wxWindows don't define this style
81 #ifndef wxNB_TOP
82 #define wxNB_TOP (0)
83 #endif
84
85 // ----------------------------------------------------------------------------
86 // NotebookWidgetsPage
87 // ----------------------------------------------------------------------------
88
89 class NotebookWidgetsPage : public WidgetsPage
90 {
91 public:
92 NotebookWidgetsPage(wxNotebook *notebook, wxImageList *imaglist);
93 virtual ~NotebookWidgetsPage();
94
95 protected:
96 // event handlers
97 void OnPageChanging(wxNotebookEvent& event);
98 void OnPageChanged(wxNotebookEvent& event);
99
100 void OnButtonReset(wxCommandEvent& event);
101 void OnButtonDeleteAll(wxCommandEvent& event);
102 void OnButtonSelectPage(wxCommandEvent& event);
103 void OnButtonAddPage(wxCommandEvent& event);
104 void OnButtonInsertPage(wxCommandEvent& event);
105 void OnButtonRemovePage(wxCommandEvent& event);
106
107 void OnCheckOrRadioBox(wxCommandEvent& event);
108
109 void OnUpdateUINumPagesText(wxUpdateUIEvent& event);
110 void OnUpdateUICurSelectText(wxUpdateUIEvent& event);
111
112 void OnUpdateUISelectButton(wxUpdateUIEvent& event);
113 void OnUpdateUIInsertButton(wxUpdateUIEvent& event);
114 void OnUpdateUIRemoveButton(wxUpdateUIEvent& event);
115
116 void OnUpdateUIResetButton(wxUpdateUIEvent& event);
117
118 // reset the wxNotebook parameters
119 void Reset();
120
121 // (re)create the wxNotebook
122 void CreateNotebook();
123
124 // create or destroy the image list
125 void CreateImageList();
126
127 // create a new page
128 wxWindow *CreateNewPage();
129
130 // get the image index for the new page
131 int GetIconIndex() const;
132
133 // get the numeric value of text ctrl
134 int GetTextValue(wxTextCtrl *text) const;
135
136 // the controls
137 // ------------
138
139 // the check/radio boxes for styles
140 wxCheckBox *m_chkImages;
141 wxRadioBox *m_radioOrient;
142
143 // the text controls containing input for various commands
144 wxTextCtrl *m_textInsert,
145 *m_textRemove,
146 *m_textSelect;
147
148 // the notebook itself and the sizer it is in
149 wxNotebook *m_notebook;
150 wxSizer *m_sizerNotebook;
151
152 // thei mage list for our notebook
153 wxImageList *m_imageList;
154
155 private:
156 DECLARE_EVENT_TABLE();
157 DECLARE_WIDGETS_PAGE(NotebookWidgetsPage);
158 };
159
160 // ----------------------------------------------------------------------------
161 // event tables
162 // ----------------------------------------------------------------------------
163
164 BEGIN_EVENT_TABLE(NotebookWidgetsPage, WidgetsPage)
165 EVT_BUTTON(NotebookPage_Reset, NotebookWidgetsPage::OnButtonReset)
166 EVT_BUTTON(NotebookPage_SelectPage, NotebookWidgetsPage::OnButtonSelectPage)
167 EVT_BUTTON(NotebookPage_AddPage, NotebookWidgetsPage::OnButtonAddPage)
168 EVT_BUTTON(NotebookPage_InsertPage, NotebookWidgetsPage::OnButtonInsertPage)
169 EVT_BUTTON(NotebookPage_RemovePage, NotebookWidgetsPage::OnButtonRemovePage)
170 EVT_BUTTON(NotebookPage_DeleteAll, NotebookWidgetsPage::OnButtonDeleteAll)
171
172 EVT_UPDATE_UI(NotebookPage_NumPagesText, NotebookWidgetsPage::OnUpdateUINumPagesText)
173 EVT_UPDATE_UI(NotebookPage_CurSelectText, NotebookWidgetsPage::OnUpdateUICurSelectText)
174
175 EVT_UPDATE_UI(NotebookPage_SelectPage, NotebookWidgetsPage::OnUpdateUISelectButton)
176 EVT_UPDATE_UI(NotebookPage_InsertPage, NotebookWidgetsPage::OnUpdateUIInsertButton)
177 EVT_UPDATE_UI(NotebookPage_RemovePage, NotebookWidgetsPage::OnUpdateUIRemoveButton)
178
179 EVT_NOTEBOOK_PAGE_CHANGING(-1, NotebookWidgetsPage::OnPageChanging)
180 EVT_NOTEBOOK_PAGE_CHANGED(-1, NotebookWidgetsPage::OnPageChanged)
181
182 EVT_CHECKBOX(-1, NotebookWidgetsPage::OnCheckOrRadioBox)
183 EVT_RADIOBOX(-1, NotebookWidgetsPage::OnCheckOrRadioBox)
184 END_EVENT_TABLE()
185
186 // ============================================================================
187 // implementation
188 // ============================================================================
189
190 IMPLEMENT_WIDGETS_PAGE(NotebookWidgetsPage, _T("Notebook"));
191
192 NotebookWidgetsPage::NotebookWidgetsPage(wxNotebook *notebook,
193 wxImageList *imaglist)
194 : WidgetsPage(notebook)
195 {
196 imaglist->Add(wxBitmap(notebook_xpm));
197
198 // init everything
199 m_chkImages = NULL;
200 m_imageList = NULL;
201
202 m_notebook = (wxNotebook *)NULL;
203 m_sizerNotebook = (wxSizer *)NULL;
204
205 wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
206
207 // left pane
208 wxStaticBox *box = new wxStaticBox(this, -1, _T("&Set style"));
209
210 // must be in sync with Orient enum
211 wxString orientations[] =
212 {
213 _T("&top"),
214 _T("&bottom"),
215 _T("&left"),
216 _T("&right"),
217 };
218
219 wxASSERT_MSG( WXSIZEOF(orientations) == Orient_Max,
220 _T("forgot to update something") );
221
222 m_chkImages = new wxCheckBox(this, -1, _T("Show &images"));
223 m_radioOrient = new wxRadioBox(this, -1, _T("&Tab orientation"),
224 wxDefaultPosition, wxDefaultSize,
225 WXSIZEOF(orientations), orientations,
226 1, wxRA_SPECIFY_COLS);
227
228 wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
229
230 sizerLeft->Add(m_chkImages, 0, wxALL, 5);
231 sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
232 sizerLeft->Add(m_radioOrient, 0, wxALL, 5);
233
234 wxButton *btn = new wxButton(this, NotebookPage_Reset, _T("&Reset"));
235 sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
236
237 // middle pane
238 wxStaticBox *box2 = new wxStaticBox(this, -1, _T("&Contents"));
239 wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
240
241 wxTextCtrl *text;
242 wxSizer *sizerRow = CreateSizerWithTextAndLabel(_T("Number of pages: "),
243 NotebookPage_NumPagesText,
244 &text);
245 text->SetEditable(FALSE);
246 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
247
248 sizerRow = CreateSizerWithTextAndLabel(_T("Current selection: "),
249 NotebookPage_CurSelectText,
250 &text);
251 text->SetEditable(FALSE);
252 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
253
254 sizerRow = CreateSizerWithTextAndButton(NotebookPage_SelectPage,
255 _T("&Select page"),
256 NotebookPage_SelectText,
257 &m_textSelect);
258 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
259
260 btn = new wxButton(this, NotebookPage_AddPage, _T("&Add page"));
261 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
262
263 sizerRow = CreateSizerWithTextAndButton(NotebookPage_InsertPage,
264 _T("&Insert page at"),
265 NotebookPage_InsertText,
266 &m_textInsert);
267 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
268
269 sizerRow = CreateSizerWithTextAndButton(NotebookPage_RemovePage,
270 _T("&Remove page"),
271 NotebookPage_RemoveText,
272 &m_textRemove);
273 sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
274
275 btn = new wxButton(this, NotebookPage_DeleteAll, _T("&Delete All"));
276 sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
277
278 // right pane
279 wxSizer *sizerRight = new wxBoxSizer(wxHORIZONTAL);
280 m_notebook = new wxNotebook(this, NotebookPage_Notebook);
281 sizerRight->Add(m_notebook, 1, wxGROW | wxALL, 5);
282 sizerRight->SetMinSize(250, 0);
283 m_sizerNotebook = sizerRight; // save it to modify it later
284
285 // the 3 panes panes compose the window
286 sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
287 sizerTop->Add(sizerMiddle, 0, wxGROW | wxALL, 10);
288 sizerTop->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
289
290 // final initializations
291 Reset();
292 CreateImageList();
293
294 SetAutoLayout(TRUE);
295 SetSizer(sizerTop);
296
297 sizerTop->Fit(this);
298 }
299
300 NotebookWidgetsPage::~NotebookWidgetsPage()
301 {
302 delete m_imageList;
303 }
304
305 // ----------------------------------------------------------------------------
306 // operations
307 // ----------------------------------------------------------------------------
308
309 void NotebookWidgetsPage::Reset()
310 {
311 m_chkImages->SetValue(TRUE);
312 m_radioOrient->SetSelection(Orient_Top);
313 }
314
315 void NotebookWidgetsPage::CreateImageList()
316 {
317 if ( m_chkImages->GetValue() )
318 {
319 if ( !m_imageList )
320 {
321 // create a dummy image list with a few icons
322 m_imageList = new wxImageList(32, 32);
323 m_imageList->Add(wxTheApp->GetStdIcon(wxICON_INFORMATION));
324 m_imageList->Add(wxTheApp->GetStdIcon(wxICON_QUESTION));
325 m_imageList->Add(wxTheApp->GetStdIcon(wxICON_WARNING));
326 m_imageList->Add(wxTheApp->GetStdIcon(wxICON_ERROR));
327 }
328
329 m_notebook->SetImageList(m_imageList);
330 }
331 else // no images
332 {
333 if ( m_imageList )
334 {
335 delete m_imageList;
336 m_imageList = NULL;
337 }
338 }
339
340 // because of the bug in wxMSW we can't use SetImageList(NULL) - although
341 // it would be logical if this removed the image list from notebook, under
342 // MSW it crashes instead
343 }
344
345 void NotebookWidgetsPage::CreateNotebook()
346 {
347 int flags;
348 switch ( m_radioOrient->GetSelection() )
349 {
350 default:
351 wxFAIL_MSG( _T("unknown notebok orientation") );
352 // fall through
353
354 case Orient_Top:
355 flags = wxNB_TOP;
356 break;
357
358 case Orient_Bottom:
359 flags = wxNB_BOTTOM;
360 break;
361
362 case Orient_Left:
363 flags = wxNB_LEFT;
364 break;
365
366 case Orient_Right:
367 flags = wxNB_RIGHT;
368 break;
369 }
370
371 wxNotebook *notebook = m_notebook;
372
373 m_notebook = new wxNotebook(this, NotebookPage_Notebook,
374 wxDefaultPosition, wxDefaultSize,
375 flags);
376
377 CreateImageList();
378
379 if ( notebook )
380 {
381 int sel = notebook->GetSelection();
382
383 int count = notebook->GetPageCount();
384 for ( int n = 0; n < count; n++ )
385 {
386 wxNotebookPage *page = notebook->GetPage(0);
387 page->Reparent(m_notebook);
388
389 m_notebook->AddPage(page, notebook->GetPageText(0), FALSE,
390 notebook->GetPageImage(0));
391
392 notebook->RemovePage(0);
393 }
394
395 m_sizerNotebook->Remove(notebook);
396 delete notebook;
397
398 // restore selection
399 if ( sel != -1 )
400 {
401 m_notebook->SetSelection(sel);
402 }
403 }
404
405 m_sizerNotebook->Add(m_notebook, 1, wxGROW | wxALL, 5);
406 m_sizerNotebook->Layout();
407 }
408
409 // ----------------------------------------------------------------------------
410 // helpers
411 // ----------------------------------------------------------------------------
412
413 int NotebookWidgetsPage::GetTextValue(wxTextCtrl *text) const
414 {
415 long pos;
416 if ( !text->GetValue().ToLong(&pos) )
417 pos = -1;
418
419 return (int)pos;
420 }
421
422 int NotebookWidgetsPage::GetIconIndex() const
423 {
424 if ( m_imageList )
425 {
426 int nImages = m_imageList->GetImageCount();
427 if ( nImages > 0 )
428 {
429 return m_notebook->GetPageCount() % nImages;
430 }
431 }
432
433 return -1;
434 }
435
436 wxWindow *NotebookWidgetsPage::CreateNewPage()
437 {
438 return new wxTextCtrl(m_notebook, -1, _T("I'm a notebook page"));
439 }
440
441 // ----------------------------------------------------------------------------
442 // event handlers
443 // ----------------------------------------------------------------------------
444
445 void NotebookWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
446 {
447 Reset();
448
449 CreateNotebook();
450 }
451
452 void NotebookWidgetsPage::OnButtonDeleteAll(wxCommandEvent& WXUNUSED(event))
453 {
454 m_notebook->DeleteAllPages();
455 }
456
457 void NotebookWidgetsPage::OnButtonSelectPage(wxCommandEvent& event)
458 {
459 int pos = GetTextValue(m_textSelect);
460 wxCHECK_RET( pos >= 0, _T("button should be disabled") );
461
462 m_notebook->SetSelection(pos);
463 }
464
465 void NotebookWidgetsPage::OnButtonAddPage(wxCommandEvent& WXUNUSED(event))
466 {
467 m_notebook->AddPage(CreateNewPage(), _T("Added page"), FALSE,
468 GetIconIndex());
469 }
470
471 void NotebookWidgetsPage::OnButtonInsertPage(wxCommandEvent& WXUNUSED(event))
472 {
473 int pos = GetTextValue(m_textInsert);
474 wxCHECK_RET( pos >= 0, _T("button should be disabled") );
475
476 m_notebook->InsertPage(pos, CreateNewPage(), _T("Inserted page"), FALSE,
477 GetIconIndex());
478 }
479
480 void NotebookWidgetsPage::OnButtonRemovePage(wxCommandEvent& WXUNUSED(event))
481 {
482 int pos = GetTextValue(m_textRemove);
483 wxCHECK_RET( pos >= 0, _T("button should be disabled") );
484
485 m_notebook->DeletePage(pos);
486 }
487
488 void NotebookWidgetsPage::OnUpdateUISelectButton(wxUpdateUIEvent& event)
489 {
490 event.Enable( GetTextValue(m_textSelect) >= 0 );
491 }
492
493 void NotebookWidgetsPage::OnUpdateUIInsertButton(wxUpdateUIEvent& event)
494 {
495 event.Enable( GetTextValue(m_textInsert) >= 0 );
496 }
497
498 void NotebookWidgetsPage::OnUpdateUIRemoveButton(wxUpdateUIEvent& event)
499 {
500 event.Enable( GetTextValue(m_textRemove) >= 0 );
501 }
502
503 void NotebookWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
504 {
505 event.Enable( !m_chkImages->GetValue() ||
506 m_radioOrient->GetSelection() != wxNB_TOP );
507 }
508
509 void NotebookWidgetsPage::OnUpdateUINumPagesText(wxUpdateUIEvent& event)
510 {
511 event.SetText( wxString::Format(_T("%d"), m_notebook->GetPageCount()) );
512 }
513
514 void NotebookWidgetsPage::OnUpdateUICurSelectText(wxUpdateUIEvent& event)
515 {
516 event.SetText( wxString::Format(_T("%d"), m_notebook->GetSelection()) );
517 }
518
519 void NotebookWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& event)
520 {
521 CreateNotebook();
522 }
523
524 void NotebookWidgetsPage::OnPageChanging(wxNotebookEvent& event)
525 {
526 wxLogMessage(_T("Notebook page changing from %d to %d (currently %d)."),
527 event.GetOldSelection(),
528 event.GetSelection(),
529 m_notebook->GetSelection());
530
531 event.Skip();
532 }
533
534 void NotebookWidgetsPage::OnPageChanged(wxNotebookEvent& event)
535 {
536 wxLogMessage(_T("Notebook page changed from %d to %d (currently %d)."),
537 event.GetOldSelection(),
538 event.GetSelection(),
539 m_notebook->GetSelection());
540
541 event.Skip();
542 }
543