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