1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        samples/notebook/notebook.cpp
3 // Purpose:     a sample demonstrating notebook usage
4 // Author:      Julian Smart
5 // Modified by: Dimitri Schoolwerth
6 // Created:     26/10/98
7 // Copyright:   (c) 1998-2002 wxWidgets team
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13 
14 
15 #ifndef WX_PRECOMP
16     #include "wx/wx.h"
17 #endif
18 
19 #include "wx/imaglist.h"
20 #include "wx/artprov.h"
21 #include "wx/cshelp.h"
22 #include "wx/utils.h"
23 #include "notebook.h"
24 
25 #ifndef wxHAS_IMAGES_IN_RESOURCES
26     #include "../sample.xpm"
27 #endif
28 
29 //-----------------------------------------------------------------------------
30 // MyApp
31 //-----------------------------------------------------------------------------
32 
33 wxIMPLEMENT_APP(MyApp);
34 
OnInit()35 bool MyApp::OnInit()
36 {
37     if ( !wxApp::OnInit() )
38         return false;
39 
40 #if wxUSE_HELP
41     wxHelpProvider::Set( new wxSimpleHelpProvider );
42 #endif
43 
44     // Create the main window
45     MyFrame *frame = new MyFrame();
46 
47     // Problem with generic wxNotebook implementation whereby it doesn't size
48     // properly unless you set the size again
49 #if defined(__WXMOTIF__)
50     int width, height;
51     frame->GetSize(& width, & height);
52     frame->SetSize(wxDefaultCoord, wxDefaultCoord, width, height);
53 #endif
54 
55     frame->Show();
56 
57     return true;
58 }
59 
60 
61 //-----------------------------------------------------------------------------
62 // Creation functions
63 //-----------------------------------------------------------------------------
64 
CreateUserCreatedPage(wxBookCtrlBase * parent)65 wxPanel *CreateUserCreatedPage(wxBookCtrlBase *parent)
66 {
67     wxPanel *panel = new wxPanel(parent);
68 
69 #if wxUSE_HELP
70     panel->SetHelpText("Panel with a Button");
71 #endif
72 
73     (void) new wxButton( panel, wxID_ANY, "Button",
74                          wxPoint(10, 10), wxDefaultSize );
75 
76     return panel;
77 }
78 
CreateRadioButtonsPage(wxBookCtrlBase * parent)79 wxPanel *CreateRadioButtonsPage(wxBookCtrlBase *parent)
80 {
81     wxPanel *panel = new wxPanel(parent);
82 
83 #if wxUSE_HELP
84     panel->SetHelpText("Panel with some Radio Buttons");
85 #endif
86 
87     wxString animals[] =
88       { "Fox", "Hare", "Rabbit",
89         "Sabre-toothed tiger", "T Rex" };
90 
91     wxRadioBox *radiobox1 = new wxRadioBox(panel, wxID_ANY, "Choose one",
92         wxDefaultPosition, wxDefaultSize, 5, animals, 2, wxRA_SPECIFY_ROWS);
93 
94     wxString computers[] =
95       { "Amiga", "Commodore 64", "PET",
96         "Another" };
97 
98     wxRadioBox *radiobox2 = new wxRadioBox(panel, wxID_ANY,
99         "Choose your favourite", wxDefaultPosition, wxDefaultSize,
100         4, computers, 0, wxRA_SPECIFY_COLS);
101 
102     wxBoxSizer *sizerPanel = new wxBoxSizer(wxVERTICAL);
103     sizerPanel->Add(radiobox1, 2, wxEXPAND);
104     sizerPanel->Add(radiobox2, 1, wxEXPAND);
105     panel->SetSizer(sizerPanel);
106 
107     return panel;
108 }
109 
CreateVetoPage(wxBookCtrlBase * parent)110 wxPanel *CreateVetoPage(wxBookCtrlBase *parent)
111 {
112     wxPanel *panel = new wxPanel(parent);
113 
114 #if wxUSE_HELP
115     panel->SetHelpText("An empty panel");
116 #endif
117 
118     (void) new wxStaticText( panel, wxID_ANY,
119                              "This page intentionally left blank",
120                              wxPoint(10, 10) );
121 
122     return panel;
123 }
124 
CreateBigButtonPage(wxBookCtrlBase * parent)125 wxPanel *CreateBigButtonPage(wxBookCtrlBase *parent)
126 {
127     wxPanel *panel = new wxPanel(parent);
128 
129 #if wxUSE_HELP
130     panel->SetHelpText("Panel with a maximized button");
131 #endif
132 
133     wxButton *buttonBig = new wxButton(panel, wxID_ANY, "Maximized button");
134 
135     wxBoxSizer *sizerPanel = new wxBoxSizer(wxVERTICAL);
136     sizerPanel->Add(buttonBig, 1, wxEXPAND);
137     panel->SetSizer(sizerPanel);
138 
139     return panel;
140 }
141 
CreateInsertPage(wxBookCtrlBase * parent)142 wxPanel *CreateInsertPage(wxBookCtrlBase *parent)
143 {
144     wxPanel *panel = new wxPanel(parent);
145 
146 #if wxUSE_HELP
147     panel->SetHelpText("Maroon panel");
148 #endif
149 
150     panel->SetBackgroundColour( wxColour( "MAROON" ) );
151     (void) new wxStaticText( panel, wxID_ANY,
152                              "This page has been inserted, not added.",
153                              wxPoint(10, 10) );
154 
155     return panel;
156 }
157 
GetIconIndex(wxBookCtrlBase * bookCtrl)158 int GetIconIndex(wxBookCtrlBase* bookCtrl)
159 {
160     if (bookCtrl && bookCtrl->GetImageList())
161     {
162        int nImages = bookCtrl->GetImageList()->GetImageCount();
163        if (nImages > 0)
164        {
165            return bookCtrl->GetPageCount() % nImages;
166        }
167     }
168 
169     return -1;
170 }
171 
CreateInitialPages(wxBookCtrlBase * parent)172 void CreateInitialPages(wxBookCtrlBase *parent)
173 {
174     // Create and add some panels to the notebook
175 
176     wxPanel *panel = CreateRadioButtonsPage(parent);
177     parent->AddPage( panel, RADIOBUTTONS_PAGE_NAME, false, GetIconIndex(parent) );
178 
179     panel = CreateVetoPage(parent);
180     parent->AddPage( panel, VETO_PAGE_NAME, false, GetIconIndex(parent) );
181 
182     panel = CreateBigButtonPage(parent);
183     parent->AddPage( panel, MAXIMIZED_BUTTON_PAGE_NAME, false, GetIconIndex(parent) );
184 
185     panel = CreateInsertPage(parent);
186     parent->InsertPage( 0, panel, I_WAS_INSERTED_PAGE_NAME, false, GetIconIndex(parent) );
187 
188     parent->SetSelection(1);
189 }
190 
CreatePage(wxBookCtrlBase * parent,const wxString & pageName)191 wxPanel *CreatePage(wxBookCtrlBase *parent, const wxString&pageName)
192 {
193     if ( pageName.Contains(INSERTED_PAGE_NAME) ||
194             pageName.Contains(ADDED_PAGE_NAME) ||
195                 pageName.Contains(ADDED_SUB_PAGE_NAME) ||
196                     pageName.Contains(ADDED_PAGE_NAME_BEFORE) )
197         return CreateUserCreatedPage(parent);
198 
199     if ( pageName == I_WAS_INSERTED_PAGE_NAME )
200         return CreateInsertPage(parent);
201 
202     if ( pageName == VETO_PAGE_NAME )
203         return CreateVetoPage(parent);
204 
205     if ( pageName == RADIOBUTTONS_PAGE_NAME )
206         return CreateRadioButtonsPage(parent);
207 
208     if ( pageName == MAXIMIZED_BUTTON_PAGE_NAME )
209         return CreateBigButtonPage(parent);
210 
211     wxFAIL_MSG( "unknown page name" );
212 
213     return NULL;
214 }
215 
216 
217 //-----------------------------------------------------------------------------
218 // MyFrame
219 //-----------------------------------------------------------------------------
220 
wxBEGIN_EVENT_TABLE(MyFrame,wxFrame)221 wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
222     // File menu
223     EVT_MENU_RANGE(ID_BOOK_NOTEBOOK, ID_BOOK_MAX, MyFrame::OnType)
224     EVT_MENU_RANGE(ID_ORIENT_DEFAULT, ID_ORIENT_MAX, MyFrame::OnOrient)
225     EVT_MENU(ID_SHOW_IMAGES, MyFrame::OnShowImages)
226     EVT_MENU_RANGE(ID_FIXEDWIDTH, ID_HORZ_LAYOUT, MyFrame::OnStyle)
227     EVT_MENU(wxID_EXIT, MyFrame::OnExit)
228 
229     // Operations menu
230     EVT_MENU(ID_ADD_PAGE, MyFrame::OnAddPage)
231     EVT_MENU(ID_ADD_PAGE_NO_SELECT, MyFrame::OnAddPageNoSelect)
232     EVT_MENU(ID_INSERT_PAGE, MyFrame::OnInsertPage)
233     EVT_MENU(ID_DELETE_CUR_PAGE, MyFrame::OnDeleteCurPage)
234     EVT_MENU(ID_DELETE_LAST_PAGE, MyFrame::OnDeleteLastPage)
235     EVT_MENU(ID_NEXT_PAGE, MyFrame::OnNextPage)
236     EVT_MENU(ID_CHANGE_SELECTION, MyFrame::OnChangeSelection)
237     EVT_MENU(ID_SET_SELECTION, MyFrame::OnSetSelection)
238     EVT_MENU(ID_GET_PAGE_SIZE, MyFrame::OnGetPageSize)
239     EVT_MENU(ID_SET_PAGE_SIZE, MyFrame::OnSetPageSize)
240 
241 #if wxUSE_HELP
242     EVT_MENU(ID_CONTEXT_HELP, MyFrame::OnContextHelp)
243 #endif // wxUSE_HELP
244     EVT_MENU(ID_HITTEST, MyFrame::OnHitTest)
245 
246     // Book controls
247 #if wxUSE_NOTEBOOK
248     EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, MyFrame::OnNotebook)
249     EVT_NOTEBOOK_PAGE_CHANGING(wxID_ANY, MyFrame::OnNotebook)
250 #endif
251 #if wxUSE_LISTBOOK
252     EVT_LISTBOOK_PAGE_CHANGED(wxID_ANY, MyFrame::OnListbook)
253     EVT_LISTBOOK_PAGE_CHANGING(wxID_ANY, MyFrame::OnListbook)
254 #endif
255 #if wxUSE_CHOICEBOOK
256     EVT_CHOICEBOOK_PAGE_CHANGED(wxID_ANY, MyFrame::OnChoicebook)
257     EVT_CHOICEBOOK_PAGE_CHANGING(wxID_ANY, MyFrame::OnChoicebook)
258 #endif
259 #if wxUSE_TREEBOOK
260     EVT_TREEBOOK_PAGE_CHANGED(wxID_ANY, MyFrame::OnTreebook)
261     EVT_TREEBOOK_PAGE_CHANGING(wxID_ANY, MyFrame::OnTreebook)
262 
263     EVT_MENU(ID_ADD_SUB_PAGE, MyFrame::OnAddSubPage)
264     EVT_MENU(ID_ADD_PAGE_BEFORE, MyFrame::OnAddPageBefore)
265     EVT_UPDATE_UI_RANGE(ID_ADD_PAGE_BEFORE, ID_ADD_SUB_PAGE,
266                             MyFrame::OnUpdateTreeMenu)
267 #endif
268 #if wxUSE_TOOLBOOK
269     EVT_TOOLBOOK_PAGE_CHANGED(wxID_ANY, MyFrame::OnToolbook)
270     EVT_TOOLBOOK_PAGE_CHANGING(wxID_ANY, MyFrame::OnToolbook)
271 #endif
272 #if wxUSE_AUI
273     EVT_AUINOTEBOOK_PAGE_CHANGED(wxID_ANY, MyFrame::OnAuiNotebook)
274     EVT_AUINOTEBOOK_PAGE_CHANGING(wxID_ANY, MyFrame::OnAuiNotebook)
275 #endif
276 
277     // Update title in idle time
278     EVT_IDLE(MyFrame::OnIdle)
279 wxEND_EVENT_TABLE()
280 
281 MyFrame::MyFrame()
282     : wxFrame(NULL, wxID_ANY, wxString("wxWidgets book controls sample"))
283 {
284 #if wxUSE_HELP
285     SetExtraStyle(wxFRAME_EX_CONTEXTHELP);
286 #endif // wxUSE_HELP
287 
288 #if wxUSE_NOTEBOOK
289     m_type = Type_Notebook;
290 #elif wxUSE_CHOICEBOOK
291     m_type = Type_Choicebook;
292 #elif wxUSE_LISTBOOK
293     m_type = Type_Listbook;
294 #elif wxUSE_TREEBOOK
295     m_type = Type_Treebook;
296 #elif wxUSE_TOOLBOOK
297     m_type = Type_Toolbook;
298 #elif wxUSE_AUI
299     m_type = Type_Aui;
300 #else
301     m_type = Type_Simplebook;
302 #endif
303 
304     m_orient = ID_ORIENT_DEFAULT;
305     m_chkShowImages = true;
306     m_fixedWidth = false;
307     m_multi = false;
308     m_noPageTheme = false;
309     m_buttonBar = false;
310     m_horzLayout = false;
311 
312     SetIcon(wxICON(sample));
313 
314     // menu of the sample
315     wxMenu *menuType = new wxMenu;
316 #if wxUSE_NOTEBOOK
317     menuType->AppendRadioItem(ID_BOOK_NOTEBOOK,   "&Notebook\tCtrl-1");
318 #endif
319 #if wxUSE_LISTBOOK
320     menuType->AppendRadioItem(ID_BOOK_LISTBOOK,   "&Listbook\tCtrl-2");
321 #endif
322 #if wxUSE_CHOICEBOOK
323     menuType->AppendRadioItem(ID_BOOK_CHOICEBOOK, "&Choicebook\tCtrl-3");
324 #endif
325 #if wxUSE_TREEBOOK
326     menuType->AppendRadioItem(ID_BOOK_TREEBOOK,   "&Treebook\tCtrl-4");
327 #endif
328 #if wxUSE_TOOLBOOK
329     menuType->AppendRadioItem(ID_BOOK_TOOLBOOK,   "T&oolbook\tCtrl-5");
330 #endif
331 #if wxUSE_AUI
332     menuType->AppendRadioItem(ID_BOOK_AUINOTEBOOK,   "&AuiNotebook\tCtrl-6");
333 #endif
334     menuType->AppendRadioItem(ID_BOOK_SIMPLEBOOK, "&Simple book\tCtrl-7");
335 
336     menuType->Check(ID_BOOK_NOTEBOOK + m_type, true);
337 
338     wxMenu *menuOrient = new wxMenu;
339     menuOrient->AppendRadioItem(ID_ORIENT_DEFAULT, "&Default\tAlt-0");
340     menuOrient->AppendRadioItem(ID_ORIENT_TOP,     "&Top\tAlt-1");
341     menuOrient->AppendRadioItem(ID_ORIENT_BOTTOM,  "&Bottom\tAlt-2");
342     menuOrient->AppendRadioItem(ID_ORIENT_LEFT,    "&Left\tAlt-3");
343     menuOrient->AppendRadioItem(ID_ORIENT_RIGHT,   "&Right\tAlt-4");
344 
345     wxMenu *menuStyle = new wxMenu;
346 #if wxUSE_NOTEBOOK
347     menuStyle->AppendCheckItem(ID_FIXEDWIDTH, "&Fixed Width (wxNotebook)");
348     menuStyle->AppendCheckItem(ID_MULTI, "&Multiple lines (wxNotebook)");
349     menuStyle->AppendCheckItem(ID_NOPAGETHEME, "&No Page Theme (wxNotebook)");
350 #endif
351 #if wxUSE_TOOLBOOK
352     menuStyle->AppendCheckItem(ID_BUTTONBAR, "&Button Bar (wxToolbook)");
353     menuStyle->AppendCheckItem(ID_HORZ_LAYOUT, "&Horizontal layout (wxToolbook)");
354 #endif
355 
356     wxMenu *menuPageOperations = new wxMenu;
357     menuPageOperations->Append(ID_ADD_PAGE, "&Add page\tAlt-A");
358     menuPageOperations->Append(ID_ADD_PAGE_NO_SELECT, "&Add page (don't select)\tAlt-B");
359     menuPageOperations->Append(ID_INSERT_PAGE, "&Insert page\tAlt-I");
360     menuPageOperations->Append(ID_DELETE_CUR_PAGE, "&Delete current page\tAlt-D");
361     menuPageOperations->Append(ID_DELETE_LAST_PAGE, "D&elete last page\tAlt-L");
362     menuPageOperations->Append(ID_NEXT_PAGE, "&Next page\tAlt-N");
363 #if wxUSE_TREEBOOK
364     menuPageOperations->AppendSeparator();
365     menuPageOperations->Append(ID_ADD_PAGE_BEFORE, "Insert page &before\tAlt-B");
366     menuPageOperations->Append(ID_ADD_SUB_PAGE, "Add s&ub page\tAlt-U");
367 #endif
368     menuPageOperations->AppendSeparator();
369     menuPageOperations->Append(ID_CHANGE_SELECTION, "&Change selection to 0\tCtrl-0");
370     menuPageOperations->Append(ID_SET_SELECTION, "&Set selection to 0\tShift-Ctrl-0");
371     menuPageOperations->AppendSeparator();
372     menuPageOperations->Append(ID_GET_PAGE_SIZE, "Sho&w page size");
373     menuPageOperations->Append(ID_SET_PAGE_SIZE, "Set &page size");
374 
375     wxMenu *menuOperations = new wxMenu;
376 #if wxUSE_HELP
377     menuOperations->Append(ID_CONTEXT_HELP, "&Context help\tCtrl-F1");
378 #endif // wxUSE_HELP
379     menuOperations->Append(ID_HITTEST, "&Hit test\tCtrl-H");
380 
381     wxMenu *menuFile = new wxMenu;
382     menuFile->Append(wxID_ANY, "&Type", menuType, "Type of control");
383     menuFile->Append(wxID_ANY, "&Orientation", menuOrient, "Orientation of control");
384     menuFile->AppendCheckItem(ID_SHOW_IMAGES, "&Show images\tAlt-S");
385     menuFile->Append(wxID_ANY, "&Style", menuStyle, "Style of control");
386     menuFile->AppendSeparator();
387     menuFile->Append(wxID_EXIT, "E&xit", "Quits the application");
388     menuFile->Check(ID_SHOW_IMAGES, m_chkShowImages);
389 
390     wxMenuBar *menuBar = new wxMenuBar;
391     menuBar->Append(menuFile, "&File");
392     menuBar->Append(menuPageOperations, "&Pages");
393     menuBar->Append(menuOperations, "&Operations");
394     SetMenuBar(menuBar);
395 
396     // books creation
397     m_panel    = NULL;
398     m_bookCtrl = NULL;
399 
400     // create a dummy image list with a few icons
401     const wxSize imageSize(32, 32);
402 
403     m_imageList = new wxImageList(imageSize.GetWidth(), imageSize.GetHeight());
404     m_imageList->
405         Add(wxArtProvider::GetIcon(wxART_INFORMATION, wxART_OTHER, imageSize));
406     m_imageList->
407         Add(wxArtProvider::GetIcon(wxART_QUESTION, wxART_OTHER, imageSize));
408     m_imageList->
409         Add(wxArtProvider::GetIcon(wxART_WARNING, wxART_OTHER, imageSize));
410     m_imageList->
411         Add(wxArtProvider::GetIcon(wxART_ERROR, wxART_OTHER, imageSize));
412 
413     m_panel = new wxPanel(this);
414 
415 #if USE_LOG
416     m_text = new wxTextCtrl(m_panel, wxID_ANY, wxEmptyString,
417                             wxDefaultPosition, wxDefaultSize,
418                             wxTE_MULTILINE | wxTE_READONLY);
419 
420     m_logTargetOld = wxLog::SetActiveTarget( new wxLogTextCtrl(m_text) );
421 #endif // USE_LOG
422 
423     // Set sizers
424     m_sizerFrame = new wxBoxSizer(wxVERTICAL);
425 
426 #if USE_LOG
427     m_sizerFrame->Add(m_text, 1, wxEXPAND);
428 #endif // USE_LOG
429 
430     RecreateBook();
431 
432     m_panel->SetSizer(m_sizerFrame);
433     m_panel->Layout();
434 
435     wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
436     sizer->Add(m_panel, wxSizerFlags(1).Expand());
437     SetSizerAndFit(sizer);
438 }
439 
~MyFrame()440 MyFrame::~MyFrame()
441 {
442 #if USE_LOG
443     delete wxLog::SetActiveTarget(m_logTargetOld);
444 #endif // USE_LOG
445 
446     delete m_imageList;
447 }
448 
449 // DISPATCH_ON_TYPE() macro is an ugly way to write the "same" code for
450 // different wxBookCtrlBase-derived classes without duplicating code and
451 // without using templates, it expands into "before <xxx> after" where "xxx"
452 // part is control class-specific
453 #if wxUSE_NOTEBOOK
454     #define CASE_NOTEBOOK(x) case Type_Notebook: x; break;
455 #else
456     #define CASE_NOTEBOOK(x)
457 #endif
458 
459 #if wxUSE_LISTBOOK
460     #define CASE_LISTBOOK(x) case Type_Listbook: x; break;
461 #else
462     #define CASE_LISTBOOK(x)
463 #endif
464 
465 #if wxUSE_CHOICEBOOK
466     #define CASE_CHOICEBOOK(x) case Type_Choicebook: x; break;
467 #else
468     #define CASE_CHOICEBOOK(x)
469 #endif
470 
471 #if wxUSE_TREEBOOK
472     #define CASE_TREEBOOK(x) case Type_Treebook: x; break;
473 #else
474     #define CASE_TREEBOOK(x)
475 #endif
476 
477 #if wxUSE_TOOLBOOK
478     #define CASE_TOOLBOOK(x) case Type_Toolbook: x; break;
479 #else
480     #define CASE_TOOLBOOK(x)
481 #endif
482 
483 #if wxUSE_AUI
484     #define CASE_AUINOTEBOOK(x) case Type_AuiNotebook: x; break;
485 #else
486     #define CASE_AUINOTEBOOK(x)
487 #endif
488 
489 #define CASE_SIMPLEBOOK(x) case Type_Simplebook: x; break;
490 
491 #define DISPATCH_ON_TYPE(before, nb, lb, cb, tb, toolb, aui, sb, after)       \
492     switch ( m_type )                                                         \
493     {                                                                         \
494         CASE_NOTEBOOK(before nb after)                                        \
495         CASE_LISTBOOK(before lb after)                                        \
496         CASE_CHOICEBOOK(before cb after)                                      \
497         CASE_TREEBOOK(before tb after)                                        \
498         CASE_TOOLBOOK(before toolb after)                                     \
499         CASE_AUINOTEBOOK(before aui after)                                    \
500         CASE_SIMPLEBOOK(before sb after)                                      \
501                                                                               \
502         default:                                                              \
503             wxFAIL_MSG( "unknown book control type" );                   \
504     }
505 
RecreateBook()506 void MyFrame::RecreateBook()
507 {
508     int flags;
509     switch ( m_orient )
510     {
511         case ID_ORIENT_TOP:
512             flags = wxBK_TOP;
513             break;
514 
515         case ID_ORIENT_BOTTOM:
516             flags = wxBK_BOTTOM;
517             break;
518 
519         case ID_ORIENT_LEFT:
520             flags = wxBK_LEFT;
521             break;
522 
523         case ID_ORIENT_RIGHT:
524             flags = wxBK_RIGHT;
525             break;
526 
527         default:
528             flags = wxBK_DEFAULT;
529     }
530 
531 #if wxUSE_NOTEBOOK
532     if ( m_fixedWidth && m_type == Type_Notebook )
533         flags |= wxNB_FIXEDWIDTH;
534     if ( m_multi && m_type == Type_Notebook )
535         flags |= wxNB_MULTILINE;
536     if ( m_noPageTheme && m_type == Type_Notebook )
537         flags |= wxNB_NOPAGETHEME;
538 #endif
539 #if wxUSE_TOOLBOOK
540     if ( m_buttonBar && m_type == Type_Toolbook )
541         flags |= wxTBK_BUTTONBAR;
542     if ( m_horzLayout && m_type == Type_Toolbook )
543         flags |= wxTBK_HORZ_LAYOUT;
544 #endif
545 
546     wxBookCtrlBase *oldBook = m_bookCtrl;
547 
548     m_bookCtrl = NULL;
549 
550     DISPATCH_ON_TYPE(m_bookCtrl = new,
551                          wxNotebook,
552                          wxListbook,
553                          wxChoicebook,
554                          wxTreebook,
555                          wxToolbook,
556                          wxAuiNotebook,
557                          wxSimplebook,
558                      (m_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, flags));
559 
560     if ( !m_bookCtrl )
561         return;
562 
563     m_bookCtrl->Hide();
564 
565     // wxToolbook doesn't work without icons so always use them for it.
566     if ( m_chkShowImages || m_type == Type_Toolbook )
567     {
568         m_bookCtrl->SetImageList(m_imageList);
569     }
570 
571     if ( oldBook )
572     {
573 #if wxUSE_TREEBOOK
574         // we only need the old treebook if we're recreating another treebook
575         wxTreebook *tbkOld = m_type == Type_Treebook
576                                 ? wxDynamicCast(oldBook, wxTreebook)
577                                 : NULL;
578 #endif // wxUSE_TREEBOOK
579 
580         const int count = oldBook->GetPageCount();
581         for ( int n = 0; n < count; n++ )
582         {
583             const int image = GetIconIndex(m_bookCtrl);
584             const wxString str = oldBook->GetPageText(n);
585 
586             wxWindow *page = CreatePage(m_bookCtrl, str);
587 
588             // treebook complication: need to account for possible parent page
589 #if wxUSE_TREEBOOK
590             if ( tbkOld )
591             {
592                 const int parent = tbkOld->GetPageParent(n);
593                 if ( parent != wxNOT_FOUND )
594                 {
595                     wxStaticCast(m_bookCtrl, wxTreebook)->
596                         InsertSubPage(parent, page, str, false, image);
597 
598                     // skip adding it again below
599                     continue;
600                 }
601             }
602 #endif // wxUSE_TREEBOOK
603 
604             m_bookCtrl->AddPage(page, str, false, image);
605         }
606 
607         const int sel = oldBook->GetSelection();
608         if ( sel != wxNOT_FOUND )
609             m_bookCtrl->SetSelection(sel);
610 
611 
612         m_sizerFrame->Detach(oldBook);
613         delete oldBook;
614     }
615     else // no old book
616     {
617         CreateInitialPages(m_bookCtrl);
618     }
619 
620     m_sizerFrame->Insert(0, m_bookCtrl, wxSizerFlags(5).Expand().Border());
621 
622     m_sizerFrame->Show(m_bookCtrl);
623     m_sizerFrame->Layout();
624 }
625 
AddFlagStrIfFlagPresent(wxString & flagStr,long flags,long flag,const wxString & flagName) const626 void MyFrame::AddFlagStrIfFlagPresent(wxString & flagStr, long flags, long flag,
627                                       const wxString& flagName) const
628 {
629     if( (flags & flag) == flag )
630     {
631         if( !flagStr.empty() )
632             flagStr += " | ";
633         flagStr += flagName;
634     }
635 }
636 
CreateNewPage() const637 wxPanel *MyFrame::CreateNewPage() const
638 {
639     wxPanel *panel = new wxPanel(m_bookCtrl, wxID_ANY );
640 
641 #if wxUSE_HELP
642     panel->SetHelpText("Panel with \"First\" and \"Second\" buttons");
643 #endif
644 
645     (void) new wxButton(panel, wxID_ANY, "First button", wxPoint(10, 30));
646     (void) new wxButton(panel, wxID_ANY, "Second button", wxPoint(150, 30));
647 
648     return panel;
649 }
650 
651 
652 //-----------------------------------------------------------------------------
653 // MyFrame - event handlers
654 //-----------------------------------------------------------------------------
655 
656 #if wxUSE_HELP
657 
OnContextHelp(wxCommandEvent & WXUNUSED (event))658 void MyFrame::OnContextHelp(wxCommandEvent& WXUNUSED(event))
659 {
660     // launches local event loop
661     wxContextHelp ch( this );
662 }
663 
664 #endif // wxUSE_HELP
665 
OnHitTest(wxCommandEvent & WXUNUSED (event))666 void MyFrame::OnHitTest(wxCommandEvent& WXUNUSED(event))
667 {
668     wxBookCtrlBase * book = GetCurrentBook();
669     const wxPoint pt = ::wxGetMousePosition();
670 
671     long flags;
672     int pagePos = book->HitTest( book->ScreenToClient(pt), &flags );
673 
674     wxString flagsStr;
675 
676     AddFlagStrIfFlagPresent( flagsStr, flags, wxBK_HITTEST_NOWHERE, "wxBK_HITTEST_NOWHERE" );
677     AddFlagStrIfFlagPresent( flagsStr, flags, wxBK_HITTEST_ONICON,  "wxBK_HITTEST_ONICON" );
678     AddFlagStrIfFlagPresent( flagsStr, flags, wxBK_HITTEST_ONLABEL, "wxBK_HITTEST_ONLABEL" );
679     AddFlagStrIfFlagPresent( flagsStr, flags, wxBK_HITTEST_ONITEM,  "wxBK_HITTEST_ONITEM" );
680     AddFlagStrIfFlagPresent( flagsStr, flags, wxBK_HITTEST_ONPAGE,  "wxBK_HITTEST_ONPAGE" );
681 
682     wxLogMessage("HitTest at (%d,%d): %d: %s",
683                  pt.x,
684                  pt.y,
685                  pagePos,
686                  flagsStr);
687 }
688 
OnType(wxCommandEvent & event)689 void MyFrame::OnType(wxCommandEvent& event)
690 {
691     m_type = static_cast<BookType>(event.GetId() - ID_BOOK_NOTEBOOK);
692 
693     if ( m_bookCtrl )
694         m_sizerFrame->Hide(m_bookCtrl);
695 
696     RecreateBook();
697 }
698 
699 #if wxUSE_TREEBOOK
700 
OnUpdateTreeMenu(wxUpdateUIEvent & event)701 void MyFrame::OnUpdateTreeMenu(wxUpdateUIEvent& event)
702 {
703     event.Enable(m_type == Type_Treebook);
704 }
705 
706 #endif // wxUSE_TREEBOOK
707 
OnOrient(wxCommandEvent & event)708 void MyFrame::OnOrient(wxCommandEvent& event)
709 {
710     m_orient = event.GetId();
711     RecreateBook();
712     m_sizerFrame->Layout();
713 }
714 
OnShowImages(wxCommandEvent & event)715 void MyFrame::OnShowImages(wxCommandEvent& event)
716 {
717     m_chkShowImages = event.IsChecked();
718     RecreateBook();
719     m_sizerFrame->Layout();
720 }
721 
OnStyle(wxCommandEvent & event)722 void MyFrame::OnStyle(wxCommandEvent& event)
723 {
724     bool checked = event.IsChecked();
725     switch (event.GetId())
726     {
727         case ID_FIXEDWIDTH:  m_fixedWidth = checked;  break;
728         case ID_MULTI:       m_multi = checked;       break;
729         case ID_NOPAGETHEME: m_noPageTheme = checked; break;
730         case ID_BUTTONBAR:   m_buttonBar = checked;   break;
731         case ID_HORZ_LAYOUT: m_horzLayout = checked;  break;
732         default: break; // avoid compiler warning
733     }
734 
735     RecreateBook();
736     m_sizerFrame->Layout();
737 }
738 
OnExit(wxCommandEvent & WXUNUSED (event))739 void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
740 {
741     Close();
742 }
743 
OnAddPage(wxCommandEvent & WXUNUSED (event))744 void MyFrame::OnAddPage(wxCommandEvent& WXUNUSED(event))
745 {
746     wxBookCtrlBase *currBook = GetCurrentBook();
747 
748     if ( currBook )
749     {
750         static unsigned s_pageAdded = 0;
751         currBook->AddPage(CreateNewPage(),
752                           wxString::Format
753                           (
754                             ADDED_PAGE_NAME "%u",
755                             ++s_pageAdded
756                           ),
757                           true,
758                           GetIconIndex(currBook));
759     }
760 }
761 
OnAddPageNoSelect(wxCommandEvent & WXUNUSED (event))762 void MyFrame::OnAddPageNoSelect(wxCommandEvent& WXUNUSED(event))
763 {
764     wxBookCtrlBase *currBook = GetCurrentBook();
765 
766     if ( currBook )
767     {
768         static unsigned s_pageAdded = 0;
769         currBook->AddPage(CreateNewPage(),
770                           wxString::Format
771                           (
772                             ADDED_PAGE_NAME "%u",
773                             ++s_pageAdded
774                           ),
775                           false,
776                           GetIconIndex(currBook));
777     }
778 }
779 
780 #if wxUSE_TREEBOOK
OnAddSubPage(wxCommandEvent & WXUNUSED (event))781 void MyFrame::OnAddSubPage(wxCommandEvent& WXUNUSED(event))
782 {
783     wxTreebook *currBook = wxDynamicCast(GetCurrentBook(), wxTreebook);
784     if ( currBook )
785     {
786         const int selPos = currBook->GetSelection();
787         if ( selPos == wxNOT_FOUND )
788         {
789             wxLogError("Select the parent page first!");
790             return;
791         }
792 
793         static unsigned s_subPageAdded = 0;
794         currBook->InsertSubPage
795                   (
796                     selPos,
797                     CreateNewPage(),
798                     wxString::Format
799                     (
800                      ADDED_SUB_PAGE_NAME "%u",
801                      ++s_subPageAdded
802                     ),
803                     true,
804                     GetIconIndex(currBook)
805                   );
806     }
807 }
808 
OnAddPageBefore(wxCommandEvent & WXUNUSED (event))809 void MyFrame::OnAddPageBefore(wxCommandEvent& WXUNUSED(event))
810 {
811     wxBookCtrlBase *currBook = GetCurrentBook();
812     if ( currBook )
813     {
814         const int selPos = currBook->GetSelection();
815         if ( selPos == wxNOT_FOUND )
816         {
817             wxLogError("Select the parent page first!");
818             return;
819         }
820 
821         static unsigned s_subPageAdded = 0;
822         currBook->InsertPage(selPos,
823                              CreateNewPage(),
824                              wxString::Format
825                              (
826                                 ADDED_PAGE_NAME_BEFORE "%u",
827                                 ++s_subPageAdded
828                              ),
829                              true,
830                              GetIconIndex(currBook));
831     }
832 }
833 #endif // wxUSE_TREEBOOK
834 
OnInsertPage(wxCommandEvent & WXUNUSED (event))835 void MyFrame::OnInsertPage(wxCommandEvent& WXUNUSED(event))
836 {
837     static unsigned s_pageIns = 0;
838 
839     wxBookCtrlBase *currBook = GetCurrentBook();
840 
841     if ( currBook )
842     {
843         wxPanel *panel = CreateUserCreatedPage( currBook );
844 
845         currBook->InsertPage( 0, panel,
846             wxString::Format(INSERTED_PAGE_NAME "%u", ++s_pageIns), false,
847             GetIconIndex(currBook) );
848 
849         currBook->SetSelection(0);
850     }
851 }
852 
OnDeleteCurPage(wxCommandEvent & WXUNUSED (event))853 void MyFrame::OnDeleteCurPage(wxCommandEvent& WXUNUSED(event))
854 {
855     wxBookCtrlBase *currBook = GetCurrentBook();
856 
857     if ( currBook )
858     {
859         int sel = currBook->GetSelection();
860 
861         if (sel != wxNOT_FOUND)
862         {
863             currBook->DeletePage(sel);
864         }
865     }
866 }
867 
OnDeleteLastPage(wxCommandEvent & WXUNUSED (event))868 void MyFrame::OnDeleteLastPage(wxCommandEvent& WXUNUSED(event))
869 {
870     wxBookCtrlBase *currBook = GetCurrentBook();
871 
872     if ( currBook )
873     {
874         int page = currBook->GetPageCount();
875 
876         if ( page != 0 )
877         {
878             currBook->DeletePage(page - 1);
879         }
880     }
881 }
882 
OnNextPage(wxCommandEvent & WXUNUSED (event))883 void MyFrame::OnNextPage(wxCommandEvent& WXUNUSED(event))
884 {
885     wxBookCtrlBase *currBook = GetCurrentBook();
886 
887     if ( currBook )
888     {
889         currBook->AdvanceSelection();
890     }
891 }
892 
OnChangeSelection(wxCommandEvent & WXUNUSED (event))893 void MyFrame::OnChangeSelection(wxCommandEvent& WXUNUSED(event))
894 {
895     wxBookCtrlBase *currBook = GetCurrentBook();
896 
897     if ( currBook )
898         currBook->ChangeSelection(0);
899 }
900 
OnSetSelection(wxCommandEvent & WXUNUSED (event))901 void MyFrame::OnSetSelection(wxCommandEvent& WXUNUSED(event))
902 {
903     wxBookCtrlBase *currBook = GetCurrentBook();
904 
905     if ( currBook )
906         currBook->SetSelection(0);
907 }
908 
OnGetPageSize(wxCommandEvent & WXUNUSED (event))909 void MyFrame::OnGetPageSize(wxCommandEvent& WXUNUSED(event))
910 {
911     wxBookCtrlBase* const currBook = GetCurrentBook();
912     if ( !currBook )
913         return;
914 
915     const wxSize sizePage = currBook->GetPage(0)->GetSize();
916     const wxSize sizeBook = currBook->GetSize();
917 
918     wxLogMessage("Page size is (%d, %d), book size (%d, %d)",
919                  sizePage.x, sizePage.y,
920                  sizeBook.x, sizeBook.y);
921 }
922 
OnSetPageSize(wxCommandEvent & WXUNUSED (event))923 void MyFrame::OnSetPageSize(wxCommandEvent& WXUNUSED(event))
924 {
925     wxBookCtrlBase* const currBook = GetCurrentBook();
926     if ( !currBook )
927         return;
928 
929     const wxSize sizePage(300, 300);
930     currBook->SetPageSize(sizePage);
931 
932     wxLogMessage("Page size set to (%d, %d)",
933                  sizePage.x, sizePage.y);
934 }
935 
OnIdle(wxIdleEvent & WXUNUSED (event))936 void MyFrame::OnIdle( wxIdleEvent& WXUNUSED(event) )
937 {
938     static int s_nPages = wxNOT_FOUND;
939     static int s_nSel = wxNOT_FOUND;
940     static wxBookCtrlBase *s_currBook = NULL;
941 
942     wxBookCtrlBase *currBook = GetCurrentBook();
943 
944     int nPages = currBook ? currBook->GetPageCount() : 0;
945     int nSel = currBook ? currBook->GetSelection() : wxNOT_FOUND;
946 
947     if ( nPages != s_nPages || nSel != s_nSel || s_currBook != currBook )
948     {
949         s_nPages = nPages;
950         s_nSel = nSel;
951         s_currBook = currBook;
952 
953         wxString selection;
954         if ( nSel == wxNOT_FOUND )
955             selection << "not found";
956         else
957             selection << nSel;
958 
959         wxString title;
960         title.Printf("Notebook and friends (%d pages, selection: %s)", nPages, selection);
961 
962         SetTitle(title);
963     }
964 }
965 
OnBookCtrl(wxBookCtrlBaseEvent & event)966 void MyFrame::OnBookCtrl(wxBookCtrlBaseEvent& event)
967 {
968     static const struct EventInfo
969     {
970         wxEventType typeChanged,
971                     typeChanging;
972         const wxString name;
973     } events[] =
974     {
975 #if wxUSE_NOTEBOOK
976         {
977             wxEVT_NOTEBOOK_PAGE_CHANGED,
978             wxEVT_NOTEBOOK_PAGE_CHANGING,
979             "wxNotebook"
980         },
981 #endif // wxUSE_NOTEBOOK
982 #if wxUSE_LISTBOOK
983         {
984             wxEVT_LISTBOOK_PAGE_CHANGED,
985             wxEVT_LISTBOOK_PAGE_CHANGING,
986             "wxListbook"
987         },
988 #endif // wxUSE_LISTBOOK
989 #if wxUSE_CHOICEBOOK
990         {
991             wxEVT_CHOICEBOOK_PAGE_CHANGED,
992             wxEVT_CHOICEBOOK_PAGE_CHANGING,
993             "wxChoicebook"
994         },
995 #endif // wxUSE_CHOICEBOOK
996 #if wxUSE_TREEBOOK
997         {
998             wxEVT_TREEBOOK_PAGE_CHANGED,
999             wxEVT_TREEBOOK_PAGE_CHANGING,
1000             "wxTreebook"
1001         },
1002 #endif // wxUSE_TREEBOOK
1003 #if wxUSE_TOOLBOOK
1004         {
1005             wxEVT_TOOLBOOK_PAGE_CHANGED,
1006             wxEVT_TOOLBOOK_PAGE_CHANGING,
1007             "wxToolbook"
1008         },
1009 #endif // wxUSE_TOOLBOOK
1010 #if wxUSE_AUI
1011         {
1012             wxEVT_AUINOTEBOOK_PAGE_CHANGED,
1013             wxEVT_AUINOTEBOOK_PAGE_CHANGING,
1014             "wxAuiNotebook"
1015         },
1016 #endif // wxUSE_AUI
1017     };
1018 
1019 
1020     wxString nameEvent,
1021              nameControl,
1022              veto;
1023     const wxEventType eventType = event.GetEventType();
1024 
1025     // NB: can't use wxStaticCast here as wxBookCtrlBase is not in
1026     //     wxRTTI
1027     const wxBookCtrlBase * const
1028         book = static_cast<wxBookCtrlBase *>(event.GetEventObject());
1029 
1030     for ( size_t n = 0; n < WXSIZEOF(events); n++ )
1031     {
1032         const EventInfo& ei = events[n];
1033         if ( eventType == ei.typeChanged )
1034         {
1035             nameEvent = "Changed";
1036         }
1037         else if ( eventType == ei.typeChanging )
1038         {
1039             const int idx = event.GetOldSelection();
1040 
1041             if ( idx != wxNOT_FOUND &&
1042                     book && book->GetPageText(idx) == VETO_PAGE_NAME )
1043             {
1044                 if ( wxMessageBox
1045                      (
1046                       "Are you sure you want to leave this page?\n"
1047                       "(This demonstrates veto-ing)",
1048                       "Notebook sample",
1049                       wxICON_QUESTION | wxYES_NO,
1050                       this
1051                      ) != wxYES )
1052                 {
1053                     event.Veto();
1054                     veto = " (vetoed)";
1055                 }
1056             }
1057 
1058             nameEvent = "Changing";
1059         }
1060         else // skip end of the loop
1061         {
1062             continue;
1063         }
1064 
1065         nameControl = ei.name;
1066         break;
1067     }
1068 
1069     static int s_num = 0;
1070 
1071     wxLogMessage("Event #%d: %s: %s (%d) new sel %d, old %d, current %d%s",
1072                  ++s_num,
1073                  nameControl,
1074                  nameEvent,
1075                  eventType,
1076                  event.GetSelection(),
1077                  event.GetOldSelection(),
1078                  book->GetSelection(),
1079                  veto);
1080 
1081 #if USE_LOG
1082     m_text->SetInsertionPointEnd();
1083 #endif
1084 }
1085