wxAuiNotebook has external tab dragging now

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@43121 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Benjamin Williams
2006-11-06 13:44:26 +00:00
parent 56c6aab7e6
commit 5d3aeb0f57
3 changed files with 308 additions and 90 deletions

View File

@@ -27,6 +27,8 @@
#include "wx/control.h" #include "wx/control.h"
class wxAuiNotebook;
enum wxAuiNotebookOption enum wxAuiNotebookOption
{ {
@@ -36,11 +38,13 @@ enum wxAuiNotebookOption
wxAUI_NB_BOTTOM = 1 << 3, // not implemented yet wxAUI_NB_BOTTOM = 1 << 3, // not implemented yet
wxAUI_NB_TAB_SPLIT = 1 << 4, wxAUI_NB_TAB_SPLIT = 1 << 4,
wxAUI_NB_TAB_MOVE = 1 << 5, wxAUI_NB_TAB_MOVE = 1 << 5,
wxAUI_NB_SCROLL_BUTTONS = 1 << 6, wxAUI_NB_TAB_EXTERNAL_MOVE = 1 << 6,
wxAUI_NB_WINDOWLIST_BUTTON = 1 << 7, wxAUI_NB_SCROLL_BUTTONS = 1 << 7,
wxAUI_NB_CLOSE_BUTTON = 1 << 8, wxAUI_NB_WINDOWLIST_BUTTON = 1 << 8,
wxAUI_NB_CLOSE_ON_ACTIVE_TAB = 1 << 9, wxAUI_NB_CLOSE_BUTTON = 1 << 9,
wxAUI_NB_CLOSE_ON_ALL_TABS = 1 << 10, 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_DEFAULT_STYLE = wxAUI_NB_TOP |
wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_SPLIT |
@@ -192,24 +196,33 @@ public:
int win_id = 0) int win_id = 0)
: wxNotifyEvent(command_type, win_id) : wxNotifyEvent(command_type, win_id)
{ {
old_selection = -1;
selection = -1;
drag_source = NULL;
} }
#ifndef SWIG #ifndef SWIG
wxAuiNotebookEvent(const wxAuiNotebookEvent& c) : wxNotifyEvent(c) wxAuiNotebookEvent(const wxAuiNotebookEvent& c) : wxNotifyEvent(c)
{ {
old_selection = c.old_selection; old_selection = c.old_selection;
selection = c.selection; selection = c.selection;
drag_source = c.drag_source;
} }
#endif #endif
wxEvent *Clone() const { return new wxAuiNotebookEvent(*this); } wxEvent *Clone() const { return new wxAuiNotebookEvent(*this); }
void SetSelection(int s) { selection = s; m_commandInt = s; } void SetSelection(int s) { selection = s; m_commandInt = s; }
void SetOldSelection(int s) { old_selection = s; }
int GetSelection() const { return selection; } int GetSelection() const { return selection; }
void SetOldSelection(int s) { old_selection = s; }
int GetOldSelection() const { return old_selection; } int GetOldSelection() const { return old_selection; }
void SetDragSource(wxAuiNotebook* s) { drag_source = s; }
wxAuiNotebook* GetDragSource() const { return drag_source; }
public: public:
int old_selection; int old_selection;
int selection; int selection;
wxAuiNotebook* drag_source;
#ifndef SWIG #ifndef SWIG
private: private:
@@ -343,6 +356,7 @@ protected:
wxAuiTabContainerButton* m_hover_button; wxAuiTabContainerButton* m_hover_button;
#ifndef SWIG #ifndef SWIG
DECLARE_CLASS(wxAuiTabCtrl)
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
#endif #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_BEGIN_DRAG, 0)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_AUI, wxEVT_COMMAND_AUINOTEBOOK_END_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_DRAG_MOTION, 0)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_AUI, wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 0)
END_DECLARE_EVENT_TYPES() END_DECLARE_EVENT_TYPES()
typedef void (wxEvtHandler::*wxAuiNotebookEventFunction)(wxAuiNotebookEvent&); 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)) wx__DECLARE_EVT1(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, winid, wxAuiNotebookEventHandler(fn))
#define EVT_AUINOTEBOOK_DRAG_MOTION(winid, fn) \ #define EVT_AUINOTEBOOK_DRAG_MOTION(winid, fn) \
wx__DECLARE_EVT1(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, winid, wxAuiNotebookEventHandler(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 #else
@@ -484,6 +501,7 @@ typedef void (wxEvtHandler::*wxAuiNotebookEventFunction)(wxAuiNotebookEvent&);
%constant wxEventType wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG; %constant wxEventType wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG;
%constant wxEventType wxEVT_COMMAND_AUINOTEBOOK_END_DRAG; %constant wxEventType wxEVT_COMMAND_AUINOTEBOOK_END_DRAG;
%constant wxEventType wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION; %constant wxEventType wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION;
%constant wxEventType wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND;
%pythoncode { %pythoncode {
EVT_AUINOTEBOOK_PAGE_CHANGED = wx.PyEventBinder( wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, 1 ) 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_BEGIN_DRAG = wx.PyEventBinder( wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, 1 )
EVT_AUINOTEBOOK_END_DRAG = wx.PyEventBinder( wxEVT_COMMAND_AUINOTEBOOK_END_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_DRAG_MOTION = wx.PyEventBinder( wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, 1 )
EVT_AUINOTEBOOK_ALLOW_DND = wx.PyEventBinder( wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, 1 )
} }
#endif #endif

View File

@@ -90,6 +90,7 @@ class MyFrame : public wxFrame
ID_NotebookCloseButtonAll, ID_NotebookCloseButtonAll,
ID_NotebookCloseButtonActive, ID_NotebookCloseButtonActive,
ID_NotebookAllowTabMove, ID_NotebookAllowTabMove,
ID_NotebookAllowTabExternalMove,
ID_NotebookAllowTabSplit, ID_NotebookAllowTabSplit,
ID_NotebookWindowList, ID_NotebookWindowList,
ID_NotebookScrollButtons, ID_NotebookScrollButtons,
@@ -136,6 +137,7 @@ private:
void OnCopyPerspectiveCode(wxCommandEvent& evt); void OnCopyPerspectiveCode(wxCommandEvent& evt);
void OnRestorePerspective(wxCommandEvent& evt); void OnRestorePerspective(wxCommandEvent& evt);
void OnSettings(wxCommandEvent& evt); void OnSettings(wxCommandEvent& evt);
void OnAllowNotebookDnD(wxAuiNotebookEvent& evt);
void OnExit(wxCommandEvent& evt); void OnExit(wxCommandEvent& evt);
void OnAbout(wxCommandEvent& evt); void OnAbout(wxCommandEvent& evt);
@@ -577,6 +579,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_NotebookCloseButtonAll, MyFrame::OnNotebookFlag) EVT_MENU(ID_NotebookCloseButtonAll, MyFrame::OnNotebookFlag)
EVT_MENU(ID_NotebookCloseButtonActive, MyFrame::OnNotebookFlag) EVT_MENU(ID_NotebookCloseButtonActive, MyFrame::OnNotebookFlag)
EVT_MENU(ID_NotebookAllowTabMove, MyFrame::OnNotebookFlag) EVT_MENU(ID_NotebookAllowTabMove, MyFrame::OnNotebookFlag)
EVT_MENU(ID_NotebookAllowTabExternalMove, MyFrame::OnNotebookFlag)
EVT_MENU(ID_NotebookAllowTabSplit, MyFrame::OnNotebookFlag) EVT_MENU(ID_NotebookAllowTabSplit, MyFrame::OnNotebookFlag)
EVT_MENU(ID_NotebookScrollButtons, MyFrame::OnNotebookFlag) EVT_MENU(ID_NotebookScrollButtons, MyFrame::OnNotebookFlag)
EVT_MENU(ID_NotebookWindowList, 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_NotebookCloseButtonAll, MyFrame::OnUpdateUI)
EVT_UPDATE_UI(ID_NotebookCloseButtonActive, MyFrame::OnUpdateUI) EVT_UPDATE_UI(ID_NotebookCloseButtonActive, MyFrame::OnUpdateUI)
EVT_UPDATE_UI(ID_NotebookAllowTabMove, 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_NotebookAllowTabSplit, MyFrame::OnUpdateUI)
EVT_UPDATE_UI(ID_NotebookScrollButtons, MyFrame::OnUpdateUI) EVT_UPDATE_UI(ID_NotebookScrollButtons, MyFrame::OnUpdateUI)
EVT_UPDATE_UI(ID_NotebookWindowList, 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, EVT_MENU_RANGE(MyFrame::ID_FirstPerspective, MyFrame::ID_FirstPerspective+1000,
MyFrame::OnRestorePerspective) MyFrame::OnRestorePerspective)
EVT_AUI_PANECLOSE(MyFrame::OnPaneClose) EVT_AUI_PANECLOSE(MyFrame::OnPaneClose)
EVT_AUINOTEBOOK_ALLOW_DND(wxID_ANY, MyFrame::OnAllowNotebookDnD)
END_EVENT_TABLE() END_EVENT_TABLE()
@@ -632,7 +637,7 @@ MyFrame::MyFrame(wxWindow* parent,
SetIcon(wxIcon(sample_xpm)); SetIcon(wxIcon(sample_xpm));
// set up default notebook style // 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 // create menu
wxMenuBar* mb = new wxMenuBar; wxMenuBar* mb = new wxMenuBar;
@@ -680,6 +685,7 @@ MyFrame::MyFrame(wxWindow* parent,
notebook_menu->AppendRadioItem(ID_NotebookCloseButtonActive, _("Close Button on Active Tab")); notebook_menu->AppendRadioItem(ID_NotebookCloseButtonActive, _("Close Button on Active Tab"));
notebook_menu->AppendSeparator(); notebook_menu->AppendSeparator();
notebook_menu->AppendCheckItem(ID_NotebookAllowTabMove, _("Allow Tab Move")); 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_NotebookAllowTabSplit, _("Allow Notebook Split"));
notebook_menu->AppendCheckItem(ID_NotebookScrollButtons, _("Scroll Buttons Visible")); notebook_menu->AppendCheckItem(ID_NotebookScrollButtons, _("Scroll Buttons Visible"));
notebook_menu->AppendCheckItem(ID_NotebookWindowList, _("Window List Button Visible")); notebook_menu->AppendCheckItem(ID_NotebookWindowList, _("Window List Button Visible"));
@@ -1044,6 +1050,10 @@ void MyFrame::OnNotebookFlag(wxCommandEvent& event)
if (id == ID_NotebookAllowTabMove) if (id == ID_NotebookAllowTabMove)
{ {
m_notebook_style ^= wxAUI_NB_TAB_MOVE; m_notebook_style ^= wxAUI_NB_TAB_MOVE;
}
if (id == ID_NotebookAllowTabExternalMove)
{
m_notebook_style ^= wxAUI_NB_TAB_EXTERNAL_MOVE;
} }
else if (id == ID_NotebookAllowTabSplit) else if (id == ID_NotebookAllowTabSplit)
{ {
@@ -1137,6 +1147,9 @@ void MyFrame::OnUpdateUI(wxUpdateUIEvent& event)
case ID_NotebookAllowTabMove: case ID_NotebookAllowTabMove:
event.Check((m_notebook_style & wxAUI_NB_TAB_MOVE) != 0); event.Check((m_notebook_style & wxAUI_NB_TAB_MOVE) != 0);
break; break;
case ID_NotebookAllowTabExternalMove:
event.Check((m_notebook_style & wxAUI_NB_TAB_EXTERNAL_MOVE) != 0);
break;
case ID_NotebookScrollButtons: case ID_NotebookScrollButtons:
event.Check((m_notebook_style & wxAUI_NB_SCROLL_BUTTONS) != 0); event.Check((m_notebook_style & wxAUI_NB_SCROLL_BUTTONS) != 0);
break; break;
@@ -1177,7 +1190,7 @@ void MyFrame::OnCreatePerspective(wxCommandEvent& WXUNUSED(event))
m_perspectives.Add(m_mgr.SavePerspective()); m_perspectives.Add(m_mgr.SavePerspective());
} }
void MyFrame::OnCopyPerspectiveCode(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnCopyPerspectiveCode(wxCommandEvent& WXUNUSED(evt))
{ {
wxString s = m_mgr.SavePerspective(); wxString s = m_mgr.SavePerspective();
@@ -1190,11 +1203,17 @@ void MyFrame::OnCopyPerspectiveCode(wxCommandEvent& WXUNUSED(event))
#endif #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() wxPoint MyFrame::GetStartPosition()
{ {

View 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_BEGIN_DRAG)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG) DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION) DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND)
IMPLEMENT_CLASS(wxAuiNotebook, wxControl) IMPLEMENT_CLASS(wxAuiNotebook, wxControl)
IMPLEMENT_CLASS(wxAuiTabCtrl, wxControl)
IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent, wxEvent) IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent, wxEvent)
@@ -1743,6 +1745,29 @@ bool wxAuiNotebook::InsertPage(size_t page_idx,
bool wxAuiNotebook::DeletePage(size_t page_idx) bool wxAuiNotebook::DeletePage(size_t page_idx)
{ {
wxWindow* wnd = m_tabs.GetWindowFromIdx(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; wxWindow* new_active = NULL;
// find out which onscreen tab ctrl owns this tab // find out which onscreen tab ctrl owns this tab
@@ -1806,6 +1831,7 @@ bool wxAuiNotebook::DeletePage(size_t page_idx)
} }
return true; return true;
*/
} }
@@ -1814,21 +1840,58 @@ bool wxAuiNotebook::DeletePage(size_t page_idx)
// but does not destroy the window // but does not destroy the window
bool wxAuiNotebook::RemovePage(size_t page_idx) bool wxAuiNotebook::RemovePage(size_t page_idx)
{ {
// remove the tab from our own catalog
wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx); wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
wxWindow* new_active = NULL;
// 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;
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)) if (!m_tabs.RemovePage(wnd))
return false; return false;
// remove the tab from the onscreen tab ctrl // remove the tab from the onscreen tab ctrl
wxAuiTabCtrl* ctrl; ctrl->RemovePage(wnd);
int ctrl_idx;
if (FindTab(wnd, &ctrl, &ctrl_idx))
{
ctrl->RemovePage(wnd);
return true;
}
return false;
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 // SetPageText() changes the tab caption of the specified page
@@ -2059,8 +2122,8 @@ void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt)
wxPoint zero(0,0); wxPoint zero(0,0);
wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject(); wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject();
wxAuiTabCtrl* dest_tabs = GetTabCtrlFromPoint(client_pt); wxAuiTabCtrl* dest_tabs = GetTabCtrlFromPoint(client_pt);
if (dest_tabs == src_tabs) if (dest_tabs == src_tabs)
{ {
if (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 tab moving is not allowed, leave
if (!(m_flags & wxAUI_NB_TAB_SPLIT)) if (!(m_flags & wxAUI_NB_TAB_SPLIT))
{ {
@@ -2142,16 +2238,12 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
m_mgr.HideHint(); 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* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject();
wxAuiTabCtrl* dest_tabs = NULL;
if (src_tabs) if (src_tabs)
{ {
// set cursor back to an arrow
src_tabs->SetCursor(wxCursor(wxCURSOR_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); wxPoint mouse_client_pt = ScreenToClient(mouse_screen_pt);
// the src tab control is the control that fired this event
wxAuiTabCtrl* dest_tabs = NULL;
// check for an external move
// If the pointer is in an existing tab frame, do a tab insert if (m_flags & wxAUI_NB_TAB_EXTERNAL_MOVE)
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; wxWindow* tab_ctrl = ::wxFindWindowAtPoint(mouse_screen_pt);
if (dest_tabs == src_tabs)
return;
while (tab_ctrl)
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); if (tab_ctrl->IsKindOf(CLASSINFO(wxAuiTabCtrl)))
break;
tab_ctrl = tab_ctrl->GetParent();
}
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);
}
// 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;
}
} }
} }
else
// only perform a tab split if it's allowed
if (m_flags & wxAUI_NB_TAB_SPLIT)
{ {
// If there is no tabframe at all, create one // If the pointer is in an existing tab frame, do a tab insert
wxTabFrame* new_tabs = new wxTabFrame; wxWindow* hit_wnd = ::wxFindWindowAtPoint(mouse_screen_pt);
new_tabs->SetTabCtrlHeight(m_tab_ctrl_height); wxTabFrame* tab_frame = (wxTabFrame*)GetTabFrameFromTabCtrl(hit_wnd);
new_tabs->m_tabs = new wxAuiTabCtrl(this, int insert_idx = -1;
m_tab_id_counter++, if (tab_frame)
wxDefaultPosition, {
wxDefaultSize, dest_tabs = tab_frame->m_tabs;
wxNO_BORDER);
new_tabs->m_tabs->SetFlags(m_flags);
m_mgr.AddPane(new_tabs, if (dest_tabs == src_tabs)
wxAuiPaneInfo().Bottom().CaptionVisible(false), return;
mouse_client_pt);
m_mgr.Update();
dest_tabs = new_tabs->m_tabs; 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;
}
// 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();
}
// 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));
} }
// 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();
}
// 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));
} }