]> git.saurik.com Git - wxWidgets.git/commitdiff
wxAuiNotebook has external tab dragging now
authorBenjamin Williams <bwilliams@kirix.com>
Mon, 6 Nov 2006 13:44:26 +0000 (13:44 +0000)
committerBenjamin Williams <bwilliams@kirix.com>
Mon, 6 Nov 2006 13:44:26 +0000 (13:44 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@43121 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/aui/auibook.h
samples/aui/auidemo.cpp
src/aui/auibook.cpp

index bbe5b596a5f3cc3d7467d3452df7dd449de9aecf..cbb43cfcd5c86dd4e201953c964441ad64169053 100644 (file)
@@ -27,6 +27,8 @@
 #include "wx/control.h"
 
 
+class wxAuiNotebook;
+
 
 enum wxAuiNotebookOption
 {
@@ -36,11 +38,13 @@ enum wxAuiNotebookOption
     wxAUI_NB_BOTTOM              = 1 << 3,  // not implemented yet
     wxAUI_NB_TAB_SPLIT           = 1 << 4,
     wxAUI_NB_TAB_MOVE            = 1 << 5,
-    wxAUI_NB_SCROLL_BUTTONS      = 1 << 6,
-    wxAUI_NB_WINDOWLIST_BUTTON   = 1 << 7,
-    wxAUI_NB_CLOSE_BUTTON        = 1 << 8,
-    wxAUI_NB_CLOSE_ON_ACTIVE_TAB = 1 << 9,
-    wxAUI_NB_CLOSE_ON_ALL_TABS   = 1 << 10,
+    wxAUI_NB_TAB_EXTERNAL_MOVE   = 1 << 6,
+    wxAUI_NB_SCROLL_BUTTONS      = 1 << 7,
+    wxAUI_NB_WINDOWLIST_BUTTON   = 1 << 8,
+    wxAUI_NB_CLOSE_BUTTON        = 1 << 9,
+    wxAUI_NB_CLOSE_ON_ACTIVE_TAB = 1 << 10,
+    wxAUI_NB_CLOSE_ON_ALL_TABS   = 1 << 11,
+    
     
     wxAUI_NB_DEFAULT_STYLE = wxAUI_NB_TOP |
                              wxAUI_NB_TAB_SPLIT |
@@ -192,24 +196,33 @@ public:
                        int win_id = 0)
           : wxNotifyEvent(command_type, win_id)
     {
+        old_selection = -1;
+        selection = -1;
+        drag_source = NULL;
     }
 #ifndef SWIG
     wxAuiNotebookEvent(const wxAuiNotebookEvent& c) : wxNotifyEvent(c)
     {
         old_selection = c.old_selection;
         selection = c.selection;
+        drag_source = c.drag_source;
     }
 #endif
     wxEvent *Clone() const { return new wxAuiNotebookEvent(*this); }
 
     void SetSelection(int s) { selection = s; m_commandInt = s; }
-    void SetOldSelection(int s) { old_selection = s; }
     int GetSelection() const { return selection; }
+    
+    void SetOldSelection(int s) { old_selection = s; }
     int GetOldSelection() const { return old_selection; }
+    
+    void SetDragSource(wxAuiNotebook* s) { drag_source = s; }
+    wxAuiNotebook* GetDragSource() const { return drag_source; }
 
 public:
     int old_selection;
     int selection;
+    wxAuiNotebook* drag_source;
 
 #ifndef SWIG
 private:
@@ -343,6 +356,7 @@ protected:
     wxAuiTabContainerButton* m_hover_button;
 
 #ifndef SWIG
+    DECLARE_CLASS(wxAuiTabCtrl)
     DECLARE_EVENT_TABLE()
 #endif
 };
@@ -455,6 +469,7 @@ BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_AUI, wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, 0)
     DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_AUI, wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, 0)
     DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_AUI, wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 0)
+    DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_AUI, wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 0)
 END_DECLARE_EVENT_TYPES()
 
 typedef void (wxEvtHandler::*wxAuiNotebookEventFunction)(wxAuiNotebookEvent&);
@@ -474,6 +489,8 @@ typedef void (wxEvtHandler::*wxAuiNotebookEventFunction)(wxAuiNotebookEvent&);
     wx__DECLARE_EVT1(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, winid, wxAuiNotebookEventHandler(fn))
 #define EVT_AUINOTEBOOK_DRAG_MOTION(winid, fn) \
     wx__DECLARE_EVT1(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, winid, wxAuiNotebookEventHandler(fn))
+#define EVT_AUINOTEBOOK_ALLOW_DND(winid, fn) \
+    wx__DECLARE_EVT1(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, winid, wxAuiNotebookEventHandler(fn))
 
 #else
 
@@ -484,6 +501,7 @@ typedef void (wxEvtHandler::*wxAuiNotebookEventFunction)(wxAuiNotebookEvent&);
 %constant wxEventType wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG;
 %constant wxEventType wxEVT_COMMAND_AUINOTEBOOK_END_DRAG;
 %constant wxEventType wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION;
+%constant wxEventType wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND;
 
 %pythoncode {
     EVT_AUINOTEBOOK_PAGE_CHANGED = wx.PyEventBinder( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, 1 )
@@ -492,6 +510,7 @@ typedef void (wxEvtHandler::*wxAuiNotebookEventFunction)(wxAuiNotebookEvent&);
     EVT_AUINOTEBOOK_BEGIN_DRAG = wx.PyEventBinder( wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, 1 )
     EVT_AUINOTEBOOK_END_DRAG = wx.PyEventBinder( wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, 1 )
     EVT_AUINOTEBOOK_DRAG_MOTION = wx.PyEventBinder( wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 1 )
+    EVT_AUINOTEBOOK_ALLOW_DND = wx.PyEventBinder( wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 1 )
 }
 #endif
 
index 23ebd8bb734f79267f0b373c4562eff329a87983..a531dc033ff491de40efc3c787e09a8a4377c4b1 100644 (file)
@@ -90,6 +90,7 @@ class MyFrame : public wxFrame
         ID_NotebookCloseButtonAll,
         ID_NotebookCloseButtonActive,
         ID_NotebookAllowTabMove,
+        ID_NotebookAllowTabExternalMove,
         ID_NotebookAllowTabSplit,
         ID_NotebookWindowList,
         ID_NotebookScrollButtons,
@@ -136,6 +137,7 @@ private:
     void OnCopyPerspectiveCode(wxCommandEvent& evt);
     void OnRestorePerspective(wxCommandEvent& evt);
     void OnSettings(wxCommandEvent& evt);
+    void OnAllowNotebookDnD(wxAuiNotebookEvent& evt);
     void OnExit(wxCommandEvent& evt);
     void OnAbout(wxCommandEvent& evt);
 
@@ -577,6 +579,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(ID_NotebookCloseButtonAll, MyFrame::OnNotebookFlag)
     EVT_MENU(ID_NotebookCloseButtonActive, MyFrame::OnNotebookFlag)
     EVT_MENU(ID_NotebookAllowTabMove, MyFrame::OnNotebookFlag)
+    EVT_MENU(ID_NotebookAllowTabExternalMove, MyFrame::OnNotebookFlag)
     EVT_MENU(ID_NotebookAllowTabSplit, MyFrame::OnNotebookFlag)
     EVT_MENU(ID_NotebookScrollButtons, MyFrame::OnNotebookFlag)
     EVT_MENU(ID_NotebookWindowList, MyFrame::OnNotebookFlag)
@@ -597,6 +600,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_UPDATE_UI(ID_NotebookCloseButtonAll, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_NotebookCloseButtonActive, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_NotebookAllowTabMove, MyFrame::OnUpdateUI)
+    EVT_UPDATE_UI(ID_NotebookAllowTabExternalMove, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_NotebookAllowTabSplit, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_NotebookScrollButtons, MyFrame::OnUpdateUI)
     EVT_UPDATE_UI(ID_NotebookWindowList, MyFrame::OnUpdateUI)
@@ -614,6 +618,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU_RANGE(MyFrame::ID_FirstPerspective, MyFrame::ID_FirstPerspective+1000,
                    MyFrame::OnRestorePerspective)
     EVT_AUI_PANECLOSE(MyFrame::OnPaneClose)
+    EVT_AUINOTEBOOK_ALLOW_DND(wxID_ANY, MyFrame::OnAllowNotebookDnD)
 END_EVENT_TABLE()
 
 
@@ -632,7 +637,7 @@ MyFrame::MyFrame(wxWindow* parent,
     SetIcon(wxIcon(sample_xpm));
 
     // set up default notebook style
-    m_notebook_style = wxAUI_NB_DEFAULT_STYLE | wxNO_BORDER;
+    m_notebook_style = wxAUI_NB_DEFAULT_STYLE | wxAUI_NB_TAB_EXTERNAL_MOVE | wxNO_BORDER;
 
     // create menu
     wxMenuBar* mb = new wxMenuBar;
@@ -680,6 +685,7 @@ MyFrame::MyFrame(wxWindow* parent,
     notebook_menu->AppendRadioItem(ID_NotebookCloseButtonActive, _("Close Button on Active Tab"));
     notebook_menu->AppendSeparator();
     notebook_menu->AppendCheckItem(ID_NotebookAllowTabMove, _("Allow Tab Move"));
+    notebook_menu->AppendCheckItem(ID_NotebookAllowTabExternalMove, _("Allow External Tab Move"));
     notebook_menu->AppendCheckItem(ID_NotebookAllowTabSplit, _("Allow Notebook Split"));
     notebook_menu->AppendCheckItem(ID_NotebookScrollButtons, _("Scroll Buttons Visible"));
     notebook_menu->AppendCheckItem(ID_NotebookWindowList, _("Window List Button Visible"));
@@ -1044,6 +1050,10 @@ void MyFrame::OnNotebookFlag(wxCommandEvent& event)
     if (id == ID_NotebookAllowTabMove)
     {
         m_notebook_style ^= wxAUI_NB_TAB_MOVE;
+    }
+    if (id == ID_NotebookAllowTabExternalMove)
+    {
+        m_notebook_style ^= wxAUI_NB_TAB_EXTERNAL_MOVE;
     }
      else if (id == ID_NotebookAllowTabSplit)
     {
@@ -1137,6 +1147,9 @@ void MyFrame::OnUpdateUI(wxUpdateUIEvent& event)
         case ID_NotebookAllowTabMove:
             event.Check((m_notebook_style & wxAUI_NB_TAB_MOVE) != 0);
             break;
+        case ID_NotebookAllowTabExternalMove:
+            event.Check((m_notebook_style & wxAUI_NB_TAB_EXTERNAL_MOVE) != 0);
+            break;
         case ID_NotebookScrollButtons:
             event.Check((m_notebook_style & wxAUI_NB_SCROLL_BUTTONS) != 0);
             break;
@@ -1177,7 +1190,7 @@ void MyFrame::OnCreatePerspective(wxCommandEvent& WXUNUSED(event))
     m_perspectives.Add(m_mgr.SavePerspective());
 }
 
-void MyFrame::OnCopyPerspectiveCode(wxCommandEvent& WXUNUSED(event))
+void MyFrame::OnCopyPerspectiveCode(wxCommandEvent& WXUNUSED(evt))
 {
     wxString s = m_mgr.SavePerspective();
 
@@ -1190,11 +1203,17 @@ void MyFrame::OnCopyPerspectiveCode(wxCommandEvent& WXUNUSED(event))
 #endif
 }
 
-void MyFrame::OnRestorePerspective(wxCommandEvent& event)
+void MyFrame::OnRestorePerspective(wxCommandEvent& evt)
 {
-    m_mgr.LoadPerspective(m_perspectives.Item(event.GetId() - ID_FirstPerspective));
+    m_mgr.LoadPerspective(m_perspectives.Item(evt.GetId() - ID_FirstPerspective));
 }
 
+void MyFrame::OnAllowNotebookDnD(wxAuiNotebookEvent& evt)
+{    
+    // for the purpose of this test application, explicitly
+    // allow all noteboko drag and drop events
+    evt.Allow();
+}
 
 wxPoint MyFrame::GetStartPosition()
 {
index 3c913453a5b46a3aa760d0e669e6c11241868f4f..bc7f8fb218abde90295cecb68d420d74d8a10312 100644 (file)
@@ -41,9 +41,11 @@ 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)
 
 
 IMPLEMENT_CLASS(wxAuiNotebook, wxControl)
+IMPLEMENT_CLASS(wxAuiTabCtrl, wxControl)
 IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent, wxEvent)
 
 
@@ -1743,6 +1745,29 @@ bool wxAuiNotebook::InsertPage(size_t page_idx,
 bool wxAuiNotebook::DeletePage(size_t page_idx)
 {    
     wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
+
+    if (!RemovePage(page_idx))
+        return false;
+
+
+    // actually destroy the window now
+    if (wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
+    {
+        // delete the child frame with pending delete, as is
+        // customary with frame windows
+        if (!wxPendingDelete.Member(wnd))
+            wxPendingDelete.Append(wnd);
+    }
+     else
+    {
+        wnd->Destroy();
+    }
+    
+    return true;
+    
+/*
+
+    wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
     wxWindow* new_active = NULL;
 
     // find out which onscreen tab ctrl owns this tab
@@ -1806,6 +1831,7 @@ bool wxAuiNotebook::DeletePage(size_t page_idx)
     }
     
     return true;
+    */
 }
 
 
@@ -1814,21 +1840,58 @@ bool wxAuiNotebook::DeletePage(size_t page_idx)
 // but does not destroy the window
 bool wxAuiNotebook::RemovePage(size_t page_idx)
 {
-    // remove the tab from our own catalog
     wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
-    if (!m_tabs.RemovePage(wnd))
-        return false;
+    wxWindow* new_active = NULL;
 
-    // remove the tab from the onscreen tab ctrl
+    // find out which onscreen tab ctrl owns this tab
     wxAuiTabCtrl* ctrl;
     int ctrl_idx;
-    if (FindTab(wnd, &ctrl, &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;
+
+    if (new_idx >= 0 && new_idx < (int)ctrl->GetPageCount())
     {
-        ctrl->RemovePage(wnd);
-        return true;
+        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;
+            }
+        }
     }
 
-    return false;
+    // remove the tab from main catalog
+    if (!m_tabs.RemovePage(wnd))
+        return false;
+
+    // remove the tab from the onscreen tab ctrl
+    ctrl->RemovePage(wnd);
+
+
+    RemoveEmptyTabFrames();
+
+    // set new active pane
+    if (new_active)
+    {
+        m_curpage = -1;
+        SetSelection(m_tabs.GetIdxFromWindow(new_active));
+    }
+    
+    return true;
 }
 
 // SetPageText() changes the tab caption of the specified page
@@ -2059,8 +2122,8 @@ void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt)
     wxPoint zero(0,0);
 
     wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject();
-
     wxAuiTabCtrl* dest_tabs = GetTabCtrlFromPoint(client_pt);
+    
     if (dest_tabs == src_tabs)
     {
         if (src_tabs)
@@ -2109,6 +2172,39 @@ void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt)
     }
 
 
+    // if external drag is allowed, check if the tab is being dragged
+    // over a different wxAuiNotebook control
+    if (m_flags & wxAUI_NB_TAB_EXTERNAL_MOVE)
+    {
+        wxWindow* tab_ctrl = ::wxFindWindowAtPoint(screen_pt);
+        
+        // if we are over a hint window, leave
+        if (tab_ctrl->IsKindOf(CLASSINFO(wxFrame)))
+            return;
+        
+        while (tab_ctrl)
+        {
+            if (tab_ctrl->IsKindOf(CLASSINFO(wxAuiTabCtrl)))
+                break;
+            tab_ctrl = tab_ctrl->GetParent();
+        }
+        
+        if (tab_ctrl)
+        {
+            wxAuiNotebook* nb = (wxAuiNotebook*)tab_ctrl->GetParent();
+            
+            if (nb != this)
+            {
+                wxRect hint_rect = tab_ctrl->GetRect();
+                tab_ctrl->ClientToScreen(&hint_rect.x, &hint_rect.y);
+                m_mgr.ShowHint(hint_rect);
+                return;
+            }
+            
+        }
+    }
+
+
     // if tab moving is not allowed, leave
     if (!(m_flags & wxAUI_NB_TAB_SPLIT))
     {
@@ -2142,16 +2238,12 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
 
     m_mgr.HideHint();
 
-    // if tab moving is not allowed, leave
-    if (!(m_flags & wxAUI_NB_TAB_SPLIT))
-    {
-        return;
-    }
     
-    // set cursor back to an arrow
     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));
     }
     
@@ -2160,79 +2252,167 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
     wxPoint mouse_client_pt = ScreenToClient(mouse_screen_pt);
 
 
-    // the src tab control is the control that fired this event
-    wxAuiTabCtrl* dest_tabs = NULL;
 
-
-    // If the pointer is in an existing tab frame, do a tab insert
-    wxWindow* hit_wnd = ::wxFindWindowAtPoint(mouse_screen_pt);
-    wxTabFrame* tab_frame = (wxTabFrame*)GetTabFrameFromTabCtrl(hit_wnd);
-    int insert_idx = -1;
-    if (tab_frame)
+    // check for an external move
+    if (m_flags & wxAUI_NB_TAB_EXTERNAL_MOVE)
     {
-        dest_tabs = tab_frame->m_tabs;
-
-        if (dest_tabs == src_tabs)
-            return;
+        wxWindow* tab_ctrl = ::wxFindWindowAtPoint(mouse_screen_pt);
         
-            
-        wxPoint pt = dest_tabs->ScreenToClient(mouse_screen_pt);
-        wxWindow* target = NULL;
-        dest_tabs->TabHitTest(pt.x, pt.y, &target);
-        if (target)
+        while (tab_ctrl)
         {
-            insert_idx = dest_tabs->GetIdxFromWindow(target);
+            if (tab_ctrl->IsKindOf(CLASSINFO(wxAuiTabCtrl)))
+                break;
+            tab_ctrl = tab_ctrl->GetParent();
         }
-    }
-     else
-    {
-        // If there is no tabframe at all, create one
-        wxTabFrame* new_tabs = new wxTabFrame;
-        new_tabs->SetTabCtrlHeight(m_tab_ctrl_height);
-        new_tabs->m_tabs = new wxAuiTabCtrl(this,
-                                            m_tab_id_counter++,
-                                            wxDefaultPosition,
-                                            wxDefaultSize,
-                                            wxNO_BORDER);
-        new_tabs->m_tabs->SetFlags(m_flags);
+        
+        if (tab_ctrl)
+        {
+            wxAuiNotebook* nb = (wxAuiNotebook*)tab_ctrl->GetParent();
+            
+            if (nb != this)
+            {
+                // find out from the destination control
+                // if it's ok to drop this tab here
+                wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, m_windowId);
+                e.SetSelection(evt.GetSelection());
+                e.SetOldSelection(evt.GetSelection());
+                e.SetEventObject(this);
+                e.SetDragSource(this);
+                e.Veto(); // dropping must be explicitly approved by control owner
+                
+                nb->GetEventHandler()->ProcessEvent(e);
+                
+                if (!e.IsAllowed())
+                {
+                    // no answer or negative answer
+                    m_mgr.HideHint();
+                    return;
+                }
+                
+                // drop was allowed
+                int src_idx = evt.GetSelection();
+                wxWindow* src_page = src_tabs->GetWindowFromIdx(src_idx);
+                
+                // get main index of the page
+                int main_idx = m_tabs.GetIdxFromWindow(src_page);
+                
+                // make a copy of the page info
+                wxAuiNotebookPage page_info = m_tabs.GetPage((size_t)main_idx);
+                
+                // remove the page from the source notebook
+                RemovePage(main_idx);
+                
+                // reparent the page
+                src_page->Reparent(nb);
+                
+                
+                // found out the insert idx
+                wxAuiTabCtrl* dest_tabs = (wxAuiTabCtrl*)tab_ctrl;
+                wxPoint pt = dest_tabs->ScreenToClient(mouse_screen_pt);
+
+                wxWindow* target = NULL;
+                int insert_idx = -1;
+                dest_tabs->TabHitTest(pt.x, pt.y, &target);
+                if (target)
+                {
+                    insert_idx = dest_tabs->GetIdxFromWindow(target);
+                }
 
-        m_mgr.AddPane(new_tabs,
-                      wxAuiPaneInfo().Bottom().CaptionVisible(false),
-                      mouse_client_pt);
-        m_mgr.Update();
-        dest_tabs = new_tabs->m_tabs;
+                
+                // add the page to the new notebook
+                if (insert_idx == -1)
+                    insert_idx = dest_tabs->GetPageCount();
+                dest_tabs->InsertPage(page_info.window, page_info, insert_idx);
+                nb->m_tabs.AddPage(page_info.window, page_info);
+
+                nb->DoSizing();
+                dest_tabs->DoShowHide();
+                dest_tabs->Refresh();
+        
+                // set the selection in the destination tab control
+                nb->SetSelection(nb->m_tabs.GetIdxFromWindow(page_info.window));
+
+                return;
+            }
+        }
     }
 
 
 
-    // remove the page from the source tabs
-    wxAuiNotebookPage page_info = src_tabs->GetPage(evt.GetSelection());
-    page_info.active = false;
-    src_tabs->RemovePage(page_info.window);
-    if (src_tabs->GetPageCount() > 0)
+
+    // only perform a tab split if it's allowed
+    if (m_flags & wxAUI_NB_TAB_SPLIT)
     {
-        src_tabs->SetActivePage((size_t)0);
-        src_tabs->DoShowHide();
-        src_tabs->Refresh();
-    }
+        // If the pointer is in an existing tab frame, do a tab insert
+        wxWindow* hit_wnd = ::wxFindWindowAtPoint(mouse_screen_pt);
+        wxTabFrame* tab_frame = (wxTabFrame*)GetTabFrameFromTabCtrl(hit_wnd);
+        int insert_idx = -1;
+        if (tab_frame)
+        {
+            dest_tabs = tab_frame->m_tabs;
 
+            if (dest_tabs == src_tabs)
+                return;
+            
+                
+            wxPoint pt = dest_tabs->ScreenToClient(mouse_screen_pt);
+            wxWindow* target = NULL;
+            dest_tabs->TabHitTest(pt.x, pt.y, &target);
+            if (target)
+            {
+                insert_idx = dest_tabs->GetIdxFromWindow(target);
+            }
+        }
+         else
+        {
+            // If there is no tabframe at all, create one
+            wxTabFrame* new_tabs = new wxTabFrame;
+            new_tabs->SetTabCtrlHeight(m_tab_ctrl_height);
+            new_tabs->m_tabs = new wxAuiTabCtrl(this,
+                                                m_tab_id_counter++,
+                                                wxDefaultPosition,
+                                                wxDefaultSize,
+                                                wxNO_BORDER);
+            new_tabs->m_tabs->SetFlags(m_flags);
+
+            m_mgr.AddPane(new_tabs,
+                          wxAuiPaneInfo().Bottom().CaptionVisible(false),
+                          mouse_client_pt);
+            m_mgr.Update();
+            dest_tabs = new_tabs->m_tabs;
+        }
 
 
-    // add the page to the destination tabs
-    if (insert_idx == -1)
-        insert_idx = dest_tabs->GetPageCount();
-    dest_tabs->InsertPage(page_info.window, page_info, insert_idx);
 
-    if (src_tabs->GetPageCount() == 0)
-    {
-        RemoveEmptyTabFrames();
-    }
+        // remove the page from the source tabs
+        wxAuiNotebookPage page_info = src_tabs->GetPage(evt.GetSelection());
+        page_info.active = false;
+        src_tabs->RemovePage(page_info.window);
+        if (src_tabs->GetPageCount() > 0)
+        {
+            src_tabs->SetActivePage((size_t)0);
+            src_tabs->DoShowHide();
+            src_tabs->Refresh();
+        }
 
-    DoSizing();
-    dest_tabs->DoShowHide();
-    dest_tabs->Refresh();
 
-    SetSelection(m_tabs.GetIdxFromWindow(page_info.window));
+
+        // add the page to the destination tabs
+        if (insert_idx == -1)
+            insert_idx = dest_tabs->GetPageCount();
+        dest_tabs->InsertPage(page_info.window, page_info, insert_idx);
+
+        if (src_tabs->GetPageCount() == 0)
+        {
+            RemoveEmptyTabFrames();
+        }
+
+        DoSizing();
+        dest_tabs->DoShowHide();
+        dest_tabs->Refresh();
+
+        SetSelection(m_tabs.GetIdxFromWindow(page_info.window));
+    }
 }