]> git.saurik.com Git - wxWidgets.git/blobdiff - src/aui/auibook.cpp
Fix wxEncodingConverter::Convert(wchar_t) documentation.
[wxWidgets.git] / src / aui / auibook.cpp
index a3b7b64be842aa4345dd125a478a32fce987a7a9..36640c3fcccbb025f0cced46a34eebd54dc96557 100644 (file)
 #include "wx/aui/tabmdi.h"
 #include "wx/dcbuffer.h"
 
 #include "wx/aui/tabmdi.h"
 #include "wx/dcbuffer.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)
 
 
 
 
 
 
@@ -60,8 +69,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent, wxEvent)
 // these functions live in dockart.cpp -- they'll eventually
 // be moved to a new utility cpp file
 
 // these functions live in dockart.cpp -- they'll eventually
 // be moved to a new utility cpp file
 
-wxColor wxAuiStepColour(const wxColor& c, int percent);
-
 wxBitmap wxAuiBitmapFromBits(const unsigned char bits[], int w, int h,
                              const wxColour& color);
 
 wxBitmap wxAuiBitmapFromBits(const unsigned char bits[], int w, int h,
                              const wxColour& color);
 
@@ -84,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(wxAuiStepColour(bkcolour, 120)));
-        dc.SetPen(wxPen(wxAuiStepColour(bkcolour, 75)));
+        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);
@@ -112,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;
         }
 
@@ -130,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};
@@ -177,49 +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
 
-    // the base_colour is too pale to use as our base colour,
+    // the baseColour is too pale to use as our base colour,
     // so darken it a bit --
     // so darken it a bit --
-    if ((255-base_colour.Red()) +
-        (255-base_colour.Green()) +
-        (255-base_colour.Blue()) < 60)
+    if ((255-baseColour.Red()) +
+        (255-baseColour.Green()) +
+        (255-baseColour.Blue()) < 60)
     {
     {
-        base_colour = wxAuiStepColour(base_colour, 92);
+        baseColour = baseColour.ChangeLightness(92);
     }
 
     }
 
-    m_base_colour = base_colour;
-    wxColor border_colour = wxAuiStepColour(base_colour, 75);
+    m_activeColour = baseColour;
+    m_baseColour = baseColour;
+    wxColor borderColour = baseColour.ChangeLightness(75);
 
 
-    m_border_pen = wxPen(border_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 = wxAuiBitmapFromBits(close_bits, 16, 16, *wxBLACK);
-    m_disabled_close_bmp = wxAuiBitmapFromBits(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 = wxAuiBitmapFromBits(left_bits, 16, 16, *wxBLACK);
-    m_disabled_left_bmp = wxAuiBitmapFromBits(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 = wxAuiBitmapFromBits(right_bits, 16, 16, *wxBLACK);
-    m_disabled_right_bmp = wxAuiBitmapFromBits(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 = wxAuiBitmapFromBits(list_bits, 16, 16, *wxBLACK);
-    m_disabled_windowlist_bmp = wxAuiBitmapFromBits(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;
 }
@@ -230,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)
@@ -241,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;
 
     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_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;
 }
 
 
 }
 
 
@@ -274,17 +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 top_color = wxAuiStepColour(m_base_colour, 90);
-    wxColor bottom_color = wxAuiStepColour(m_base_colour, 170);
+
+    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);
 
     dc.GradientFillLinear(r, top_color, bottom_color, wxSOUTH);
 
-    // draw base lines
-    int y = rect.GetHeight();
-    int w = rect.GetWidth();
-    dc.SetPen(m_border_pen);
-    dc.SetBrush(m_base_colour_brush);
-    dc.DrawRectangle(-1, y-4, w+2, 4);
+
+   // 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);
+   }
 }
 
 
 }
 
 
@@ -308,17 +336,17 @@ 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
     wxString caption = page.caption;
     if (caption.empty())
         caption = wxT("Xj");
 
 
     // if the caption is empty, measure some temporary text
     wxString caption = page.caption;
     if (caption.empty())
         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
     dc.GetTextExtent(caption, &normal_textx, &normal_texty);
 
     // figure out the size of the tab
@@ -330,7 +358,7 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
                                  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;
@@ -343,14 +371,12 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
 
     if (page.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;
     }
 
@@ -383,13 +409,26 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
 
 
     wxPoint border_points[6];
 
 
     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);
-
+    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;
@@ -401,8 +440,8 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
 
         // draw base background color
         wxRect r(tab_x, tab_y, tab_width, tab_height);
 
         // 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.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.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
@@ -411,23 +450,23 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
         dc.DrawRectangle(r.x+2, r.y+1, r.width-3, r.height-4);
 
         // these two points help the rounded corners appear more antialiased
         dc.DrawRectangle(r.x+2, r.y+1, r.width-3, r.height-4);
 
         // these two points help the rounded corners appear more antialiased
-        dc.SetPen(m_base_colour_pen);
+        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;
         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;
-        r.width -= 2;
+        r.width -= 3;
         r.y += r.height;
         r.y -= 2;
 
         // draw gradient background
         wxColor top_color = *wxWHITE;
         r.y += r.height;
         r.y -= 2;
 
         // draw gradient background
         wxColor top_color = *wxWHITE;
-        wxColor bottom_color = m_base_colour;
+        wxColor bottom_color = m_activeColour;
         dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH);
     }
         dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH);
     }
-     else
+    else
     {
         // draw inactive tab
 
     {
         // draw inactive tab
 
@@ -443,21 +482,21 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
         r.height--;
 
         // -- draw top gradient fill for glossy look
         r.height--;
 
         // -- draw top gradient fill for glossy look
-        wxColor top_color = m_base_colour;
-        wxColor bottom_color = wxAuiStepColour(top_color, 160);
+        wxColor top_color = m_baseColour;
+        wxColor bottom_color = top_color.ChangeLightness(160);
         dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH);
 
         r.y += r.height;
         r.y--;
 
         // -- draw bottom fill for glossy look
         dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH);
 
         r.y += r.height;
         r.y--;
 
         // -- draw bottom fill for glossy look
-        top_color = m_base_colour;
-        bottom_color = m_base_colour;
+        top_color = m_baseColour;
+        bottom_color = m_baseColour;
         dc.GradientFillLinear(r, top_color, bottom_color, wxSOUTH);
     }
 
     // draw tab outline
         dc.GradientFillLinear(r, top_color, bottom_color, wxSOUTH);
     }
 
     // draw tab outline
-    dc.SetPen(m_border_pen);
+    dc.SetPen(m_borderPen);
     dc.SetBrush(*wxTRANSPARENT_BRUSH);
     dc.DrawPolygon(WXSIZEOF(border_points), border_points);
 
     dc.SetBrush(*wxTRANSPARENT_BRUSH);
     dc.DrawPolygon(WXSIZEOF(border_points), border_points);
 
@@ -465,8 +504,12 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
     // this gets rid of the top one of those lines in the tab control
     if (page.active)
     {
     // this gets rid of the top one of those lines in the tab control
     if (page.active)
     {
-        wxColor start_color = m_base_colour;
-        dc.SetPen(m_base_colour_pen);
+        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[5].x,
         dc.DrawLine(border_points[0].x+1,
                     border_points[0].y,
                     border_points[5].x,
@@ -478,13 +521,13 @@ 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();
     }
 
     }
 
-
+    int bitmap_offset = 0;
     if (page.bitmap.IsOk())
     {
     if (page.bitmap.IsOk())
     {
-        int bitmap_offset = tab_x + 8;
+        bitmap_offset = tab_x + 8;
 
         // draw bitmap
         dc.DrawBitmap(page.bitmap,
 
         // draw bitmap
         dc.DrawBitmap(page.bitmap,
@@ -494,8 +537,9 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
 
         text_offset = bitmap_offset + page.bitmap.GetWidth();
         text_offset += 3; // bitmap padding
 
         text_offset = bitmap_offset + page.bitmap.GetWidth();
         text_offset += 3; // bitmap padding
+
     }
     }
-     else
+    else
     {
         text_offset = tab_x + 8;
     }
     {
         text_offset = tab_x + 8;
     }
@@ -510,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);
 
@@ -554,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);
@@ -565,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())
@@ -581,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;
@@ -605,27 +676,27 @@ void wxAuiDefaultTabArt::DrawButton(wxDC& dc,
     {
         case wxAUI_BUTTON_CLOSE:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
     {
         case wxAUI_BUTTON_CLOSE:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                bmp = m_disabled_close_bmp;
-                 else
-                bmp = m_active_close_bmp;
+                bmp = m_disabledCloseBmp;
+            else
+                bmp = m_activeCloseBmp;
             break;
         case wxAUI_BUTTON_LEFT:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
             break;
         case wxAUI_BUTTON_LEFT:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                bmp = m_disabled_left_bmp;
-                 else
-                bmp = m_active_left_bmp;
+                bmp = m_disabledLeftBmp;
+            else
+                bmp = m_activeLeftBmp;
             break;
         case wxAUI_BUTTON_RIGHT:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
             break;
         case wxAUI_BUTTON_RIGHT:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                bmp = m_disabled_right_bmp;
-                 else
-                bmp = m_active_right_bmp;
+                bmp = m_disabledRightBmp;
+            else
+                bmp = m_activeRightBmp;
             break;
         case wxAUI_BUTTON_WINDOWLIST:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
             break;
         case wxAUI_BUTTON_WINDOWLIST:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                bmp = m_disabled_windowlist_bmp;
-                 else
-                bmp = m_active_windowlist_bmp;
+                bmp = m_disabledWindowListBmp;
+            else
+                bmp = m_activeWindowListBmp;
             break;
     }
 
             break;
     }
 
@@ -642,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),
@@ -655,10 +726,9 @@ void wxAuiDefaultTabArt::DrawButton(wxDC& dc,
     *out_rect = rect;
 }
 
     *out_rect = rect;
 }
 
-
 int wxAuiDefaultTabArt::ShowDropDown(wxWindow* wnd,
                                      const wxAuiNotebookPageArray& pages,
 int wxAuiDefaultTabArt::ShowDropDown(wxWindow* wnd,
                                      const wxAuiNotebookPageArray& pages,
-                                     int active_idx)
+                                     int /*active_idx*/)
 {
     wxMenu menuPopup;
 
 {
     wxMenu menuPopup;
 
@@ -666,12 +736,17 @@ int wxAuiDefaultTabArt::ShowDropDown(wxWindow* wnd,
     for (i = 0; i < count; ++i)
     {
         const wxAuiNotebookPage& page = pages.Item(i);
     for (i = 0; i < count; ++i)
     {
         const wxAuiNotebookPage& page = pages.Item(i);
-        menuPopup.AppendCheckItem(1000+i, page.caption);
-    }
+        wxString caption = page.caption;
 
 
-    if (active_idx != -1)
-    {
-        menuPopup.Check(1000+active_idx, true);
+        // 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
     }
 
     // find out where to put the popup menu of window items
@@ -696,19 +771,19 @@ int wxAuiDefaultTabArt::ShowDropDown(wxWindow* wnd,
 
 int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd,
                                            const wxAuiNotebookPageArray& pages,
 
 int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd,
                                            const wxAuiNotebookPageArray& pages,
-                                           const wxSize& required_bmp_size)
+                                           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.
 
     // 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 measure_bmp;
-    if (required_bmp_size.IsFullySpecified())
+    wxBitmap measureBmp;
+    if (requiredBmp_size.IsFullySpecified())
     {
     {
-        measure_bmp.Create(required_bmp_size.x,
-                           required_bmp_size.y);
+        measureBmp.Create(requiredBmp_size.x,
+                           requiredBmp_size.y);
     }
 
 
     }
 
 
@@ -719,9 +794,9 @@ int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd,
         wxAuiNotebookPage& page = pages.Item(i);
 
         wxBitmap bmp;
         wxAuiNotebookPage& page = pages.Item(i);
 
         wxBitmap bmp;
-        if (measure_bmp.IsOk())
-            bmp = measure_bmp;
-             else
+        if (measureBmp.IsOk())
+            bmp = measureBmp;
+        else
             bmp = page.bitmap;
 
         // we don't use the caption text because we don't
             bmp = page.bitmap;
 
         // we don't use the caption text because we don't
@@ -745,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 = base_colour;
-    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 = wxAuiBitmapFromBits(close_bits, 16, 16, *wxBLACK);
-    m_disabled_close_bmp = wxAuiBitmapFromBits(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 = wxAuiBitmapFromBits(left_bits, 16, 16, *wxBLACK);
-    m_disabled_left_bmp = wxAuiBitmapFromBits(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 = wxAuiBitmapFromBits(right_bits, 16, 16, *wxBLACK);
-    m_disabled_right_bmp = wxAuiBitmapFromBits(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 = wxAuiBitmapFromBits(list_bits, 16, 16, *wxBLACK);
-    m_disabled_windowlist_bmp = wxAuiBitmapFromBits(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));
 
 }
 
 
 }
 
@@ -803,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;
@@ -815,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,
@@ -845,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);
 
@@ -882,10 +981,10 @@ void wxAuiSimpleTabArt::DrawTab(wxDC& dc,
     if (caption.empty())
         caption = wxT("Xj");
 
     if (caption.empty())
         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
     dc.GetTextExtent(caption, &normal_textx, &normal_texty);
 
     // figure out the size of the tab
@@ -908,17 +1007,17 @@ void wxAuiSimpleTabArt::DrawTab(wxDC& dc,
 
     if (page.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;
     }
@@ -956,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);
     }
@@ -979,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;
         if (page.active)
     // draw close button if necessary
     if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
     {
         wxBitmap bmp;
         if (page.active)
-            bmp = m_active_close_bmp;
-             else
-            bmp = m_disabled_close_bmp;
+            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,
@@ -1018,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;
@@ -1053,27 +1163,27 @@ void wxAuiSimpleTabArt::DrawButton(wxDC& dc,
     {
         case wxAUI_BUTTON_CLOSE:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
     {
         case wxAUI_BUTTON_CLOSE:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                bmp = m_disabled_close_bmp;
-                 else
-                bmp = m_active_close_bmp;
+                bmp = m_disabledCloseBmp;
+            else
+                bmp = m_activeCloseBmp;
             break;
         case wxAUI_BUTTON_LEFT:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
             break;
         case wxAUI_BUTTON_LEFT:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                bmp = m_disabled_left_bmp;
-                 else
-                bmp = m_active_left_bmp;
+                bmp = m_disabledLeftBmp;
+            else
+                bmp = m_activeLeftBmp;
             break;
         case wxAUI_BUTTON_RIGHT:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
             break;
         case wxAUI_BUTTON_RIGHT:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                bmp = m_disabled_right_bmp;
-                 else
-                bmp = m_active_right_bmp;
+                bmp = m_disabledRightBmp;
+            else
+                bmp = m_activeRightBmp;
             break;
         case wxAUI_BUTTON_WINDOWLIST:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
             break;
         case wxAUI_BUTTON_WINDOWLIST:
             if (button_state & wxAUI_BUTTON_STATE_DISABLED)
-                bmp = m_disabled_windowlist_bmp;
-                 else
-                bmp = m_active_windowlist_bmp;
+                bmp = m_disabledWindowListBmp;
+            else
+                bmp = m_activeWindowListBmp;
             break;
     }
 
             break;
     }
 
@@ -1089,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),
@@ -1102,7 +1212,6 @@ void wxAuiSimpleTabArt::DrawButton(wxDC& dc,
     *out_rect = rect;
 }
 
     *out_rect = rect;
 }
 
-
 int wxAuiSimpleTabArt::ShowDropDown(wxWindow* wnd,
                                     const wxAuiNotebookPageArray& pages,
                                     int active_idx)
 int wxAuiSimpleTabArt::ShowDropDown(wxWindow* wnd,
                                     const wxAuiNotebookPageArray& pages,
                                     int active_idx)
@@ -1128,7 +1237,7 @@ int wxAuiSimpleTabArt::ShowDropDown(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
@@ -1149,10 +1258,10 @@ int wxAuiSimpleTabArt::ShowDropDown(wxWindow* wnd,
 
 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow* wnd,
                                           const wxAuiNotebookPageArray& WXUNUSED(pages),
 
 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow* wnd,
                                           const wxAuiNotebookPageArray& WXUNUSED(pages),
-                                          const wxSize& WXUNUSED(required_bmp_size))
+                                          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,
@@ -1166,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;
 }
 
 
 }
 
 
@@ -1197,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;
 
@@ -1282,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;
@@ -1320,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
@@ -1387,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;
         }
@@ -1437,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)
@@ -1473,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);
 }
@@ -1504,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;
 }
 
 
 }
 
 
@@ -1524,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();
@@ -1566,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)
@@ -1587,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)
@@ -1600,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;
             }
         }
     }
             }
         }
     }
@@ -1611,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;
         }
     }
 
         }
     }
 
@@ -1644,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;
@@ -1655,7 +1779,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
                           wnd,
                           button_rect,
                           button.id,
                           wnd,
                           button_rect,
                           button.id,
-                          button.cur_state,
+                          button.curState,
                           wxRIGHT,
                           &button.rect);
 
                           wxRIGHT,
                           &button.rect);
 
@@ -1675,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);
@@ -1684,7 +1808,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
                           wnd,
                           button_rect,
                           button.id,
                           wnd,
                           button_rect,
                           button.id,
-                          button.cur_state,
+                          button.curState,
                           wxLEFT,
                           &button.rect);
 
                           wxLEFT,
                           &button.rect);
 
@@ -1700,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;
     }
 
 
     }
 
 
@@ -1732,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;
@@ -1765,7 +1887,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd)
                        wnd,
                        page,
                        rect,
                        wnd,
                        page,
                        rect,
-                       tab_button.cur_state,
+                       tab_button.curState,
                        &page.rect,
                        &tab_button.rect,
                        &x_extent);
                        &page.rect,
                        &tab_button.rect,
                        &x_extent);
@@ -1782,33 +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,
                        page,
                        active_rect,
 
         rect.x = active_offset;
         m_art->DrawTab(dc,
                        wnd,
                        page,
                        active_rect,
-                       tab_button.cur_state,
+                       tab_button.curState,
                        &page.rect,
                        &tab_button.rect,
                        &x_extent);
                        &page.rect,
                        &tab_button.rect,
                        &x_extent);
@@ -1820,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
@@ -1830,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;
@@ -1838,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))
@@ -1868,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;
@@ -1877,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)
@@ -1901,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);
     }
@@ -1954,11 +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::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_AUINOTEBOOK_BUTTON(wxID_ANY, wxAuiTabCtrl::OnButton)
     EVT_MOTION(wxAuiTabCtrl::OnMotion)
     EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow)
     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()
 
 
@@ -1968,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()
@@ -2002,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;
@@ -2026,65 +2291,144 @@ 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::OnMiddleUp(wxMouseEvent& evt)
+{
+    wxWindow* wnd = NULL;
+    if (!TabHitTest(evt.m_x, evt.m_y, &wnd))
+        return;
+
+    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)
 }
 
 void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt)
@@ -2093,44 +2437,44 @@ void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt)
 
     // check if the mouse is hovering above a button
     wxAuiTabContainerButton* button;
 
     // check if the mouse is hovering above a button
     wxAuiTabContainerButton* button;
-    if (ButtonHitTest(pos.x, pos.y, &button))
+    if (ButtonHitTest(pos.x, pos.y, &button) && !(button->curState & wxAUI_BUTTON_STATE_DISABLED))
     {
     {
-        if (m_hover_button && button != m_hover_button)
+        if (m_hoverButton && button != 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 (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);
@@ -2141,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();
     }
@@ -2180,14 +2524,14 @@ 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)
     {
         int idx = GetArtProvider()->ShowDropDown(this, m_pages, GetActivePage());
 
     {
         int idx = GetArtProvider()->ShowDropDown(this, m_pages, GetActivePage());
 
@@ -2200,80 +2544,256 @@ void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent& event)
             GetEventHandler()->ProcessEvent(e);
         }
     }
             GetEventHandler()->ProcessEvent(e);
         }
     }
-     else
+    else
     {
         event.Skip();
     }
 }
 
     {
         event.Skip();
     }
 }
 
-// wxTabFrame is an interesting case.  It's important that all child pages
-// of the multi-notebook control are all actually children of that control
-// (and not grandchildren).  wxTabFrame facilitates this.  There is one
-// instance of wxTabFrame for each tab control inside the multi-notebook.
-// It's important to know that wxTabFrame is not a real window, but it merely
-// used to capture the dimensions/positioning of the internal tab control and
-// it's managed page windows
+void wxAuiTabCtrl::OnSetFocus(wxFocusEvent& WXUNUSED(event))
+{
+    Refresh();
+}
 
 
-class wxTabFrame : public wxWindow
+void wxAuiTabCtrl::OnKillFocus(wxFocusEvent& WXUNUSED(event))
 {
 {
-public:
+    Refresh();
+}
 
 
-    wxTabFrame()
+void wxAuiTabCtrl::OnChar(wxKeyEvent& event)
+{
+    if (GetActivePage() == -1)
     {
     {
-        m_tabs = NULL;
-        m_rect = wxRect(0,0,200,200);
-        m_tab_ctrl_height = 20;
+        event.Skip();
+        return;
     }
 
     }
 
-    void SetTabCtrlHeight(int h)
-    {
-        m_tab_ctrl_height = h;
-    }
+    // 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.
 
 
-    void DoSetSize(int x, int y,
-                   int width, int height,
-                   int WXUNUSED(sizeFlags = wxSIZE_AUTO))
-    {
-        m_rect = wxRect(x, y, width, height);
-        DoSizing();
-    }
+    int key = event.GetKeyCode();
 
 
-    void DoGetClientSize(int* x, int* y) const
+    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)
     {
     {
-        *x = m_rect.width;
-        *y = m_rect.height;
-    }
+        bool bCtrlDown = event.ControlDown();
+        bool bShiftDown = event.ShiftDown();
 
 
-    bool Show( bool WXUNUSED(show = true) ) { return false; }
+        bool bForward = (key == WXK_TAB && !bShiftDown) || (key == WXK_PAGEDOWN);
+        bool bWindowChange = (key == WXK_PAGEUP) || (key == WXK_PAGEDOWN) || bCtrlDown;
+        bool bFromTab = (key == WXK_TAB);
 
 
-    void DoSizing()
-    {
-        if (!m_tabs)
+        wxAuiNotebook* nb = wxDynamicCast(GetParent(), wxAuiNotebook);
+        if (!nb)
+        {
+            event.Skip();
             return;
             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));
-        m_tabs->Refresh();
-        m_tabs->Update();
-
-        wxAuiNotebookPageArray& pages = m_tabs->GetPages();
-        size_t i, page_count = pages.GetCount();
+        wxNavigationKeyEvent keyEvent;
+        keyEvent.SetDirection(bForward);
+        keyEvent.SetWindowChange(bWindowChange);
+        keyEvent.SetFromTab(bFromTab);
+        keyEvent.SetEventObject(nb);
 
 
-        for (i = 0; i < page_count; ++i)
+        if (!nb->GetEventHandler()->ProcessEvent(keyEvent))
         {
         {
-            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);
+            // Not processed? Do an explicit tab into the page.
+            wxWindow* win = GetWindowFromIdx(GetActivePage());
+            if (win)
+                win->SetFocus();
+        }
+        return;
+    }
 
 
-            if (page.window->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
+    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();
+
+    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
+// of the multi-notebook control are all actually children of that control
+// (and not grandchildren).  wxTabFrame facilitates this.  There is one
+// instance of wxTabFrame for each tab control inside the multi-notebook.
+// It's important to know that wxTabFrame is not a real window, but it merely
+// used to capture the dimensions/positioning of the internal tab control and
+// it's managed page windows
+
+class wxTabFrame : public wxWindow
+{
+public:
+
+    wxTabFrame()
+    {
+        m_tabs = NULL;
+        m_rect = wxRect(0,0,200,200);
+        m_tabCtrlHeight = 20;
+    }
+
+    ~wxTabFrame()
+    {
+        wxDELETE(m_tabs);
+    }
+
+    void SetTabCtrlHeight(int h)
+    {
+        m_tabCtrlHeight = h;
+    }
+
+protected:
+    void DoSetSize(int x, int y,
+                   int width, int height,
+                   int WXUNUSED(sizeFlags = wxSIZE_AUTO))
+    {
+        m_rect = wxRect(x, y, width, height);
+        DoSizing();
+    }
+
+    void DoGetClientSize(int* x, int* y) const
+    {
+        *x = m_rect.width;
+        *y = m_rect.height;
+    }
+
+public:
+    bool Show( bool WXUNUSED(show = true) ) { return false; }
+
+    void DoSizing()
+    {
+        if (!m_tabs)
+            return;
+
+        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();
+
+        wxAuiNotebookPageArray& pages = m_tabs->GetPages();
+        size_t i, page_count = pages.GetCount();
+
+        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);
+            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();
             }
             {
                 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)
@@ -2282,17 +2802,16 @@ 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;
 };
 
 
 };
 
 
@@ -2301,46 +2820,56 @@ 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)
     EVT_SIZE(wxAuiNotebook::OnSize)
 BEGIN_EVENT_TABLE(wxAuiNotebook, wxControl)
     EVT_SIZE(wxAuiNotebook::OnSize)
-    EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocus)
-    EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+    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(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
                       wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG,
                       wxAuiNotebook::OnTabBeginDrag)
                       wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG,
                       wxAuiNotebook::OnTabBeginDrag)
-    EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+    EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
                       wxEVT_COMMAND_AUINOTEBOOK_END_DRAG,
                       wxAuiNotebook::OnTabEndDrag)
                       wxEVT_COMMAND_AUINOTEBOOK_END_DRAG,
                       wxAuiNotebook::OnTabEndDrag)
-    EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+    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(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+    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()
-{
-    m_curpage = -1;
-    m_tab_id_counter = wxAuiBaseTabCtrlId;
-    m_dummy_wnd = NULL;
-    m_tab_ctrl_height = 20;
-    m_requested_bmp_size = wxDefaultSize;
-    m_requested_tabctrl_height = -1;
-}
-
-wxAuiNotebook::wxAuiNotebook(wxWindow *parent,
-                             wxWindowID id,
-                             const wxPoint& pos,
-                             const wxSize& size,
-                             long style) : wxControl(parent, id, pos, size, style)
+void wxAuiNotebook::Init()
 {
 {
-    m_dummy_wnd = NULL;
-    m_requested_bmp_size = wxDefaultSize;
-    m_requested_tabctrl_height = -1;
-    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,
@@ -2361,27 +2890,28 @@ 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 = wxAuiBaseTabCtrlId;
-    m_dummy_wnd = NULL;
+    SetName(wxT("wxAuiNotebook"));
+    m_curPage = -1;
+    m_tabIdCounter = wxAuiBaseTabCtrlId;
+    m_dummyWnd = NULL;
     m_flags = (unsigned int)style;
     m_flags = (unsigned int)style;
-    m_tab_ctrl_height = 20;
+    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.SetFlags(wxAUI_MGR_DEFAULT);
     m_mgr.SetDockSizeConstraint(1.0, 1.0); // no dock size constraint
 
 
     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,
+    m_mgr.AddPane(m_dummyWnd,
               wxAuiPaneInfo().Name(wxT("dummy")).Bottom().CaptionVisible(false).Show(false));
 
     m_mgr.Update();
               wxAuiPaneInfo().Name(wxT("dummy")).Bottom().CaptionVisible(false).Show(false));
 
     m_mgr.Update();
@@ -2389,6 +2919,12 @@ void wxAuiNotebook::InitNotebook(long style)
 
 wxAuiNotebook::~wxAuiNotebook()
 {
 
 wxAuiNotebook::~wxAuiNotebook()
 {
+    // Indicate we're deleting pages
+    SendDestroyEvent();
+
+    while ( GetPageCount() > 0 )
+        DeletePage(0);
+
     m_mgr.UnInit();
 }
 
     m_mgr.UnInit();
 }
 
@@ -2396,7 +2932,23 @@ void wxAuiNotebook::SetArtProvider(wxAuiTabArt* art)
 {
     m_tabs.SetArtProvider(art);
 
 {
     m_tabs.SetArtProvider(art);
 
-    UpdateTabCtrlHeight();
+    // 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() )
+    {
+        wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
+        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;
+            tabctrl->SetArtProvider(art->Clone());
+        }
+    }
 }
 
 // SetTabCtrlHeight() is the highest-level override of the
 }
 
 // SetTabCtrlHeight() is the highest-level override of the
@@ -2404,14 +2956,14 @@ void wxAuiNotebook::SetArtProvider(wxAuiTabArt* art)
 // 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
 // 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 behavior
+// any previous call and returns to the default behaviour
 
 void wxAuiNotebook::SetTabCtrlHeight(int height)
 {
 
 void wxAuiNotebook::SetTabCtrlHeight(int height)
 {
-    m_requested_tabctrl_height = height;
+    m_requestedTabCtrlHeight = height;
 
     // if window is already initialized, recalculate the tab height
 
     // if window is already initialized, recalculate the tab height
-    if (m_dummy_wnd)
+    if (m_dummyWnd)
     {
         UpdateTabCtrlHeight();
     }
     {
         UpdateTabCtrlHeight();
     }
@@ -2427,44 +2979,46 @@ void wxAuiNotebook::SetTabCtrlHeight(int height)
 
 void wxAuiNotebook::SetUniformBitmapSize(const wxSize& size)
 {
 
 void wxAuiNotebook::SetUniformBitmapSize(const wxSize& size)
 {
-    m_requested_bmp_size = size;
+    m_requestedBmpSize = size;
 
     // if window is already initialized, recalculate the tab height
 
     // if window is already initialized, recalculate the tab height
-    if (m_dummy_wnd)
+    if (m_dummyWnd)
     {
         UpdateTabCtrlHeight();
     }
 }
 
 // UpdateTabCtrlHeight() does the actual tab resizing. It's meant
     {
         UpdateTabCtrlHeight();
     }
 }
 
 // UpdateTabCtrlHeight() does the actual tab resizing. It's meant
-// to be used interally
-void wxAuiNotebook::UpdateTabCtrlHeight()
+// 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
 {
     // 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_tab_ctrl_height != height)
-    {
-        wxAuiTabArt* art = m_tabs.GetArtProvider();
+    if (m_tabCtrlHeight == height)
+        return false;
 
 
-        m_tab_ctrl_height = height;
+    wxAuiTabArt* art = m_tabs.GetArtProvider();
 
 
-        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_tab_ctrl_height);
-            tabctrl->SetArtProvider(art->Clone());
-            tab_frame->DoSizing();
-        }
+    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()
 }
 
 void wxAuiNotebook::UpdateHintWindowSize()
@@ -2477,7 +3031,7 @@ void wxAuiNotebook::UpdateHintWindowSize()
     {
         info.MinSize(size);
         info.BestSize(size);
     {
         info.MinSize(size);
         info.BestSize(size);
-        m_dummy_wnd->SetSize(size);
+        m_dummyWnd->SetSize(size);
     }
 }
 
     }
 }
 
@@ -2507,7 +3061,7 @@ wxSize wxAuiNotebook::CalculateNewSplitSize()
         new_split_size.x /= 2;
         new_split_size.y /= 2;
     }
         new_split_size.x /= 2;
         new_split_size.y /= 2;
     }
-     else
+    else
     {
         // this is in place of a more complicated calculation
         // that needs to be implemented
     {
         // this is in place of a more complicated calculation
         // that needs to be implemented
@@ -2522,15 +3076,15 @@ int wxAuiNotebook::CalculateTabCtrlHeight()
     // if a fixed tab ctrl height is specified,
     // just return that instead of calculating a
     // tab height
     // if a fixed tab ctrl height is specified,
     // just return that instead of calculating a
     // tab height
-    if (m_requested_tabctrl_height != -1)
-        return m_requested_tabctrl_height;
+    if (m_requestedTabCtrlHeight != -1)
+        return m_requestedTabCtrlHeight;
 
     // find out new best tab height
     wxAuiTabArt* art = m_tabs.GetArtProvider();
 
     return art->GetBestTabCtrlSize(this,
                                    m_tabs.GetPages(),
 
     // find out new best tab height
     wxAuiTabArt* art = m_tabs.GetArtProvider();
 
     return art->GetBestTabCtrlSize(this,
                                    m_tabs.GetPages(),
-                                   m_requested_bmp_size);
+                                   m_requestedBmpSize);
 }
 
 
 }
 
 
@@ -2582,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;
@@ -2600,24 +3160,25 @@ bool wxAuiNotebook::InsertPage(size_t page_idx,
     // (though no select events will be fired)
     if (!select && m_tabs.GetPageCount() == 1)
         select = true;
     // (though no select events will be fired)
     if (!select && m_tabs.GetPageCount() == 1)
         select = true;
-        //m_curpage = GetPageIndex(page);
+        //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);
 
     UpdateTabCtrlHeight();
     DoSizing();
     active_tabctrl->DoShowHide();
 
         active_tabctrl->InsertPage(page, info, page_idx);
 
     UpdateTabCtrlHeight();
     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;
@@ -2628,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)))
     {
@@ -2641,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();
     }
@@ -2655,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))
@@ -2696,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;
+
+        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;
+    }
 
 
-    RemoveEmptyTabFrames();
 
 
-    // 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;
 }
 
@@ -2793,69 +3396,36 @@ wxBitmap wxAuiNotebook::GetPageBitmap(size_t page_idx) const
 // 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)
 {
 {
-    // don't change the page unless necessary
-    if ((int)new_page == m_curpage)
-        return m_curpage;
-
-    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);
-
-            ctrl->SetActivePage(ctrl_idx);
-            DoSizing();
-            ctrl->DoShowHide();
-
+    return DoModifySelection(new_page, true);
+}
 
 
+void wxAuiNotebook::SetSelectionToWindow(wxWindow *win)
+{
+    const int idx = m_tabs.GetIdxFromWindow(win);
+    wxCHECK_RET( idx != wxNOT_FOUND, wxT("invalid notebook page") );
 
 
-            // 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();
+    // 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)
 
 
-            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
@@ -2893,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;
@@ -2920,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,
@@ -2965,16 +3535,16 @@ bool wxAuiNotebook::FindTab(wxWindow* page, wxAuiTabCtrl** ctrl, int* idx)
 void wxAuiNotebook::Split(size_t page, int direction)
 {
     wxSize cli_size = GetClientSize();
 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;
     // 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;
     // 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;
     // find out which tab control the page currently belongs to
     wxAuiTabCtrl *src_tabs, *dest_tabs;
     int src_idx = -1;
@@ -2983,14 +3553,14 @@ void wxAuiNotebook::Split(size_t page, int direction)
         return;
     if (!src_tabs || src_idx == -1)
         return;
         return;
     if (!src_tabs || src_idx == -1)
         return;
-    
+
     // choose a split size
     wxSize split_size;
     if (GetPageCount() > 2)
     {
         split_size = CalculateNewSplitSize();
     }
     // choose a split size
     wxSize split_size;
     if (GetPageCount() > 2)
     {
         split_size = CalculateNewSplitSize();
     }
-     else
+    else
     {
         // because there are two panes, always split them
         // equally
     {
         // because there are two panes, always split them
         // equally
@@ -2998,50 +3568,50 @@ void wxAuiNotebook::Split(size_t page, int direction)
         split_size.x /= 2;
         split_size.y /= 2;
     }
         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);
     // create a new tab frame
     wxTabFrame* new_tabs = new wxTabFrame;
     new_tabs->m_rect = wxRect(wxPoint(0,0), split_size);
-    new_tabs->SetTabCtrlHeight(m_tab_ctrl_height);
+    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);
     dest_tabs = new_tabs->m_tabs;
 
     // create a pane info structure with the information
     // about where the pane should be added
     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 pane_info = wxAuiPaneInfo().Bottom().CaptionVisible(false);
+    wxAuiPaneInfo paneInfo = wxAuiPaneInfo().Bottom().CaptionVisible(false);
     wxPoint mouse_pt;
     wxPoint mouse_pt;
-        
+
     if (direction == wxLEFT)
     {
     if (direction == wxLEFT)
     {
-        pane_info.Left();
+        paneInfo.Left();
         mouse_pt = wxPoint(0, cli_size.y/2);
     }
         mouse_pt = wxPoint(0, cli_size.y/2);
     }
-     else if (direction == wxRIGHT)
+    else if (direction == wxRIGHT)
     {
     {
-        pane_info.Right();
+        paneInfo.Right();
         mouse_pt = wxPoint(cli_size.x, cli_size.y/2);
     }
         mouse_pt = wxPoint(cli_size.x, cli_size.y/2);
     }
-     else if (direction == wxTOP)
+    else if (direction == wxTOP)
     {
     {
-        pane_info.Top();
+        paneInfo.Top();
         mouse_pt = wxPoint(cli_size.x/2, 0);
     }
         mouse_pt = wxPoint(cli_size.x/2, 0);
     }
-     else if (direction == wxBOTTOM)
+    else if (direction == wxBOTTOM)
     {
     {
-        pane_info.Bottom();
+        paneInfo.Bottom();
         mouse_pt = wxPoint(cli_size.x/2, cli_size.y);
     }
         mouse_pt = wxPoint(cli_size.x/2, cli_size.y);
     }
-        
-    m_mgr.AddPane(new_tabs, pane_info, mouse_pt);
+
+    m_mgr.AddPane(new_tabs, paneInfo, mouse_pt);
     m_mgr.Update();
     m_mgr.Update();
-            
+
     // remove the page from the source tabs
     wxAuiNotebookPage page_info = src_tabs->GetPage(src_idx);
     page_info.active = false;
     // remove the page from the source tabs
     wxAuiNotebookPage page_info = src_tabs->GetPage(src_idx);
     page_info.active = false;
@@ -3067,11 +3637,11 @@ void wxAuiNotebook::Split(size_t page, int direction)
     dest_tabs->Refresh();
 
     // force the set selection function reset the selection
     dest_tabs->Refresh();
 
     // force the set selection function reset the selection
-    m_curpage = -1;
-    
+    m_curPage = -1;
+
     // set the active page to the one we just split off
     // set the active page to the one we just split off
-    SetSelection(m_tabs.GetIdxFromWindow(page_info.window));
-    
+    SetSelectionToPage(page_info);
+
     UpdateHintWindowSize();
 }
 
     UpdateHintWindowSize();
 }
 
@@ -3083,28 +3653,31 @@ void wxAuiNotebook::OnSize(wxSizeEvent& evt)
     evt.Skip();
 }
 
     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);
@@ -3140,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;
             }
 
@@ -3153,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;
 
         }
 
 
         }
 
@@ -3194,7 +3767,7 @@ void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt)
                 }
             }
         }
                 }
             }
         }
-         else
+        else
         {
             if (!dest_tabs)
             {
         {
             if (!dest_tabs)
             {
@@ -3227,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();
@@ -3296,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);
@@ -3333,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;
             }
@@ -3344,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
@@ -3366,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())
@@ -3381,12 +3971,12 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
             // If there is no tabframe at all, create one
             wxTabFrame* new_tabs = new wxTabFrame;
             new_tabs->m_rect = wxRect(wxPoint(0,0), CalculateNewSplitSize());
             // If there is no tabframe at all, create one
             wxTabFrame* new_tabs = new wxTabFrame;
             new_tabs->m_rect = wxRect(wxPoint(0,0), CalculateNewSplitSize());
-            new_tabs->SetTabCtrlHeight(m_tab_ctrl_height);
+            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);
 
@@ -3427,17 +4017,36 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
         dest_tabs->Refresh();
 
         // force the set selection function reset the selection
         dest_tabs->Refresh();
 
         // force the set selection function reset the selection
-        m_curpage = -1;
+        m_curPage = -1;
 
         // set the active page to the one we just split off
 
         // set the active page to the one we just split off
-        SetSelection(m_tabs.GetIdxFromWindow(page_info.window));
+        SetSelectionToPage(page_info);
 
         UpdateHintWindowSize();
     }
 
         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
@@ -3498,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;
         }
@@ -3526,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);
 
 
-void wxAuiNotebook::OnTabButton(wxCommandEvent& command_evt)
+                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(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);
@@ -3565,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