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
33IMPLEMENT_APP(MyApp)
34
35bool 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
57wxPanel *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
71wxPanel *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
100wxPanel *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
114wxPanel *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
132wxPanel *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
147int 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
161void 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
180wxPanel *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
205MyFrame::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
338MyFrame::~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
394int 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
403void 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
508BEGIN_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)
559END_EVENT_TABLE()
560
561#if wxUSE_HELP
562
563void MyFrame::OnContextHelp(wxCommandEvent& WXUNUSED(event))
564{
565    // launches local event loop
566    wxContextHelp ch( this );
567}
568
569#endif // wxUSE_HELP
570
571void 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
581void 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
603void 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
615void MyFrame::OnUpdateTreeMenu(wxUpdateUIEvent& event)
616{
617    event.Enable(m_type == Type_Treebook);
618}
619
620#endif // wxUSE_TREEBOOK
621
622
623void MyFrame::OnOrient(wxCommandEvent& event)
624{
625    m_orient = event.GetId();
626    RecreateBook();
627    m_sizerFrame->Layout();
628}
629
630void MyFrame::OnShowImages(wxCommandEvent& event)
631{
632    m_chkShowImages = event.IsChecked();
633    RecreateBook();
634    m_sizerFrame->Layout();
635}
636
637void 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
645void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
646{
647    Close();
648}
649
650wxPanel *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
664void 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
682void 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
701void 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
729void 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
755void 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
773void 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
788void 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
803void MyFrame::OnNextPage(wxCommandEvent& WXUNUSED(event))
804{
805    wxBookCtrlBase *currBook = GetCurrentBook();
806
807    if ( currBook )
808    {
809        currBook->AdvanceSelection();
810    }
811}
812
813void 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
825void 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
855void 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