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" 
  31 #include "wx/aui/tabmdi.h" 
  32 #include "wx/dcbuffer.h" 
  34 #include "wx/renderer.h" 
  37 #include "wx/osx/carbon/private.h" 
  40 #include "wx/arrimpl.cpp" 
  41 WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray
) 
  42 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray
) 
  44 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
) 
  45 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED
) 
  46 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
) 
  47 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
) 
  48 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
) 
  49 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
) 
  50 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
) 
  51 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
) 
  52 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
) 
  53 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
) 
  54 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE
) 
  55 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
) 
  56 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
) 
  57 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
) 
  58 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
) 
  60 IMPLEMENT_CLASS(wxAuiNotebook
, wxControl
) 
  61 IMPLEMENT_CLASS(wxAuiTabCtrl
, wxControl
) 
  62 IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent
, wxEvent
) 
  68 // these functions live in dockart.cpp -- they'll eventually 
  69 // be moved to a new utility cpp file 
  71 wxColor 
wxAuiStepColour(const wxColor
& c
, int percent
); 
  73 wxBitmap 
wxAuiBitmapFromBits(const unsigned char bits
[], int w
, int h
, 
  74                              const wxColour
& color
); 
  76 wxString 
wxAuiChopText(wxDC
& dc
, const wxString
& text
, int max_size
); 
  78 static void DrawButtons(wxDC
& dc
, 
  81                         const wxColour
& bkcolour
, 
  86     if (button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
  92     if (button_state 
== wxAUI_BUTTON_STATE_HOVER 
|| 
  93         button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
  95         dc
.SetBrush(wxBrush(wxAuiStepColour(bkcolour
, 120))); 
  96         dc
.SetPen(wxPen(wxAuiStepColour(bkcolour
, 75))); 
  98         // draw the background behind the button 
  99         dc
.DrawRectangle(rect
.x
, rect
.y
, 15, 15); 
 102     // draw the button itself 
 103     dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true); 
 106 static void IndentPressedBitmap(wxRect
* rect
, int button_state
) 
 108     if (button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
 117 // -- GUI helper classes and functions -- 
 119 class wxAuiCommandCapture 
: public wxEvtHandler
 
 123     wxAuiCommandCapture() { m_last_id 
= 0; } 
 124     int GetCommandId() const { return m_last_id
; } 
 126     bool ProcessEvent(wxEvent
& evt
) 
 128         if (evt
.GetEventType() == wxEVT_COMMAND_MENU_SELECTED
) 
 130             m_last_id 
= evt
.GetId(); 
 134         if (GetNextHandler()) 
 135             return GetNextHandler()->ProcessEvent(evt
); 
 147 #if defined( __WXMAC__ ) 
 148  static unsigned char close_bits
[]={ 
 149      0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3, 
 150      0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3, 
 151      0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF }; 
 152 #elif defined( __WXGTK__) 
 153  static unsigned char close_bits
[]={ 
 154      0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8, 
 155      0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef, 
 156      0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 
 158  static unsigned char close_bits
[]={ 
 159      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9, 
 160      0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3, 
 161      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 164 static unsigned char left_bits
[] = { 
 165    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe, 
 166    0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe, 
 167    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 169 static unsigned char right_bits
[] = { 
 170    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff, 
 171    0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff, 
 172    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 174 static unsigned char list_bits
[] = { 
 175    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
 176    0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff, 
 177    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 184 // -- wxAuiDefaultTabArt class implementation -- 
 186 wxAuiDefaultTabArt::wxAuiDefaultTabArt() 
 188     m_normal_font 
= *wxNORMAL_FONT
; 
 189     m_selected_font 
= *wxNORMAL_FONT
; 
 190     m_selected_font
.SetWeight(wxBOLD
); 
 191     m_measuring_font 
= m_selected_font
; 
 193     m_fixed_tab_width 
= 100; 
 194     m_tab_ctrl_height 
= 0; 
 197     wxColor base_colour 
= wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground
)); 
 199     wxColor base_colour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 202     // the base_colour is too pale to use as our base colour, 
 203     // so darken it a bit -- 
 204     if ((255-base_colour
.Red()) + 
 205         (255-base_colour
.Green()) + 
 206         (255-base_colour
.Blue()) < 60) 
 208         base_colour 
= wxAuiStepColour(base_colour
, 92); 
 211     m_base_colour 
= base_colour
; 
 212     wxColor border_colour 
= wxAuiStepColour(base_colour
, 75); 
 214     m_border_pen 
= wxPen(border_colour
); 
 215     m_base_colour_pen 
= wxPen(m_base_colour
); 
 216     m_base_colour_brush 
= wxBrush(m_base_colour
); 
 218     m_active_close_bmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
); 
 219     m_disabled_close_bmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128)); 
 221     m_active_left_bmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
); 
 222     m_disabled_left_bmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128)); 
 224     m_active_right_bmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
); 
 225     m_disabled_right_bmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128)); 
 227     m_active_windowlist_bmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
); 
 228     m_disabled_windowlist_bmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128)); 
 233 wxAuiDefaultTabArt::~wxAuiDefaultTabArt() 
 237 wxAuiTabArt
* wxAuiDefaultTabArt::Clone() 
 239     wxAuiDefaultTabArt
* art 
= new wxAuiDefaultTabArt
; 
 240     art
->SetNormalFont(m_normal_font
); 
 241     art
->SetSelectedFont(m_selected_font
); 
 242     art
->SetMeasuringFont(m_measuring_font
); 
 247 void wxAuiDefaultTabArt::SetFlags(unsigned int flags
) 
 252 void wxAuiDefaultTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
, 
 255     m_fixed_tab_width 
= 100; 
 257     int tot_width 
= (int)tab_ctrl_size
.x 
- GetIndentSize() - 4; 
 259     if (m_flags 
& wxAUI_NB_CLOSE_BUTTON
) 
 260         tot_width 
-= m_active_close_bmp
.GetWidth(); 
 261     if (m_flags 
& wxAUI_NB_WINDOWLIST_BUTTON
) 
 262         tot_width 
-= m_active_windowlist_bmp
.GetWidth(); 
 266         m_fixed_tab_width 
= tot_width
/(int)tab_count
; 
 270     if (m_fixed_tab_width 
< 100) 
 271         m_fixed_tab_width 
= 100; 
 273     if (m_fixed_tab_width 
> tot_width
/2) 
 274         m_fixed_tab_width 
= tot_width
/2; 
 276     if (m_fixed_tab_width 
> 220) 
 277         m_fixed_tab_width 
= 220; 
 279     m_tab_ctrl_height 
= tab_ctrl_size
.y
; 
 283 void wxAuiDefaultTabArt::DrawBackground(wxDC
& dc
, 
 284                                         wxWindow
* WXUNUSED(wnd
), 
 289     wxColor top_color       
= wxAuiStepColour(m_base_colour
, 90); 
 290     wxColor bottom_color   
= wxAuiStepColour(m_base_colour
, 170); 
 293    if (m_flags 
&wxAUI_NB_BOTTOM
) 
 294        r 
= wxRect(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
); 
 295    // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 296    // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 297    else //for wxAUI_NB_TOP 
 298        r 
= wxRect(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
-3); 
 300     dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
); 
 305    dc
.SetPen(m_border_pen
); 
 306    int y 
= rect
.GetHeight(); 
 307    int w 
= rect
.GetWidth(); 
 309    if (m_flags 
&wxAUI_NB_BOTTOM
) 
 311        dc
.SetBrush(wxBrush(bottom_color
)); 
 312        dc
.DrawRectangle(-1, 0, w
+2, 4); 
 314    // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 315    // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 316    else //for wxAUI_NB_TOP 
 318        dc
.SetBrush(m_base_colour_brush
); 
 319        dc
.DrawRectangle(-1, y
-4, w
+2, 4); 
 324 // DrawTab() draws an individual tab. 
 327 // in_rect  - rectangle the tab should be confined to 
 328 // caption  - tab's caption 
 329 // active   - whether or not the tab is active 
 330 // out_rect - actual output rectangle 
 331 // x_extent - the advance x; where the next tab should start 
 333 void wxAuiDefaultTabArt::DrawTab(wxDC
& dc
, 
 335                                  const wxAuiNotebookPage
& page
, 
 336                                  const wxRect
& in_rect
, 
 337                                  int close_button_state
, 
 338                                  wxRect
* out_tab_rect
, 
 339                                  wxRect
* out_button_rect
, 
 342     wxCoord normal_textx
, normal_texty
; 
 343     wxCoord selected_textx
, selected_texty
; 
 346     // if the caption is empty, measure some temporary text 
 347     wxString caption 
= page
.caption
; 
 351     dc
.SetFont(m_selected_font
); 
 352     dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
); 
 354     dc
.SetFont(m_normal_font
); 
 355     dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
); 
 357     // figure out the size of the tab 
 358     wxSize tab_size 
= GetTabSize(dc
, 
 366     wxCoord tab_height 
= m_tab_ctrl_height 
- 3; 
 367     wxCoord tab_width 
= tab_size
.x
; 
 368     wxCoord tab_x 
= in_rect
.x
; 
 369     wxCoord tab_y 
= in_rect
.y 
+ in_rect
.height 
- tab_height
; 
 372     caption 
= page
.caption
; 
 375     // select pen, brush and font for the tab to be drawn 
 379         dc
.SetFont(m_selected_font
); 
 380         texty 
= selected_texty
; 
 384         dc
.SetFont(m_normal_font
); 
 385         texty 
= normal_texty
; 
 389     // create points that will make the tab outline 
 391     int clip_width 
= tab_width
; 
 392     if (tab_x 
+ clip_width 
> in_rect
.x 
+ in_rect
.width
) 
 393         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     // FIXME: these ports don't provide wxRegion ctor from array of points 
 405 #if !defined(__WXDFB__) && !defined(__WXCOCOA__) 
 406     // set the clipping region for the tab -- 
 407     wxRegion clipping_region(WXSIZEOF(clip_points), clip_points); 
 408     dc.SetClippingRegion(clipping_region); 
 409 #endif // !wxDFB && !wxCocoa 
 411     // since the above code above doesn't play well with WXDFB or WXCOCOA, 
 412     // we'll just use a rectangle for the clipping region for now -- 
 413     dc
.SetClippingRegion(tab_x
, tab_y
, clip_width
+1, tab_height
-3); 
 416     wxPoint border_points
[6]; 
 417     if (m_flags 
&wxAUI_NB_BOTTOM
) 
 419         border_points
[0] = wxPoint(tab_x
,             tab_y
); 
 420         border_points
[1] = wxPoint(tab_x
,             tab_y
+tab_height
-6); 
 421         border_points
[2] = wxPoint(tab_x
+2,           tab_y
+tab_height
-4); 
 422         border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
+tab_height
-4); 
 423         border_points
[4] = wxPoint(tab_x
+tab_width
,   tab_y
+tab_height
-6); 
 424         border_points
[5] = wxPoint(tab_x
+tab_width
,   tab_y
); 
 426     else //if (m_flags & wxAUI_NB_TOP) {} 
 428         border_points
[0] = wxPoint(tab_x
,             tab_y
+tab_height
-4); 
 429         border_points
[1] = wxPoint(tab_x
,             tab_y
+2); 
 430         border_points
[2] = wxPoint(tab_x
+2,           tab_y
); 
 431         border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
); 
 432         border_points
[4] = wxPoint(tab_x
+tab_width
,   tab_y
+2); 
 433         border_points
[5] = wxPoint(tab_x
+tab_width
,   tab_y
+tab_height
-4); 
 435     // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 436     // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 438     int drawn_tab_yoff 
= border_points
[1].y
; 
 439     int drawn_tab_height 
= border_points
[0].y 
- border_points
[1].y
; 
 446         // draw base background color 
 447         wxRect 
r(tab_x
, tab_y
, tab_width
, tab_height
); 
 448         dc
.SetPen(m_base_colour_pen
); 
 449         dc
.SetBrush(m_base_colour_brush
); 
 450         dc
.DrawRectangle(r
.x
+1, r
.y
+1, r
.width
-1, r
.height
-4); 
 452         // this white helps fill out the gradient at the top of the tab 
 453         dc
.SetPen(*wxWHITE_PEN
); 
 454         dc
.SetBrush(*wxWHITE_BRUSH
); 
 455         dc
.DrawRectangle(r
.x
+2, r
.y
+1, r
.width
-3, r
.height
-4); 
 457         // these two points help the rounded corners appear more antialiased 
 458         dc
.SetPen(m_base_colour_pen
); 
 459         dc
.DrawPoint(r
.x
+2, r
.y
+1); 
 460         dc
.DrawPoint(r
.x
+r
.width
-2, r
.y
+1); 
 462         // set rectangle down a bit for gradient drawing 
 463         r
.SetHeight(r
.GetHeight()/2); 
 469         // draw gradient background 
 470         wxColor top_color 
= *wxWHITE
; 
 471         wxColor bottom_color 
= m_base_colour
; 
 472         dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
); 
 478         wxRect 
r(tab_x
, tab_y
+1, tab_width
, tab_height
-3); 
 480         // start the gradent up a bit and leave the inside border inset 
 481         // by a pixel for a 3D look.  Only the top half of the inactive 
 482         // tab will have a slight gradient 
 489         // -- draw top gradient fill for glossy look 
 490         wxColor top_color 
= m_base_colour
; 
 491         wxColor bottom_color 
= wxAuiStepColour(top_color
, 160); 
 492         dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
); 
 497         // -- draw bottom fill for glossy look 
 498         top_color 
= m_base_colour
; 
 499         bottom_color 
= m_base_colour
; 
 500         dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
); 
 504     dc
.SetPen(m_border_pen
); 
 505     dc
.SetBrush(*wxTRANSPARENT_BRUSH
); 
 506     dc
.DrawPolygon(WXSIZEOF(border_points
), border_points
); 
 508     // there are two horizontal grey lines at the bottom of the tab control, 
 509     // this gets rid of the top one of those lines in the tab control 
 512         if (m_flags 
&wxAUI_NB_BOTTOM
) 
 513             dc
.SetPen(wxPen(wxColour(wxAuiStepColour(m_base_colour
, 170)))); 
 514         // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 515         // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 516         else //for wxAUI_NB_TOP 
 517             dc
.SetPen(m_base_colour_pen
); 
 518         dc
.DrawLine(border_points
[0].x
+1, 
 525     int text_offset 
= tab_x 
+ 8; 
 526     int close_button_width 
= 0; 
 527     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
 529         close_button_width 
= m_active_close_bmp
.GetWidth(); 
 532     int bitmap_offset 
= 0; 
 533     if (page
.bitmap
.IsOk()) 
 535         bitmap_offset 
= tab_x 
+ 8; 
 538         dc
.DrawBitmap(page
.bitmap
, 
 540                       drawn_tab_yoff 
+ (drawn_tab_height
/2) - (page
.bitmap
.GetHeight()/2), 
 543         text_offset 
= bitmap_offset 
+ page
.bitmap
.GetWidth(); 
 544         text_offset 
+= 3; // bitmap padding 
 549         text_offset 
= tab_x 
+ 8; 
 553     wxString draw_text 
= wxAuiChopText(dc
, 
 555                           tab_width 
- (text_offset
-tab_x
) - close_button_width
); 
 558     dc
.DrawText(draw_text
, 
 560                 drawn_tab_yoff 
+ (drawn_tab_height
)/2 - (texty
/2) - 1); 
 562     // draw focus rectangle 
 563     if (page
.active 
&& (wnd
->FindFocus() == wnd
)) 
 565         wxRect 
focusRectText(text_offset
, (drawn_tab_yoff 
+ (drawn_tab_height
)/2 - (texty
/2) - 1), 
 566             selected_textx
, selected_texty
); 
 569         wxRect focusRectBitmap
; 
 571         if (page
.bitmap
.IsOk()) 
 572             focusRectBitmap 
= wxRect(bitmap_offset
, drawn_tab_yoff 
+ (drawn_tab_height
/2) - (page
.bitmap
.GetHeight()/2), 
 573                                             page
.bitmap
.GetWidth(), page
.bitmap
.GetHeight()); 
 575         if (page
.bitmap
.IsOk() && draw_text
.IsEmpty()) 
 576             focusRect 
= focusRectBitmap
; 
 577         else if (!page
.bitmap
.IsOk() && !draw_text
.IsEmpty()) 
 578             focusRect 
= focusRectText
; 
 579         else if (page
.bitmap
.IsOk() && !draw_text
.IsEmpty()) 
 580             focusRect 
= focusRectText
.Union(focusRectBitmap
); 
 582         focusRect
.Inflate(2, 2); 
 584         wxRendererNative::Get().DrawFocusRect(wnd
, dc
, focusRect
, 0); 
 587     // draw close button if necessary 
 588     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
 590         wxBitmap bmp 
= m_disabled_close_bmp
; 
 592         if (close_button_state 
== wxAUI_BUTTON_STATE_HOVER 
|| 
 593             close_button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
 595             bmp 
= m_active_close_bmp
; 
 598         wxRect 
rect(tab_x 
+ tab_width 
- close_button_width 
- 1, 
 599                     tab_y 
+ (tab_height
/2) - (bmp
.GetHeight()/2), 
 602         IndentPressedBitmap(&rect
, close_button_state
); 
 603         dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true); 
 605         *out_button_rect 
= rect
; 
 608     *out_tab_rect 
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
); 
 610     dc
.DestroyClippingRegion(); 
 613 int wxAuiDefaultTabArt::GetIndentSize() 
 618 wxSize 
wxAuiDefaultTabArt::GetTabSize(wxDC
& dc
, 
 619                                       wxWindow
* WXUNUSED(wnd
), 
 620                                       const wxString
& caption
, 
 621                                       const wxBitmap
& bitmap
, 
 622                                       bool WXUNUSED(active
), 
 623                                       int close_button_state
, 
 626     wxCoord measured_textx
, measured_texty
, tmp
; 
 628     dc
.SetFont(m_measuring_font
); 
 629     dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
); 
 631     dc
.GetTextExtent(wxT("ABCDEFXj"), &tmp
, &measured_texty
); 
 633     // add padding around the text 
 634     wxCoord tab_width 
= measured_textx
; 
 635     wxCoord tab_height 
= measured_texty
; 
 637     // if the close button is showing, add space for it 
 638     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
 639         tab_width 
+= m_active_close_bmp
.GetWidth() + 3; 
 641     // if there's a bitmap, add space for it 
 644         tab_width 
+= bitmap
.GetWidth(); 
 645         tab_width 
+= 3; // right side bitmap padding 
 646         tab_height 
= wxMax(tab_height
, bitmap
.GetHeight()); 
 653     if (m_flags 
& wxAUI_NB_TAB_FIXED_WIDTH
) 
 655         tab_width 
= m_fixed_tab_width
; 
 658     *x_extent 
= tab_width
; 
 660     return wxSize(tab_width
, tab_height
); 
 664 void wxAuiDefaultTabArt::DrawButton(wxDC
& dc
, 
 665                                     wxWindow
* WXUNUSED(wnd
), 
 666                                     const wxRect
& in_rect
, 
 677         case wxAUI_BUTTON_CLOSE
: 
 678             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 679                 bmp 
= m_disabled_close_bmp
; 
 681                 bmp 
= m_active_close_bmp
; 
 683         case wxAUI_BUTTON_LEFT
: 
 684             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 685                 bmp 
= m_disabled_left_bmp
; 
 687                 bmp 
= m_active_left_bmp
; 
 689         case wxAUI_BUTTON_RIGHT
: 
 690             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 691                 bmp 
= m_disabled_right_bmp
; 
 693                 bmp 
= m_active_right_bmp
; 
 695         case wxAUI_BUTTON_WINDOWLIST
: 
 696             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 697                 bmp 
= m_disabled_windowlist_bmp
; 
 699                 bmp 
= m_active_windowlist_bmp
; 
 709     if (orientation 
== wxLEFT
) 
 711         rect
.SetX(in_rect
.x
); 
 712         rect
.SetY(((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2)); 
 713         rect
.SetWidth(bmp
.GetWidth()); 
 714         rect
.SetHeight(bmp
.GetHeight()); 
 718         rect 
= wxRect(in_rect
.x 
+ in_rect
.width 
- bmp
.GetWidth(), 
 719                       ((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2), 
 720                       bmp
.GetWidth(), bmp
.GetHeight()); 
 723     IndentPressedBitmap(&rect
, button_state
); 
 724     dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true); 
 729 int wxAuiDefaultTabArt::ShowDropDown(wxWindow
* wnd
, 
 730                                      const wxAuiNotebookPageArray
& pages
, 
 735     size_t i
, count 
= pages
.GetCount(); 
 736     for (i 
= 0; i 
< count
; ++i
) 
 738         const wxAuiNotebookPage
& page 
= pages
.Item(i
); 
 739         wxString caption 
= page
.caption
; 
 741         // if there is no caption, make it a space.  This will prevent 
 742         // an assert in the menu code. 
 743         if (caption
.IsEmpty()) 
 746         menuPopup
.AppendCheckItem(1000+i
, caption
); 
 749     if (active_idx 
!= -1) 
 751         menuPopup
.Check(1000+active_idx
, true); 
 754     // find out where to put the popup menu of window items 
 755     wxPoint pt 
= ::wxGetMousePosition(); 
 756     pt 
= wnd
->ScreenToClient(pt
); 
 758     // find out the screen coordinate at the bottom of the tab ctrl 
 759     wxRect cli_rect 
= wnd
->GetClientRect(); 
 760     pt
.y 
= cli_rect
.y 
+ cli_rect
.height
; 
 762     wxAuiCommandCapture
* cc 
= new wxAuiCommandCapture
; 
 763     wnd
->PushEventHandler(cc
); 
 764     wnd
->PopupMenu(&menuPopup
, pt
); 
 765     int command 
= cc
->GetCommandId(); 
 766     wnd
->PopEventHandler(true); 
 774 int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow
* wnd
, 
 775                                            const wxAuiNotebookPageArray
& pages
, 
 776                                            const wxSize
& required_bmp_size
) 
 779     dc
.SetFont(m_measuring_font
); 
 781     // sometimes a standard bitmap size needs to be enforced, especially 
 782     // if some tabs have bitmaps and others don't.  This is important because 
 783     // it prevents the tab control from resizing when tabs are added. 
 784     wxBitmap measure_bmp
; 
 785     if (required_bmp_size
.IsFullySpecified()) 
 787         measure_bmp
.Create(required_bmp_size
.x
, 
 788                            required_bmp_size
.y
); 
 793     size_t i
, page_count 
= pages
.GetCount(); 
 794     for (i 
= 0; i 
< page_count
; ++i
) 
 796         wxAuiNotebookPage
& page 
= pages
.Item(i
); 
 799         if (measure_bmp
.IsOk()) 
 804         // we don't use the caption text because we don't 
 805         // want tab heights to be different in the case 
 806         // of a very short piece of text on one tab and a very 
 807         // tall piece of text on another tab 
 809         wxSize s 
= GetTabSize(dc
, 
 814                               wxAUI_BUTTON_STATE_HIDDEN
, 
 817         max_y 
= wxMax(max_y
, s
.y
); 
 823 void wxAuiDefaultTabArt::SetNormalFont(const wxFont
& font
) 
 825     m_normal_font 
= font
; 
 828 void wxAuiDefaultTabArt::SetSelectedFont(const wxFont
& font
) 
 830     m_selected_font 
= font
; 
 833 void wxAuiDefaultTabArt::SetMeasuringFont(const wxFont
& font
) 
 835     m_measuring_font 
= font
; 
 839 // -- wxAuiSimpleTabArt class implementation -- 
 841 wxAuiSimpleTabArt::wxAuiSimpleTabArt() 
 843     m_normal_font 
= *wxNORMAL_FONT
; 
 844     m_selected_font 
= *wxNORMAL_FONT
; 
 845     m_selected_font
.SetWeight(wxBOLD
); 
 846     m_measuring_font 
= m_selected_font
; 
 849     m_fixed_tab_width 
= 100; 
 851     wxColour base_colour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 853     wxColour background_colour 
= base_colour
; 
 854     wxColour normaltab_colour 
= base_colour
; 
 855     wxColour selectedtab_colour 
= *wxWHITE
; 
 857     m_bkbrush 
= wxBrush(background_colour
); 
 858     m_normal_bkbrush 
= wxBrush(normaltab_colour
); 
 859     m_normal_bkpen 
= wxPen(normaltab_colour
); 
 860     m_selected_bkbrush 
= wxBrush(selectedtab_colour
); 
 861     m_selected_bkpen 
= wxPen(selectedtab_colour
); 
 863     m_active_close_bmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
); 
 864     m_disabled_close_bmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128)); 
 866     m_active_left_bmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
); 
 867     m_disabled_left_bmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128)); 
 869     m_active_right_bmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
); 
 870     m_disabled_right_bmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128)); 
 872     m_active_windowlist_bmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
); 
 873     m_disabled_windowlist_bmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128)); 
 877 wxAuiSimpleTabArt::~wxAuiSimpleTabArt() 
 881 wxAuiTabArt
* wxAuiSimpleTabArt::Clone() 
 883     return static_cast<wxAuiTabArt
*>(new wxAuiSimpleTabArt
); 
 887 void wxAuiSimpleTabArt::SetFlags(unsigned int flags
) 
 892 void wxAuiSimpleTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
, 
 895     m_fixed_tab_width 
= 100; 
 897     int tot_width 
= (int)tab_ctrl_size
.x 
- GetIndentSize() - 4; 
 899     if (m_flags 
& wxAUI_NB_CLOSE_BUTTON
) 
 900         tot_width 
-= m_active_close_bmp
.GetWidth(); 
 901     if (m_flags 
& wxAUI_NB_WINDOWLIST_BUTTON
) 
 902         tot_width 
-= m_active_windowlist_bmp
.GetWidth(); 
 906         m_fixed_tab_width 
= tot_width
/(int)tab_count
; 
 910     if (m_fixed_tab_width 
< 100) 
 911         m_fixed_tab_width 
= 100; 
 913     if (m_fixed_tab_width 
> tot_width
/2) 
 914         m_fixed_tab_width 
= tot_width
/2; 
 916     if (m_fixed_tab_width 
> 220) 
 917         m_fixed_tab_width 
= 220; 
 920 void wxAuiSimpleTabArt::DrawBackground(wxDC
& dc
, 
 921                                        wxWindow
* WXUNUSED(wnd
), 
 925     dc
.SetBrush(m_bkbrush
); 
 926     dc
.SetPen(*wxTRANSPARENT_PEN
); 
 927     dc
.DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2); 
 930     dc
.SetPen(*wxGREY_PEN
); 
 931     dc
.DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1); 
 935 // DrawTab() draws an individual tab. 
 938 // in_rect  - rectangle the tab should be confined to 
 939 // caption  - tab's caption 
 940 // active   - whether or not the tab is active 
 941 // out_rect - actual output rectangle 
 942 // x_extent - the advance x; where the next tab should start 
 944 void wxAuiSimpleTabArt::DrawTab(wxDC
& dc
, 
 946                                 const wxAuiNotebookPage
& page
, 
 947                                 const wxRect
& in_rect
, 
 948                                 int close_button_state
, 
 949                                 wxRect
* out_tab_rect
, 
 950                                 wxRect
* out_button_rect
, 
 953     wxCoord normal_textx
, normal_texty
; 
 954     wxCoord selected_textx
, selected_texty
; 
 955     wxCoord textx
, texty
; 
 957     // if the caption is empty, measure some temporary text 
 958     wxString caption 
= page
.caption
; 
 962     dc
.SetFont(m_selected_font
); 
 963     dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
); 
 965     dc
.SetFont(m_normal_font
); 
 966     dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
); 
 968     // figure out the size of the tab 
 969     wxSize tab_size 
= GetTabSize(dc
, 
 977     wxCoord tab_height 
= tab_size
.y
; 
 978     wxCoord tab_width 
= tab_size
.x
; 
 979     wxCoord tab_x 
= in_rect
.x
; 
 980     wxCoord tab_y 
= in_rect
.y 
+ in_rect
.height 
- tab_height
; 
 982     caption 
= page
.caption
; 
 984     // select pen, brush and font for the tab to be drawn 
 988         dc
.SetPen(m_selected_bkpen
); 
 989         dc
.SetBrush(m_selected_bkbrush
); 
 990         dc
.SetFont(m_selected_font
); 
 991         textx 
= selected_textx
; 
 992         texty 
= selected_texty
; 
 996         dc
.SetPen(m_normal_bkpen
); 
 997         dc
.SetBrush(m_normal_bkbrush
); 
 998         dc
.SetFont(m_normal_font
); 
 999         textx 
= normal_textx
; 
1000         texty 
= normal_texty
; 
1007     points
[0].x 
= tab_x
; 
1008     points
[0].y 
= tab_y 
+ tab_height 
- 1; 
1009     points
[1].x 
= tab_x 
+ tab_height 
- 3; 
1010     points
[1].y 
= tab_y 
+ 2; 
1011     points
[2].x 
= tab_x 
+ tab_height 
+ 3; 
1012     points
[2].y 
= tab_y
; 
1013     points
[3].x 
= tab_x 
+ tab_width 
- 2; 
1014     points
[3].y 
= tab_y
; 
1015     points
[4].x 
= tab_x 
+ tab_width
; 
1016     points
[4].y 
= tab_y 
+ 2; 
1017     points
[5].x 
= tab_x 
+ tab_width
; 
1018     points
[5].y 
= tab_y 
+ tab_height 
- 1; 
1019     points
[6] = points
[0]; 
1021     dc
.SetClippingRegion(in_rect
); 
1023     dc
.DrawPolygon(WXSIZEOF(points
) - 1, points
); 
1025     dc
.SetPen(*wxGREY_PEN
); 
1027     //dc.DrawLines(active ? WXSIZEOF(points) - 1 : WXSIZEOF(points), points); 
1028     dc
.DrawLines(WXSIZEOF(points
), points
); 
1033     int close_button_width 
= 0; 
1034     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
1036         close_button_width 
= m_active_close_bmp
.GetWidth(); 
1037         text_offset 
= tab_x 
+ (tab_height
/2) + ((tab_width
-close_button_width
)/2) - (textx
/2); 
1041         text_offset 
= tab_x 
+ (tab_height
/3) + (tab_width
/2) - (textx
/2); 
1044     // set minimum text offset 
1045     if (text_offset 
< tab_x 
+ tab_height
) 
1046         text_offset 
= tab_x 
+ tab_height
; 
1048     // chop text if necessary 
1049     wxString draw_text 
= wxAuiChopText(dc
, 
1051                           tab_width 
- (text_offset
-tab_x
) - close_button_width
); 
1054     dc
.DrawText(draw_text
, 
1056                  (tab_y 
+ tab_height
)/2 - (texty
/2) + 1); 
1059     // draw focus rectangle 
1060     if (page
.active 
&& (wnd
->FindFocus() == wnd
)) 
1062         wxRect 
focusRect(text_offset
, ((tab_y 
+ tab_height
)/2 - (texty
/2) + 1), 
1063             selected_textx
, selected_texty
); 
1065         focusRect
.Inflate(2, 2); 
1067         wxRendererNative::Get().DrawFocusRect(wnd
, dc
, focusRect
, 0); 
1070     // draw close button if necessary 
1071     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
1075             bmp 
= m_active_close_bmp
; 
1077             bmp 
= m_disabled_close_bmp
; 
1079         wxRect 
rect(tab_x 
+ tab_width 
- close_button_width 
- 1, 
1080                     tab_y 
+ (tab_height
/2) - (bmp
.GetHeight()/2) + 1, 
1083         DrawButtons(dc
, rect
, bmp
, *wxWHITE
, close_button_state
); 
1085         *out_button_rect 
= rect
; 
1089     *out_tab_rect 
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
); 
1091     dc
.DestroyClippingRegion(); 
1094 int wxAuiSimpleTabArt::GetIndentSize() 
1099 wxSize 
wxAuiSimpleTabArt::GetTabSize(wxDC
& dc
, 
1100                                      wxWindow
* WXUNUSED(wnd
), 
1101                                      const wxString
& caption
, 
1102                                      const wxBitmap
& WXUNUSED(bitmap
), 
1103                                      bool WXUNUSED(active
), 
1104                                      int close_button_state
, 
1107     wxCoord measured_textx
, measured_texty
; 
1109     dc
.SetFont(m_measuring_font
); 
1110     dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
); 
1112     wxCoord tab_height 
= measured_texty 
+ 4; 
1113     wxCoord tab_width 
= measured_textx 
+ tab_height 
+ 5; 
1115     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
1116         tab_width 
+= m_active_close_bmp
.GetWidth(); 
1118     if (m_flags 
& wxAUI_NB_TAB_FIXED_WIDTH
) 
1120         tab_width 
= m_fixed_tab_width
; 
1123     *x_extent 
= tab_width 
- (tab_height
/2) - 1; 
1125     return wxSize(tab_width
, tab_height
); 
1129 void wxAuiSimpleTabArt::DrawButton(wxDC
& dc
, 
1130                                    wxWindow
* WXUNUSED(wnd
), 
1131                                    const wxRect
& in_rect
, 
1142         case wxAUI_BUTTON_CLOSE
: 
1143             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1144                 bmp 
= m_disabled_close_bmp
; 
1146                 bmp 
= m_active_close_bmp
; 
1148         case wxAUI_BUTTON_LEFT
: 
1149             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1150                 bmp 
= m_disabled_left_bmp
; 
1152                 bmp 
= m_active_left_bmp
; 
1154         case wxAUI_BUTTON_RIGHT
: 
1155             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1156                 bmp 
= m_disabled_right_bmp
; 
1158                 bmp 
= m_active_right_bmp
; 
1160         case wxAUI_BUTTON_WINDOWLIST
: 
1161             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1162                 bmp 
= m_disabled_windowlist_bmp
; 
1164                 bmp 
= m_active_windowlist_bmp
; 
1173     if (orientation 
== wxLEFT
) 
1175         rect
.SetX(in_rect
.x
); 
1176         rect
.SetY(((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2)); 
1177         rect
.SetWidth(bmp
.GetWidth()); 
1178         rect
.SetHeight(bmp
.GetHeight()); 
1182         rect 
= wxRect(in_rect
.x 
+ in_rect
.width 
- bmp
.GetWidth(), 
1183                       ((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2), 
1184                       bmp
.GetWidth(), bmp
.GetHeight()); 
1188     DrawButtons(dc
, rect
, bmp
, *wxWHITE
, button_state
); 
1193 int wxAuiSimpleTabArt::ShowDropDown(wxWindow
* wnd
, 
1194                                     const wxAuiNotebookPageArray
& pages
, 
1199     size_t i
, count 
= pages
.GetCount(); 
1200     for (i 
= 0; i 
< count
; ++i
) 
1202         const wxAuiNotebookPage
& page 
= pages
.Item(i
); 
1203         menuPopup
.AppendCheckItem(1000+i
, page
.caption
); 
1206     if (active_idx 
!= -1) 
1208         menuPopup
.Check(1000+active_idx
, true); 
1211     // find out where to put the popup menu of window 
1212     // items.  Subtract 100 for now to center the menu 
1213     // a bit, until a better mechanism can be implemented 
1214     wxPoint pt 
= ::wxGetMousePosition(); 
1215     pt 
= wnd
->ScreenToClient(pt
); 
1221     // find out the screen coordinate at the bottom of the tab ctrl 
1222     wxRect cli_rect 
= wnd
->GetClientRect(); 
1223     pt
.y 
= cli_rect
.y 
+ cli_rect
.height
; 
1225     wxAuiCommandCapture
* cc 
= new wxAuiCommandCapture
; 
1226     wnd
->PushEventHandler(cc
); 
1227     wnd
->PopupMenu(&menuPopup
, pt
); 
1228     int command 
= cc
->GetCommandId(); 
1229     wnd
->PopEventHandler(true); 
1231     if (command 
>= 1000) 
1232         return command
-1000; 
1237 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow
* wnd
, 
1238                                           const wxAuiNotebookPageArray
& WXUNUSED(pages
), 
1239                                           const wxSize
& WXUNUSED(required_bmp_size
)) 
1242     dc
.SetFont(m_measuring_font
); 
1244     wxSize s 
= GetTabSize(dc
, 
1249                           wxAUI_BUTTON_STATE_HIDDEN
, 
1254 void wxAuiSimpleTabArt::SetNormalFont(const wxFont
& font
) 
1256     m_normal_font 
= font
; 
1259 void wxAuiSimpleTabArt::SetSelectedFont(const wxFont
& font
) 
1261     m_selected_font 
= font
; 
1264 void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont
& font
) 
1266     m_measuring_font 
= font
; 
1272 // -- wxAuiTabContainer class implementation -- 
1275 // wxAuiTabContainer is a class which contains information about each 
1276 // tab.  It also can render an entire tab control to a specified DC. 
1277 // It's not a window class itself, because this code will be used by 
1278 // the wxFrameMananger, where it is disadvantageous to have separate 
1279 // windows for each tab control in the case of "docked tabs" 
1281 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window 
1282 // which can be used as a tab control in the normal sense. 
1285 wxAuiTabContainer::wxAuiTabContainer() 
1289     m_art 
= new wxAuiDefaultTabArt
; 
1291     AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
); 
1292     AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
); 
1293     AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
); 
1294     AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
); 
1297 wxAuiTabContainer::~wxAuiTabContainer() 
1302 void wxAuiTabContainer::SetArtProvider(wxAuiTabArt
* art
) 
1309         m_art
->SetFlags(m_flags
); 
1313 wxAuiTabArt
* wxAuiTabContainer::GetArtProvider() const 
1318 void wxAuiTabContainer::SetFlags(unsigned int flags
) 
1322     // check for new close button settings 
1323     RemoveButton(wxAUI_BUTTON_LEFT
); 
1324     RemoveButton(wxAUI_BUTTON_RIGHT
); 
1325     RemoveButton(wxAUI_BUTTON_WINDOWLIST
); 
1326     RemoveButton(wxAUI_BUTTON_CLOSE
); 
1329     if (flags 
& wxAUI_NB_SCROLL_BUTTONS
) 
1331         AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
); 
1332         AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
); 
1335     if (flags 
& wxAUI_NB_WINDOWLIST_BUTTON
) 
1337         AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
); 
1340     if (flags 
& wxAUI_NB_CLOSE_BUTTON
) 
1342         AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
); 
1347         m_art
->SetFlags(m_flags
); 
1351 unsigned int wxAuiTabContainer::GetFlags() const 
1357 void wxAuiTabContainer::SetNormalFont(const wxFont
& font
) 
1359     m_art
->SetNormalFont(font
); 
1362 void wxAuiTabContainer::SetSelectedFont(const wxFont
& font
) 
1364     m_art
->SetSelectedFont(font
); 
1367 void wxAuiTabContainer::SetMeasuringFont(const wxFont
& font
) 
1369     m_art
->SetMeasuringFont(font
); 
1372 void wxAuiTabContainer::SetRect(const wxRect
& rect
) 
1378         m_art
->SetSizingInfo(rect
.GetSize(), m_pages
.GetCount()); 
1382 bool wxAuiTabContainer::AddPage(wxWindow
* page
, 
1383                                 const wxAuiNotebookPage
& info
) 
1385     wxAuiNotebookPage page_info
; 
1387     page_info
.window 
= page
; 
1389     m_pages
.Add(page_info
); 
1391     // let the art provider know how many pages we have 
1394         m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount()); 
1400 bool wxAuiTabContainer::InsertPage(wxWindow
* page
, 
1401                                    const wxAuiNotebookPage
& info
, 
1404     wxAuiNotebookPage page_info
; 
1406     page_info
.window 
= page
; 
1408     if (idx 
>= m_pages
.GetCount()) 
1409         m_pages
.Add(page_info
); 
1411         m_pages
.Insert(page_info
, idx
); 
1413     // let the art provider know how many pages we have 
1416         m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount()); 
1422 bool wxAuiTabContainer::MovePage(wxWindow
* page
, 
1425     int idx 
= GetIdxFromWindow(page
); 
1429     // get page entry, make a copy of it 
1430     wxAuiNotebookPage p 
= GetPage(idx
); 
1432     // remove old page entry 
1435     // insert page where it should be 
1436     InsertPage(page
, p
, new_idx
); 
1441 bool wxAuiTabContainer::RemovePage(wxWindow
* wnd
) 
1443     size_t i
, page_count 
= m_pages
.GetCount(); 
1444     for (i 
= 0; i 
< page_count
; ++i
) 
1446         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1447         if (page
.window 
== wnd
) 
1449             m_pages
.RemoveAt(i
); 
1451             // let the art provider know how many pages we have 
1454                 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount()); 
1464 bool wxAuiTabContainer::SetActivePage(wxWindow
* wnd
) 
1468     size_t i
, page_count 
= m_pages
.GetCount(); 
1469     for (i 
= 0; i 
< page_count
; ++i
) 
1471         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1472         if (page
.window 
== wnd
) 
1479             page
.active 
= false; 
1486 void wxAuiTabContainer::SetNoneActive() 
1488     size_t i
, page_count 
= m_pages
.GetCount(); 
1489     for (i 
= 0; i 
< page_count
; ++i
) 
1491         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1492         page
.active 
= false; 
1496 bool wxAuiTabContainer::SetActivePage(size_t page
) 
1498     if (page 
>= m_pages
.GetCount()) 
1501     return SetActivePage(m_pages
.Item(page
).window
); 
1504 int wxAuiTabContainer::GetActivePage() const 
1506     size_t i
, page_count 
= m_pages
.GetCount(); 
1507     for (i 
= 0; i 
< page_count
; ++i
) 
1509         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1517 wxWindow
* wxAuiTabContainer::GetWindowFromIdx(size_t idx
) const 
1519     if (idx 
>= m_pages
.GetCount()) 
1522     return m_pages
[idx
].window
; 
1525 int wxAuiTabContainer::GetIdxFromWindow(wxWindow
* wnd
) const 
1527     const size_t page_count 
= m_pages
.GetCount(); 
1528     for ( size_t i 
= 0; i 
< page_count
; ++i 
) 
1530         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1531         if (page
.window 
== wnd
) 
1537 wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
) 
1539     wxASSERT_MSG(idx 
< m_pages
.GetCount(), wxT("Invalid Page index")); 
1541     return m_pages
[idx
]; 
1544 const wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
) const 
1546     wxASSERT_MSG(idx 
< m_pages
.GetCount(), wxT("Invalid Page index")); 
1548     return m_pages
[idx
]; 
1551 wxAuiNotebookPageArray
& wxAuiTabContainer::GetPages() 
1556 size_t wxAuiTabContainer::GetPageCount() const 
1558     return m_pages
.GetCount(); 
1561 void wxAuiTabContainer::AddButton(int id
, 
1563                                   const wxBitmap
& normal_bitmap
, 
1564                                   const wxBitmap
& disabled_bitmap
) 
1566     wxAuiTabContainerButton button
; 
1568     button
.bitmap 
= normal_bitmap
; 
1569     button
.dis_bitmap 
= disabled_bitmap
; 
1570     button
.location 
= location
; 
1571     button
.cur_state 
= wxAUI_BUTTON_STATE_NORMAL
; 
1573     m_buttons
.Add(button
); 
1576 void wxAuiTabContainer::RemoveButton(int id
) 
1578     size_t i
, button_count 
= m_buttons
.GetCount(); 
1580     for (i 
= 0; i 
< button_count
; ++i
) 
1582         if (m_buttons
.Item(i
).id 
== id
) 
1584             m_buttons
.RemoveAt(i
); 
1592 size_t wxAuiTabContainer::GetTabOffset() const 
1594     return m_tab_offset
; 
1597 void wxAuiTabContainer::SetTabOffset(size_t offset
) 
1599     m_tab_offset 
= offset
; 
1605 // Render() renders the tab catalog to the specified DC 
1606 // It is a virtual function and can be overridden to 
1607 // provide custom drawing capabilities 
1608 void wxAuiTabContainer::Render(wxDC
* raw_dc
, wxWindow
* wnd
) 
1610     if (!raw_dc 
|| !raw_dc
->IsOk()) 
1615     // use the same layout direction as the window DC uses to ensure that the 
1616     // text is rendered correctly 
1617     dc
.SetLayoutDirection(raw_dc
->GetLayoutDirection()); 
1621     size_t page_count 
= m_pages
.GetCount(); 
1622     size_t button_count 
= m_buttons
.GetCount(); 
1624     // create off-screen bitmap 
1625     bmp
.Create(m_rect
.GetWidth(), m_rect
.GetHeight()); 
1626     dc
.SelectObject(bmp
); 
1631     // find out if size of tabs is larger than can be 
1632     // afforded on screen 
1633     int total_width 
= 0; 
1634     int visible_width 
= 0; 
1635     for (i 
= 0; i 
< page_count
; ++i
) 
1637         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1639         // determine if a close button is on this tab 
1640         bool close_button 
= false; 
1641         if ((m_flags 
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 || 
1642             ((m_flags 
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
)) 
1644             close_button 
= true; 
1649         wxSize size 
= m_art
->GetTabSize(dc
, 
1655                               wxAUI_BUTTON_STATE_NORMAL 
: 
1656                               wxAUI_BUTTON_STATE_HIDDEN
, 
1659         if (i
+1 < page_count
) 
1660             total_width 
+= x_extent
; 
1662             total_width 
+= size
.x
; 
1664         if (i 
>= m_tab_offset
) 
1666             if (i
+1 < page_count
) 
1667                 visible_width 
+= x_extent
; 
1669                 visible_width 
+= size
.x
; 
1673     if (total_width 
> m_rect
.GetWidth() || m_tab_offset 
!= 0) 
1675         // show left/right buttons 
1676         for (i 
= 0; i 
< button_count
; ++i
) 
1678             wxAuiTabContainerButton
& button 
= m_buttons
.Item(i
); 
1679             if (button
.id 
== wxAUI_BUTTON_LEFT 
|| 
1680                 button
.id 
== wxAUI_BUTTON_RIGHT
) 
1682                 button
.cur_state 
&= ~wxAUI_BUTTON_STATE_HIDDEN
; 
1688         // hide left/right buttons 
1689         for (i 
= 0; i 
< button_count
; ++i
) 
1691             wxAuiTabContainerButton
& button 
= m_buttons
.Item(i
); 
1692             if (button
.id 
== wxAUI_BUTTON_LEFT 
|| 
1693                 button
.id 
== wxAUI_BUTTON_RIGHT
) 
1695                 button
.cur_state 
|= wxAUI_BUTTON_STATE_HIDDEN
; 
1700     // determine whether left button should be enabled 
1701     for (i 
= 0; i 
< button_count
; ++i
) 
1703         wxAuiTabContainerButton
& button 
= m_buttons
.Item(i
); 
1704         if (button
.id 
== wxAUI_BUTTON_LEFT
) 
1706             if (m_tab_offset 
== 0) 
1707                 button
.cur_state 
|= wxAUI_BUTTON_STATE_DISABLED
; 
1709                 button
.cur_state 
&= ~wxAUI_BUTTON_STATE_DISABLED
; 
1711         if (button
.id 
== wxAUI_BUTTON_RIGHT
) 
1713             if (visible_width 
< m_rect
.GetWidth() - ((int)button_count
*16)) 
1714                 button
.cur_state 
|= wxAUI_BUTTON_STATE_DISABLED
; 
1716                 button
.cur_state 
&= ~wxAUI_BUTTON_STATE_DISABLED
; 
1723     m_art
->DrawBackground(dc
, wnd
, m_rect
); 
1726     int left_buttons_width 
= 0; 
1727     int right_buttons_width 
= 0; 
1731     // draw the buttons on the right side 
1732     offset 
= m_rect
.x 
+ m_rect
.width
; 
1733     for (i 
= 0; i 
< button_count
; ++i
) 
1735         wxAuiTabContainerButton
& button 
= m_buttons
.Item(button_count 
- i 
- 1); 
1737         if (button
.location 
!= wxRIGHT
) 
1739         if (button
.cur_state 
& wxAUI_BUTTON_STATE_HIDDEN
) 
1742         wxRect button_rect 
= m_rect
; 
1743         button_rect
.SetY(1); 
1744         button_rect
.SetWidth(offset
); 
1746         m_art
->DrawButton(dc
, 
1754         offset 
-= button
.rect
.GetWidth(); 
1755         right_buttons_width 
+= button
.rect
.GetWidth(); 
1762     // draw the buttons on the left side 
1764     for (i 
= 0; i 
< button_count
; ++i
) 
1766         wxAuiTabContainerButton
& button 
= m_buttons
.Item(button_count 
- i 
- 1); 
1768         if (button
.location 
!= wxLEFT
) 
1770         if (button
.cur_state 
& wxAUI_BUTTON_STATE_HIDDEN
) 
1773         wxRect 
button_rect(offset
, 1, 1000, m_rect
.height
); 
1775         m_art
->DrawButton(dc
, 
1783         offset 
+= button
.rect
.GetWidth(); 
1784         left_buttons_width 
+= button
.rect
.GetWidth(); 
1787     offset 
= left_buttons_width
; 
1790         offset 
+= m_art
->GetIndentSize(); 
1793     // prepare the tab-close-button array 
1794     // make sure tab button entries which aren't used are marked as hidden 
1795     for (i 
= page_count
; i 
< m_tab_close_buttons
.GetCount(); ++i
) 
1796         m_tab_close_buttons
.Item(i
).cur_state 
= wxAUI_BUTTON_STATE_HIDDEN
; 
1798     // make sure there are enough tab button entries to accommodate all tabs 
1799     while (m_tab_close_buttons
.GetCount() < page_count
) 
1801         wxAuiTabContainerButton tempbtn
; 
1802         tempbtn
.id 
= wxAUI_BUTTON_CLOSE
; 
1803         tempbtn
.location 
= wxCENTER
; 
1804         tempbtn
.cur_state 
= wxAUI_BUTTON_STATE_HIDDEN
; 
1805         m_tab_close_buttons
.Add(tempbtn
); 
1809     // buttons before the tab offset must be set to hidden 
1810     for (i 
= 0; i 
< m_tab_offset
; ++i
) 
1812         m_tab_close_buttons
.Item(i
).cur_state 
= wxAUI_BUTTON_STATE_HIDDEN
; 
1818     size_t active 
= 999; 
1819     int active_offset 
= 0; 
1823     wxRect rect 
= m_rect
; 
1825     rect
.height 
= m_rect
.height
; 
1827     for (i 
= m_tab_offset
; i 
< page_count
; ++i
) 
1829         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1830         wxAuiTabContainerButton
& tab_button 
= m_tab_close_buttons
.Item(i
); 
1832         // determine if a close button is on this tab 
1833         if ((m_flags 
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 || 
1834             ((m_flags 
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
)) 
1836             if (tab_button
.cur_state 
== wxAUI_BUTTON_STATE_HIDDEN
) 
1838                 tab_button
.id 
= wxAUI_BUTTON_CLOSE
; 
1839                 tab_button
.cur_state 
= wxAUI_BUTTON_STATE_NORMAL
; 
1840                 tab_button
.location 
= wxCENTER
; 
1845             tab_button
.cur_state 
= wxAUI_BUTTON_STATE_HIDDEN
; 
1849         rect
.width 
= m_rect
.width 
- right_buttons_width 
- offset 
- 2; 
1851         if (rect
.width 
<= 0) 
1858                        tab_button
.cur_state
, 
1866             active_offset 
= offset
; 
1874     // make sure to deactivate buttons which are off the screen to the right 
1875     for (++i
; i 
< m_tab_close_buttons
.GetCount(); ++i
) 
1877         m_tab_close_buttons
.Item(i
).cur_state 
= wxAUI_BUTTON_STATE_HIDDEN
; 
1881     // draw the active tab again so it stands in the foreground 
1882     if (active 
>= m_tab_offset 
&& active 
< m_pages
.GetCount()) 
1884         wxAuiNotebookPage
& page 
= m_pages
.Item(active
); 
1886         wxAuiTabContainerButton
& tab_button 
= m_tab_close_buttons
.Item(active
); 
1888         rect
.x 
= active_offset
; 
1893                        tab_button
.cur_state
, 
1900     raw_dc
->Blit(m_rect
.x
, m_rect
.y
, 
1901                  m_rect
.GetWidth(), m_rect
.GetHeight(), 
1905 // Is the tab visible? 
1906 bool wxAuiTabContainer::IsTabVisible(int tabPage
, int tabOffset
, wxDC
* dc
, wxWindow
* wnd
) 
1908     if (!dc 
|| !dc
->IsOk()) 
1912     size_t page_count 
= m_pages
.GetCount(); 
1913     size_t button_count 
= m_buttons
.GetCount(); 
1915     // Hasn't been rendered yet; assume it's visible 
1916     if (m_tab_close_buttons
.GetCount() < page_count
) 
1919     // First check if both buttons are disabled - if so, there's no need to 
1920     // check further for visibility. 
1921     int arrowButtonVisibleCount 
= 0; 
1922     for (i 
= 0; i 
< button_count
; ++i
) 
1924         wxAuiTabContainerButton
& button 
= m_buttons
.Item(i
); 
1925         if (button
.id 
== wxAUI_BUTTON_LEFT 
|| 
1926             button
.id 
== wxAUI_BUTTON_RIGHT
) 
1928             if ((button
.cur_state 
& wxAUI_BUTTON_STATE_HIDDEN
) == 0) 
1929                 arrowButtonVisibleCount 
++; 
1933     // Tab must be visible 
1934     if (arrowButtonVisibleCount 
== 0) 
1937     // If tab is less than the given offset, it must be invisible by definition 
1938     if (tabPage 
< tabOffset
) 
1942     int left_buttons_width 
= 0; 
1943     int right_buttons_width 
= 0; 
1947     // calculate size of the buttons on the right side 
1948     offset 
= m_rect
.x 
+ m_rect
.width
; 
1949     for (i 
= 0; i 
< button_count
; ++i
) 
1951         wxAuiTabContainerButton
& button 
= m_buttons
.Item(button_count 
- i 
- 1); 
1953         if (button
.location 
!= wxRIGHT
) 
1955         if (button
.cur_state 
& wxAUI_BUTTON_STATE_HIDDEN
) 
1958         offset 
-= button
.rect
.GetWidth(); 
1959         right_buttons_width 
+= button
.rect
.GetWidth(); 
1964     // calculate size of the buttons on the left side 
1965     for (i 
= 0; i 
< button_count
; ++i
) 
1967         wxAuiTabContainerButton
& button 
= m_buttons
.Item(button_count 
- i 
- 1); 
1969         if (button
.location 
!= wxLEFT
) 
1971         if (button
.cur_state 
& wxAUI_BUTTON_STATE_HIDDEN
) 
1974         offset 
+= button
.rect
.GetWidth(); 
1975         left_buttons_width 
+= button
.rect
.GetWidth(); 
1978     offset 
= left_buttons_width
; 
1981         offset 
+= m_art
->GetIndentSize(); 
1985     wxRect rect 
= m_rect
; 
1987     rect
.height 
= m_rect
.height
; 
1989     // See if the given page is visible at the given tab offset (effectively scroll position) 
1990     for (i 
= tabOffset
; i 
< page_count
; ++i
) 
1992         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1993         wxAuiTabContainerButton
& tab_button 
= m_tab_close_buttons
.Item(i
); 
1996         rect
.width 
= m_rect
.width 
- right_buttons_width 
- offset 
- 2; 
1998         if (rect
.width 
<= 0) 
1999             return false; // haven't found the tab, and we've run out of space, so return false 
2002         wxSize size 
= m_art
->GetTabSize(*dc
, 
2007                             tab_button
.cur_state
, 
2012         if (i 
== (size_t) tabPage
) 
2014             // If not all of the tab is visible, and supposing there's space to display it all, 
2015             // we could do better so we return false. 
2016             if (((m_rect
.width 
- right_buttons_width 
- offset 
- 2) <= 0) && ((m_rect
.width 
- right_buttons_width 
- left_buttons_width
) > x_extent
)) 
2023     // Shouldn't really get here, but if it does, assume the tab is visible to prevent 
2024     // further looping in calling code. 
2028 // Make the tab visible if it wasn't already 
2029 void wxAuiTabContainer::MakeTabVisible(int tabPage
, wxWindow
* win
) 
2032     if (!IsTabVisible(tabPage
, GetTabOffset(), & dc
, win
)) 
2035         for (i 
= 0; i 
< (int) m_pages
.GetCount(); i
++) 
2037             if (IsTabVisible(tabPage
, i
, & dc
, win
)) 
2047 // TabHitTest() tests if a tab was hit, passing the window pointer 
2048 // back if that condition was fulfilled.  The function returns 
2049 // true if a tab was hit, otherwise false 
2050 bool wxAuiTabContainer::TabHitTest(int x
, int y
, wxWindow
** hit
) const 
2052     if (!m_rect
.Contains(x
,y
)) 
2055     wxAuiTabContainerButton
* btn 
= NULL
; 
2056     if (ButtonHitTest(x
, y
, &btn
)) 
2058         if (m_buttons
.Index(*btn
) != wxNOT_FOUND
) 
2062     size_t i
, page_count 
= m_pages
.GetCount(); 
2064     for (i 
= m_tab_offset
; i 
< page_count
; ++i
) 
2066         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
2067         if (page
.rect
.Contains(x
,y
)) 
2078 // ButtonHitTest() tests if a button was hit. The function returns 
2079 // true if a button was hit, otherwise false 
2080 bool wxAuiTabContainer::ButtonHitTest(int x
, int y
, 
2081                                       wxAuiTabContainerButton
** hit
) const 
2083     if (!m_rect
.Contains(x
,y
)) 
2086     size_t i
, button_count
; 
2089     button_count 
= m_buttons
.GetCount(); 
2090     for (i 
= 0; i 
< button_count
; ++i
) 
2092         wxAuiTabContainerButton
& button 
= m_buttons
.Item(i
); 
2093         if (button
.rect
.Contains(x
,y
) && 
2094             !(button
.cur_state 
& (wxAUI_BUTTON_STATE_HIDDEN 
| 
2095                                    wxAUI_BUTTON_STATE_DISABLED
))) 
2103     button_count 
= m_tab_close_buttons
.GetCount(); 
2104     for (i 
= 0; i 
< button_count
; ++i
) 
2106         wxAuiTabContainerButton
& button 
= m_tab_close_buttons
.Item(i
); 
2107         if (button
.rect
.Contains(x
,y
) && 
2108             !(button
.cur_state 
& (wxAUI_BUTTON_STATE_HIDDEN 
| 
2109                                    wxAUI_BUTTON_STATE_DISABLED
))) 
2122 // the utility function ShowWnd() is the same as show, 
2123 // except it handles wxAuiMDIChildFrame windows as well, 
2124 // as the Show() method on this class is "unplugged" 
2125 static void ShowWnd(wxWindow
* wnd
, bool show
) 
2128     if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
))) 
2130         wxAuiMDIChildFrame
* cf 
= (wxAuiMDIChildFrame
*)wnd
; 
2141 // DoShowHide() this function shows the active window, then 
2142 // hides all of the other windows (in that order) 
2143 void wxAuiTabContainer::DoShowHide() 
2145     wxAuiNotebookPageArray
& pages 
= GetPages(); 
2146     size_t i
, page_count 
= pages
.GetCount(); 
2148     // show new active page first 
2149     for (i 
= 0; i 
< page_count
; ++i
) 
2151         wxAuiNotebookPage
& page 
= pages
.Item(i
); 
2154             ShowWnd(page
.window
, true); 
2159     // hide all other pages 
2160     for (i 
= 0; i 
< page_count
; ++i
) 
2162         wxAuiNotebookPage
& page 
= pages
.Item(i
); 
2164             ShowWnd(page
.window
, false); 
2173 // -- wxAuiTabCtrl class implementation -- 
2177 BEGIN_EVENT_TABLE(wxAuiTabCtrl
, wxControl
) 
2178     EVT_PAINT(wxAuiTabCtrl::OnPaint
) 
2179     EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground
) 
2180     EVT_SIZE(wxAuiTabCtrl::OnSize
) 
2181     EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown
) 
2182     EVT_LEFT_DCLICK(wxAuiTabCtrl::OnLeftDClick
) 
2183     EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp
) 
2184     EVT_MIDDLE_DOWN(wxAuiTabCtrl::OnMiddleDown
) 
2185     EVT_MIDDLE_UP(wxAuiTabCtrl::OnMiddleUp
) 
2186     EVT_RIGHT_DOWN(wxAuiTabCtrl::OnRightDown
) 
2187     EVT_RIGHT_UP(wxAuiTabCtrl::OnRightUp
) 
2188     EVT_MOTION(wxAuiTabCtrl::OnMotion
) 
2189     EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow
) 
2190     EVT_AUINOTEBOOK_BUTTON(wxID_ANY
, wxAuiTabCtrl::OnButton
) 
2191     EVT_SET_FOCUS(wxAuiTabCtrl::OnSetFocus
) 
2192     EVT_KILL_FOCUS(wxAuiTabCtrl::OnKillFocus
) 
2193     EVT_CHAR(wxAuiTabCtrl::OnChar
) 
2197 wxAuiTabCtrl::wxAuiTabCtrl(wxWindow
* parent
, 
2201                            long style
) : wxControl(parent
, id
, pos
, size
, style
) 
2203     SetName(wxT("wxAuiTabCtrl")); 
2204     m_click_pt 
= wxDefaultPosition
; 
2205     m_is_dragging 
= false; 
2206     m_hover_button 
= NULL
; 
2207     m_pressed_button 
= NULL
; 
2210 wxAuiTabCtrl::~wxAuiTabCtrl() 
2214 void wxAuiTabCtrl::OnPaint(wxPaintEvent
&) 
2218     dc
.SetFont(GetFont()); 
2220     if (GetPageCount() > 0) 
2224 void wxAuiTabCtrl::OnEraseBackground(wxEraseEvent
& WXUNUSED(evt
)) 
2228 void wxAuiTabCtrl::OnSize(wxSizeEvent
& evt
) 
2230     wxSize s 
= evt
.GetSize(); 
2231     wxRect 
r(0, 0, s
.GetWidth(), s
.GetHeight()); 
2235 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent
& evt
) 
2238     m_click_pt 
= wxDefaultPosition
; 
2239     m_is_dragging 
= false; 
2241     m_pressed_button 
= NULL
; 
2245     if (TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
)) 
2247         int new_selection 
= GetIdxFromWindow(wnd
); 
2249         // wxAuiNotebooks always want to receive this event 
2250         // even if the tab is already active, because they may 
2251         // have multiple tab controls 
2252         if (new_selection 
!= GetActivePage() || 
2253             GetParent()->IsKindOf(CLASSINFO(wxAuiNotebook
))) 
2255             wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
); 
2256             e
.SetSelection(new_selection
); 
2257             e
.SetOldSelection(GetActivePage()); 
2258             e
.SetEventObject(this); 
2259             GetEventHandler()->ProcessEvent(e
); 
2262         m_click_pt
.x 
= evt
.m_x
; 
2263         m_click_pt
.y 
= evt
.m_y
; 
2269         m_pressed_button 
= m_hover_button
; 
2270         m_pressed_button
->cur_state 
= wxAUI_BUTTON_STATE_PRESSED
; 
2276 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent
& evt
) 
2278     if (GetCapture() == this) 
2283         m_is_dragging 
= false; 
2285         wxAuiNotebookEvent 
evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, m_windowId
); 
2286         evt
.SetSelection(GetIdxFromWindow(m_click_tab
)); 
2287         evt
.SetOldSelection(evt
.GetSelection()); 
2288         evt
.SetEventObject(this); 
2289         GetEventHandler()->ProcessEvent(evt
); 
2294     if (m_pressed_button
) 
2296         // make sure we're still clicking the button 
2297         wxAuiTabContainerButton
* button 
= NULL
; 
2298         if (!ButtonHitTest(evt
.m_x
, evt
.m_y
, &button
)) 
2301         if (button 
!= m_pressed_button
) 
2303             m_pressed_button 
= NULL
; 
2310         if (!(m_pressed_button
->cur_state 
& wxAUI_BUTTON_STATE_DISABLED
)) 
2312             wxAuiNotebookEvent 
evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, m_windowId
); 
2313             evt
.SetSelection(GetIdxFromWindow(m_click_tab
)); 
2314             evt
.SetInt(m_pressed_button
->id
); 
2315             evt
.SetEventObject(this); 
2316             GetEventHandler()->ProcessEvent(evt
); 
2319         m_pressed_button 
= NULL
; 
2322     m_click_pt 
= wxDefaultPosition
; 
2323     m_is_dragging 
= false; 
2327 void wxAuiTabCtrl::OnMiddleUp(wxMouseEvent
& evt
) 
2329     wxWindow
* wnd 
= NULL
; 
2330     if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
)) 
2333     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
, m_windowId
); 
2334     e
.SetEventObject(this); 
2335     e
.SetSelection(GetIdxFromWindow(wnd
)); 
2336     GetEventHandler()->ProcessEvent(e
); 
2339 void wxAuiTabCtrl::OnMiddleDown(wxMouseEvent
& evt
) 
2341     wxWindow
* wnd 
= NULL
; 
2342     if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
)) 
2345     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
, m_windowId
); 
2346     e
.SetEventObject(this); 
2347     e
.SetSelection(GetIdxFromWindow(wnd
)); 
2348     GetEventHandler()->ProcessEvent(e
); 
2351 void wxAuiTabCtrl::OnRightUp(wxMouseEvent
& evt
) 
2353     wxWindow
* wnd 
= NULL
; 
2354     if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
)) 
2357     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
, m_windowId
); 
2358     e
.SetEventObject(this); 
2359     e
.SetSelection(GetIdxFromWindow(wnd
)); 
2360     GetEventHandler()->ProcessEvent(e
); 
2363 void wxAuiTabCtrl::OnRightDown(wxMouseEvent
& evt
) 
2365     wxWindow
* wnd 
= NULL
; 
2366     if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
)) 
2369     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
, m_windowId
); 
2370     e
.SetEventObject(this); 
2371     e
.SetSelection(GetIdxFromWindow(wnd
)); 
2372     GetEventHandler()->ProcessEvent(e
); 
2375 void wxAuiTabCtrl::OnLeftDClick(wxMouseEvent
& evt
) 
2378     wxAuiTabContainerButton
* button
; 
2379     if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
) && !ButtonHitTest(evt
.m_x
, evt
.m_y
, &button
)) 
2381         wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
, m_windowId
); 
2382         e
.SetEventObject(this); 
2383         GetEventHandler()->ProcessEvent(e
); 
2387 void wxAuiTabCtrl::OnMotion(wxMouseEvent
& evt
) 
2389     wxPoint pos 
= evt
.GetPosition(); 
2391     // check if the mouse is hovering above a button 
2392     wxAuiTabContainerButton
* button
; 
2393     if (ButtonHitTest(pos
.x
, pos
.y
, &button
)) 
2395         if (m_hover_button 
&& button 
!= m_hover_button
) 
2397             m_hover_button
->cur_state 
= wxAUI_BUTTON_STATE_NORMAL
; 
2398             m_hover_button 
= NULL
; 
2403         if (button
->cur_state 
!= wxAUI_BUTTON_STATE_HOVER
) 
2405             button
->cur_state 
= wxAUI_BUTTON_STATE_HOVER
; 
2408             m_hover_button 
= button
; 
2416             m_hover_button
->cur_state 
= wxAUI_BUTTON_STATE_NORMAL
; 
2417             m_hover_button 
= NULL
; 
2424     if (!evt
.LeftIsDown() || m_click_pt 
== wxDefaultPosition
) 
2429         wxAuiNotebookEvent 
evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, m_windowId
); 
2430         evt
.SetSelection(GetIdxFromWindow(m_click_tab
)); 
2431         evt
.SetOldSelection(evt
.GetSelection()); 
2432         evt
.SetEventObject(this); 
2433         GetEventHandler()->ProcessEvent(evt
); 
2438     int drag_x_threshold 
= wxSystemSettings::GetMetric(wxSYS_DRAG_X
); 
2439     int drag_y_threshold 
= wxSystemSettings::GetMetric(wxSYS_DRAG_Y
); 
2441     if (abs(pos
.x 
- m_click_pt
.x
) > drag_x_threshold 
|| 
2442         abs(pos
.y 
- m_click_pt
.y
) > drag_y_threshold
) 
2444         wxAuiNotebookEvent 
evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, m_windowId
); 
2445         evt
.SetSelection(GetIdxFromWindow(m_click_tab
)); 
2446         evt
.SetOldSelection(evt
.GetSelection()); 
2447         evt
.SetEventObject(this); 
2448         GetEventHandler()->ProcessEvent(evt
); 
2450         m_is_dragging 
= true; 
2454 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
)) 
2458         m_hover_button
->cur_state 
= wxAUI_BUTTON_STATE_NORMAL
; 
2459         m_hover_button 
= NULL
; 
2465 void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent
& event
) 
2467     int button 
= event
.GetInt(); 
2469     if (button 
== wxAUI_BUTTON_LEFT 
|| button 
== wxAUI_BUTTON_RIGHT
) 
2471         if (button 
== wxAUI_BUTTON_LEFT
) 
2473             if (GetTabOffset() > 0) 
2475                 SetTabOffset(GetTabOffset()-1); 
2482             SetTabOffset(GetTabOffset()+1); 
2487     else if (button 
== wxAUI_BUTTON_WINDOWLIST
) 
2489         int idx 
= GetArtProvider()->ShowDropDown(this, m_pages
, GetActivePage()); 
2493             wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
); 
2494             e
.SetSelection(idx
); 
2495             e
.SetOldSelection(GetActivePage()); 
2496             e
.SetEventObject(this); 
2497             GetEventHandler()->ProcessEvent(e
); 
2506 void wxAuiTabCtrl::OnSetFocus(wxFocusEvent
& WXUNUSED(event
)) 
2511 void wxAuiTabCtrl::OnKillFocus(wxFocusEvent
& WXUNUSED(event
)) 
2516 void wxAuiTabCtrl::OnChar(wxKeyEvent
& event
) 
2518     if (GetActivePage() == -1) 
2524     // We can't leave tab processing to the system; on Windows, tabs and keys 
2525     // get eaten by the system and not processed properly if we specify both 
2526     // wxTAB_TRAVERSAL and wxWANTS_CHARS. And if we specify just wxTAB_TRAVERSAL, 
2527     // we don't key arrow key events. 
2529     int key 
= event
.GetKeyCode(); 
2531     if (key 
== WXK_NUMPAD_PAGEUP
) 
2533     if (key 
== WXK_NUMPAD_PAGEDOWN
) 
2535     if (key 
== WXK_NUMPAD_HOME
) 
2537     if (key 
== WXK_NUMPAD_END
) 
2539     if (key 
== WXK_NUMPAD_LEFT
) 
2541     if (key 
== WXK_NUMPAD_RIGHT
) 
2544     if (key 
== WXK_TAB 
|| key 
== WXK_PAGEUP 
|| key 
== WXK_PAGEDOWN
) 
2546         bool bCtrlDown 
= event
.ControlDown(); 
2547         bool bShiftDown 
= event
.ShiftDown(); 
2549         bool bForward 
= (key 
== WXK_TAB 
&& !bShiftDown
) || (key 
== WXK_PAGEDOWN
); 
2550         bool bWindowChange 
= (key 
== WXK_PAGEUP
) || (key 
== WXK_PAGEDOWN
) || bCtrlDown
; 
2551         bool bFromTab 
= (key 
== WXK_TAB
); 
2553         wxAuiNotebook
* nb 
= wxDynamicCast(GetParent(), wxAuiNotebook
); 
2560         wxNavigationKeyEvent keyEvent
; 
2561         keyEvent
.SetDirection(bForward
); 
2562         keyEvent
.SetWindowChange(bWindowChange
); 
2563         keyEvent
.SetFromTab(bFromTab
); 
2564         keyEvent
.SetEventObject(nb
); 
2566         if (!nb
->GetEventHandler()->ProcessEvent(keyEvent
)) 
2568             // Not processed? Do an explicit tab into the page. 
2569             wxWindow
* win 
= GetWindowFromIdx(GetActivePage()); 
2576     if (m_pages
.GetCount() < 2) 
2584     int forwardKey
, backwardKey
; 
2585     if (GetLayoutDirection() == wxLayout_RightToLeft
) 
2587         forwardKey 
= WXK_LEFT
; 
2588         backwardKey 
= WXK_RIGHT
; 
2592         forwardKey 
= WXK_RIGHT
; 
2593         backwardKey 
= WXK_LEFT
; 
2596     if (key 
== forwardKey
) 
2598         if (m_pages
.GetCount() > 1) 
2600             if (GetActivePage() == -1) 
2602             else if (GetActivePage() < (int) (m_pages
.GetCount() - 1)) 
2603                 newPage 
= GetActivePage() + 1; 
2606     else if (key 
== backwardKey
) 
2608         if (m_pages
.GetCount() > 1) 
2610             if (GetActivePage() == -1) 
2611                 newPage 
= (int) (m_pages
.GetCount() - 1); 
2612             else if (GetActivePage() > 0) 
2613                 newPage 
= GetActivePage() - 1; 
2616     else if (key 
== WXK_HOME
) 
2620     else if (key 
== WXK_END
) 
2622         newPage 
= (int) (m_pages
.GetCount() - 1); 
2629         wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
); 
2630         e
.SetSelection(newPage
); 
2631         e
.SetOldSelection(newPage
); 
2632         e
.SetEventObject(this); 
2633         this->GetEventHandler()->ProcessEvent(e
); 
2639 // wxTabFrame is an interesting case.  It's important that all child pages 
2640 // of the multi-notebook control are all actually children of that control 
2641 // (and not grandchildren).  wxTabFrame facilitates this.  There is one 
2642 // instance of wxTabFrame for each tab control inside the multi-notebook. 
2643 // It's important to know that wxTabFrame is not a real window, but it merely 
2644 // used to capture the dimensions/positioning of the internal tab control and 
2645 // it's managed page windows 
2647 class wxTabFrame 
: public wxWindow
 
2654         m_rect 
= wxRect(0,0,200,200); 
2655         m_tab_ctrl_height 
= 20; 
2663     void SetTabCtrlHeight(int h
) 
2665         m_tab_ctrl_height 
= h
; 
2669     void DoSetSize(int x
, int y
, 
2670                    int width
, int height
, 
2671                    int WXUNUSED(sizeFlags 
= wxSIZE_AUTO
)) 
2673         m_rect 
= wxRect(x
, y
, width
, height
); 
2677     void DoGetClientSize(int* x
, int* y
) const 
2684     bool Show( bool WXUNUSED(show 
= true) ) { return false; } 
2691         m_tab_rect 
= wxRect(m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
); 
2692         if (m_tabs
->GetFlags() & wxAUI_NB_BOTTOM
) 
2694             m_tab_rect 
= wxRect (m_rect
.x
, m_rect
.y 
+ m_rect
.height 
- m_tab_ctrl_height
, m_rect
.width
, m_tab_ctrl_height
); 
2695             m_tabs
->SetSize     (m_rect
.x
, m_rect
.y 
+ m_rect
.height 
- m_tab_ctrl_height
, m_rect
.width
, m_tab_ctrl_height
); 
2696             m_tabs
->SetRect     (wxRect(0, 0, m_rect
.width
, m_tab_ctrl_height
)); 
2698         else //TODO: if (GetFlags() & wxAUI_NB_TOP) 
2700             m_tab_rect 
= wxRect (m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
); 
2701             m_tabs
->SetSize     (m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
); 
2702             m_tabs
->SetRect     (wxRect(0, 0,        m_rect
.width
, m_tab_ctrl_height
)); 
2704         // TODO: else if (GetFlags() & wxAUI_NB_LEFT){} 
2705         // TODO: else if (GetFlags() & wxAUI_NB_RIGHT){} 
2710         wxAuiNotebookPageArray
& pages 
= m_tabs
->GetPages(); 
2711         size_t i
, page_count 
= pages
.GetCount(); 
2713         for (i 
= 0; i 
< page_count
; ++i
) 
2715             int height 
= m_rect
.height 
- m_tab_ctrl_height
; 
2718                 // avoid passing negative height to wxWindow::SetSize(), this 
2719                 // results in assert failures/GTK+ warnings 
2723             wxAuiNotebookPage
& page 
= pages
.Item(i
); 
2724             if (m_tabs
->GetFlags() & wxAUI_NB_BOTTOM
) 
2726                 page
.window
->SetSize(m_rect
.x
, m_rect
.y
, m_rect
.width
, height
); 
2728             else //TODO: if (GetFlags() & wxAUI_NB_TOP) 
2730                 page
.window
->SetSize(m_rect
.x
, m_rect
.y 
+ m_tab_ctrl_height
, 
2731                                      m_rect
.width
, height
); 
2733             // TODO: else if (GetFlags() & wxAUI_NB_LEFT){} 
2734             // TODO: else if (GetFlags() & wxAUI_NB_RIGHT){} 
2737             if (page
.window
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
))) 
2739                 wxAuiMDIChildFrame
* wnd 
= (wxAuiMDIChildFrame
*)page
.window
; 
2740                 wnd
->ApplyMDIChildFrameRect(); 
2747     void DoGetSize(int* x
, int* y
) const 
2750             *x 
= m_rect
.GetWidth(); 
2752             *y 
= m_rect
.GetHeight(); 
2763     wxAuiTabCtrl
* m_tabs
; 
2764     int m_tab_ctrl_height
; 
2768 const int wxAuiBaseTabCtrlId 
= 5380; 
2771 // -- wxAuiNotebook class implementation -- 
2773 BEGIN_EVENT_TABLE(wxAuiNotebook
, wxControl
) 
2774     EVT_SIZE(wxAuiNotebook::OnSize
) 
2775     EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocusNotebook
) 
2776     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2777                       wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, 
2778                       wxAuiNotebook::OnTabClicked
) 
2779     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2780                       wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, 
2781                       wxAuiNotebook::OnTabBeginDrag
) 
2782     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2783                       wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, 
2784                       wxAuiNotebook::OnTabEndDrag
) 
2785     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2786                       wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, 
2787                       wxAuiNotebook::OnTabDragMotion
) 
2788     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2789                       wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, 
2790                       wxAuiNotebook::OnTabButton
) 
2791     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2792                       wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
, 
2793                       wxAuiNotebook::OnTabMiddleDown
) 
2794     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2795                       wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
, 
2796                       wxAuiNotebook::OnTabMiddleUp
) 
2797     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2798                       wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
, 
2799                       wxAuiNotebook::OnTabRightDown
) 
2800     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2801                       wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
, 
2802                       wxAuiNotebook::OnTabRightUp
) 
2803     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2804                       wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
, 
2805                       wxAuiNotebook::OnTabBgDClick
) 
2806     EVT_NAVIGATION_KEY(wxAuiNotebook::OnNavigationKeyNotebook
) 
2808 #ifdef wxHAS_NATIVE_TAB_TRAVERSAL 
2809     WX_EVENT_TABLE_CONTROL_CONTAINER(wxAuiNotebook
) 
2811     // Avoid clash with container event handler functions 
2812     EVT_SET_FOCUS(wxAuiNotebook::OnFocus
) 
2816 WX_DELEGATE_TO_CONTROL_CONTAINER(wxAuiNotebook
, wxControl
) 
2818 wxAuiNotebook::wxAuiNotebook() 
2821     m_tab_id_counter 
= wxAuiBaseTabCtrlId
; 
2823     m_tab_ctrl_height 
= 20; 
2824     m_requested_bmp_size 
= wxDefaultSize
; 
2825     m_requested_tabctrl_height 
= -1; 
2828 wxAuiNotebook::wxAuiNotebook(wxWindow 
*parent
, 
2832                              long style
) : wxControl(parent
, id
, pos
, size
, style
) 
2835     m_requested_bmp_size 
= wxDefaultSize
; 
2836     m_requested_tabctrl_height 
= -1; 
2837     InitNotebook(style
); 
2840 bool wxAuiNotebook::Create(wxWindow
* parent
, 
2846     if (!wxControl::Create(parent
, id
, pos
, size
, style
)) 
2849     InitNotebook(style
); 
2854 // InitNotebook() contains common initialization 
2855 // code called by all constructors 
2856 void wxAuiNotebook::InitNotebook(long style
) 
2858     WX_INIT_CONTROL_CONTAINER(); 
2859     // SetCanFocus(false); 
2861     SetName(wxT("wxAuiNotebook")); 
2863     m_tab_id_counter 
= wxAuiBaseTabCtrlId
; 
2865     m_flags 
= (unsigned int)style
; 
2866     m_tab_ctrl_height 
= 20; 
2868     m_normal_font 
= *wxNORMAL_FONT
; 
2869     m_selected_font 
= *wxNORMAL_FONT
; 
2870     m_selected_font
.SetWeight(wxBOLD
); 
2872     SetArtProvider(new wxAuiDefaultTabArt
); 
2874     m_dummy_wnd 
= new wxWindow(this, wxID_ANY
, wxPoint(0,0), wxSize(0,0)); 
2875     m_dummy_wnd
->SetSize(200, 200); 
2876     m_dummy_wnd
->Show(false); 
2878     m_mgr
.SetManagedWindow(this); 
2879     m_mgr
.SetFlags(wxAUI_MGR_DEFAULT
); 
2880     m_mgr
.SetDockSizeConstraint(1.0, 1.0); // no dock size constraint 
2882     m_mgr
.AddPane(m_dummy_wnd
, 
2883               wxAuiPaneInfo().Name(wxT("dummy")).Bottom().CaptionVisible(false).Show(false)); 
2888 wxAuiNotebook::~wxAuiNotebook() 
2890     // Indicate we're deleting pages 
2891     m_isBeingDeleted 
= true; 
2893     while ( GetPageCount() > 0 ) 
2899 void wxAuiNotebook::SetArtProvider(wxAuiTabArt
* art
) 
2901     m_tabs
.SetArtProvider(art
); 
2903     UpdateTabCtrlHeight(); 
2906 // SetTabCtrlHeight() is the highest-level override of the 
2907 // tab height.  A call to this function effectively enforces a 
2908 // specified tab ctrl height, overriding all other considerations, 
2909 // such as text or bitmap height.  It overrides any call to 
2910 // SetUniformBitmapSize().  Specifying a height of -1 reverts 
2911 // any previous call and returns to the default behavior 
2913 void wxAuiNotebook::SetTabCtrlHeight(int height
) 
2915     m_requested_tabctrl_height 
= height
; 
2917     // if window is already initialized, recalculate the tab height 
2920         UpdateTabCtrlHeight(); 
2925 // SetUniformBitmapSize() ensures that all tabs will have 
2926 // the same height, even if some tabs don't have bitmaps 
2927 // Passing wxDefaultSize to this function will instruct 
2928 // the control to use dynamic tab height-- so when a tab 
2929 // with a large bitmap is added, the tab ctrl's height will 
2930 // automatically increase to accommodate the bitmap 
2932 void wxAuiNotebook::SetUniformBitmapSize(const wxSize
& size
) 
2934     m_requested_bmp_size 
= size
; 
2936     // if window is already initialized, recalculate the tab height 
2939         UpdateTabCtrlHeight(); 
2943 // UpdateTabCtrlHeight() does the actual tab resizing. It's meant 
2944 // to be used interally 
2945 void wxAuiNotebook::UpdateTabCtrlHeight() 
2947     // get the tab ctrl height we will use 
2948     int height 
= CalculateTabCtrlHeight(); 
2950     // if the tab control height needs to change, update 
2951     // all of our tab controls with the new height 
2952     if (m_tab_ctrl_height 
!= height
) 
2954         wxAuiTabArt
* art 
= m_tabs
.GetArtProvider(); 
2956         m_tab_ctrl_height 
= height
; 
2958         wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
2959         size_t i
, pane_count 
= all_panes
.GetCount(); 
2960         for (i 
= 0; i 
< pane_count
; ++i
) 
2962             wxAuiPaneInfo
& pane 
= all_panes
.Item(i
); 
2963             if (pane
.name 
== wxT("dummy")) 
2965             wxTabFrame
* tab_frame 
= (wxTabFrame
*)pane
.window
; 
2966             wxAuiTabCtrl
* tabctrl 
= tab_frame
->m_tabs
; 
2967             tab_frame
->SetTabCtrlHeight(m_tab_ctrl_height
); 
2968             tabctrl
->SetArtProvider(art
->Clone()); 
2969             tab_frame
->DoSizing(); 
2974 void wxAuiNotebook::UpdateHintWindowSize() 
2976     wxSize size 
= CalculateNewSplitSize(); 
2978     // the placeholder hint window should be set to this size 
2979     wxAuiPaneInfo
& info 
= m_mgr
.GetPane(wxT("dummy")); 
2983         info
.BestSize(size
); 
2984         m_dummy_wnd
->SetSize(size
); 
2989 // calculates the size of the new split 
2990 wxSize 
wxAuiNotebook::CalculateNewSplitSize() 
2992     // count number of tab controls 
2993     int tab_ctrl_count 
= 0; 
2994     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
2995     size_t i
, pane_count 
= all_panes
.GetCount(); 
2996     for (i 
= 0; i 
< pane_count
; ++i
) 
2998         wxAuiPaneInfo
& pane 
= all_panes
.Item(i
); 
2999         if (pane
.name 
== wxT("dummy")) 
3004     wxSize new_split_size
; 
3006     // if there is only one tab control, the first split 
3007     // should happen around the middle 
3008     if (tab_ctrl_count 
< 2) 
3010         new_split_size 
= GetClientSize(); 
3011         new_split_size
.x 
/= 2; 
3012         new_split_size
.y 
/= 2; 
3016         // this is in place of a more complicated calculation 
3017         // that needs to be implemented 
3018         new_split_size 
= wxSize(180,180); 
3021     return new_split_size
; 
3024 int wxAuiNotebook::CalculateTabCtrlHeight() 
3026     // if a fixed tab ctrl height is specified, 
3027     // just return that instead of calculating a 
3029     if (m_requested_tabctrl_height 
!= -1) 
3030         return m_requested_tabctrl_height
; 
3032     // find out new best tab height 
3033     wxAuiTabArt
* art 
= m_tabs
.GetArtProvider(); 
3035     return art
->GetBestTabCtrlSize(this, 
3037                                    m_requested_bmp_size
); 
3041 wxAuiTabArt
* wxAuiNotebook::GetArtProvider() const 
3043     return m_tabs
.GetArtProvider(); 
3046 void wxAuiNotebook::SetWindowStyleFlag(long style
) 
3048     wxControl::SetWindowStyleFlag(style
); 
3050     m_flags 
= (unsigned int)style
; 
3052     // if the control is already initialized 
3053     if (m_mgr
.GetManagedWindow() == (wxWindow
*)this) 
3055         // let all of the tab children know about the new style 
3057         wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
3058         size_t i
, pane_count 
= all_panes
.GetCount(); 
3059         for (i 
= 0; i 
< pane_count
; ++i
) 
3061             wxAuiPaneInfo
& pane 
= all_panes
.Item(i
); 
3062             if (pane
.name 
== wxT("dummy")) 
3064             wxTabFrame
* tabframe 
= (wxTabFrame
*)pane
.window
; 
3065             wxAuiTabCtrl
* tabctrl 
= tabframe
->m_tabs
; 
3066             tabctrl
->SetFlags(m_flags
); 
3067             tabframe
->DoSizing(); 
3075 bool wxAuiNotebook::AddPage(wxWindow
* page
, 
3076                             const wxString
& caption
, 
3078                             const wxBitmap
& bitmap
) 
3080     return InsertPage(GetPageCount(), page
, caption
, select
, bitmap
); 
3083 bool wxAuiNotebook::InsertPage(size_t page_idx
, 
3085                                const wxString
& caption
, 
3087                                const wxBitmap
& bitmap
) 
3089     wxASSERT_MSG(page
, wxT("page pointer must be non-NULL")); 
3093     page
->Reparent(this); 
3095     wxAuiNotebookPage info
; 
3097     info
.caption 
= caption
; 
3098     info
.bitmap 
= bitmap
; 
3099     info
.active 
= false; 
3101     // if there are currently no tabs, the first added 
3102     // tab must be active 
3103     if (m_tabs
.GetPageCount() == 0) 
3106     m_tabs
.InsertPage(page
, info
, page_idx
); 
3108     // if that was the first page added, even if 
3109     // select is false, it must become the "current page" 
3110     // (though no select events will be fired) 
3111     if (!select 
&& m_tabs
.GetPageCount() == 1) 
3113         //m_curpage = GetPageIndex(page); 
3115     wxAuiTabCtrl
* active_tabctrl 
= GetActiveTabCtrl(); 
3116     if (page_idx 
>= active_tabctrl
->GetPageCount()) 
3117         active_tabctrl
->AddPage(page
, info
); 
3119         active_tabctrl
->InsertPage(page
, info
, page_idx
); 
3121     UpdateTabCtrlHeight(); 
3123     active_tabctrl
->DoShowHide(); 
3125     // adjust selected index 
3126     if(m_curpage 
>= (int) page_idx
) 
3131         SetSelectionToWindow(page
); 
3138 // DeletePage() removes a tab from the multi-notebook, 
3139 // and destroys the window as well 
3140 bool wxAuiNotebook::DeletePage(size_t page_idx
) 
3142     if (page_idx 
>= m_tabs
.GetPageCount()) 
3145     wxWindow
* wnd 
= m_tabs
.GetWindowFromIdx(page_idx
); 
3147     // hide the window in advance, as this will 
3149     ShowWnd(wnd
, false); 
3151     if (!RemovePage(page_idx
)) 
3155     // actually destroy the window now 
3156     if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
))) 
3158         // delete the child frame with pending delete, as is 
3159         // customary with frame windows 
3160         if (!wxPendingDelete
.Member(wnd
)) 
3161             wxPendingDelete
.Append(wnd
); 
3174 // RemovePage() removes a tab from the multi-notebook, 
3175 // but does not destroy the window 
3176 bool wxAuiNotebook::RemovePage(size_t page_idx
) 
3178     // save active window pointer 
3179     wxWindow
* active_wnd 
= NULL
; 
3181         active_wnd 
= m_tabs
.GetWindowFromIdx(m_curpage
); 
3183     // save pointer of window being deleted 
3184     wxWindow
* wnd 
= m_tabs
.GetWindowFromIdx(page_idx
); 
3185     wxWindow
* new_active 
= NULL
; 
3187     // make sure we found the page 
3191     // find out which onscreen tab ctrl owns this tab 
3194     if (!FindTab(wnd
, &ctrl
, &ctrl_idx
)) 
3197     bool is_curpage 
= (m_curpage 
== (int)page_idx
); 
3198     bool is_active_in_split 
= ctrl
->GetPage(ctrl_idx
).active
; 
3201     // remove the tab from main catalog 
3202     if (!m_tabs
.RemovePage(wnd
)) 
3205     // remove the tab from the onscreen tab ctrl 
3206     ctrl
->RemovePage(wnd
); 
3208     if (is_active_in_split
) 
3210         int ctrl_new_page_count 
= (int)ctrl
->GetPageCount(); 
3212         if (ctrl_idx 
>= ctrl_new_page_count
) 
3213             ctrl_idx 
= ctrl_new_page_count
-1; 
3215         if (ctrl_idx 
>= 0 && ctrl_idx 
< (int)ctrl
->GetPageCount()) 
3217             // set new page as active in the tab split 
3218             ctrl
->SetActivePage(ctrl_idx
); 
3220             // if the page deleted was the current page for the 
3221             // entire tab control, then record the window 
3222             // pointer of the new active page for activation 
3225                 new_active 
= ctrl
->GetWindowFromIdx(ctrl_idx
); 
3231         // we are not deleting the active page, so keep it the same 
3232         new_active 
= active_wnd
; 
3238         // we haven't yet found a new page to active, 
3239         // so select the next page from the main tab 
3242         if (page_idx 
< m_tabs
.GetPageCount()) 
3244             new_active 
= m_tabs
.GetPage(page_idx
).window
; 
3247         if (!new_active 
&& m_tabs
.GetPageCount() > 0) 
3249             new_active 
= m_tabs
.GetPage(0).window
; 
3254     RemoveEmptyTabFrames(); 
3256     // set new active pane 
3257     if (new_active 
&& !m_isBeingDeleted
) 
3260         SetSelectionToWindow(new_active
); 
3266 // GetPageIndex() returns the index of the page, or -1 if the 
3267 // page could not be located in the notebook 
3268 int wxAuiNotebook::GetPageIndex(wxWindow
* page_wnd
) const 
3270     return m_tabs
.GetIdxFromWindow(page_wnd
); 
3275 // SetPageText() changes the tab caption of the specified page 
3276 bool wxAuiNotebook::SetPageText(size_t page_idx
, const wxString
& text
) 
3278     if (page_idx 
>= m_tabs
.GetPageCount()) 
3281     // update our own tab catalog 
3282     wxAuiNotebookPage
& page_info 
= m_tabs
.GetPage(page_idx
); 
3283     page_info
.caption 
= text
; 
3285     // update what's on screen 
3288     if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
)) 
3290         wxAuiNotebookPage
& info 
= ctrl
->GetPage(ctrl_idx
); 
3291         info
.caption 
= text
; 
3299 // returns the page caption 
3300 wxString 
wxAuiNotebook::GetPageText(size_t page_idx
) const 
3302     if (page_idx 
>= m_tabs
.GetPageCount()) 
3303         return wxEmptyString
; 
3305     // update our own tab catalog 
3306     const wxAuiNotebookPage
& page_info 
= m_tabs
.GetPage(page_idx
); 
3307     return page_info
.caption
; 
3310 bool wxAuiNotebook::SetPageBitmap(size_t page_idx
, const wxBitmap
& bitmap
) 
3312     if (page_idx 
>= m_tabs
.GetPageCount()) 
3315     // update our own tab catalog 
3316     wxAuiNotebookPage
& page_info 
= m_tabs
.GetPage(page_idx
); 
3317     page_info
.bitmap 
= bitmap
; 
3319     // tab height might have changed 
3320     UpdateTabCtrlHeight(); 
3322     // update what's on screen 
3325     if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
)) 
3327         wxAuiNotebookPage
& info 
= ctrl
->GetPage(ctrl_idx
); 
3328         info
.bitmap 
= bitmap
; 
3336 // returns the page bitmap 
3337 wxBitmap 
wxAuiNotebook::GetPageBitmap(size_t page_idx
) const 
3339     if (page_idx 
>= m_tabs
.GetPageCount()) 
3342     // update our own tab catalog 
3343     const wxAuiNotebookPage
& page_info 
= m_tabs
.GetPage(page_idx
); 
3344     return page_info
.bitmap
; 
3347 // GetSelection() returns the index of the currently active page 
3348 int wxAuiNotebook::GetSelection() const 
3353 // SetSelection() sets the currently active page 
3354 size_t wxAuiNotebook::SetSelection(size_t new_page
) 
3356     wxWindow
* wnd 
= m_tabs
.GetWindowFromIdx(new_page
); 
3360     // don't change the page unless necessary; 
3361     // however, clicking again on a tab should give it the focus. 
3362     if ((int)new_page 
== m_curpage
) 
3366         if (FindTab(wnd
, &ctrl
, &ctrl_idx
)) 
3368             if (FindFocus() != ctrl
) 
3374     wxAuiNotebookEvent 
evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
); 
3375     evt
.SetSelection(new_page
); 
3376     evt
.SetOldSelection(m_curpage
); 
3377     evt
.SetEventObject(this); 
3378     if (!GetEventHandler()->ProcessEvent(evt
) || evt
.IsAllowed()) 
3380         int old_curpage 
= m_curpage
; 
3381         m_curpage 
= new_page
; 
3383         // program allows the page change 
3384         evt
.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
); 
3385         (void)GetEventHandler()->ProcessEvent(evt
); 
3390         if (FindTab(wnd
, &ctrl
, &ctrl_idx
)) 
3392             m_tabs
.SetActivePage(wnd
); 
3394             ctrl
->SetActivePage(ctrl_idx
); 
3398             ctrl
->MakeTabVisible(ctrl_idx
, ctrl
); 
3401             wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
3402             size_t i
, pane_count 
= all_panes
.GetCount(); 
3403             for (i 
= 0; i 
< pane_count
; ++i
) 
3405                 wxAuiPaneInfo
& pane 
= all_panes
.Item(i
); 
3406                 if (pane
.name 
== wxT("dummy")) 
3408                 wxAuiTabCtrl
* tabctrl 
= ((wxTabFrame
*)pane
.window
)->m_tabs
; 
3409                 if (tabctrl 
!= ctrl
) 
3410                     tabctrl
->SetSelectedFont(m_normal_font
); 
3412                     tabctrl
->SetSelectedFont(m_selected_font
); 
3416             // Set the focus to the page if we're not currently focused on the tab. 
3417             // This is Firefox-like behaviour. 
3418             if (wnd
->IsShownOnScreen() && FindFocus() != ctrl
) 
3428 void wxAuiNotebook::SetSelectionToWindow(wxWindow 
*win
) 
3430     const int idx 
= m_tabs
.GetIdxFromWindow(win
); 
3431     wxCHECK_RET( idx 
!= wxNOT_FOUND
, _T("invalid notebook page") ); 
3436 // GetPageCount() returns the total number of 
3437 // pages managed by the multi-notebook 
3438 size_t wxAuiNotebook::GetPageCount() const 
3440     return m_tabs
.GetPageCount(); 
3443 // GetPage() returns the wxWindow pointer of the 
3445 wxWindow
* wxAuiNotebook::GetPage(size_t page_idx
) const 
3447     wxASSERT(page_idx 
< m_tabs
.GetPageCount()); 
3449     return m_tabs
.GetWindowFromIdx(page_idx
); 
3452 // DoSizing() performs all sizing operations in each tab control 
3453 void wxAuiNotebook::DoSizing() 
3455     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
3456     size_t i
, pane_count 
= all_panes
.GetCount(); 
3457     for (i 
= 0; i 
< pane_count
; ++i
) 
3459         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
3462         wxTabFrame
* tabframe 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
3463         tabframe
->DoSizing(); 
3467 // GetActiveTabCtrl() returns the active tab control.  It is 
3468 // called to determine which control gets new windows being added 
3469 wxAuiTabCtrl
* wxAuiNotebook::GetActiveTabCtrl() 
3471     if (m_curpage 
>= 0 && m_curpage 
< (int)m_tabs
.GetPageCount()) 
3476         // find the tab ctrl with the current page 
3477         if (FindTab(m_tabs
.GetPage(m_curpage
).window
, 
3484     // no current page, just find the first tab ctrl 
3485     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
3486     size_t i
, pane_count 
= all_panes
.GetCount(); 
3487     for (i 
= 0; i 
< pane_count
; ++i
) 
3489         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
3492         wxTabFrame
* tabframe 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
3493         return tabframe
->m_tabs
; 
3496     // If there is no tabframe at all, create one 
3497     wxTabFrame
* tabframe 
= new wxTabFrame
; 
3498     tabframe
->SetTabCtrlHeight(m_tab_ctrl_height
); 
3499     tabframe
->m_tabs 
= new wxAuiTabCtrl(this, 
3503                                         wxNO_BORDER
|wxWANTS_CHARS
); 
3504     tabframe
->m_tabs
->SetFlags(m_flags
); 
3505     tabframe
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone()); 
3506     m_mgr
.AddPane(tabframe
, 
3507                   wxAuiPaneInfo().Center().CaptionVisible(false)); 
3511     return tabframe
->m_tabs
; 
3514 // FindTab() finds the tab control that currently contains the window as well 
3515 // as the index of the window in the tab control.  It returns true if the 
3516 // window was found, otherwise false. 
3517 bool wxAuiNotebook::FindTab(wxWindow
* page
, wxAuiTabCtrl
** ctrl
, int* idx
) 
3519     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
3520     size_t i
, pane_count 
= all_panes
.GetCount(); 
3521     for (i 
= 0; i 
< pane_count
; ++i
) 
3523         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
3526         wxTabFrame
* tabframe 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
3528         int page_idx 
= tabframe
->m_tabs
->GetIdxFromWindow(page
); 
3531             *ctrl 
= tabframe
->m_tabs
; 
3540 void wxAuiNotebook::Split(size_t page
, int direction
) 
3542     wxSize cli_size 
= GetClientSize(); 
3544     // get the page's window pointer 
3545     wxWindow
* wnd 
= GetPage(page
); 
3549     // notebooks with 1 or less pages can't be split 
3550     if (GetPageCount() < 2) 
3553     // find out which tab control the page currently belongs to 
3554     wxAuiTabCtrl 
*src_tabs
, *dest_tabs
; 
3557     if (!FindTab(wnd
, &src_tabs
, &src_idx
)) 
3559     if (!src_tabs 
|| src_idx 
== -1) 
3562     // choose a split size 
3564     if (GetPageCount() > 2) 
3566         split_size 
= CalculateNewSplitSize(); 
3570         // because there are two panes, always split them 
3572         split_size 
= GetClientSize(); 
3578     // create a new tab frame 
3579     wxTabFrame
* new_tabs 
= new wxTabFrame
; 
3580     new_tabs
->m_rect 
= wxRect(wxPoint(0,0), split_size
); 
3581     new_tabs
->SetTabCtrlHeight(m_tab_ctrl_height
); 
3582     new_tabs
->m_tabs 
= new wxAuiTabCtrl(this, 
3586                                         wxNO_BORDER
|wxWANTS_CHARS
); 
3587     new_tabs
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone()); 
3588     new_tabs
->m_tabs
->SetFlags(m_flags
); 
3589     dest_tabs 
= new_tabs
->m_tabs
; 
3591     // create a pane info structure with the information 
3592     // about where the pane should be added 
3593     wxAuiPaneInfo pane_info 
= wxAuiPaneInfo().Bottom().CaptionVisible(false); 
3596     if (direction 
== wxLEFT
) 
3599         mouse_pt 
= wxPoint(0, cli_size
.y
/2); 
3601     else if (direction 
== wxRIGHT
) 
3604         mouse_pt 
= wxPoint(cli_size
.x
, cli_size
.y
/2); 
3606     else if (direction 
== wxTOP
) 
3609         mouse_pt 
= wxPoint(cli_size
.x
/2, 0); 
3611     else if (direction 
== wxBOTTOM
) 
3614         mouse_pt 
= wxPoint(cli_size
.x
/2, cli_size
.y
); 
3617     m_mgr
.AddPane(new_tabs
, pane_info
, mouse_pt
); 
3620     // remove the page from the source tabs 
3621     wxAuiNotebookPage page_info 
= src_tabs
->GetPage(src_idx
); 
3622     page_info
.active 
= false; 
3623     src_tabs
->RemovePage(page_info
.window
); 
3624     if (src_tabs
->GetPageCount() > 0) 
3626         src_tabs
->SetActivePage((size_t)0); 
3627         src_tabs
->DoShowHide(); 
3628         src_tabs
->Refresh(); 
3632     // add the page to the destination tabs 
3633     dest_tabs
->InsertPage(page_info
.window
, page_info
, 0); 
3635     if (src_tabs
->GetPageCount() == 0) 
3637         RemoveEmptyTabFrames(); 
3641     dest_tabs
->DoShowHide(); 
3642     dest_tabs
->Refresh(); 
3644     // force the set selection function reset the selection 
3647     // set the active page to the one we just split off 
3648     SetSelectionToPage(page_info
); 
3650     UpdateHintWindowSize(); 
3654 void wxAuiNotebook::OnSize(wxSizeEvent
& evt
) 
3656     UpdateHintWindowSize(); 
3661 void wxAuiNotebook::OnTabClicked(wxCommandEvent
& command_evt
) 
3663     wxAuiNotebookEvent
& evt 
= (wxAuiNotebookEvent
&)command_evt
; 
3665     wxAuiTabCtrl
* ctrl 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
3666     wxASSERT(ctrl 
!= NULL
); 
3668     wxWindow
* wnd 
= ctrl
->GetWindowFromIdx(evt
.GetSelection()); 
3669     wxASSERT(wnd 
!= NULL
); 
3671     SetSelectionToWindow(wnd
); 
3674 void wxAuiNotebook::OnTabBgDClick(wxCommandEvent
& WXUNUSED(evt
)) 
3676     // notify owner that the tabbar background has been double-clicked 
3677     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
, m_windowId
); 
3678     e
.SetEventObject(this); 
3679     GetEventHandler()->ProcessEvent(e
); 
3682 void wxAuiNotebook::OnTabBeginDrag(wxCommandEvent
&) 
3687 void wxAuiNotebook::OnTabDragMotion(wxCommandEvent
& evt
) 
3689     wxPoint screen_pt 
= ::wxGetMousePosition(); 
3690     wxPoint client_pt 
= ScreenToClient(screen_pt
); 
3693     wxAuiTabCtrl
* src_tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
3694     wxAuiTabCtrl
* dest_tabs 
= GetTabCtrlFromPoint(client_pt
); 
3696     if (dest_tabs 
== src_tabs
) 
3700             src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
)); 
3703         // always hide the hint for inner-tabctrl drag 
3706         // if tab moving is not allowed, leave 
3707         if (!(m_flags 
& wxAUI_NB_TAB_MOVE
)) 
3712         wxPoint pt 
= dest_tabs
->ScreenToClient(screen_pt
); 
3713         wxWindow
* dest_location_tab
; 
3715         // this is an inner-tab drag/reposition 
3716         if (dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &dest_location_tab
)) 
3718             int src_idx 
= evt
.GetSelection(); 
3719             int dest_idx 
= dest_tabs
->GetIdxFromWindow(dest_location_tab
); 
3721             // prevent jumpy drag 
3722             if ((src_idx 
== dest_idx
) || dest_idx 
== -1 || 
3723                 (src_idx 
> dest_idx 
&& m_last_drag_x 
<= pt
.x
) || 
3724                 (src_idx 
< dest_idx 
&& m_last_drag_x 
>= pt
.x
)) 
3726                 m_last_drag_x 
= pt
.x
; 
3731             wxWindow
* src_tab 
= dest_tabs
->GetWindowFromIdx(src_idx
); 
3732             dest_tabs
->MovePage(src_tab
, dest_idx
); 
3733             dest_tabs
->SetActivePage((size_t)dest_idx
); 
3734             dest_tabs
->DoShowHide(); 
3735             dest_tabs
->Refresh(); 
3736             m_last_drag_x 
= pt
.x
; 
3744     // if external drag is allowed, check if the tab is being dragged 
3745     // over a different wxAuiNotebook control 
3746     if (m_flags 
& wxAUI_NB_TAB_EXTERNAL_MOVE
) 
3748         wxWindow
* tab_ctrl 
= ::wxFindWindowAtPoint(screen_pt
); 
3750         // if we aren't over any window, stop here 
3754         // make sure we are not over the hint window 
3755         if (!tab_ctrl
->IsKindOf(CLASSINFO(wxFrame
))) 
3759                 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
))) 
3761                 tab_ctrl 
= tab_ctrl
->GetParent(); 
3766                 wxAuiNotebook
* nb 
= (wxAuiNotebook
*)tab_ctrl
->GetParent(); 
3770                     wxRect hint_rect 
= tab_ctrl
->GetClientRect(); 
3771                     tab_ctrl
->ClientToScreen(&hint_rect
.x
, &hint_rect
.y
); 
3772                     m_mgr
.ShowHint(hint_rect
); 
3781                 // we are either over a hint window, or not over a tab 
3782                 // window, and there is no where to drag to, so exit 
3789     // if there are less than two panes, split can't happen, so leave 
3790     if (m_tabs
.GetPageCount() < 2) 
3793     // if tab moving is not allowed, leave 
3794     if (!(m_flags 
& wxAUI_NB_TAB_SPLIT
)) 
3800         src_tabs
->SetCursor(wxCursor(wxCURSOR_SIZING
)); 
3806         wxRect hint_rect 
= dest_tabs
->GetRect(); 
3807         ClientToScreen(&hint_rect
.x
, &hint_rect
.y
); 
3808         m_mgr
.ShowHint(hint_rect
); 
3812         m_mgr
.DrawHintRect(m_dummy_wnd
, client_pt
, zero
); 
3818 void wxAuiNotebook::OnTabEndDrag(wxCommandEvent
& command_evt
) 
3820     wxAuiNotebookEvent
& evt 
= (wxAuiNotebookEvent
&)command_evt
; 
3825     wxAuiTabCtrl
* src_tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
3826     wxCHECK_RET( src_tabs
, _T("no source object?") ); 
3828     src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
)); 
3830     // get the mouse position, which will be used to determine the drop point 
3831     wxPoint mouse_screen_pt 
= ::wxGetMousePosition(); 
3832     wxPoint mouse_client_pt 
= ScreenToClient(mouse_screen_pt
); 
3836     // check for an external move 
3837     if (m_flags 
& wxAUI_NB_TAB_EXTERNAL_MOVE
) 
3839         wxWindow
* tab_ctrl 
= ::wxFindWindowAtPoint(mouse_screen_pt
); 
3843             if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
))) 
3845             tab_ctrl 
= tab_ctrl
->GetParent(); 
3850             wxAuiNotebook
* nb 
= (wxAuiNotebook
*)tab_ctrl
->GetParent(); 
3854                 // find out from the destination control 
3855                 // if it's ok to drop this tab here 
3856                 wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
, m_windowId
); 
3857                 e
.SetSelection(evt
.GetSelection()); 
3858                 e
.SetOldSelection(evt
.GetSelection()); 
3859                 e
.SetEventObject(this); 
3860                 e
.SetDragSource(this); 
3861                 e
.Veto(); // dropping must be explicitly approved by control owner 
3863                 nb
->GetEventHandler()->ProcessEvent(e
); 
3867                     // no answer or negative answer 
3873                 int src_idx 
= evt
.GetSelection(); 
3874                 wxWindow
* src_page 
= src_tabs
->GetWindowFromIdx(src_idx
); 
3876                 // Check that it's not an impossible parent relationship 
3878                 while (p 
&& !p
->IsTopLevel()) 
3887                 // get main index of the page 
3888                 int main_idx 
= m_tabs
.GetIdxFromWindow(src_page
); 
3889                 wxCHECK_RET( main_idx 
!= wxNOT_FOUND
, _T("no source page?") ); 
3892                 // make a copy of the page info 
3893                 wxAuiNotebookPage page_info 
= m_tabs
.GetPage(main_idx
); 
3895                 // remove the page from the source notebook 
3896                 RemovePage(main_idx
); 
3898                 // reparent the page 
3899                 src_page
->Reparent(nb
); 
3902                 // found out the insert idx 
3903                 wxAuiTabCtrl
* dest_tabs 
= (wxAuiTabCtrl
*)tab_ctrl
; 
3904                 wxPoint pt 
= dest_tabs
->ScreenToClient(mouse_screen_pt
); 
3906                 wxWindow
* target 
= NULL
; 
3907                 int insert_idx 
= -1; 
3908                 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
); 
3911                     insert_idx 
= dest_tabs
->GetIdxFromWindow(target
); 
3915                 // add the page to the new notebook 
3916                 if (insert_idx 
== -1) 
3917                     insert_idx 
= dest_tabs
->GetPageCount(); 
3918                 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
); 
3919                 nb
->m_tabs
.AddPage(page_info
.window
, page_info
); 
3922                 dest_tabs
->DoShowHide(); 
3923                 dest_tabs
->Refresh(); 
3925                 // set the selection in the destination tab control 
3926                 nb
->SetSelectionToPage(page_info
); 
3928                 // notify owner that the tab has been dragged 
3929                 wxAuiNotebookEvent 
e2(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE
, m_windowId
); 
3930                 e2
.SetSelection(evt
.GetSelection()); 
3931                 e2
.SetOldSelection(evt
.GetSelection()); 
3932                 e2
.SetEventObject(this); 
3933                 GetEventHandler()->ProcessEvent(e2
); 
3943     // only perform a tab split if it's allowed 
3944     wxAuiTabCtrl
* dest_tabs 
= NULL
; 
3946     if ((m_flags 
& wxAUI_NB_TAB_SPLIT
) && m_tabs
.GetPageCount() >= 2) 
3948         // If the pointer is in an existing tab frame, do a tab insert 
3949         wxWindow
* hit_wnd 
= ::wxFindWindowAtPoint(mouse_screen_pt
); 
3950         wxTabFrame
* tab_frame 
= (wxTabFrame
*)GetTabFrameFromTabCtrl(hit_wnd
); 
3951         int insert_idx 
= -1; 
3954             dest_tabs 
= tab_frame
->m_tabs
; 
3956             if (dest_tabs 
== src_tabs
) 
3960             wxPoint pt 
= dest_tabs
->ScreenToClient(mouse_screen_pt
); 
3961             wxWindow
* target 
= NULL
; 
3962             dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
); 
3965                 insert_idx 
= dest_tabs
->GetIdxFromWindow(target
); 
3971             wxRect rect 
= m_mgr
.CalculateHintRect(m_dummy_wnd
, 
3976                 // there is no suitable drop location here, exit out 
3980             // If there is no tabframe at all, create one 
3981             wxTabFrame
* new_tabs 
= new wxTabFrame
; 
3982             new_tabs
->m_rect 
= wxRect(wxPoint(0,0), CalculateNewSplitSize()); 
3983             new_tabs
->SetTabCtrlHeight(m_tab_ctrl_height
); 
3984             new_tabs
->m_tabs 
= new wxAuiTabCtrl(this, 
3988                                                 wxNO_BORDER
|wxWANTS_CHARS
); 
3989             new_tabs
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone()); 
3990             new_tabs
->m_tabs
->SetFlags(m_flags
); 
3992             m_mgr
.AddPane(new_tabs
, 
3993                           wxAuiPaneInfo().Bottom().CaptionVisible(false), 
3996             dest_tabs 
= new_tabs
->m_tabs
; 
4001         // remove the page from the source tabs 
4002         wxAuiNotebookPage page_info 
= src_tabs
->GetPage(evt
.GetSelection()); 
4003         page_info
.active 
= false; 
4004         src_tabs
->RemovePage(page_info
.window
); 
4005         if (src_tabs
->GetPageCount() > 0) 
4007             src_tabs
->SetActivePage((size_t)0); 
4008             src_tabs
->DoShowHide(); 
4009             src_tabs
->Refresh(); 
4014         // add the page to the destination tabs 
4015         if (insert_idx 
== -1) 
4016             insert_idx 
= dest_tabs
->GetPageCount(); 
4017         dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
); 
4019         if (src_tabs
->GetPageCount() == 0) 
4021             RemoveEmptyTabFrames(); 
4025         dest_tabs
->DoShowHide(); 
4026         dest_tabs
->Refresh(); 
4028         // force the set selection function reset the selection 
4031         // set the active page to the one we just split off 
4032         SetSelectionToPage(page_info
); 
4034         UpdateHintWindowSize(); 
4037     // notify owner that the tab has been dragged 
4038     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE
, m_windowId
); 
4039     e
.SetSelection(evt
.GetSelection()); 
4040     e
.SetOldSelection(evt
.GetSelection()); 
4041     e
.SetEventObject(this); 
4042     GetEventHandler()->ProcessEvent(e
); 
4047 wxAuiTabCtrl
* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint
& pt
) 
4049     // if we've just removed the last tab from the source 
4050     // tab set, the remove the tab control completely 
4051     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
4052     size_t i
, pane_count 
= all_panes
.GetCount(); 
4053     for (i 
= 0; i 
< pane_count
; ++i
) 
4055         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
4058         wxTabFrame
* tabframe 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
4059         if (tabframe
->m_tab_rect
.Contains(pt
)) 
4060             return tabframe
->m_tabs
; 
4066 wxWindow
* wxAuiNotebook::GetTabFrameFromTabCtrl(wxWindow
* tab_ctrl
) 
4068     // if we've just removed the last tab from the source 
4069     // tab set, the remove the tab control completely 
4070     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
4071     size_t i
, pane_count 
= all_panes
.GetCount(); 
4072     for (i 
= 0; i 
< pane_count
; ++i
) 
4074         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
4077         wxTabFrame
* tabframe 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
4078         if (tabframe
->m_tabs 
== tab_ctrl
) 
4087 void wxAuiNotebook::RemoveEmptyTabFrames() 
4089     // if we've just removed the last tab from the source 
4090     // tab set, the remove the tab control completely 
4091     wxAuiPaneInfoArray all_panes 
= m_mgr
.GetAllPanes(); 
4092     size_t i
, pane_count 
= all_panes
.GetCount(); 
4093     for (i 
= 0; i 
< pane_count
; ++i
) 
4095         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
4098         wxTabFrame
* tab_frame 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
4099         if (tab_frame
->m_tabs
->GetPageCount() == 0) 
4101             m_mgr
.DetachPane(tab_frame
); 
4103             // use pending delete because sometimes during 
4104             // window closing, refreshs are pending 
4105             if (!wxPendingDelete
.Member(tab_frame
->m_tabs
)) 
4106                 wxPendingDelete
.Append(tab_frame
->m_tabs
); 
4108             tab_frame
->m_tabs 
= NULL
; 
4115     // check to see if there is still a center pane; 
4116     // if there isn't, make a frame the center pane 
4117     wxAuiPaneInfoArray panes 
= m_mgr
.GetAllPanes(); 
4118     pane_count 
= panes
.GetCount(); 
4119     wxWindow
* first_good 
= NULL
; 
4120     bool center_found 
= false; 
4121     for (i 
= 0; i 
< pane_count
; ++i
) 
4123         if (panes
.Item(i
).name 
== wxT("dummy")) 
4125         if (panes
.Item(i
).dock_direction 
== wxAUI_DOCK_CENTRE
) 
4126             center_found 
= true; 
4128             first_good 
= panes
.Item(i
).window
; 
4131     if (!center_found 
&& first_good
) 
4133         m_mgr
.GetPane(first_good
).Centre(); 
4136     if (!m_isBeingDeleted
) 
4140 void wxAuiNotebook::OnChildFocusNotebook(wxChildFocusEvent
& evt
) 
4142     // if we're dragging a tab, don't change the current selection. 
4143     // This code prevents a bug that used to happen when the hint window 
4144     // was hidden.  In the bug, the focus would return to the notebook 
4145     // child, which would then enter this handler and call 
4146     // SetSelection, which is not desired turn tab dragging. 
4148     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
4149     size_t i
, pane_count 
= all_panes
.GetCount(); 
4150     for (i 
= 0; i 
< pane_count
; ++i
) 
4152         wxAuiPaneInfo
& pane 
= all_panes
.Item(i
); 
4153         if (pane
.name 
== wxT("dummy")) 
4155         wxTabFrame
* tabframe 
= (wxTabFrame
*)pane
.window
; 
4156         if (tabframe
->m_tabs
->IsDragging()) 
4161     // change the tab selection to the child 
4162     // which was focused 
4163     int idx 
= m_tabs
.GetIdxFromWindow(evt
.GetWindow()); 
4164     if (idx 
!= -1 && idx 
!= m_curpage
) 
4170 void wxAuiNotebook::OnNavigationKeyNotebook(wxNavigationKeyEvent
& event
) 
4172     if ( event
.IsWindowChange() ) { 
4174         // FIXME: the problem with this is that if we have a split notebook, 
4175         // we selection may go all over the place. 
4176         AdvanceSelection(event
.GetDirection()); 
4179         // we get this event in 3 cases 
4181         // a) one of our pages might have generated it because the user TABbed 
4182         // out from it in which case we should propagate the event upwards and 
4183         // our parent will take care of setting the focus to prev/next sibling 
4187         // b) the parent panel wants to give the focus to us so that we 
4188         // forward it to our selected page. We can't deal with this in 
4189         // OnSetFocus() because we don't know which direction the focus came 
4190         // from in this case and so can't choose between setting the focus to 
4191         // first or last panel child 
4195         // c) we ourselves (see MSWTranslateMessage) generated the event 
4197         wxWindow 
* const parent 
= GetParent(); 
4199         // the wxObject* casts are required to avoid MinGW GCC 2.95.3 ICE 
4200         const bool isFromParent 
= event
.GetEventObject() == (wxObject
*) parent
; 
4201         const bool isFromSelf 
= event
.GetEventObject() == (wxObject
*) this; 
4203         if ( isFromParent 
|| isFromSelf 
) 
4205             // no, it doesn't come from child, case (b) or (c): forward to a 
4206             // page but only if direction is backwards (TAB) or from ourselves, 
4207             if ( GetSelection() != wxNOT_FOUND 
&& 
4208                     (!event
.GetDirection() || isFromSelf
) ) 
4210                 // so that the page knows that the event comes from it's parent 
4211                 // and is being propagated downwards 
4212                 event
.SetEventObject(this); 
4214                 wxWindow 
*page 
= GetPage(GetSelection()); 
4215                 if ( !page
->GetEventHandler()->ProcessEvent(event
) ) 
4219                 //else: page manages focus inside it itself 
4221             else // otherwise set the focus to the notebook itself 
4228             // it comes from our child, case (a), pass to the parent, but only 
4229             // if the direction is forwards. Otherwise set the focus to the 
4230             // notebook itself. The notebook is always the 'first' control of a 
4232             if ( !event
.GetDirection() ) 
4238                 event
.SetCurrentFocus(this); 
4239                 parent
->GetEventHandler()->ProcessEvent(event
); 
4245 void wxAuiNotebook::OnTabButton(wxCommandEvent
& command_evt
) 
4247     wxAuiNotebookEvent
& evt 
= (wxAuiNotebookEvent
&)command_evt
; 
4248     wxAuiTabCtrl
* tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
4250     int button_id 
= evt
.GetInt(); 
4252     if (button_id 
== wxAUI_BUTTON_CLOSE
) 
4254         int selection 
= evt
.GetSelection(); 
4256         if (selection 
== -1) 
4258             // if the close button is to the right, use the active 
4259             // page selection to determine which page to close 
4260             selection 
= GetSelection(); 
4263         if (selection 
!= -1) 
4265             wxWindow
* close_wnd 
= tabs
->GetWindowFromIdx(selection
); 
4267             // ask owner if it's ok to close the tab 
4268             wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
, m_windowId
); 
4269             e
.SetSelection(m_tabs
.GetIdxFromWindow(close_wnd
)); 
4270             const int idx 
= m_tabs
.GetIdxFromWindow(close_wnd
); 
4271             e
.SetSelection(idx
); 
4272             e
.SetOldSelection(evt
.GetSelection()); 
4273             e
.SetEventObject(this); 
4274             GetEventHandler()->ProcessEvent(e
); 
4280             if (close_wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
))) 
4287                 int main_idx 
= m_tabs
.GetIdxFromWindow(close_wnd
); 
4288                 wxCHECK_RET( main_idx 
!= wxNOT_FOUND
, _T("no page to delete?") ); 
4290                 DeletePage(main_idx
); 
4293             // notify owner that the tab has been closed 
4294             wxAuiNotebookEvent 
e2(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED
, m_windowId
); 
4295             e2
.SetSelection(idx
); 
4296             e2
.SetEventObject(this); 
4297             GetEventHandler()->ProcessEvent(e2
); 
4303 void wxAuiNotebook::OnTabMiddleDown(wxCommandEvent
& evt
) 
4305     // patch event through to owner 
4306     wxAuiTabCtrl
* tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
4307     wxWindow
* wnd 
= tabs
->GetWindowFromIdx(evt
.GetSelection()); 
4309     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
, m_windowId
); 
4310     e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
)); 
4311     e
.SetEventObject(this); 
4312     GetEventHandler()->ProcessEvent(e
); 
4315 void wxAuiNotebook::OnTabMiddleUp(wxCommandEvent
& evt
) 
4317     // if the wxAUI_NB_MIDDLE_CLICK_CLOSE is specified, middle 
4318     // click should act like a tab close action.  However, first 
4319     // give the owner an opportunity to handle the middle up event 
4320     // for custom action 
4322     wxAuiTabCtrl
* tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
4323     wxWindow
* wnd 
= tabs
->GetWindowFromIdx(evt
.GetSelection()); 
4325     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
, m_windowId
); 
4326     e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
)); 
4327     e
.SetEventObject(this); 
4328     if (GetEventHandler()->ProcessEvent(e
)) 
4333     // check if we are supposed to close on middle-up 
4334     if ((m_flags 
& wxAUI_NB_MIDDLE_CLICK_CLOSE
) == 0) 
4337     // simulate the user pressing the close button on the tab 
4338     evt
.SetInt(wxAUI_BUTTON_CLOSE
); 
4342 void wxAuiNotebook::OnTabRightDown(wxCommandEvent
& evt
) 
4344     // patch event through to owner 
4345     wxAuiTabCtrl
* tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
4346     wxWindow
* wnd 
= tabs
->GetWindowFromIdx(evt
.GetSelection()); 
4348     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
, m_windowId
); 
4349     e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
)); 
4350     e
.SetEventObject(this); 
4351     GetEventHandler()->ProcessEvent(e
); 
4354 void wxAuiNotebook::OnTabRightUp(wxCommandEvent
& evt
) 
4356     // patch event through to owner 
4357     wxAuiTabCtrl
* tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
4358     wxWindow
* wnd 
= tabs
->GetWindowFromIdx(evt
.GetSelection()); 
4360     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
, m_windowId
); 
4361     e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
)); 
4362     e
.SetEventObject(this); 
4363     GetEventHandler()->ProcessEvent(e
); 
4366 // Sets the normal font 
4367 void wxAuiNotebook::SetNormalFont(const wxFont
& font
) 
4369     m_normal_font 
= font
; 
4370     GetArtProvider()->SetNormalFont(font
); 
4373 // Sets the selected tab font 
4374 void wxAuiNotebook::SetSelectedFont(const wxFont
& font
) 
4376     m_selected_font 
= font
; 
4377     GetArtProvider()->SetSelectedFont(font
); 
4380 // Sets the measuring font 
4381 void wxAuiNotebook::SetMeasuringFont(const wxFont
& font
) 
4383     GetArtProvider()->SetMeasuringFont(font
); 
4386 // Sets the tab font 
4387 bool wxAuiNotebook::SetFont(const wxFont
& font
) 
4389     wxControl::SetFont(font
); 
4391     wxFont 
normalFont(font
); 
4392     wxFont 
selectedFont(normalFont
); 
4393     selectedFont
.SetWeight(wxBOLD
); 
4395     SetNormalFont(normalFont
); 
4396     SetSelectedFont(selectedFont
); 
4397     SetMeasuringFont(selectedFont
); 
4402 // Gets the tab control height 
4403 int wxAuiNotebook::GetTabCtrlHeight() const 
4405     return m_tab_ctrl_height
; 
4408 // Gets the height of the notebook for a given page height 
4409 int wxAuiNotebook::GetHeightForPageHeight(int pageHeight
) 
4411     UpdateTabCtrlHeight(); 
4413     int tabCtrlHeight 
= GetTabCtrlHeight(); 
4414     int decorHeight 
= 2; 
4415     return tabCtrlHeight 
+ pageHeight 
+ decorHeight
; 
4418 // Advances the selection, generation page selection events 
4419 void wxAuiNotebook::AdvanceSelection(bool forward
) 
4421     if (GetPageCount() <= 1) 
4424     int currentSelection 
= GetSelection(); 
4428         if (currentSelection 
== (int) (GetPageCount() - 1)) 
4430         else if (currentSelection 
== -1) 
4431             currentSelection 
= 0; 
4433             currentSelection 
++; 
4437         if (currentSelection 
<= 0) 
4440             currentSelection 
--; 
4443     SetSelection(currentSelection
); 
4446 // Shows the window menu 
4447 bool wxAuiNotebook::ShowWindowMenu() 
4449     wxAuiTabCtrl
* tabCtrl 
= GetActiveTabCtrl(); 
4451     int idx 
= tabCtrl
->GetArtProvider()->ShowDropDown(tabCtrl
, tabCtrl
->GetPages(), tabCtrl
->GetActivePage()); 
4455         wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, tabCtrl
->GetId()); 
4456         e
.SetSelection(idx
); 
4457         e
.SetOldSelection(tabCtrl
->GetActivePage()); 
4458         e
.SetEventObject(tabCtrl
); 
4459         GetEventHandler()->ProcessEvent(e
);