]> git.saurik.com Git - wxWidgets.git/blobdiff - src/aui/auibook.cpp
Replace wxDataViewCtrl::StartEditor() with EditItem().
[wxWidgets.git] / src / aui / auibook.cpp
index 7a0386ece72324e5fd13579aa368bfbe138f4107..36640c3fcccbb025f0cced46a34eebd54dc96557 100644 (file)
 #ifndef WX_PRECOMP
     #include "wx/settings.h"
     #include "wx/image.h"
 #ifndef WX_PRECOMP
     #include "wx/settings.h"
     #include "wx/image.h"
+    #include "wx/menu.h"
 #endif
 
 #include "wx/aui/tabmdi.h"
 #include "wx/dcbuffer.h"
 #endif
 
 #include "wx/aui/tabmdi.h"
 #include "wx/dcbuffer.h"
-#include "wx/menu.h"
+
+#include "wx/renderer.h"
 
 #ifdef __WXMAC__
 
 #ifdef __WXMAC__
-#include "wx/mac/carbon/private.h"
+#include "wx/osx/private.h"
 #endif
 
 #include "wx/arrimpl.cpp"
 WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray)
 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray)
 
 #endif
 
 #include "wx/arrimpl.cpp"
 WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray)
 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray)
 
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BUTTON)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION)
-DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND)
-
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_BUTTON, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_CANCEL_DRAG, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, wxAuiNotebookEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, wxAuiNotebookEvent);
 
 IMPLEMENT_CLASS(wxAuiNotebook, wxControl)
 IMPLEMENT_CLASS(wxAuiTabCtrl, wxControl)
 
 IMPLEMENT_CLASS(wxAuiNotebook, wxControl)
 IMPLEMENT_CLASS(wxAuiTabCtrl, wxControl)
-IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent, wxEvent)
+IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent, wxBookCtrlEvent)
 
 
 
 
 
 
 
 
 
 
-// This functions are here for this proof of concept
-// and will be factored out later. See dockart.cpp
-static wxColor StepColour(const wxColor& c, int percent)
-{
-    int r = c.Red(), g = c.Green(), b = c.Blue();
-    return wxColour((unsigned char)wxMin((r*percent)/100,255),
-                    (unsigned char)wxMin((g*percent)/100,255),
-                    (unsigned char)wxMin((b*percent)/100,255));
-}
+// these functions live in dockart.cpp -- they'll eventually
+// be moved to a new utility cpp file
 
 
-// This functions are here for this proof of concept
-// and will be factored out later. See dockart.cpp
-static wxBitmap BitmapFromBits(const unsigned char bits[], int w, int h,
-                               const wxColour& color)
-{
-    wxImage img = wxBitmap((const char*)bits, w, h).ConvertToImage();
-    img.Replace(0,0,0,123,123,123);
-    img.Replace(255,255,255,color.Red(),color.Green(),color.Blue());
-    img.SetMaskColour(123,123,123);
-    return wxBitmap(img);
-}
+wxBitmap wxAuiBitmapFromBits(const unsigned char bits[], int w, int h,
+                             const wxColour& color);
+
+wxString wxAuiChopText(wxDC& dc, const wxString& text, int max_size);
 
 static void DrawButtons(wxDC& dc,
                         const wxRect& _rect,
 
 static void DrawButtons(wxDC& dc,
                         const wxRect& _rect,
@@ -96,8 +91,8 @@ static void DrawButtons(wxDC& dc,
     if (button_state == wxAUI_BUTTON_STATE_HOVER ||
         button_state == wxAUI_BUTTON_STATE_PRESSED)
     {
     if (button_state == wxAUI_BUTTON_STATE_HOVER ||
         button_state == wxAUI_BUTTON_STATE_PRESSED)
     {
-        dc.SetBrush(wxBrush(StepColour(bkcolour, 120)));
-        dc.SetPen(wxPen(StepColour(bkcolour, 70)));
+        dc.SetBrush(wxBrush(bkcolour.ChangeLightness(120)));
+        dc.SetPen(wxPen(bkcolour.ChangeLightness(75)));
 
         // draw the background behind the button
         dc.DrawRectangle(rect.x, rect.y, 15, 15);
 
         // draw the background behind the button
         dc.DrawRectangle(rect.x, rect.y, 15, 15);
@@ -116,36 +111,6 @@ static void IndentPressedBitmap(wxRect* rect, int button_state)
     }
 }
 
     }
 }
 
-// chops the text so that it fits within |max_size| pixels.
-// Also adds an elipsis if necessary
-
-static wxString ChopText(wxDC& dc, const wxString& text, int max_size)
-{
-    wxCoord x,y;
-
-    // first check if the text fits with no problems
-    dc.GetTextExtent(text, &x, &y);
-    if (x <= max_size)
-        return text;
-
-    size_t i, len = text.Length();
-    size_t last_good_length = 0;
-    for (i = 0; i < len; ++i)
-    {
-        wxString s = text.Left(i);
-        s += wxT("...");
-
-        dc.GetTextExtent(s, &x, &y);
-        if (x > max_size)
-            break;
-
-        last_good_length = i;
-    }
-
-    wxString ret = text.Left(last_good_length);
-    ret += wxT("...");
-    return ret;
-}
 
 
 // -- GUI helper classes and functions --
 
 
 // -- GUI helper classes and functions --
@@ -154,14 +119,14 @@ class wxAuiCommandCapture : public wxEvtHandler
 {
 public:
 
 {
 public:
 
-    wxAuiCommandCapture() { m_last_id = 0; }
-    int GetCommandId() const { return m_last_id; }
+    wxAuiCommandCapture() { m_lastId = 0; }
+    int GetCommandId() const { return m_lastId; }
 
     bool ProcessEvent(wxEvent& evt)
     {
         if (evt.GetEventType() == wxEVT_COMMAND_MENU_SELECTED)
         {
 
     bool ProcessEvent(wxEvent& evt)
     {
         if (evt.GetEventType() == wxEVT_COMMAND_MENU_SELECTED)
         {
-            m_last_id = evt.GetId();
+            m_lastId = evt.GetId();
             return true;
         }
 
             return true;
         }
 
@@ -172,40 +137,40 @@ public:
     }
 
 private:
     }
 
 private:
-    int m_last_id;
+    int m_lastId;
 };
 
 
 // -- bitmaps --
 
 #if defined( __WXMAC__ )
 };
 
 
 // -- bitmaps --
 
 #if defined( __WXMAC__ )
- static unsigned char close_bits[]={
+ static const unsigned char close_bits[]={
      0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
      0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
      0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
 #elif defined( __WXGTK__)
      0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
      0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
      0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
 #elif defined( __WXGTK__)
- static unsigned char close_bits[]={
+ static const unsigned char close_bits[]={
      0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
      0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
      0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 #else
      0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
      0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
      0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 #else
- static unsigned char close_bits[]={
+ static const unsigned char close_bits[]={
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9,
      0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 #endif
 
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9,
      0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 #endif
 
-static unsigned char left_bits[] = {
+static const unsigned char left_bits[] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe,
    0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe,
    0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
-static unsigned char right_bits[] = {
+static const unsigned char right_bits[] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff,
    0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff,
    0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 
-static unsigned char list_bits[] = {
+static const unsigned char list_bits[] = {
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -219,40 +184,48 @@ static unsigned char list_bits[] = {
 
 wxAuiDefaultTabArt::wxAuiDefaultTabArt()
 {
 
 wxAuiDefaultTabArt::wxAuiDefaultTabArt()
 {
-    m_normal_font = *wxNORMAL_FONT;
-    m_selected_font = *wxNORMAL_FONT;
-    m_selected_font.SetWeight(wxBOLD);
-    m_measuring_font = m_selected_font;
+    m_normalFont = *wxNORMAL_FONT;
+    m_selectedFont = *wxNORMAL_FONT;
+    m_selectedFont.SetWeight(wxBOLD);
+    m_measuringFont = m_selectedFont;
 
 
-    m_fixed_tab_width = 100;
-    m_tab_ctrl_height = 0;
+    m_fixedTabWidth = 100;
+    m_tabCtrlHeight = 0;
 
 
-#ifdef __WXMAC__
-    wxBrush toolbarbrush;
-    toolbarbrush.MacSetTheme( kThemeBrushToolbarBackground );
-    wxColor base_colour = toolbarbrush.GetColour();
+#if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON
+    wxColor baseColour = wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground));
 #else
 #else
-    wxColor base_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
+    wxColor baseColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
 #endif
 
 #endif
 
-    m_base_colour = base_colour;
-    wxColor darker2_colour = StepColour(base_colour, 70);
+    // the baseColour is too pale to use as our base colour,
+    // so darken it a bit --
+    if ((255-baseColour.Red()) +
+        (255-baseColour.Green()) +
+        (255-baseColour.Blue()) < 60)
+    {
+        baseColour = baseColour.ChangeLightness(92);
+    }
+
+    m_activeColour = baseColour;
+    m_baseColour = baseColour;
+    wxColor borderColour = baseColour.ChangeLightness(75);
 
 
-    m_border_pen = wxPen(darker2_colour);
-    m_base_colour_pen = wxPen(m_base_colour);
-    m_base_colour_brush = wxBrush(m_base_colour);
+    m_borderPen = wxPen(borderColour);
+    m_baseColourPen = wxPen(m_baseColour);
+    m_baseColourBrush = wxBrush(m_baseColour);
 
 
-    m_active_close_bmp = BitmapFromBits(close_bits, 16, 16, *wxBLACK);
-    m_disabled_close_bmp = BitmapFromBits(close_bits, 16, 16, wxColour(128,128,128));
+    m_activeCloseBmp = wxAuiBitmapFromBits(close_bits, 16, 16, *wxBLACK);
+    m_disabledCloseBmp = wxAuiBitmapFromBits(close_bits, 16, 16, wxColour(128,128,128));
 
 
-    m_active_left_bmp = BitmapFromBits(left_bits, 16, 16, *wxBLACK);
-    m_disabled_left_bmp = BitmapFromBits(left_bits, 16, 16, wxColour(128,128,128));
+    m_activeLeftBmp = wxAuiBitmapFromBits(left_bits, 16, 16, *wxBLACK);
+    m_disabledLeftBmp = wxAuiBitmapFromBits(left_bits, 16, 16, wxColour(128,128,128));
 
 
-    m_active_right_bmp = BitmapFromBits(right_bits, 16, 16, *wxBLACK);
-    m_disabled_right_bmp = BitmapFromBits(right_bits, 16, 16, wxColour(128,128,128));
+    m_activeRightBmp = wxAuiBitmapFromBits(right_bits, 16, 16, *wxBLACK);
+    m_disabledRightBmp = wxAuiBitmapFromBits(right_bits, 16, 16, wxColour(128,128,128));
 
 
-    m_active_windowlist_bmp = BitmapFromBits(list_bits, 16, 16, *wxBLACK);
-    m_disabled_windowlist_bmp = BitmapFromBits(list_bits, 16, 16, wxColour(128,128,128));
+    m_activeWindowListBmp = wxAuiBitmapFromBits(list_bits, 16, 16, *wxBLACK);
+    m_disabledWindowListBmp = wxAuiBitmapFromBits(list_bits, 16, 16, wxColour(128,128,128));
 
     m_flags = 0;
 }
 
     m_flags = 0;
 }
@@ -263,7 +236,7 @@ wxAuiDefaultTabArt::~wxAuiDefaultTabArt()
 
 wxAuiTabArt* wxAuiDefaultTabArt::Clone()
 {
 
 wxAuiTabArt* wxAuiDefaultTabArt::Clone()
 {
-    return static_cast<wxAuiTabArt*>(new wxAuiDefaultTabArt);
+    return new wxAuiDefaultTabArt(*this);
 }
 
 void wxAuiDefaultTabArt::SetFlags(unsigned int flags)
 }
 
 void wxAuiDefaultTabArt::SetFlags(unsigned int flags)
@@ -274,31 +247,31 @@ void wxAuiDefaultTabArt::SetFlags(unsigned int flags)
 void wxAuiDefaultTabArt::SetSizingInfo(const wxSize& tab_ctrl_size,
                                        size_t tab_count)
 {
 void wxAuiDefaultTabArt::SetSizingInfo(const wxSize& tab_ctrl_size,
                                        size_t tab_count)
 {
-    m_fixed_tab_width = 100;
+    m_fixedTabWidth = 100;
 
     int tot_width = (int)tab_ctrl_size.x - GetIndentSize() - 4;
 
     int tot_width = (int)tab_ctrl_size.x - GetIndentSize() - 4;
-    
+
     if (m_flags & wxAUI_NB_CLOSE_BUTTON)
     if (m_flags & wxAUI_NB_CLOSE_BUTTON)
-        tot_width -= m_active_close_bmp.GetWidth();
+        tot_width -= m_activeCloseBmp.GetWidth();
     if (m_flags & wxAUI_NB_WINDOWLIST_BUTTON)
     if (m_flags & wxAUI_NB_WINDOWLIST_BUTTON)
-        tot_width -= m_active_windowlist_bmp.GetWidth();
+        tot_width -= m_activeWindowListBmp.GetWidth();
 
     if (tab_count > 0)
     {
 
     if (tab_count > 0)
     {
-        m_fixed_tab_width = tot_width/(int)tab_count;
+        m_fixedTabWidth = tot_width/(int)tab_count;
     }
 
 
     }
 
 
-    if (m_fixed_tab_width < 100)
-        m_fixed_tab_width = 100;
+    if (m_fixedTabWidth < 100)
+        m_fixedTabWidth = 100;
 
 
-    if (m_fixed_tab_width > tot_width/2)
-        m_fixed_tab_width = tot_width/2;
+    if (m_fixedTabWidth > tot_width/2)
+        m_fixedTabWidth = tot_width/2;
 
 
-    if (m_fixed_tab_width > 220)
-        m_fixed_tab_width = 220;
+    if (m_fixedTabWidth > 220)
+        m_fixedTabWidth = 220;
 
 
-    m_tab_ctrl_height = tab_ctrl_size.y;
+    m_tabCtrlHeight = tab_ctrl_size.y;
 }
 
 
 }
 
 
@@ -307,20 +280,39 @@ void wxAuiDefaultTabArt::DrawBackground(wxDC& dc,
                                         const wxRect& rect)
 {
     // draw background
                                         const wxRect& rect)
 {
     // draw background
-    wxRect r(rect.x, rect.y, rect.width+2, rect.height-3);
-    wxColor start_colour = StepColour(m_base_colour, 90);
-    wxColor end_colour = StepColour(m_base_colour, 110);
-    dc.GradientFillLinear(r, start_colour, end_colour, wxSOUTH);
 
 
-    // draw base lines
-    int y = rect.GetHeight();
-    int w = rect.GetWidth();
-    dc.SetPen(m_border_pen);
-    dc.DrawLine(0, y-4, w, y-4);
-    dc.DrawLine(0, y-1, w, y-1);
-    dc.SetPen(wxPen(start_colour));
-    dc.DrawLine(0, y-3, w, y-3);
-    dc.DrawLine(0, y-2, w, y-2);
+    wxColor top_color       = m_baseColour.ChangeLightness(90);
+    wxColor bottom_color   = m_baseColour.ChangeLightness(170);
+    wxRect r;
+
+   if (m_flags &wxAUI_NB_BOTTOM)
+       r = wxRect(rect.x, rect.y, rect.width+2, rect.height);
+   // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
+   // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
+   else //for wxAUI_NB_TOP
+       r = wxRect(rect.x, rect.y, rect.width+2, rect.height-3);
+
+    dc.GradientFillLinear(r, top_color, bottom_color, wxSOUTH);
+
+
+   // draw base lines
+
+   dc.SetPen(m_borderPen);
+   int y = rect.GetHeight();
+   int w = rect.GetWidth();
+
+   if (m_flags &wxAUI_NB_BOTTOM)
+   {
+       dc.SetBrush(wxBrush(bottom_color));
+       dc.DrawRectangle(-1, 0, w+2, 4);
+   }
+   // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
+   // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
+   else //for wxAUI_NB_TOP
+   {
+       dc.SetBrush(m_baseColourBrush);
+       dc.DrawRectangle(-1, y-4, w+2, 4);
+   }
 }
 
 
 }
 
 
@@ -335,10 +327,8 @@ void wxAuiDefaultTabArt::DrawBackground(wxDC& dc,
 
 void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
                                  wxWindow* wnd,
 
 void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
                                  wxWindow* wnd,
+                                 const wxAuiNotebookPage& page,
                                  const wxRect& in_rect,
                                  const wxRect& in_rect,
-                                 const wxString& caption_text,
-                                 const wxBitmap& bitmap,
-                                 bool active,
                                  int close_button_state,
                                  wxRect* out_tab_rect,
                                  wxRect* out_button_rect,
                                  int close_button_state,
                                  wxRect* out_tab_rect,
                                  wxRect* out_button_rect,
@@ -346,49 +336,47 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
 {
     wxCoord normal_textx, normal_texty;
     wxCoord selected_textx, selected_texty;
 {
     wxCoord normal_textx, normal_texty;
     wxCoord selected_textx, selected_texty;
-    wxCoord textx, texty;
+    wxCoord texty;
 
     // if the caption is empty, measure some temporary text
 
     // if the caption is empty, measure some temporary text
-    wxString caption = caption_text;
-    if (caption_text.empty())
+    wxString caption = page.caption;
+    if (caption.empty())
         caption = wxT("Xj");
 
         caption = wxT("Xj");
 
-    dc.SetFont(m_selected_font);
+    dc.SetFont(m_selectedFont);
     dc.GetTextExtent(caption, &selected_textx, &selected_texty);
 
     dc.GetTextExtent(caption, &selected_textx, &selected_texty);
 
-    dc.SetFont(m_normal_font);
+    dc.SetFont(m_normalFont);
     dc.GetTextExtent(caption, &normal_textx, &normal_texty);
 
     // figure out the size of the tab
     wxSize tab_size = GetTabSize(dc,
                                  wnd,
     dc.GetTextExtent(caption, &normal_textx, &normal_texty);
 
     // figure out the size of the tab
     wxSize tab_size = GetTabSize(dc,
                                  wnd,
-                                 caption,
-                                 bitmap,
-                                 active,
+                                 page.caption,
+                                 page.bitmap,
+                                 page.active,
                                  close_button_state,
                                  x_extent);
 
                                  close_button_state,
                                  x_extent);
 
-    wxCoord tab_height = m_tab_ctrl_height - 3;
+    wxCoord tab_height = m_tabCtrlHeight - 3;
     wxCoord tab_width = tab_size.x;
     wxCoord tab_x = in_rect.x;
     wxCoord tab_y = in_rect.y + in_rect.height - tab_height;
 
 
     wxCoord tab_width = tab_size.x;
     wxCoord tab_x = in_rect.x;
     wxCoord tab_y = in_rect.y + in_rect.height - tab_height;
 
 
-    caption = caption_text;
+    caption = page.caption;
 
 
     // select pen, brush and font for the tab to be drawn
 
 
 
     // select pen, brush and font for the tab to be drawn
 
-    if (active)
+    if (page.active)
     {
     {
-        dc.SetFont(m_selected_font);
-        textx = selected_textx;
+        dc.SetFont(m_selectedFont);
         texty = selected_texty;
     }
         texty = selected_texty;
     }
-     else
+    else
     {
     {
-        dc.SetFont(m_normal_font);
-        textx = normal_textx;
+        dc.SetFont(m_normalFont);
         texty = normal_texty;
     }
 
         texty = normal_texty;
     }
 
@@ -399,6 +387,7 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
     if (tab_x + clip_width > in_rect.x + in_rect.width)
         clip_width = (in_rect.x + in_rect.width) - tab_x;
 
     if (tab_x + clip_width > in_rect.x + in_rect.width)
         clip_width = (in_rect.x + in_rect.width) - tab_x;
 
+/*
     wxPoint clip_points[6];
     clip_points[0] = wxPoint(tab_x,              tab_y+tab_height-3);
     clip_points[1] = wxPoint(tab_x,              tab_y+2);
     wxPoint clip_points[6];
     clip_points[0] = wxPoint(tab_x,              tab_y+tab_height-3);
     clip_points[1] = wxPoint(tab_x,              tab_y+2);
@@ -408,94 +397,122 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
     clip_points[5] = wxPoint(tab_x+clip_width+1, tab_y+tab_height-3);
 
     // FIXME: these ports don't provide wxRegion ctor from array of points
     clip_points[5] = wxPoint(tab_x+clip_width+1, tab_y+tab_height-3);
 
     // FIXME: these ports don't provide wxRegion ctor from array of points
-#if !defined(__WXMGL__) && !defined(__WXDFB__)
+#if !defined(__WXDFB__) && !defined(__WXCOCOA__)
     // set the clipping region for the tab --
     wxRegion clipping_region(WXSIZEOF(clip_points), clip_points);
     dc.SetClippingRegion(clipping_region);
     // set the clipping region for the tab --
     wxRegion clipping_region(WXSIZEOF(clip_points), clip_points);
     dc.SetClippingRegion(clipping_region);
-#endif // !wxMGL && !wxDFB
+#endif // !wxDFB && !wxCocoa
+*/
+    // since the above code above doesn't play well with WXDFB or WXCOCOA,
+    // we'll just use a rectangle for the clipping region for now --
+    dc.SetClippingRegion(tab_x, tab_y, clip_width+1, tab_height-3);
 
 
-    wxPoint border_points[6];
-    border_points[0] = wxPoint(tab_x,             tab_y+tab_height-4);
-    border_points[1] = wxPoint(tab_x,             tab_y+2);
-    border_points[2] = wxPoint(tab_x+2,           tab_y);
-    border_points[3] = wxPoint(tab_x+tab_width-2, tab_y);
-    border_points[4] = wxPoint(tab_x+tab_width,   tab_y+2);
-    border_points[5] = wxPoint(tab_x+tab_width,   tab_y+tab_height-4);
 
 
+    wxPoint border_points[6];
+    if (m_flags &wxAUI_NB_BOTTOM)
+    {
+        border_points[0] = wxPoint(tab_x,             tab_y);
+        border_points[1] = wxPoint(tab_x,             tab_y+tab_height-6);
+        border_points[2] = wxPoint(tab_x+2,           tab_y+tab_height-4);
+        border_points[3] = wxPoint(tab_x+tab_width-2, tab_y+tab_height-4);
+        border_points[4] = wxPoint(tab_x+tab_width,   tab_y+tab_height-6);
+        border_points[5] = wxPoint(tab_x+tab_width,   tab_y);
+    }
+    else //if (m_flags & wxAUI_NB_TOP) {}
+    {
+        border_points[0] = wxPoint(tab_x,             tab_y+tab_height-4);
+        border_points[1] = wxPoint(tab_x,             tab_y+2);
+        border_points[2] = wxPoint(tab_x+2,           tab_y);
+        border_points[3] = wxPoint(tab_x+tab_width-2, tab_y);
+        border_points[4] = wxPoint(tab_x+tab_width,   tab_y+2);
+        border_points[5] = wxPoint(tab_x+tab_width,   tab_y+tab_height-4);
+    }
+    // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
+    // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
 
     int drawn_tab_yoff = border_points[1].y;
     int drawn_tab_height = border_points[0].y - border_points[1].y;
 
 
 
     int drawn_tab_yoff = border_points[1].y;
     int drawn_tab_height = border_points[0].y - border_points[1].y;
 
 
-    if (active)
+    if (page.active)
     {
         // draw active tab
 
         // draw base background color
         wxRect r(tab_x, tab_y, tab_width, tab_height);
     {
         // draw active tab
 
         // draw base background color
         wxRect r(tab_x, tab_y, tab_width, tab_height);
-        dc.SetPen(m_base_colour_pen);
-        dc.SetBrush(m_base_colour_brush);
-        dc.DrawRectangle(r.x, r.y, r.width, r.height);
+        dc.SetPen(wxPen(m_activeColour));
+        dc.SetBrush(wxBrush(m_activeColour));
+        dc.DrawRectangle(r.x+1, r.y+1, r.width-1, r.height-4);
 
         // this white helps fill out the gradient at the top of the tab
         dc.SetPen(*wxWHITE_PEN);
         dc.SetBrush(*wxWHITE_BRUSH);
 
         // this white helps fill out the gradient at the top of the tab
         dc.SetPen(*wxWHITE_PEN);
         dc.SetBrush(*wxWHITE_BRUSH);
-        dc.DrawRectangle(r.x+2, r.y+2, r.width-3, r.height);
+        dc.DrawRectangle(r.x+2, r.y+1, r.width-3, r.height-4);
 
         // these two points help the rounded corners appear more antialiased
 
         // these two points help the rounded corners appear more antialiased
-        dc.SetPen(m_base_colour_pen);
-        dc.DrawPoint(r.x+2, r.y+2);
-        dc.DrawPoint(r.x+r.width-2, r.y+2);
+        dc.SetPen(wxPen(m_activeColour));
+        dc.DrawPoint(r.x+2, r.y+1);
+        dc.DrawPoint(r.x+r.width-2, r.y+1);
 
         // set rectangle down a bit for gradient drawing
         r.SetHeight(r.GetHeight()/2);
         r.x += 2;
 
         // set rectangle down a bit for gradient drawing
         r.SetHeight(r.GetHeight()/2);
         r.x += 2;
-        r.width -= 2;
+        r.width -= 3;
         r.y += r.height;
         r.y += r.height;
+        r.y -= 2;
 
         // draw gradient background
 
         // draw gradient background
-        wxColor start_color = StepColour(m_base_colour, 95);
-        wxColor end_color = *wxWHITE;
-        dc.GradientFillLinear(r, start_color, end_color, wxNORTH);
+        wxColor top_color = *wxWHITE;
+        wxColor bottom_color = m_activeColour;
+        dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH);
     }
     }
-     else
+    else
     {
         // draw inactive tab
 
         wxRect r(tab_x, tab_y+1, tab_width, tab_height-3);
 
     {
         // draw inactive tab
 
         wxRect r(tab_x, tab_y+1, tab_width, tab_height-3);
 
-        // draw base background color for inactive tabs
-        dc.SetPen(m_base_colour_pen);
-        dc.SetBrush(m_base_colour_brush);
-        dc.DrawRectangle(r.x, r.y, r.width, r.height);
-
         // start the gradent up a bit and leave the inside border inset
         // by a pixel for a 3D look.  Only the top half of the inactive
         // tab will have a slight gradient
         // start the gradent up a bit and leave the inside border inset
         // by a pixel for a 3D look.  Only the top half of the inactive
         // tab will have a slight gradient
-        r.x += 2;
-        r.width -= 2;
+        r.x += 3;
+        r.y++;
+        r.width -= 4;
         r.height /= 2;
         r.height /= 2;
+        r.height--;
 
 
-        // -- draw bottom gradient fill for glossy look
-        wxColor top_color = m_base_colour;
-        wxColor bottom_color = StepColour(top_color, 106);
+        // -- draw top gradient fill for glossy look
+        wxColor top_color = m_baseColour;
+        wxColor bottom_color = top_color.ChangeLightness(160);
         dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH);
         dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH);
+
+        r.y += r.height;
+        r.y--;
+
+        // -- draw bottom fill for glossy look
+        top_color = m_baseColour;
+        bottom_color = m_baseColour;
+        dc.GradientFillLinear(r, top_color, bottom_color, wxSOUTH);
     }
 
     // draw tab outline
     }
 
     // draw tab outline
-    dc.SetPen(m_border_pen);
+    dc.SetPen(m_borderPen);
     dc.SetBrush(*wxTRANSPARENT_BRUSH);
     dc.DrawPolygon(WXSIZEOF(border_points), border_points);
 
     // there are two horizontal grey lines at the bottom of the tab control,
     // this gets rid of the top one of those lines in the tab control
     dc.SetBrush(*wxTRANSPARENT_BRUSH);
     dc.DrawPolygon(WXSIZEOF(border_points), border_points);
 
     // there are two horizontal grey lines at the bottom of the tab control,
     // this gets rid of the top one of those lines in the tab control
-    if (active)
+    if (page.active)
     {
     {
-        wxColor start_color = StepColour(m_base_colour, 93);
-        dc.SetPen(wxPen(start_color));
-        dc.DrawLine(border_points[0].x,
+        if (m_flags &wxAUI_NB_BOTTOM)
+            dc.SetPen(wxPen(m_baseColour.ChangeLightness(170)));
+        // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
+        // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
+        else //for wxAUI_NB_TOP
+            dc.SetPen(m_baseColourPen);
+        dc.DrawLine(border_points[0].x+1,
                     border_points[0].y,
                     border_points[0].y,
-                    border_points[5].x+1,
+                    border_points[5].x,
                     border_points[5].y);
     }
 
                     border_points[5].y);
     }
 
@@ -504,30 +521,31 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
     int close_button_width = 0;
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
     {
     int close_button_width = 0;
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
     {
-        close_button_width = m_active_close_bmp.GetWidth();
+        close_button_width = m_activeCloseBmp.GetWidth();
     }
 
     }
 
-
-    if (bitmap.IsOk())
+    int bitmap_offset = 0;
+    if (page.bitmap.IsOk())
     {
     {
-        int bitmap_offset = tab_x + 8;
+        bitmap_offset = tab_x + 8;
 
         // draw bitmap
 
         // draw bitmap
-        dc.DrawBitmap(bitmap,
+        dc.DrawBitmap(page.bitmap,
                       bitmap_offset,
                       bitmap_offset,
-                      drawn_tab_yoff + (drawn_tab_height/2) - (bitmap.GetHeight()/2) + 1,
+                      drawn_tab_yoff + (drawn_tab_height/2) - (page.bitmap.GetHeight()/2),
                       true);
 
                       true);
 
-        text_offset = bitmap_offset + bitmap.GetWidth();
+        text_offset = bitmap_offset + page.bitmap.GetWidth();
         text_offset += 3; // bitmap padding
         text_offset += 3; // bitmap padding
+
     }
     }
-     else
+    else
     {
         text_offset = tab_x + 8;
     }
 
 
     {
         text_offset = tab_x + 8;
     }
 
 
-    wxString draw_text = ChopText(dc,
+    wxString draw_text = wxAuiChopText(dc,
                           caption,
                           tab_width - (text_offset-tab_x) - close_button_width);
 
                           caption,
                           tab_width - (text_offset-tab_x) - close_button_width);
 
@@ -536,24 +554,51 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
                 text_offset,
                 drawn_tab_yoff + (drawn_tab_height)/2 - (texty/2) - 1);
 
                 text_offset,
                 drawn_tab_yoff + (drawn_tab_height)/2 - (texty/2) - 1);
 
+    // draw focus rectangle
+    if (page.active && (wnd->FindFocus() == wnd))
+    {
+        wxRect focusRectText(text_offset, (drawn_tab_yoff + (drawn_tab_height)/2 - (texty/2) - 1),
+            selected_textx, selected_texty);
+
+        wxRect focusRect;
+        wxRect focusRectBitmap;
+
+        if (page.bitmap.IsOk())
+            focusRectBitmap = wxRect(bitmap_offset, drawn_tab_yoff + (drawn_tab_height/2) - (page.bitmap.GetHeight()/2),
+                                            page.bitmap.GetWidth(), page.bitmap.GetHeight());
 
 
+        if (page.bitmap.IsOk() && draw_text.IsEmpty())
+            focusRect = focusRectBitmap;
+        else if (!page.bitmap.IsOk() && !draw_text.IsEmpty())
+            focusRect = focusRectText;
+        else if (page.bitmap.IsOk() && !draw_text.IsEmpty())
+            focusRect = focusRectText.Union(focusRectBitmap);
 
 
+        focusRect.Inflate(2, 2);
+
+        wxRendererNative::Get().DrawFocusRect(wnd, dc, focusRect, 0);
+    }
 
     // draw close button if necessary
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
     {
 
     // draw close button if necessary
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
     {
-        wxBitmap bmp = m_disabled_close_bmp;
+        wxBitmap bmp = m_disabledCloseBmp;
 
         if (close_button_state == wxAUI_BUTTON_STATE_HOVER ||
             close_button_state == wxAUI_BUTTON_STATE_PRESSED)
         {
 
         if (close_button_state == wxAUI_BUTTON_STATE_HOVER ||
             close_button_state == wxAUI_BUTTON_STATE_PRESSED)
         {
-            bmp = m_active_close_bmp;
+            bmp = m_activeCloseBmp;
         }
 
         }
 
+        int offsetY = tab_y-1;
+        if (m_flags & wxAUI_NB_BOTTOM)
+            offsetY = 1;
+
         wxRect rect(tab_x + tab_width - close_button_width - 1,
         wxRect rect(tab_x + tab_width - close_button_width - 1,
-                    tab_y + (tab_height/2) - (bmp.GetHeight()/2),
+                    offsetY + (tab_height/2) - (bmp.GetHeight()/2),
                     close_button_width,
                     tab_height);
                     close_button_width,
                     tab_height);
+
         IndentPressedBitmap(&rect, close_button_state);
         dc.DrawBitmap(bmp, rect.x, rect.y, true);
 
         IndentPressedBitmap(&rect, close_button_state);
         dc.DrawBitmap(bmp, rect.x, rect.y, true);
 
@@ -580,7 +625,7 @@ wxSize wxAuiDefaultTabArt::GetTabSize(wxDC& dc,
 {
     wxCoord measured_textx, measured_texty, tmp;
 
 {
     wxCoord measured_textx, measured_texty, tmp;
 
-    dc.SetFont(m_measuring_font);
+    dc.SetFont(m_measuringFont);
     dc.GetTextExtent(caption, &measured_textx, &measured_texty);
 
     dc.GetTextExtent(wxT("ABCDEFXj"), &tmp, &measured_texty);
     dc.GetTextExtent(caption, &measured_textx, &measured_texty);
 
     dc.GetTextExtent(wxT("ABCDEFXj"), &tmp, &measured_texty);
@@ -591,7 +636,7 @@ wxSize wxAuiDefaultTabArt::GetTabSize(wxDC& dc,
 
     // if the close button is showing, add space for it
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
 
     // if the close button is showing, add space for it
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
-        tab_width += m_active_close_bmp.GetWidth() + 3;
+        tab_width += m_activeCloseBmp.GetWidth() + 3;
 
     // if there's a bitmap, add space for it
     if (bitmap.IsOk())
 
     // if there's a bitmap, add space for it
     if (bitmap.IsOk())
@@ -607,7 +652,7 @@ wxSize wxAuiDefaultTabArt::GetTabSize(wxDC& dc,
 
     if (m_flags & wxAUI_NB_TAB_FIXED_WIDTH)
     {
 
     if (m_flags & wxAUI_NB_TAB_FIXED_WIDTH)
     {
-        tab_width = m_fixed_tab_width;
+        tab_width = m_fixedTabWidth;
     }
 
     *x_extent = tab_width;
     }
 
     *x_extent = tab_width;
@@ -622,47 +667,40 @@ void wxAuiDefaultTabArt::DrawButton(wxDC& dc,
                                     int bitmap_id,
                                     int button_state,
                                     int orientation,
                                     int bitmap_id,
                                     int button_state,
                                     int orientation,
-                                    const wxBitmap& bitmap_override,
                                     wxRect* out_rect)
 {
     wxBitmap bmp;
     wxRect rect;
 
                                     wxRect* out_rect)
 {
     wxBitmap bmp;
     wxRect rect;
 
-    if (bitmap_override.IsOk())
+    switch (bitmap_id)
     {
     {
-        bmp = bitmap_override;
-    }
-     else
-    {
-        switch (bitmap_id)
-        {
-            case wxAUI_BUTTON_CLOSE:
-                if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                    bmp = m_disabled_close_bmp;
-                     else
-                    bmp = m_active_close_bmp;
-                break;
-            case wxAUI_BUTTON_LEFT:
-                if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                    bmp = m_disabled_left_bmp;
-                     else
-                    bmp = m_active_left_bmp;
-                break;
-            case wxAUI_BUTTON_RIGHT:
-                if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                    bmp = m_disabled_right_bmp;
-                     else
-                    bmp = m_active_right_bmp;
-                break;
-            case wxAUI_BUTTON_WINDOWLIST:
-                if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                    bmp = m_disabled_windowlist_bmp;
-                     else
-                    bmp = m_active_windowlist_bmp;
-                break;
-        }
+        case wxAUI_BUTTON_CLOSE:
+            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
+                bmp = m_disabledCloseBmp;
+            else
+                bmp = m_activeCloseBmp;
+            break;
+        case wxAUI_BUTTON_LEFT:
+            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
+                bmp = m_disabledLeftBmp;
+            else
+                bmp = m_activeLeftBmp;
+            break;
+        case wxAUI_BUTTON_RIGHT:
+            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
+                bmp = m_disabledRightBmp;
+            else
+                bmp = m_activeRightBmp;
+            break;
+        case wxAUI_BUTTON_WINDOWLIST:
+            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
+                bmp = m_disabledWindowListBmp;
+            else
+                bmp = m_activeWindowListBmp;
+            break;
     }
 
     }
 
+
     if (!bmp.IsOk())
         return;
 
     if (!bmp.IsOk())
         return;
 
@@ -675,7 +713,7 @@ void wxAuiDefaultTabArt::DrawButton(wxDC& dc,
         rect.SetWidth(bmp.GetWidth());
         rect.SetHeight(bmp.GetHeight());
     }
         rect.SetWidth(bmp.GetWidth());
         rect.SetHeight(bmp.GetHeight());
     }
-     else
+    else
     {
         rect = wxRect(in_rect.x + in_rect.width - bmp.GetWidth(),
                       ((in_rect.y + in_rect.height)/2) - (bmp.GetHeight()/2),
     {
         rect = wxRect(in_rect.x + in_rect.width - bmp.GetWidth(),
                       ((in_rect.y + in_rect.height)/2) - (bmp.GetHeight()/2),
@@ -688,33 +726,32 @@ void wxAuiDefaultTabArt::DrawButton(wxDC& dc,
     *out_rect = rect;
 }
 
     *out_rect = rect;
 }
 
-
-int wxAuiDefaultTabArt::ShowWindowList(wxWindow* wnd,
-                                       const wxArrayString& items,
-                                       int active_idx)
+int wxAuiDefaultTabArt::ShowDropDown(wxWindow* wnd,
+                                     const wxAuiNotebookPageArray& pages,
+                                     int /*active_idx*/)
 {
 {
-       wxMenu menuPopup;
+    wxMenu menuPopup;
 
 
-    size_t i, count = items.GetCount();
+    size_t i, count = pages.GetCount();
     for (i = 0; i < count; ++i)
     {
     for (i = 0; i < count; ++i)
     {
-        menuPopup.AppendCheckItem(1000+i, items.Item(i));
-    }
-
-    if (active_idx != -1)
-    {
-        menuPopup.Check(1000+active_idx, true);
+        const wxAuiNotebookPage& page = pages.Item(i);
+        wxString caption = page.caption;
+
+        // if there is no caption, make it a space.  This will prevent
+        // an assert in the menu code.
+        if (caption.IsEmpty())
+            caption = wxT(" ");
+
+        wxMenuItem* item = new wxMenuItem(NULL, 1000+i, caption);
+        if (page.bitmap.IsOk())
+            item->SetBitmap(page.bitmap);
+        menuPopup.Append(item);
     }
 
     }
 
-    // find out where to put the popup menu of window
-    // items.  Subtract 100 for now to center the menu
-    // a bit, until a better mechanism can be implemented
+    // find out where to put the popup menu of window items
     wxPoint pt = ::wxGetMousePosition();
     pt = wnd->ScreenToClient(pt);
     wxPoint pt = ::wxGetMousePosition();
     pt = wnd->ScreenToClient(pt);
-    if (pt.x < 100)
-        pt.x = 0;
-         else
-        pt.x -= 100;
 
     // find out the screen coordinate at the bottom of the tab ctrl
     wxRect cli_rect = wnd->GetClientRect();
 
     // find out the screen coordinate at the bottom of the tab ctrl
     wxRect cli_rect = wnd->GetClientRect();
@@ -733,10 +770,22 @@ int wxAuiDefaultTabArt::ShowWindowList(wxWindow* wnd,
 }
 
 int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd,
 }
 
 int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd,
-                                           wxAuiNotebookPageArray& pages)
+                                           const wxAuiNotebookPageArray& pages,
+                                           const wxSize& requiredBmp_size)
 {
     wxClientDC dc(wnd);
 {
     wxClientDC dc(wnd);
-    dc.SetFont(m_measuring_font);
+    dc.SetFont(m_measuringFont);
+
+    // sometimes a standard bitmap size needs to be enforced, especially
+    // if some tabs have bitmaps and others don't.  This is important because
+    // it prevents the tab control from resizing when tabs are added.
+    wxBitmap measureBmp;
+    if (requiredBmp_size.IsFullySpecified())
+    {
+        measureBmp.Create(requiredBmp_size.x,
+                           requiredBmp_size.y);
+    }
+
 
     int max_y = 0;
     size_t i, page_count = pages.GetCount();
 
     int max_y = 0;
     size_t i, page_count = pages.GetCount();
@@ -744,6 +793,12 @@ int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd,
     {
         wxAuiNotebookPage& page = pages.Item(i);
 
     {
         wxAuiNotebookPage& page = pages.Item(i);
 
+        wxBitmap bmp;
+        if (measureBmp.IsOk())
+            bmp = measureBmp;
+        else
+            bmp = page.bitmap;
+
         // we don't use the caption text because we don't
         // want tab heights to be different in the case
         // of a very short piece of text on one tab and a very
         // we don't use the caption text because we don't
         // want tab heights to be different in the case
         // of a very short piece of text on one tab and a very
@@ -752,10 +807,11 @@ int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd,
         wxSize s = GetTabSize(dc,
                               wnd,
                               wxT("ABCDEFGHIj"),
         wxSize s = GetTabSize(dc,
                               wnd,
                               wxT("ABCDEFGHIj"),
-                              page.bitmap,
+                              bmp,
                               true,
                               wxAUI_BUTTON_STATE_HIDDEN,
                               &x_ext);
                               true,
                               wxAUI_BUTTON_STATE_HIDDEN,
                               &x_ext);
+
         max_y = wxMax(max_y, s.y);
     }
 
         max_y = wxMax(max_y, s.y);
     }
 
@@ -764,55 +820,67 @@ int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd,
 
 void wxAuiDefaultTabArt::SetNormalFont(const wxFont& font)
 {
 
 void wxAuiDefaultTabArt::SetNormalFont(const wxFont& font)
 {
-    m_normal_font = font;
+    m_normalFont = font;
 }
 
 void wxAuiDefaultTabArt::SetSelectedFont(const wxFont& font)
 {
 }
 
 void wxAuiDefaultTabArt::SetSelectedFont(const wxFont& font)
 {
-    m_selected_font = font;
+    m_selectedFont = font;
 }
 
 void wxAuiDefaultTabArt::SetMeasuringFont(const wxFont& font)
 {
 }
 
 void wxAuiDefaultTabArt::SetMeasuringFont(const wxFont& font)
 {
-    m_measuring_font = font;
+    m_measuringFont = font;
 }
 
 }
 
+void wxAuiDefaultTabArt::SetColour(const wxColour& colour)
+{
+    m_baseColour = colour;
+    m_borderPen = wxPen(m_baseColour.ChangeLightness(75));
+    m_baseColourPen = wxPen(m_baseColour);
+    m_baseColourBrush = wxBrush(m_baseColour);
+}
+
+void wxAuiDefaultTabArt::SetActiveColour(const wxColour& colour)
+{
+    m_activeColour = colour;
+}
 
 // -- wxAuiSimpleTabArt class implementation --
 
 wxAuiSimpleTabArt::wxAuiSimpleTabArt()
 {
 
 // -- wxAuiSimpleTabArt class implementation --
 
 wxAuiSimpleTabArt::wxAuiSimpleTabArt()
 {
-    m_normal_font = *wxNORMAL_FONT;
-    m_selected_font = *wxNORMAL_FONT;
-    m_selected_font.SetWeight(wxBOLD);
-    m_measuring_font = m_selected_font;
+    m_normalFont = *wxNORMAL_FONT;
+    m_selectedFont = *wxNORMAL_FONT;
+    m_selectedFont.SetWeight(wxBOLD);
+    m_measuringFont = m_selectedFont;
 
     m_flags = 0;
 
     m_flags = 0;
-    m_fixed_tab_width = 100;
+    m_fixedTabWidth = 100;
 
 
-    wxColour base_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
+    wxColour baseColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
 
 
-    wxColour background_colour = StepColour(base_colour, 95);
-    wxColour normaltab_colour = base_colour;
-    wxColour selectedtab_colour = *wxWHITE;
+    wxColour backgroundColour = baseColour;
+    wxColour normaltabColour = baseColour;
+    wxColour selectedtabColour = *wxWHITE;
 
 
-    m_bkbrush = wxBrush(background_colour);
-    m_normal_bkbrush = wxBrush(normaltab_colour);
-    m_normal_bkpen = wxPen(normaltab_colour);
-    m_selected_bkbrush = wxBrush(selectedtab_colour);
-    m_selected_bkpen = wxPen(selectedtab_colour);
+    m_bkBrush = wxBrush(backgroundColour);
+    m_normalBkBrush = wxBrush(normaltabColour);
+    m_normalBkPen = wxPen(normaltabColour);
+    m_selectedBkBrush = wxBrush(selectedtabColour);
+    m_selectedBkPen = wxPen(selectedtabColour);
 
 
-    m_active_close_bmp = BitmapFromBits(close_bits, 16, 16, *wxBLACK);
-    m_disabled_close_bmp = BitmapFromBits(close_bits, 16, 16, wxColour(128,128,128));
+    m_activeCloseBmp = wxAuiBitmapFromBits(close_bits, 16, 16, *wxBLACK);
+    m_disabledCloseBmp = wxAuiBitmapFromBits(close_bits, 16, 16, wxColour(128,128,128));
 
 
-    m_active_left_bmp = BitmapFromBits(left_bits, 16, 16, *wxBLACK);
-    m_disabled_left_bmp = BitmapFromBits(left_bits, 16, 16, wxColour(128,128,128));
+    m_activeLeftBmp = wxAuiBitmapFromBits(left_bits, 16, 16, *wxBLACK);
+    m_disabledLeftBmp = wxAuiBitmapFromBits(left_bits, 16, 16, wxColour(128,128,128));
 
 
-    m_active_right_bmp = BitmapFromBits(right_bits, 16, 16, *wxBLACK);
-    m_disabled_right_bmp = BitmapFromBits(right_bits, 16, 16, wxColour(128,128,128));
+    m_activeRightBmp = wxAuiBitmapFromBits(right_bits, 16, 16, *wxBLACK);
+    m_disabledRightBmp = wxAuiBitmapFromBits(right_bits, 16, 16, wxColour(128,128,128));
 
 
-    m_active_windowlist_bmp = BitmapFromBits(list_bits, 16, 16, *wxBLACK);
-    m_disabled_windowlist_bmp = BitmapFromBits(list_bits, 16, 16, wxColour(128,128,128));
+    m_activeWindowListBmp = wxAuiBitmapFromBits(list_bits, 16, 16, *wxBLACK);
+    m_disabledWindowListBmp = wxAuiBitmapFromBits(list_bits, 16, 16, wxColour(128,128,128));
 
 }
 
 
 }
 
@@ -822,10 +890,9 @@ wxAuiSimpleTabArt::~wxAuiSimpleTabArt()
 
 wxAuiTabArt* wxAuiSimpleTabArt::Clone()
 {
 
 wxAuiTabArt* wxAuiSimpleTabArt::Clone()
 {
-    return static_cast<wxAuiTabArt*>(new wxAuiSimpleTabArt);
+    return new wxAuiSimpleTabArt(*this);
 }
 
 }
 
-
 void wxAuiSimpleTabArt::SetFlags(unsigned int flags)
 {
     m_flags = flags;
 void wxAuiSimpleTabArt::SetFlags(unsigned int flags)
 {
     m_flags = flags;
@@ -834,29 +901,42 @@ void wxAuiSimpleTabArt::SetFlags(unsigned int flags)
 void wxAuiSimpleTabArt::SetSizingInfo(const wxSize& tab_ctrl_size,
                                       size_t tab_count)
 {
 void wxAuiSimpleTabArt::SetSizingInfo(const wxSize& tab_ctrl_size,
                                       size_t tab_count)
 {
-    m_fixed_tab_width = 100;
+    m_fixedTabWidth = 100;
 
     int tot_width = (int)tab_ctrl_size.x - GetIndentSize() - 4;
 
     if (m_flags & wxAUI_NB_CLOSE_BUTTON)
 
     int tot_width = (int)tab_ctrl_size.x - GetIndentSize() - 4;
 
     if (m_flags & wxAUI_NB_CLOSE_BUTTON)
-        tot_width -= m_active_close_bmp.GetWidth();
+        tot_width -= m_activeCloseBmp.GetWidth();
     if (m_flags & wxAUI_NB_WINDOWLIST_BUTTON)
     if (m_flags & wxAUI_NB_WINDOWLIST_BUTTON)
-        tot_width -= m_active_windowlist_bmp.GetWidth();
+        tot_width -= m_activeWindowListBmp.GetWidth();
 
     if (tab_count > 0)
     {
 
     if (tab_count > 0)
     {
-        m_fixed_tab_width = tot_width/(int)tab_count;
+        m_fixedTabWidth = tot_width/(int)tab_count;
     }
 
 
     }
 
 
-    if (m_fixed_tab_width < 100)
-        m_fixed_tab_width = 100;
+    if (m_fixedTabWidth < 100)
+        m_fixedTabWidth = 100;
+
+    if (m_fixedTabWidth > tot_width/2)
+        m_fixedTabWidth = tot_width/2;
+
+    if (m_fixedTabWidth > 220)
+        m_fixedTabWidth = 220;
+}
 
 
-    if (m_fixed_tab_width > tot_width/2)
-        m_fixed_tab_width = tot_width/2;
+void wxAuiSimpleTabArt::SetColour(const wxColour& colour)
+{
+    m_bkBrush = wxBrush(colour);
+    m_normalBkBrush = wxBrush(colour);
+    m_normalBkPen = wxPen(colour);
+}
 
 
-    if (m_fixed_tab_width > 220)
-        m_fixed_tab_width = 220;
+void wxAuiSimpleTabArt::SetActiveColour(const wxColour& colour)
+{
+    m_selectedBkBrush = wxBrush(colour);
+    m_selectedBkPen = wxPen(colour);
 }
 
 void wxAuiSimpleTabArt::DrawBackground(wxDC& dc,
 }
 
 void wxAuiSimpleTabArt::DrawBackground(wxDC& dc,
@@ -864,7 +944,7 @@ void wxAuiSimpleTabArt::DrawBackground(wxDC& dc,
                                        const wxRect& rect)
 {
     // draw background
                                        const wxRect& rect)
 {
     // draw background
-    dc.SetBrush(m_bkbrush);
+    dc.SetBrush(m_bkBrush);
     dc.SetPen(*wxTRANSPARENT_PEN);
     dc.DrawRectangle(-1, -1, rect.GetWidth()+2, rect.GetHeight()+2);
 
     dc.SetPen(*wxTRANSPARENT_PEN);
     dc.DrawRectangle(-1, -1, rect.GetWidth()+2, rect.GetHeight()+2);
 
@@ -885,10 +965,8 @@ void wxAuiSimpleTabArt::DrawBackground(wxDC& dc,
 
 void wxAuiSimpleTabArt::DrawTab(wxDC& dc,
                                 wxWindow* wnd,
 
 void wxAuiSimpleTabArt::DrawTab(wxDC& dc,
                                 wxWindow* wnd,
+                                const wxAuiNotebookPage& page,
                                 const wxRect& in_rect,
                                 const wxRect& in_rect,
-                                const wxString& caption_text,
-                                const wxBitmap& bitmap,
-                                bool active,
                                 int close_button_state,
                                 wxRect* out_tab_rect,
                                 wxRect* out_button_rect,
                                 int close_button_state,
                                 wxRect* out_tab_rect,
                                 wxRect* out_button_rect,
@@ -899,22 +977,22 @@ void wxAuiSimpleTabArt::DrawTab(wxDC& dc,
     wxCoord textx, texty;
 
     // if the caption is empty, measure some temporary text
     wxCoord textx, texty;
 
     // if the caption is empty, measure some temporary text
-    wxString caption = caption_text;
-    if (caption_text.empty())
+    wxString caption = page.caption;
+    if (caption.empty())
         caption = wxT("Xj");
 
         caption = wxT("Xj");
 
-    dc.SetFont(m_selected_font);
+    dc.SetFont(m_selectedFont);
     dc.GetTextExtent(caption, &selected_textx, &selected_texty);
 
     dc.GetTextExtent(caption, &selected_textx, &selected_texty);
 
-    dc.SetFont(m_normal_font);
+    dc.SetFont(m_normalFont);
     dc.GetTextExtent(caption, &normal_textx, &normal_texty);
 
     // figure out the size of the tab
     wxSize tab_size = GetTabSize(dc,
                                  wnd,
     dc.GetTextExtent(caption, &normal_textx, &normal_texty);
 
     // figure out the size of the tab
     wxSize tab_size = GetTabSize(dc,
                                  wnd,
-                                 caption,
-                                 bitmap,
-                                 active,
+                                 page.caption,
+                                 page.bitmap,
+                                 page.active,
                                  close_button_state,
                                  x_extent);
 
                                  close_button_state,
                                  x_extent);
 
@@ -923,23 +1001,23 @@ void wxAuiSimpleTabArt::DrawTab(wxDC& dc,
     wxCoord tab_x = in_rect.x;
     wxCoord tab_y = in_rect.y + in_rect.height - tab_height;
 
     wxCoord tab_x = in_rect.x;
     wxCoord tab_y = in_rect.y + in_rect.height - tab_height;
 
-    caption = caption_text;
+    caption = page.caption;
 
     // select pen, brush and font for the tab to be drawn
 
 
     // select pen, brush and font for the tab to be drawn
 
-    if (active)
+    if (page.active)
     {
     {
-        dc.SetPen(m_selected_bkpen);
-        dc.SetBrush(m_selected_bkbrush);
-        dc.SetFont(m_selected_font);
+        dc.SetPen(m_selectedBkPen);
+        dc.SetBrush(m_selectedBkBrush);
+        dc.SetFont(m_selectedFont);
         textx = selected_textx;
         texty = selected_texty;
     }
         textx = selected_textx;
         texty = selected_texty;
     }
-     else
+    else
     {
     {
-        dc.SetPen(m_normal_bkpen);
-        dc.SetBrush(m_normal_bkbrush);
-        dc.SetFont(m_normal_font);
+        dc.SetPen(m_normalBkPen);
+        dc.SetBrush(m_normalBkBrush);
+        dc.SetFont(m_normalFont);
         textx = normal_textx;
         texty = normal_texty;
     }
         textx = normal_textx;
         texty = normal_texty;
     }
@@ -977,10 +1055,10 @@ void wxAuiSimpleTabArt::DrawTab(wxDC& dc,
     int close_button_width = 0;
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
     {
     int close_button_width = 0;
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
     {
-        close_button_width = m_active_close_bmp.GetWidth();
+        close_button_width = m_activeCloseBmp.GetWidth();
         text_offset = tab_x + (tab_height/2) + ((tab_width-close_button_width)/2) - (textx/2);
     }
         text_offset = tab_x + (tab_height/2) + ((tab_width-close_button_width)/2) - (textx/2);
     }
-     else
+    else
     {
         text_offset = tab_x + (tab_height/3) + (tab_width/2) - (textx/2);
     }
     {
         text_offset = tab_x + (tab_height/3) + (tab_width/2) - (textx/2);
     }
@@ -990,7 +1068,7 @@ void wxAuiSimpleTabArt::DrawTab(wxDC& dc,
         text_offset = tab_x + tab_height;
 
     // chop text if necessary
         text_offset = tab_x + tab_height;
 
     // chop text if necessary
-    wxString draw_text = ChopText(dc,
+    wxString draw_text = wxAuiChopText(dc,
                           caption,
                           tab_width - (text_offset-tab_x) - close_button_width);
 
                           caption,
                           tab_width - (text_offset-tab_x) - close_button_width);
 
@@ -1000,14 +1078,25 @@ void wxAuiSimpleTabArt::DrawTab(wxDC& dc,
                  (tab_y + tab_height)/2 - (texty/2) + 1);
 
 
                  (tab_y + tab_height)/2 - (texty/2) + 1);
 
 
+    // draw focus rectangle
+    if (page.active && (wnd->FindFocus() == wnd))
+    {
+        wxRect focusRect(text_offset, ((tab_y + tab_height)/2 - (texty/2) + 1),
+            selected_textx, selected_texty);
+
+        focusRect.Inflate(2, 2);
+
+        wxRendererNative::Get().DrawFocusRect(wnd, dc, focusRect, 0);
+    }
+
     // draw close button if necessary
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
     {
         wxBitmap bmp;
     // draw close button if necessary
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
     {
         wxBitmap bmp;
-        if (active)
-            bmp = m_active_close_bmp;
-             else
-            bmp = m_disabled_close_bmp;
+        if (page.active)
+            bmp = m_activeCloseBmp;
+        else
+            bmp = m_disabledCloseBmp;
 
         wxRect rect(tab_x + tab_width - close_button_width - 1,
                     tab_y + (tab_height/2) - (bmp.GetHeight()/2) + 1,
 
         wxRect rect(tab_x + tab_width - close_button_width - 1,
                     tab_y + (tab_height/2) - (bmp.GetHeight()/2) + 1,
@@ -1039,18 +1128,18 @@ wxSize wxAuiSimpleTabArt::GetTabSize(wxDC& dc,
 {
     wxCoord measured_textx, measured_texty;
 
 {
     wxCoord measured_textx, measured_texty;
 
-    dc.SetFont(m_measuring_font);
+    dc.SetFont(m_measuringFont);
     dc.GetTextExtent(caption, &measured_textx, &measured_texty);
 
     wxCoord tab_height = measured_texty + 4;
     wxCoord tab_width = measured_textx + tab_height + 5;
 
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
     dc.GetTextExtent(caption, &measured_textx, &measured_texty);
 
     wxCoord tab_height = measured_texty + 4;
     wxCoord tab_width = measured_textx + tab_height + 5;
 
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
-        tab_width += m_active_close_bmp.GetWidth();
+        tab_width += m_activeCloseBmp.GetWidth();
 
     if (m_flags & wxAUI_NB_TAB_FIXED_WIDTH)
     {
 
     if (m_flags & wxAUI_NB_TAB_FIXED_WIDTH)
     {
-        tab_width = m_fixed_tab_width;
+        tab_width = m_fixedTabWidth;
     }
 
     *x_extent = tab_width - (tab_height/2) - 1;
     }
 
     *x_extent = tab_width - (tab_height/2) - 1;
@@ -1065,45 +1154,37 @@ void wxAuiSimpleTabArt::DrawButton(wxDC& dc,
                                    int bitmap_id,
                                    int button_state,
                                    int orientation,
                                    int bitmap_id,
                                    int button_state,
                                    int orientation,
-                                   const wxBitmap& bitmap_override,
                                    wxRect* out_rect)
 {
     wxBitmap bmp;
     wxRect rect;
 
                                    wxRect* out_rect)
 {
     wxBitmap bmp;
     wxRect rect;
 
-    if (bitmap_override.IsOk())
-    {
-        bmp = bitmap_override;
-    }
-     else
+    switch (bitmap_id)
     {
     {
-        switch (bitmap_id)
-        {
-            case wxAUI_BUTTON_CLOSE:
-                if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                    bmp = m_disabled_close_bmp;
-                     else
-                    bmp = m_active_close_bmp;
-                break;
-            case wxAUI_BUTTON_LEFT:
-                if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                    bmp = m_disabled_left_bmp;
-                     else
-                    bmp = m_active_left_bmp;
-                break;
-            case wxAUI_BUTTON_RIGHT:
-                if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                    bmp = m_disabled_right_bmp;
-                     else
-                    bmp = m_active_right_bmp;
-                break;
-            case wxAUI_BUTTON_WINDOWLIST:
-                if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                    bmp = m_disabled_windowlist_bmp;
-                     else
-                    bmp = m_active_windowlist_bmp;
-                break;
-        }
+        case wxAUI_BUTTON_CLOSE:
+            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
+                bmp = m_disabledCloseBmp;
+            else
+                bmp = m_activeCloseBmp;
+            break;
+        case wxAUI_BUTTON_LEFT:
+            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
+                bmp = m_disabledLeftBmp;
+            else
+                bmp = m_activeLeftBmp;
+            break;
+        case wxAUI_BUTTON_RIGHT:
+            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
+                bmp = m_disabledRightBmp;
+            else
+                bmp = m_activeRightBmp;
+            break;
+        case wxAUI_BUTTON_WINDOWLIST:
+            if (button_state & wxAUI_BUTTON_STATE_DISABLED)
+                bmp = m_disabledWindowListBmp;
+            else
+                bmp = m_activeWindowListBmp;
+            break;
     }
 
     if (!bmp.IsOk())
     }
 
     if (!bmp.IsOk())
@@ -1118,7 +1199,7 @@ void wxAuiSimpleTabArt::DrawButton(wxDC& dc,
         rect.SetWidth(bmp.GetWidth());
         rect.SetHeight(bmp.GetHeight());
     }
         rect.SetWidth(bmp.GetWidth());
         rect.SetHeight(bmp.GetHeight());
     }
-     else
+    else
     {
         rect = wxRect(in_rect.x + in_rect.width - bmp.GetWidth(),
                       ((in_rect.y + in_rect.height)/2) - (bmp.GetHeight()/2),
     {
         rect = wxRect(in_rect.x + in_rect.width - bmp.GetWidth(),
                       ((in_rect.y + in_rect.height)/2) - (bmp.GetHeight()/2),
@@ -1131,17 +1212,17 @@ void wxAuiSimpleTabArt::DrawButton(wxDC& dc,
     *out_rect = rect;
 }
 
     *out_rect = rect;
 }
 
-
-int wxAuiSimpleTabArt::ShowWindowList(wxWindow* wnd,
-                                      const wxArrayString& items,
-                                      int active_idx)
+int wxAuiSimpleTabArt::ShowDropDown(wxWindow* wnd,
+                                    const wxAuiNotebookPageArray& pages,
+                                    int active_idx)
 {
 {
-       wxMenu menuPopup;
+    wxMenu menuPopup;
 
 
-    size_t i, count = items.GetCount();
+    size_t i, count = pages.GetCount();
     for (i = 0; i < count; ++i)
     {
     for (i = 0; i < count; ++i)
     {
-        menuPopup.AppendCheckItem(1000+i, items.Item(i));
+        const wxAuiNotebookPage& page = pages.Item(i);
+        menuPopup.AppendCheckItem(1000+i, page.caption);
     }
 
     if (active_idx != -1)
     }
 
     if (active_idx != -1)
@@ -1156,7 +1237,7 @@ int wxAuiSimpleTabArt::ShowWindowList(wxWindow* wnd,
     pt = wnd->ScreenToClient(pt);
     if (pt.x < 100)
         pt.x = 0;
     pt = wnd->ScreenToClient(pt);
     if (pt.x < 100)
         pt.x = 0;
-         else
+    else
         pt.x -= 100;
 
     // find out the screen coordinate at the bottom of the tab ctrl
         pt.x -= 100;
 
     // find out the screen coordinate at the bottom of the tab ctrl
@@ -1176,10 +1257,11 @@ int wxAuiSimpleTabArt::ShowWindowList(wxWindow* wnd,
 }
 
 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow* wnd,
 }
 
 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow* wnd,
-                                          wxAuiNotebookPageArray& WXUNUSED(pages))
+                                          const wxAuiNotebookPageArray& WXUNUSED(pages),
+                                          const wxSize& WXUNUSED(requiredBmp_size))
 {
     wxClientDC dc(wnd);
 {
     wxClientDC dc(wnd);
-    dc.SetFont(m_measuring_font);
+    dc.SetFont(m_measuringFont);
     int x_ext = 0;
     wxSize s = GetTabSize(dc,
                           wnd,
     int x_ext = 0;
     wxSize s = GetTabSize(dc,
                           wnd,
@@ -1193,17 +1275,17 @@ int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow* wnd,
 
 void wxAuiSimpleTabArt::SetNormalFont(const wxFont& font)
 {
 
 void wxAuiSimpleTabArt::SetNormalFont(const wxFont& font)
 {
-    m_normal_font = font;
+    m_normalFont = font;
 }
 
 void wxAuiSimpleTabArt::SetSelectedFont(const wxFont& font)
 {
 }
 
 void wxAuiSimpleTabArt::SetSelectedFont(const wxFont& font)
 {
-    m_selected_font = font;
+    m_selectedFont = font;
 }
 
 void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont& font)
 {
 }
 
 void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont& font)
 {
-    m_measuring_font = font;
+    m_measuringFont = font;
 }
 
 
 }
 
 
@@ -1224,7 +1306,7 @@ void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont& font)
 
 wxAuiTabContainer::wxAuiTabContainer()
 {
 
 wxAuiTabContainer::wxAuiTabContainer()
 {
-    m_tab_offset = 0;
+    m_tabOffset = 0;
     m_flags = 0;
     m_art = new wxAuiDefaultTabArt;
 
     m_flags = 0;
     m_art = new wxAuiDefaultTabArt;
 
@@ -1309,6 +1391,16 @@ void wxAuiTabContainer::SetMeasuringFont(const wxFont& font)
     m_art->SetMeasuringFont(font);
 }
 
     m_art->SetMeasuringFont(font);
 }
 
+void wxAuiTabContainer::SetColour(const wxColour& colour)
+{
+    m_art->SetColour(colour);
+}
+
+void wxAuiTabContainer::SetActiveColour(const wxColour& colour)
+{
+    m_art->SetActiveColour(colour);
+}
+
 void wxAuiTabContainer::SetRect(const wxRect& rect)
 {
     m_rect = rect;
 void wxAuiTabContainer::SetRect(const wxRect& rect)
 {
     m_rect = rect;
@@ -1347,7 +1439,7 @@ bool wxAuiTabContainer::InsertPage(wxWindow* page,
 
     if (idx >= m_pages.GetCount())
         m_pages.Add(page_info);
 
     if (idx >= m_pages.GetCount())
         m_pages.Add(page_info);
-         else
+    else
         m_pages.Insert(page_info, idx);
 
     // let the art provider know how many pages we have
         m_pages.Insert(page_info, idx);
 
     // let the art provider know how many pages we have
@@ -1414,7 +1506,7 @@ bool wxAuiTabContainer::SetActivePage(wxWindow* wnd)
             page.active = true;
             found = true;
         }
             page.active = true;
             found = true;
         }
-         else
+        else
         {
             page.active = false;
         }
         {
             page.active = false;
         }
@@ -1464,14 +1556,14 @@ wxWindow* wxAuiTabContainer::GetWindowFromIdx(size_t idx) const
 
 int wxAuiTabContainer::GetIdxFromWindow(wxWindow* wnd) const
 {
 
 int wxAuiTabContainer::GetIdxFromWindow(wxWindow* wnd) const
 {
-    size_t i, page_count = m_pages.GetCount();
-    for (i = 0; i < page_count; ++i)
+    const size_t page_count = m_pages.GetCount();
+    for ( size_t i = 0; i < page_count; ++i )
     {
         wxAuiNotebookPage& page = m_pages.Item(i);
         if (page.window == wnd)
             return i;
     }
     {
         wxAuiNotebookPage& page = m_pages.Item(i);
         if (page.window == wnd)
             return i;
     }
-    return -1;
+    return wxNOT_FOUND;
 }
 
 wxAuiNotebookPage& wxAuiTabContainer::GetPage(size_t idx)
 }
 
 wxAuiNotebookPage& wxAuiTabContainer::GetPage(size_t idx)
@@ -1481,6 +1573,13 @@ wxAuiNotebookPage& wxAuiTabContainer::GetPage(size_t idx)
     return m_pages[idx];
 }
 
     return m_pages[idx];
 }
 
+const wxAuiNotebookPage& wxAuiTabContainer::GetPage(size_t idx) const
+{
+    wxASSERT_MSG(idx < m_pages.GetCount(), wxT("Invalid Page index"));
+
+    return m_pages[idx];
+}
+
 wxAuiNotebookPageArray& wxAuiTabContainer::GetPages()
 {
     return m_pages;
 wxAuiNotebookPageArray& wxAuiTabContainer::GetPages()
 {
     return m_pages;
@@ -1493,15 +1592,15 @@ size_t wxAuiTabContainer::GetPageCount() const
 
 void wxAuiTabContainer::AddButton(int id,
                                   int location,
 
 void wxAuiTabContainer::AddButton(int id,
                                   int location,
-                                  const wxBitmap& normal_bitmap,
-                                  const wxBitmap& disabled_bitmap)
+                                  const wxBitmap& normalBitmap,
+                                  const wxBitmap& disabledBitmap)
 {
     wxAuiTabContainerButton button;
     button.id = id;
 {
     wxAuiTabContainerButton button;
     button.id = id;
-    button.bitmap = normal_bitmap;
-    button.dis_bitmap = disabled_bitmap;
+    button.bitmap = normalBitmap;
+    button.disBitmap = disabledBitmap;
     button.location = location;
     button.location = location;
-    button.cur_state = wxAUI_BUTTON_STATE_NORMAL;
+    button.curState = wxAUI_BUTTON_STATE_NORMAL;
 
     m_buttons.Add(button);
 }
 
     m_buttons.Add(button);
 }
@@ -1524,12 +1623,12 @@ void wxAuiTabContainer::RemoveButton(int id)
 
 size_t wxAuiTabContainer::GetTabOffset() const
 {
 
 size_t wxAuiTabContainer::GetTabOffset() const
 {
-    return m_tab_offset;
+    return m_tabOffset;
 }
 
 void wxAuiTabContainer::SetTabOffset(size_t offset)
 {
 }
 
 void wxAuiTabContainer::SetTabOffset(size_t offset)
 {
-    m_tab_offset = offset;
+    m_tabOffset = offset;
 }
 
 
 }
 
 
@@ -1544,6 +1643,11 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
         return;
 
     wxMemoryDC dc;
         return;
 
     wxMemoryDC dc;
+
+    // use the same layout direction as the window DC uses to ensure that the
+    // text is rendered correctly
+    dc.SetLayoutDirection(raw_dc->GetLayoutDirection());
+
     wxBitmap bmp;
     size_t i;
     size_t page_count = m_pages.GetCount();
     wxBitmap bmp;
     size_t i;
     size_t page_count = m_pages.GetCount();
@@ -1586,19 +1690,19 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
 
         if (i+1 < page_count)
             total_width += x_extent;
 
         if (i+1 < page_count)
             total_width += x_extent;
-             else
+        else
             total_width += size.x;
 
             total_width += size.x;
 
-        if (i >= m_tab_offset)
+        if (i >= m_tabOffset)
         {
             if (i+1 < page_count)
                 visible_width += x_extent;
         {
             if (i+1 < page_count)
                 visible_width += x_extent;
-                 else
+            else
                 visible_width += size.x;
         }
     }
 
                 visible_width += size.x;
         }
     }
 
-    if (total_width > m_rect.GetWidth() || m_tab_offset != 0)
+    if (total_width > m_rect.GetWidth() || m_tabOffset != 0)
     {
         // show left/right buttons
         for (i = 0; i < button_count; ++i)
     {
         // show left/right buttons
         for (i = 0; i < button_count; ++i)
@@ -1607,11 +1711,11 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
             if (button.id == wxAUI_BUTTON_LEFT ||
                 button.id == wxAUI_BUTTON_RIGHT)
             {
             if (button.id == wxAUI_BUTTON_LEFT ||
                 button.id == wxAUI_BUTTON_RIGHT)
             {
-                button.cur_state &= ~wxAUI_BUTTON_STATE_HIDDEN;
+                button.curState &= ~wxAUI_BUTTON_STATE_HIDDEN;
             }
         }
     }
             }
         }
     }
-     else
+    else
     {
         // hide left/right buttons
         for (i = 0; i < button_count; ++i)
     {
         // hide left/right buttons
         for (i = 0; i < button_count; ++i)
@@ -1620,7 +1724,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
             if (button.id == wxAUI_BUTTON_LEFT ||
                 button.id == wxAUI_BUTTON_RIGHT)
             {
             if (button.id == wxAUI_BUTTON_LEFT ||
                 button.id == wxAUI_BUTTON_RIGHT)
             {
-                button.cur_state |= wxAUI_BUTTON_STATE_HIDDEN;
+                button.curState |= wxAUI_BUTTON_STATE_HIDDEN;
             }
         }
     }
             }
         }
     }
@@ -1631,17 +1735,17 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
         wxAuiTabContainerButton& button = m_buttons.Item(i);
         if (button.id == wxAUI_BUTTON_LEFT)
         {
         wxAuiTabContainerButton& button = m_buttons.Item(i);
         if (button.id == wxAUI_BUTTON_LEFT)
         {
-            if (m_tab_offset == 0)
-                button.cur_state |= wxAUI_BUTTON_STATE_DISABLED;
-                 else
-                button.cur_state &= ~wxAUI_BUTTON_STATE_DISABLED;
+            if (m_tabOffset == 0)
+                button.curState |= wxAUI_BUTTON_STATE_DISABLED;
+            else
+                button.curState &= ~wxAUI_BUTTON_STATE_DISABLED;
         }
         if (button.id == wxAUI_BUTTON_RIGHT)
         {
             if (visible_width < m_rect.GetWidth() - ((int)button_count*16))
         }
         if (button.id == wxAUI_BUTTON_RIGHT)
         {
             if (visible_width < m_rect.GetWidth() - ((int)button_count*16))
-                button.cur_state |= wxAUI_BUTTON_STATE_DISABLED;
-                 else
-                button.cur_state &= ~wxAUI_BUTTON_STATE_DISABLED;
+                button.curState |= wxAUI_BUTTON_STATE_DISABLED;
+            else
+                button.curState &= ~wxAUI_BUTTON_STATE_DISABLED;
         }
     }
 
         }
     }
 
@@ -1664,7 +1768,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
 
         if (button.location != wxRIGHT)
             continue;
 
         if (button.location != wxRIGHT)
             continue;
-        if (button.cur_state & wxAUI_BUTTON_STATE_HIDDEN)
+        if (button.curState & wxAUI_BUTTON_STATE_HIDDEN)
             continue;
 
         wxRect button_rect = m_rect;
             continue;
 
         wxRect button_rect = m_rect;
@@ -1675,9 +1779,8 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
                           wnd,
                           button_rect,
                           button.id,
                           wnd,
                           button_rect,
                           button.id,
-                          button.cur_state,
+                          button.curState,
                           wxRIGHT,
                           wxRIGHT,
-                          wxNullBitmap,
                           &button.rect);
 
         offset -= button.rect.GetWidth();
                           &button.rect);
 
         offset -= button.rect.GetWidth();
@@ -1696,7 +1799,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
 
         if (button.location != wxLEFT)
             continue;
 
         if (button.location != wxLEFT)
             continue;
-        if (button.cur_state & wxAUI_BUTTON_STATE_HIDDEN)
+        if (button.curState & wxAUI_BUTTON_STATE_HIDDEN)
             continue;
 
         wxRect button_rect(offset, 1, 1000, m_rect.height);
             continue;
 
         wxRect button_rect(offset, 1, 1000, m_rect.height);
@@ -1705,9 +1808,8 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
                           wnd,
                           button_rect,
                           button.id,
                           wnd,
                           button_rect,
                           button.id,
-                          button.cur_state,
+                          button.curState,
                           wxLEFT,
                           wxLEFT,
-                          wxNullBitmap,
                           &button.rect);
 
         offset += button.rect.GetWidth();
                           &button.rect);
 
         offset += button.rect.GetWidth();
@@ -1722,24 +1824,24 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
 
     // prepare the tab-close-button array
     // make sure tab button entries which aren't used are marked as hidden
 
     // prepare the tab-close-button array
     // make sure tab button entries which aren't used are marked as hidden
-    for (i = page_count; i < m_tab_close_buttons.GetCount(); ++i)
-        m_tab_close_buttons.Item(i).cur_state = wxAUI_BUTTON_STATE_HIDDEN;
+    for (i = page_count; i < m_tabCloseButtons.GetCount(); ++i)
+        m_tabCloseButtons.Item(i).curState = wxAUI_BUTTON_STATE_HIDDEN;
 
     // make sure there are enough tab button entries to accommodate all tabs
 
     // make sure there are enough tab button entries to accommodate all tabs
-    while (m_tab_close_buttons.GetCount() < page_count)
+    while (m_tabCloseButtons.GetCount() < page_count)
     {
         wxAuiTabContainerButton tempbtn;
         tempbtn.id = wxAUI_BUTTON_CLOSE;
         tempbtn.location = wxCENTER;
     {
         wxAuiTabContainerButton tempbtn;
         tempbtn.id = wxAUI_BUTTON_CLOSE;
         tempbtn.location = wxCENTER;
-        tempbtn.cur_state = wxAUI_BUTTON_STATE_HIDDEN;
-        m_tab_close_buttons.Add(tempbtn);
+        tempbtn.curState = wxAUI_BUTTON_STATE_HIDDEN;
+        m_tabCloseButtons.Add(tempbtn);
     }
 
 
     // buttons before the tab offset must be set to hidden
     }
 
 
     // buttons before the tab offset must be set to hidden
-    for (i = 0; i < m_tab_offset; ++i)
+    for (i = 0; i < m_tabOffset; ++i)
     {
     {
-        m_tab_close_buttons.Item(i).cur_state = wxAUI_BUTTON_STATE_HIDDEN;
+        m_tabCloseButtons.Item(i).curState = wxAUI_BUTTON_STATE_HIDDEN;
     }
 
 
     }
 
 
@@ -1754,27 +1856,25 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
     rect.y = 0;
     rect.height = m_rect.height;
 
     rect.y = 0;
     rect.height = m_rect.height;
 
-    for (i = m_tab_offset; i < page_count; ++i)
+    for (i = m_tabOffset; i < page_count; ++i)
     {
         wxAuiNotebookPage& page = m_pages.Item(i);
     {
         wxAuiNotebookPage& page = m_pages.Item(i);
-        wxAuiTabContainerButton& tab_button = m_tab_close_buttons.Item(i);
+        wxAuiTabContainerButton& tab_button = m_tabCloseButtons.Item(i);
 
         // determine if a close button is on this tab
 
         // determine if a close button is on this tab
-        bool close_button = false;
         if ((m_flags & wxAUI_NB_CLOSE_ON_ALL_TABS) != 0 ||
             ((m_flags & wxAUI_NB_CLOSE_ON_ACTIVE_TAB) != 0 && page.active))
         {
         if ((m_flags & wxAUI_NB_CLOSE_ON_ALL_TABS) != 0 ||
             ((m_flags & wxAUI_NB_CLOSE_ON_ACTIVE_TAB) != 0 && page.active))
         {
-            close_button = true;
-            if (tab_button.cur_state == wxAUI_BUTTON_STATE_HIDDEN)
+            if (tab_button.curState == wxAUI_BUTTON_STATE_HIDDEN)
             {
                 tab_button.id = wxAUI_BUTTON_CLOSE;
             {
                 tab_button.id = wxAUI_BUTTON_CLOSE;
-                tab_button.cur_state = wxAUI_BUTTON_STATE_NORMAL;
+                tab_button.curState = wxAUI_BUTTON_STATE_NORMAL;
                 tab_button.location = wxCENTER;
             }
         }
                 tab_button.location = wxCENTER;
             }
         }
-         else
+        else
         {
         {
-            tab_button.cur_state = wxAUI_BUTTON_STATE_HIDDEN;
+            tab_button.curState = wxAUI_BUTTON_STATE_HIDDEN;
         }
 
         rect.x = offset;
         }
 
         rect.x = offset;
@@ -1785,11 +1885,9 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
 
         m_art->DrawTab(dc,
                        wnd,
 
         m_art->DrawTab(dc,
                        wnd,
+                       page,
                        rect,
                        rect,
-                       page.caption,
-                       page.bitmap,
-                       page.active,
-                       tab_button.cur_state,
+                       tab_button.curState,
                        &page.rect,
                        &tab_button.rect,
                        &x_extent);
                        &page.rect,
                        &tab_button.rect,
                        &x_extent);
@@ -1806,35 +1904,25 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
 
 
     // make sure to deactivate buttons which are off the screen to the right
 
 
     // make sure to deactivate buttons which are off the screen to the right
-    for (++i; i < m_tab_close_buttons.GetCount(); ++i)
+    for (++i; i < m_tabCloseButtons.GetCount(); ++i)
     {
     {
-        m_tab_close_buttons.Item(i).cur_state = wxAUI_BUTTON_STATE_HIDDEN;
+        m_tabCloseButtons.Item(i).curState = wxAUI_BUTTON_STATE_HIDDEN;
     }
 
 
     // draw the active tab again so it stands in the foreground
     }
 
 
     // draw the active tab again so it stands in the foreground
-    if (active >= m_tab_offset && active < m_pages.GetCount())
+    if (active >= m_tabOffset && active < m_pages.GetCount())
     {
         wxAuiNotebookPage& page = m_pages.Item(active);
 
     {
         wxAuiNotebookPage& page = m_pages.Item(active);
 
-        wxAuiTabContainerButton& tab_button = m_tab_close_buttons.Item(active);
-
-        // determine if a close button is on this tab
-        bool close_button = false;
-        if ((m_flags & wxAUI_NB_CLOSE_ON_ALL_TABS) != 0 ||
-            ((m_flags & wxAUI_NB_CLOSE_ON_ACTIVE_TAB) != 0 && page.active))
-        {
-            close_button = true;
-        }
+        wxAuiTabContainerButton& tab_button = m_tabCloseButtons.Item(active);
 
         rect.x = active_offset;
         m_art->DrawTab(dc,
                        wnd,
 
         rect.x = active_offset;
         m_art->DrawTab(dc,
                        wnd,
+                       page,
                        active_rect,
                        active_rect,
-                       page.caption,
-                       page.bitmap,
-                       page.active,
-                       tab_button.cur_state,
+                       tab_button.curState,
                        &page.rect,
                        &tab_button.rect,
                        &x_extent);
                        &page.rect,
                        &tab_button.rect,
                        &x_extent);
@@ -1846,6 +1934,147 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
                  &dc, 0, 0);
 }
 
                  &dc, 0, 0);
 }
 
+// Is the tab visible?
+bool wxAuiTabContainer::IsTabVisible(int tabPage, int tabOffset, wxDC* dc, wxWindow* wnd)
+{
+    if (!dc || !dc->IsOk())
+        return false;
+
+    size_t i;
+    size_t page_count = m_pages.GetCount();
+    size_t button_count = m_buttons.GetCount();
+
+    // Hasn't been rendered yet; assume it's visible
+    if (m_tabCloseButtons.GetCount() < page_count)
+        return true;
+
+    // First check if both buttons are disabled - if so, there's no need to
+    // check further for visibility.
+    int arrowButtonVisibleCount = 0;
+    for (i = 0; i < button_count; ++i)
+    {
+        wxAuiTabContainerButton& button = m_buttons.Item(i);
+        if (button.id == wxAUI_BUTTON_LEFT ||
+            button.id == wxAUI_BUTTON_RIGHT)
+        {
+            if ((button.curState & wxAUI_BUTTON_STATE_HIDDEN) == 0)
+                arrowButtonVisibleCount ++;
+        }
+    }
+
+    // Tab must be visible
+    if (arrowButtonVisibleCount == 0)
+        return true;
+
+    // If tab is less than the given offset, it must be invisible by definition
+    if (tabPage < tabOffset)
+        return false;
+
+    // draw buttons
+    int left_buttons_width = 0;
+    int right_buttons_width = 0;
+
+    int offset = 0;
+
+    // calculate size of the buttons on the right side
+    offset = m_rect.x + m_rect.width;
+    for (i = 0; i < button_count; ++i)
+    {
+        wxAuiTabContainerButton& button = m_buttons.Item(button_count - i - 1);
+
+        if (button.location != wxRIGHT)
+            continue;
+        if (button.curState & wxAUI_BUTTON_STATE_HIDDEN)
+            continue;
+
+        offset -= button.rect.GetWidth();
+        right_buttons_width += button.rect.GetWidth();
+    }
+
+    offset = 0;
+
+    // calculate size of the buttons on the left side
+    for (i = 0; i < button_count; ++i)
+    {
+        wxAuiTabContainerButton& button = m_buttons.Item(button_count - i - 1);
+
+        if (button.location != wxLEFT)
+            continue;
+        if (button.curState & wxAUI_BUTTON_STATE_HIDDEN)
+            continue;
+
+        offset += button.rect.GetWidth();
+        left_buttons_width += button.rect.GetWidth();
+    }
+
+    offset = left_buttons_width;
+
+    if (offset == 0)
+        offset += m_art->GetIndentSize();
+
+    wxRect active_rect;
+
+    wxRect rect = m_rect;
+    rect.y = 0;
+    rect.height = m_rect.height;
+
+    // See if the given page is visible at the given tab offset (effectively scroll position)
+    for (i = tabOffset; i < page_count; ++i)
+    {
+        wxAuiNotebookPage& page = m_pages.Item(i);
+        wxAuiTabContainerButton& tab_button = m_tabCloseButtons.Item(i);
+
+        rect.x = offset;
+        rect.width = m_rect.width - right_buttons_width - offset - 2;
+
+        if (rect.width <= 0)
+            return false; // haven't found the tab, and we've run out of space, so return false
+
+        int x_extent = 0;
+        m_art->GetTabSize(*dc,
+                            wnd,
+                            page.caption,
+                            page.bitmap,
+                            page.active,
+                            tab_button.curState,
+                            &x_extent);
+
+        offset += x_extent;
+
+        if (i == (size_t) tabPage)
+        {
+            // If not all of the tab is visible, and supposing there's space to display it all,
+            // we could do better so we return false.
+            if (((m_rect.width - right_buttons_width - offset - 2) <= 0) && ((m_rect.width - right_buttons_width - left_buttons_width) > x_extent))
+                return false;
+            else
+                return true;
+        }
+    }
+
+    // Shouldn't really get here, but if it does, assume the tab is visible to prevent
+    // further looping in calling code.
+    return true;
+}
+
+// Make the tab visible if it wasn't already
+void wxAuiTabContainer::MakeTabVisible(int tabPage, wxWindow* win)
+{
+    wxClientDC dc(win);
+    if (!IsTabVisible(tabPage, GetTabOffset(), & dc, win))
+    {
+        int i;
+        for (i = 0; i < (int) m_pages.GetCount(); i++)
+        {
+            if (IsTabVisible(tabPage, i, & dc, win))
+            {
+                SetTabOffset(i);
+                win->Refresh();
+                return;
+            }
+        }
+    }
+}
 
 // TabHitTest() tests if a tab was hit, passing the window pointer
 // back if that condition was fulfilled.  The function returns
 
 // TabHitTest() tests if a tab was hit, passing the window pointer
 // back if that condition was fulfilled.  The function returns
@@ -1856,7 +2085,7 @@ bool wxAuiTabContainer::TabHitTest(int x, int y, wxWindow** hit) const
         return false;
 
     wxAuiTabContainerButton* btn = NULL;
         return false;
 
     wxAuiTabContainerButton* btn = NULL;
-    if (ButtonHitTest(x, y, &btn))
+    if (ButtonHitTest(x, y, &btn) && !(btn->curState & wxAUI_BUTTON_STATE_DISABLED))
     {
         if (m_buttons.Index(*btn) != wxNOT_FOUND)
             return false;
     {
         if (m_buttons.Index(*btn) != wxNOT_FOUND)
             return false;
@@ -1864,7 +2093,7 @@ bool wxAuiTabContainer::TabHitTest(int x, int y, wxWindow** hit) const
 
     size_t i, page_count = m_pages.GetCount();
 
 
     size_t i, page_count = m_pages.GetCount();
 
-    for (i = m_tab_offset; i < page_count; ++i)
+    for (i = m_tabOffset; i < page_count; ++i)
     {
         wxAuiNotebookPage& page = m_pages.Item(i);
         if (page.rect.Contains(x,y))
     {
         wxAuiNotebookPage& page = m_pages.Item(i);
         if (page.rect.Contains(x,y))
@@ -1894,8 +2123,7 @@ bool wxAuiTabContainer::ButtonHitTest(int x, int y,
     {
         wxAuiTabContainerButton& button = m_buttons.Item(i);
         if (button.rect.Contains(x,y) &&
     {
         wxAuiTabContainerButton& button = m_buttons.Item(i);
         if (button.rect.Contains(x,y) &&
-            !(button.cur_state & (wxAUI_BUTTON_STATE_HIDDEN |
-                                   wxAUI_BUTTON_STATE_DISABLED)))
+            !(button.curState & wxAUI_BUTTON_STATE_HIDDEN ))
         {
             if (hit)
                 *hit = &button;
         {
             if (hit)
                 *hit = &button;
@@ -1903,12 +2131,12 @@ bool wxAuiTabContainer::ButtonHitTest(int x, int y,
         }
     }
 
         }
     }
 
-    button_count = m_tab_close_buttons.GetCount();
+    button_count = m_tabCloseButtons.GetCount();
     for (i = 0; i < button_count; ++i)
     {
     for (i = 0; i < button_count; ++i)
     {
-        wxAuiTabContainerButton& button = m_tab_close_buttons.Item(i);
+        wxAuiTabContainerButton& button = m_tabCloseButtons.Item(i);
         if (button.rect.Contains(x,y) &&
         if (button.rect.Contains(x,y) &&
-            !(button.cur_state & (wxAUI_BUTTON_STATE_HIDDEN |
+            !(button.curState & (wxAUI_BUTTON_STATE_HIDDEN |
                                    wxAUI_BUTTON_STATE_DISABLED)))
         {
             if (hit)
                                    wxAUI_BUTTON_STATE_DISABLED)))
         {
             if (hit)
@@ -1927,12 +2155,14 @@ bool wxAuiTabContainer::ButtonHitTest(int x, int y,
 // as the Show() method on this class is "unplugged"
 static void ShowWnd(wxWindow* wnd, bool show)
 {
 // as the Show() method on this class is "unplugged"
 static void ShowWnd(wxWindow* wnd, bool show)
 {
+#if wxUSE_MDI
     if (wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
     {
         wxAuiMDIChildFrame* cf = (wxAuiMDIChildFrame*)wnd;
         cf->DoShow(show);
     }
     if (wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
     {
         wxAuiMDIChildFrame* cf = (wxAuiMDIChildFrame*)wnd;
         cf->DoShow(show);
     }
-     else
+    else
+#endif
     {
         wnd->Show(show);
     }
     {
         wnd->Show(show);
     }
@@ -1961,7 +2191,8 @@ void wxAuiTabContainer::DoShowHide()
     for (i = 0; i < page_count; ++i)
     {
         wxAuiNotebookPage& page = pages.Item(i);
     for (i = 0; i < page_count; ++i)
     {
         wxAuiNotebookPage& page = pages.Item(i);
-        ShowWnd(page.window, page.active);
+        if (!page.active)
+            ShowWnd(page.window, false);
     }
 }
 
     }
 }
 
@@ -1979,10 +2210,19 @@ BEGIN_EVENT_TABLE(wxAuiTabCtrl, wxControl)
     EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground)
     EVT_SIZE(wxAuiTabCtrl::OnSize)
     EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown)
     EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground)
     EVT_SIZE(wxAuiTabCtrl::OnSize)
     EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown)
+    EVT_LEFT_DCLICK(wxAuiTabCtrl::OnLeftDClick)
     EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp)
     EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp)
+    EVT_MIDDLE_DOWN(wxAuiTabCtrl::OnMiddleDown)
+    EVT_MIDDLE_UP(wxAuiTabCtrl::OnMiddleUp)
+    EVT_RIGHT_DOWN(wxAuiTabCtrl::OnRightDown)
+    EVT_RIGHT_UP(wxAuiTabCtrl::OnRightUp)
     EVT_MOTION(wxAuiTabCtrl::OnMotion)
     EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow)
     EVT_MOTION(wxAuiTabCtrl::OnMotion)
     EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow)
-    EVT_AUINOTEBOOK_BUTTON(-1, wxAuiTabCtrl::OnButton)
+    EVT_AUINOTEBOOK_BUTTON(wxID_ANY, wxAuiTabCtrl::OnButton)
+    EVT_SET_FOCUS(wxAuiTabCtrl::OnSetFocus)
+    EVT_KILL_FOCUS(wxAuiTabCtrl::OnKillFocus)
+    EVT_CHAR(wxAuiTabCtrl::OnChar)
+    EVT_MOUSE_CAPTURE_LOST(wxAuiTabCtrl::OnCaptureLost)
 END_EVENT_TABLE()
 
 
 END_EVENT_TABLE()
 
 
@@ -1992,10 +2232,11 @@ wxAuiTabCtrl::wxAuiTabCtrl(wxWindow* parent,
                            const wxSize& size,
                            long style) : wxControl(parent, id, pos, size, style)
 {
                            const wxSize& size,
                            long style) : wxControl(parent, id, pos, size, style)
 {
-    m_click_pt = wxDefaultPosition;
-    m_is_dragging = false;
-    m_hover_button = NULL;
-    m_pressed_button = NULL;
+    SetName(wxT("wxAuiTabCtrl"));
+    m_clickPt = wxDefaultPosition;
+    m_isDragging = false;
+    m_hoverButton = NULL;
+    m_pressedButton = NULL;
 }
 
 wxAuiTabCtrl::~wxAuiTabCtrl()
 }
 
 wxAuiTabCtrl::~wxAuiTabCtrl()
@@ -2026,10 +2267,10 @@ void wxAuiTabCtrl::OnSize(wxSizeEvent& evt)
 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt)
 {
     CaptureMouse();
 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt)
 {
     CaptureMouse();
-    m_click_pt = wxDefaultPosition;
-    m_is_dragging = false;
-    m_click_tab = NULL;
-    m_pressed_button = NULL;
+    m_clickPt = wxDefaultPosition;
+    m_isDragging = false;
+    m_clickTab = NULL;
+    m_pressedButton = NULL;
 
 
     wxWindow* wnd;
 
 
     wxWindow* wnd;
@@ -2037,7 +2278,11 @@ void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt)
     {
         int new_selection = GetIdxFromWindow(wnd);
 
     {
         int new_selection = GetIdxFromWindow(wnd);
 
-        if (new_selection != GetActivePage())
+        // wxAuiNotebooks always want to receive this event
+        // even if the tab is already active, because they may
+        // have multiple tab controls
+        if (new_selection != GetActivePage() ||
+            GetParent()->IsKindOf(CLASSINFO(wxAuiNotebook)))
         {
             wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, m_windowId);
             e.SetSelection(new_selection);
         {
             wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, m_windowId);
             e.SetSelection(new_selection);
@@ -2046,111 +2291,190 @@ void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt)
             GetEventHandler()->ProcessEvent(e);
         }
 
             GetEventHandler()->ProcessEvent(e);
         }
 
-        m_click_pt.x = evt.m_x;
-        m_click_pt.y = evt.m_y;
-        m_click_tab = wnd;
+        m_clickPt.x = evt.m_x;
+        m_clickPt.y = evt.m_y;
+        m_clickTab = wnd;
     }
 
     }
 
-    if (m_hover_button)
+    if (m_hoverButton)
     {
     {
-        m_pressed_button = m_hover_button;
-        m_pressed_button->cur_state = wxAUI_BUTTON_STATE_PRESSED;
+        m_pressedButton = m_hoverButton;
+        m_pressedButton->curState = wxAUI_BUTTON_STATE_PRESSED;
         Refresh();
         Update();
     }
 }
 
         Refresh();
         Update();
     }
 }
 
+void wxAuiTabCtrl::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event))
+{
+    if (m_isDragging)
+    {
+        m_isDragging = false;
+
+        wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_CANCEL_DRAG, m_windowId);
+        evt.SetSelection(GetIdxFromWindow(m_clickTab));
+        evt.SetOldSelection(evt.GetSelection());
+        evt.SetEventObject(this);
+        GetEventHandler()->ProcessEvent(evt);
+    }
+}
+
 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent& evt)
 {
     if (GetCapture() == this)
         ReleaseMouse();
 
 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent& evt)
 {
     if (GetCapture() == this)
         ReleaseMouse();
 
-    if (m_is_dragging)
+    if (m_isDragging)
     {
     {
+        m_isDragging = false;
+
         wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, m_windowId);
         wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, m_windowId);
-        evt.SetSelection(GetIdxFromWindow(m_click_tab));
+        evt.SetSelection(GetIdxFromWindow(m_clickTab));
         evt.SetOldSelection(evt.GetSelection());
         evt.SetEventObject(this);
         GetEventHandler()->ProcessEvent(evt);
         evt.SetOldSelection(evt.GetSelection());
         evt.SetEventObject(this);
         GetEventHandler()->ProcessEvent(evt);
+
         return;
     }
 
         return;
     }
 
-    if (m_pressed_button)
+    if (m_pressedButton)
     {
         // make sure we're still clicking the button
         wxAuiTabContainerButton* button = NULL;
     {
         // make sure we're still clicking the button
         wxAuiTabContainerButton* button = NULL;
-        if (!ButtonHitTest(evt.m_x, evt.m_y, &button))
+        if (!ButtonHitTest(evt.m_x, evt.m_y, &button) ||
+            button->curState & wxAUI_BUTTON_STATE_DISABLED)
             return;
 
             return;
 
-        if (button != m_pressed_button)
+        if (button != m_pressedButton)
         {
         {
-            m_pressed_button = NULL;
+            m_pressedButton = NULL;
             return;
         }
 
         Refresh();
         Update();
 
             return;
         }
 
         Refresh();
         Update();
 
-        if (!(m_pressed_button->cur_state & wxAUI_BUTTON_STATE_DISABLED))
+        if (!(m_pressedButton->curState & wxAUI_BUTTON_STATE_DISABLED))
         {
             wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON, m_windowId);
         {
             wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON, m_windowId);
-            evt.SetInt(m_pressed_button->id);
+            evt.SetSelection(GetIdxFromWindow(m_clickTab));
+            evt.SetInt(m_pressedButton->id);
             evt.SetEventObject(this);
             GetEventHandler()->ProcessEvent(evt);
         }
 
             evt.SetEventObject(this);
             GetEventHandler()->ProcessEvent(evt);
         }
 
-        m_pressed_button = NULL;
+        m_pressedButton = NULL;
     }
 
     }
 
-    m_click_pt = wxDefaultPosition;
-    m_is_dragging = false;
-    m_click_tab = NULL;
+    m_clickPt = wxDefaultPosition;
+    m_isDragging = false;
+    m_clickTab = NULL;
 }
 
 }
 
-void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt)
+void wxAuiTabCtrl::OnMiddleUp(wxMouseEvent& evt)
 {
 {
-    wxPoint pos = evt.GetPosition();
+    wxWindow* wnd = NULL;
+    if (!TabHitTest(evt.m_x, evt.m_y, &wnd))
+        return;
 
 
-    // check if the mouse is hovering above a button
-    wxAuiTabContainerButton* button;
-    if (ButtonHitTest(pos.x, pos.y, &button))
-    {
-        if (m_hover_button && button != m_hover_button)
-        {
-            m_hover_button->cur_state = wxAUI_BUTTON_STATE_NORMAL;
-            m_hover_button = NULL;
-            Refresh();
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, m_windowId);
+    e.SetEventObject(this);
+    e.SetSelection(GetIdxFromWindow(wnd));
+    GetEventHandler()->ProcessEvent(e);
+}
+
+void wxAuiTabCtrl::OnMiddleDown(wxMouseEvent& evt)
+{
+    wxWindow* wnd = NULL;
+    if (!TabHitTest(evt.m_x, evt.m_y, &wnd))
+        return;
+
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, m_windowId);
+    e.SetEventObject(this);
+    e.SetSelection(GetIdxFromWindow(wnd));
+    GetEventHandler()->ProcessEvent(e);
+}
+
+void wxAuiTabCtrl::OnRightUp(wxMouseEvent& evt)
+{
+    wxWindow* wnd = NULL;
+    if (!TabHitTest(evt.m_x, evt.m_y, &wnd))
+        return;
+
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, m_windowId);
+    e.SetEventObject(this);
+    e.SetSelection(GetIdxFromWindow(wnd));
+    GetEventHandler()->ProcessEvent(e);
+}
+
+void wxAuiTabCtrl::OnRightDown(wxMouseEvent& evt)
+{
+    wxWindow* wnd = NULL;
+    if (!TabHitTest(evt.m_x, evt.m_y, &wnd))
+        return;
+
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, m_windowId);
+    e.SetEventObject(this);
+    e.SetSelection(GetIdxFromWindow(wnd));
+    GetEventHandler()->ProcessEvent(e);
+}
+
+void wxAuiTabCtrl::OnLeftDClick(wxMouseEvent& evt)
+{
+    wxWindow* wnd;
+    wxAuiTabContainerButton* button;
+    if (!TabHitTest(evt.m_x, evt.m_y, &wnd) && !ButtonHitTest(evt.m_x, evt.m_y, &button))
+    {
+        wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, m_windowId);
+        e.SetEventObject(this);
+        GetEventHandler()->ProcessEvent(e);
+    }
+}
+
+void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt)
+{
+    wxPoint pos = evt.GetPosition();
+
+    // check if the mouse is hovering above a button
+    wxAuiTabContainerButton* button;
+    if (ButtonHitTest(pos.x, pos.y, &button) && !(button->curState & wxAUI_BUTTON_STATE_DISABLED))
+    {
+        if (m_hoverButton && button != m_hoverButton)
+        {
+            m_hoverButton->curState = wxAUI_BUTTON_STATE_NORMAL;
+            m_hoverButton = NULL;
+            Refresh();
             Update();
         }
 
             Update();
         }
 
-        if (button->cur_state != wxAUI_BUTTON_STATE_HOVER)
+        if (button->curState != wxAUI_BUTTON_STATE_HOVER)
         {
         {
-            button->cur_state = wxAUI_BUTTON_STATE_HOVER;
+            button->curState = wxAUI_BUTTON_STATE_HOVER;
             Refresh();
             Update();
             Refresh();
             Update();
-            m_hover_button = button;
+            m_hoverButton = button;
             return;
         }
     }
             return;
         }
     }
-     else
+    else
     {
     {
-        if (m_hover_button)
+        if (m_hoverButton)
         {
         {
-            m_hover_button->cur_state = wxAUI_BUTTON_STATE_NORMAL;
-            m_hover_button = NULL;
+            m_hoverButton->curState = wxAUI_BUTTON_STATE_NORMAL;
+            m_hoverButton = NULL;
             Refresh();
             Update();
         }
     }
 
 
             Refresh();
             Update();
         }
     }
 
 
-    if (!evt.LeftIsDown() || m_click_pt == wxDefaultPosition)
+    if (!evt.LeftIsDown() || m_clickPt == wxDefaultPosition)
         return;
 
         return;
 
-    if (m_is_dragging)
+    if (m_isDragging)
     {
         wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, m_windowId);
     {
         wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, m_windowId);
-        evt.SetSelection(GetIdxFromWindow(m_click_tab));
+        evt.SetSelection(GetIdxFromWindow(m_clickTab));
         evt.SetOldSelection(evt.GetSelection());
         evt.SetEventObject(this);
         GetEventHandler()->ProcessEvent(evt);
         evt.SetOldSelection(evt.GetSelection());
         evt.SetEventObject(this);
         GetEventHandler()->ProcessEvent(evt);
@@ -2161,25 +2485,25 @@ void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt)
     int drag_x_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_X);
     int drag_y_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_Y);
 
     int drag_x_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_X);
     int drag_y_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_Y);
 
-    if (abs(pos.x - m_click_pt.x) > drag_x_threshold ||
-        abs(pos.y - m_click_pt.y) > drag_y_threshold)
+    if (abs(pos.x - m_clickPt.x) > drag_x_threshold ||
+        abs(pos.y - m_clickPt.y) > drag_y_threshold)
     {
         wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, m_windowId);
     {
         wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, m_windowId);
-        evt.SetSelection(GetIdxFromWindow(m_click_tab));
+        evt.SetSelection(GetIdxFromWindow(m_clickTab));
         evt.SetOldSelection(evt.GetSelection());
         evt.SetEventObject(this);
         GetEventHandler()->ProcessEvent(evt);
 
         evt.SetOldSelection(evt.GetSelection());
         evt.SetEventObject(this);
         GetEventHandler()->ProcessEvent(evt);
 
-        m_is_dragging = true;
+        m_isDragging = true;
     }
 }
 
 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent& WXUNUSED(event))
 {
     }
 }
 
 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent& WXUNUSED(event))
 {
-    if (m_hover_button)
+    if (m_hoverButton)
     {
     {
-        m_hover_button->cur_state = wxAUI_BUTTON_STATE_NORMAL;
-        m_hover_button = NULL;
+        m_hoverButton->curState = wxAUI_BUTTON_STATE_NORMAL;
+        m_hoverButton = NULL;
         Refresh();
         Update();
     }
         Refresh();
         Update();
     }
@@ -2200,25 +2524,16 @@ void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent& event)
                 Update();
             }
         }
                 Update();
             }
         }
-         else
+        else
         {
             SetTabOffset(GetTabOffset()+1);
             Refresh();
             Update();
         }
     }
         {
             SetTabOffset(GetTabOffset()+1);
             Refresh();
             Update();
         }
     }
-     else if (button == wxAUI_BUTTON_WINDOWLIST)
+    else if (button == wxAUI_BUTTON_WINDOWLIST)
     {
     {
-        wxArrayString as;
-
-        size_t i, page_count = m_pages.GetCount();
-        for (i = 0; i < page_count; ++i)
-        {
-            wxAuiNotebookPage& page = m_pages.Item(i);
-            as.Add(page.caption);
-        }
-
-        int idx = GetArtProvider()->ShowWindowList(this, as, GetActivePage());
+        int idx = GetArtProvider()->ShowDropDown(this, m_pages, GetActivePage());
 
         if (idx != -1)
         {
 
         if (idx != -1)
         {
@@ -2229,10 +2544,143 @@ void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent& event)
             GetEventHandler()->ProcessEvent(e);
         }
     }
             GetEventHandler()->ProcessEvent(e);
         }
     }
-     else
+    else
+    {
+        event.Skip();
+    }
+}
+
+void wxAuiTabCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event))
+{
+    Refresh();
+}
+
+void wxAuiTabCtrl::OnKillFocus(wxFocusEvent& WXUNUSED(event))
+{
+    Refresh();
+}
+
+void wxAuiTabCtrl::OnChar(wxKeyEvent& event)
+{
+    if (GetActivePage() == -1)
+    {
+        event.Skip();
+        return;
+    }
+
+    // We can't leave tab processing to the system; on Windows, tabs and keys
+    // get eaten by the system and not processed properly if we specify both
+    // wxTAB_TRAVERSAL and wxWANTS_CHARS. And if we specify just wxTAB_TRAVERSAL,
+    // we don't key arrow key events.
+
+    int key = event.GetKeyCode();
+
+    if (key == WXK_NUMPAD_PAGEUP)
+        key = WXK_PAGEUP;
+    if (key == WXK_NUMPAD_PAGEDOWN)
+        key = WXK_PAGEDOWN;
+    if (key == WXK_NUMPAD_HOME)
+        key = WXK_HOME;
+    if (key == WXK_NUMPAD_END)
+        key = WXK_END;
+    if (key == WXK_NUMPAD_LEFT)
+        key = WXK_LEFT;
+    if (key == WXK_NUMPAD_RIGHT)
+        key = WXK_RIGHT;
+
+    if (key == WXK_TAB || key == WXK_PAGEUP || key == WXK_PAGEDOWN)
+    {
+        bool bCtrlDown = event.ControlDown();
+        bool bShiftDown = event.ShiftDown();
+
+        bool bForward = (key == WXK_TAB && !bShiftDown) || (key == WXK_PAGEDOWN);
+        bool bWindowChange = (key == WXK_PAGEUP) || (key == WXK_PAGEDOWN) || bCtrlDown;
+        bool bFromTab = (key == WXK_TAB);
+
+        wxAuiNotebook* nb = wxDynamicCast(GetParent(), wxAuiNotebook);
+        if (!nb)
+        {
+            event.Skip();
+            return;
+        }
+
+        wxNavigationKeyEvent keyEvent;
+        keyEvent.SetDirection(bForward);
+        keyEvent.SetWindowChange(bWindowChange);
+        keyEvent.SetFromTab(bFromTab);
+        keyEvent.SetEventObject(nb);
+
+        if (!nb->GetEventHandler()->ProcessEvent(keyEvent))
+        {
+            // Not processed? Do an explicit tab into the page.
+            wxWindow* win = GetWindowFromIdx(GetActivePage());
+            if (win)
+                win->SetFocus();
+        }
+        return;
+    }
+
+    if (m_pages.GetCount() < 2)
+    {
+        event.Skip();
+        return;
+    }
+
+    int newPage = -1;
+
+    int forwardKey, backwardKey;
+    if (GetLayoutDirection() == wxLayout_RightToLeft)
+    {
+        forwardKey = WXK_LEFT;
+        backwardKey = WXK_RIGHT;
+    }
+    else
+     {
+        forwardKey = WXK_RIGHT;
+        backwardKey = WXK_LEFT;
+    }
+
+    if (key == forwardKey)
+    {
+        if (m_pages.GetCount() > 1)
+        {
+            if (GetActivePage() == -1)
+                newPage = 0;
+            else if (GetActivePage() < (int) (m_pages.GetCount() - 1))
+                newPage = GetActivePage() + 1;
+        }
+    }
+    else if (key == backwardKey)
+    {
+        if (m_pages.GetCount() > 1)
+        {
+            if (GetActivePage() == -1)
+                newPage = (int) (m_pages.GetCount() - 1);
+            else if (GetActivePage() > 0)
+                newPage = GetActivePage() - 1;
+        }
+    }
+    else if (key == WXK_HOME)
     {
     {
+        newPage = 0;
+    }
+    else if (key == WXK_END)
+    {
+        newPage = (int) (m_pages.GetCount() - 1);
+    }
+    else
         event.Skip();
         event.Skip();
+
+    if (newPage != -1)
+    {
+        wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, m_windowId);
+        e.SetSelection(newPage);
+        e.SetOldSelection(newPage);
+        e.SetEventObject(this);
+        this->GetEventHandler()->ProcessEvent(e);
     }
     }
+    else
+        event.Skip();
 }
 
 // wxTabFrame is an interesting case.  It's important that all child pages
 }
 
 // wxTabFrame is an interesting case.  It's important that all child pages
@@ -2251,14 +2699,20 @@ public:
     {
         m_tabs = NULL;
         m_rect = wxRect(0,0,200,200);
     {
         m_tabs = NULL;
         m_rect = wxRect(0,0,200,200);
-        m_tab_ctrl_height = 20;
+        m_tabCtrlHeight = 20;
+    }
+
+    ~wxTabFrame()
+    {
+        wxDELETE(m_tabs);
     }
 
     void SetTabCtrlHeight(int h)
     {
     }
 
     void SetTabCtrlHeight(int h)
     {
-        m_tab_ctrl_height = h;
+        m_tabCtrlHeight = h;
     }
 
     }
 
+protected:
     void DoSetSize(int x, int y,
                    int width, int height,
                    int WXUNUSED(sizeFlags = wxSIZE_AUTO))
     void DoSetSize(int x, int y,
                    int width, int height,
                    int WXUNUSED(sizeFlags = wxSIZE_AUTO))
@@ -2273,6 +2727,7 @@ public:
         *y = m_rect.height;
     }
 
         *y = m_rect.height;
     }
 
+public:
     bool Show( bool WXUNUSED(show = true) ) { return false; }
 
     void DoSizing()
     bool Show( bool WXUNUSED(show = true) ) { return false; }
 
     void DoSizing()
@@ -2280,9 +2735,25 @@ public:
         if (!m_tabs)
             return;
 
         if (!m_tabs)
             return;
 
-        m_tab_rect = wxRect(m_rect.x, m_rect.y, m_rect.width, m_tab_ctrl_height);
-        m_tabs->SetSize(m_rect.x, m_rect.y, m_rect.width, m_tab_ctrl_height);
-        m_tabs->SetRect(wxRect(0, 0, m_rect.width, m_tab_ctrl_height));
+        if (m_tabs->IsFrozen() || m_tabs->GetParent()->IsFrozen())
+            return;
+
+        m_tab_rect = wxRect(m_rect.x, m_rect.y, m_rect.width, m_tabCtrlHeight);
+        if (m_tabs->GetFlags() & wxAUI_NB_BOTTOM)
+        {
+            m_tab_rect = wxRect (m_rect.x, m_rect.y + m_rect.height - m_tabCtrlHeight, m_rect.width, m_tabCtrlHeight);
+            m_tabs->SetSize     (m_rect.x, m_rect.y + m_rect.height - m_tabCtrlHeight, m_rect.width, m_tabCtrlHeight);
+            m_tabs->SetRect     (wxRect(0, 0, m_rect.width, m_tabCtrlHeight));
+        }
+        else //TODO: if (GetFlags() & wxAUI_NB_TOP)
+        {
+            m_tab_rect = wxRect (m_rect.x, m_rect.y, m_rect.width, m_tabCtrlHeight);
+            m_tabs->SetSize     (m_rect.x, m_rect.y, m_rect.width, m_tabCtrlHeight);
+            m_tabs->SetRect     (wxRect(0, 0,        m_rect.width, m_tabCtrlHeight));
+        }
+        // TODO: else if (GetFlags() & wxAUI_NB_LEFT){}
+        // TODO: else if (GetFlags() & wxAUI_NB_RIGHT){}
+
         m_tabs->Refresh();
         m_tabs->Update();
 
         m_tabs->Refresh();
         m_tabs->Update();
 
@@ -2291,18 +2762,38 @@ public:
 
         for (i = 0; i < page_count; ++i)
         {
 
         for (i = 0; i < page_count; ++i)
         {
+            int height = m_rect.height - m_tabCtrlHeight;
+            if ( height < 0 )
+            {
+                // avoid passing negative height to wxWindow::SetSize(), this
+                // results in assert failures/GTK+ warnings
+                height = 0;
+            }
+
             wxAuiNotebookPage& page = pages.Item(i);
             wxAuiNotebookPage& page = pages.Item(i);
-            page.window->SetSize(m_rect.x, m_rect.y + m_tab_ctrl_height,
-                                 m_rect.width, m_rect.height - m_tab_ctrl_height);
+            if (m_tabs->GetFlags() & wxAUI_NB_BOTTOM)
+            {
+                page.window->SetSize(m_rect.x, m_rect.y, m_rect.width, height);
+            }
+            else //TODO: if (GetFlags() & wxAUI_NB_TOP)
+            {
+                page.window->SetSize(m_rect.x, m_rect.y + m_tabCtrlHeight,
+                                     m_rect.width, height);
+            }
+            // TODO: else if (GetFlags() & wxAUI_NB_LEFT){}
+            // TODO: else if (GetFlags() & wxAUI_NB_RIGHT){}
 
 
+#if wxUSE_MDI
             if (page.window->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
             {
                 wxAuiMDIChildFrame* wnd = (wxAuiMDIChildFrame*)page.window;
                 wnd->ApplyMDIChildFrameRect();
             }
             if (page.window->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
             {
                 wxAuiMDIChildFrame* wnd = (wxAuiMDIChildFrame*)page.window;
                 wnd->ApplyMDIChildFrameRect();
             }
+#endif
         }
     }
 
         }
     }
 
+protected:
     void DoGetSize(int* x, int* y) const
     {
         if (x)
     void DoGetSize(int* x, int* y) const
     {
         if (x)
@@ -2311,62 +2802,74 @@ public:
             *y = m_rect.GetHeight();
     }
 
             *y = m_rect.GetHeight();
     }
 
+public:
     void Update()
     {
         // does nothing
     }
 
     void Update()
     {
         // does nothing
     }
 
-public:
-
     wxRect m_rect;
     wxRect m_tab_rect;
     wxAuiTabCtrl* m_tabs;
     wxRect m_rect;
     wxRect m_tab_rect;
     wxAuiTabCtrl* m_tabs;
-    int m_tab_ctrl_height;
+    int m_tabCtrlHeight;
 };
 
 
 };
 
 
-
+const int wxAuiBaseTabCtrlId = 5380;
 
 
 // -- wxAuiNotebook class implementation --
 
 
 
 // -- wxAuiNotebook class implementation --
 
+#define EVT_AUI_RANGE(id1, id2, event, func) \
+    wx__DECLARE_EVT2(event, id1, id2, wxAuiNotebookEventHandler(func))
+
 BEGIN_EVENT_TABLE(wxAuiNotebook, wxControl)
 BEGIN_EVENT_TABLE(wxAuiNotebook, wxControl)
-    //EVT_ERASE_BACKGROUND(wxAuiNotebook::OnEraseBackground)
-    //EVT_SIZE(wxAuiNotebook::OnSize)
-    //EVT_LEFT_DOWN(wxAuiNotebook::OnLeftDown)
-    EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocus)
-    EVT_COMMAND_RANGE(10000, 10100,
+    EVT_SIZE(wxAuiNotebook::OnSize)
+    EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocusNotebook)
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
                       wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING,
                       wxAuiNotebook::OnTabClicked)
                       wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING,
                       wxAuiNotebook::OnTabClicked)
-    EVT_COMMAND_RANGE(10000, 10100,
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
                       wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG,
                       wxAuiNotebook::OnTabBeginDrag)
                       wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG,
                       wxAuiNotebook::OnTabBeginDrag)
-    EVT_COMMAND_RANGE(10000, 10100,
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
                       wxEVT_COMMAND_AUINOTEBOOK_END_DRAG,
                       wxAuiNotebook::OnTabEndDrag)
                       wxEVT_COMMAND_AUINOTEBOOK_END_DRAG,
                       wxAuiNotebook::OnTabEndDrag)
-    EVT_COMMAND_RANGE(10000, 10100,
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+                      wxEVT_COMMAND_AUINOTEBOOK_CANCEL_DRAG,
+                      wxAuiNotebook::OnTabCancelDrag)
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
                       wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION,
                       wxAuiNotebook::OnTabDragMotion)
                       wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION,
                       wxAuiNotebook::OnTabDragMotion)
-    EVT_COMMAND_RANGE(10000, 10100,
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
                       wxEVT_COMMAND_AUINOTEBOOK_BUTTON,
                       wxAuiNotebook::OnTabButton)
                       wxEVT_COMMAND_AUINOTEBOOK_BUTTON,
                       wxAuiNotebook::OnTabButton)
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+                      wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN,
+                      wxAuiNotebook::OnTabMiddleDown)
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+                      wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP,
+                      wxAuiNotebook::OnTabMiddleUp)
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+                      wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN,
+                      wxAuiNotebook::OnTabRightDown)
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+                      wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP,
+                      wxAuiNotebook::OnTabRightUp)
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+                      wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK,
+                      wxAuiNotebook::OnTabBgDClick)
+    EVT_NAVIGATION_KEY(wxAuiNotebook::OnNavigationKeyNotebook)
 END_EVENT_TABLE()
 
 END_EVENT_TABLE()
 
-wxAuiNotebook::wxAuiNotebook()
+void wxAuiNotebook::Init()
 {
 {
-    m_curpage = -1;
-    m_tab_id_counter = 10000;
-    m_dummy_wnd = NULL;
-    m_tab_ctrl_height = 20;
-}
-
-wxAuiNotebook::wxAuiNotebook(wxWindow *parent,
-                             wxWindowID id,
-                             const wxPoint& pos,
-                             const wxSize& size,
-                             long style) : wxControl(parent, id, pos, size, style)
-{
-    InitNotebook(style);
+    m_curPage = -1;
+    m_tabIdCounter = wxAuiBaseTabCtrlId;
+    m_dummyWnd = NULL;
+    m_tabCtrlHeight = 20;
+    m_requestedBmpSize = wxDefaultSize;
+    m_requestedTabCtrlHeight = -1;
 }
 
 bool wxAuiNotebook::Create(wxWindow* parent,
 }
 
 bool wxAuiNotebook::Create(wxWindow* parent,
@@ -2387,32 +2890,41 @@ bool wxAuiNotebook::Create(wxWindow* parent,
 // code called by all constructors
 void wxAuiNotebook::InitNotebook(long style)
 {
 // code called by all constructors
 void wxAuiNotebook::InitNotebook(long style)
 {
-    m_curpage = -1;
-    m_tab_id_counter = 10000;
-    m_dummy_wnd = NULL;
-    m_tab_ctrl_height = 20;
+    SetName(wxT("wxAuiNotebook"));
+    m_curPage = -1;
+    m_tabIdCounter = wxAuiBaseTabCtrlId;
+    m_dummyWnd = NULL;
     m_flags = (unsigned int)style;
     m_flags = (unsigned int)style;
+    m_tabCtrlHeight = 20;
 
 
-    m_normal_font = *wxNORMAL_FONT;
-    m_selected_font = *wxNORMAL_FONT;
-    m_selected_font.SetWeight(wxBOLD);
+    m_normalFont = *wxNORMAL_FONT;
+    m_selectedFont = *wxNORMAL_FONT;
+    m_selectedFont.SetWeight(wxBOLD);
 
     SetArtProvider(new wxAuiDefaultTabArt);
 
 
     SetArtProvider(new wxAuiDefaultTabArt);
 
-    m_dummy_wnd = new wxWindow(this, wxID_ANY, wxPoint(0,0), wxSize(0,0));
-    m_dummy_wnd->SetSize(200, 200);
-    m_dummy_wnd->Show(false);
+    m_dummyWnd = new wxWindow(this, wxID_ANY, wxPoint(0,0), wxSize(0,0));
+    m_dummyWnd->SetSize(200, 200);
+    m_dummyWnd->Show(false);
 
     m_mgr.SetManagedWindow(this);
 
     m_mgr.SetManagedWindow(this);
+    m_mgr.SetFlags(wxAUI_MGR_DEFAULT);
+    m_mgr.SetDockSizeConstraint(1.0, 1.0); // no dock size constraint
 
 
-    m_mgr.AddPane(m_dummy_wnd,
-              wxAuiPaneInfo().Name(wxT("dummy")).Bottom().Show(false));
+    m_mgr.AddPane(m_dummyWnd,
+              wxAuiPaneInfo().Name(wxT("dummy")).Bottom().CaptionVisible(false).Show(false));
 
     m_mgr.Update();
 }
 
 wxAuiNotebook::~wxAuiNotebook()
 {
 
     m_mgr.Update();
 }
 
 wxAuiNotebook::~wxAuiNotebook()
 {
+    // Indicate we're deleting pages
+    SendDestroyEvent();
+
+    while ( GetPageCount() > 0 )
+        DeletePage(0);
+
     m_mgr.UnInit();
 }
 
     m_mgr.UnInit();
 }
 
@@ -2420,41 +2932,159 @@ void wxAuiNotebook::SetArtProvider(wxAuiTabArt* art)
 {
     m_tabs.SetArtProvider(art);
 
 {
     m_tabs.SetArtProvider(art);
 
-    SetTabCtrlHeight(CalculateTabCtrlHeight());
-}
-
-void wxAuiNotebook::SetTabCtrlHeight(int height)
-{
-    // if the tab control height needs to change, update
-    // all of our tab controls with the new height
-    if (m_tab_ctrl_height != height)
+    // Update the height and do nothing else if it did something but otherwise
+    // (i.e. if the new art provider uses the same height as the old one) we
+    // need to manually set the art provider for all tabs ourselves.
+    if ( !UpdateTabCtrlHeight() )
     {
     {
-        wxAuiTabArt* art = m_tabs.GetArtProvider();
-
-        m_tab_ctrl_height = height;
-
         wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
         wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
-        size_t i, pane_count = all_panes.GetCount();
-        for (i = 0; i < pane_count; ++i)
+        const size_t pane_count = all_panes.GetCount();
+        for (size_t i = 0; i < pane_count; ++i)
         {
             wxAuiPaneInfo& pane = all_panes.Item(i);
             if (pane.name == wxT("dummy"))
                 continue;
             wxTabFrame* tab_frame = (wxTabFrame*)pane.window;
             wxAuiTabCtrl* tabctrl = tab_frame->m_tabs;
         {
             wxAuiPaneInfo& pane = all_panes.Item(i);
             if (pane.name == wxT("dummy"))
                 continue;
             wxTabFrame* tab_frame = (wxTabFrame*)pane.window;
             wxAuiTabCtrl* tabctrl = tab_frame->m_tabs;
-            tab_frame->SetTabCtrlHeight(m_tab_ctrl_height);
             tabctrl->SetArtProvider(art->Clone());
             tabctrl->SetArtProvider(art->Clone());
-            tab_frame->DoSizing();
         }
     }
 }
 
         }
     }
 }
 
+// SetTabCtrlHeight() is the highest-level override of the
+// tab height.  A call to this function effectively enforces a
+// specified tab ctrl height, overriding all other considerations,
+// such as text or bitmap height.  It overrides any call to
+// SetUniformBitmapSize().  Specifying a height of -1 reverts
+// any previous call and returns to the default behaviour
+
+void wxAuiNotebook::SetTabCtrlHeight(int height)
+{
+    m_requestedTabCtrlHeight = height;
+
+    // if window is already initialized, recalculate the tab height
+    if (m_dummyWnd)
+    {
+        UpdateTabCtrlHeight();
+    }
+}
+
+
+// SetUniformBitmapSize() ensures that all tabs will have
+// the same height, even if some tabs don't have bitmaps
+// Passing wxDefaultSize to this function will instruct
+// the control to use dynamic tab height-- so when a tab
+// with a large bitmap is added, the tab ctrl's height will
+// automatically increase to accommodate the bitmap
+
+void wxAuiNotebook::SetUniformBitmapSize(const wxSize& size)
+{
+    m_requestedBmpSize = size;
+
+    // if window is already initialized, recalculate the tab height
+    if (m_dummyWnd)
+    {
+        UpdateTabCtrlHeight();
+    }
+}
+
+// UpdateTabCtrlHeight() does the actual tab resizing. It's meant
+// to be used internally
+bool wxAuiNotebook::UpdateTabCtrlHeight()
+{
+    // get the tab ctrl height we will use
+    int height = CalculateTabCtrlHeight();
+
+    // if the tab control height needs to change, update
+    // all of our tab controls with the new height
+    if (m_tabCtrlHeight == height)
+        return false;
+
+    wxAuiTabArt* art = m_tabs.GetArtProvider();
+
+    m_tabCtrlHeight = height;
+
+    wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
+    size_t i, pane_count = all_panes.GetCount();
+    for (i = 0; i < pane_count; ++i)
+    {
+        wxAuiPaneInfo& pane = all_panes.Item(i);
+        if (pane.name == wxT("dummy"))
+            continue;
+        wxTabFrame* tab_frame = (wxTabFrame*)pane.window;
+        wxAuiTabCtrl* tabctrl = tab_frame->m_tabs;
+        tab_frame->SetTabCtrlHeight(m_tabCtrlHeight);
+        tabctrl->SetArtProvider(art->Clone());
+        tab_frame->DoSizing();
+    }
+
+    return true;
+}
+
+void wxAuiNotebook::UpdateHintWindowSize()
+{
+    wxSize size = CalculateNewSplitSize();
+
+    // the placeholder hint window should be set to this size
+    wxAuiPaneInfo& info = m_mgr.GetPane(wxT("dummy"));
+    if (info.IsOk())
+    {
+        info.MinSize(size);
+        info.BestSize(size);
+        m_dummyWnd->SetSize(size);
+    }
+}
+
+
+// calculates the size of the new split
+wxSize wxAuiNotebook::CalculateNewSplitSize()
+{
+    // count number of tab controls
+    int tab_ctrl_count = 0;
+    wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
+    size_t i, pane_count = all_panes.GetCount();
+    for (i = 0; i < pane_count; ++i)
+    {
+        wxAuiPaneInfo& pane = all_panes.Item(i);
+        if (pane.name == wxT("dummy"))
+            continue;
+        tab_ctrl_count++;
+    }
+
+    wxSize new_split_size;
+
+    // if there is only one tab control, the first split
+    // should happen around the middle
+    if (tab_ctrl_count < 2)
+    {
+        new_split_size = GetClientSize();
+        new_split_size.x /= 2;
+        new_split_size.y /= 2;
+    }
+    else
+    {
+        // this is in place of a more complicated calculation
+        // that needs to be implemented
+        new_split_size = wxSize(180,180);
+    }
+
+    return new_split_size;
+}
+
 int wxAuiNotebook::CalculateTabCtrlHeight()
 {
 int wxAuiNotebook::CalculateTabCtrlHeight()
 {
+    // if a fixed tab ctrl height is specified,
+    // just return that instead of calculating a
+    // tab height
+    if (m_requestedTabCtrlHeight != -1)
+        return m_requestedTabCtrlHeight;
+
     // find out new best tab height
     wxAuiTabArt* art = m_tabs.GetArtProvider();
 
     // find out new best tab height
     wxAuiTabArt* art = m_tabs.GetArtProvider();
 
-    return art->GetBestTabCtrlSize(this, m_tabs.GetPages());
+    return art->GetBestTabCtrlSize(this,
+                                   m_tabs.GetPages(),
+                                   m_requestedBmpSize);
 }
 
 
 }
 
 
@@ -2506,6 +3136,12 @@ bool wxAuiNotebook::InsertPage(size_t page_idx,
                                bool select,
                                const wxBitmap& bitmap)
 {
                                bool select,
                                const wxBitmap& bitmap)
 {
+    wxASSERT_MSG(page, wxT("page pointer must be non-NULL"));
+    if (!page)
+        return false;
+
+    page->Reparent(this);
+
     wxAuiNotebookPage info;
     info.window = page;
     info.caption = caption;
     wxAuiNotebookPage info;
     info.window = page;
     info.caption = caption;
@@ -2519,22 +3155,30 @@ bool wxAuiNotebook::InsertPage(size_t page_idx,
 
     m_tabs.InsertPage(page, info, page_idx);
 
 
     m_tabs.InsertPage(page, info, page_idx);
 
+    // if that was the first page added, even if
+    // select is false, it must become the "current page"
+    // (though no select events will be fired)
+    if (!select && m_tabs.GetPageCount() == 1)
+        select = true;
+        //m_curPage = GetPageIndex(page);
+
     wxAuiTabCtrl* active_tabctrl = GetActiveTabCtrl();
     if (page_idx >= active_tabctrl->GetPageCount())
         active_tabctrl->AddPage(page, info);
     wxAuiTabCtrl* active_tabctrl = GetActiveTabCtrl();
     if (page_idx >= active_tabctrl->GetPageCount())
         active_tabctrl->AddPage(page, info);
-         else
+    else
         active_tabctrl->InsertPage(page, info, page_idx);
 
         active_tabctrl->InsertPage(page, info, page_idx);
 
-    SetTabCtrlHeight(CalculateTabCtrlHeight());
+    UpdateTabCtrlHeight();
     DoSizing();
     active_tabctrl->DoShowHide();
 
     DoSizing();
     active_tabctrl->DoShowHide();
 
+    // adjust selected index
+    if(m_curPage >= (int) page_idx)
+        m_curPage++;
+
     if (select)
     {
     if (select)
     {
-        int idx = m_tabs.GetIdxFromWindow(page);
-        wxASSERT_MSG(idx != -1, wxT("Invalid Page index returned on wxAuiNotebook::InsertPage()"));
-
-        SetSelection(idx);
+        SetSelectionToWindow(page);
     }
 
     return true;
     }
 
     return true;
@@ -2545,11 +3189,19 @@ bool wxAuiNotebook::InsertPage(size_t page_idx,
 // and destroys the window as well
 bool wxAuiNotebook::DeletePage(size_t page_idx)
 {
 // and destroys the window as well
 bool wxAuiNotebook::DeletePage(size_t page_idx)
 {
+    if (page_idx >= m_tabs.GetPageCount())
+        return false;
+
     wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
 
     wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
 
+    // hide the window in advance, as this will
+    // prevent flicker
+    ShowWnd(wnd, false);
+
     if (!RemovePage(page_idx))
         return false;
 
     if (!RemovePage(page_idx))
         return false;
 
+#if wxUSE_MDI
     // actually destroy the window now
     if (wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
     {
     // actually destroy the window now
     if (wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
     {
@@ -2558,7 +3210,8 @@ bool wxAuiNotebook::DeletePage(size_t page_idx)
         if (!wxPendingDelete.Member(wnd))
             wxPendingDelete.Append(wnd);
     }
         if (!wxPendingDelete.Member(wnd))
             wxPendingDelete.Append(wnd);
     }
-     else
+    else
+#endif
     {
         wnd->Destroy();
     }
     {
         wnd->Destroy();
     }
@@ -2572,39 +3225,28 @@ bool wxAuiNotebook::DeletePage(size_t page_idx)
 // but does not destroy the window
 bool wxAuiNotebook::RemovePage(size_t page_idx)
 {
 // but does not destroy the window
 bool wxAuiNotebook::RemovePage(size_t page_idx)
 {
+    // save active window pointer
+    wxWindow* active_wnd = NULL;
+    if (m_curPage >= 0)
+        active_wnd = m_tabs.GetWindowFromIdx(m_curPage);
+
+    // save pointer of window being deleted
     wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
     wxWindow* new_active = NULL;
 
     wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
     wxWindow* new_active = NULL;
 
+    // make sure we found the page
+    if (!wnd)
+        return false;
+
     // find out which onscreen tab ctrl owns this tab
     wxAuiTabCtrl* ctrl;
     int ctrl_idx;
     if (!FindTab(wnd, &ctrl, &ctrl_idx))
         return false;
 
     // find out which onscreen tab ctrl owns this tab
     wxAuiTabCtrl* ctrl;
     int ctrl_idx;
     if (!FindTab(wnd, &ctrl, &ctrl_idx))
         return false;
 
-    // find a new page and set it as active
-    int new_idx = ctrl_idx+1;
-    if (new_idx >= (int)ctrl->GetPageCount())
-        new_idx = ctrl_idx-1;
+    bool is_curpage = (m_curPage == (int)page_idx);
+    bool is_active_in_split = ctrl->GetPage(ctrl_idx).active;
 
 
-    if (new_idx >= 0 && new_idx < (int)ctrl->GetPageCount())
-    {
-        new_active = ctrl->GetWindowFromIdx(new_idx);
-    }
-     else
-    {
-        // set the active page to the first page that
-        // isn't the one being deleted
-        size_t i, page_count = m_tabs.GetPageCount();
-        for (i = 0; i < page_count; ++i)
-        {
-            wxWindow* w = m_tabs.GetWindowFromIdx(i);
-            if (wnd != w)
-            {
-                new_active = m_tabs.GetWindowFromIdx(i);
-                break;
-            }
-        }
-    }
 
     // remove the tab from main catalog
     if (!m_tabs.RemovePage(wnd))
 
     // remove the tab from main catalog
     if (!m_tabs.RemovePage(wnd))
@@ -2613,16 +3255,60 @@ bool wxAuiNotebook::RemovePage(size_t page_idx)
     // remove the tab from the onscreen tab ctrl
     ctrl->RemovePage(wnd);
 
     // remove the tab from the onscreen tab ctrl
     ctrl->RemovePage(wnd);
 
+    if (is_active_in_split)
+    {
+        int ctrl_new_page_count = (int)ctrl->GetPageCount();
+
+        if (ctrl_idx >= ctrl_new_page_count)
+            ctrl_idx = ctrl_new_page_count-1;
 
 
-    RemoveEmptyTabFrames();
+        if (ctrl_idx >= 0 && ctrl_idx < (int)ctrl->GetPageCount())
+        {
+            // set new page as active in the tab split
+            ctrl->SetActivePage(ctrl_idx);
+
+            // if the page deleted was the current page for the
+            // entire tab control, then record the window
+            // pointer of the new active page for activation
+            if (is_curpage)
+            {
+                new_active = ctrl->GetWindowFromIdx(ctrl_idx);
+            }
+        }
+    }
+    else
+    {
+        // we are not deleting the active page, so keep it the same
+        new_active = active_wnd;
+    }
 
 
-    // set new active pane
-    if (new_active)
+
+    if (!new_active)
     {
     {
-        m_curpage = -1;
-        SetSelection(m_tabs.GetIdxFromWindow(new_active));
+        // we haven't yet found a new page to active,
+        // so select the next page from the main tab
+        // catalogue
+
+        if (page_idx < m_tabs.GetPageCount())
+        {
+            new_active = m_tabs.GetPage(page_idx).window;
+        }
+
+        if (!new_active && m_tabs.GetPageCount() > 0)
+        {
+            new_active = m_tabs.GetPage(0).window;
+        }
     }
 
     }
 
+
+    RemoveEmptyTabFrames();
+
+    m_curPage = wxNOT_FOUND;
+
+    // set new active pane unless we're being destroyed anyhow
+    if (new_active && !m_isBeingDeleted)
+        SetSelectionToWindow(new_active);
+
     return true;
 }
 
     return true;
 }
 
@@ -2659,6 +3345,16 @@ bool wxAuiNotebook::SetPageText(size_t page_idx, const wxString& text)
     return true;
 }
 
     return true;
 }
 
+// returns the page caption
+wxString wxAuiNotebook::GetPageText(size_t page_idx) const
+{
+    if (page_idx >= m_tabs.GetPageCount())
+        return wxEmptyString;
+
+    // update our own tab catalog
+    const wxAuiNotebookPage& page_info = m_tabs.GetPage(page_idx);
+    return page_info.caption;
+}
 
 bool wxAuiNotebook::SetPageBitmap(size_t page_idx, const wxBitmap& bitmap)
 {
 
 bool wxAuiNotebook::SetPageBitmap(size_t page_idx, const wxBitmap& bitmap)
 {
@@ -2670,7 +3366,7 @@ bool wxAuiNotebook::SetPageBitmap(size_t page_idx, const wxBitmap& bitmap)
     page_info.bitmap = bitmap;
 
     // tab height might have changed
     page_info.bitmap = bitmap;
 
     // tab height might have changed
-    SetTabCtrlHeight(CalculateTabCtrlHeight());
+    UpdateTabCtrlHeight();
 
     // update what's on screen
     wxAuiTabCtrl* ctrl;
 
     // update what's on screen
     wxAuiTabCtrl* ctrl;
@@ -2686,69 +3382,50 @@ bool wxAuiNotebook::SetPageBitmap(size_t page_idx, const wxBitmap& bitmap)
     return true;
 }
 
     return true;
 }
 
+// returns the page bitmap
+wxBitmap wxAuiNotebook::GetPageBitmap(size_t page_idx) const
+{
+    if (page_idx >= m_tabs.GetPageCount())
+        return wxBitmap();
+
+    // update our own tab catalog
+    const wxAuiNotebookPage& page_info = m_tabs.GetPage(page_idx);
+    return page_info.bitmap;
+}
 
 // GetSelection() returns the index of the currently active page
 int wxAuiNotebook::GetSelection() const
 {
 
 // GetSelection() returns the index of the currently active page
 int wxAuiNotebook::GetSelection() const
 {
-    return m_curpage;
+    return m_curPage;
 }
 
 // SetSelection() sets the currently active page
 }
 
 // SetSelection() sets the currently active page
-size_t wxAuiNotebook::SetSelection(size_t new_page)
+int wxAuiNotebook::SetSelection(size_t new_page)
 {
 {
-    wxWindow* wnd = m_tabs.GetWindowFromIdx(new_page);
-    if (!wnd)
-        return m_curpage;
-
-    wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, m_windowId);
-    evt.SetSelection(new_page);
-    evt.SetOldSelection(m_curpage);
-    evt.SetEventObject(this);
-    if (!GetEventHandler()->ProcessEvent(evt) || evt.IsAllowed())
-    {
-        int old_curpage = m_curpage;
-        m_curpage = new_page;
-
-        // program allows the page change
-        evt.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED);
-        (void)GetEventHandler()->ProcessEvent(evt);
-
-
-        wxAuiTabCtrl* ctrl;
-        int ctrl_idx;
-        if (FindTab(wnd, &ctrl, &ctrl_idx))
-        {
-            m_tabs.SetActivePage(wnd);
+    return DoModifySelection(new_page, true);
+}
 
 
-            ctrl->SetActivePage(ctrl_idx);
-            DoSizing();
-            ctrl->DoShowHide();
+void wxAuiNotebook::SetSelectionToWindow(wxWindow *win)
+{
+    const int idx = m_tabs.GetIdxFromWindow(win);
+    wxCHECK_RET( idx != wxNOT_FOUND, wxT("invalid notebook page") );
 
 
 
 
+    // since a tab was clicked, let the parent know that we received
+    // the focus, even if we will assign that focus immediately
+    // to the child tab in the SetSelection call below
+    // (the child focus event will also let wxAuiManager, if any,
+    // know that the notebook control has been activated)
 
 
-            // set fonts
-            wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
-            size_t i, pane_count = all_panes.GetCount();
-            for (i = 0; i < pane_count; ++i)
-            {
-                wxAuiPaneInfo& pane = all_panes.Item(i);
-                if (pane.name == wxT("dummy"))
-                    continue;
-                wxAuiTabCtrl* tabctrl = ((wxTabFrame*)pane.window)->m_tabs;
-                if (tabctrl != ctrl)
-                    tabctrl->SetSelectedFont(m_normal_font);
-                     else
-                    tabctrl->SetSelectedFont(m_selected_font);
-                tabctrl->Refresh();
-            }
-
-            wnd->SetFocus();
-
-            return old_curpage;
-        }
+    wxWindow* parent = GetParent();
+    if (parent)
+    {
+        wxChildFocusEvent eventFocus(this);
+        parent->GetEventHandler()->ProcessEvent(eventFocus);
     }
 
     }
 
-    return m_curpage;
+
+    SetSelection(idx);
 }
 
 // GetPageCount() returns the total number of
 }
 
 // GetPageCount() returns the total number of
@@ -2786,13 +3463,13 @@ void wxAuiNotebook::DoSizing()
 // called to determine which control gets new windows being added
 wxAuiTabCtrl* wxAuiNotebook::GetActiveTabCtrl()
 {
 // called to determine which control gets new windows being added
 wxAuiTabCtrl* wxAuiNotebook::GetActiveTabCtrl()
 {
-    if (m_curpage >= 0 && m_curpage < (int)m_tabs.GetPageCount())
+    if (m_curPage >= 0 && m_curPage < (int)m_tabs.GetPageCount())
     {
         wxAuiTabCtrl* ctrl;
         int idx;
 
         // find the tab ctrl with the current page
     {
         wxAuiTabCtrl* ctrl;
         int idx;
 
         // find the tab ctrl with the current page
-        if (FindTab(m_tabs.GetPage(m_curpage).window,
+        if (FindTab(m_tabs.GetPage(m_curPage).window,
                     &ctrl, &idx))
         {
             return ctrl;
                     &ctrl, &idx))
         {
             return ctrl;
@@ -2813,12 +3490,12 @@ wxAuiTabCtrl* wxAuiNotebook::GetActiveTabCtrl()
 
     // If there is no tabframe at all, create one
     wxTabFrame* tabframe = new wxTabFrame;
 
     // If there is no tabframe at all, create one
     wxTabFrame* tabframe = new wxTabFrame;
-    tabframe->SetTabCtrlHeight(m_tab_ctrl_height);
+    tabframe->SetTabCtrlHeight(m_tabCtrlHeight);
     tabframe->m_tabs = new wxAuiTabCtrl(this,
     tabframe->m_tabs = new wxAuiTabCtrl(this,
-                                        m_tab_id_counter++,
+                                        m_tabIdCounter++,
                                         wxDefaultPosition,
                                         wxDefaultSize,
                                         wxDefaultPosition,
                                         wxDefaultSize,
-                                        wxNO_BORDER);
+                                        wxNO_BORDER|wxWANTS_CHARS);
     tabframe->m_tabs->SetFlags(m_flags);
     tabframe->m_tabs->SetArtProvider(m_tabs.GetArtProvider()->Clone());
     m_mgr.AddPane(tabframe,
     tabframe->m_tabs->SetFlags(m_flags);
     tabframe->m_tabs->SetArtProvider(m_tabs.GetArtProvider()->Clone());
     m_mgr.AddPane(tabframe,
@@ -2841,51 +3518,166 @@ bool wxAuiNotebook::FindTab(wxWindow* page, wxAuiTabCtrl** ctrl, int* idx)
         if (all_panes.Item(i).name == wxT("dummy"))
             continue;
 
         if (all_panes.Item(i).name == wxT("dummy"))
             continue;
 
-        wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
+        wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
+
+        int page_idx = tabframe->m_tabs->GetIdxFromWindow(page);
+        if (page_idx != -1)
+        {
+            *ctrl = tabframe->m_tabs;
+            *idx = page_idx;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void wxAuiNotebook::Split(size_t page, int direction)
+{
+    wxSize cli_size = GetClientSize();
+
+    // get the page's window pointer
+    wxWindow* wnd = GetPage(page);
+    if (!wnd)
+        return;
+
+    // notebooks with 1 or less pages can't be split
+    if (GetPageCount() < 2)
+        return;
+
+    // find out which tab control the page currently belongs to
+    wxAuiTabCtrl *src_tabs, *dest_tabs;
+    int src_idx = -1;
+    src_tabs = NULL;
+    if (!FindTab(wnd, &src_tabs, &src_idx))
+        return;
+    if (!src_tabs || src_idx == -1)
+        return;
+
+    // choose a split size
+    wxSize split_size;
+    if (GetPageCount() > 2)
+    {
+        split_size = CalculateNewSplitSize();
+    }
+    else
+    {
+        // because there are two panes, always split them
+        // equally
+        split_size = GetClientSize();
+        split_size.x /= 2;
+        split_size.y /= 2;
+    }
+
+
+    // create a new tab frame
+    wxTabFrame* new_tabs = new wxTabFrame;
+    new_tabs->m_rect = wxRect(wxPoint(0,0), split_size);
+    new_tabs->SetTabCtrlHeight(m_tabCtrlHeight);
+    new_tabs->m_tabs = new wxAuiTabCtrl(this,
+                                        m_tabIdCounter++,
+                                        wxDefaultPosition,
+                                        wxDefaultSize,
+                                        wxNO_BORDER|wxWANTS_CHARS);
+    new_tabs->m_tabs->SetArtProvider(m_tabs.GetArtProvider()->Clone());
+    new_tabs->m_tabs->SetFlags(m_flags);
+    dest_tabs = new_tabs->m_tabs;
+
+    // create a pane info structure with the information
+    // about where the pane should be added
+    wxAuiPaneInfo paneInfo = wxAuiPaneInfo().Bottom().CaptionVisible(false);
+    wxPoint mouse_pt;
+
+    if (direction == wxLEFT)
+    {
+        paneInfo.Left();
+        mouse_pt = wxPoint(0, cli_size.y/2);
+    }
+    else if (direction == wxRIGHT)
+    {
+        paneInfo.Right();
+        mouse_pt = wxPoint(cli_size.x, cli_size.y/2);
+    }
+    else if (direction == wxTOP)
+    {
+        paneInfo.Top();
+        mouse_pt = wxPoint(cli_size.x/2, 0);
+    }
+    else if (direction == wxBOTTOM)
+    {
+        paneInfo.Bottom();
+        mouse_pt = wxPoint(cli_size.x/2, cli_size.y);
+    }
+
+    m_mgr.AddPane(new_tabs, paneInfo, mouse_pt);
+    m_mgr.Update();
+
+    // remove the page from the source tabs
+    wxAuiNotebookPage page_info = src_tabs->GetPage(src_idx);
+    page_info.active = false;
+    src_tabs->RemovePage(page_info.window);
+    if (src_tabs->GetPageCount() > 0)
+    {
+        src_tabs->SetActivePage((size_t)0);
+        src_tabs->DoShowHide();
+        src_tabs->Refresh();
+    }
+
+
+    // add the page to the destination tabs
+    dest_tabs->InsertPage(page_info.window, page_info, 0);
+
+    if (src_tabs->GetPageCount() == 0)
+    {
+        RemoveEmptyTabFrames();
+    }
+
+    DoSizing();
+    dest_tabs->DoShowHide();
+    dest_tabs->Refresh();
+
+    // force the set selection function reset the selection
+    m_curPage = -1;
 
 
-        int page_idx = tabframe->m_tabs->GetIdxFromWindow(page);
-        if (page_idx != -1)
-        {
-            *ctrl = tabframe->m_tabs;
-            *idx = page_idx;
-            return true;
-        }
-    }
+    // set the active page to the one we just split off
+    SetSelectionToPage(page_info);
 
 
-    return false;
+    UpdateHintWindowSize();
 }
 
 
 }
 
 
-void wxAuiNotebook::OnEraseBackground(wxEraseEvent&)
+void wxAuiNotebook::OnSize(wxSizeEvent& evt)
 {
 {
-}
+    UpdateHintWindowSize();
 
 
-void wxAuiNotebook::OnSize(wxSizeEvent&)
-{
+    evt.Skip();
 }
 
 }
 
-void wxAuiNotebook::OnTabClicked(wxCommandEvent& command_evt)
+void wxAuiNotebook::OnTabClicked(wxAuiNotebookEvent& evt)
 {
 {
-    wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt;
-
     wxAuiTabCtrl* ctrl = (wxAuiTabCtrl*)evt.GetEventObject();
     wxASSERT(ctrl != NULL);
 
     wxWindow* wnd = ctrl->GetWindowFromIdx(evt.GetSelection());
     wxASSERT(wnd != NULL);
 
     wxAuiTabCtrl* ctrl = (wxAuiTabCtrl*)evt.GetEventObject();
     wxASSERT(ctrl != NULL);
 
     wxWindow* wnd = ctrl->GetWindowFromIdx(evt.GetSelection());
     wxASSERT(wnd != NULL);
 
-    int idx = m_tabs.GetIdxFromWindow(wnd);
-    wxASSERT(idx != -1);
+    SetSelectionToWindow(wnd);
+}
 
 
-    SetSelection(idx);
+void wxAuiNotebook::OnTabBgDClick(wxAuiNotebookEvent& WXUNUSED(evt))
+{
+    // notify owner that the tabbar background has been double-clicked
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, m_windowId);
+    e.SetEventObject(this);
+    GetEventHandler()->ProcessEvent(e);
 }
 
 }
 
-void wxAuiNotebook::OnTabBeginDrag(wxCommandEvent&)
+void wxAuiNotebook::OnTabBeginDrag(wxAuiNotebookEvent&)
 {
 {
-    m_last_drag_x = 0;
+    m_lastDragX = 0;
 }
 
 }
 
-void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt)
+void wxAuiNotebook::OnTabDragMotion(wxAuiNotebookEvent& evt)
 {
     wxPoint screen_pt = ::wxGetMousePosition();
     wxPoint client_pt = ScreenToClient(screen_pt);
 {
     wxPoint screen_pt = ::wxGetMousePosition();
     wxPoint client_pt = ScreenToClient(screen_pt);
@@ -2921,10 +3713,10 @@ void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt)
 
             // prevent jumpy drag
             if ((src_idx == dest_idx) || dest_idx == -1 ||
 
             // prevent jumpy drag
             if ((src_idx == dest_idx) || dest_idx == -1 ||
-                (src_idx > dest_idx && m_last_drag_x <= pt.x) ||
-                (src_idx < dest_idx && m_last_drag_x >= pt.x))
+                (src_idx > dest_idx && m_lastDragX <= pt.x) ||
+                (src_idx < dest_idx && m_lastDragX >= pt.x))
             {
             {
-                m_last_drag_x = pt.x;
+                m_lastDragX = pt.x;
                 return;
             }
 
                 return;
             }
 
@@ -2934,7 +3726,7 @@ void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt)
             dest_tabs->SetActivePage((size_t)dest_idx);
             dest_tabs->DoShowHide();
             dest_tabs->Refresh();
             dest_tabs->SetActivePage((size_t)dest_idx);
             dest_tabs->DoShowHide();
             dest_tabs->Refresh();
-            m_last_drag_x = pt.x;
+            m_lastDragX = pt.x;
 
         }
 
 
         }
 
@@ -2975,7 +3767,7 @@ void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt)
                 }
             }
         }
                 }
             }
         }
-         else
+        else
         {
             if (!dest_tabs)
             {
         {
             if (!dest_tabs)
             {
@@ -3008,28 +3800,23 @@ void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt)
         ClientToScreen(&hint_rect.x, &hint_rect.y);
         m_mgr.ShowHint(hint_rect);
     }
         ClientToScreen(&hint_rect.x, &hint_rect.y);
         m_mgr.ShowHint(hint_rect);
     }
-     else
+    else
     {
     {
-        m_mgr.DrawHintRect(m_dummy_wnd, client_pt, zero);
+        m_mgr.DrawHintRect(m_dummyWnd, client_pt, zero);
     }
 }
 
 
 
     }
 }
 
 
 
-void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
+void wxAuiNotebook::OnTabEndDrag(wxAuiNotebookEvent& evt)
 {
 {
-    wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt;
-
     m_mgr.HideHint();
 
 
     wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject();
     m_mgr.HideHint();
 
 
     wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject();
-    wxAuiTabCtrl* dest_tabs = NULL;
-    if (src_tabs)
-    {
-        // set cursor back to an arrow
-        src_tabs->SetCursor(wxCursor(wxCURSOR_ARROW));
-    }
+    wxCHECK_RET( src_tabs, wxT("no source object?") );
+
+    src_tabs->SetCursor(wxCursor(wxCURSOR_ARROW));
 
     // get the mouse position, which will be used to determine the drop point
     wxPoint mouse_screen_pt = ::wxGetMousePosition();
 
     // get the mouse position, which will be used to determine the drop point
     wxPoint mouse_screen_pt = ::wxGetMousePosition();
@@ -3077,11 +3864,24 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
                 int src_idx = evt.GetSelection();
                 wxWindow* src_page = src_tabs->GetWindowFromIdx(src_idx);
 
                 int src_idx = evt.GetSelection();
                 wxWindow* src_page = src_tabs->GetWindowFromIdx(src_idx);
 
+                // Check that it's not an impossible parent relationship
+                wxWindow* p = nb;
+                while (p && !p->IsTopLevel())
+                {
+                    if (p == src_page)
+                    {
+                        return;
+                    }
+                    p = p->GetParent();
+                }
+
                 // get main index of the page
                 int main_idx = m_tabs.GetIdxFromWindow(src_page);
                 // get main index of the page
                 int main_idx = m_tabs.GetIdxFromWindow(src_page);
+                wxCHECK_RET( main_idx != wxNOT_FOUND, wxT("no source page?") );
+
 
                 // make a copy of the page info
 
                 // make a copy of the page info
-                wxAuiNotebookPage page_info = m_tabs.GetPage((size_t)main_idx);
+                wxAuiNotebookPage page_info = m_tabs.GetPage(main_idx);
 
                 // remove the page from the source notebook
                 RemovePage(main_idx);
 
                 // remove the page from the source notebook
                 RemovePage(main_idx);
@@ -3114,7 +3914,14 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
                 dest_tabs->Refresh();
 
                 // set the selection in the destination tab control
                 dest_tabs->Refresh();
 
                 // set the selection in the destination tab control
-                nb->SetSelection(nb->m_tabs.GetIdxFromWindow(page_info.window));
+                nb->SetSelectionToPage(page_info);
+
+                // notify owner that the tab has been dragged
+                wxAuiNotebookEvent e2(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, m_windowId);
+                e2.SetSelection(evt.GetSelection());
+                e2.SetOldSelection(evt.GetSelection());
+                e2.SetEventObject(this);
+                GetEventHandler()->ProcessEvent(e2);
 
                 return;
             }
 
                 return;
             }
@@ -3125,6 +3932,8 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
 
 
     // only perform a tab split if it's allowed
 
 
     // only perform a tab split if it's allowed
+    wxAuiTabCtrl* dest_tabs = NULL;
+
     if ((m_flags & wxAUI_NB_TAB_SPLIT) && m_tabs.GetPageCount() >= 2)
     {
         // If the pointer is in an existing tab frame, do a tab insert
     if ((m_flags & wxAUI_NB_TAB_SPLIT) && m_tabs.GetPageCount() >= 2)
     {
         // If the pointer is in an existing tab frame, do a tab insert
@@ -3147,10 +3956,10 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
                 insert_idx = dest_tabs->GetIdxFromWindow(target);
             }
         }
                 insert_idx = dest_tabs->GetIdxFromWindow(target);
             }
         }
-         else
+        else
         {
             wxPoint zero(0,0);
         {
             wxPoint zero(0,0);
-            wxRect rect = m_mgr.CalculateHintRect(m_dummy_wnd,
+            wxRect rect = m_mgr.CalculateHintRect(m_dummyWnd,
                                                   mouse_client_pt,
                                                   zero);
             if (rect.IsEmpty())
                                                   mouse_client_pt,
                                                   zero);
             if (rect.IsEmpty())
@@ -3159,15 +3968,15 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
                 return;
             }
 
                 return;
             }
 
-
             // If there is no tabframe at all, create one
             wxTabFrame* new_tabs = new wxTabFrame;
             // If there is no tabframe at all, create one
             wxTabFrame* new_tabs = new wxTabFrame;
-            new_tabs->SetTabCtrlHeight(m_tab_ctrl_height);
+            new_tabs->m_rect = wxRect(wxPoint(0,0), CalculateNewSplitSize());
+            new_tabs->SetTabCtrlHeight(m_tabCtrlHeight);
             new_tabs->m_tabs = new wxAuiTabCtrl(this,
             new_tabs->m_tabs = new wxAuiTabCtrl(this,
-                                                m_tab_id_counter++,
+                                                m_tabIdCounter++,
                                                 wxDefaultPosition,
                                                 wxDefaultSize,
                                                 wxDefaultPosition,
                                                 wxDefaultSize,
-                                                wxNO_BORDER);
+                                                wxNO_BORDER|wxWANTS_CHARS);
             new_tabs->m_tabs->SetArtProvider(m_tabs.GetArtProvider()->Clone());
             new_tabs->m_tabs->SetFlags(m_flags);
 
             new_tabs->m_tabs->SetArtProvider(m_tabs.GetArtProvider()->Clone());
             new_tabs->m_tabs->SetFlags(m_flags);
 
@@ -3207,12 +4016,37 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
         dest_tabs->DoShowHide();
         dest_tabs->Refresh();
 
         dest_tabs->DoShowHide();
         dest_tabs->Refresh();
 
-        SetSelection(m_tabs.GetIdxFromWindow(page_info.window));
+        // force the set selection function reset the selection
+        m_curPage = -1;
+
+        // set the active page to the one we just split off
+        SetSelectionToPage(page_info);
+
+        UpdateHintWindowSize();
     }
     }
+
+    // notify owner that the tab has been dragged
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, m_windowId);
+    e.SetSelection(evt.GetSelection());
+    e.SetOldSelection(evt.GetSelection());
+    e.SetEventObject(this);
+    GetEventHandler()->ProcessEvent(e);
 }
 
 
 
 }
 
 
 
+void wxAuiNotebook::OnTabCancelDrag(wxAuiNotebookEvent& command_evt)
+{
+    wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt;
+
+    m_mgr.HideHint();
+
+    wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject();
+    wxCHECK_RET( src_tabs, wxT("no source object?") );
+
+    src_tabs->SetCursor(wxCursor(wxCURSOR_ARROW));
+}
+
 wxAuiTabCtrl* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint& pt)
 {
     // if we've just removed the last tab from the source
 wxAuiTabCtrl* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint& pt)
 {
     // if we've just removed the last tab from the source
@@ -3273,7 +4107,8 @@ void wxAuiNotebook::RemoveEmptyTabFrames()
             // window closing, refreshs are pending
             if (!wxPendingDelete.Member(tab_frame->m_tabs))
                 wxPendingDelete.Append(tab_frame->m_tabs);
             // window closing, refreshs are pending
             if (!wxPendingDelete.Member(tab_frame->m_tabs))
                 wxPendingDelete.Append(tab_frame->m_tabs);
-            //tab_frame->m_tabs->Destroy();
+
+            tab_frame->m_tabs = NULL;
 
             delete tab_frame;
         }
 
             delete tab_frame;
         }
@@ -3301,38 +4136,143 @@ void wxAuiNotebook::RemoveEmptyTabFrames()
         m_mgr.GetPane(first_good).Centre();
     }
 
         m_mgr.GetPane(first_good).Centre();
     }
 
-    m_mgr.Update();
+    if (!m_isBeingDeleted)
+        m_mgr.Update();
 }
 
 }
 
-void wxAuiNotebook::OnChildFocus(wxChildFocusEvent& evt)
+void wxAuiNotebook::OnChildFocusNotebook(wxChildFocusEvent& evt)
 {
 {
+    evt.Skip();
+
+    // if we're dragging a tab, don't change the current selection.
+    // This code prevents a bug that used to happen when the hint window
+    // was hidden.  In the bug, the focus would return to the notebook
+    // child, which would then enter this handler and call
+    // SetSelection, which is not desired turn tab dragging.
+
+    wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
+    size_t i, pane_count = all_panes.GetCount();
+    for (i = 0; i < pane_count; ++i)
+    {
+        wxAuiPaneInfo& pane = all_panes.Item(i);
+        if (pane.name == wxT("dummy"))
+            continue;
+        wxTabFrame* tabframe = (wxTabFrame*)pane.window;
+        if (tabframe->m_tabs->IsDragging())
+            return;
+    }
+
+
+    // change the tab selection to the child
+    // which was focused
     int idx = m_tabs.GetIdxFromWindow(evt.GetWindow());
     int idx = m_tabs.GetIdxFromWindow(evt.GetWindow());
-    if (idx != -1 && idx != m_curpage)
+    if (idx != -1 && idx != m_curPage)
     {
         SetSelection(idx);
     }
 }
 
     {
         SetSelection(idx);
     }
 }
 
+void wxAuiNotebook::OnNavigationKeyNotebook(wxNavigationKeyEvent& event)
+{
+    if ( event.IsWindowChange() ) {
+        // change pages
+        // FIXME: the problem with this is that if we have a split notebook,
+        // we selection may go all over the place.
+        AdvanceSelection(event.GetDirection());
+    }
+    else {
+        // we get this event in 3 cases
+        //
+        // a) one of our pages might have generated it because the user TABbed
+        // out from it in which case we should propagate the event upwards and
+        // our parent will take care of setting the focus to prev/next sibling
+        //
+        // or
+        //
+        // b) the parent panel wants to give the focus to us so that we
+        // forward it to our selected page. We can't deal with this in
+        // OnSetFocus() because we don't know which direction the focus came
+        // from in this case and so can't choose between setting the focus to
+        // first or last panel child
+        //
+        // or
+        //
+        // c) we ourselves (see MSWTranslateMessage) generated the event
+        //
+        wxWindow * const parent = GetParent();
+
+        // the wxObject* casts are required to avoid MinGW GCC 2.95.3 ICE
+        const bool isFromParent = event.GetEventObject() == (wxObject*) parent;
+        const bool isFromSelf = event.GetEventObject() == (wxObject*) this;
+
+        if ( isFromParent || isFromSelf )
+        {
+            // no, it doesn't come from child, case (b) or (c): forward to a
+            // page but only if direction is backwards (TAB) or from ourselves,
+            if ( GetSelection() != wxNOT_FOUND &&
+                    (!event.GetDirection() || isFromSelf) )
+            {
+                // so that the page knows that the event comes from it's parent
+                // and is being propagated downwards
+                event.SetEventObject(this);
+
+                wxWindow *page = GetPage(GetSelection());
+                if ( !page->GetEventHandler()->ProcessEvent(event) )
+                {
+                    page->SetFocus();
+                }
+                //else: page manages focus inside it itself
+            }
+            else // otherwise set the focus to the notebook itself
+            {
+                SetFocus();
+            }
+        }
+        else
+        {
+            // it comes from our child, case (a), pass to the parent, but only
+            // if the direction is forwards. Otherwise set the focus to the
+            // notebook itself. The notebook is always the 'first' control of a
+            // page.
+            if ( !event.GetDirection() )
+            {
+                SetFocus();
+            }
+            else if ( parent )
+            {
+                event.SetCurrentFocus(this);
+                parent->GetEventHandler()->ProcessEvent(event);
+            }
+        }
+    }
+}
 
 
-void wxAuiNotebook::OnTabButton(wxCommandEvent& command_evt)
+void wxAuiNotebook::OnTabButton(wxAuiNotebookEvent& evt)
 {
 {
-    wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt;
     wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject();
 
     int button_id = evt.GetInt();
 
     if (button_id == wxAUI_BUTTON_CLOSE)
     {
     wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject();
 
     int button_id = evt.GetInt();
 
     if (button_id == wxAUI_BUTTON_CLOSE)
     {
-        int selection = tabs->GetActivePage();
+        int selection = evt.GetSelection();
+
+        if (selection == -1)
+        {
+            // if the close button is to the right, use the active
+            // page selection to determine which page to close
+            selection = tabs->GetActivePage();
+        }
 
         if (selection != -1)
         {
             wxWindow* close_wnd = tabs->GetWindowFromIdx(selection);
 
 
         if (selection != -1)
         {
             wxWindow* close_wnd = tabs->GetWindowFromIdx(selection);
 
-
             // ask owner if it's ok to close the tab
             wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, m_windowId);
             e.SetSelection(m_tabs.GetIdxFromWindow(close_wnd));
             // ask owner if it's ok to close the tab
             wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, m_windowId);
             e.SetSelection(m_tabs.GetIdxFromWindow(close_wnd));
+            const int idx = m_tabs.GetIdxFromWindow(close_wnd);
+            e.SetSelection(idx);
             e.SetOldSelection(evt.GetSelection());
             e.SetEventObject(this);
             GetEventHandler()->ProcessEvent(e);
             e.SetOldSelection(evt.GetSelection());
             e.SetEventObject(this);
             GetEventHandler()->ProcessEvent(e);
@@ -3340,20 +4280,356 @@ void wxAuiNotebook::OnTabButton(wxCommandEvent& command_evt)
                 return;
 
 
                 return;
 
 
+#if wxUSE_MDI
             if (close_wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
             {
                 close_wnd->Close();
             }
             if (close_wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
             {
                 close_wnd->Close();
             }
-             else
+            else
+#endif
             {
                 int main_idx = m_tabs.GetIdxFromWindow(close_wnd);
             {
                 int main_idx = m_tabs.GetIdxFromWindow(close_wnd);
+                wxCHECK_RET( main_idx != wxNOT_FOUND, wxT("no page to delete?") );
+
                 DeletePage(main_idx);
             }
                 DeletePage(main_idx);
             }
+
+            // notify owner that the tab has been closed
+            wxAuiNotebookEvent e2(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, m_windowId);
+            e2.SetSelection(idx);
+            e2.SetEventObject(this);
+            GetEventHandler()->ProcessEvent(e2);
         }
     }
 }
 
 
         }
     }
 }
 
 
+void wxAuiNotebook::OnTabMiddleDown(wxAuiNotebookEvent& evt)
+{
+    // patch event through to owner
+    wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject();
+    wxWindow* wnd = tabs->GetWindowFromIdx(evt.GetSelection());
+
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, m_windowId);
+    e.SetSelection(m_tabs.GetIdxFromWindow(wnd));
+    e.SetEventObject(this);
+    GetEventHandler()->ProcessEvent(e);
+}
+
+void wxAuiNotebook::OnTabMiddleUp(wxAuiNotebookEvent& evt)
+{
+    // if the wxAUI_NB_MIDDLE_CLICK_CLOSE is specified, middle
+    // click should act like a tab close action.  However, first
+    // give the owner an opportunity to handle the middle up event
+    // for custom action
+
+    wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject();
+    wxWindow* wnd = tabs->GetWindowFromIdx(evt.GetSelection());
+
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, m_windowId);
+    e.SetSelection(m_tabs.GetIdxFromWindow(wnd));
+    e.SetEventObject(this);
+    if (GetEventHandler()->ProcessEvent(e))
+        return;
+    if (!e.IsAllowed())
+        return;
+
+    // check if we are supposed to close on middle-up
+    if ((m_flags & wxAUI_NB_MIDDLE_CLICK_CLOSE) == 0)
+        return;
+
+    // simulate the user pressing the close button on the tab
+    evt.SetInt(wxAUI_BUTTON_CLOSE);
+    OnTabButton(evt);
+}
+
+void wxAuiNotebook::OnTabRightDown(wxAuiNotebookEvent& evt)
+{
+    // patch event through to owner
+    wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject();
+    wxWindow* wnd = tabs->GetWindowFromIdx(evt.GetSelection());
+
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, m_windowId);
+    e.SetSelection(m_tabs.GetIdxFromWindow(wnd));
+    e.SetEventObject(this);
+    GetEventHandler()->ProcessEvent(e);
+}
+
+void wxAuiNotebook::OnTabRightUp(wxAuiNotebookEvent& evt)
+{
+    // patch event through to owner
+    wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject();
+    wxWindow* wnd = tabs->GetWindowFromIdx(evt.GetSelection());
+
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, m_windowId);
+    e.SetSelection(m_tabs.GetIdxFromWindow(wnd));
+    e.SetEventObject(this);
+    GetEventHandler()->ProcessEvent(e);
+}
+
+// Sets the normal font
+void wxAuiNotebook::SetNormalFont(const wxFont& font)
+{
+    m_normalFont = font;
+    GetArtProvider()->SetNormalFont(font);
+}
+
+// Sets the selected tab font
+void wxAuiNotebook::SetSelectedFont(const wxFont& font)
+{
+    m_selectedFont = font;
+    GetArtProvider()->SetSelectedFont(font);
+}
+
+// Sets the measuring font
+void wxAuiNotebook::SetMeasuringFont(const wxFont& font)
+{
+    GetArtProvider()->SetMeasuringFont(font);
+}
+
+// Sets the tab font
+bool wxAuiNotebook::SetFont(const wxFont& font)
+{
+    wxControl::SetFont(font);
+
+    wxFont normalFont(font);
+    wxFont selectedFont(normalFont);
+    selectedFont.SetWeight(wxBOLD);
+
+    SetNormalFont(normalFont);
+    SetSelectedFont(selectedFont);
+    SetMeasuringFont(selectedFont);
+
+    return true;
+}
+
+// Gets the tab control height
+int wxAuiNotebook::GetTabCtrlHeight() const
+{
+    return m_tabCtrlHeight;
+}
+
+// Gets the height of the notebook for a given page height
+int wxAuiNotebook::GetHeightForPageHeight(int pageHeight)
+{
+    UpdateTabCtrlHeight();
+
+    int tabCtrlHeight = GetTabCtrlHeight();
+    int decorHeight = 2;
+    return tabCtrlHeight + pageHeight + decorHeight;
+}
+
+// Advances the selection, generation page selection events
+void wxAuiNotebook::AdvanceSelection(bool forward)
+{
+    if (GetPageCount() <= 1)
+        return;
+
+    int currentSelection = GetSelection();
+
+    if (forward)
+    {
+        if (currentSelection == (int) (GetPageCount() - 1))
+            return;
+        else if (currentSelection == -1)
+            currentSelection = 0;
+        else
+            currentSelection ++;
+    }
+    else
+    {
+        if (currentSelection <= 0)
+            return;
+        else
+            currentSelection --;
+    }
+
+    SetSelection(currentSelection);
+}
+
+// Shows the window menu
+bool wxAuiNotebook::ShowWindowMenu()
+{
+    wxAuiTabCtrl* tabCtrl = GetActiveTabCtrl();
+
+    int idx = tabCtrl->GetArtProvider()->ShowDropDown(tabCtrl, tabCtrl->GetPages(), tabCtrl->GetActivePage());
+
+    if (idx != -1)
+    {
+        wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, tabCtrl->GetId());
+        e.SetSelection(idx);
+        e.SetOldSelection(tabCtrl->GetActivePage());
+        e.SetEventObject(tabCtrl);
+        GetEventHandler()->ProcessEvent(e);
+
+        return true;
+    }
+    else
+        return false;
+}
+
+void wxAuiNotebook::Thaw()
+{
+    DoSizing();
+
+    wxControl::Thaw();
+}
+
+void wxAuiNotebook::SetPageSize (const wxSize& WXUNUSED(size))
+{
+    wxFAIL_MSG("Not implemented for wxAuiNotebook");
+}
+
+int wxAuiNotebook::HitTest (const wxPoint& WXUNUSED(pt), long* WXUNUSED(flags)) const
+{
+    wxFAIL_MSG("Not implemented for wxAuiNotebook");
+    return wxNOT_FOUND;
+}
+
+int wxAuiNotebook::GetPageImage(size_t WXUNUSED(n)) const
+{
+    wxFAIL_MSG("Not implemented for wxAuiNotebook");
+    return -1;
+}
+
+bool wxAuiNotebook::SetPageImage(size_t n, int imageId)
+{
+    return SetPageBitmap(n, GetImageList()->GetBitmap(imageId));
+}
+
+wxWindow* wxAuiNotebook::GetCurrentPage () const
+{
+    return GetPage(GetSelection());
+}
+
+int wxAuiNotebook::ChangeSelection(size_t n)
+{
+    return DoModifySelection(n, false);
+}
+
+bool wxAuiNotebook::AddPage(wxWindow *page, const wxString &text, bool select, 
+                            int imageId)
+{
+    if(HasImageList()) 
+    {
+        return AddPage(page, text, select, GetImageList()->GetBitmap(imageId));
+    }
+    else
+    {
+        return AddPage(page, text, select, wxNullBitmap);
+    }
+}
+
+bool wxAuiNotebook::DeleteAllPages()
+{
+    size_t count = GetPageCount();
+    for(size_t i = 0; i < count; i++)
+    {
+        DeletePage(0);
+    }
+    return true;
+}
+
+bool wxAuiNotebook::InsertPage(size_t index, wxWindow *page, 
+                               const wxString &text, bool select, 
+                               int imageId)
+{
+    if(HasImageList())
+    {
+        return InsertPage(index, page, text, select, 
+                          GetImageList()->GetBitmap(imageId));
+    }
+    else
+    {
+        return InsertPage(index, page, text, select, wxNullBitmap);
+    }
+}
+
+int wxAuiNotebook::DoModifySelection(size_t n, bool events)
+{
+    wxWindow* wnd = m_tabs.GetWindowFromIdx(n);
+    if (!wnd)
+        return m_curPage;
+
+    // don't change the page unless necessary;
+    // however, clicking again on a tab should give it the focus.
+    if ((int)n == m_curPage)
+    {
+        wxAuiTabCtrl* ctrl;
+        int ctrl_idx;
+        if (FindTab(wnd, &ctrl, &ctrl_idx))
+        {
+            if (FindFocus() != ctrl)
+                ctrl->SetFocus();
+        }
+        return m_curPage;
+    }
+
+    bool vetoed = false;
+
+    wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, m_windowId);
+
+    if(events)
+    {
+        evt.SetSelection(n);
+        evt.SetOldSelection(m_curPage);
+        evt.SetEventObject(this);
+        GetEventHandler()->ProcessEvent(evt);
+        vetoed = !evt.IsAllowed();
+    }
+
+    if (!vetoed)
+    {
+        int old_curpage = m_curPage;
+        m_curPage = n;
+
+        // program allows the page change
+        if(events)
+        {
+            evt.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED);
+            (void)GetEventHandler()->ProcessEvent(evt);
+        }
+
+
+        wxAuiTabCtrl* ctrl;
+        int ctrl_idx;
+        if (FindTab(wnd, &ctrl, &ctrl_idx))
+        {
+            m_tabs.SetActivePage(wnd);
+
+            ctrl->SetActivePage(ctrl_idx);
+            DoSizing();
+            ctrl->DoShowHide();
+
+            ctrl->MakeTabVisible(ctrl_idx, ctrl);
+
+            // set fonts
+            wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
+            size_t i, pane_count = all_panes.GetCount();
+            for (i = 0; i < pane_count; ++i)
+            {
+                wxAuiPaneInfo& pane = all_panes.Item(i);
+                if (pane.name == wxT("dummy"))
+                    continue;
+                wxAuiTabCtrl* tabctrl = ((wxTabFrame*)pane.window)->m_tabs;
+                if (tabctrl != ctrl)
+                    tabctrl->SetSelectedFont(m_normalFont);
+                else
+                    tabctrl->SetSelectedFont(m_selectedFont);
+                tabctrl->Refresh();
+            }
+
+            // Set the focus to the page if we're not currently focused on the tab.
+            // This is Firefox-like behaviour.
+            if (wnd->IsShownOnScreen() && FindFocus() != ctrl)
+                wnd->SetFocus();
+
+            return old_curpage;
+        }
+    }
+
+    return m_curPage;
+}
 
 
 #endif // wxUSE_AUI
 
 
 #endif // wxUSE_AUI