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"
35 #include "wx/mac/carbon/private.h"
38 #include "wx/arrimpl.cpp"
39 WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray
)
40 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray
)
42 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
)
43 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
)
44 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
)
45 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
)
46 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
)
47 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
)
48 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
)
49 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
)
52 IMPLEMENT_CLASS(wxAuiNotebook
, wxControl
)
53 IMPLEMENT_CLASS(wxAuiTabCtrl
, wxControl
)
54 IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent
, wxEvent
)
60 // This functions are here for this proof of concept
61 // and will be factored out later. See dockart.cpp
62 static wxColor
StepColour(const wxColor
& c
, int percent
)
64 int r
= c
.Red(), g
= c
.Green(), b
= c
.Blue();
65 return wxColour((unsigned char)wxMin((r
*percent
)/100,255),
66 (unsigned char)wxMin((g
*percent
)/100,255),
67 (unsigned char)wxMin((b
*percent
)/100,255));
70 // This functions are here for this proof of concept
71 // and will be factored out later. See dockart.cpp
72 static wxBitmap
BitmapFromBits(const unsigned char bits
[], int w
, int h
,
73 const wxColour
& color
)
75 wxImage img
= wxBitmap((const char*)bits
, w
, h
).ConvertToImage();
76 img
.Replace(0,0,0,123,123,123);
77 img
.Replace(255,255,255,color
.Red(),color
.Green(),color
.Blue());
78 img
.SetMaskColour(123,123,123);
82 static void DrawButtons(wxDC
& dc
,
85 const wxColour
& bkcolour
,
90 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
96 if (button_state
== wxAUI_BUTTON_STATE_HOVER
||
97 button_state
== wxAUI_BUTTON_STATE_PRESSED
)
99 dc
.SetBrush(wxBrush(StepColour(bkcolour
, 120)));
100 dc
.SetPen(wxPen(StepColour(bkcolour
, 70)));
102 // draw the background behind the button
103 dc
.DrawRectangle(rect
.x
, rect
.y
, 15, 15);
106 // draw the button itself
107 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
110 static void IndentPressedBitmap(wxRect
* rect
, int button_state
)
112 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
119 // chops the text so that it fits within |max_size| pixels.
120 // Also adds an elipsis if necessary
122 static wxString
ChopText(wxDC
& dc
, const wxString
& text
, int max_size
)
126 // first check if the text fits with no problems
127 dc
.GetTextExtent(text
, &x
, &y
);
131 size_t i
, len
= text
.Length();
132 size_t last_good_length
= 0;
133 for (i
= 0; i
< len
; ++i
)
135 wxString s
= text
.Left(i
);
138 dc
.GetTextExtent(s
, &x
, &y
);
142 last_good_length
= i
;
145 wxString ret
= text
.Left(last_good_length
);
151 // -- GUI helper classes and functions --
153 class wxAuiCommandCapture
: public wxEvtHandler
157 wxAuiCommandCapture() { m_last_id
= 0; }
158 int GetCommandId() const { return m_last_id
; }
160 bool ProcessEvent(wxEvent
& evt
)
162 if (evt
.GetEventType() == wxEVT_COMMAND_MENU_SELECTED
)
164 m_last_id
= evt
.GetId();
168 if (GetNextHandler())
169 return GetNextHandler()->ProcessEvent(evt
);
181 #if defined( __WXMAC__ )
182 static unsigned char close_bits
[]={
183 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
184 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
185 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
186 #elif defined( __WXGTK__)
187 static unsigned char close_bits
[]={
188 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
189 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
190 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
192 static unsigned char close_bits
[]={
193 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9,
194 0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3,
195 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
198 static unsigned char left_bits
[] = {
199 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe,
200 0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe,
201 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
203 static unsigned char right_bits
[] = {
204 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff,
205 0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff,
206 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
208 static unsigned char list_bits
[] = {
209 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
210 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff,
211 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
218 // -- wxAuiDefaultTabArt class implementation --
220 wxAuiDefaultTabArt::wxAuiDefaultTabArt()
222 m_normal_font
= *wxNORMAL_FONT
;
223 m_selected_font
= *wxNORMAL_FONT
;
224 m_selected_font
.SetWeight(wxBOLD
);
225 m_measuring_font
= m_selected_font
;
227 m_fixed_tab_width
= 100;
228 m_tab_ctrl_height
= 0;
231 wxBrush toolbarbrush
;
232 toolbarbrush
.MacSetTheme( kThemeBrushToolbarBackground
);
233 wxColor base_colour
= toolbarbrush
.GetColour();
235 wxColor base_colour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
238 m_base_colour
= base_colour
;
239 wxColor darker2_colour
= StepColour(base_colour
, 70);
241 m_border_pen
= wxPen(darker2_colour
);
242 m_base_colour_pen
= wxPen(m_base_colour
);
243 m_base_colour_brush
= wxBrush(m_base_colour
);
245 m_active_close_bmp
= BitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
246 m_disabled_close_bmp
= BitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
248 m_active_left_bmp
= BitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
249 m_disabled_left_bmp
= BitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
251 m_active_right_bmp
= BitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
252 m_disabled_right_bmp
= BitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
254 m_active_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
255 m_disabled_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
260 wxAuiDefaultTabArt::~wxAuiDefaultTabArt()
264 wxAuiTabArt
* wxAuiDefaultTabArt::Clone()
266 return static_cast<wxAuiTabArt
*>(new wxAuiDefaultTabArt
);
269 void wxAuiDefaultTabArt::SetFlags(unsigned int flags
)
274 void wxAuiDefaultTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
,
277 m_fixed_tab_width
= 100;
279 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
282 m_fixed_tab_width
= tot_width
/(int)tab_count
;
286 if (m_fixed_tab_width
< 100)
287 m_fixed_tab_width
= 100;
289 if (m_fixed_tab_width
> tot_width
/2)
290 m_fixed_tab_width
= tot_width
/2;
292 if (m_fixed_tab_width
> 220)
293 m_fixed_tab_width
= 220;
295 m_tab_ctrl_height
= tab_ctrl_size
.y
;
299 void wxAuiDefaultTabArt::DrawBackground(wxDC
& dc
,
300 wxWindow
* WXUNUSED(wnd
),
304 wxRect
r(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
-3);
305 wxColor start_colour
= StepColour(m_base_colour
, 90);
306 wxColor end_colour
= StepColour(m_base_colour
, 110);
307 dc
.GradientFillLinear(r
, start_colour
, end_colour
, wxSOUTH
);
310 int y
= rect
.GetHeight();
311 int w
= rect
.GetWidth();
312 dc
.SetPen(m_border_pen
);
313 dc
.DrawLine(0, y
-4, w
, y
-4);
314 dc
.DrawLine(0, y
-1, w
, y
-1);
315 dc
.SetPen(wxPen(start_colour
));
316 dc
.DrawLine(0, y
-3, w
, y
-3);
317 dc
.DrawLine(0, y
-2, w
, y
-2);
321 // DrawTab() draws an individual tab.
324 // in_rect - rectangle the tab should be confined to
325 // caption - tab's caption
326 // active - whether or not the tab is active
327 // out_rect - actual output rectangle
328 // x_extent - the advance x; where the next tab should start
330 void wxAuiDefaultTabArt::DrawTab(wxDC
& dc
,
332 const wxRect
& in_rect
,
333 const wxString
& caption_text
,
334 const wxBitmap
& bitmap
,
336 int close_button_state
,
337 wxRect
* out_tab_rect
,
338 wxRect
* out_button_rect
,
341 wxCoord normal_textx
, normal_texty
;
342 wxCoord selected_textx
, selected_texty
;
343 wxCoord textx
, texty
;
345 // if the caption is empty, measure some temporary text
346 wxString caption
= caption_text
;
347 if (caption_text
.empty())
350 dc
.SetFont(m_selected_font
);
351 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
353 dc
.SetFont(m_normal_font
);
354 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
356 // figure out the size of the tab
357 wxSize tab_size
= GetTabSize(dc
,
365 wxCoord tab_height
= m_tab_ctrl_height
- 3;
366 wxCoord tab_width
= tab_size
.x
;
367 wxCoord tab_x
= in_rect
.x
;
368 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
371 caption
= caption_text
;
374 // select pen, brush and font for the tab to be drawn
378 dc
.SetFont(m_selected_font
);
379 textx
= selected_textx
;
380 texty
= selected_texty
;
384 dc
.SetFont(m_normal_font
);
385 textx
= normal_textx
;
386 texty
= normal_texty
;
390 // create points that will make the tab outline
392 int clip_width
= tab_width
;
393 if (tab_x
+ clip_width
> in_rect
.x
+ in_rect
.width
)
394 clip_width
= (in_rect
.x
+ in_rect
.width
) - tab_x
;
396 wxPoint clip_points
[6];
397 clip_points
[0] = wxPoint(tab_x
, tab_y
+tab_height
-3);
398 clip_points
[1] = wxPoint(tab_x
, tab_y
+2);
399 clip_points
[2] = wxPoint(tab_x
+2, tab_y
);
400 clip_points
[3] = wxPoint(tab_x
+clip_width
-1, tab_y
);
401 clip_points
[4] = wxPoint(tab_x
+clip_width
+1, tab_y
+2);
402 clip_points
[5] = wxPoint(tab_x
+clip_width
+1, tab_y
+tab_height
-3);
404 // set the clipping region for the tab --
405 wxRegion
clipping_region(WXSIZEOF(clip_points
), clip_points
);
406 dc
.SetClippingRegion(clipping_region
);
408 wxPoint border_points
[6];
409 border_points
[0] = wxPoint(tab_x
, tab_y
+tab_height
-4);
410 border_points
[1] = wxPoint(tab_x
, tab_y
+2);
411 border_points
[2] = wxPoint(tab_x
+2, tab_y
);
412 border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
);
413 border_points
[4] = wxPoint(tab_x
+tab_width
, tab_y
+2);
414 border_points
[5] = wxPoint(tab_x
+tab_width
, tab_y
+tab_height
-4);
417 int drawn_tab_yoff
= border_points
[1].y
;
418 int drawn_tab_height
= border_points
[0].y
- border_points
[1].y
;
425 // draw base background color
426 wxRect
r(tab_x
, tab_y
, tab_width
, tab_height
);
427 dc
.SetPen(m_base_colour_pen
);
428 dc
.SetBrush(m_base_colour_brush
);
429 dc
.DrawRectangle(r
.x
, r
.y
, r
.width
, r
.height
);
431 // this white helps fill out the gradient at the top of the tab
432 dc
.SetPen(*wxWHITE_PEN
);
433 dc
.SetBrush(*wxWHITE_BRUSH
);
434 dc
.DrawRectangle(r
.x
+2, r
.y
+2, r
.width
-3, r
.height
);
436 // these two points help the rounded corners appear more antialiased
437 dc
.SetPen(m_base_colour_pen
);
438 dc
.DrawPoint(r
.x
+2, r
.y
+2);
439 dc
.DrawPoint(r
.x
+r
.width
-2, r
.y
+2);
441 // set rectangle down a bit for gradient drawing
442 r
.SetHeight(r
.GetHeight()/2);
447 // draw gradient background
448 wxColor start_color
= StepColour(m_base_colour
, 95);
449 wxColor end_color
= *wxWHITE
;
450 dc
.GradientFillLinear(r
, start_color
, end_color
, wxNORTH
);
456 wxRect
r(tab_x
, tab_y
+1, tab_width
, tab_height
-3);
458 // draw base background color for inactive tabs
459 dc
.SetPen(m_base_colour_pen
);
460 dc
.SetBrush(m_base_colour_brush
);
461 dc
.DrawRectangle(r
.x
, r
.y
, r
.width
, r
.height
);
463 // start the gradent up a bit and leave the inside border inset
464 // by a pixel for a 3D look. Only the top half of the inactive
465 // tab will have a slight gradient
470 // -- draw bottom gradient fill for glossy look
471 wxColor top_color
= m_base_colour
;
472 wxColor bottom_color
= StepColour(top_color
, 106);
473 dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
);
477 dc
.SetPen(m_border_pen
);
478 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
479 dc
.DrawPolygon(WXSIZEOF(border_points
), border_points
);
481 // there are two horizontal grey lines at the bottom of the tab control,
482 // this gets rid of the top one of those lines in the tab control
485 wxColor start_color
= StepColour(m_base_colour
, 93);
486 dc
.SetPen(wxPen(start_color
));
487 dc
.DrawLine(border_points
[0].x
,
489 border_points
[5].x
+1,
494 int text_offset
= tab_x
+ 8;
495 int close_button_width
= 0;
496 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
498 close_button_width
= m_active_close_bmp
.GetWidth();
504 int bitmap_offset
= tab_x
+ 8;
507 dc
.DrawBitmap(bitmap
,
509 drawn_tab_yoff
+ (drawn_tab_height
/2) - (bitmap
.GetHeight()/2) + 1,
512 text_offset
= bitmap_offset
+ bitmap
.GetWidth();
513 text_offset
+= 3; // bitmap padding
517 text_offset
= tab_x
+ 8;
521 wxString draw_text
= ChopText(dc
,
523 tab_width
- (text_offset
-tab_x
) - close_button_width
);
526 dc
.DrawText(draw_text
,
528 drawn_tab_yoff
+ (drawn_tab_height
)/2 - (texty
/2) - 1);
533 // draw close button if necessary
534 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
536 wxBitmap bmp
= m_disabled_close_bmp
;
538 if (close_button_state
== wxAUI_BUTTON_STATE_HOVER
||
539 close_button_state
== wxAUI_BUTTON_STATE_PRESSED
)
541 bmp
= m_active_close_bmp
;
544 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
545 tab_y
+ (tab_height
/2) - (bmp
.GetHeight()/2),
548 IndentPressedBitmap(&rect
, close_button_state
);
549 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
551 *out_button_rect
= rect
;
554 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
556 dc
.DestroyClippingRegion();
559 int wxAuiDefaultTabArt::GetIndentSize()
564 wxSize
wxAuiDefaultTabArt::GetTabSize(wxDC
& dc
,
565 wxWindow
* WXUNUSED(wnd
),
566 const wxString
& caption
,
567 const wxBitmap
& bitmap
,
568 bool WXUNUSED(active
),
569 int close_button_state
,
572 wxCoord measured_textx
, measured_texty
, tmp
;
574 dc
.SetFont(m_measuring_font
);
575 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
577 dc
.GetTextExtent(wxT("ABCDEFXj"), &tmp
, &measured_texty
);
579 // add padding around the text
580 wxCoord tab_width
= measured_textx
;
581 wxCoord tab_height
= measured_texty
;
583 // if the close button is showing, add space for it
584 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
585 tab_width
+= m_active_close_bmp
.GetWidth() + 3;
587 // if there's a bitmap, add space for it
590 tab_width
+= bitmap
.GetWidth();
591 tab_width
+= 3; // right side bitmap padding
592 tab_height
= wxMax(tab_height
, bitmap
.GetHeight());
599 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
601 tab_width
= m_fixed_tab_width
;
604 *x_extent
= tab_width
;
606 return wxSize(tab_width
, tab_height
);
610 void wxAuiDefaultTabArt::DrawButton(wxDC
& dc
,
611 wxWindow
* WXUNUSED(wnd
),
612 const wxRect
& in_rect
,
616 const wxBitmap
& bitmap_override
,
622 if (bitmap_override
.IsOk())
624 bmp
= bitmap_override
;
630 case wxAUI_BUTTON_CLOSE
:
631 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
632 bmp
= m_disabled_close_bmp
;
634 bmp
= m_active_close_bmp
;
636 case wxAUI_BUTTON_LEFT
:
637 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
638 bmp
= m_disabled_left_bmp
;
640 bmp
= m_active_left_bmp
;
642 case wxAUI_BUTTON_RIGHT
:
643 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
644 bmp
= m_disabled_right_bmp
;
646 bmp
= m_active_right_bmp
;
648 case wxAUI_BUTTON_WINDOWLIST
:
649 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
650 bmp
= m_disabled_windowlist_bmp
;
652 bmp
= m_active_windowlist_bmp
;
662 if (orientation
== wxLEFT
)
664 rect
.SetX(in_rect
.x
);
665 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
666 rect
.SetWidth(bmp
.GetWidth());
667 rect
.SetHeight(bmp
.GetHeight());
671 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
672 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
673 bmp
.GetWidth(), bmp
.GetHeight());
676 IndentPressedBitmap(&rect
, button_state
);
677 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
683 int wxAuiDefaultTabArt::ShowWindowList(wxWindow
* wnd
,
684 const wxArrayString
& items
,
689 size_t i
, count
= items
.GetCount();
690 for (i
= 0; i
< count
; ++i
)
692 menuPopup
.AppendCheckItem(1000+i
, items
.Item(i
));
695 if (active_idx
!= -1)
697 menuPopup
.Check(1000+active_idx
, true);
700 // find out where to put the popup menu of window
701 // items. Subtract 100 for now to center the menu
702 // a bit, until a better mechanism can be implemented
703 wxPoint pt
= ::wxGetMousePosition();
704 pt
= wnd
->ScreenToClient(pt
);
710 // find out the screen coordinate at the bottom of the tab ctrl
711 wxRect cli_rect
= wnd
->GetClientRect();
712 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
714 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
715 wnd
->PushEventHandler(cc
);
716 wnd
->PopupMenu(&menuPopup
, pt
);
717 int command
= cc
->GetCommandId();
718 wnd
->PopEventHandler(true);
726 int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
727 wxAuiNotebookPageArray
& pages
)
730 dc
.SetFont(m_measuring_font
);
733 size_t i
, page_count
= pages
.GetCount();
734 for (i
= 0; i
< page_count
; ++i
)
736 wxAuiNotebookPage
& page
= pages
.Item(i
);
738 // we don't use the caption text because we don't
739 // want tab heights to be different in the case
740 // of a very short piece of text on one tab and a very
741 // tall piece of text on another tab
743 wxSize s
= GetTabSize(dc
,
748 wxAUI_BUTTON_STATE_HIDDEN
,
750 max_y
= wxMax(max_y
, s
.y
);
756 void wxAuiDefaultTabArt::SetNormalFont(const wxFont
& font
)
758 m_normal_font
= font
;
761 void wxAuiDefaultTabArt::SetSelectedFont(const wxFont
& font
)
763 m_selected_font
= font
;
766 void wxAuiDefaultTabArt::SetMeasuringFont(const wxFont
& font
)
768 m_measuring_font
= font
;
772 // -- wxAuiSimpleTabArt class implementation --
774 wxAuiSimpleTabArt::wxAuiSimpleTabArt()
776 m_normal_font
= *wxNORMAL_FONT
;
777 m_selected_font
= *wxNORMAL_FONT
;
778 m_selected_font
.SetWeight(wxBOLD
);
779 m_measuring_font
= m_selected_font
;
782 m_fixed_tab_width
= 100;
784 wxColour base_colour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
786 wxColour background_colour
= StepColour(base_colour
, 95);
787 wxColour normaltab_colour
= base_colour
;
788 wxColour selectedtab_colour
= *wxWHITE
;
790 m_bkbrush
= wxBrush(background_colour
);
791 m_normal_bkbrush
= wxBrush(normaltab_colour
);
792 m_normal_bkpen
= wxPen(normaltab_colour
);
793 m_selected_bkbrush
= wxBrush(selectedtab_colour
);
794 m_selected_bkpen
= wxPen(selectedtab_colour
);
796 m_active_close_bmp
= BitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
797 m_disabled_close_bmp
= BitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
799 m_active_left_bmp
= BitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
800 m_disabled_left_bmp
= BitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
802 m_active_right_bmp
= BitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
803 m_disabled_right_bmp
= BitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
805 m_active_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
806 m_disabled_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
810 wxAuiSimpleTabArt::~wxAuiSimpleTabArt()
814 wxAuiTabArt
* wxAuiSimpleTabArt::Clone()
816 return static_cast<wxAuiTabArt
*>(new wxAuiSimpleTabArt
);
820 void wxAuiSimpleTabArt::SetFlags(unsigned int flags
)
825 void wxAuiSimpleTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
,
828 m_fixed_tab_width
= 100;
830 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
833 m_fixed_tab_width
= tot_width
/(int)tab_count
;
837 if (m_fixed_tab_width
< 100)
838 m_fixed_tab_width
= 100;
840 if (m_fixed_tab_width
> tot_width
/2)
841 m_fixed_tab_width
= tot_width
/2;
843 if (m_fixed_tab_width
> 220)
844 m_fixed_tab_width
= 220;
847 void wxAuiSimpleTabArt::DrawBackground(wxDC
& dc
,
848 wxWindow
* WXUNUSED(wnd
),
852 dc
.SetBrush(m_bkbrush
);
853 dc
.SetPen(*wxTRANSPARENT_PEN
);
854 dc
.DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2);
857 dc
.SetPen(*wxGREY_PEN
);
858 dc
.DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1);
862 // DrawTab() draws an individual tab.
865 // in_rect - rectangle the tab should be confined to
866 // caption - tab's caption
867 // active - whether or not the tab is active
868 // out_rect - actual output rectangle
869 // x_extent - the advance x; where the next tab should start
871 void wxAuiSimpleTabArt::DrawTab(wxDC
& dc
,
873 const wxRect
& in_rect
,
874 const wxString
& caption_text
,
875 const wxBitmap
& bitmap
,
877 int close_button_state
,
878 wxRect
* out_tab_rect
,
879 wxRect
* out_button_rect
,
882 wxCoord normal_textx
, normal_texty
;
883 wxCoord selected_textx
, selected_texty
;
884 wxCoord textx
, texty
;
886 // if the caption is empty, measure some temporary text
887 wxString caption
= caption_text
;
888 if (caption_text
.empty())
891 dc
.SetFont(m_selected_font
);
892 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
894 dc
.SetFont(m_normal_font
);
895 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
897 // figure out the size of the tab
898 wxSize tab_size
= GetTabSize(dc
,
906 wxCoord tab_height
= tab_size
.y
;
907 wxCoord tab_width
= tab_size
.x
;
908 wxCoord tab_x
= in_rect
.x
;
909 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
911 caption
= caption_text
;
913 // select pen, brush and font for the tab to be drawn
917 dc
.SetPen(m_selected_bkpen
);
918 dc
.SetBrush(m_selected_bkbrush
);
919 dc
.SetFont(m_selected_font
);
920 textx
= selected_textx
;
921 texty
= selected_texty
;
925 dc
.SetPen(m_normal_bkpen
);
926 dc
.SetBrush(m_normal_bkbrush
);
927 dc
.SetFont(m_normal_font
);
928 textx
= normal_textx
;
929 texty
= normal_texty
;
937 points
[0].y
= tab_y
+ tab_height
- 1;
938 points
[1].x
= tab_x
+ tab_height
- 3;
939 points
[1].y
= tab_y
+ 2;
940 points
[2].x
= tab_x
+ tab_height
+ 3;
942 points
[3].x
= tab_x
+ tab_width
- 2;
944 points
[4].x
= tab_x
+ tab_width
;
945 points
[4].y
= tab_y
+ 2;
946 points
[5].x
= tab_x
+ tab_width
;
947 points
[5].y
= tab_y
+ tab_height
- 1;
948 points
[6] = points
[0];
950 dc
.SetClippingRegion(in_rect
);
952 dc
.DrawPolygon(WXSIZEOF(points
) - 1, points
);
954 dc
.SetPen(*wxGREY_PEN
);
956 //dc.DrawLines(active ? WXSIZEOF(points) - 1 : WXSIZEOF(points), points);
957 dc
.DrawLines(WXSIZEOF(points
), points
);
962 int close_button_width
= 0;
963 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
965 close_button_width
= m_active_close_bmp
.GetWidth();
966 text_offset
= tab_x
+ (tab_height
/2) + ((tab_width
-close_button_width
)/2) - (textx
/2);
970 text_offset
= tab_x
+ (tab_height
/3) + (tab_width
/2) - (textx
/2);
973 // set minimum text offset
974 if (text_offset
< tab_x
+ tab_height
)
975 text_offset
= tab_x
+ tab_height
;
977 // chop text if necessary
978 wxString draw_text
= ChopText(dc
,
980 tab_width
- (text_offset
-tab_x
) - close_button_width
);
983 dc
.DrawText(draw_text
,
985 (tab_y
+ tab_height
)/2 - (texty
/2) + 1);
988 // draw close button if necessary
989 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
993 bmp
= m_active_close_bmp
;
995 bmp
= m_disabled_close_bmp
;
997 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
998 tab_y
+ (tab_height
/2) - (bmp
.GetHeight()/2) + 1,
1001 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, close_button_state
);
1003 *out_button_rect
= rect
;
1007 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
1009 dc
.DestroyClippingRegion();
1012 int wxAuiSimpleTabArt::GetIndentSize()
1017 wxSize
wxAuiSimpleTabArt::GetTabSize(wxDC
& dc
,
1018 wxWindow
* WXUNUSED(wnd
),
1019 const wxString
& caption
,
1020 const wxBitmap
& WXUNUSED(bitmap
),
1021 bool WXUNUSED(active
),
1022 int close_button_state
,
1025 wxCoord measured_textx
, measured_texty
;
1027 dc
.SetFont(m_measuring_font
);
1028 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
1030 wxCoord tab_height
= measured_texty
+ 4;
1031 wxCoord tab_width
= measured_textx
+ tab_height
+ 5;
1033 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1034 tab_width
+= m_active_close_bmp
.GetWidth();
1036 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
1038 tab_width
= m_fixed_tab_width
;
1041 *x_extent
= tab_width
- (tab_height
/2) - 1;
1043 return wxSize(tab_width
, tab_height
);
1047 void wxAuiSimpleTabArt::DrawButton(wxDC
& dc
,
1048 wxWindow
* WXUNUSED(wnd
),
1049 const wxRect
& in_rect
,
1053 const wxBitmap
& bitmap_override
,
1059 if (bitmap_override
.IsOk())
1061 bmp
= bitmap_override
;
1067 case wxAUI_BUTTON_CLOSE
:
1068 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1069 bmp
= m_disabled_close_bmp
;
1071 bmp
= m_active_close_bmp
;
1073 case wxAUI_BUTTON_LEFT
:
1074 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1075 bmp
= m_disabled_left_bmp
;
1077 bmp
= m_active_left_bmp
;
1079 case wxAUI_BUTTON_RIGHT
:
1080 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1081 bmp
= m_disabled_right_bmp
;
1083 bmp
= m_active_right_bmp
;
1085 case wxAUI_BUTTON_WINDOWLIST
:
1086 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1087 bmp
= m_disabled_windowlist_bmp
;
1089 bmp
= m_active_windowlist_bmp
;
1099 if (orientation
== wxLEFT
)
1101 rect
.SetX(in_rect
.x
);
1102 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
1103 rect
.SetWidth(bmp
.GetWidth());
1104 rect
.SetHeight(bmp
.GetHeight());
1108 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
1109 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
1110 bmp
.GetWidth(), bmp
.GetHeight());
1114 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, button_state
);
1120 int wxAuiSimpleTabArt::ShowWindowList(wxWindow
* wnd
,
1121 const wxArrayString
& items
,
1126 size_t i
, count
= items
.GetCount();
1127 for (i
= 0; i
< count
; ++i
)
1129 menuPopup
.AppendCheckItem(1000+i
, items
.Item(i
));
1132 if (active_idx
!= -1)
1134 menuPopup
.Check(1000+active_idx
, true);
1137 // find out where to put the popup menu of window
1138 // items. Subtract 100 for now to center the menu
1139 // a bit, until a better mechanism can be implemented
1140 wxPoint pt
= ::wxGetMousePosition();
1141 pt
= wnd
->ScreenToClient(pt
);
1147 // find out the screen coordinate at the bottom of the tab ctrl
1148 wxRect cli_rect
= wnd
->GetClientRect();
1149 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
1151 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
1152 wnd
->PushEventHandler(cc
);
1153 wnd
->PopupMenu(&menuPopup
, pt
);
1154 int command
= cc
->GetCommandId();
1155 wnd
->PopEventHandler(true);
1157 if (command
>= 1000)
1158 return command
-1000;
1163 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
1164 wxAuiNotebookPageArray
& WXUNUSED(pages
))
1167 dc
.SetFont(m_measuring_font
);
1169 wxSize s
= GetTabSize(dc
,
1174 wxAUI_BUTTON_STATE_HIDDEN
,
1179 void wxAuiSimpleTabArt::SetNormalFont(const wxFont
& font
)
1181 m_normal_font
= font
;
1184 void wxAuiSimpleTabArt::SetSelectedFont(const wxFont
& font
)
1186 m_selected_font
= font
;
1189 void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont
& font
)
1191 m_measuring_font
= font
;
1197 // -- wxAuiTabContainer class implementation --
1200 // wxAuiTabContainer is a class which contains information about each
1201 // tab. It also can render an entire tab control to a specified DC.
1202 // It's not a window class itself, because this code will be used by
1203 // the wxFrameMananger, where it is disadvantageous to have separate
1204 // windows for each tab control in the case of "docked tabs"
1206 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window
1207 // which can be used as a tab control in the normal sense.
1210 wxAuiTabContainer::wxAuiTabContainer()
1214 m_art
= new wxAuiDefaultTabArt
;
1216 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
1217 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
1218 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
1219 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
1222 wxAuiTabContainer::~wxAuiTabContainer()
1227 void wxAuiTabContainer::SetArtProvider(wxAuiTabArt
* art
)
1234 m_art
->SetFlags(m_flags
);
1238 wxAuiTabArt
* wxAuiTabContainer::GetArtProvider() const
1243 void wxAuiTabContainer::SetFlags(unsigned int flags
)
1247 // check for new close button settings
1248 RemoveButton(wxAUI_BUTTON_LEFT
);
1249 RemoveButton(wxAUI_BUTTON_RIGHT
);
1250 RemoveButton(wxAUI_BUTTON_WINDOWLIST
);
1251 RemoveButton(wxAUI_BUTTON_CLOSE
);
1254 if (flags
& wxAUI_NB_SCROLL_BUTTONS
)
1256 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
1257 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
1260 if (flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
1262 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
1265 if (flags
& wxAUI_NB_CLOSE_BUTTON
)
1267 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
1272 m_art
->SetFlags(m_flags
);
1276 unsigned int wxAuiTabContainer::GetFlags() const
1282 void wxAuiTabContainer::SetNormalFont(const wxFont
& font
)
1284 m_art
->SetNormalFont(font
);
1287 void wxAuiTabContainer::SetSelectedFont(const wxFont
& font
)
1289 m_art
->SetSelectedFont(font
);
1292 void wxAuiTabContainer::SetMeasuringFont(const wxFont
& font
)
1294 m_art
->SetMeasuringFont(font
);
1297 void wxAuiTabContainer::SetRect(const wxRect
& rect
)
1303 m_art
->SetSizingInfo(rect
.GetSize(), m_pages
.GetCount());
1307 bool wxAuiTabContainer::AddPage(wxWindow
* page
,
1308 const wxAuiNotebookPage
& info
)
1310 wxAuiNotebookPage page_info
;
1312 page_info
.window
= page
;
1314 m_pages
.Add(page_info
);
1316 // let the art provider know how many pages we have
1319 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1325 bool wxAuiTabContainer::InsertPage(wxWindow
* page
,
1326 const wxAuiNotebookPage
& info
,
1329 wxAuiNotebookPage page_info
;
1331 page_info
.window
= page
;
1333 if (idx
>= m_pages
.GetCount())
1334 m_pages
.Add(page_info
);
1336 m_pages
.Insert(page_info
, idx
);
1338 // let the art provider know how many pages we have
1341 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1347 bool wxAuiTabContainer::MovePage(wxWindow
* page
,
1350 int idx
= GetIdxFromWindow(page
);
1354 // get page entry, make a copy of it
1355 wxAuiNotebookPage p
= GetPage(idx
);
1357 // remove old page entry
1360 // insert page where it should be
1361 InsertPage(page
, p
, new_idx
);
1366 bool wxAuiTabContainer::RemovePage(wxWindow
* wnd
)
1368 size_t i
, page_count
= m_pages
.GetCount();
1369 for (i
= 0; i
< page_count
; ++i
)
1371 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1372 if (page
.window
== wnd
)
1374 m_pages
.RemoveAt(i
);
1376 // let the art provider know how many pages we have
1379 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1389 bool wxAuiTabContainer::SetActivePage(wxWindow
* wnd
)
1393 size_t i
, page_count
= m_pages
.GetCount();
1394 for (i
= 0; i
< page_count
; ++i
)
1396 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1397 if (page
.window
== wnd
)
1404 page
.active
= false;
1411 void wxAuiTabContainer::SetNoneActive()
1413 size_t i
, page_count
= m_pages
.GetCount();
1414 for (i
= 0; i
< page_count
; ++i
)
1416 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1417 page
.active
= false;
1421 bool wxAuiTabContainer::SetActivePage(size_t page
)
1423 if (page
>= m_pages
.GetCount())
1426 return SetActivePage(m_pages
.Item(page
).window
);
1429 int wxAuiTabContainer::GetActivePage() const
1431 size_t i
, page_count
= m_pages
.GetCount();
1432 for (i
= 0; i
< page_count
; ++i
)
1434 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1442 wxWindow
* wxAuiTabContainer::GetWindowFromIdx(size_t idx
) const
1444 if (idx
>= m_pages
.GetCount())
1447 return m_pages
[idx
].window
;
1450 int wxAuiTabContainer::GetIdxFromWindow(wxWindow
* wnd
) const
1452 size_t i
, page_count
= m_pages
.GetCount();
1453 for (i
= 0; i
< page_count
; ++i
)
1455 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1456 if (page
.window
== wnd
)
1462 wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
)
1464 wxASSERT_MSG(idx
< m_pages
.GetCount(), wxT("Invalid Page index"));
1466 return m_pages
[idx
];
1469 wxAuiNotebookPageArray
& wxAuiTabContainer::GetPages()
1474 size_t wxAuiTabContainer::GetPageCount() const
1476 return m_pages
.GetCount();
1479 void wxAuiTabContainer::AddButton(int id
,
1481 const wxBitmap
& normal_bitmap
,
1482 const wxBitmap
& disabled_bitmap
)
1484 wxAuiTabContainerButton button
;
1486 button
.bitmap
= normal_bitmap
;
1487 button
.dis_bitmap
= disabled_bitmap
;
1488 button
.location
= location
;
1489 button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1491 m_buttons
.Add(button
);
1494 void wxAuiTabContainer::RemoveButton(int id
)
1496 size_t i
, button_count
= m_buttons
.GetCount();
1498 for (i
= 0; i
< button_count
; ++i
)
1500 if (m_buttons
.Item(i
).id
== id
)
1502 m_buttons
.RemoveAt(i
);
1510 size_t wxAuiTabContainer::GetTabOffset() const
1512 return m_tab_offset
;
1515 void wxAuiTabContainer::SetTabOffset(size_t offset
)
1517 m_tab_offset
= offset
;
1523 // Render() renders the tab catalog to the specified DC
1524 // It is a virtual function and can be overridden to
1525 // provide custom drawing capabilities
1526 void wxAuiTabContainer::Render(wxDC
* raw_dc
, wxWindow
* wnd
)
1528 if (!raw_dc
|| !raw_dc
->IsOk())
1534 size_t page_count
= m_pages
.GetCount();
1535 size_t button_count
= m_buttons
.GetCount();
1537 // create off-screen bitmap
1538 bmp
.Create(m_rect
.GetWidth(), m_rect
.GetHeight());
1539 dc
.SelectObject(bmp
);
1544 // find out if size of tabs is larger than can be
1545 // afforded on screen
1546 int total_width
= 0;
1547 int visible_width
= 0;
1548 for (i
= 0; i
< page_count
; ++i
)
1550 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1552 // determine if a close button is on this tab
1553 bool close_button
= false;
1554 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1555 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1557 close_button
= true;
1562 wxSize size
= m_art
->GetTabSize(dc
,
1568 wxAUI_BUTTON_STATE_NORMAL
:
1569 wxAUI_BUTTON_STATE_HIDDEN
,
1572 if (i
+1 < page_count
)
1573 total_width
+= x_extent
;
1575 total_width
+= size
.x
;
1577 if (i
>= m_tab_offset
)
1579 if (i
+1 < page_count
)
1580 visible_width
+= x_extent
;
1582 visible_width
+= size
.x
;
1586 if (total_width
> m_rect
.GetWidth() || m_tab_offset
!= 0)
1588 // show left/right buttons
1589 for (i
= 0; i
< button_count
; ++i
)
1591 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1592 if (button
.id
== wxAUI_BUTTON_LEFT
||
1593 button
.id
== wxAUI_BUTTON_RIGHT
)
1595 button
.cur_state
&= ~wxAUI_BUTTON_STATE_HIDDEN
;
1601 // hide left/right buttons
1602 for (i
= 0; i
< button_count
; ++i
)
1604 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1605 if (button
.id
== wxAUI_BUTTON_LEFT
||
1606 button
.id
== wxAUI_BUTTON_RIGHT
)
1608 button
.cur_state
|= wxAUI_BUTTON_STATE_HIDDEN
;
1613 // determine whether left button should be enabled
1614 for (i
= 0; i
< button_count
; ++i
)
1616 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1617 if (button
.id
== wxAUI_BUTTON_LEFT
)
1619 if (m_tab_offset
== 0)
1620 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
1622 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
1624 if (button
.id
== wxAUI_BUTTON_RIGHT
)
1626 if (visible_width
< m_rect
.GetWidth() - ((int)button_count
*16))
1627 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
1629 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
1636 m_art
->DrawBackground(dc
, wnd
, m_rect
);
1639 int left_buttons_width
= 0;
1640 int right_buttons_width
= 0;
1644 // draw the buttons on the right side
1645 offset
= m_rect
.x
+ m_rect
.width
;
1646 for (i
= 0; i
< button_count
; ++i
)
1648 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
1650 if (button
.location
!= wxRIGHT
)
1652 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
1655 wxRect button_rect
= m_rect
;
1656 button_rect
.SetY(1);
1657 button_rect
.SetWidth(offset
);
1659 m_art
->DrawButton(dc
,
1668 offset
-= button
.rect
.GetWidth();
1669 right_buttons_width
+= button
.rect
.GetWidth();
1676 // draw the buttons on the left side
1678 for (i
= 0; i
< button_count
; ++i
)
1680 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
1682 if (button
.location
!= wxLEFT
)
1684 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
1687 wxRect
button_rect(offset
, 1, 1000, m_rect
.height
);
1689 m_art
->DrawButton(dc
,
1698 offset
+= button
.rect
.GetWidth();
1699 left_buttons_width
+= button
.rect
.GetWidth();
1702 offset
= left_buttons_width
;
1705 offset
+= m_art
->GetIndentSize();
1708 // prepare the tab-close-button array
1709 // make sure tab button entries which aren't used are marked as hidden
1710 for (i
= page_count
; i
< m_tab_close_buttons
.GetCount(); ++i
)
1711 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1713 // make sure there are enough tab button entries to accommodate all tabs
1714 while (m_tab_close_buttons
.GetCount() < page_count
)
1716 wxAuiTabContainerButton tempbtn
;
1717 tempbtn
.id
= wxAUI_BUTTON_CLOSE
;
1718 tempbtn
.location
= wxCENTER
;
1719 tempbtn
.cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1720 m_tab_close_buttons
.Add(tempbtn
);
1724 // buttons before the tab offset must be set to hidden
1725 for (i
= 0; i
< m_tab_offset
; ++i
)
1727 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1733 size_t active
= 999;
1734 int active_offset
= 0;
1738 wxRect rect
= m_rect
;
1740 rect
.height
= m_rect
.height
;
1742 for (i
= m_tab_offset
; i
< page_count
; ++i
)
1744 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1745 wxAuiTabContainerButton
& tab_button
= m_tab_close_buttons
.Item(i
);
1747 // determine if a close button is on this tab
1748 bool close_button
= false;
1749 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1750 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1752 close_button
= true;
1753 if (tab_button
.cur_state
== wxAUI_BUTTON_STATE_HIDDEN
)
1755 tab_button
.id
= wxAUI_BUTTON_CLOSE
;
1756 tab_button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1757 tab_button
.location
= wxCENTER
;
1762 tab_button
.cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1766 rect
.width
= m_rect
.width
- right_buttons_width
- offset
- 2;
1768 if (rect
.width
<= 0)
1777 tab_button
.cur_state
,
1785 active_offset
= offset
;
1793 // make sure to deactivate buttons which are off the screen to the right
1794 for (++i
; i
< m_tab_close_buttons
.GetCount(); ++i
)
1796 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1800 // draw the active tab again so it stands in the foreground
1801 if (active
>= m_tab_offset
&& active
< m_pages
.GetCount())
1803 wxAuiNotebookPage
& page
= m_pages
.Item(active
);
1805 wxAuiTabContainerButton
& tab_button
= m_tab_close_buttons
.Item(active
);
1807 // determine if a close button is on this tab
1808 bool close_button
= false;
1809 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1810 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1812 close_button
= true;
1815 rect
.x
= active_offset
;
1822 tab_button
.cur_state
,
1829 raw_dc
->Blit(m_rect
.x
, m_rect
.y
,
1830 m_rect
.GetWidth(), m_rect
.GetHeight(),
1835 // TabHitTest() tests if a tab was hit, passing the window pointer
1836 // back if that condition was fulfilled. The function returns
1837 // true if a tab was hit, otherwise false
1838 bool wxAuiTabContainer::TabHitTest(int x
, int y
, wxWindow
** hit
) const
1840 if (!m_rect
.Contains(x
,y
))
1843 wxAuiTabContainerButton
* btn
= NULL
;
1844 if (ButtonHitTest(x
, y
, &btn
))
1846 if (m_buttons
.Index(*btn
) != wxNOT_FOUND
)
1850 size_t i
, page_count
= m_pages
.GetCount();
1852 for (i
= m_tab_offset
; i
< page_count
; ++i
)
1854 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1855 if (page
.rect
.Contains(x
,y
))
1866 // ButtonHitTest() tests if a button was hit. The function returns
1867 // true if a button was hit, otherwise false
1868 bool wxAuiTabContainer::ButtonHitTest(int x
, int y
,
1869 wxAuiTabContainerButton
** hit
) const
1871 if (!m_rect
.Contains(x
,y
))
1874 size_t i
, button_count
;
1877 button_count
= m_buttons
.GetCount();
1878 for (i
= 0; i
< button_count
; ++i
)
1880 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1881 if (button
.rect
.Contains(x
,y
) &&
1882 !(button
.cur_state
& (wxAUI_BUTTON_STATE_HIDDEN
|
1883 wxAUI_BUTTON_STATE_DISABLED
)))
1891 button_count
= m_tab_close_buttons
.GetCount();
1892 for (i
= 0; i
< button_count
; ++i
)
1894 wxAuiTabContainerButton
& button
= m_tab_close_buttons
.Item(i
);
1895 if (button
.rect
.Contains(x
,y
) &&
1896 !(button
.cur_state
& (wxAUI_BUTTON_STATE_HIDDEN
|
1897 wxAUI_BUTTON_STATE_DISABLED
)))
1910 // the utility function ShowWnd() is the same as show,
1911 // except it handles wxAuiMDIChildFrame windows as well,
1912 // as the Show() method on this class is "unplugged"
1913 static void ShowWnd(wxWindow
* wnd
, bool show
)
1915 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
1917 wxAuiMDIChildFrame
* cf
= (wxAuiMDIChildFrame
*)wnd
;
1927 // DoShowHide() this function shows the active window, then
1928 // hides all of the other windows (in that order)
1929 void wxAuiTabContainer::DoShowHide()
1931 wxAuiNotebookPageArray
& pages
= GetPages();
1932 size_t i
, page_count
= pages
.GetCount();
1934 // show new active page first
1935 for (i
= 0; i
< page_count
; ++i
)
1937 wxAuiNotebookPage
& page
= pages
.Item(i
);
1940 ShowWnd(page
.window
, true);
1945 // hide all other pages
1946 for (i
= 0; i
< page_count
; ++i
)
1948 wxAuiNotebookPage
& page
= pages
.Item(i
);
1949 ShowWnd(page
.window
, page
.active
);
1958 // -- wxAuiTabCtrl class implementation --
1962 BEGIN_EVENT_TABLE(wxAuiTabCtrl
, wxControl
)
1963 EVT_PAINT(wxAuiTabCtrl::OnPaint
)
1964 EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground
)
1965 EVT_SIZE(wxAuiTabCtrl::OnSize
)
1966 EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown
)
1967 EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp
)
1968 EVT_MOTION(wxAuiTabCtrl::OnMotion
)
1969 EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow
)
1970 EVT_AUINOTEBOOK_BUTTON(-1, wxAuiTabCtrl::OnButton
)
1974 wxAuiTabCtrl::wxAuiTabCtrl(wxWindow
* parent
,
1978 long style
) : wxControl(parent
, id
, pos
, size
, style
)
1980 m_click_pt
= wxDefaultPosition
;
1981 m_is_dragging
= false;
1982 m_hover_button
= NULL
;
1983 m_pressed_button
= NULL
;
1986 wxAuiTabCtrl::~wxAuiTabCtrl()
1990 void wxAuiTabCtrl::OnPaint(wxPaintEvent
&)
1994 dc
.SetFont(GetFont());
1996 if (GetPageCount() > 0)
2000 void wxAuiTabCtrl::OnEraseBackground(wxEraseEvent
& WXUNUSED(evt
))
2004 void wxAuiTabCtrl::OnSize(wxSizeEvent
& evt
)
2006 wxSize s
= evt
.GetSize();
2007 wxRect
r(0, 0, s
.GetWidth(), s
.GetHeight());
2011 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent
& evt
)
2014 m_click_pt
= wxDefaultPosition
;
2015 m_is_dragging
= false;
2017 m_pressed_button
= NULL
;
2021 if (TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
2023 int new_selection
= GetIdxFromWindow(wnd
);
2025 if (new_selection
!= GetActivePage())
2027 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2028 e
.SetSelection(new_selection
);
2029 e
.SetOldSelection(GetActivePage());
2030 e
.SetEventObject(this);
2031 GetEventHandler()->ProcessEvent(e
);
2034 m_click_pt
.x
= evt
.m_x
;
2035 m_click_pt
.y
= evt
.m_y
;
2041 m_pressed_button
= m_hover_button
;
2042 m_pressed_button
->cur_state
= wxAUI_BUTTON_STATE_PRESSED
;
2048 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent
& evt
)
2050 if (GetCapture() == this)
2055 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, m_windowId
);
2056 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2057 evt
.SetOldSelection(evt
.GetSelection());
2058 evt
.SetEventObject(this);
2059 GetEventHandler()->ProcessEvent(evt
);
2063 if (m_pressed_button
)
2065 // make sure we're still clicking the button
2066 wxAuiTabContainerButton
* button
= NULL
;
2067 if (!ButtonHitTest(evt
.m_x
, evt
.m_y
, &button
))
2070 if (button
!= m_pressed_button
)
2072 m_pressed_button
= NULL
;
2079 if (!(m_pressed_button
->cur_state
& wxAUI_BUTTON_STATE_DISABLED
))
2081 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, m_windowId
);
2082 evt
.SetInt(m_pressed_button
->id
);
2083 evt
.SetEventObject(this);
2084 GetEventHandler()->ProcessEvent(evt
);
2087 m_pressed_button
= NULL
;
2090 m_click_pt
= wxDefaultPosition
;
2091 m_is_dragging
= false;
2095 void wxAuiTabCtrl::OnMotion(wxMouseEvent
& evt
)
2097 wxPoint pos
= evt
.GetPosition();
2099 // check if the mouse is hovering above a button
2100 wxAuiTabContainerButton
* button
;
2101 if (ButtonHitTest(pos
.x
, pos
.y
, &button
))
2103 if (m_hover_button
&& button
!= m_hover_button
)
2105 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2106 m_hover_button
= NULL
;
2111 if (button
->cur_state
!= wxAUI_BUTTON_STATE_HOVER
)
2113 button
->cur_state
= wxAUI_BUTTON_STATE_HOVER
;
2116 m_hover_button
= button
;
2124 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2125 m_hover_button
= NULL
;
2132 if (!evt
.LeftIsDown() || m_click_pt
== wxDefaultPosition
)
2137 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, m_windowId
);
2138 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2139 evt
.SetOldSelection(evt
.GetSelection());
2140 evt
.SetEventObject(this);
2141 GetEventHandler()->ProcessEvent(evt
);
2146 int drag_x_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_X
);
2147 int drag_y_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_Y
);
2149 if (abs(pos
.x
- m_click_pt
.x
) > drag_x_threshold
||
2150 abs(pos
.y
- m_click_pt
.y
) > drag_y_threshold
)
2152 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, m_windowId
);
2153 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2154 evt
.SetOldSelection(evt
.GetSelection());
2155 evt
.SetEventObject(this);
2156 GetEventHandler()->ProcessEvent(evt
);
2158 m_is_dragging
= true;
2162 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
))
2166 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2167 m_hover_button
= NULL
;
2173 void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent
& event
)
2175 int button
= event
.GetInt();
2177 if (button
== wxAUI_BUTTON_LEFT
|| button
== wxAUI_BUTTON_RIGHT
)
2179 if (button
== wxAUI_BUTTON_LEFT
)
2181 if (GetTabOffset() > 0)
2183 SetTabOffset(GetTabOffset()-1);
2190 SetTabOffset(GetTabOffset()+1);
2195 else if (button
== wxAUI_BUTTON_WINDOWLIST
)
2199 size_t i
, page_count
= m_pages
.GetCount();
2200 for (i
= 0; i
< page_count
; ++i
)
2202 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
2203 as
.Add(page
.caption
);
2206 int idx
= GetArtProvider()->ShowWindowList(this, as
, GetActivePage());
2210 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2211 e
.SetSelection(idx
);
2212 e
.SetOldSelection(GetActivePage());
2213 e
.SetEventObject(this);
2214 GetEventHandler()->ProcessEvent(e
);
2223 // wxTabFrame is an interesting case. It's important that all child pages
2224 // of the multi-notebook control are all actually children of that control
2225 // (and not grandchildren). wxTabFrame facilitates this. There is one
2226 // instance of wxTabFrame for each tab control inside the multi-notebook.
2227 // It's important to know that wxTabFrame is not a real window, but it merely
2228 // used to capture the dimensions/positioning of the internal tab control and
2229 // it's managed page windows
2231 class wxTabFrame
: public wxWindow
2238 m_rect
= wxRect(0,0,200,200);
2239 m_tab_ctrl_height
= 20;
2242 void SetTabCtrlHeight(int h
)
2244 m_tab_ctrl_height
= h
;
2247 void DoSetSize(int x
, int y
,
2248 int width
, int height
,
2249 int WXUNUSED(sizeFlags
= wxSIZE_AUTO
))
2251 m_rect
= wxRect(x
, y
, width
, height
);
2255 void DoGetClientSize(int* x
, int* y
) const
2261 bool Show( bool WXUNUSED(show
= true) ) { return false; }
2268 m_tab_rect
= wxRect(m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
);
2269 m_tabs
->SetSize(m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
);
2270 m_tabs
->SetRect(wxRect(0, 0, m_rect
.width
, m_tab_ctrl_height
));
2274 wxAuiNotebookPageArray
& pages
= m_tabs
->GetPages();
2275 size_t i
, page_count
= pages
.GetCount();
2277 for (i
= 0; i
< page_count
; ++i
)
2279 wxAuiNotebookPage
& page
= pages
.Item(i
);
2280 page
.window
->SetSize(m_rect
.x
, m_rect
.y
+ m_tab_ctrl_height
,
2281 m_rect
.width
, m_rect
.height
- m_tab_ctrl_height
);
2283 if (page
.window
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
2285 wxAuiMDIChildFrame
* wnd
= (wxAuiMDIChildFrame
*)page
.window
;
2286 wnd
->ApplyMDIChildFrameRect();
2291 void DoGetSize(int* x
, int* y
) const
2294 *x
= m_rect
.GetWidth();
2296 *y
= m_rect
.GetHeight();
2308 wxAuiTabCtrl
* m_tabs
;
2309 int m_tab_ctrl_height
;
2316 // -- wxAuiNotebook class implementation --
2318 BEGIN_EVENT_TABLE(wxAuiNotebook
, wxControl
)
2319 //EVT_ERASE_BACKGROUND(wxAuiNotebook::OnEraseBackground)
2320 //EVT_SIZE(wxAuiNotebook::OnSize)
2321 //EVT_LEFT_DOWN(wxAuiNotebook::OnLeftDown)
2322 EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocus
)
2323 EVT_COMMAND_RANGE(10000, 10100,
2324 wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
,
2325 wxAuiNotebook::OnTabClicked
)
2326 EVT_COMMAND_RANGE(10000, 10100,
2327 wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
,
2328 wxAuiNotebook::OnTabBeginDrag
)
2329 EVT_COMMAND_RANGE(10000, 10100,
2330 wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
,
2331 wxAuiNotebook::OnTabEndDrag
)
2332 EVT_COMMAND_RANGE(10000, 10100,
2333 wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
,
2334 wxAuiNotebook::OnTabDragMotion
)
2335 EVT_COMMAND_RANGE(10000, 10100,
2336 wxEVT_COMMAND_AUINOTEBOOK_BUTTON
,
2337 wxAuiNotebook::OnTabButton
)
2340 wxAuiNotebook::wxAuiNotebook()
2343 m_tab_id_counter
= 10000;
2345 m_tab_ctrl_height
= 20;
2348 wxAuiNotebook::wxAuiNotebook(wxWindow
*parent
,
2352 long style
) : wxControl(parent
, id
, pos
, size
, style
)
2354 InitNotebook(style
);
2357 bool wxAuiNotebook::Create(wxWindow
* parent
,
2363 if (!wxControl::Create(parent
, id
, pos
, size
, style
))
2366 InitNotebook(style
);
2371 // InitNotebook() contains common initialization
2372 // code called by all constructors
2373 void wxAuiNotebook::InitNotebook(long style
)
2376 m_tab_id_counter
= 10000;
2378 m_tab_ctrl_height
= 20;
2379 m_flags
= (unsigned int)style
;
2381 m_normal_font
= *wxNORMAL_FONT
;
2382 m_selected_font
= *wxNORMAL_FONT
;
2383 m_selected_font
.SetWeight(wxBOLD
);
2385 SetArtProvider(new wxAuiDefaultTabArt
);
2387 m_dummy_wnd
= new wxWindow(this, wxID_ANY
, wxPoint(0,0), wxSize(0,0));
2388 m_dummy_wnd
->SetSize(200, 200);
2389 m_dummy_wnd
->Show(false);
2391 m_mgr
.SetManagedWindow(this);
2393 m_mgr
.AddPane(m_dummy_wnd
,
2394 wxAuiPaneInfo().Name(wxT("dummy")).Bottom().Show(false));
2399 wxAuiNotebook::~wxAuiNotebook()
2404 void wxAuiNotebook::SetArtProvider(wxAuiTabArt
* art
)
2406 m_tabs
.SetArtProvider(art
);
2408 SetTabCtrlHeight(CalculateTabCtrlHeight());
2411 void wxAuiNotebook::SetTabCtrlHeight(int height
)
2413 // if the tab control height needs to change, update
2414 // all of our tab controls with the new height
2415 if (m_tab_ctrl_height
!= height
)
2417 wxAuiTabArt
* art
= m_tabs
.GetArtProvider();
2419 m_tab_ctrl_height
= height
;
2421 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2422 size_t i
, pane_count
= all_panes
.GetCount();
2423 for (i
= 0; i
< pane_count
; ++i
)
2425 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2426 if (pane
.name
== wxT("dummy"))
2428 wxTabFrame
* tab_frame
= (wxTabFrame
*)pane
.window
;
2429 wxAuiTabCtrl
* tabctrl
= tab_frame
->m_tabs
;
2430 tab_frame
->SetTabCtrlHeight(m_tab_ctrl_height
);
2431 tabctrl
->SetArtProvider(art
->Clone());
2432 tab_frame
->DoSizing();
2437 int wxAuiNotebook::CalculateTabCtrlHeight()
2439 // find out new best tab height
2440 wxAuiTabArt
* art
= m_tabs
.GetArtProvider();
2442 return art
->GetBestTabCtrlSize(this, m_tabs
.GetPages());
2446 wxAuiTabArt
* wxAuiNotebook::GetArtProvider() const
2448 return m_tabs
.GetArtProvider();
2451 void wxAuiNotebook::SetWindowStyleFlag(long style
)
2453 wxControl::SetWindowStyleFlag(style
);
2455 m_flags
= (unsigned int)style
;
2457 // if the control is already initialized
2458 if (m_mgr
.GetManagedWindow() == (wxWindow
*)this)
2460 // let all of the tab children know about the new style
2462 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2463 size_t i
, pane_count
= all_panes
.GetCount();
2464 for (i
= 0; i
< pane_count
; ++i
)
2466 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2467 if (pane
.name
== wxT("dummy"))
2469 wxAuiTabCtrl
* tabctrl
= ((wxTabFrame
*)pane
.window
)->m_tabs
;
2470 tabctrl
->SetFlags(m_flags
);
2478 bool wxAuiNotebook::AddPage(wxWindow
* page
,
2479 const wxString
& caption
,
2481 const wxBitmap
& bitmap
)
2483 return InsertPage(GetPageCount(), page
, caption
, select
, bitmap
);
2486 bool wxAuiNotebook::InsertPage(size_t page_idx
,
2488 const wxString
& caption
,
2490 const wxBitmap
& bitmap
)
2492 wxAuiNotebookPage info
;
2494 info
.caption
= caption
;
2495 info
.bitmap
= bitmap
;
2496 info
.active
= false;
2498 // if there are currently no tabs, the first added
2499 // tab must be active
2500 if (m_tabs
.GetPageCount() == 0)
2503 m_tabs
.InsertPage(page
, info
, page_idx
);
2505 wxAuiTabCtrl
* active_tabctrl
= GetActiveTabCtrl();
2506 if (page_idx
>= active_tabctrl
->GetPageCount())
2507 active_tabctrl
->AddPage(page
, info
);
2509 active_tabctrl
->InsertPage(page
, info
, page_idx
);
2511 SetTabCtrlHeight(CalculateTabCtrlHeight());
2513 active_tabctrl
->DoShowHide();
2517 int idx
= m_tabs
.GetIdxFromWindow(page
);
2518 wxASSERT_MSG(idx
!= -1, wxT("Invalid Page index returned on wxAuiNotebook::InsertPage()"));
2527 // DeletePage() removes a tab from the multi-notebook,
2528 // and destroys the window as well
2529 bool wxAuiNotebook::DeletePage(size_t page_idx
)
2531 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
2533 if (!RemovePage(page_idx
))
2536 // actually destroy the window now
2537 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
2539 // delete the child frame with pending delete, as is
2540 // customary with frame windows
2541 if (!wxPendingDelete
.Member(wnd
))
2542 wxPendingDelete
.Append(wnd
);
2554 // RemovePage() removes a tab from the multi-notebook,
2555 // but does not destroy the window
2556 bool wxAuiNotebook::RemovePage(size_t page_idx
)
2558 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
2559 wxWindow
* new_active
= NULL
;
2561 // find out which onscreen tab ctrl owns this tab
2564 if (!FindTab(wnd
, &ctrl
, &ctrl_idx
))
2567 // find a new page and set it as active
2568 int new_idx
= ctrl_idx
+1;
2569 if (new_idx
>= (int)ctrl
->GetPageCount())
2570 new_idx
= ctrl_idx
-1;
2572 if (new_idx
>= 0 && new_idx
< (int)ctrl
->GetPageCount())
2574 new_active
= ctrl
->GetWindowFromIdx(new_idx
);
2578 // set the active page to the first page that
2579 // isn't the one being deleted
2580 size_t i
, page_count
= m_tabs
.GetPageCount();
2581 for (i
= 0; i
< page_count
; ++i
)
2583 wxWindow
* w
= m_tabs
.GetWindowFromIdx(i
);
2586 new_active
= m_tabs
.GetWindowFromIdx(i
);
2592 // remove the tab from main catalog
2593 if (!m_tabs
.RemovePage(wnd
))
2596 // remove the tab from the onscreen tab ctrl
2597 ctrl
->RemovePage(wnd
);
2600 RemoveEmptyTabFrames();
2602 // set new active pane
2606 SetSelection(m_tabs
.GetIdxFromWindow(new_active
));
2612 // GetPageIndex() returns the index of the page, or -1 if the
2613 // page could not be located in the notebook
2614 int wxAuiNotebook::GetPageIndex(wxWindow
* page_wnd
) const
2616 return m_tabs
.GetIdxFromWindow(page_wnd
);
2621 // SetPageText() changes the tab caption of the specified page
2622 bool wxAuiNotebook::SetPageText(size_t page_idx
, const wxString
& text
)
2624 if (page_idx
>= m_tabs
.GetPageCount())
2627 // update our own tab catalog
2628 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2629 page_info
.caption
= text
;
2631 // update what's on screen
2634 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
2636 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
2637 info
.caption
= text
;
2646 bool wxAuiNotebook::SetPageBitmap(size_t page_idx
, const wxBitmap
& bitmap
)
2648 if (page_idx
>= m_tabs
.GetPageCount())
2651 // update our own tab catalog
2652 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2653 page_info
.bitmap
= bitmap
;
2655 // tab height might have changed
2656 SetTabCtrlHeight(CalculateTabCtrlHeight());
2658 // update what's on screen
2661 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
2663 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
2664 info
.bitmap
= bitmap
;
2673 // GetSelection() returns the index of the currently active page
2674 int wxAuiNotebook::GetSelection() const
2679 // SetSelection() sets the currently active page
2680 size_t wxAuiNotebook::SetSelection(size_t new_page
)
2682 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(new_page
);
2686 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2687 evt
.SetSelection(new_page
);
2688 evt
.SetOldSelection(m_curpage
);
2689 evt
.SetEventObject(this);
2690 if (!GetEventHandler()->ProcessEvent(evt
) || evt
.IsAllowed())
2692 int old_curpage
= m_curpage
;
2693 m_curpage
= new_page
;
2695 // program allows the page change
2696 evt
.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
);
2697 (void)GetEventHandler()->ProcessEvent(evt
);
2702 if (FindTab(wnd
, &ctrl
, &ctrl_idx
))
2704 m_tabs
.SetActivePage(wnd
);
2706 ctrl
->SetActivePage(ctrl_idx
);
2713 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2714 size_t i
, pane_count
= all_panes
.GetCount();
2715 for (i
= 0; i
< pane_count
; ++i
)
2717 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2718 if (pane
.name
== wxT("dummy"))
2720 wxAuiTabCtrl
* tabctrl
= ((wxTabFrame
*)pane
.window
)->m_tabs
;
2721 if (tabctrl
!= ctrl
)
2722 tabctrl
->SetSelectedFont(m_normal_font
);
2724 tabctrl
->SetSelectedFont(m_selected_font
);
2737 // GetPageCount() returns the total number of
2738 // pages managed by the multi-notebook
2739 size_t wxAuiNotebook::GetPageCount() const
2741 return m_tabs
.GetPageCount();
2744 // GetPage() returns the wxWindow pointer of the
2746 wxWindow
* wxAuiNotebook::GetPage(size_t page_idx
) const
2748 wxASSERT(page_idx
< m_tabs
.GetPageCount());
2750 return m_tabs
.GetWindowFromIdx(page_idx
);
2753 // DoSizing() performs all sizing operations in each tab control
2754 void wxAuiNotebook::DoSizing()
2756 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2757 size_t i
, pane_count
= all_panes
.GetCount();
2758 for (i
= 0; i
< pane_count
; ++i
)
2760 if (all_panes
.Item(i
).name
== wxT("dummy"))
2763 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2764 tabframe
->DoSizing();
2768 // GetActiveTabCtrl() returns the active tab control. It is
2769 // called to determine which control gets new windows being added
2770 wxAuiTabCtrl
* wxAuiNotebook::GetActiveTabCtrl()
2772 if (m_curpage
>= 0 && m_curpage
< (int)m_tabs
.GetPageCount())
2777 // find the tab ctrl with the current page
2778 if (FindTab(m_tabs
.GetPage(m_curpage
).window
,
2785 // no current page, just find the first tab ctrl
2786 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2787 size_t i
, pane_count
= all_panes
.GetCount();
2788 for (i
= 0; i
< pane_count
; ++i
)
2790 if (all_panes
.Item(i
).name
== wxT("dummy"))
2793 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2794 return tabframe
->m_tabs
;
2797 // If there is no tabframe at all, create one
2798 wxTabFrame
* tabframe
= new wxTabFrame
;
2799 tabframe
->SetTabCtrlHeight(m_tab_ctrl_height
);
2800 tabframe
->m_tabs
= new wxAuiTabCtrl(this,
2805 tabframe
->m_tabs
->SetFlags(m_flags
);
2806 tabframe
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone());
2807 m_mgr
.AddPane(tabframe
,
2808 wxAuiPaneInfo().Center().CaptionVisible(false));
2812 return tabframe
->m_tabs
;
2815 // FindTab() finds the tab control that currently contains the window as well
2816 // as the index of the window in the tab control. It returns true if the
2817 // window was found, otherwise false.
2818 bool wxAuiNotebook::FindTab(wxWindow
* page
, wxAuiTabCtrl
** ctrl
, int* idx
)
2820 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2821 size_t i
, pane_count
= all_panes
.GetCount();
2822 for (i
= 0; i
< pane_count
; ++i
)
2824 if (all_panes
.Item(i
).name
== wxT("dummy"))
2827 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2829 int page_idx
= tabframe
->m_tabs
->GetIdxFromWindow(page
);
2832 *ctrl
= tabframe
->m_tabs
;
2842 void wxAuiNotebook::OnEraseBackground(wxEraseEvent
&)
2846 void wxAuiNotebook::OnSize(wxSizeEvent
&)
2850 void wxAuiNotebook::OnTabClicked(wxCommandEvent
& command_evt
)
2852 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
2854 wxAuiTabCtrl
* ctrl
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2855 wxASSERT(ctrl
!= NULL
);
2857 wxWindow
* wnd
= ctrl
->GetWindowFromIdx(evt
.GetSelection());
2858 wxASSERT(wnd
!= NULL
);
2860 int idx
= m_tabs
.GetIdxFromWindow(wnd
);
2861 wxASSERT(idx
!= -1);
2866 void wxAuiNotebook::OnTabBeginDrag(wxCommandEvent
&)
2871 void wxAuiNotebook::OnTabDragMotion(wxCommandEvent
& evt
)
2873 wxPoint screen_pt
= ::wxGetMousePosition();
2874 wxPoint client_pt
= ScreenToClient(screen_pt
);
2877 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2878 wxAuiTabCtrl
* dest_tabs
= GetTabCtrlFromPoint(client_pt
);
2880 if (dest_tabs
== src_tabs
)
2884 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
2887 // always hide the hint for inner-tabctrl drag
2890 // if tab moving is not allowed, leave
2891 if (!(m_flags
& wxAUI_NB_TAB_MOVE
))
2896 wxPoint pt
= dest_tabs
->ScreenToClient(screen_pt
);
2897 wxWindow
* dest_location_tab
;
2899 // this is an inner-tab drag/reposition
2900 if (dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &dest_location_tab
))
2902 int src_idx
= evt
.GetSelection();
2903 int dest_idx
= dest_tabs
->GetIdxFromWindow(dest_location_tab
);
2905 // prevent jumpy drag
2906 if ((src_idx
== dest_idx
) || dest_idx
== -1 ||
2907 (src_idx
> dest_idx
&& m_last_drag_x
<= pt
.x
) ||
2908 (src_idx
< dest_idx
&& m_last_drag_x
>= pt
.x
))
2910 m_last_drag_x
= pt
.x
;
2915 wxWindow
* src_tab
= dest_tabs
->GetWindowFromIdx(src_idx
);
2916 dest_tabs
->MovePage(src_tab
, dest_idx
);
2917 dest_tabs
->SetActivePage((size_t)dest_idx
);
2918 dest_tabs
->DoShowHide();
2919 dest_tabs
->Refresh();
2920 m_last_drag_x
= pt
.x
;
2928 // if external drag is allowed, check if the tab is being dragged
2929 // over a different wxAuiNotebook control
2930 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
2932 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(screen_pt
);
2934 // if we aren't over any window, stop here
2938 // make sure we are not over the hint window
2939 if (!tab_ctrl
->IsKindOf(CLASSINFO(wxFrame
)))
2943 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
2945 tab_ctrl
= tab_ctrl
->GetParent();
2950 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
2954 wxRect hint_rect
= tab_ctrl
->GetClientRect();
2955 tab_ctrl
->ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
2956 m_mgr
.ShowHint(hint_rect
);
2965 // we are either over a hint window, or not over a tab
2966 // window, and there is no where to drag to, so exit
2973 // if there are less than two panes, split can't happen, so leave
2974 if (m_tabs
.GetPageCount() < 2)
2977 // if tab moving is not allowed, leave
2978 if (!(m_flags
& wxAUI_NB_TAB_SPLIT
))
2984 src_tabs
->SetCursor(wxCursor(wxCURSOR_SIZING
));
2990 wxRect hint_rect
= dest_tabs
->GetRect();
2991 ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
2992 m_mgr
.ShowHint(hint_rect
);
2996 m_mgr
.DrawHintRect(m_dummy_wnd
, client_pt
, zero
);
3002 void wxAuiNotebook::OnTabEndDrag(wxCommandEvent
& command_evt
)
3004 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
3009 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3010 wxAuiTabCtrl
* dest_tabs
= NULL
;
3013 // set cursor back to an arrow
3014 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
3017 // get the mouse position, which will be used to determine the drop point
3018 wxPoint mouse_screen_pt
= ::wxGetMousePosition();
3019 wxPoint mouse_client_pt
= ScreenToClient(mouse_screen_pt
);
3023 // check for an external move
3024 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
3026 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(mouse_screen_pt
);
3030 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
3032 tab_ctrl
= tab_ctrl
->GetParent();
3037 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
3041 // find out from the destination control
3042 // if it's ok to drop this tab here
3043 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
, m_windowId
);
3044 e
.SetSelection(evt
.GetSelection());
3045 e
.SetOldSelection(evt
.GetSelection());
3046 e
.SetEventObject(this);
3047 e
.SetDragSource(this);
3048 e
.Veto(); // dropping must be explicitly approved by control owner
3050 nb
->GetEventHandler()->ProcessEvent(e
);
3054 // no answer or negative answer
3060 int src_idx
= evt
.GetSelection();
3061 wxWindow
* src_page
= src_tabs
->GetWindowFromIdx(src_idx
);
3063 // get main index of the page
3064 int main_idx
= m_tabs
.GetIdxFromWindow(src_page
);
3066 // make a copy of the page info
3067 wxAuiNotebookPage page_info
= m_tabs
.GetPage((size_t)main_idx
);
3069 // remove the page from the source notebook
3070 RemovePage(main_idx
);
3072 // reparent the page
3073 src_page
->Reparent(nb
);
3076 // found out the insert idx
3077 wxAuiTabCtrl
* dest_tabs
= (wxAuiTabCtrl
*)tab_ctrl
;
3078 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
3080 wxWindow
* target
= NULL
;
3081 int insert_idx
= -1;
3082 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
3085 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
3089 // add the page to the new notebook
3090 if (insert_idx
== -1)
3091 insert_idx
= dest_tabs
->GetPageCount();
3092 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
3093 nb
->m_tabs
.AddPage(page_info
.window
, page_info
);
3096 dest_tabs
->DoShowHide();
3097 dest_tabs
->Refresh();
3099 // set the selection in the destination tab control
3100 nb
->SetSelection(nb
->m_tabs
.GetIdxFromWindow(page_info
.window
));
3110 // only perform a tab split if it's allowed
3111 if ((m_flags
& wxAUI_NB_TAB_SPLIT
) && m_tabs
.GetPageCount() >= 2)
3113 // If the pointer is in an existing tab frame, do a tab insert
3114 wxWindow
* hit_wnd
= ::wxFindWindowAtPoint(mouse_screen_pt
);
3115 wxTabFrame
* tab_frame
= (wxTabFrame
*)GetTabFrameFromTabCtrl(hit_wnd
);
3116 int insert_idx
= -1;
3119 dest_tabs
= tab_frame
->m_tabs
;
3121 if (dest_tabs
== src_tabs
)
3125 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
3126 wxWindow
* target
= NULL
;
3127 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
3130 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
3136 wxRect rect
= m_mgr
.CalculateHintRect(m_dummy_wnd
,
3141 // there is no suitable drop location here, exit out
3146 // If there is no tabframe at all, create one
3147 wxTabFrame
* new_tabs
= new wxTabFrame
;
3148 new_tabs
->SetTabCtrlHeight(m_tab_ctrl_height
);
3149 new_tabs
->m_tabs
= new wxAuiTabCtrl(this,
3154 new_tabs
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone());
3155 new_tabs
->m_tabs
->SetFlags(m_flags
);
3157 m_mgr
.AddPane(new_tabs
,
3158 wxAuiPaneInfo().Bottom().CaptionVisible(false),
3161 dest_tabs
= new_tabs
->m_tabs
;
3166 // remove the page from the source tabs
3167 wxAuiNotebookPage page_info
= src_tabs
->GetPage(evt
.GetSelection());
3168 page_info
.active
= false;
3169 src_tabs
->RemovePage(page_info
.window
);
3170 if (src_tabs
->GetPageCount() > 0)
3172 src_tabs
->SetActivePage((size_t)0);
3173 src_tabs
->DoShowHide();
3174 src_tabs
->Refresh();
3179 // add the page to the destination tabs
3180 if (insert_idx
== -1)
3181 insert_idx
= dest_tabs
->GetPageCount();
3182 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
3184 if (src_tabs
->GetPageCount() == 0)
3186 RemoveEmptyTabFrames();
3190 dest_tabs
->DoShowHide();
3191 dest_tabs
->Refresh();
3193 SetSelection(m_tabs
.GetIdxFromWindow(page_info
.window
));
3199 wxAuiTabCtrl
* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint
& pt
)
3201 // if we've just removed the last tab from the source
3202 // tab set, the remove the tab control completely
3203 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
3204 size_t i
, pane_count
= all_panes
.GetCount();
3205 for (i
= 0; i
< pane_count
; ++i
)
3207 if (all_panes
.Item(i
).name
== wxT("dummy"))
3210 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3211 if (tabframe
->m_tab_rect
.Contains(pt
))
3212 return tabframe
->m_tabs
;
3218 wxWindow
* wxAuiNotebook::GetTabFrameFromTabCtrl(wxWindow
* tab_ctrl
)
3220 // if we've just removed the last tab from the source
3221 // tab set, the remove the tab control completely
3222 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
3223 size_t i
, pane_count
= all_panes
.GetCount();
3224 for (i
= 0; i
< pane_count
; ++i
)
3226 if (all_panes
.Item(i
).name
== wxT("dummy"))
3229 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3230 if (tabframe
->m_tabs
== tab_ctrl
)
3239 void wxAuiNotebook::RemoveEmptyTabFrames()
3241 // if we've just removed the last tab from the source
3242 // tab set, the remove the tab control completely
3243 wxAuiPaneInfoArray all_panes
= m_mgr
.GetAllPanes();
3244 size_t i
, pane_count
= all_panes
.GetCount();
3245 for (i
= 0; i
< pane_count
; ++i
)
3247 if (all_panes
.Item(i
).name
== wxT("dummy"))
3250 wxTabFrame
* tab_frame
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3251 if (tab_frame
->m_tabs
->GetPageCount() == 0)
3253 m_mgr
.DetachPane(tab_frame
);
3255 // use pending delete because sometimes during
3256 // window closing, refreshs are pending
3257 if (!wxPendingDelete
.Member(tab_frame
->m_tabs
))
3258 wxPendingDelete
.Append(tab_frame
->m_tabs
);
3259 //tab_frame->m_tabs->Destroy();
3266 // check to see if there is still a center pane;
3267 // if there isn't, make a frame the center pane
3268 wxAuiPaneInfoArray panes
= m_mgr
.GetAllPanes();
3269 pane_count
= panes
.GetCount();
3270 wxWindow
* first_good
= NULL
;
3271 bool center_found
= false;
3272 for (i
= 0; i
< pane_count
; ++i
)
3274 if (panes
.Item(i
).name
== wxT("dummy"))
3276 if (panes
.Item(i
).dock_direction
== wxAUI_DOCK_CENTRE
)
3277 center_found
= true;
3279 first_good
= panes
.Item(i
).window
;
3282 if (!center_found
&& first_good
)
3284 m_mgr
.GetPane(first_good
).Centre();
3290 void wxAuiNotebook::OnChildFocus(wxChildFocusEvent
& evt
)
3292 int idx
= m_tabs
.GetIdxFromWindow(evt
.GetWindow());
3293 if (idx
!= -1 && idx
!= m_curpage
)
3300 void wxAuiNotebook::OnTabButton(wxCommandEvent
& command_evt
)
3302 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
3303 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3305 int button_id
= evt
.GetInt();
3307 if (button_id
== wxAUI_BUTTON_CLOSE
)
3309 int selection
= tabs
->GetActivePage();
3311 if (selection
!= -1)
3313 wxWindow
* close_wnd
= tabs
->GetWindowFromIdx(selection
);
3316 // ask owner if it's ok to close the tab
3317 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
, m_windowId
);
3318 e
.SetSelection(m_tabs
.GetIdxFromWindow(close_wnd
));
3319 e
.SetOldSelection(evt
.GetSelection());
3320 e
.SetEventObject(this);
3321 GetEventHandler()->ProcessEvent(e
);
3326 if (close_wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
3332 int main_idx
= m_tabs
.GetIdxFromWindow(close_wnd
);
3333 DeletePage(main_idx
);