From e9c0df38e7bdf9dcc527833c6ed7ae30155c24cc Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Thu, 21 Aug 2003 23:06:36 +0000
Subject: [PATCH] added wxListbook

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23083 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 configure.in               |  10 +
 docs/changes.txt           |   1 +
 docs/latex/wx/listbook.tex |  51 +++++
 include/wx/listbook.h      | 173 ++++++++++++++
 include/wx/mac/setup0.h    |   8 +
 include/wx/msw/setup0.h    |   8 +
 include/wx/os2/setup0.h    |   1 +
 include/wx/univ/setup0.h   |   8 +
 setup.h.in                 |   1 +
 setup.h_vms                |   1 +
 src/generic/listbkg.cpp    | 445 +++++++++++++++++++++++++++++++++++++
 11 files changed, 707 insertions(+)
 create mode 100644 docs/latex/wx/listbook.tex
 create mode 100644 include/wx/listbook.h
 create mode 100644 src/generic/listbkg.cpp

diff --git a/configure.in b/configure.in
index 890f0b3943..14ef2a6b05 100644
--- a/configure.in
+++ b/configure.in
@@ -490,6 +490,7 @@ if test $DEBUG_CONFIGURE = 1; then
   DEFAULT_wxUSE_GAUGE=no
   DEFAULT_wxUSE_GRID=no
   DEFAULT_wxUSE_IMAGLIST=no
+  DEFAULT_wxUSE_LISTBOOK=no
   DEFAULT_wxUSE_LISTBOX=no
   DEFAULT_wxUSE_LISTCTRL=no
   DEFAULT_wxUSE_NOTEBOOK=no
@@ -666,6 +667,7 @@ else
   DEFAULT_wxUSE_GAUGE=yes
   DEFAULT_wxUSE_GRID=yes
   DEFAULT_wxUSE_IMAGLIST=yes
+  DEFAULT_wxUSE_LISTBOOK=yes
   DEFAULT_wxUSE_LISTBOX=yes
   DEFAULT_wxUSE_LISTCTRL=yes
   DEFAULT_wxUSE_NOTEBOOK=yes
@@ -941,6 +943,7 @@ if test "$wxUSE_CONTROLS" = "yes"; then
   DEFAULT_wxUSE_GAUGE=yes
   DEFAULT_wxUSE_GRID=yes
   DEFAULT_wxUSE_IMAGLIST=yes
+  DEFAULT_wxUSE_LISTBOOK=yes
   DEFAULT_wxUSE_LISTBOX=yes
   DEFAULT_wxUSE_LISTCTRL=yes
   DEFAULT_wxUSE_NOTEBOOK=yes
@@ -978,6 +981,7 @@ elif test "$wxUSE_CONTROLS" = "no"; then
   DEFAULT_wxUSE_GAUGE=no
   DEFAULT_wxUSE_GRID=no
   DEFAULT_wxUSE_IMAGLIST=no
+  DEFAULT_wxUSE_LISTBOOK=no
   DEFAULT_wxUSE_LISTBOX=no
   DEFAULT_wxUSE_LISTCTRL=no
   DEFAULT_wxUSE_NOTEBOOK=no
@@ -1029,6 +1033,7 @@ WX_ARG_ENABLE(display,     [  --enable-display        use wxDisplay class], wxUS
 WX_ARG_ENABLE(gauge,       [  --enable-gauge          use wxGauge class], wxUSE_GAUGE)
 WX_ARG_ENABLE(grid,        [  --enable-grid           use wxGrid class], wxUSE_GRID)
 WX_ARG_ENABLE(imaglist,    [  --enable-imaglist       use wxImageList class], wxUSE_IMAGLIST)
+WX_ARG_ENABLE(listbook,    [  --enable-listbook       use wxListbook class], wxUSE_LISTBOOK)
 WX_ARG_ENABLE(listbox,     [  --enable-listbox        use wxListBox class], wxUSE_LISTBOX)
 WX_ARG_ENABLE(listctrl,    [  --enable-listctrl       use wxListCtrl class], wxUSE_LISTCTRL)
 WX_ARG_ENABLE(notebook,    [  --enable-notebook       use wxNotebook class], wxUSE_NOTEBOOK)
@@ -5047,6 +5052,11 @@ if test "$wxUSE_IMAGLIST" = "yes"; then
     AC_DEFINE(wxUSE_IMAGLIST)
 fi
 
+if test "$wxUSE_LISTBOOK" = "yes"; then
+    AC_DEFINE(wxUSE_LISTBOOK)
+    USES_CONTROLS=1
+fi
+
 if test "$wxUSE_LISTBOX" = "yes"; then
     AC_DEFINE(wxUSE_LISTBOX)
     USES_CONTROLS=1
diff --git a/docs/changes.txt b/docs/changes.txt
index 8d8dc79431..1c890d92f3 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -78,6 +78,7 @@ wxBase:
 All GUI ports:
 
 - added wxVScrolledWindow, wxVListBox and wxHtmlLbox classes
+- added wxListbook
 - added alpha channel support to wxImage
 - added wxRenderer class allowing to customize the drawing of generic controls
 - added wxCLOSE_BOX style for dialogs and frames
diff --git a/docs/latex/wx/listbook.tex b/docs/latex/wx/listbook.tex
new file mode 100644
index 0000000000..2452b73254
--- /dev/null
+++ b/docs/latex/wx/listbook.tex
@@ -0,0 +1,51 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Name:        listbook.tex
+%% Purpose:     wxListbook documentation
+%% Author:      Vadim Zeitlin
+%% Modified by:
+%% Created:     22.08.03
+%% RCS-ID:      $Id$
+%% Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
+%% License:     wxWindows license
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{\class{wxListbook}}\label{wxlistbook}
+
+wxListbook is a class similar to \helpref{wxNotebook}{wxnotebook} but which
+uses a \helpref{wxListCtrl}{wxlistctrl} to show the labels instead of the
+tabs.
+
+There is no documentation for this class yet but its usage is strictly
+identical to wxNotebook (except for the features clearly related to tabs
+only), so please refer to that class documentation for now. You can also
+use the \helpref{notebook sample}{samplenotebook} to see wxListbook in action.
+
+\wxheading{Derived from}
+
+\helpref{wxControl}{wxcontrol}\\
+\helpref{wxWindow}{wxwindow}\\
+\helpref{wxEvtHandler}{wxevthandler}\\
+\helpref{wxObject}{wxobject}
+
+\wxheading{Include files}
+
+<wx/listbook.h>
+
+\wxheading{Window styles}
+
+\twocolwidtha{5cm}
+\begin{twocollist}\itemsep=0pt
+
+\twocolitem{\windowstyle{wxLB\_DEFAULT}}{Choose the default location for the
+labels depending on the current platform (left everywhere except Mac where
+it is top).}
+\twocolitem{\windowstyle{wxLB\_TOP}}{Place labels above the page area.}
+\twocolitem{\windowstyle{wxLB\_LEFT}}{Place labels on the left side.}
+\twocolitem{\windowstyle{wxLB\_RIGHT}}{Place labels on the right side.}
+\twocolitem{\windowstyle{wxLB\_BOTTOM}}{Place labels below the page area.}
+
+\end{twocollist}
+
+\wxheading{See also}
+
+\helpref{wxNotebook}{wxnotebook}, \helpref{notebook sample}{samplenotebook}
diff --git a/include/wx/listbook.h b/include/wx/listbook.h
new file mode 100644
index 0000000000..1c4c5ae513
--- /dev/null
+++ b/include/wx/listbook.h
@@ -0,0 +1,173 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        wx/listbook.h
+// Purpose:     wxListbook: wxListCtrl and wxNotebook combination
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     19.08.03
+// RCS-ID:      $Id$
+// Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_LISTBOOK_H_
+#define _WX_LISTBOOK_H_
+
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+    #pragma interface "listbook.h"
+#endif
+
+#include "wx/defs.h"
+
+#if wxUSE_LISTBOOK
+
+#include "wx/bookctrl.h"
+
+class WXDLLEXPORT wxListView;
+class WXDLLEXPORT wxListEvent;
+class WXDLLEXPORT wxStaticLine;;
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// wxListbook styles
+enum
+{
+    // default alignment: left everywhere except Mac where it is top
+    wxLB_DEFAULT = 0,
+
+    // put the list control to the left/right/top/bottom of the page area
+    wxLB_TOP    = 0x1,
+    wxLB_BOTTOM = 0x2,
+    wxLB_LEFT   = 0x4,
+    wxLB_RIGHT  = 0x8,
+
+    // the mask which can be used to extract the alignment from the style
+    wxLB_ALIGN_MASK = 0xf
+};
+
+// ----------------------------------------------------------------------------
+// wxListbook
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListbook : public wxBookCtrl
+{
+public:
+    wxListbook()
+    {
+        Init();
+    }
+
+    wxListbook(wxWindow *parent,
+               wxWindowID id,
+               const wxPoint& pos = wxDefaultPosition,
+               const wxSize& size = wxDefaultSize,
+               long style = 0,
+               const wxString& name = wxEmptyString)
+    {
+        Init();
+
+        (void)Create(parent, id, pos, size, style, name);
+    }
+
+    // quasi ctor
+    bool Create(wxWindow *parent,
+                wxWindowID id,
+                const wxPoint& pos = wxDefaultPosition,
+                const wxSize& size = wxDefaultSize,
+                long style = 0,
+                const wxString& name = wxEmptyString);
+
+
+    virtual int GetSelection() const;
+    virtual bool SetPageText(size_t n, const wxString& strText);
+    virtual wxString GetPageText(size_t n) const;
+    virtual int GetPageImage(size_t n) const;
+    virtual bool SetPageImage(size_t n, int imageId);
+    virtual wxSize CalcSizeFromPage(const wxSize& sizePage) const;
+    virtual bool InsertPage(size_t n,
+                            wxWindow *page,
+                            const wxString& text,
+                            bool bSelect = false,
+                            int imageId = -1);
+    virtual int SetSelection(size_t n);
+    virtual void SetImageList(wxImageList *imageList);
+
+    // returns true if we have wxLB_TOP or wxLB_BOTTOM style
+    bool IsVertical() const { return HasFlag(wxLB_BOTTOM | wxLB_TOP); }
+
+protected:
+    virtual wxWindow *DoRemovePage(size_t page);
+
+private:
+    // common part of all constructors
+    void Init();
+
+    // get the size which the list control should have
+    wxSize GetListSize() const;
+
+    // get the page area
+    wxRect GetPageRect() const;
+
+    // event handlers
+    void OnSize(wxSizeEvent& event);
+    void OnListSelected(wxListEvent& event);
+
+
+    // the list control we use for showing the pages index
+    wxListView *m_list;
+
+    // the line separating it from the page area
+    wxStaticLine *m_line;
+
+    // the currently selected page or wxNOT_FOUND if none
+    int m_selection;
+
+
+    DECLARE_EVENT_TABLE()
+    DECLARE_DYNAMIC_CLASS_NO_COPY(wxListbook)
+};
+
+// ----------------------------------------------------------------------------
+// listbook event class and related stuff
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxListbookEvent : public wxBookCtrlEvent
+{
+public:
+    wxListbookEvent(wxEventType commandType = wxEVT_NULL, int id = 0,
+                    int nSel = -1, int nOldSel = -1)
+        : wxBookCtrlEvent(commandType, id, nSel, nOldSel)
+    {
+    }
+
+private:
+    DECLARE_DYNAMIC_CLASS_NO_COPY(wxListbookEvent)
+};
+
+extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED;
+extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING;
+
+typedef void (wxEvtHandler::*wxListbookEventFunction)(wxListbookEvent&);
+
+#define EVT_LISTBOOK_PAGE_CHANGED(id, fn)                                   \
+  DECLARE_EVENT_TABLE_ENTRY(                                                \
+    wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED,                                    \
+    id,                                                                     \
+    -1,                                                                     \
+    (wxObjectEventFunction)(wxEventFunction)(wxListbookEventFunction) &fn,  \
+    NULL                                                                    \
+  ),
+
+#define EVT_LISTBOOK_PAGE_CHANGING(id, fn)                                  \
+  DECLARE_EVENT_TABLE_ENTRY(                                                \
+    wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING,                                   \
+    id,                                                                     \
+    -1,                                                                     \
+    (wxObjectEventFunction)(wxEventFunction)(wxListbookEventFunction) &fn,  \
+    NULL                                                                    \
+  ),
+
+#endif // wxUSE_LISTBOOK
+
+#endif // _WX_LISTBOOK_H_
diff --git a/include/wx/mac/setup0.h b/include/wx/mac/setup0.h
index 4d10c59d8c..86101d7218 100644
--- a/include/wx/mac/setup0.h
+++ b/include/wx/mac/setup0.h
@@ -524,6 +524,14 @@
 // Recommended setting: 1
 #define wxUSE_NOTEBOOK 1
 
+// wxListbook control is similar to wxNotebook but uses wxListCtrl instead of
+// the tabs
+//
+// Default is 1.
+//
+// Recommended setting: 1
+#define wxUSE_LISTBOOK 1
+
 // wxTabDialog is a generic version of wxNotebook but it is incompatible with
 // the new class. It shouldn't be used in new code.
 //
diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h
index e4dac7bfda..b6133c6cdd 100644
--- a/include/wx/msw/setup0.h
+++ b/include/wx/msw/setup0.h
@@ -532,6 +532,14 @@
 // Recommended setting: 1
 #define wxUSE_NOTEBOOK 1
 
+// wxListbook control is similar to wxNotebook but uses wxListCtrl instead of
+// the tabs
+//
+// Default is 1.
+//
+// Recommended setting: 1
+#define wxUSE_LISTBOOK 1
+
 // wxTabDialog is a generic version of wxNotebook but it is incompatible with
 // the new class. It shouldn't be used in new code.
 //
diff --git a/include/wx/os2/setup0.h b/include/wx/os2/setup0.h
index e3fcbed7ac..acdfde8279 100644
--- a/include/wx/os2/setup0.h
+++ b/include/wx/os2/setup0.h
@@ -120,6 +120,7 @@
 #define wxUSE_MIMETYPE     1
 #define wxUSE_MSGDLG       1
 #define wxUSE_NOTEBOOK     1
+#define wxUSE_LISTBOOK     1
 #define wxUSE_SPLITTER     1
 #define wxUSE_STOPWATCH    1
 #define wxUSE_TAB_DIALOG   1
diff --git a/include/wx/univ/setup0.h b/include/wx/univ/setup0.h
index 4923de982d..736b6ae3ac 100644
--- a/include/wx/univ/setup0.h
+++ b/include/wx/univ/setup0.h
@@ -569,6 +569,14 @@
 // Recommended setting: 1
 #define wxUSE_NOTEBOOK 1
 
+// wxListbook control is similar to wxNotebook but uses wxListCtrl instead of
+// the tabs
+//
+// Default is 1.
+//
+// Recommended setting: 1
+#define wxUSE_LISTBOOK 1
+
 // wxTabDialog is a generic version of wxNotebook but it is incompatible with
 // the new class. It shouldn't be used in new code.
 //
diff --git a/setup.h.in b/setup.h.in
index 2ceb4a4136..42698ef53b 100644
--- a/setup.h.in
+++ b/setup.h.in
@@ -438,6 +438,7 @@
  * Use this control
  */
 #define wxUSE_NOTEBOOK 0
+#define wxUSE_LISTBOOK 0
 /*
  * Use this control
  */
diff --git a/setup.h_vms b/setup.h_vms
index 5d0bdd3895..bdeb5af7fc 100644
--- a/setup.h_vms
+++ b/setup.h_vms
@@ -454,6 +454,7 @@
  * Use this control
  */
 #define wxUSE_NOTEBOOK 1
+#define wxUSE_LISTBOOK 1
 /*
  * Use this control
  */
diff --git a/src/generic/listbkg.cpp b/src/generic/listbkg.cpp
new file mode 100644
index 0000000000..b1fdca86aa
--- /dev/null
+++ b/src/generic/listbkg.cpp
@@ -0,0 +1,445 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        generic/listbkg.cpp
+// Purpose:     generic implementation of wxListbook
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     19.08.03
+// RCS-ID:      $Id$
+// Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+    #pragma implementation "listbook.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#if wxUSE_LISTBOOK
+
+#include "wx/listctrl.h"
+#include "wx/statline.h"
+#include "wx/listbook.h"
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// margin between the list and the page, should be bigger than wxStaticLine
+// size
+const wxCoord MARGIN = 5;
+
+// ----------------------------------------------------------------------------
+// various wxWindows macros
+// ----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxListbook, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxListbookEvent, wxNotifyEvent)
+
+const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING = wxNewEventType();
+const wxEventType wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED = wxNewEventType();
+
+BEGIN_EVENT_TABLE(wxListbook, wxBookCtrl)
+    EVT_SIZE(wxListbook::OnSize)
+
+    EVT_LIST_ITEM_SELECTED(wxID_ANY, wxListbook::OnListSelected)
+END_EVENT_TABLE()
+
+// ============================================================================
+// wxListbook implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxListbook creation
+// ----------------------------------------------------------------------------
+
+void wxListbook::Init()
+{
+    m_list = NULL;
+    m_line = NULL;
+    m_selection = wxNOT_FOUND;
+}
+
+bool
+wxListbook::Create(wxWindow *parent,
+                   wxWindowID id,
+                   const wxPoint& pos,
+                   const wxSize& size,
+                   long style,
+                   const wxString& name)
+{
+    if ( (style & wxLB_ALIGN_MASK) == wxLB_DEFAULT )
+    {
+#ifdef __WXMAC__
+        style |= wxLB_TOP;
+#else // !__WXMAC__
+        style |= wxLB_LEFT;
+#endif // __WXMAC__/!__WXMAC__
+    }
+
+    if ( !wxControl::Create(parent, id, pos, size, style,
+                            wxDefaultValidator, name) )
+        return false;
+
+    m_list = new wxListView
+                 (
+                    this,
+                    -1,
+                    wxDefaultPosition,
+                    wxDefaultSize,
+                    wxLC_ICON | wxLC_SINGLE_SEL
+                 );
+
+    m_line = new wxStaticLine
+                 (
+                    this,
+                    -1,
+                    wxDefaultPosition,
+                    wxDefaultSize,
+                    IsVertical() ? wxLI_HORIZONTAL : wxLI_VERTICAL
+                 );
+
+    return true;
+}
+
+// ----------------------------------------------------------------------------
+// wxListbook geometry management
+// ----------------------------------------------------------------------------
+
+wxSize wxListbook::GetListSize() const
+{
+    const wxSize sizeClient = GetClientSize();
+
+    // we need to find the longest/tallest label
+    wxCoord widthMax = 0,
+            heightMax = 0;
+    const int count = m_list->GetItemCount();
+    if ( count )
+    {
+        for ( int i = 0; i < count; i++ )
+        {
+            wxRect r;
+            m_list->GetItemRect(i, r);
+
+            wxCoord w = r.x + r.width,
+                    h = r.y + r.height;
+
+            if ( w > widthMax )
+                widthMax = w;
+            if ( h > heightMax )
+                heightMax = h;
+        }
+    }
+
+    wxSize size;
+    if ( IsVertical() )
+    {
+        size.x = sizeClient.x;
+        size.y = heightMax;
+    }
+    else // left/right aligned
+    {
+        size.x = widthMax + 10;
+        size.y = sizeClient.y;
+    }
+
+    return size;
+}
+
+wxRect wxListbook::GetPageRect() const
+{
+    const wxSize sizeList = GetListSize();
+
+    wxRect rectPage(wxPoint(0, 0), GetClientSize());
+    switch ( GetWindowStyle() & wxLB_ALIGN_MASK )
+    {
+        default:
+            wxFAIL_MSG( _T("unexpected wxListbook alignment") );
+            // fall through
+
+        case wxLB_TOP:
+            rectPage.y = sizeList.y + MARGIN;
+            // fall through
+
+        case wxLB_BOTTOM:
+            rectPage.height -= sizeList.y + MARGIN;
+            break;
+
+        case wxLB_LEFT:
+            rectPage.x = sizeList.x + MARGIN;
+            // fall through
+
+        case wxLB_RIGHT:
+            rectPage.width -= sizeList.x + MARGIN;
+            break;
+    }
+
+    return rectPage;
+}
+
+void wxListbook::OnSize(wxSizeEvent& event)
+{
+    // resize the list control and the page area to fit inside our new size
+    const wxSize sizeClient = GetClientSize(),
+                 sizeList = GetListSize();
+
+    wxPoint posList;
+    switch ( GetWindowStyle() & wxLB_ALIGN_MASK )
+    {
+        default:
+            wxFAIL_MSG( _T("unexpected wxListbook alignment") );
+            // fall through
+
+        case wxLB_TOP:
+        case wxLB_LEFT:
+            // posList is already ok
+            break;
+
+        case wxLB_BOTTOM:
+            posList.y = sizeClient.y - sizeList.y;
+            break;
+
+        case wxLB_RIGHT:
+            posList.x = sizeClient.x - sizeList.x;
+            break;
+    }
+
+    m_list->SetSize(posList.x, posList.y, sizeList.x, sizeList.y);
+
+    if ( m_line )
+    {
+        wxRect rectLine(wxPoint(0, 0), sizeClient);
+
+        switch ( GetWindowStyle() & wxLB_ALIGN_MASK )
+        {
+            case wxLB_TOP:
+                rectLine.y = sizeList.y + 1;
+                rectLine.height = MARGIN - 2;
+                break;
+
+            case wxLB_BOTTOM:
+                rectLine.height = MARGIN - 2;
+                rectLine.y = sizeClient.y - sizeList.y - rectLine.height;
+                break;
+
+            case wxLB_LEFT:
+                rectLine.x = sizeList.x + 1;
+                rectLine.width = MARGIN - 2;
+                break;
+
+            case wxLB_RIGHT:
+                rectLine.width = MARGIN - 2;
+                rectLine.x = sizeClient.x - sizeList.x - rectLine.width;
+                break;
+        }
+
+        m_line->SetSize(rectLine);
+    }
+
+    // we should always have some selection if possible
+    if ( m_selection == wxNOT_FOUND && GetPageCount() )
+    {
+        SetSelection(0);
+    }
+
+    if ( m_selection != wxNOT_FOUND )
+    {
+        wxWindow *page = m_pages[m_selection];
+        wxCHECK_RET( page, _T("NULL page in wxListbook?") );
+
+        page->SetSize(GetPageRect());
+        if ( !page->IsShown() )
+        {
+            page->Show();
+        }
+    }
+
+    event.Skip();
+}
+
+wxSize wxListbook::CalcSizeFromPage(const wxSize& sizePage) const
+{
+    // we need to add the size of the list control and the margin
+    const wxSize sizeList = GetListSize();
+
+    wxSize size = sizePage;
+    if ( IsVertical() )
+    {
+        size.y += sizeList.y + MARGIN;
+    }
+    else // left/right aligned
+    {
+        size.x += sizeList.x + MARGIN;
+    }
+
+    return size;
+}
+
+
+// ----------------------------------------------------------------------------
+// accessing the pages
+// ----------------------------------------------------------------------------
+
+bool wxListbook::SetPageText(size_t n, const wxString& strText)
+{
+    m_list->SetItemText(n, strText);
+
+    return true;
+}
+
+wxString wxListbook::GetPageText(size_t n) const
+{
+    return m_list->GetItemText(n);
+}
+
+int wxListbook::GetPageImage(size_t WXUNUSED(n)) const
+{
+    wxFAIL_MSG( _T("wxListbook::GetPageImage() not implemented") );
+
+    return -1;
+}
+
+bool wxListbook::SetPageImage(size_t n, int imageId)
+{
+    return m_list->SetItemImage(n, imageId, imageId);
+}
+
+// ----------------------------------------------------------------------------
+// image list stuff
+// ----------------------------------------------------------------------------
+
+void wxListbook::SetImageList(wxImageList *imageList)
+{
+    m_list->SetImageList(imageList, wxIMAGE_LIST_NORMAL);
+
+    wxBookCtrl::SetImageList(imageList);
+}
+
+// ----------------------------------------------------------------------------
+// selection
+// ----------------------------------------------------------------------------
+
+int wxListbook::GetSelection() const
+{
+    return m_selection;
+}
+
+int wxListbook::SetSelection(size_t n)
+{
+    wxCHECK_MSG( n < GetPageCount(), wxNOT_FOUND,
+                 _T("invalid page index in wxListbook::SetSelection()") );
+
+    int selOld = m_selection;
+
+    if ( (int)n != m_selection )
+    {
+        m_selection = n;
+
+        m_list->Select(m_selection);
+        m_list->Focus(m_selection);
+    }
+
+    return selOld;
+}
+
+
+// ----------------------------------------------------------------------------
+// adding/removing the pages
+// ----------------------------------------------------------------------------
+
+bool
+wxListbook::InsertPage(size_t n,
+                       wxWindow *page,
+                       const wxString& text,
+                       bool bSelect,
+                       int imageId)
+{
+    if ( !wxBookCtrl::InsertPage(n, page, text, bSelect, imageId) )
+        return false;
+
+    m_list->InsertItem(n, text, imageId);
+
+    if ( bSelect )
+    {
+        m_list->Select(n);
+        m_list->Focus(n);
+    }
+    else // don't select this page
+    {
+        // it will be shown only when selected
+        page->Hide();
+    }
+
+    return true;
+}
+
+wxWindow *wxListbook::DoRemovePage(size_t page)
+{
+    wxWindow *win = wxBookCtrl::DoRemovePage(page);
+    if ( win )
+    {
+        m_list->DeleteItem(page);
+    }
+
+    return win;
+}
+
+// ----------------------------------------------------------------------------
+// wxListbook events
+// ----------------------------------------------------------------------------
+
+void wxListbook::OnListSelected(wxListEvent& eventList)
+{
+    const int selNew = eventList.GetIndex();
+
+    if ( selNew == m_selection )
+    {
+        // this event can only come from our own Select(m_selection) below
+        // which we call when the page change is vetoed, so we should simply
+        // ignore it
+        return;
+    }
+
+    // first send "change in progress" event which may be vetoed by user
+    wxListbookEvent eventIng(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGING, GetId());
+
+    eventIng.SetEventObject(this);
+    eventIng.SetSelection(selNew);
+    eventIng.SetOldSelection(m_selection);
+    if ( GetEventHandler()->ProcessEvent(eventIng) && !eventIng.IsAllowed() )
+    {
+        m_list->Select(m_selection);
+        return;
+    }
+
+    // change allowed: do change the page and notify the user about it
+    if ( m_selection != wxNOT_FOUND )
+        m_pages[m_selection]->Hide();
+    wxWindow *page = m_pages[m_selection = selNew];
+    page->SetSize(GetPageRect());
+    page->Show();
+
+    wxListbookEvent eventEd(wxEVT_COMMAND_LISTBOOK_PAGE_CHANGED, GetId());
+
+    eventEd.SetEventObject(this);
+    eventEd.SetSelection(selNew);
+    eventEd.SetOldSelection(m_selection);
+
+    (void)GetEventHandler()->ProcessEvent(eventEd);
+}
+
+#endif // wxUSE_LISTBOOK
+
-- 
2.50.0

