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