1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/aui/auibook.cpp
3 // Purpose: wxaui: wx advanced user interface - notebook
4 // Author: Benjamin I. Williams
7 // Copyright: (C) Copyright 2006, Kirix Corporation, All Rights Reserved
8 // Licence: wxWindows Library Licence, Version 3.1
9 ///////////////////////////////////////////////////////////////////////////////
11 // ----------------------------------------------------------------------------
13 // ----------------------------------------------------------------------------
15 #include "wx/wxprec.h"
23 #include "wx/aui/auibook.h"
26 #include "wx/settings.h"
30 #include "wx/aui/tabmdi.h"
31 #include "wx/dcbuffer.h"
34 #include "wx/arrimpl.cpp"
35 WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray
)
36 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray
)
38 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
)
39 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
)
40 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
)
41 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
)
42 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
)
43 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
)
44 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
)
47 IMPLEMENT_CLASS(wxAuiNotebook
, wxControl
)
48 IMPLEMENT_CLASS(wxAuiTabCtrl
, wxControl
)
49 IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent
, wxEvent
)
55 // This functions are here for this proof of concept
56 // and will be factored out later. See dockart.cpp
57 static wxColor
StepColour(const wxColor
& c
, int percent
)
59 int r
= c
.Red(), g
= c
.Green(), b
= c
.Blue();
60 return wxColour((unsigned char)wxMin((r
*percent
)/100,255),
61 (unsigned char)wxMin((g
*percent
)/100,255),
62 (unsigned char)wxMin((b
*percent
)/100,255));
65 // This functions are here for this proof of concept
66 // and will be factored out later. See dockart.cpp
67 static wxBitmap
BitmapFromBits(const unsigned char bits
[], int w
, int h
,
68 const wxColour
& color
)
70 wxImage img
= wxBitmap((const char*)bits
, w
, h
).ConvertToImage();
71 img
.Replace(0,0,0,123,123,123);
72 img
.Replace(255,255,255,color
.Red(),color
.Green(),color
.Blue());
73 img
.SetMaskColour(123,123,123);
77 static void DrawButtonS(wxDC
& dc
,
80 const wxColour
& bkcolour
,
85 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
91 if (button_state
== wxAUI_BUTTON_STATE_HOVER
||
92 button_state
== wxAUI_BUTTON_STATE_PRESSED
)
94 dc
.SetBrush(wxBrush(StepColour(bkcolour
, 120)));
95 dc
.SetPen(wxPen(StepColour(bkcolour
, 70)));
97 // draw the background behind the button
98 dc
.DrawRectangle(rect
.x
, rect
.y
, 15, 15);
101 // draw the button itself
102 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
109 // -- wxAuiDefaultTabArt class implementation --
111 wxAuiDefaultTabArt::wxAuiDefaultTabArt()
113 m_normal_font
= *wxNORMAL_FONT
;
114 m_selected_font
= *wxNORMAL_FONT
;
115 m_selected_font
.SetWeight(wxBOLD
);
116 m_measuring_font
= m_selected_font
;
118 wxColour base_colour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
120 wxColour background_colour
= StepColour(base_colour
, 95);
121 wxColour normaltab_colour
= base_colour
;
122 wxColour selectedtab_colour
= *wxWHITE
;
124 m_bkbrush
= wxBrush(background_colour
);
125 m_normal_bkbrush
= wxBrush(normaltab_colour
);
126 m_normal_bkpen
= wxPen(normaltab_colour
);
127 m_selected_bkbrush
= wxBrush(selectedtab_colour
);
128 m_selected_bkpen
= wxPen(selectedtab_colour
);
131 #if defined( __WXMAC__ )
132 static unsigned char close_bits
[]={
133 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
134 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
135 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
136 #elif defined( __WXGTK__)
137 static unsigned char close_bits
[]={
138 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
139 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
140 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
142 static unsigned char close_bits
[]={
143 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xfb,0xcf,0xf9,
144 0x9f,0xfc,0x3f,0xfe,0x3f,0xfe,0x9f,0xfc,0xcf,0xf9,0xef,0xfb,
145 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
148 static unsigned char left_bits
[] = {
149 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe,
150 0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe,
151 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
153 static unsigned char right_bits
[] = {
154 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff,
155 0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff,
156 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
158 static unsigned char list_bits
[] = {
159 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
160 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff,
161 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
164 m_active_close_bmp
= BitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
165 m_disabled_close_bmp
= BitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
167 m_active_left_bmp
= BitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
168 m_disabled_left_bmp
= BitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
170 m_active_right_bmp
= BitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
171 m_disabled_right_bmp
= BitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
173 m_active_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
174 m_disabled_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
178 wxAuiDefaultTabArt::~wxAuiDefaultTabArt()
182 void wxAuiDefaultTabArt::DrawBackground(wxDC
& dc
,
183 wxWindow
* WXUNUSED(wnd
),
187 dc
.SetBrush(m_bkbrush
);
188 dc
.SetPen(*wxTRANSPARENT_PEN
);
189 dc
.DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2);
192 dc
.SetPen(*wxGREY_PEN
);
193 dc
.DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1);
197 // DrawTab() draws an individual tab.
200 // in_rect - rectangle the tab should be confined to
201 // caption - tab's caption
202 // active - whether or not the tab is active
203 // out_rect - actual output rectangle
204 // x_extent - the advance x; where the next tab should start
206 void wxAuiDefaultTabArt::DrawTab(wxDC
& dc
,
208 const wxRect
& in_rect
,
209 const wxString
& caption_text
,
211 int close_button_state
,
212 wxRect
* out_tab_rect
,
213 wxRect
* out_button_rect
,
216 wxCoord normal_textx
, normal_texty
;
217 wxCoord selected_textx
, selected_texty
;
218 wxCoord textx
, texty
;
220 // if the caption is empty, measure some temporary text
221 wxString caption
= caption_text
;
222 if (caption_text
.empty())
225 dc
.SetFont(m_selected_font
);
226 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
228 dc
.SetFont(m_normal_font
);
229 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
231 // figure out the size of the tab
232 wxSize tab_size
= GetTabSize(dc
, wnd
, caption
, active
, close_button_state
, x_extent
);
234 wxCoord tab_height
= tab_size
.y
;
235 wxCoord tab_width
= tab_size
.x
;
236 wxCoord tab_x
= in_rect
.x
;
237 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
239 // select pen, brush and font for the tab to be drawn
243 dc
.SetPen(m_selected_bkpen
);
244 dc
.SetBrush(m_selected_bkbrush
);
245 dc
.SetFont(m_selected_font
);
246 textx
= selected_textx
;
247 texty
= selected_texty
;
251 dc
.SetPen(m_normal_bkpen
);
252 dc
.SetBrush(m_normal_bkbrush
);
253 dc
.SetFont(m_normal_font
);
254 textx
= normal_textx
;
255 texty
= normal_texty
;
263 points
[0].y
= tab_y
+ tab_height
- 1;
264 points
[1].x
= tab_x
+ tab_height
- 3;
265 points
[1].y
= tab_y
+ 2;
266 points
[2].x
= tab_x
+ tab_height
+ 3;
268 points
[3].x
= tab_x
+ tab_width
- 2;
270 points
[4].x
= tab_x
+ tab_width
;
271 points
[4].y
= tab_y
+ 2;
272 points
[5].x
= tab_x
+ tab_width
;
273 points
[5].y
= tab_y
+ tab_height
- 1;
274 points
[6] = points
[0];
277 dc
.DrawPolygon(6, points
);
279 dc
.SetPen(*wxGREY_PEN
);
281 //dc.DrawLines(active ? 6 : 7, points);
282 dc
.DrawLines(7, points
);
287 int close_button_width
= 0;
288 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
290 close_button_width
= m_active_close_bmp
.GetWidth();
291 text_offset
= tab_x
+ (tab_height
/2) + ((tab_width
-close_button_width
)/2) - (textx
/2);
295 text_offset
= tab_x
+ (tab_height
/3) + (tab_width
/2) - (textx
/2);
302 (tab_y
+ tab_height
)/2 - (texty
/2) + 1);
305 // draw close button if necessary
306 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
310 bmp
= m_active_close_bmp
;
312 bmp
= m_disabled_close_bmp
;
314 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
315 tab_y
+ (tab_height
/2) - (bmp
.GetHeight()/2) + 1,
318 DrawButtonS(dc
, rect
, bmp
, *wxWHITE
, close_button_state
);
320 *out_button_rect
= rect
;
324 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
328 wxSize
wxAuiDefaultTabArt::GetTabSize(wxDC
& dc
,
329 wxWindow
* WXUNUSED(wnd
),
330 const wxString
& caption
,
331 bool WXUNUSED(active
),
332 int close_button_state
,
335 wxCoord measured_textx
, measured_texty
;
337 dc
.SetFont(m_measuring_font
);
338 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
340 wxCoord tab_height
= measured_texty
+ 4;
341 wxCoord tab_width
= measured_textx
+ tab_height
+ 5;
343 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
344 tab_width
+= m_active_close_bmp
.GetWidth();
346 *x_extent
= tab_width
- (tab_height
/2) - 1;
348 return wxSize(tab_width
, tab_height
);
352 void wxAuiDefaultTabArt::DrawButton(
354 wxWindow
* WXUNUSED(wnd
),
355 const wxRect
& in_rect
,
359 const wxBitmap
& bitmap_override
,
365 if (bitmap_override
.IsOk())
367 bmp
= bitmap_override
;
373 case wxAUI_BUTTON_CLOSE
:
374 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
375 bmp
= m_disabled_close_bmp
;
377 bmp
= m_active_close_bmp
;
379 case wxAUI_BUTTON_LEFT
:
380 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
381 bmp
= m_disabled_left_bmp
;
383 bmp
= m_active_left_bmp
;
385 case wxAUI_BUTTON_RIGHT
:
386 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
387 bmp
= m_disabled_right_bmp
;
389 bmp
= m_active_right_bmp
;
391 case wxAUI_BUTTON_WINDOWLIST
:
392 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
393 bmp
= m_disabled_windowlist_bmp
;
395 bmp
= m_active_windowlist_bmp
;
405 if (orientation
== wxLEFT
)
407 rect
.SetX(in_rect
.x
);
408 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
409 rect
.SetWidth(bmp
.GetWidth());
410 rect
.SetHeight(bmp
.GetHeight());
414 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
415 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
416 bmp
.GetWidth(), bmp
.GetHeight());
420 DrawButtonS(dc
, rect
, bmp
, *wxWHITE
, button_state
);
428 // -- GUI helper classes and functions --
430 class wxAuiCommandCapture
: public wxEvtHandler
434 wxAuiCommandCapture() { m_last_id
= 0; }
435 int GetCommandId() const { return m_last_id
; }
437 bool ProcessEvent(wxEvent
& evt
)
439 if (evt
.GetEventType() == wxEVT_COMMAND_MENU_SELECTED
)
441 m_last_id
= evt
.GetId();
445 if (GetNextHandler())
446 return GetNextHandler()->ProcessEvent(evt
);
457 int wxAuiDefaultTabArt::ShowWindowList(wxWindow
* wnd
,
458 const wxArrayString
& items
,
463 size_t i
, count
= items
.GetCount();
464 for (i
= 0; i
< count
; ++i
)
466 menuPopup
.AppendCheckItem(1000+i
, items
.Item(i
));
469 if (active_idx
!= -1)
471 menuPopup
.Check(1000+active_idx
, true);
474 // find out where to put the popup menu of window
475 // items. Subtract 100 for now to center the menu
476 // a bit, until a better mechanism can be implemented
477 wxPoint pt
= ::wxGetMousePosition();
478 pt
= wnd
->ScreenToClient(pt
);
484 // find out the screen coordinate at the bottom of the tab ctrl
485 wxRect cli_rect
= wnd
->GetClientRect();
486 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
488 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
489 wnd
->PushEventHandler(cc
);
490 wnd
->PopupMenu(&menuPopup
, pt
);
491 int command
= cc
->GetCommandId();
492 wnd
->PopEventHandler(true);
500 int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow
* wnd
)
503 dc
.SetFont(m_measuring_font
);
505 wxSize s
= GetTabSize(dc
,
509 wxAUI_BUTTON_STATE_HIDDEN
,
514 void wxAuiDefaultTabArt::SetNormalFont(const wxFont
& font
)
516 m_normal_font
= font
;
519 void wxAuiDefaultTabArt::SetSelectedFont(const wxFont
& font
)
521 m_selected_font
= font
;
524 void wxAuiDefaultTabArt::SetMeasuringFont(const wxFont
& font
)
526 m_measuring_font
= font
;
534 // -- wxAuiTabContainer class implementation --
537 // wxAuiTabContainer is a class which contains information about each
538 // tab. It also can render an entire tab control to a specified DC.
539 // It's not a window class itself, because this code will be used by
540 // the wxFrameMananger, where it is disadvantageous to have separate
541 // windows for each tab control in the case of "docked tabs"
543 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window
544 // which can be used as a tab control in the normal sense.
547 wxAuiTabContainer::wxAuiTabContainer()
551 m_art
= new wxAuiDefaultTabArt
;
553 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
554 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
555 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
556 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
559 wxAuiTabContainer::~wxAuiTabContainer()
564 void wxAuiTabContainer::SetArtProvider(wxAuiTabArt
* art
)
570 wxAuiTabArt
* wxAuiTabContainer::GetArtProvider()
575 void wxAuiTabContainer::SetFlags(unsigned int flags
)
579 // check for new close button settings
580 RemoveButton(wxAUI_BUTTON_LEFT
);
581 RemoveButton(wxAUI_BUTTON_RIGHT
);
582 RemoveButton(wxAUI_BUTTON_WINDOWLIST
);
583 RemoveButton(wxAUI_BUTTON_CLOSE
);
586 if (flags
& wxAUI_NB_SCROLL_BUTTONS
)
588 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
589 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
592 if (flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
594 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
597 if (flags
& wxAUI_NB_CLOSE_BUTTON
)
599 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
603 unsigned int wxAuiTabContainer::GetFlags() const
609 void wxAuiTabContainer::SetNormalFont(const wxFont
& font
)
611 m_art
->SetNormalFont(font
);
614 void wxAuiTabContainer::SetSelectedFont(const wxFont
& font
)
616 m_art
->SetSelectedFont(font
);
619 void wxAuiTabContainer::SetMeasuringFont(const wxFont
& font
)
621 m_art
->SetMeasuringFont(font
);
624 void wxAuiTabContainer::SetRect(const wxRect
& rect
)
629 bool wxAuiTabContainer::AddPage(wxWindow
* page
,
630 const wxAuiNotebookPage
& info
)
632 wxAuiNotebookPage page_info
;
634 page_info
.window
= page
;
636 m_pages
.Add(page_info
);
641 bool wxAuiTabContainer::InsertPage(wxWindow
* page
,
642 const wxAuiNotebookPage
& info
,
645 wxAuiNotebookPage page_info
;
647 page_info
.window
= page
;
649 if (idx
>= m_pages
.GetCount())
650 m_pages
.Add(page_info
);
652 m_pages
.Insert(page_info
, idx
);
657 bool wxAuiTabContainer::MovePage(wxWindow
* page
,
660 int idx
= GetIdxFromWindow(page
);
664 // get page entry, make a copy of it
665 wxAuiNotebookPage p
= GetPage(idx
);
667 // remove old page entry
670 // insert page where it should be
671 InsertPage(page
, p
, new_idx
);
676 bool wxAuiTabContainer::RemovePage(wxWindow
* wnd
)
678 size_t i
, page_count
= m_pages
.GetCount();
679 for (i
= 0; i
< page_count
; ++i
)
681 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
682 if (page
.window
== wnd
)
692 bool wxAuiTabContainer::SetActivePage(wxWindow
* wnd
)
696 size_t i
, page_count
= m_pages
.GetCount();
697 for (i
= 0; i
< page_count
; ++i
)
699 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
700 if (page
.window
== wnd
)
714 void wxAuiTabContainer::SetNoneActive()
716 size_t i
, page_count
= m_pages
.GetCount();
717 for (i
= 0; i
< page_count
; ++i
)
719 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
724 bool wxAuiTabContainer::SetActivePage(size_t page
)
726 if (page
>= m_pages
.GetCount())
729 return SetActivePage(m_pages
.Item(page
).window
);
732 int wxAuiTabContainer::GetActivePage() const
734 size_t i
, page_count
= m_pages
.GetCount();
735 for (i
= 0; i
< page_count
; ++i
)
737 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
745 wxWindow
* wxAuiTabContainer::GetWindowFromIdx(size_t idx
) const
747 if (idx
>= m_pages
.GetCount())
750 return m_pages
[idx
].window
;
753 int wxAuiTabContainer::GetIdxFromWindow(wxWindow
* wnd
) const
755 size_t i
, page_count
= m_pages
.GetCount();
756 for (i
= 0; i
< page_count
; ++i
)
758 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
759 if (page
.window
== wnd
)
765 wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
)
767 wxASSERT_MSG(idx
< m_pages
.GetCount(), wxT("Invalid Page index"));
772 wxAuiNotebookPageArray
& wxAuiTabContainer::GetPages()
777 size_t wxAuiTabContainer::GetPageCount() const
779 return m_pages
.GetCount();
782 void wxAuiTabContainer::AddButton(int id
,
784 const wxBitmap
& normal_bitmap
,
785 const wxBitmap
& disabled_bitmap
)
787 wxAuiTabContainerButton button
;
789 button
.bitmap
= normal_bitmap
;
790 button
.dis_bitmap
= disabled_bitmap
;
791 button
.location
= location
;
792 button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
794 m_buttons
.Add(button
);
797 void wxAuiTabContainer::RemoveButton(int id
)
799 size_t i
, button_count
= m_buttons
.GetCount();
801 for (i
= 0; i
< button_count
; ++i
)
803 if (m_buttons
.Item(i
).id
== id
)
805 m_buttons
.RemoveAt(i
);
813 size_t wxAuiTabContainer::GetTabOffset() const
818 void wxAuiTabContainer::SetTabOffset(size_t offset
)
820 m_tab_offset
= offset
;
823 // Render() renders the tab catalog to the specified DC
824 // It is a virtual function and can be overridden to
825 // provide custom drawing capabilities
826 void wxAuiTabContainer::Render(wxDC
* raw_dc
, wxWindow
* wnd
)
831 size_t page_count
= m_pages
.GetCount();
832 size_t button_count
= m_buttons
.GetCount();
834 // create off-screen bitmap
835 bmp
.Create(m_rect
.GetWidth(), m_rect
.GetHeight());
836 dc
.SelectObject(bmp
);
839 // find out if size of tabs is larger than can be
840 // afforded on screen
842 int visible_width
= 0;
843 for (i
= 0; i
< page_count
; ++i
)
845 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
847 // determine if a close button is on this tab
848 bool close_button
= false;
849 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
850 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
857 wxSize size
= m_art
->GetTabSize(dc
,
862 wxAUI_BUTTON_STATE_NORMAL
:
863 wxAUI_BUTTON_STATE_HIDDEN
,
866 if (i
+1 < page_count
)
867 total_width
+= x_extent
;
869 total_width
+= size
.x
;
871 if (i
>= m_tab_offset
)
873 if (i
+1 < page_count
)
874 visible_width
+= x_extent
;
876 visible_width
+= size
.x
;
880 if (total_width
> m_rect
.GetWidth() - 20 || m_tab_offset
!= 0)
882 // show left/right buttons
883 for (i
= 0; i
< button_count
; ++i
)
885 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
886 if (button
.id
== wxAUI_BUTTON_LEFT
||
887 button
.id
== wxAUI_BUTTON_RIGHT
)
889 button
.cur_state
&= ~wxAUI_BUTTON_STATE_HIDDEN
;
895 // hide left/right buttons
896 for (i
= 0; i
< button_count
; ++i
)
898 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
899 if (button
.id
== wxAUI_BUTTON_LEFT
||
900 button
.id
== wxAUI_BUTTON_RIGHT
)
902 button
.cur_state
|= wxAUI_BUTTON_STATE_HIDDEN
;
907 // determine whether left button should be enabled
908 for (i
= 0; i
< button_count
; ++i
)
910 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
911 if (button
.id
== wxAUI_BUTTON_LEFT
)
913 if (m_tab_offset
== 0)
914 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
916 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
918 if (button
.id
== wxAUI_BUTTON_RIGHT
)
920 if (visible_width
< m_rect
.GetWidth() - ((int)button_count
*16))
921 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
923 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
930 m_art
->DrawBackground(dc
, wnd
, m_rect
);
933 int left_buttons_width
= 0;
934 int right_buttons_width
= 0;
938 // draw the buttons on the right side
939 offset
= m_rect
.x
+ m_rect
.width
;
940 for (i
= 0; i
< button_count
; ++i
)
942 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
944 if (button
.location
!= wxRIGHT
)
946 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
949 wxRect button_rect
= m_rect
;
951 button_rect
.SetWidth(offset
);
953 m_art
->DrawButton(dc
,
962 offset
-= button
.rect
.GetWidth();
963 right_buttons_width
+= button
.rect
.GetWidth();
970 // draw the buttons on the left side
972 for (i
= 0; i
< button_count
; ++i
)
974 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
976 if (button
.location
!= wxLEFT
)
978 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
981 wxRect
button_rect(offset
, 1, 1000, m_rect
.height
);
983 m_art
->DrawButton(dc
,
992 offset
+= button
.rect
.GetWidth();
993 left_buttons_width
+= button
.rect
.GetWidth();
996 offset
= left_buttons_width
;
998 // set a clipping region to the tabs don't draw over the buttons
999 dc
.SetClippingRegion(left_buttons_width
, 0,
1000 m_rect
.GetWidth() - right_buttons_width
- left_buttons_width
- 2,
1001 m_rect
.GetHeight());
1005 // prepare the tab-close-button array
1006 while (m_tab_close_buttons
.GetCount() < page_count
)
1008 wxAuiTabContainerButton tempbtn
;
1009 tempbtn
.id
= wxAUI_BUTTON_CLOSE
;
1010 tempbtn
.location
= wxCENTER
;
1011 tempbtn
.cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1012 m_tab_close_buttons
.Add(tempbtn
);
1015 for (i
= 0; i
< m_tab_offset
; ++i
)
1017 // buttons before the tab offset must be set to hidden
1018 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1024 size_t active
= 999;
1025 int active_offset
= 0;
1028 wxRect rect
= m_rect
;
1031 rect
.height
= m_rect
.height
;
1033 for (i
= m_tab_offset
; i
< page_count
; ++i
)
1035 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1036 wxAuiTabContainerButton
& tab_button
= m_tab_close_buttons
.Item(i
);
1038 // determine if a close button is on this tab
1039 bool close_button
= false;
1040 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1041 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1043 close_button
= true;
1044 if (tab_button
.cur_state
== wxAUI_BUTTON_STATE_HIDDEN
)
1046 tab_button
.id
= wxAUI_BUTTON_CLOSE
;
1047 tab_button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1048 tab_button
.location
= wxCENTER
;
1053 tab_button
.cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1063 tab_button
.cur_state
,
1071 active_offset
= offset
;
1077 // draw the active tab again so it stands in the foreground
1078 if (active
>= m_tab_offset
&& active
< m_pages
.GetCount())
1080 wxAuiNotebookPage
& page
= m_pages
.Item(active
);
1082 wxAuiTabContainerButton
& tab_button
= m_tab_close_buttons
.Item(active
);
1084 // determine if a close button is on this tab
1085 bool close_button
= false;
1086 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1087 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1089 close_button
= true;
1092 rect
.x
= active_offset
;
1098 tab_button
.cur_state
,
1104 dc
.DestroyClippingRegion();
1106 raw_dc
->Blit(m_rect
.x
, m_rect
.y
,
1107 m_rect
.GetWidth(), m_rect
.GetHeight(),
1112 // TabHitTest() tests if a tab was hit, passing the window pointer
1113 // back if that condition was fulfilled. The function returns
1114 // true if a tab was hit, otherwise false
1115 bool wxAuiTabContainer::TabHitTest(int x
, int y
, wxWindow
** hit
) const
1117 if (!m_rect
.Contains(x
,y
))
1120 wxAuiTabContainerButton
* btn
= NULL
;
1121 if (ButtonHitTest(x
, y
, &btn
))
1123 if (m_buttons
.Index(*btn
) != wxNOT_FOUND
)
1127 size_t i
, page_count
= m_pages
.GetCount();
1129 for (i
= m_tab_offset
; i
< page_count
; ++i
)
1131 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1132 if (page
.rect
.Contains(x
,y
))
1143 // ButtonHitTest() tests if a button was hit. The function returns
1144 // true if a button was hit, otherwise false
1145 bool wxAuiTabContainer::ButtonHitTest(int x
, int y
,
1146 wxAuiTabContainerButton
** hit
) const
1148 if (!m_rect
.Contains(x
,y
))
1151 size_t i
, button_count
;
1154 button_count
= m_buttons
.GetCount();
1155 for (i
= 0; i
< button_count
; ++i
)
1157 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1158 if (button
.rect
.Contains(x
,y
))
1166 button_count
= m_tab_close_buttons
.GetCount();
1167 for (i
= 0; i
< button_count
; ++i
)
1169 wxAuiTabContainerButton
& button
= m_tab_close_buttons
.Item(i
);
1170 if (button
.rect
.Contains(x
,y
))
1183 // the utility function ShowWnd() is the same as show,
1184 // except it handles wxAuiMDIChildFrame windows as well,
1185 // as the Show() method on this class is "unplugged"
1186 static void ShowWnd(wxWindow
* wnd
, bool show
)
1188 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
1190 wxAuiMDIChildFrame
* cf
= (wxAuiMDIChildFrame
*)wnd
;
1200 // DoShowHide() this function shows the active window, then
1201 // hides all of the other windows (in that order)
1202 void wxAuiTabContainer::DoShowHide()
1204 wxAuiNotebookPageArray
& pages
= GetPages();
1205 size_t i
, page_count
= pages
.GetCount();
1207 // show new active page first
1208 for (i
= 0; i
< page_count
; ++i
)
1210 wxAuiNotebookPage
& page
= pages
.Item(i
);
1213 ShowWnd(page
.window
, true);
1218 // hide all other pages
1219 for (i
= 0; i
< page_count
; ++i
)
1221 wxAuiNotebookPage
& page
= pages
.Item(i
);
1222 ShowWnd(page
.window
, page
.active
);
1231 // -- wxAuiTabCtrl class implementation --
1235 BEGIN_EVENT_TABLE(wxAuiTabCtrl
, wxControl
)
1236 EVT_PAINT(wxAuiTabCtrl::OnPaint
)
1237 EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground
)
1238 EVT_SIZE(wxAuiTabCtrl::OnSize
)
1239 EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown
)
1240 EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp
)
1241 EVT_MOTION(wxAuiTabCtrl::OnMotion
)
1242 EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow
)
1243 EVT_AUINOTEBOOK_BUTTON(-1, wxAuiTabCtrl::OnButton
)
1247 wxAuiTabCtrl::wxAuiTabCtrl(wxWindow
* parent
,
1251 long style
) : wxControl(parent
, id
, pos
, size
, style
)
1253 m_click_pt
= wxDefaultPosition
;
1254 m_is_dragging
= false;
1255 m_hover_button
= NULL
;
1258 wxAuiTabCtrl::~wxAuiTabCtrl()
1262 void wxAuiTabCtrl::OnPaint(wxPaintEvent
&)
1266 dc
.SetFont(GetFont());
1268 if (GetPageCount() > 0)
1272 void wxAuiTabCtrl::OnEraseBackground(wxEraseEvent
& WXUNUSED(evt
))
1276 void wxAuiTabCtrl::OnSize(wxSizeEvent
& evt
)
1278 wxSize s
= evt
.GetSize();
1279 wxRect
r(0, 0, s
.GetWidth(), s
.GetHeight());
1283 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent
& evt
)
1286 m_click_pt
= wxDefaultPosition
;
1287 m_is_dragging
= false;
1291 if (TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
1293 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
1294 e
.SetSelection(GetIdxFromWindow(wnd
));
1295 e
.SetOldSelection(GetActivePage());
1296 e
.SetEventObject(this);
1297 GetEventHandler()->ProcessEvent(e
);
1299 m_click_pt
.x
= evt
.m_x
;
1300 m_click_pt
.y
= evt
.m_y
;
1306 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_PRESSED
;
1312 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent
&)
1314 if (GetCapture() == this)
1319 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, m_windowId
);
1320 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
1321 evt
.SetOldSelection(evt
.GetSelection());
1322 evt
.SetEventObject(this);
1323 GetEventHandler()->ProcessEvent(evt
);
1329 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_HOVER
;
1333 if (!(m_hover_button
->cur_state
& wxAUI_BUTTON_STATE_DISABLED
))
1335 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, m_windowId
);
1336 evt
.SetInt(m_hover_button
->id
);
1337 evt
.SetEventObject(this);
1338 GetEventHandler()->ProcessEvent(evt
);
1342 m_click_pt
= wxDefaultPosition
;
1343 m_is_dragging
= false;
1347 void wxAuiTabCtrl::OnMotion(wxMouseEvent
& evt
)
1349 wxPoint pos
= evt
.GetPosition();
1351 // check if the mouse is hovering above a button
1352 wxAuiTabContainerButton
* button
;
1353 if (ButtonHitTest(pos
.x
, pos
.y
, &button
))
1355 if (m_hover_button
&& button
!= m_hover_button
)
1357 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1358 m_hover_button
= NULL
;
1363 if (button
->cur_state
!= wxAUI_BUTTON_STATE_HOVER
)
1365 button
->cur_state
= wxAUI_BUTTON_STATE_HOVER
;
1368 m_hover_button
= button
;
1376 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1377 m_hover_button
= NULL
;
1384 if (!evt
.LeftIsDown() || m_click_pt
== wxDefaultPosition
)
1389 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, m_windowId
);
1390 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
1391 evt
.SetOldSelection(evt
.GetSelection());
1392 evt
.SetEventObject(this);
1393 GetEventHandler()->ProcessEvent(evt
);
1398 int drag_x_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_X
);
1399 int drag_y_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_Y
);
1401 if (abs(pos
.x
- m_click_pt
.x
) > drag_x_threshold
||
1402 abs(pos
.y
- m_click_pt
.y
) > drag_y_threshold
)
1404 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, m_windowId
);
1405 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
1406 evt
.SetOldSelection(evt
.GetSelection());
1407 evt
.SetEventObject(this);
1408 GetEventHandler()->ProcessEvent(evt
);
1410 m_is_dragging
= true;
1414 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
))
1418 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1419 m_hover_button
= NULL
;
1425 void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent
& event
)
1427 int button
= event
.GetInt();
1429 if (button
== wxAUI_BUTTON_LEFT
|| button
== wxAUI_BUTTON_RIGHT
)
1431 if (button
== wxAUI_BUTTON_LEFT
)
1433 if (GetTabOffset() > 0)
1435 SetTabOffset(GetTabOffset()-1);
1442 SetTabOffset(GetTabOffset()+1);
1447 else if (button
== wxAUI_BUTTON_WINDOWLIST
)
1451 size_t i
, page_count
= m_pages
.GetCount();
1452 for (i
= 0; i
< page_count
; ++i
)
1454 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1455 as
.Add(page
.caption
);
1458 int idx
= GetArtProvider()->ShowWindowList(this, as
, GetActivePage());
1462 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
1463 e
.SetSelection(idx
);
1464 e
.SetOldSelection(GetActivePage());
1465 e
.SetEventObject(this);
1466 GetEventHandler()->ProcessEvent(e
);
1475 // wxTabFrame is an interesting case. It's important that all child pages
1476 // of the multi-notebook control are all actually children of that control
1477 // (and not grandchildren). wxTabFrame facilitates this. There is one
1478 // instance of wxTabFrame for each tab control inside the multi-notebook.
1479 // It's important to know that wxTabFrame is not a real window, but it merely
1480 // used to capture the dimensions/positioning of the internal tab control and
1481 // it's managed page windows
1483 class wxTabFrame
: public wxWindow
1490 m_rect
= wxRect(0,0,200,200);
1491 m_tab_ctrl_height
= 20;
1494 void SetTabCtrlHeight(int h
)
1496 m_tab_ctrl_height
= h
;
1499 void DoSetSize(int x
, int y
,
1500 int width
, int height
,
1501 int WXUNUSED(sizeFlags
= wxSIZE_AUTO
))
1503 m_rect
= wxRect(x
, y
, width
, height
);
1507 void DoGetClientSize(int* x
, int* y
) const
1513 bool Show( bool WXUNUSED(show
= true) ) { return false; }
1520 int tab_height
= wxMin(m_rect
.height
, m_tab_ctrl_height
);
1521 m_tab_rect
= wxRect(m_rect
.x
, m_rect
.y
, m_rect
.width
, tab_height
);
1522 m_tabs
->SetSize(m_rect
.x
, m_rect
.y
, m_rect
.width
, tab_height
);
1523 m_tabs
->SetRect(wxRect(0, 0, m_rect
.width
, tab_height
));
1527 wxAuiNotebookPageArray
& pages
= m_tabs
->GetPages();
1528 size_t i
, page_count
= pages
.GetCount();
1530 for (i
= 0; i
< page_count
; ++i
)
1532 wxAuiNotebookPage
& page
= pages
.Item(i
);
1533 page
.window
->SetSize(m_rect
.x
, m_rect
.y
+tab_height
,
1534 m_rect
.width
, m_rect
.height
-tab_height
);
1536 if (page
.window
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
1538 wxAuiMDIChildFrame
* wnd
= (wxAuiMDIChildFrame
*)page
.window
;
1539 wnd
->ApplyMDIChildFrameRect();
1544 void DoGetSize(int* x
, int* y
) const
1547 *x
= m_rect
.GetWidth();
1549 *y
= m_rect
.GetHeight();
1561 wxAuiTabCtrl
* m_tabs
;
1562 int m_tab_ctrl_height
;
1569 // -- wxAuiNotebook class implementation --
1571 BEGIN_EVENT_TABLE(wxAuiNotebook
, wxControl
)
1572 //EVT_ERASE_BACKGROUND(wxAuiNotebook::OnEraseBackground)
1573 //EVT_SIZE(wxAuiNotebook::OnSize)
1574 //EVT_LEFT_DOWN(wxAuiNotebook::OnLeftDown)
1575 EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocus
)
1576 EVT_COMMAND_RANGE(10000, 10100,
1577 wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
,
1578 wxAuiNotebook::OnTabClicked
)
1579 EVT_COMMAND_RANGE(10000, 10100,
1580 wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
,
1581 wxAuiNotebook::OnTabBeginDrag
)
1582 EVT_COMMAND_RANGE(10000, 10100,
1583 wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
,
1584 wxAuiNotebook::OnTabEndDrag
)
1585 EVT_COMMAND_RANGE(10000, 10100,
1586 wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
,
1587 wxAuiNotebook::OnTabDragMotion
)
1588 EVT_COMMAND_RANGE(10000, 10100,
1589 wxEVT_COMMAND_AUINOTEBOOK_BUTTON
,
1590 wxAuiNotebook::OnTabButton
)
1593 wxAuiNotebook::wxAuiNotebook()
1596 m_tab_id_counter
= 10000;
1598 m_tab_ctrl_height
= 20;
1601 wxAuiNotebook::wxAuiNotebook(wxWindow
*parent
,
1605 long style
) : wxControl(parent
, id
, pos
, size
, style
)
1607 InitNotebook(style
);
1610 bool wxAuiNotebook::Create(wxWindow
* parent
,
1616 if (!wxControl::Create(parent
, id
, pos
, size
, style
))
1619 InitNotebook(style
);
1624 // InitNotebook() contains common initialization
1625 // code called by all constructors
1626 void wxAuiNotebook::InitNotebook(long style
)
1629 m_tab_id_counter
= 10000;
1631 m_tab_ctrl_height
= 20;
1632 m_flags
= (unsigned int)style
;
1634 m_normal_font
= *wxNORMAL_FONT
;
1635 m_selected_font
= *wxNORMAL_FONT
;
1636 m_selected_font
.SetWeight(wxBOLD
);
1638 // choose a default for the tab height
1639 m_tab_ctrl_height
= m_tabs
.GetArtProvider()->GetBestTabCtrlSize(this);
1641 m_dummy_wnd
= new wxWindow(this, wxID_ANY
, wxPoint(0,0), wxSize(0,0));
1642 m_dummy_wnd
->SetSize(200, 200);
1643 m_dummy_wnd
->Show(false);
1645 m_mgr
.SetManagedWindow(this);
1647 m_mgr
.AddPane(m_dummy_wnd
,
1648 wxAuiPaneInfo().Name(wxT("dummy")).Bottom().Show(false));
1653 wxAuiNotebook::~wxAuiNotebook()
1658 void wxAuiNotebook::SetArtProvider(wxAuiTabArt
* art
)
1660 m_tabs
.SetArtProvider(art
);
1663 wxAuiTabArt
* wxAuiNotebook::GetArtProvider()
1665 return m_tabs
.GetArtProvider();
1668 void wxAuiNotebook::SetWindowStyleFlag(long style
)
1670 wxControl::SetWindowStyleFlag(style
);
1672 m_flags
= (unsigned int)style
;
1674 // if the control is already initialized
1675 if (m_mgr
.GetManagedWindow() == (wxWindow
*)this)
1677 // let all of the tab children know about the new style
1679 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1680 size_t i
, pane_count
= all_panes
.GetCount();
1681 for (i
= 0; i
< pane_count
; ++i
)
1683 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
1684 if (pane
.name
== wxT("dummy"))
1686 wxAuiTabCtrl
* tabctrl
= ((wxTabFrame
*)pane
.window
)->m_tabs
;
1687 tabctrl
->SetFlags(m_flags
);
1695 bool wxAuiNotebook::AddPage(wxWindow
* page
,
1696 const wxString
& caption
,
1698 const wxBitmap
& bitmap
)
1700 return InsertPage(GetPageCount(), page
, caption
, select
, bitmap
);
1703 bool wxAuiNotebook::InsertPage(size_t page_idx
,
1705 const wxString
& caption
,
1707 const wxBitmap
& bitmap
)
1709 wxAuiNotebookPage info
;
1711 info
.caption
= caption
;
1712 info
.bitmap
= bitmap
;
1713 info
.active
= false;
1715 // if there are currently no tabs, the first added
1716 // tab must be active
1717 if (m_tabs
.GetPageCount() == 0)
1720 m_tabs
.InsertPage(page
, info
, page_idx
);
1722 wxAuiTabCtrl
* active_tabctrl
= GetActiveTabCtrl();
1723 if (page_idx
>= active_tabctrl
->GetPageCount())
1724 active_tabctrl
->AddPage(page
, info
);
1726 active_tabctrl
->InsertPage(page
, info
, page_idx
);
1729 active_tabctrl
->DoShowHide();
1733 int idx
= m_tabs
.GetIdxFromWindow(page
);
1734 wxASSERT_MSG(idx
!= -1, wxT("Invalid Page index returned on wxAuiNotebook::InsertPage()"));
1743 // DeletePage() removes a tab from the multi-notebook,
1744 // and destroys the window as well
1745 bool wxAuiNotebook::DeletePage(size_t page_idx
)
1747 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
1749 if (!RemovePage(page_idx
))
1753 // actually destroy the window now
1754 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
1756 // delete the child frame with pending delete, as is
1757 // customary with frame windows
1758 if (!wxPendingDelete
.Member(wnd
))
1759 wxPendingDelete
.Append(wnd
);
1770 wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
1771 wxWindow* new_active = NULL;
1773 // find out which onscreen tab ctrl owns this tab
1776 if (!FindTab(wnd, &ctrl, &ctrl_idx))
1779 // find a new page and set it as active
1780 int new_idx = ctrl_idx+1;
1781 if (new_idx >= (int)ctrl->GetPageCount())
1782 new_idx = ctrl_idx-1;
1784 if (new_idx >= 0 && new_idx < (int)ctrl->GetPageCount())
1786 new_active = ctrl->GetWindowFromIdx(new_idx);
1790 // set the active page to the first page that
1791 // isn't the one being deleted
1792 size_t i, page_count = m_tabs.GetPageCount();
1793 for (i = 0; i < page_count; ++i)
1795 wxWindow* w = m_tabs.GetWindowFromIdx(i);
1798 new_active = m_tabs.GetWindowFromIdx(i);
1804 // remove the tab from main catalog
1805 if (!m_tabs.RemovePage(wnd))
1808 // remove the tab from the onscreen tab ctrl
1809 ctrl->RemovePage(wnd);
1811 // actually destroy the window now
1812 if (wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
1814 // delete the child frame with pending delete, as is
1815 // customary with frame windows
1816 if (!wxPendingDelete.Member(wnd))
1817 wxPendingDelete.Append(wnd);
1824 RemoveEmptyTabFrames();
1826 // set new active pane
1830 SetSelection(m_tabs.GetIdxFromWindow(new_active));
1839 // RemovePage() removes a tab from the multi-notebook,
1840 // but does not destroy the window
1841 bool wxAuiNotebook::RemovePage(size_t page_idx
)
1843 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
1844 wxWindow
* new_active
= NULL
;
1846 // find out which onscreen tab ctrl owns this tab
1849 if (!FindTab(wnd
, &ctrl
, &ctrl_idx
))
1852 // find a new page and set it as active
1853 int new_idx
= ctrl_idx
+1;
1854 if (new_idx
>= (int)ctrl
->GetPageCount())
1855 new_idx
= ctrl_idx
-1;
1857 if (new_idx
>= 0 && new_idx
< (int)ctrl
->GetPageCount())
1859 new_active
= ctrl
->GetWindowFromIdx(new_idx
);
1863 // set the active page to the first page that
1864 // isn't the one being deleted
1865 size_t i
, page_count
= m_tabs
.GetPageCount();
1866 for (i
= 0; i
< page_count
; ++i
)
1868 wxWindow
* w
= m_tabs
.GetWindowFromIdx(i
);
1871 new_active
= m_tabs
.GetWindowFromIdx(i
);
1877 // remove the tab from main catalog
1878 if (!m_tabs
.RemovePage(wnd
))
1881 // remove the tab from the onscreen tab ctrl
1882 ctrl
->RemovePage(wnd
);
1885 RemoveEmptyTabFrames();
1887 // set new active pane
1891 SetSelection(m_tabs
.GetIdxFromWindow(new_active
));
1897 // SetPageText() changes the tab caption of the specified page
1898 bool wxAuiNotebook::SetPageText(size_t page_idx
, const wxString
& text
)
1900 if (page_idx
>= m_tabs
.GetPageCount())
1903 // update our own tab catalog
1904 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
1905 page_info
.caption
= text
;
1907 // update what's on screen
1910 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
1912 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
1913 info
.caption
= text
;
1921 // GetSelection() returns the index of the currently active page
1922 int wxAuiNotebook::GetSelection() const
1927 // SetSelection() sets the currently active page
1928 size_t wxAuiNotebook::SetSelection(size_t new_page
)
1930 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(new_page
);
1934 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
1935 evt
.SetSelection(new_page
);
1936 evt
.SetOldSelection(m_curpage
);
1937 evt
.SetEventObject(this);
1938 if (!GetEventHandler()->ProcessEvent(evt
) || evt
.IsAllowed())
1940 // program allows the page change
1941 evt
.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
);
1942 (void)GetEventHandler()->ProcessEvent(evt
);
1948 if (FindTab(wnd
, &ctrl
, &ctrl_idx
))
1950 m_tabs
.SetActivePage(wnd
);
1952 ctrl
->SetActivePage(ctrl_idx
);
1956 int old_curpage
= m_curpage
;
1957 m_curpage
= new_page
;
1961 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1962 size_t i
, pane_count
= all_panes
.GetCount();
1963 for (i
= 0; i
< pane_count
; ++i
)
1965 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
1966 if (pane
.name
== wxT("dummy"))
1968 wxAuiTabCtrl
* tabctrl
= ((wxTabFrame
*)pane
.window
)->m_tabs
;
1969 if (tabctrl
!= ctrl
)
1970 tabctrl
->SetSelectedFont(m_normal_font
);
1972 tabctrl
->SetSelectedFont(m_selected_font
);
1985 // GetPageCount() returns the total number of
1986 // pages managed by the multi-notebook
1987 size_t wxAuiNotebook::GetPageCount() const
1989 return m_tabs
.GetPageCount();
1992 // GetPage() returns the wxWindow pointer of the
1994 wxWindow
* wxAuiNotebook::GetPage(size_t page_idx
) const
1996 wxASSERT(page_idx
< m_tabs
.GetPageCount());
1998 return m_tabs
.GetWindowFromIdx(page_idx
);
2001 // DoSizing() performs all sizing operations in each tab control
2002 void wxAuiNotebook::DoSizing()
2004 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2005 size_t i
, pane_count
= all_panes
.GetCount();
2006 for (i
= 0; i
< pane_count
; ++i
)
2008 if (all_panes
.Item(i
).name
== wxT("dummy"))
2011 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2012 tabframe
->DoSizing();
2016 // GetActiveTabCtrl() returns the active tab control. It is
2017 // called to determine which control gets new windows being added
2018 wxAuiTabCtrl
* wxAuiNotebook::GetActiveTabCtrl()
2020 if (m_curpage
>= 0 && m_curpage
< (int)m_tabs
.GetPageCount())
2025 // find the tab ctrl with the current page
2026 if (FindTab(m_tabs
.GetPage(m_curpage
).window
,
2033 // no current page, just find the first tab ctrl
2034 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2035 size_t i
, pane_count
= all_panes
.GetCount();
2036 for (i
= 0; i
< pane_count
; ++i
)
2038 if (all_panes
.Item(i
).name
== wxT("dummy"))
2041 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2042 return tabframe
->m_tabs
;
2045 // If there is no tabframe at all, create one
2046 wxTabFrame
* tabframe
= new wxTabFrame
;
2047 tabframe
->SetTabCtrlHeight(m_tab_ctrl_height
);
2048 tabframe
->m_tabs
= new wxAuiTabCtrl(this,
2053 tabframe
->m_tabs
->SetFlags(m_flags
);
2054 m_mgr
.AddPane(tabframe
,
2055 wxAuiPaneInfo().Center().CaptionVisible(false));
2059 return tabframe
->m_tabs
;
2062 // FindTab() finds the tab control that currently contains the window as well
2063 // as the index of the window in the tab control. It returns true if the
2064 // window was found, otherwise false.
2065 bool wxAuiNotebook::FindTab(wxWindow
* page
, wxAuiTabCtrl
** ctrl
, int* idx
)
2067 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2068 size_t i
, pane_count
= all_panes
.GetCount();
2069 for (i
= 0; i
< pane_count
; ++i
)
2071 if (all_panes
.Item(i
).name
== wxT("dummy"))
2074 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2076 int page_idx
= tabframe
->m_tabs
->GetIdxFromWindow(page
);
2079 *ctrl
= tabframe
->m_tabs
;
2089 void wxAuiNotebook::OnEraseBackground(wxEraseEvent
&)
2093 void wxAuiNotebook::OnSize(wxSizeEvent
&)
2097 void wxAuiNotebook::OnTabClicked(wxCommandEvent
& command_evt
)
2099 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
2101 wxAuiTabCtrl
* ctrl
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2102 wxASSERT(ctrl
!= NULL
);
2104 wxWindow
* wnd
= ctrl
->GetWindowFromIdx(evt
.GetSelection());
2105 wxASSERT(wnd
!= NULL
);
2107 int idx
= m_tabs
.GetIdxFromWindow(wnd
);
2108 wxASSERT(idx
!= -1);
2113 void wxAuiNotebook::OnTabBeginDrag(wxCommandEvent
&)
2118 void wxAuiNotebook::OnTabDragMotion(wxCommandEvent
& evt
)
2120 wxPoint screen_pt
= ::wxGetMousePosition();
2121 wxPoint client_pt
= ScreenToClient(screen_pt
);
2124 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2125 wxAuiTabCtrl
* dest_tabs
= GetTabCtrlFromPoint(client_pt
);
2127 if (dest_tabs
== src_tabs
)
2131 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
2134 // always hide the hint for inner-tabctrl drag
2137 // if tab moving is not allowed, leave
2138 if (!(m_flags
& wxAUI_NB_TAB_MOVE
))
2143 wxPoint pt
= dest_tabs
->ScreenToClient(screen_pt
);
2144 wxWindow
* dest_location_tab
;
2146 // this is an inner-tab drag/reposition
2147 if (dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &dest_location_tab
))
2149 int src_idx
= evt
.GetSelection();
2150 int dest_idx
= dest_tabs
->GetIdxFromWindow(dest_location_tab
);
2152 // prevent jumpy drag
2153 if ((src_idx
== dest_idx
) || dest_idx
== -1 ||
2154 (src_idx
> dest_idx
&& m_last_drag_x
<= pt
.x
) ||
2155 (src_idx
< dest_idx
&& m_last_drag_x
>= pt
.x
))
2157 m_last_drag_x
= pt
.x
;
2162 wxWindow
* src_tab
= dest_tabs
->GetWindowFromIdx(src_idx
);
2163 dest_tabs
->MovePage(src_tab
, dest_idx
);
2164 dest_tabs
->SetActivePage((size_t)dest_idx
);
2165 dest_tabs
->DoShowHide();
2166 dest_tabs
->Refresh();
2167 m_last_drag_x
= pt
.x
;
2175 // if external drag is allowed, check if the tab is being dragged
2176 // over a different wxAuiNotebook control
2177 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
2179 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(screen_pt
);
2181 // if we are over a hint window, leave
2182 if (tab_ctrl
->IsKindOf(CLASSINFO(wxFrame
)))
2187 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
2189 tab_ctrl
= tab_ctrl
->GetParent();
2194 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
2198 wxRect hint_rect
= tab_ctrl
->GetRect();
2199 tab_ctrl
->ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
2200 m_mgr
.ShowHint(hint_rect
);
2208 // if tab moving is not allowed, leave
2209 if (!(m_flags
& wxAUI_NB_TAB_SPLIT
))
2217 src_tabs
->SetCursor(wxCursor(wxCURSOR_SIZING
));
2223 wxRect hint_rect
= dest_tabs
->GetRect();
2224 ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
2225 m_mgr
.ShowHint(hint_rect
);
2229 m_mgr
.DrawHintRect(m_dummy_wnd
, client_pt
, zero
);
2235 void wxAuiNotebook::OnTabEndDrag(wxCommandEvent
& command_evt
)
2237 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
2242 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2243 wxAuiTabCtrl
* dest_tabs
= NULL
;
2246 // set cursor back to an arrow
2247 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
2250 // get the mouse position, which will be used to determine the drop point
2251 wxPoint mouse_screen_pt
= ::wxGetMousePosition();
2252 wxPoint mouse_client_pt
= ScreenToClient(mouse_screen_pt
);
2256 // check for an external move
2257 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
2259 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(mouse_screen_pt
);
2263 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
2265 tab_ctrl
= tab_ctrl
->GetParent();
2270 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
2274 // find out from the destination control
2275 // if it's ok to drop this tab here
2276 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
, m_windowId
);
2277 e
.SetSelection(evt
.GetSelection());
2278 e
.SetOldSelection(evt
.GetSelection());
2279 e
.SetEventObject(this);
2280 e
.SetDragSource(this);
2281 e
.Veto(); // dropping must be explicitly approved by control owner
2283 nb
->GetEventHandler()->ProcessEvent(e
);
2287 // no answer or negative answer
2293 int src_idx
= evt
.GetSelection();
2294 wxWindow
* src_page
= src_tabs
->GetWindowFromIdx(src_idx
);
2296 // get main index of the page
2297 int main_idx
= m_tabs
.GetIdxFromWindow(src_page
);
2299 // make a copy of the page info
2300 wxAuiNotebookPage page_info
= m_tabs
.GetPage((size_t)main_idx
);
2302 // remove the page from the source notebook
2303 RemovePage(main_idx
);
2305 // reparent the page
2306 src_page
->Reparent(nb
);
2309 // found out the insert idx
2310 wxAuiTabCtrl
* dest_tabs
= (wxAuiTabCtrl
*)tab_ctrl
;
2311 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
2313 wxWindow
* target
= NULL
;
2314 int insert_idx
= -1;
2315 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
2318 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
2322 // add the page to the new notebook
2323 if (insert_idx
== -1)
2324 insert_idx
= dest_tabs
->GetPageCount();
2325 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
2326 nb
->m_tabs
.AddPage(page_info
.window
, page_info
);
2329 dest_tabs
->DoShowHide();
2330 dest_tabs
->Refresh();
2332 // set the selection in the destination tab control
2333 nb
->SetSelection(nb
->m_tabs
.GetIdxFromWindow(page_info
.window
));
2343 // only perform a tab split if it's allowed
2344 if (m_flags
& wxAUI_NB_TAB_SPLIT
)
2346 // If the pointer is in an existing tab frame, do a tab insert
2347 wxWindow
* hit_wnd
= ::wxFindWindowAtPoint(mouse_screen_pt
);
2348 wxTabFrame
* tab_frame
= (wxTabFrame
*)GetTabFrameFromTabCtrl(hit_wnd
);
2349 int insert_idx
= -1;
2352 dest_tabs
= tab_frame
->m_tabs
;
2354 if (dest_tabs
== src_tabs
)
2358 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
2359 wxWindow
* target
= NULL
;
2360 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
2363 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
2368 // If there is no tabframe at all, create one
2369 wxTabFrame
* new_tabs
= new wxTabFrame
;
2370 new_tabs
->SetTabCtrlHeight(m_tab_ctrl_height
);
2371 new_tabs
->m_tabs
= new wxAuiTabCtrl(this,
2376 new_tabs
->m_tabs
->SetFlags(m_flags
);
2378 m_mgr
.AddPane(new_tabs
,
2379 wxAuiPaneInfo().Bottom().CaptionVisible(false),
2382 dest_tabs
= new_tabs
->m_tabs
;
2387 // remove the page from the source tabs
2388 wxAuiNotebookPage page_info
= src_tabs
->GetPage(evt
.GetSelection());
2389 page_info
.active
= false;
2390 src_tabs
->RemovePage(page_info
.window
);
2391 if (src_tabs
->GetPageCount() > 0)
2393 src_tabs
->SetActivePage((size_t)0);
2394 src_tabs
->DoShowHide();
2395 src_tabs
->Refresh();
2400 // add the page to the destination tabs
2401 if (insert_idx
== -1)
2402 insert_idx
= dest_tabs
->GetPageCount();
2403 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
2405 if (src_tabs
->GetPageCount() == 0)
2407 RemoveEmptyTabFrames();
2411 dest_tabs
->DoShowHide();
2412 dest_tabs
->Refresh();
2414 SetSelection(m_tabs
.GetIdxFromWindow(page_info
.window
));
2420 wxAuiTabCtrl
* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint
& pt
)
2422 // if we've just removed the last tab from the source
2423 // tab set, the remove the tab control completely
2424 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2425 size_t i
, pane_count
= all_panes
.GetCount();
2426 for (i
= 0; i
< pane_count
; ++i
)
2428 if (all_panes
.Item(i
).name
== wxT("dummy"))
2431 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2432 if (tabframe
->m_tab_rect
.Contains(pt
))
2433 return tabframe
->m_tabs
;
2439 wxWindow
* wxAuiNotebook::GetTabFrameFromTabCtrl(wxWindow
* tab_ctrl
)
2441 // if we've just removed the last tab from the source
2442 // tab set, the remove the tab control completely
2443 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2444 size_t i
, pane_count
= all_panes
.GetCount();
2445 for (i
= 0; i
< pane_count
; ++i
)
2447 if (all_panes
.Item(i
).name
== wxT("dummy"))
2450 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2451 if (tabframe
->m_tabs
== tab_ctrl
)
2460 void wxAuiNotebook::RemoveEmptyTabFrames()
2462 // if we've just removed the last tab from the source
2463 // tab set, the remove the tab control completely
2464 wxAuiPaneInfoArray all_panes
= m_mgr
.GetAllPanes();
2465 size_t i
, pane_count
= all_panes
.GetCount();
2466 for (i
= 0; i
< pane_count
; ++i
)
2468 if (all_panes
.Item(i
).name
== wxT("dummy"))
2471 wxTabFrame
* tab_frame
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2472 if (tab_frame
->m_tabs
->GetPageCount() == 0)
2474 m_mgr
.DetachPane(tab_frame
);
2476 // use pending delete because sometimes during
2477 // window closing, refreshs are pending
2478 if (!wxPendingDelete
.Member(tab_frame
->m_tabs
))
2479 wxPendingDelete
.Append(tab_frame
->m_tabs
);
2480 //tab_frame->m_tabs->Destroy();
2487 // check to see if there is still a center pane;
2488 // if there isn't, make a frame the center pane
2489 wxAuiPaneInfoArray panes
= m_mgr
.GetAllPanes();
2490 pane_count
= panes
.GetCount();
2491 wxWindow
* first_good
= NULL
;
2492 bool center_found
= false;
2493 for (i
= 0; i
< pane_count
; ++i
)
2495 if (panes
.Item(i
).name
== wxT("dummy"))
2497 if (panes
.Item(i
).dock_direction
== wxAUI_DOCK_CENTRE
)
2498 center_found
= true;
2500 first_good
= panes
.Item(i
).window
;
2503 if (!center_found
&& first_good
)
2505 m_mgr
.GetPane(first_good
).Centre();
2511 void wxAuiNotebook::OnChildFocus(wxChildFocusEvent
& evt
)
2513 int idx
= m_tabs
.GetIdxFromWindow(evt
.GetWindow());
2514 if (idx
!= -1 && idx
!= m_curpage
)
2521 void wxAuiNotebook::OnTabButton(wxCommandEvent
& command_evt
)
2523 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
2524 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2526 int button_id
= evt
.GetInt();
2528 if (button_id
== wxAUI_BUTTON_CLOSE
)
2530 int selection
= tabs
->GetActivePage();
2532 if (selection
!= -1)
2534 wxWindow
* close_wnd
= tabs
->GetWindowFromIdx(selection
);
2536 if (close_wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
2542 int main_idx
= m_tabs
.GetIdxFromWindow(close_wnd
);
2543 DeletePage(main_idx
);