Wxauinotebook is a page tab used in the wxWidgets library to display multiple pages in the same window. This is a popular page layout method. In wxWidgets, you can add pages inherited from wxwindow to notebook, and add multiple controls to the page. In addition, because the control itself also inherits from wxwindow, you can also add a single control to the notebook.
You can drag and drop pages on the pages of notebook, that is, the location of the page to be dragged. To support dragging, you must specify the style when creating the notebook. There are two styles that support drag:
Wxaui_nb_tab_move: You can drag a page from one location to another in the same notebook.
Wxaui_nb_tab_external_move: You can drag a page from one notebook to another.
The following code snippet creates two notebooks. Two text controls are added to each notebook, that is, each notebook has two pages.
// Wxauinotebook style. <Br/> long notestyle = wxaui_nb_top | wxaui_nb_tab_split | wxaui_nb_tab_move | required | wxaui_nb_windowlist_button | wxaui_nb_tab_external_move; </P> <p> // create two notebooks <br/> wxauinotebook * pnotebook1 = new wxauinotebook (this, idnotebook1, wxdefaultposition, wxsize (200,200), notestyle ); <br/> wxauinotebook * pnotebook2 = new wxauinotebook (this, idnotebook2, wxdefaultposition, wxsize (100,100), notestyle ); </P> <p> // create four controls <br/> wxtextctrl * ptext1 = new wxtextctrl (this, wxid_any ); <br/> wxtextctrl * ptext2 = new wxtextctrl (this, wxid_any); <br/> wxtextctrl * ptext3 = new wxtextctrl (this, wxid_any ); <br/> wxtextctrl * ptext4 = new wxtextctrl (this, wxid_any ); </P> <p> // Add the four controls to two notebooks respectively. <br/> pnotebook1-> addpage (ptext1, "text1 "); <br/> pnotebook2-> addpage (ptext2, "text2"); <br/> pnotebook1-> addpage (ptext3, "text3 "); <br/> pnotebook2-> addpage (ptext4, "text4 "); </P> <p> // dock the two notebooks on the left and below respectively <br/> m_mgr.addpane (pnotebook1, wxleft, "pane caption "); <br/> m_mgr.addpane (pnotebook2, wxbottom, "pane caption"); </P> <p> // update the window layout manager <br/> m_mgr.update ();
After the creation, I tried the drag function. It's okay to drag the page in the same notebook. However, when you drag the page to another notebook, you cannot find it. I thought it was a bug. Later I checked the wxWidgets source code control on the wxaui_nb_tab_external_move style, and found another xuanjicang.
Let's see the code for wxWidgets to process the drag:
Void wxauinotebook: ontabenddrag (watermark & EVT) <br/>{< br/> encrypt (); </P> <p> wxauitabctrl * src_tabs = (wxauitabctrl *) EVT. geteventobject (); <br/> wxcheck_ret (src_tabs, _ T ("no source object? "); </P> <p> src_tabs-> setcursor (wxcursor (wxcursor_arrow); </P> <p> // get the mouse position, which will be used to determine the drop point <br/> wxpoint mouse_screen_pt =: wxgetmouseposition (); <br/> wxpoint mouse_client_pt = screentoclient (mouse_screen_pt ); </P> <p> // check for an external move <br/> If (m_flags & wxaui_nb_tab_external_move) <br/> {<br/> wxwindow * tab_ctrl =: wxfind?watpoi NT (mouse_screen_pt); </P> <p> while (tab_ctrl) <br/> {<br/> If (tab_ctrl-> iskindof (classinfo (wxauitabctrl ))) <br/> break; <br/> tab_ctrl = tab_ctrl-> getparent (); <br/>}</P> <p> If (tab_ctrl) <br/>{< br/> wxauinotebook * NB = (wxauinotebook *) tab_ctrl-> getparent (); </P> <p> If (NB! = This) <br/> {<br/> // find out from the destination control <br/> // if it's OK to drop this tab here <br/> wxauinotebookevent E (wxevt_command_auinotebook_allow_dnd, m_windowid); <br/> E. setselection (EVT. getselection (); <br/> E. setoldselection (EVT. getselection (); <br/> E. seteventobject (this); <br/> E. setdragsource (this); <br/> E. veto (); // dropping must be explicitly approved by control owner </P> <p> NB-> geteventhandler ()-> processevent (E); </P> <p> If (! E. isallowed () <br/>{< br/> // No answer or negative answer <br/> m_mgr.hidehint (); <br/> return; <br/>}</P> <p> // drop was allowed <br/> int src_idx = EVT. getselection (); <br/> wxwindow * src_page = src_tabs-> getwindowfromidx (src_idx ); </P> <p> // check that it's not an impossible parent relationship <br/> wxwindow * P = Nb; <br/> while (P &&! P-> istoplevel () <br/>{< br/> If (P = src_page) <br/>{< br/> return; <br/>}< br/> P = p-> getparent (); <br/>}</P> <p> // get main index of the page <br/> int main_idx = m_tabs.getidxfromwindow (src_page); <br/> wxcheck_ret (main_idx! = Wxnot_found, _ T ("No Source Page? "); </P> <p> // make a copy of the page info <br/> wxauinotebookpage page_info = m_tabs.getpage (main_idx ); </P> <p> // remove the page from the source notebook <br/> removepage (main_idx ); </P> <p> // reparent the page <br/> src_page-> reparent (NB ); </P> <p> // found out the insert idx <br/> wxauitabctrl * dest_tabs = (wxauitabctrl *) tab_ctrl; <br/> wxpoint Pt = dest_tabs-> screentoclient (mouse_screen_pt); </P> <P> wxwindow * target = NULL; <br/> int insert_idx =-1; <br/> dest_tabs-> tabhittest (pt. x, PT. y, & target); <br/> If (target) <br/>{< br/> insert_idx = dest_tabs-> getidxfromwindow (target ); <br/>}</P> <p> // Add the page to the new notebook <br/> If (insert_idx =-1) <br/> insert_idx = dest_tabs-> getpagecount (); <br/> dest_tabs-> insertpage (page_info.window, page_info, insert_idx); <br/> NB-> m_tabs. Addpage (page_info.window, page_info); </P> <p> NB-> dosizing (); <br/> dest_tabs-> doshowhide (); <br/> dest_tabs-> refresh (); </P> <p> // set the selection in the destination tab Control <br/> NB-> setselectiontopage (page_info ); </P> <p> // your y owner that the tab has been dragged <br/> wxauinotebookevent E2 (wxevt_command_auinotebook_drag_done, m_windowid); <br/> e2.setselection (EVT. getselection (); <br/> E2.setoldselection (EVT. getselection (); <br/> e2.seteventobject (this); <br/> geteventhandler ()-> processevent (E2); </P> <p> return; <br/>}</P> <p> //... <Br/>}
In the past, wxWidgets did not directly drag to another notebook. Instead, it first sent a wxevt_command_auinotebook_allow_dnd event to the target notebook and asked if it was allowed,
If (! E. isallowed () // wxevt_command_auinotebook_allow_dnd whether it is allowed
{
// No answer or negative answer
M_mgr.hidehint ();
Return; // do not allowed, directly return, of course, you can't drag and drop.
}
After reading this, we can understand that we only need to process the wxevt_command_auinotebook_allow_dnd event of the target notebook. Next we will add the notebook event processing:
Partition (wxnote1frame, wxframe) <br/> partition (idnotebook1, wxnote1frame: allowdnd) <br/> partition (idnotebook2, wxnote1frame: allowdnd) <br/> end_event_table () </P> <p> void wxnote1frame: allowdnd (wxauinotebookevent & event) <br/>{< br/> // evt_auinotebook_allow_dnd processing, allowing drag and drop <br/> event. allow (); <br/>}
After compilation, run it again. You can drag it to the outside.
WxWidgets is indeed a very useful interface library. Its class system is similar to that of MFC, But it encapsulates a lot of controls that are not available in MFC, saving you the trouble of expanding MFC by yourself. The document is not comprehensive enough. The wxaui_nb_tab_external_move style supports external drag-and-drop and you need to process the event yourself. It seems that we still need to work hard to promote it.