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/private.h" 
  38 // for themeing support 
  39 #include <Carbon/Carbon.h> 
  42 #include "wx/arrimpl.cpp" 
  43 WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray
) 
  44 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray
) 
  46 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
) 
  47 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED
) 
  48 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
) 
  49 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
) 
  50 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
) 
  51 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
) 
  52 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
) 
  53 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
) 
  54 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
) 
  55 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
) 
  56 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE
) 
  57 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
) 
  58 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
) 
  59 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
) 
  60 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
) 
  62 IMPLEMENT_CLASS(wxAuiNotebook
, wxControl
) 
  63 IMPLEMENT_CLASS(wxAuiTabCtrl
, wxControl
) 
  64 IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent
, wxEvent
) 
  70 // these functions live in dockart.cpp -- they'll eventually 
  71 // be moved to a new utility cpp file 
  73 wxColor 
wxAuiStepColour(const wxColor
& c
, int percent
); 
  75 wxBitmap 
wxAuiBitmapFromBits(const unsigned char bits
[], int w
, int h
, 
  76                              const wxColour
& color
); 
  78 wxString 
wxAuiChopText(wxDC
& dc
, const wxString
& text
, int max_size
); 
  80 static void DrawButtons(wxDC
& dc
, 
  83                         const wxColour
& bkcolour
, 
  88     if (button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
  94     if (button_state 
== wxAUI_BUTTON_STATE_HOVER 
|| 
  95         button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
  97         dc
.SetBrush(wxBrush(wxAuiStepColour(bkcolour
, 120))); 
  98         dc
.SetPen(wxPen(wxAuiStepColour(bkcolour
, 75))); 
 100         // draw the background behind the button 
 101         dc
.DrawRectangle(rect
.x
, rect
.y
, 15, 15); 
 104     // draw the button itself 
 105     dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true); 
 108 static void IndentPressedBitmap(wxRect
* rect
, int button_state
) 
 110     if (button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
 119 // -- GUI helper classes and functions -- 
 121 class wxAuiCommandCapture 
: public wxEvtHandler
 
 125     wxAuiCommandCapture() { m_last_id 
= 0; } 
 126     int GetCommandId() const { return m_last_id
; } 
 128     bool ProcessEvent(wxEvent
& evt
) 
 130         if (evt
.GetEventType() == wxEVT_COMMAND_MENU_SELECTED
) 
 132             m_last_id 
= evt
.GetId(); 
 136         if (GetNextHandler()) 
 137             return GetNextHandler()->ProcessEvent(evt
); 
 149 #if defined( __WXMAC__ ) 
 150  static unsigned char close_bits
[]={ 
 151      0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3, 
 152      0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3, 
 153      0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF }; 
 154 #elif defined( __WXGTK__) 
 155  static unsigned char close_bits
[]={ 
 156      0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8, 
 157      0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef, 
 158      0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 
 160  static unsigned char close_bits
[]={ 
 161      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9, 
 162      0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3, 
 163      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 166 static unsigned char left_bits
[] = { 
 167    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe, 
 168    0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe, 
 169    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 171 static unsigned char right_bits
[] = { 
 172    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff, 
 173    0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff, 
 174    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 176 static unsigned char list_bits
[] = { 
 177    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
 178    0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff, 
 179    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 186 // -- wxAuiDefaultTabArt class implementation -- 
 188 wxAuiDefaultTabArt::wxAuiDefaultTabArt() 
 190     m_normal_font 
= *wxNORMAL_FONT
; 
 191     m_selected_font 
= *wxNORMAL_FONT
; 
 192     m_selected_font
.SetWeight(wxBOLD
); 
 193     m_measuring_font 
= m_selected_font
; 
 195     m_fixed_tab_width 
= 100; 
 196     m_tab_ctrl_height 
= 0; 
 198 #if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON 
 199     wxColor base_colour 
= wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground
)); 
 201     wxColor base_colour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 204     // the base_colour is too pale to use as our base colour, 
 205     // so darken it a bit -- 
 206     if ((255-base_colour
.Red()) + 
 207         (255-base_colour
.Green()) + 
 208         (255-base_colour
.Blue()) < 60) 
 210         base_colour 
= wxAuiStepColour(base_colour
, 92); 
 213     m_base_colour 
= base_colour
; 
 214     wxColor border_colour 
= wxAuiStepColour(base_colour
, 75); 
 216     m_border_pen 
= wxPen(border_colour
); 
 217     m_base_colour_pen 
= wxPen(m_base_colour
); 
 218     m_base_colour_brush 
= wxBrush(m_base_colour
); 
 220     m_active_close_bmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
); 
 221     m_disabled_close_bmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128)); 
 223     m_active_left_bmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
); 
 224     m_disabled_left_bmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128)); 
 226     m_active_right_bmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
); 
 227     m_disabled_right_bmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128)); 
 229     m_active_windowlist_bmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
); 
 230     m_disabled_windowlist_bmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128)); 
 235 wxAuiDefaultTabArt::~wxAuiDefaultTabArt() 
 239 wxAuiTabArt
* wxAuiDefaultTabArt::Clone() 
 241     wxAuiDefaultTabArt
* art 
= new wxAuiDefaultTabArt
; 
 242     art
->SetNormalFont(m_normal_font
); 
 243     art
->SetSelectedFont(m_selected_font
); 
 244     art
->SetMeasuringFont(m_measuring_font
); 
 249 void wxAuiDefaultTabArt::SetFlags(unsigned int flags
) 
 254 void wxAuiDefaultTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
, 
 257     m_fixed_tab_width 
= 100; 
 259     int tot_width 
= (int)tab_ctrl_size
.x 
- GetIndentSize() - 4; 
 261     if (m_flags 
& wxAUI_NB_CLOSE_BUTTON
) 
 262         tot_width 
-= m_active_close_bmp
.GetWidth(); 
 263     if (m_flags 
& wxAUI_NB_WINDOWLIST_BUTTON
) 
 264         tot_width 
-= m_active_windowlist_bmp
.GetWidth(); 
 268         m_fixed_tab_width 
= tot_width
/(int)tab_count
; 
 272     if (m_fixed_tab_width 
< 100) 
 273         m_fixed_tab_width 
= 100; 
 275     if (m_fixed_tab_width 
> tot_width
/2) 
 276         m_fixed_tab_width 
= tot_width
/2; 
 278     if (m_fixed_tab_width 
> 220) 
 279         m_fixed_tab_width 
= 220; 
 281     m_tab_ctrl_height 
= tab_ctrl_size
.y
; 
 285 void wxAuiDefaultTabArt::DrawBackground(wxDC
& dc
, 
 286                                         wxWindow
* WXUNUSED(wnd
), 
 291     wxColor top_color       
= wxAuiStepColour(m_base_colour
, 90); 
 292     wxColor bottom_color   
= wxAuiStepColour(m_base_colour
, 170); 
 295    if (m_flags 
&wxAUI_NB_BOTTOM
) 
 296        r 
= wxRect(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
); 
 297    // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 298    // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 299    else //for wxAUI_NB_TOP 
 300        r 
= wxRect(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
-3); 
 302     dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
); 
 307    dc
.SetPen(m_border_pen
); 
 308    int y 
= rect
.GetHeight(); 
 309    int w 
= rect
.GetWidth(); 
 311    if (m_flags 
&wxAUI_NB_BOTTOM
) 
 313        dc
.SetBrush(wxBrush(bottom_color
)); 
 314        dc
.DrawRectangle(-1, 0, w
+2, 4); 
 316    // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 317    // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 318    else //for wxAUI_NB_TOP 
 320        dc
.SetBrush(m_base_colour_brush
); 
 321        dc
.DrawRectangle(-1, y
-4, w
+2, 4); 
 326 // DrawTab() draws an individual tab. 
 329 // in_rect  - rectangle the tab should be confined to 
 330 // caption  - tab's caption 
 331 // active   - whether or not the tab is active 
 332 // out_rect - actual output rectangle 
 333 // x_extent - the advance x; where the next tab should start 
 335 void wxAuiDefaultTabArt::DrawTab(wxDC
& dc
, 
 337                                  const wxAuiNotebookPage
& page
, 
 338                                  const wxRect
& in_rect
, 
 339                                  int close_button_state
, 
 340                                  wxRect
* out_tab_rect
, 
 341                                  wxRect
* out_button_rect
, 
 344     wxCoord normal_textx
, normal_texty
; 
 345     wxCoord selected_textx
, selected_texty
; 
 348     // if the caption is empty, measure some temporary text 
 349     wxString caption 
= page
.caption
; 
 353     dc
.SetFont(m_selected_font
); 
 354     dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
); 
 356     dc
.SetFont(m_normal_font
); 
 357     dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
); 
 359     // figure out the size of the tab 
 360     wxSize tab_size 
= GetTabSize(dc
, 
 368     wxCoord tab_height 
= m_tab_ctrl_height 
- 3; 
 369     wxCoord tab_width 
= tab_size
.x
; 
 370     wxCoord tab_x 
= in_rect
.x
; 
 371     wxCoord tab_y 
= in_rect
.y 
+ in_rect
.height 
- tab_height
; 
 374     caption 
= page
.caption
; 
 377     // select pen, brush and font for the tab to be drawn 
 381         dc
.SetFont(m_selected_font
); 
 382         texty 
= selected_texty
; 
 386         dc
.SetFont(m_normal_font
); 
 387         texty 
= normal_texty
; 
 391     // create points that will make the tab outline 
 393     int clip_width 
= tab_width
; 
 394     if (tab_x 
+ clip_width 
> in_rect
.x 
+ in_rect
.width
) 
 395         clip_width 
= (in_rect
.x 
+ in_rect
.width
) - tab_x
; 
 398     wxPoint clip_points[6]; 
 399     clip_points[0] = wxPoint(tab_x,              tab_y+tab_height-3); 
 400     clip_points[1] = wxPoint(tab_x,              tab_y+2); 
 401     clip_points[2] = wxPoint(tab_x+2,            tab_y); 
 402     clip_points[3] = wxPoint(tab_x+clip_width-1, tab_y); 
 403     clip_points[4] = wxPoint(tab_x+clip_width+1, tab_y+2); 
 404     clip_points[5] = wxPoint(tab_x+clip_width+1, tab_y+tab_height-3); 
 406     // FIXME: these ports don't provide wxRegion ctor from array of points 
 407 #if !defined(__WXDFB__) && !defined(__WXCOCOA__) 
 408     // set the clipping region for the tab -- 
 409     wxRegion clipping_region(WXSIZEOF(clip_points), clip_points); 
 410     dc.SetClippingRegion(clipping_region); 
 411 #endif // !wxDFB && !wxCocoa 
 413     // since the above code above doesn't play well with WXDFB or WXCOCOA, 
 414     // we'll just use a rectangle for the clipping region for now -- 
 415     dc
.SetClippingRegion(tab_x
, tab_y
, clip_width
+1, tab_height
-3); 
 418     wxPoint border_points
[6]; 
 419     if (m_flags 
&wxAUI_NB_BOTTOM
) 
 421         border_points
[0] = wxPoint(tab_x
,             tab_y
); 
 422         border_points
[1] = wxPoint(tab_x
,             tab_y
+tab_height
-6); 
 423         border_points
[2] = wxPoint(tab_x
+2,           tab_y
+tab_height
-4); 
 424         border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
+tab_height
-4); 
 425         border_points
[4] = wxPoint(tab_x
+tab_width
,   tab_y
+tab_height
-6); 
 426         border_points
[5] = wxPoint(tab_x
+tab_width
,   tab_y
); 
 428     else //if (m_flags & wxAUI_NB_TOP) {} 
 430         border_points
[0] = wxPoint(tab_x
,             tab_y
+tab_height
-4); 
 431         border_points
[1] = wxPoint(tab_x
,             tab_y
+2); 
 432         border_points
[2] = wxPoint(tab_x
+2,           tab_y
); 
 433         border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
); 
 434         border_points
[4] = wxPoint(tab_x
+tab_width
,   tab_y
+2); 
 435         border_points
[5] = wxPoint(tab_x
+tab_width
,   tab_y
+tab_height
-4); 
 437     // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 438     // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 440     int drawn_tab_yoff 
= border_points
[1].y
; 
 441     int drawn_tab_height 
= border_points
[0].y 
- border_points
[1].y
; 
 448         // draw base background color 
 449         wxRect 
r(tab_x
, tab_y
, tab_width
, tab_height
); 
 450         dc
.SetPen(m_base_colour_pen
); 
 451         dc
.SetBrush(m_base_colour_brush
); 
 452         dc
.DrawRectangle(r
.x
+1, r
.y
+1, r
.width
-1, r
.height
-4); 
 454         // this white helps fill out the gradient at the top of the tab 
 455         dc
.SetPen(*wxWHITE_PEN
); 
 456         dc
.SetBrush(*wxWHITE_BRUSH
); 
 457         dc
.DrawRectangle(r
.x
+2, r
.y
+1, r
.width
-3, r
.height
-4); 
 459         // these two points help the rounded corners appear more antialiased 
 460         dc
.SetPen(m_base_colour_pen
); 
 461         dc
.DrawPoint(r
.x
+2, r
.y
+1); 
 462         dc
.DrawPoint(r
.x
+r
.width
-2, r
.y
+1); 
 464         // set rectangle down a bit for gradient drawing 
 465         r
.SetHeight(r
.GetHeight()/2); 
 471         // draw gradient background 
 472         wxColor top_color 
= *wxWHITE
; 
 473         wxColor bottom_color 
= m_base_colour
; 
 474         dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
); 
 480         wxRect 
r(tab_x
, tab_y
+1, tab_width
, tab_height
-3); 
 482         // start the gradent up a bit and leave the inside border inset 
 483         // by a pixel for a 3D look.  Only the top half of the inactive 
 484         // tab will have a slight gradient 
 491         // -- draw top gradient fill for glossy look 
 492         wxColor top_color 
= m_base_colour
; 
 493         wxColor bottom_color 
= wxAuiStepColour(top_color
, 160); 
 494         dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
); 
 499         // -- draw bottom fill for glossy look 
 500         top_color 
= m_base_colour
; 
 501         bottom_color 
= m_base_colour
; 
 502         dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
); 
 506     dc
.SetPen(m_border_pen
); 
 507     dc
.SetBrush(*wxTRANSPARENT_BRUSH
); 
 508     dc
.DrawPolygon(WXSIZEOF(border_points
), border_points
); 
 510     // there are two horizontal grey lines at the bottom of the tab control, 
 511     // this gets rid of the top one of those lines in the tab control 
 514         if (m_flags 
&wxAUI_NB_BOTTOM
) 
 515             dc
.SetPen(wxPen(wxColour(wxAuiStepColour(m_base_colour
, 170)))); 
 516         // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 517         // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 518         else //for wxAUI_NB_TOP 
 519             dc
.SetPen(m_base_colour_pen
); 
 520         dc
.DrawLine(border_points
[0].x
+1, 
 527     int text_offset 
= tab_x 
+ 8; 
 528     int close_button_width 
= 0; 
 529     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
 531         close_button_width 
= m_active_close_bmp
.GetWidth(); 
 534     int bitmap_offset 
= 0; 
 535     if (page
.bitmap
.IsOk()) 
 537         bitmap_offset 
= tab_x 
+ 8; 
 540         dc
.DrawBitmap(page
.bitmap
, 
 542                       drawn_tab_yoff 
+ (drawn_tab_height
/2) - (page
.bitmap
.GetHeight()/2), 
 545         text_offset 
= bitmap_offset 
+ page
.bitmap
.GetWidth(); 
 546         text_offset 
+= 3; // bitmap padding 
 551         text_offset 
= tab_x 
+ 8; 
 555     wxString draw_text 
= wxAuiChopText(dc
, 
 557                           tab_width 
- (text_offset
-tab_x
) - close_button_width
); 
 560     dc
.DrawText(draw_text
, 
 562                 drawn_tab_yoff 
+ (drawn_tab_height
)/2 - (texty
/2) - 1); 
 564     // draw focus rectangle 
 565     if (page
.active 
&& (wnd
->FindFocus() == wnd
)) 
 567         wxRect 
focusRectText(text_offset
, (drawn_tab_yoff 
+ (drawn_tab_height
)/2 - (texty
/2) - 1), 
 568             selected_textx
, selected_texty
); 
 571         wxRect focusRectBitmap
; 
 573         if (page
.bitmap
.IsOk()) 
 574             focusRectBitmap 
= wxRect(bitmap_offset
, drawn_tab_yoff 
+ (drawn_tab_height
/2) - (page
.bitmap
.GetHeight()/2), 
 575                                             page
.bitmap
.GetWidth(), page
.bitmap
.GetHeight()); 
 577         if (page
.bitmap
.IsOk() && draw_text
.IsEmpty()) 
 578             focusRect 
= focusRectBitmap
; 
 579         else if (!page
.bitmap
.IsOk() && !draw_text
.IsEmpty()) 
 580             focusRect 
= focusRectText
; 
 581         else if (page
.bitmap
.IsOk() && !draw_text
.IsEmpty()) 
 582             focusRect 
= focusRectText
.Union(focusRectBitmap
); 
 584         focusRect
.Inflate(2, 2); 
 586         wxRendererNative::Get().DrawFocusRect(wnd
, dc
, focusRect
, 0); 
 589     // draw close button if necessary 
 590     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
 592         wxBitmap bmp 
= m_disabled_close_bmp
; 
 594         if (close_button_state 
== wxAUI_BUTTON_STATE_HOVER 
|| 
 595             close_button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
 597             bmp 
= m_active_close_bmp
; 
 600         wxRect 
rect(tab_x 
+ tab_width 
- close_button_width 
- 1, 
 601                     tab_y 
+ (tab_height
/2) - (bmp
.GetHeight()/2), 
 604         IndentPressedBitmap(&rect
, close_button_state
); 
 605         dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true); 
 607         *out_button_rect 
= rect
; 
 610     *out_tab_rect 
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
); 
 612     dc
.DestroyClippingRegion(); 
 615 int wxAuiDefaultTabArt::GetIndentSize() 
 620 wxSize 
wxAuiDefaultTabArt::GetTabSize(wxDC
& dc
, 
 621                                       wxWindow
* WXUNUSED(wnd
), 
 622                                       const wxString
& caption
, 
 623                                       const wxBitmap
& bitmap
, 
 624                                       bool WXUNUSED(active
), 
 625                                       int close_button_state
, 
 628     wxCoord measured_textx
, measured_texty
, tmp
; 
 630     dc
.SetFont(m_measuring_font
); 
 631     dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
); 
 633     dc
.GetTextExtent(wxT("ABCDEFXj"), &tmp
, &measured_texty
); 
 635     // add padding around the text 
 636     wxCoord tab_width 
= measured_textx
; 
 637     wxCoord tab_height 
= measured_texty
; 
 639     // if the close button is showing, add space for it 
 640     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
 641         tab_width 
+= m_active_close_bmp
.GetWidth() + 3; 
 643     // if there's a bitmap, add space for it 
 646         tab_width 
+= bitmap
.GetWidth(); 
 647         tab_width 
+= 3; // right side bitmap padding 
 648         tab_height 
= wxMax(tab_height
, bitmap
.GetHeight()); 
 655     if (m_flags 
& wxAUI_NB_TAB_FIXED_WIDTH
) 
 657         tab_width 
= m_fixed_tab_width
; 
 660     *x_extent 
= tab_width
; 
 662     return wxSize(tab_width
, tab_height
); 
 666 void wxAuiDefaultTabArt::DrawButton(wxDC
& dc
, 
 667                                     wxWindow
* WXUNUSED(wnd
), 
 668                                     const wxRect
& in_rect
, 
 679         case wxAUI_BUTTON_CLOSE
: 
 680             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 681                 bmp 
= m_disabled_close_bmp
; 
 683                 bmp 
= m_active_close_bmp
; 
 685         case wxAUI_BUTTON_LEFT
: 
 686             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 687                 bmp 
= m_disabled_left_bmp
; 
 689                 bmp 
= m_active_left_bmp
; 
 691         case wxAUI_BUTTON_RIGHT
: 
 692             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 693                 bmp 
= m_disabled_right_bmp
; 
 695                 bmp 
= m_active_right_bmp
; 
 697         case wxAUI_BUTTON_WINDOWLIST
: 
 698             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 699                 bmp 
= m_disabled_windowlist_bmp
; 
 701                 bmp 
= m_active_windowlist_bmp
; 
 711     if (orientation 
== wxLEFT
) 
 713         rect
.SetX(in_rect
.x
); 
 714         rect
.SetY(((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2)); 
 715         rect
.SetWidth(bmp
.GetWidth()); 
 716         rect
.SetHeight(bmp
.GetHeight()); 
 720         rect 
= wxRect(in_rect
.x 
+ in_rect
.width 
- bmp
.GetWidth(), 
 721                       ((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2), 
 722                       bmp
.GetWidth(), bmp
.GetHeight()); 
 725     IndentPressedBitmap(&rect
, button_state
); 
 726     dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true); 
 731 int wxAuiDefaultTabArt::ShowDropDown(wxWindow
* wnd
, 
 732                                      const wxAuiNotebookPageArray
& pages
, 
 737     size_t i
, count 
= pages
.GetCount(); 
 738     for (i 
= 0; i 
< count
; ++i
) 
 740         const wxAuiNotebookPage
& page 
= pages
.Item(i
); 
 741         wxString caption 
= page
.caption
; 
 743         // if there is no caption, make it a space.  This will prevent 
 744         // an assert in the menu code. 
 745         if (caption
.IsEmpty()) 
 748         menuPopup
.AppendCheckItem(1000+i
, caption
); 
 751     if (active_idx 
!= -1) 
 753         menuPopup
.Check(1000+active_idx
, true); 
 756     // find out where to put the popup menu of window items 
 757     wxPoint pt 
= ::wxGetMousePosition(); 
 758     pt 
= wnd
->ScreenToClient(pt
); 
 760     // find out the screen coordinate at the bottom of the tab ctrl 
 761     wxRect cli_rect 
= wnd
->GetClientRect(); 
 762     pt
.y 
= cli_rect
.y 
+ cli_rect
.height
; 
 764     wxAuiCommandCapture
* cc 
= new wxAuiCommandCapture
; 
 765     wnd
->PushEventHandler(cc
); 
 766     wnd
->PopupMenu(&menuPopup
, pt
); 
 767     int command 
= cc
->GetCommandId(); 
 768     wnd
->PopEventHandler(true); 
 776 int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow
* wnd
, 
 777                                            const wxAuiNotebookPageArray
& pages
, 
 778                                            const wxSize
& required_bmp_size
) 
 781     dc
.SetFont(m_measuring_font
); 
 783     // sometimes a standard bitmap size needs to be enforced, especially 
 784     // if some tabs have bitmaps and others don't.  This is important because 
 785     // it prevents the tab control from resizing when tabs are added. 
 786     wxBitmap measure_bmp
; 
 787     if (required_bmp_size
.IsFullySpecified()) 
 789         measure_bmp
.Create(required_bmp_size
.x
, 
 790                            required_bmp_size
.y
); 
 795     size_t i
, page_count 
= pages
.GetCount(); 
 796     for (i 
= 0; i 
< page_count
; ++i
) 
 798         wxAuiNotebookPage
& page 
= pages
.Item(i
); 
 801         if (measure_bmp
.IsOk()) 
 806         // we don't use the caption text because we don't 
 807         // want tab heights to be different in the case 
 808         // of a very short piece of text on one tab and a very 
 809         // tall piece of text on another tab 
 811         wxSize s 
= GetTabSize(dc
, 
 816                               wxAUI_BUTTON_STATE_HIDDEN
, 
 819         max_y 
= wxMax(max_y
, s
.y
); 
 825 void wxAuiDefaultTabArt::SetNormalFont(const wxFont
& font
) 
 827     m_normal_font 
= font
; 
 830 void wxAuiDefaultTabArt::SetSelectedFont(const wxFont
& font
) 
 832     m_selected_font 
= font
; 
 835 void wxAuiDefaultTabArt::SetMeasuringFont(const wxFont
& font
) 
 837     m_measuring_font 
= font
; 
 841 // -- wxAuiSimpleTabArt class implementation -- 
 843 wxAuiSimpleTabArt::wxAuiSimpleTabArt() 
 845     m_normal_font 
= *wxNORMAL_FONT
; 
 846     m_selected_font 
= *wxNORMAL_FONT
; 
 847     m_selected_font
.SetWeight(wxBOLD
); 
 848     m_measuring_font 
= m_selected_font
; 
 851     m_fixed_tab_width 
= 100; 
 853     wxColour base_colour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 855     wxColour background_colour 
= base_colour
; 
 856     wxColour normaltab_colour 
= base_colour
; 
 857     wxColour selectedtab_colour 
= *wxWHITE
; 
 859     m_bkbrush 
= wxBrush(background_colour
); 
 860     m_normal_bkbrush 
= wxBrush(normaltab_colour
); 
 861     m_normal_bkpen 
= wxPen(normaltab_colour
); 
 862     m_selected_bkbrush 
= wxBrush(selectedtab_colour
); 
 863     m_selected_bkpen 
= wxPen(selectedtab_colour
); 
 865     m_active_close_bmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
); 
 866     m_disabled_close_bmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128)); 
 868     m_active_left_bmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
); 
 869     m_disabled_left_bmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128)); 
 871     m_active_right_bmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
); 
 872     m_disabled_right_bmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128)); 
 874     m_active_windowlist_bmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
); 
 875     m_disabled_windowlist_bmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128)); 
 879 wxAuiSimpleTabArt::~wxAuiSimpleTabArt() 
 883 wxAuiTabArt
* wxAuiSimpleTabArt::Clone() 
 885     return static_cast<wxAuiTabArt
*>(new wxAuiSimpleTabArt
); 
 889 void wxAuiSimpleTabArt::SetFlags(unsigned int flags
) 
 894 void wxAuiSimpleTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
, 
 897     m_fixed_tab_width 
= 100; 
 899     int tot_width 
= (int)tab_ctrl_size
.x 
- GetIndentSize() - 4; 
 901     if (m_flags 
& wxAUI_NB_CLOSE_BUTTON
) 
 902         tot_width 
-= m_active_close_bmp
.GetWidth(); 
 903     if (m_flags 
& wxAUI_NB_WINDOWLIST_BUTTON
) 
 904         tot_width 
-= m_active_windowlist_bmp
.GetWidth(); 
 908         m_fixed_tab_width 
= tot_width
/(int)tab_count
; 
 912     if (m_fixed_tab_width 
< 100) 
 913         m_fixed_tab_width 
= 100; 
 915     if (m_fixed_tab_width 
> tot_width
/2) 
 916         m_fixed_tab_width 
= tot_width
/2; 
 918     if (m_fixed_tab_width 
> 220) 
 919         m_fixed_tab_width 
= 220; 
 922 void wxAuiSimpleTabArt::DrawBackground(wxDC
& dc
, 
 923                                        wxWindow
* WXUNUSED(wnd
), 
 927     dc
.SetBrush(m_bkbrush
); 
 928     dc
.SetPen(*wxTRANSPARENT_PEN
); 
 929     dc
.DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2); 
 932     dc
.SetPen(*wxGREY_PEN
); 
 933     dc
.DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1); 
 937 // DrawTab() draws an individual tab. 
 940 // in_rect  - rectangle the tab should be confined to 
 941 // caption  - tab's caption 
 942 // active   - whether or not the tab is active 
 943 // out_rect - actual output rectangle 
 944 // x_extent - the advance x; where the next tab should start 
 946 void wxAuiSimpleTabArt::DrawTab(wxDC
& dc
, 
 948                                 const wxAuiNotebookPage
& page
, 
 949                                 const wxRect
& in_rect
, 
 950                                 int close_button_state
, 
 951                                 wxRect
* out_tab_rect
, 
 952                                 wxRect
* out_button_rect
, 
 955     wxCoord normal_textx
, normal_texty
; 
 956     wxCoord selected_textx
, selected_texty
; 
 957     wxCoord textx
, texty
; 
 959     // if the caption is empty, measure some temporary text 
 960     wxString caption 
= page
.caption
; 
 964     dc
.SetFont(m_selected_font
); 
 965     dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
); 
 967     dc
.SetFont(m_normal_font
); 
 968     dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
); 
 970     // figure out the size of the tab 
 971     wxSize tab_size 
= GetTabSize(dc
, 
 979     wxCoord tab_height 
= tab_size
.y
; 
 980     wxCoord tab_width 
= tab_size
.x
; 
 981     wxCoord tab_x 
= in_rect
.x
; 
 982     wxCoord tab_y 
= in_rect
.y 
+ in_rect
.height 
- tab_height
; 
 984     caption 
= page
.caption
; 
 986     // select pen, brush and font for the tab to be drawn 
 990         dc
.SetPen(m_selected_bkpen
); 
 991         dc
.SetBrush(m_selected_bkbrush
); 
 992         dc
.SetFont(m_selected_font
); 
 993         textx 
= selected_textx
; 
 994         texty 
= selected_texty
; 
 998         dc
.SetPen(m_normal_bkpen
); 
 999         dc
.SetBrush(m_normal_bkbrush
); 
1000         dc
.SetFont(m_normal_font
); 
1001         textx 
= normal_textx
; 
1002         texty 
= normal_texty
; 
1009     points
[0].x 
= tab_x
; 
1010     points
[0].y 
= tab_y 
+ tab_height 
- 1; 
1011     points
[1].x 
= tab_x 
+ tab_height 
- 3; 
1012     points
[1].y 
= tab_y 
+ 2; 
1013     points
[2].x 
= tab_x 
+ tab_height 
+ 3; 
1014     points
[2].y 
= tab_y
; 
1015     points
[3].x 
= tab_x 
+ tab_width 
- 2; 
1016     points
[3].y 
= tab_y
; 
1017     points
[4].x 
= tab_x 
+ tab_width
; 
1018     points
[4].y 
= tab_y 
+ 2; 
1019     points
[5].x 
= tab_x 
+ tab_width
; 
1020     points
[5].y 
= tab_y 
+ tab_height 
- 1; 
1021     points
[6] = points
[0]; 
1023     dc
.SetClippingRegion(in_rect
); 
1025     dc
.DrawPolygon(WXSIZEOF(points
) - 1, points
); 
1027     dc
.SetPen(*wxGREY_PEN
); 
1029     //dc.DrawLines(active ? WXSIZEOF(points) - 1 : WXSIZEOF(points), points); 
1030     dc
.DrawLines(WXSIZEOF(points
), points
); 
1035     int close_button_width 
= 0; 
1036     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
1038         close_button_width 
= m_active_close_bmp
.GetWidth(); 
1039         text_offset 
= tab_x 
+ (tab_height
/2) + ((tab_width
-close_button_width
)/2) - (textx
/2); 
1043         text_offset 
= tab_x 
+ (tab_height
/3) + (tab_width
/2) - (textx
/2); 
1046     // set minimum text offset 
1047     if (text_offset 
< tab_x 
+ tab_height
) 
1048         text_offset 
= tab_x 
+ tab_height
; 
1050     // chop text if necessary 
1051     wxString draw_text 
= wxAuiChopText(dc
, 
1053                           tab_width 
- (text_offset
-tab_x
) - close_button_width
); 
1056     dc
.DrawText(draw_text
, 
1058                  (tab_y 
+ tab_height
)/2 - (texty
/2) + 1); 
1061     // draw focus rectangle 
1062     if (page
.active 
&& (wnd
->FindFocus() == wnd
)) 
1064         wxRect 
focusRect(text_offset
, ((tab_y 
+ tab_height
)/2 - (texty
/2) + 1), 
1065             selected_textx
, selected_texty
); 
1067         focusRect
.Inflate(2, 2); 
1069         wxRendererNative::Get().DrawFocusRect(wnd
, dc
, focusRect
, 0); 
1072     // draw close button if necessary 
1073     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
1077             bmp 
= m_active_close_bmp
; 
1079             bmp 
= m_disabled_close_bmp
; 
1081         wxRect 
rect(tab_x 
+ tab_width 
- close_button_width 
- 1, 
1082                     tab_y 
+ (tab_height
/2) - (bmp
.GetHeight()/2) + 1, 
1085         DrawButtons(dc
, rect
, bmp
, *wxWHITE
, close_button_state
); 
1087         *out_button_rect 
= rect
; 
1091     *out_tab_rect 
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
); 
1093     dc
.DestroyClippingRegion(); 
1096 int wxAuiSimpleTabArt::GetIndentSize() 
1101 wxSize 
wxAuiSimpleTabArt::GetTabSize(wxDC
& dc
, 
1102                                      wxWindow
* WXUNUSED(wnd
), 
1103                                      const wxString
& caption
, 
1104                                      const wxBitmap
& WXUNUSED(bitmap
), 
1105                                      bool WXUNUSED(active
), 
1106                                      int close_button_state
, 
1109     wxCoord measured_textx
, measured_texty
; 
1111     dc
.SetFont(m_measuring_font
); 
1112     dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
); 
1114     wxCoord tab_height 
= measured_texty 
+ 4; 
1115     wxCoord tab_width 
= measured_textx 
+ tab_height 
+ 5; 
1117     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
1118         tab_width 
+= m_active_close_bmp
.GetWidth(); 
1120     if (m_flags 
& wxAUI_NB_TAB_FIXED_WIDTH
) 
1122         tab_width 
= m_fixed_tab_width
; 
1125     *x_extent 
= tab_width 
- (tab_height
/2) - 1; 
1127     return wxSize(tab_width
, tab_height
); 
1131 void wxAuiSimpleTabArt::DrawButton(wxDC
& dc
, 
1132                                    wxWindow
* WXUNUSED(wnd
), 
1133                                    const wxRect
& in_rect
, 
1144         case wxAUI_BUTTON_CLOSE
: 
1145             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1146                 bmp 
= m_disabled_close_bmp
; 
1148                 bmp 
= m_active_close_bmp
; 
1150         case wxAUI_BUTTON_LEFT
: 
1151             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1152                 bmp 
= m_disabled_left_bmp
; 
1154                 bmp 
= m_active_left_bmp
; 
1156         case wxAUI_BUTTON_RIGHT
: 
1157             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1158                 bmp 
= m_disabled_right_bmp
; 
1160                 bmp 
= m_active_right_bmp
; 
1162         case wxAUI_BUTTON_WINDOWLIST
: 
1163             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1164                 bmp 
= m_disabled_windowlist_bmp
; 
1166                 bmp 
= m_active_windowlist_bmp
; 
1175     if (orientation 
== wxLEFT
) 
1177         rect
.SetX(in_rect
.x
); 
1178         rect
.SetY(((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2)); 
1179         rect
.SetWidth(bmp
.GetWidth()); 
1180         rect
.SetHeight(bmp
.GetHeight()); 
1184         rect 
= wxRect(in_rect
.x 
+ in_rect
.width 
- bmp
.GetWidth(), 
1185                       ((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2), 
1186                       bmp
.GetWidth(), bmp
.GetHeight()); 
1190     DrawButtons(dc
, rect
, bmp
, *wxWHITE
, button_state
); 
1195 int wxAuiSimpleTabArt::ShowDropDown(wxWindow
* wnd
, 
1196                                     const wxAuiNotebookPageArray
& pages
, 
1201     size_t i
, count 
= pages
.GetCount(); 
1202     for (i 
= 0; i 
< count
; ++i
) 
1204         const wxAuiNotebookPage
& page 
= pages
.Item(i
); 
1205         menuPopup
.AppendCheckItem(1000+i
, page
.caption
); 
1208     if (active_idx 
!= -1) 
1210         menuPopup
.Check(1000+active_idx
, true); 
1213     // find out where to put the popup menu of window 
1214     // items.  Subtract 100 for now to center the menu 
1215     // a bit, until a better mechanism can be implemented 
1216     wxPoint pt 
= ::wxGetMousePosition(); 
1217     pt 
= wnd
->ScreenToClient(pt
); 
1223     // find out the screen coordinate at the bottom of the tab ctrl 
1224     wxRect cli_rect 
= wnd
->GetClientRect(); 
1225     pt
.y 
= cli_rect
.y 
+ cli_rect
.height
; 
1227     wxAuiCommandCapture
* cc 
= new wxAuiCommandCapture
; 
1228     wnd
->PushEventHandler(cc
); 
1229     wnd
->PopupMenu(&menuPopup
, pt
); 
1230     int command 
= cc
->GetCommandId(); 
1231     wnd
->PopEventHandler(true); 
1233     if (command 
>= 1000) 
1234         return command
-1000; 
1239 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow
* wnd
, 
1240                                           const wxAuiNotebookPageArray
& WXUNUSED(pages
), 
1241                                           const wxSize
& WXUNUSED(required_bmp_size
)) 
1244     dc
.SetFont(m_measuring_font
); 
1246     wxSize s 
= GetTabSize(dc
, 
1251                           wxAUI_BUTTON_STATE_HIDDEN
, 
1256 void wxAuiSimpleTabArt::SetNormalFont(const wxFont
& font
) 
1258     m_normal_font 
= font
; 
1261 void wxAuiSimpleTabArt::SetSelectedFont(const wxFont
& font
) 
1263     m_selected_font 
= font
; 
1266 void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont
& font
) 
1268     m_measuring_font 
= font
; 
1274 // -- wxAuiTabContainer class implementation -- 
1277 // wxAuiTabContainer is a class which contains information about each 
1278 // tab.  It also can render an entire tab control to a specified DC. 
1279 // It's not a window class itself, because this code will be used by 
1280 // the wxFrameMananger, where it is disadvantageous to have separate 
1281 // windows for each tab control in the case of "docked tabs" 
1283 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window 
1284 // which can be used as a tab control in the normal sense. 
1287 wxAuiTabContainer::wxAuiTabContainer() 
1291     m_art 
= new wxAuiDefaultTabArt
; 
1293     AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
); 
1294     AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
); 
1295     AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
); 
1296     AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
); 
1299 wxAuiTabContainer::~wxAuiTabContainer() 
1304 void wxAuiTabContainer::SetArtProvider(wxAuiTabArt
* art
) 
1311         m_art
->SetFlags(m_flags
); 
1315 wxAuiTabArt
* wxAuiTabContainer::GetArtProvider() const 
1320 void wxAuiTabContainer::SetFlags(unsigned int flags
) 
1324     // check for new close button settings 
1325     RemoveButton(wxAUI_BUTTON_LEFT
); 
1326     RemoveButton(wxAUI_BUTTON_RIGHT
); 
1327     RemoveButton(wxAUI_BUTTON_WINDOWLIST
); 
1328     RemoveButton(wxAUI_BUTTON_CLOSE
); 
1331     if (flags 
& wxAUI_NB_SCROLL_BUTTONS
) 
1333         AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
); 
1334         AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
); 
1337     if (flags 
& wxAUI_NB_WINDOWLIST_BUTTON
) 
1339         AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
); 
1342     if (flags 
& wxAUI_NB_CLOSE_BUTTON
) 
1344         AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
); 
1349         m_art
->SetFlags(m_flags
); 
1353 unsigned int wxAuiTabContainer::GetFlags() const 
1359 void wxAuiTabContainer::SetNormalFont(const wxFont
& font
) 
1361     m_art
->SetNormalFont(font
); 
1364 void wxAuiTabContainer::SetSelectedFont(const wxFont
& font
) 
1366     m_art
->SetSelectedFont(font
); 
1369 void wxAuiTabContainer::SetMeasuringFont(const wxFont
& font
) 
1371     m_art
->SetMeasuringFont(font
); 
1374 void wxAuiTabContainer::SetRect(const wxRect
& rect
) 
1380         m_art
->SetSizingInfo(rect
.GetSize(), m_pages
.GetCount()); 
1384 bool wxAuiTabContainer::AddPage(wxWindow
* page
, 
1385                                 const wxAuiNotebookPage
& info
) 
1387     wxAuiNotebookPage page_info
; 
1389     page_info
.window 
= page
; 
1391     m_pages
.Add(page_info
); 
1393     // let the art provider know how many pages we have 
1396         m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount()); 
1402 bool wxAuiTabContainer::InsertPage(wxWindow
* page
, 
1403                                    const wxAuiNotebookPage
& info
, 
1406     wxAuiNotebookPage page_info
; 
1408     page_info
.window 
= page
; 
1410     if (idx 
>= m_pages
.GetCount()) 
1411         m_pages
.Add(page_info
); 
1413         m_pages
.Insert(page_info
, idx
); 
1415     // let the art provider know how many pages we have 
1418         m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount()); 
1424 bool wxAuiTabContainer::MovePage(wxWindow
* page
, 
1427     int idx 
= GetIdxFromWindow(page
); 
1431     // get page entry, make a copy of it 
1432     wxAuiNotebookPage p 
= GetPage(idx
); 
1434     // remove old page entry 
1437     // insert page where it should be 
1438     InsertPage(page
, p
, new_idx
); 
1443 bool wxAuiTabContainer::RemovePage(wxWindow
* wnd
) 
1445     size_t i
, page_count 
= m_pages
.GetCount(); 
1446     for (i 
= 0; i 
< page_count
; ++i
) 
1448         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1449         if (page
.window 
== wnd
) 
1451             m_pages
.RemoveAt(i
); 
1453             // let the art provider know how many pages we have 
1456                 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount()); 
1466 bool wxAuiTabContainer::SetActivePage(wxWindow
* wnd
) 
1470     size_t i
, page_count 
= m_pages
.GetCount(); 
1471     for (i 
= 0; i 
< page_count
; ++i
) 
1473         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1474         if (page
.window 
== wnd
) 
1481             page
.active 
= false; 
1488 void wxAuiTabContainer::SetNoneActive() 
1490     size_t i
, page_count 
= m_pages
.GetCount(); 
1491     for (i 
= 0; i 
< page_count
; ++i
) 
1493         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1494         page
.active 
= false; 
1498 bool wxAuiTabContainer::SetActivePage(size_t page
) 
1500     if (page 
>= m_pages
.GetCount()) 
1503     return SetActivePage(m_pages
.Item(page
).window
); 
1506 int wxAuiTabContainer::GetActivePage() const 
1508     size_t i
, page_count 
= m_pages
.GetCount(); 
1509     for (i 
= 0; i 
< page_count
; ++i
) 
1511         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1519 wxWindow
* wxAuiTabContainer::GetWindowFromIdx(size_t idx
) const 
1521     if (idx 
>= m_pages
.GetCount()) 
1524     return m_pages
[idx
].window
; 
1527 int wxAuiTabContainer::GetIdxFromWindow(wxWindow
* wnd
) const 
1529     const size_t page_count 
= m_pages
.GetCount(); 
1530     for ( size_t i 
= 0; i 
< page_count
; ++i 
) 
1532         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1533         if (page
.window 
== wnd
) 
1539 wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
) 
1541     wxASSERT_MSG(idx 
< m_pages
.GetCount(), wxT("Invalid Page index")); 
1543     return m_pages
[idx
]; 
1546 const wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
) const 
1548     wxASSERT_MSG(idx 
< m_pages
.GetCount(), wxT("Invalid Page index")); 
1550     return m_pages
[idx
]; 
1553 wxAuiNotebookPageArray
& wxAuiTabContainer::GetPages() 
1558 size_t wxAuiTabContainer::GetPageCount() const 
1560     return m_pages
.GetCount(); 
1563 void wxAuiTabContainer::AddButton(int id
, 
1565                                   const wxBitmap
& normal_bitmap
, 
1566                                   const wxBitmap
& disabled_bitmap
) 
1568     wxAuiTabContainerButton button
; 
1570     button
.bitmap 
= normal_bitmap
; 
1571     button
.dis_bitmap 
= disabled_bitmap
; 
1572     button
.location 
= location
; 
1573     button
.cur_state 
= wxAUI_BUTTON_STATE_NORMAL
; 
1575     m_buttons
.Add(button
); 
1578 void wxAuiTabContainer::RemoveButton(int id
) 
1580     size_t i
, button_count 
= m_buttons
.GetCount(); 
1582     for (i 
= 0; i 
< button_count
; ++i
) 
1584         if (m_buttons
.Item(i
).id 
== id
) 
1586             m_buttons
.RemoveAt(i
); 
1594 size_t wxAuiTabContainer::GetTabOffset() const 
1596     return m_tab_offset
; 
1599 void wxAuiTabContainer::SetTabOffset(size_t offset
) 
1601     m_tab_offset 
= offset
; 
1607 // Render() renders the tab catalog to the specified DC 
1608 // It is a virtual function and can be overridden to 
1609 // provide custom drawing capabilities 
1610 void wxAuiTabContainer::Render(wxDC
* raw_dc
, wxWindow
* wnd
) 
1612     if (!raw_dc 
|| !raw_dc
->IsOk()) 
1617     // use the same layout direction as the window DC uses to ensure that the 
1618     // text is rendered correctly 
1619     dc
.SetLayoutDirection(raw_dc
->GetLayoutDirection()); 
1623     size_t page_count 
= m_pages
.GetCount(); 
1624     size_t button_count 
= m_buttons
.GetCount(); 
1626     // create off-screen bitmap 
1627     bmp
.Create(m_rect
.GetWidth(), m_rect
.GetHeight()); 
1628     dc
.SelectObject(bmp
); 
1633     // find out if size of tabs is larger than can be 
1634     // afforded on screen 
1635     int total_width 
= 0; 
1636     int visible_width 
= 0; 
1637     for (i 
= 0; i 
< page_count
; ++i
) 
1639         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1641         // determine if a close button is on this tab 
1642         bool close_button 
= false; 
1643         if ((m_flags 
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 || 
1644             ((m_flags 
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
)) 
1646             close_button 
= true; 
1651         wxSize size 
= m_art
->GetTabSize(dc
, 
1657                               wxAUI_BUTTON_STATE_NORMAL 
: 
1658                               wxAUI_BUTTON_STATE_HIDDEN
, 
1661         if (i
+1 < page_count
) 
1662             total_width 
+= x_extent
; 
1664             total_width 
+= size
.x
; 
1666         if (i 
>= m_tab_offset
) 
1668             if (i
+1 < page_count
) 
1669                 visible_width 
+= x_extent
; 
1671                 visible_width 
+= size
.x
; 
1675     if (total_width 
> m_rect
.GetWidth() || m_tab_offset 
!= 0) 
1677         // show left/right buttons 
1678         for (i 
= 0; i 
< button_count
; ++i
) 
1680             wxAuiTabContainerButton
& button 
= m_buttons
.Item(i
); 
1681             if (button
.id 
== wxAUI_BUTTON_LEFT 
|| 
1682                 button
.id 
== wxAUI_BUTTON_RIGHT
) 
1684                 button
.cur_state 
&= ~wxAUI_BUTTON_STATE_HIDDEN
; 
1690         // hide left/right buttons 
1691         for (i 
= 0; i 
< button_count
; ++i
) 
1693             wxAuiTabContainerButton
& button 
= m_buttons
.Item(i
); 
1694             if (button
.id 
== wxAUI_BUTTON_LEFT 
|| 
1695                 button
.id 
== wxAUI_BUTTON_RIGHT
) 
1697                 button
.cur_state 
|= wxAUI_BUTTON_STATE_HIDDEN
; 
1702     // determine whether left button should be enabled 
1703     for (i 
= 0; i 
< button_count
; ++i
) 
1705         wxAuiTabContainerButton
& button 
= m_buttons
.Item(i
); 
1706         if (button
.id 
== wxAUI_BUTTON_LEFT
) 
1708             if (m_tab_offset 
== 0) 
1709                 button
.cur_state 
|= wxAUI_BUTTON_STATE_DISABLED
; 
1711                 button
.cur_state 
&= ~wxAUI_BUTTON_STATE_DISABLED
; 
1713         if (button
.id 
== wxAUI_BUTTON_RIGHT
) 
1715             if (visible_width 
< m_rect
.GetWidth() - ((int)button_count
*16)) 
1716                 button
.cur_state 
|= wxAUI_BUTTON_STATE_DISABLED
; 
1718                 button
.cur_state 
&= ~wxAUI_BUTTON_STATE_DISABLED
; 
1725     m_art
->DrawBackground(dc
, wnd
, m_rect
); 
1728     int left_buttons_width 
= 0; 
1729     int right_buttons_width 
= 0; 
1733     // draw the buttons on the right side 
1734     offset 
= m_rect
.x 
+ m_rect
.width
; 
1735     for (i 
= 0; i 
< button_count
; ++i
) 
1737         wxAuiTabContainerButton
& button 
= m_buttons
.Item(button_count 
- i 
- 1); 
1739         if (button
.location 
!= wxRIGHT
) 
1741         if (button
.cur_state 
& wxAUI_BUTTON_STATE_HIDDEN
) 
1744         wxRect button_rect 
= m_rect
; 
1745         button_rect
.SetY(1); 
1746         button_rect
.SetWidth(offset
); 
1748         m_art
->DrawButton(dc
, 
1756         offset 
-= button
.rect
.GetWidth(); 
1757         right_buttons_width 
+= button
.rect
.GetWidth(); 
1764     // draw the buttons on the left side 
1766     for (i 
= 0; i 
< button_count
; ++i
) 
1768         wxAuiTabContainerButton
& button 
= m_buttons
.Item(button_count 
- i 
- 1); 
1770         if (button
.location 
!= wxLEFT
) 
1772         if (button
.cur_state 
& wxAUI_BUTTON_STATE_HIDDEN
) 
1775         wxRect 
button_rect(offset
, 1, 1000, m_rect
.height
); 
1777         m_art
->DrawButton(dc
, 
1785         offset 
+= button
.rect
.GetWidth(); 
1786         left_buttons_width 
+= button
.rect
.GetWidth(); 
1789     offset 
= left_buttons_width
; 
1792         offset 
+= m_art
->GetIndentSize(); 
1795     // prepare the tab-close-button array 
1796     // make sure tab button entries which aren't used are marked as hidden 
1797     for (i 
= page_count
; i 
< m_tab_close_buttons
.GetCount(); ++i
) 
1798         m_tab_close_buttons
.Item(i
).cur_state 
= wxAUI_BUTTON_STATE_HIDDEN
; 
1800     // make sure there are enough tab button entries to accommodate all tabs 
1801     while (m_tab_close_buttons
.GetCount() < page_count
) 
1803         wxAuiTabContainerButton tempbtn
; 
1804         tempbtn
.id 
= wxAUI_BUTTON_CLOSE
; 
1805         tempbtn
.location 
= wxCENTER
; 
1806         tempbtn
.cur_state 
= wxAUI_BUTTON_STATE_HIDDEN
; 
1807         m_tab_close_buttons
.Add(tempbtn
); 
1811     // buttons before the tab offset must be set to hidden 
1812     for (i 
= 0; i 
< m_tab_offset
; ++i
) 
1814         m_tab_close_buttons
.Item(i
).cur_state 
= wxAUI_BUTTON_STATE_HIDDEN
; 
1820     size_t active 
= 999; 
1821     int active_offset 
= 0; 
1825     wxRect rect 
= m_rect
; 
1827     rect
.height 
= m_rect
.height
; 
1829     for (i 
= m_tab_offset
; i 
< page_count
; ++i
) 
1831         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1832         wxAuiTabContainerButton
& tab_button 
= m_tab_close_buttons
.Item(i
); 
1834         // determine if a close button is on this tab 
1835         if ((m_flags 
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 || 
1836             ((m_flags 
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
)) 
1838             if (tab_button
.cur_state 
== wxAUI_BUTTON_STATE_HIDDEN
) 
1840                 tab_button
.id 
= wxAUI_BUTTON_CLOSE
; 
1841                 tab_button
.cur_state 
= wxAUI_BUTTON_STATE_NORMAL
; 
1842                 tab_button
.location 
= wxCENTER
; 
1847             tab_button
.cur_state 
= wxAUI_BUTTON_STATE_HIDDEN
; 
1851         rect
.width 
= m_rect
.width 
- right_buttons_width 
- offset 
- 2; 
1853         if (rect
.width 
<= 0) 
1860                        tab_button
.cur_state
, 
1868             active_offset 
= offset
; 
1876     // make sure to deactivate buttons which are off the screen to the right 
1877     for (++i
; i 
< m_tab_close_buttons
.GetCount(); ++i
) 
1879         m_tab_close_buttons
.Item(i
).cur_state 
= wxAUI_BUTTON_STATE_HIDDEN
; 
1883     // draw the active tab again so it stands in the foreground 
1884     if (active 
>= m_tab_offset 
&& active 
< m_pages
.GetCount()) 
1886         wxAuiNotebookPage
& page 
= m_pages
.Item(active
); 
1888         wxAuiTabContainerButton
& tab_button 
= m_tab_close_buttons
.Item(active
); 
1890         rect
.x 
= active_offset
; 
1895                        tab_button
.cur_state
, 
1902     raw_dc
->Blit(m_rect
.x
, m_rect
.y
, 
1903                  m_rect
.GetWidth(), m_rect
.GetHeight(), 
1907 // Is the tab visible? 
1908 bool wxAuiTabContainer::IsTabVisible(int tabPage
, int tabOffset
, wxDC
* dc
, wxWindow
* wnd
) 
1910     if (!dc 
|| !dc
->IsOk()) 
1914     size_t page_count 
= m_pages
.GetCount(); 
1915     size_t button_count 
= m_buttons
.GetCount(); 
1917     // Hasn't been rendered yet; assume it's visible 
1918     if (m_tab_close_buttons
.GetCount() < page_count
) 
1921     // First check if both buttons are disabled - if so, there's no need to 
1922     // check further for visibility. 
1923     int arrowButtonVisibleCount 
= 0; 
1924     for (i 
= 0; i 
< button_count
; ++i
) 
1926         wxAuiTabContainerButton
& button 
= m_buttons
.Item(i
); 
1927         if (button
.id 
== wxAUI_BUTTON_LEFT 
|| 
1928             button
.id 
== wxAUI_BUTTON_RIGHT
) 
1930             if ((button
.cur_state 
& wxAUI_BUTTON_STATE_HIDDEN
) == 0) 
1931                 arrowButtonVisibleCount 
++; 
1935     // Tab must be visible 
1936     if (arrowButtonVisibleCount 
== 0) 
1939     // If tab is less than the given offset, it must be invisible by definition 
1940     if (tabPage 
< tabOffset
) 
1944     int left_buttons_width 
= 0; 
1945     int right_buttons_width 
= 0; 
1949     // calculate size of the buttons on the right side 
1950     offset 
= m_rect
.x 
+ m_rect
.width
; 
1951     for (i 
= 0; i 
< button_count
; ++i
) 
1953         wxAuiTabContainerButton
& button 
= m_buttons
.Item(button_count 
- i 
- 1); 
1955         if (button
.location 
!= wxRIGHT
) 
1957         if (button
.cur_state 
& wxAUI_BUTTON_STATE_HIDDEN
) 
1960         offset 
-= button
.rect
.GetWidth(); 
1961         right_buttons_width 
+= button
.rect
.GetWidth(); 
1966     // calculate size of the buttons on the left side 
1967     for (i 
= 0; i 
< button_count
; ++i
) 
1969         wxAuiTabContainerButton
& button 
= m_buttons
.Item(button_count 
- i 
- 1); 
1971         if (button
.location 
!= wxLEFT
) 
1973         if (button
.cur_state 
& wxAUI_BUTTON_STATE_HIDDEN
) 
1976         offset 
+= button
.rect
.GetWidth(); 
1977         left_buttons_width 
+= button
.rect
.GetWidth(); 
1980     offset 
= left_buttons_width
; 
1983         offset 
+= m_art
->GetIndentSize(); 
1987     wxRect rect 
= m_rect
; 
1989     rect
.height 
= m_rect
.height
; 
1991     // See if the given page is visible at the given tab offset (effectively scroll position) 
1992     for (i 
= tabOffset
; i 
< page_count
; ++i
) 
1994         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
1995         wxAuiTabContainerButton
& tab_button 
= m_tab_close_buttons
.Item(i
); 
1998         rect
.width 
= m_rect
.width 
- right_buttons_width 
- offset 
- 2; 
2000         if (rect
.width 
<= 0) 
2001             return false; // haven't found the tab, and we've run out of space, so return false 
2004         wxSize size 
= m_art
->GetTabSize(*dc
, 
2009                             tab_button
.cur_state
, 
2014         if (i 
== (size_t) tabPage
) 
2016             // If not all of the tab is visible, and supposing there's space to display it all, 
2017             // we could do better so we return false. 
2018             if (((m_rect
.width 
- right_buttons_width 
- offset 
- 2) <= 0) && ((m_rect
.width 
- right_buttons_width 
- left_buttons_width
) > x_extent
)) 
2025     // Shouldn't really get here, but if it does, assume the tab is visible to prevent 
2026     // further looping in calling code. 
2030 // Make the tab visible if it wasn't already 
2031 void wxAuiTabContainer::MakeTabVisible(int tabPage
, wxWindow
* win
) 
2034     if (!IsTabVisible(tabPage
, GetTabOffset(), & dc
, win
)) 
2037         for (i 
= 0; i 
< (int) m_pages
.GetCount(); i
++) 
2039             if (IsTabVisible(tabPage
, i
, & dc
, win
)) 
2049 // TabHitTest() tests if a tab was hit, passing the window pointer 
2050 // back if that condition was fulfilled.  The function returns 
2051 // true if a tab was hit, otherwise false 
2052 bool wxAuiTabContainer::TabHitTest(int x
, int y
, wxWindow
** hit
) const 
2054     if (!m_rect
.Contains(x
,y
)) 
2057     wxAuiTabContainerButton
* btn 
= NULL
; 
2058     if (ButtonHitTest(x
, y
, &btn
)) 
2060         if (m_buttons
.Index(*btn
) != wxNOT_FOUND
) 
2064     size_t i
, page_count 
= m_pages
.GetCount(); 
2066     for (i 
= m_tab_offset
; i 
< page_count
; ++i
) 
2068         wxAuiNotebookPage
& page 
= m_pages
.Item(i
); 
2069         if (page
.rect
.Contains(x
,y
)) 
2080 // ButtonHitTest() tests if a button was hit. The function returns 
2081 // true if a button was hit, otherwise false 
2082 bool wxAuiTabContainer::ButtonHitTest(int x
, int y
, 
2083                                       wxAuiTabContainerButton
** hit
) const 
2085     if (!m_rect
.Contains(x
,y
)) 
2088     size_t i
, button_count
; 
2091     button_count 
= m_buttons
.GetCount(); 
2092     for (i 
= 0; i 
< button_count
; ++i
) 
2094         wxAuiTabContainerButton
& button 
= m_buttons
.Item(i
); 
2095         if (button
.rect
.Contains(x
,y
) && 
2096             !(button
.cur_state 
& (wxAUI_BUTTON_STATE_HIDDEN 
| 
2097                                    wxAUI_BUTTON_STATE_DISABLED
))) 
2105     button_count 
= m_tab_close_buttons
.GetCount(); 
2106     for (i 
= 0; i 
< button_count
; ++i
) 
2108         wxAuiTabContainerButton
& button 
= m_tab_close_buttons
.Item(i
); 
2109         if (button
.rect
.Contains(x
,y
) && 
2110             !(button
.cur_state 
& (wxAUI_BUTTON_STATE_HIDDEN 
| 
2111                                    wxAUI_BUTTON_STATE_DISABLED
))) 
2124 // the utility function ShowWnd() is the same as show, 
2125 // except it handles wxAuiMDIChildFrame windows as well, 
2126 // as the Show() method on this class is "unplugged" 
2127 static void ShowWnd(wxWindow
* wnd
, bool show
) 
2130     if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
))) 
2132         wxAuiMDIChildFrame
* cf 
= (wxAuiMDIChildFrame
*)wnd
; 
2143 // DoShowHide() this function shows the active window, then 
2144 // hides all of the other windows (in that order) 
2145 void wxAuiTabContainer::DoShowHide() 
2147     wxAuiNotebookPageArray
& pages 
= GetPages(); 
2148     size_t i
, page_count 
= pages
.GetCount(); 
2150     // show new active page first 
2151     for (i 
= 0; i 
< page_count
; ++i
) 
2153         wxAuiNotebookPage
& page 
= pages
.Item(i
); 
2156             ShowWnd(page
.window
, true); 
2161     // hide all other pages 
2162     for (i 
= 0; i 
< page_count
; ++i
) 
2164         wxAuiNotebookPage
& page 
= pages
.Item(i
); 
2166             ShowWnd(page
.window
, false); 
2175 // -- wxAuiTabCtrl class implementation -- 
2179 BEGIN_EVENT_TABLE(wxAuiTabCtrl
, wxControl
) 
2180     EVT_PAINT(wxAuiTabCtrl::OnPaint
) 
2181     EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground
) 
2182     EVT_SIZE(wxAuiTabCtrl::OnSize
) 
2183     EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown
) 
2184     EVT_LEFT_DCLICK(wxAuiTabCtrl::OnLeftDClick
) 
2185     EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp
) 
2186     EVT_MIDDLE_DOWN(wxAuiTabCtrl::OnMiddleDown
) 
2187     EVT_MIDDLE_UP(wxAuiTabCtrl::OnMiddleUp
) 
2188     EVT_RIGHT_DOWN(wxAuiTabCtrl::OnRightDown
) 
2189     EVT_RIGHT_UP(wxAuiTabCtrl::OnRightUp
) 
2190     EVT_MOTION(wxAuiTabCtrl::OnMotion
) 
2191     EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow
) 
2192     EVT_AUINOTEBOOK_BUTTON(wxID_ANY
, wxAuiTabCtrl::OnButton
) 
2193     EVT_SET_FOCUS(wxAuiTabCtrl::OnSetFocus
) 
2194     EVT_KILL_FOCUS(wxAuiTabCtrl::OnKillFocus
) 
2195     EVT_CHAR(wxAuiTabCtrl::OnChar
) 
2196     EVT_MOUSE_CAPTURE_LOST(wxAuiTabCtrl::OnCaptureLost
) 
2200 wxAuiTabCtrl::wxAuiTabCtrl(wxWindow
* parent
, 
2204                            long style
) : wxControl(parent
, id
, pos
, size
, style
) 
2206     SetName(wxT("wxAuiTabCtrl")); 
2207     m_click_pt 
= wxDefaultPosition
; 
2208     m_is_dragging 
= false; 
2209     m_hover_button 
= NULL
; 
2210     m_pressed_button 
= NULL
; 
2213 wxAuiTabCtrl::~wxAuiTabCtrl() 
2217 void wxAuiTabCtrl::OnPaint(wxPaintEvent
&) 
2221     dc
.SetFont(GetFont()); 
2223     if (GetPageCount() > 0) 
2227 void wxAuiTabCtrl::OnEraseBackground(wxEraseEvent
& WXUNUSED(evt
)) 
2231 void wxAuiTabCtrl::OnSize(wxSizeEvent
& evt
) 
2233     wxSize s 
= evt
.GetSize(); 
2234     wxRect 
r(0, 0, s
.GetWidth(), s
.GetHeight()); 
2238 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent
& evt
) 
2241     m_click_pt 
= wxDefaultPosition
; 
2242     m_is_dragging 
= false; 
2244     m_pressed_button 
= NULL
; 
2248     if (TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
)) 
2250         int new_selection 
= GetIdxFromWindow(wnd
); 
2252         // wxAuiNotebooks always want to receive this event 
2253         // even if the tab is already active, because they may 
2254         // have multiple tab controls 
2255         if (new_selection 
!= GetActivePage() || 
2256             GetParent()->IsKindOf(CLASSINFO(wxAuiNotebook
))) 
2258             wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
); 
2259             e
.SetSelection(new_selection
); 
2260             e
.SetOldSelection(GetActivePage()); 
2261             e
.SetEventObject(this); 
2262             GetEventHandler()->ProcessEvent(e
); 
2265         m_click_pt
.x 
= evt
.m_x
; 
2266         m_click_pt
.y 
= evt
.m_y
; 
2272         m_pressed_button 
= m_hover_button
; 
2273         m_pressed_button
->cur_state 
= wxAUI_BUTTON_STATE_PRESSED
; 
2279 void wxAuiTabCtrl::OnCaptureLost(wxMouseCaptureLostEvent
& WXUNUSED(event
)) 
2283 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent
& evt
) 
2285     if (GetCapture() == this) 
2290         m_is_dragging 
= false; 
2292         wxAuiNotebookEvent 
evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, m_windowId
); 
2293         evt
.SetSelection(GetIdxFromWindow(m_click_tab
)); 
2294         evt
.SetOldSelection(evt
.GetSelection()); 
2295         evt
.SetEventObject(this); 
2296         GetEventHandler()->ProcessEvent(evt
); 
2301     if (m_pressed_button
) 
2303         // make sure we're still clicking the button 
2304         wxAuiTabContainerButton
* button 
= NULL
; 
2305         if (!ButtonHitTest(evt
.m_x
, evt
.m_y
, &button
)) 
2308         if (button 
!= m_pressed_button
) 
2310             m_pressed_button 
= NULL
; 
2317         if (!(m_pressed_button
->cur_state 
& wxAUI_BUTTON_STATE_DISABLED
)) 
2319             wxAuiNotebookEvent 
evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, m_windowId
); 
2320             evt
.SetSelection(GetIdxFromWindow(m_click_tab
)); 
2321             evt
.SetInt(m_pressed_button
->id
); 
2322             evt
.SetEventObject(this); 
2323             GetEventHandler()->ProcessEvent(evt
); 
2326         m_pressed_button 
= NULL
; 
2329     m_click_pt 
= wxDefaultPosition
; 
2330     m_is_dragging 
= false; 
2334 void wxAuiTabCtrl::OnMiddleUp(wxMouseEvent
& evt
) 
2336     wxWindow
* wnd 
= NULL
; 
2337     if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
)) 
2340     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
, m_windowId
); 
2341     e
.SetEventObject(this); 
2342     e
.SetSelection(GetIdxFromWindow(wnd
)); 
2343     GetEventHandler()->ProcessEvent(e
); 
2346 void wxAuiTabCtrl::OnMiddleDown(wxMouseEvent
& evt
) 
2348     wxWindow
* wnd 
= NULL
; 
2349     if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
)) 
2352     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
, m_windowId
); 
2353     e
.SetEventObject(this); 
2354     e
.SetSelection(GetIdxFromWindow(wnd
)); 
2355     GetEventHandler()->ProcessEvent(e
); 
2358 void wxAuiTabCtrl::OnRightUp(wxMouseEvent
& evt
) 
2360     wxWindow
* wnd 
= NULL
; 
2361     if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
)) 
2364     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
, m_windowId
); 
2365     e
.SetEventObject(this); 
2366     e
.SetSelection(GetIdxFromWindow(wnd
)); 
2367     GetEventHandler()->ProcessEvent(e
); 
2370 void wxAuiTabCtrl::OnRightDown(wxMouseEvent
& evt
) 
2372     wxWindow
* wnd 
= NULL
; 
2373     if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
)) 
2376     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
, m_windowId
); 
2377     e
.SetEventObject(this); 
2378     e
.SetSelection(GetIdxFromWindow(wnd
)); 
2379     GetEventHandler()->ProcessEvent(e
); 
2382 void wxAuiTabCtrl::OnLeftDClick(wxMouseEvent
& evt
) 
2385     wxAuiTabContainerButton
* button
; 
2386     if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
) && !ButtonHitTest(evt
.m_x
, evt
.m_y
, &button
)) 
2388         wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
, m_windowId
); 
2389         e
.SetEventObject(this); 
2390         GetEventHandler()->ProcessEvent(e
); 
2394 void wxAuiTabCtrl::OnMotion(wxMouseEvent
& evt
) 
2396     wxPoint pos 
= evt
.GetPosition(); 
2398     // check if the mouse is hovering above a button 
2399     wxAuiTabContainerButton
* button
; 
2400     if (ButtonHitTest(pos
.x
, pos
.y
, &button
)) 
2402         if (m_hover_button 
&& button 
!= m_hover_button
) 
2404             m_hover_button
->cur_state 
= wxAUI_BUTTON_STATE_NORMAL
; 
2405             m_hover_button 
= NULL
; 
2410         if (button
->cur_state 
!= wxAUI_BUTTON_STATE_HOVER
) 
2412             button
->cur_state 
= wxAUI_BUTTON_STATE_HOVER
; 
2415             m_hover_button 
= button
; 
2423             m_hover_button
->cur_state 
= wxAUI_BUTTON_STATE_NORMAL
; 
2424             m_hover_button 
= NULL
; 
2431     if (!evt
.LeftIsDown() || m_click_pt 
== wxDefaultPosition
) 
2436         wxAuiNotebookEvent 
evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, m_windowId
); 
2437         evt
.SetSelection(GetIdxFromWindow(m_click_tab
)); 
2438         evt
.SetOldSelection(evt
.GetSelection()); 
2439         evt
.SetEventObject(this); 
2440         GetEventHandler()->ProcessEvent(evt
); 
2445     int drag_x_threshold 
= wxSystemSettings::GetMetric(wxSYS_DRAG_X
); 
2446     int drag_y_threshold 
= wxSystemSettings::GetMetric(wxSYS_DRAG_Y
); 
2448     if (abs(pos
.x 
- m_click_pt
.x
) > drag_x_threshold 
|| 
2449         abs(pos
.y 
- m_click_pt
.y
) > drag_y_threshold
) 
2451         wxAuiNotebookEvent 
evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, m_windowId
); 
2452         evt
.SetSelection(GetIdxFromWindow(m_click_tab
)); 
2453         evt
.SetOldSelection(evt
.GetSelection()); 
2454         evt
.SetEventObject(this); 
2455         GetEventHandler()->ProcessEvent(evt
); 
2457         m_is_dragging 
= true; 
2461 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
)) 
2465         m_hover_button
->cur_state 
= wxAUI_BUTTON_STATE_NORMAL
; 
2466         m_hover_button 
= NULL
; 
2472 void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent
& event
) 
2474     int button 
= event
.GetInt(); 
2476     if (button 
== wxAUI_BUTTON_LEFT 
|| button 
== wxAUI_BUTTON_RIGHT
) 
2478         if (button 
== wxAUI_BUTTON_LEFT
) 
2480             if (GetTabOffset() > 0) 
2482                 SetTabOffset(GetTabOffset()-1); 
2489             SetTabOffset(GetTabOffset()+1); 
2494     else if (button 
== wxAUI_BUTTON_WINDOWLIST
) 
2496         int idx 
= GetArtProvider()->ShowDropDown(this, m_pages
, GetActivePage()); 
2500             wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
); 
2501             e
.SetSelection(idx
); 
2502             e
.SetOldSelection(GetActivePage()); 
2503             e
.SetEventObject(this); 
2504             GetEventHandler()->ProcessEvent(e
); 
2513 void wxAuiTabCtrl::OnSetFocus(wxFocusEvent
& WXUNUSED(event
)) 
2518 void wxAuiTabCtrl::OnKillFocus(wxFocusEvent
& WXUNUSED(event
)) 
2523 void wxAuiTabCtrl::OnChar(wxKeyEvent
& event
) 
2525     if (GetActivePage() == -1) 
2531     // We can't leave tab processing to the system; on Windows, tabs and keys 
2532     // get eaten by the system and not processed properly if we specify both 
2533     // wxTAB_TRAVERSAL and wxWANTS_CHARS. And if we specify just wxTAB_TRAVERSAL, 
2534     // we don't key arrow key events. 
2536     int key 
= event
.GetKeyCode(); 
2538     if (key 
== WXK_NUMPAD_PAGEUP
) 
2540     if (key 
== WXK_NUMPAD_PAGEDOWN
) 
2542     if (key 
== WXK_NUMPAD_HOME
) 
2544     if (key 
== WXK_NUMPAD_END
) 
2546     if (key 
== WXK_NUMPAD_LEFT
) 
2548     if (key 
== WXK_NUMPAD_RIGHT
) 
2551     if (key 
== WXK_TAB 
|| key 
== WXK_PAGEUP 
|| key 
== WXK_PAGEDOWN
) 
2553         bool bCtrlDown 
= event
.ControlDown(); 
2554         bool bShiftDown 
= event
.ShiftDown(); 
2556         bool bForward 
= (key 
== WXK_TAB 
&& !bShiftDown
) || (key 
== WXK_PAGEDOWN
); 
2557         bool bWindowChange 
= (key 
== WXK_PAGEUP
) || (key 
== WXK_PAGEDOWN
) || bCtrlDown
; 
2558         bool bFromTab 
= (key 
== WXK_TAB
); 
2560         wxAuiNotebook
* nb 
= wxDynamicCast(GetParent(), wxAuiNotebook
); 
2567         wxNavigationKeyEvent keyEvent
; 
2568         keyEvent
.SetDirection(bForward
); 
2569         keyEvent
.SetWindowChange(bWindowChange
); 
2570         keyEvent
.SetFromTab(bFromTab
); 
2571         keyEvent
.SetEventObject(nb
); 
2573         if (!nb
->GetEventHandler()->ProcessEvent(keyEvent
)) 
2575             // Not processed? Do an explicit tab into the page. 
2576             wxWindow
* win 
= GetWindowFromIdx(GetActivePage()); 
2583     if (m_pages
.GetCount() < 2) 
2591     int forwardKey
, backwardKey
; 
2592     if (GetLayoutDirection() == wxLayout_RightToLeft
) 
2594         forwardKey 
= WXK_LEFT
; 
2595         backwardKey 
= WXK_RIGHT
; 
2599         forwardKey 
= WXK_RIGHT
; 
2600         backwardKey 
= WXK_LEFT
; 
2603     if (key 
== forwardKey
) 
2605         if (m_pages
.GetCount() > 1) 
2607             if (GetActivePage() == -1) 
2609             else if (GetActivePage() < (int) (m_pages
.GetCount() - 1)) 
2610                 newPage 
= GetActivePage() + 1; 
2613     else if (key 
== backwardKey
) 
2615         if (m_pages
.GetCount() > 1) 
2617             if (GetActivePage() == -1) 
2618                 newPage 
= (int) (m_pages
.GetCount() - 1); 
2619             else if (GetActivePage() > 0) 
2620                 newPage 
= GetActivePage() - 1; 
2623     else if (key 
== WXK_HOME
) 
2627     else if (key 
== WXK_END
) 
2629         newPage 
= (int) (m_pages
.GetCount() - 1); 
2636         wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
); 
2637         e
.SetSelection(newPage
); 
2638         e
.SetOldSelection(newPage
); 
2639         e
.SetEventObject(this); 
2640         this->GetEventHandler()->ProcessEvent(e
); 
2646 // wxTabFrame is an interesting case.  It's important that all child pages 
2647 // of the multi-notebook control are all actually children of that control 
2648 // (and not grandchildren).  wxTabFrame facilitates this.  There is one 
2649 // instance of wxTabFrame for each tab control inside the multi-notebook. 
2650 // It's important to know that wxTabFrame is not a real window, but it merely 
2651 // used to capture the dimensions/positioning of the internal tab control and 
2652 // it's managed page windows 
2654 class wxTabFrame 
: public wxWindow
 
2661         m_rect 
= wxRect(0,0,200,200); 
2662         m_tab_ctrl_height 
= 20; 
2670     void SetTabCtrlHeight(int h
) 
2672         m_tab_ctrl_height 
= h
; 
2676     void DoSetSize(int x
, int y
, 
2677                    int width
, int height
, 
2678                    int WXUNUSED(sizeFlags 
= wxSIZE_AUTO
)) 
2680         m_rect 
= wxRect(x
, y
, width
, height
); 
2684     void DoGetClientSize(int* x
, int* y
) const 
2691     bool Show( bool WXUNUSED(show 
= true) ) { return false; } 
2698         m_tab_rect 
= wxRect(m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
); 
2699         if (m_tabs
->GetFlags() & wxAUI_NB_BOTTOM
) 
2701             m_tab_rect 
= wxRect (m_rect
.x
, m_rect
.y 
+ m_rect
.height 
- m_tab_ctrl_height
, m_rect
.width
, m_tab_ctrl_height
); 
2702             m_tabs
->SetSize     (m_rect
.x
, m_rect
.y 
+ m_rect
.height 
- m_tab_ctrl_height
, m_rect
.width
, m_tab_ctrl_height
); 
2703             m_tabs
->SetRect     (wxRect(0, 0, m_rect
.width
, m_tab_ctrl_height
)); 
2705         else //TODO: if (GetFlags() & wxAUI_NB_TOP) 
2707             m_tab_rect 
= wxRect (m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
); 
2708             m_tabs
->SetSize     (m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
); 
2709             m_tabs
->SetRect     (wxRect(0, 0,        m_rect
.width
, m_tab_ctrl_height
)); 
2711         // TODO: else if (GetFlags() & wxAUI_NB_LEFT){} 
2712         // TODO: else if (GetFlags() & wxAUI_NB_RIGHT){} 
2717         wxAuiNotebookPageArray
& pages 
= m_tabs
->GetPages(); 
2718         size_t i
, page_count 
= pages
.GetCount(); 
2720         for (i 
= 0; i 
< page_count
; ++i
) 
2722             int height 
= m_rect
.height 
- m_tab_ctrl_height
; 
2725                 // avoid passing negative height to wxWindow::SetSize(), this 
2726                 // results in assert failures/GTK+ warnings 
2730             wxAuiNotebookPage
& page 
= pages
.Item(i
); 
2731             if (m_tabs
->GetFlags() & wxAUI_NB_BOTTOM
) 
2733                 page
.window
->SetSize(m_rect
.x
, m_rect
.y
, m_rect
.width
, height
); 
2735             else //TODO: if (GetFlags() & wxAUI_NB_TOP) 
2737                 page
.window
->SetSize(m_rect
.x
, m_rect
.y 
+ m_tab_ctrl_height
, 
2738                                      m_rect
.width
, height
); 
2740             // TODO: else if (GetFlags() & wxAUI_NB_LEFT){} 
2741             // TODO: else if (GetFlags() & wxAUI_NB_RIGHT){} 
2744             if (page
.window
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
))) 
2746                 wxAuiMDIChildFrame
* wnd 
= (wxAuiMDIChildFrame
*)page
.window
; 
2747                 wnd
->ApplyMDIChildFrameRect(); 
2754     void DoGetSize(int* x
, int* y
) const 
2757             *x 
= m_rect
.GetWidth(); 
2759             *y 
= m_rect
.GetHeight(); 
2770     wxAuiTabCtrl
* m_tabs
; 
2771     int m_tab_ctrl_height
; 
2775 const int wxAuiBaseTabCtrlId 
= 5380; 
2778 // -- wxAuiNotebook class implementation -- 
2780 BEGIN_EVENT_TABLE(wxAuiNotebook
, wxControl
) 
2781     EVT_SIZE(wxAuiNotebook::OnSize
) 
2782     EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocusNotebook
) 
2783     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2784                       wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, 
2785                       wxAuiNotebook::OnTabClicked
) 
2786     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2787                       wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, 
2788                       wxAuiNotebook::OnTabBeginDrag
) 
2789     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2790                       wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, 
2791                       wxAuiNotebook::OnTabEndDrag
) 
2792     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2793                       wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, 
2794                       wxAuiNotebook::OnTabDragMotion
) 
2795     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2796                       wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, 
2797                       wxAuiNotebook::OnTabButton
) 
2798     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2799                       wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
, 
2800                       wxAuiNotebook::OnTabMiddleDown
) 
2801     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2802                       wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
, 
2803                       wxAuiNotebook::OnTabMiddleUp
) 
2804     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2805                       wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
, 
2806                       wxAuiNotebook::OnTabRightDown
) 
2807     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2808                       wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
, 
2809                       wxAuiNotebook::OnTabRightUp
) 
2810     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500, 
2811                       wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
, 
2812                       wxAuiNotebook::OnTabBgDClick
) 
2813     EVT_NAVIGATION_KEY(wxAuiNotebook::OnNavigationKeyNotebook
) 
2815 #ifdef wxHAS_NATIVE_TAB_TRAVERSAL 
2816     WX_EVENT_TABLE_CONTROL_CONTAINER(wxAuiNotebook
) 
2818     // Avoid clash with container event handler functions 
2819     EVT_SET_FOCUS(wxAuiNotebook::OnFocus
) 
2823 WX_DELEGATE_TO_CONTROL_CONTAINER(wxAuiNotebook
, wxControl
) 
2825 wxAuiNotebook::wxAuiNotebook() 
2828     m_tab_id_counter 
= wxAuiBaseTabCtrlId
; 
2830     m_tab_ctrl_height 
= 20; 
2831     m_requested_bmp_size 
= wxDefaultSize
; 
2832     m_requested_tabctrl_height 
= -1; 
2835 wxAuiNotebook::wxAuiNotebook(wxWindow 
*parent
, 
2839                              long style
) : wxControl(parent
, id
, pos
, size
, style
) 
2842     m_requested_bmp_size 
= wxDefaultSize
; 
2843     m_requested_tabctrl_height 
= -1; 
2844     InitNotebook(style
); 
2847 bool wxAuiNotebook::Create(wxWindow
* parent
, 
2853     if (!wxControl::Create(parent
, id
, pos
, size
, style
)) 
2856     InitNotebook(style
); 
2861 // InitNotebook() contains common initialization 
2862 // code called by all constructors 
2863 void wxAuiNotebook::InitNotebook(long style
) 
2865     WX_INIT_CONTROL_CONTAINER(); 
2866     // SetCanFocus(false); 
2868     SetName(wxT("wxAuiNotebook")); 
2870     m_tab_id_counter 
= wxAuiBaseTabCtrlId
; 
2872     m_flags 
= (unsigned int)style
; 
2873     m_tab_ctrl_height 
= 20; 
2875     m_normal_font 
= *wxNORMAL_FONT
; 
2876     m_selected_font 
= *wxNORMAL_FONT
; 
2877     m_selected_font
.SetWeight(wxBOLD
); 
2879     SetArtProvider(new wxAuiDefaultTabArt
); 
2881     m_dummy_wnd 
= new wxWindow(this, wxID_ANY
, wxPoint(0,0), wxSize(0,0)); 
2882     m_dummy_wnd
->SetSize(200, 200); 
2883     m_dummy_wnd
->Show(false); 
2885     m_mgr
.SetManagedWindow(this); 
2886     m_mgr
.SetFlags(wxAUI_MGR_DEFAULT
); 
2887     m_mgr
.SetDockSizeConstraint(1.0, 1.0); // no dock size constraint 
2889     m_mgr
.AddPane(m_dummy_wnd
, 
2890               wxAuiPaneInfo().Name(wxT("dummy")).Bottom().CaptionVisible(false).Show(false)); 
2895 wxAuiNotebook::~wxAuiNotebook() 
2897     // Indicate we're deleting pages 
2898     m_isBeingDeleted 
= true; 
2900     while ( GetPageCount() > 0 ) 
2906 void wxAuiNotebook::SetArtProvider(wxAuiTabArt
* art
) 
2908     m_tabs
.SetArtProvider(art
); 
2910     UpdateTabCtrlHeight(); 
2913 // SetTabCtrlHeight() is the highest-level override of the 
2914 // tab height.  A call to this function effectively enforces a 
2915 // specified tab ctrl height, overriding all other considerations, 
2916 // such as text or bitmap height.  It overrides any call to 
2917 // SetUniformBitmapSize().  Specifying a height of -1 reverts 
2918 // any previous call and returns to the default behavior 
2920 void wxAuiNotebook::SetTabCtrlHeight(int height
) 
2922     m_requested_tabctrl_height 
= height
; 
2924     // if window is already initialized, recalculate the tab height 
2927         UpdateTabCtrlHeight(); 
2932 // SetUniformBitmapSize() ensures that all tabs will have 
2933 // the same height, even if some tabs don't have bitmaps 
2934 // Passing wxDefaultSize to this function will instruct 
2935 // the control to use dynamic tab height-- so when a tab 
2936 // with a large bitmap is added, the tab ctrl's height will 
2937 // automatically increase to accommodate the bitmap 
2939 void wxAuiNotebook::SetUniformBitmapSize(const wxSize
& size
) 
2941     m_requested_bmp_size 
= size
; 
2943     // if window is already initialized, recalculate the tab height 
2946         UpdateTabCtrlHeight(); 
2950 // UpdateTabCtrlHeight() does the actual tab resizing. It's meant 
2951 // to be used interally 
2952 void wxAuiNotebook::UpdateTabCtrlHeight() 
2954     // get the tab ctrl height we will use 
2955     int height 
= CalculateTabCtrlHeight(); 
2957     // if the tab control height needs to change, update 
2958     // all of our tab controls with the new height 
2959     if (m_tab_ctrl_height 
!= height
) 
2961         wxAuiTabArt
* art 
= m_tabs
.GetArtProvider(); 
2963         m_tab_ctrl_height 
= height
; 
2965         wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
2966         size_t i
, pane_count 
= all_panes
.GetCount(); 
2967         for (i 
= 0; i 
< pane_count
; ++i
) 
2969             wxAuiPaneInfo
& pane 
= all_panes
.Item(i
); 
2970             if (pane
.name 
== wxT("dummy")) 
2972             wxTabFrame
* tab_frame 
= (wxTabFrame
*)pane
.window
; 
2973             wxAuiTabCtrl
* tabctrl 
= tab_frame
->m_tabs
; 
2974             tab_frame
->SetTabCtrlHeight(m_tab_ctrl_height
); 
2975             tabctrl
->SetArtProvider(art
->Clone()); 
2976             tab_frame
->DoSizing(); 
2981 void wxAuiNotebook::UpdateHintWindowSize() 
2983     wxSize size 
= CalculateNewSplitSize(); 
2985     // the placeholder hint window should be set to this size 
2986     wxAuiPaneInfo
& info 
= m_mgr
.GetPane(wxT("dummy")); 
2990         info
.BestSize(size
); 
2991         m_dummy_wnd
->SetSize(size
); 
2996 // calculates the size of the new split 
2997 wxSize 
wxAuiNotebook::CalculateNewSplitSize() 
2999     // count number of tab controls 
3000     int tab_ctrl_count 
= 0; 
3001     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
3002     size_t i
, pane_count 
= all_panes
.GetCount(); 
3003     for (i 
= 0; i 
< pane_count
; ++i
) 
3005         wxAuiPaneInfo
& pane 
= all_panes
.Item(i
); 
3006         if (pane
.name 
== wxT("dummy")) 
3011     wxSize new_split_size
; 
3013     // if there is only one tab control, the first split 
3014     // should happen around the middle 
3015     if (tab_ctrl_count 
< 2) 
3017         new_split_size 
= GetClientSize(); 
3018         new_split_size
.x 
/= 2; 
3019         new_split_size
.y 
/= 2; 
3023         // this is in place of a more complicated calculation 
3024         // that needs to be implemented 
3025         new_split_size 
= wxSize(180,180); 
3028     return new_split_size
; 
3031 int wxAuiNotebook::CalculateTabCtrlHeight() 
3033     // if a fixed tab ctrl height is specified, 
3034     // just return that instead of calculating a 
3036     if (m_requested_tabctrl_height 
!= -1) 
3037         return m_requested_tabctrl_height
; 
3039     // find out new best tab height 
3040     wxAuiTabArt
* art 
= m_tabs
.GetArtProvider(); 
3042     return art
->GetBestTabCtrlSize(this, 
3044                                    m_requested_bmp_size
); 
3048 wxAuiTabArt
* wxAuiNotebook::GetArtProvider() const 
3050     return m_tabs
.GetArtProvider(); 
3053 void wxAuiNotebook::SetWindowStyleFlag(long style
) 
3055     wxControl::SetWindowStyleFlag(style
); 
3057     m_flags 
= (unsigned int)style
; 
3059     // if the control is already initialized 
3060     if (m_mgr
.GetManagedWindow() == (wxWindow
*)this) 
3062         // let all of the tab children know about the new style 
3064         wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
3065         size_t i
, pane_count 
= all_panes
.GetCount(); 
3066         for (i 
= 0; i 
< pane_count
; ++i
) 
3068             wxAuiPaneInfo
& pane 
= all_panes
.Item(i
); 
3069             if (pane
.name 
== wxT("dummy")) 
3071             wxTabFrame
* tabframe 
= (wxTabFrame
*)pane
.window
; 
3072             wxAuiTabCtrl
* tabctrl 
= tabframe
->m_tabs
; 
3073             tabctrl
->SetFlags(m_flags
); 
3074             tabframe
->DoSizing(); 
3082 bool wxAuiNotebook::AddPage(wxWindow
* page
, 
3083                             const wxString
& caption
, 
3085                             const wxBitmap
& bitmap
) 
3087     return InsertPage(GetPageCount(), page
, caption
, select
, bitmap
); 
3090 bool wxAuiNotebook::InsertPage(size_t page_idx
, 
3092                                const wxString
& caption
, 
3094                                const wxBitmap
& bitmap
) 
3096     wxASSERT_MSG(page
, wxT("page pointer must be non-NULL")); 
3100     page
->Reparent(this); 
3102     wxAuiNotebookPage info
; 
3104     info
.caption 
= caption
; 
3105     info
.bitmap 
= bitmap
; 
3106     info
.active 
= false; 
3108     // if there are currently no tabs, the first added 
3109     // tab must be active 
3110     if (m_tabs
.GetPageCount() == 0) 
3113     m_tabs
.InsertPage(page
, info
, page_idx
); 
3115     // if that was the first page added, even if 
3116     // select is false, it must become the "current page" 
3117     // (though no select events will be fired) 
3118     if (!select 
&& m_tabs
.GetPageCount() == 1) 
3120         //m_curpage = GetPageIndex(page); 
3122     wxAuiTabCtrl
* active_tabctrl 
= GetActiveTabCtrl(); 
3123     if (page_idx 
>= active_tabctrl
->GetPageCount()) 
3124         active_tabctrl
->AddPage(page
, info
); 
3126         active_tabctrl
->InsertPage(page
, info
, page_idx
); 
3128     UpdateTabCtrlHeight(); 
3130     active_tabctrl
->DoShowHide(); 
3132     // adjust selected index 
3133     if(m_curpage 
>= (int) page_idx
) 
3138         SetSelectionToWindow(page
); 
3145 // DeletePage() removes a tab from the multi-notebook, 
3146 // and destroys the window as well 
3147 bool wxAuiNotebook::DeletePage(size_t page_idx
) 
3149     if (page_idx 
>= m_tabs
.GetPageCount()) 
3152     wxWindow
* wnd 
= m_tabs
.GetWindowFromIdx(page_idx
); 
3154     // hide the window in advance, as this will 
3156     ShowWnd(wnd
, false); 
3158     if (!RemovePage(page_idx
)) 
3162     // actually destroy the window now 
3163     if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
))) 
3165         // delete the child frame with pending delete, as is 
3166         // customary with frame windows 
3167         if (!wxPendingDelete
.Member(wnd
)) 
3168             wxPendingDelete
.Append(wnd
); 
3181 // RemovePage() removes a tab from the multi-notebook, 
3182 // but does not destroy the window 
3183 bool wxAuiNotebook::RemovePage(size_t page_idx
) 
3185     // save active window pointer 
3186     wxWindow
* active_wnd 
= NULL
; 
3188         active_wnd 
= m_tabs
.GetWindowFromIdx(m_curpage
); 
3190     // save pointer of window being deleted 
3191     wxWindow
* wnd 
= m_tabs
.GetWindowFromIdx(page_idx
); 
3192     wxWindow
* new_active 
= NULL
; 
3194     // make sure we found the page 
3198     // find out which onscreen tab ctrl owns this tab 
3201     if (!FindTab(wnd
, &ctrl
, &ctrl_idx
)) 
3204     bool is_curpage 
= (m_curpage 
== (int)page_idx
); 
3205     bool is_active_in_split 
= ctrl
->GetPage(ctrl_idx
).active
; 
3208     // remove the tab from main catalog 
3209     if (!m_tabs
.RemovePage(wnd
)) 
3212     // remove the tab from the onscreen tab ctrl 
3213     ctrl
->RemovePage(wnd
); 
3215     if (is_active_in_split
) 
3217         int ctrl_new_page_count 
= (int)ctrl
->GetPageCount(); 
3219         if (ctrl_idx 
>= ctrl_new_page_count
) 
3220             ctrl_idx 
= ctrl_new_page_count
-1; 
3222         if (ctrl_idx 
>= 0 && ctrl_idx 
< (int)ctrl
->GetPageCount()) 
3224             // set new page as active in the tab split 
3225             ctrl
->SetActivePage(ctrl_idx
); 
3227             // if the page deleted was the current page for the 
3228             // entire tab control, then record the window 
3229             // pointer of the new active page for activation 
3232                 new_active 
= ctrl
->GetWindowFromIdx(ctrl_idx
); 
3238         // we are not deleting the active page, so keep it the same 
3239         new_active 
= active_wnd
; 
3245         // we haven't yet found a new page to active, 
3246         // so select the next page from the main tab 
3249         if (page_idx 
< m_tabs
.GetPageCount()) 
3251             new_active 
= m_tabs
.GetPage(page_idx
).window
; 
3254         if (!new_active 
&& m_tabs
.GetPageCount() > 0) 
3256             new_active 
= m_tabs
.GetPage(0).window
; 
3261     RemoveEmptyTabFrames(); 
3263     // set new active pane 
3264     if (new_active 
&& !m_isBeingDeleted
) 
3267         SetSelectionToWindow(new_active
); 
3273 // GetPageIndex() returns the index of the page, or -1 if the 
3274 // page could not be located in the notebook 
3275 int wxAuiNotebook::GetPageIndex(wxWindow
* page_wnd
) const 
3277     return m_tabs
.GetIdxFromWindow(page_wnd
); 
3282 // SetPageText() changes the tab caption of the specified page 
3283 bool wxAuiNotebook::SetPageText(size_t page_idx
, const wxString
& text
) 
3285     if (page_idx 
>= m_tabs
.GetPageCount()) 
3288     // update our own tab catalog 
3289     wxAuiNotebookPage
& page_info 
= m_tabs
.GetPage(page_idx
); 
3290     page_info
.caption 
= text
; 
3292     // update what's on screen 
3295     if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
)) 
3297         wxAuiNotebookPage
& info 
= ctrl
->GetPage(ctrl_idx
); 
3298         info
.caption 
= text
; 
3306 // returns the page caption 
3307 wxString 
wxAuiNotebook::GetPageText(size_t page_idx
) const 
3309     if (page_idx 
>= m_tabs
.GetPageCount()) 
3310         return wxEmptyString
; 
3312     // update our own tab catalog 
3313     const wxAuiNotebookPage
& page_info 
= m_tabs
.GetPage(page_idx
); 
3314     return page_info
.caption
; 
3317 bool wxAuiNotebook::SetPageBitmap(size_t page_idx
, const wxBitmap
& bitmap
) 
3319     if (page_idx 
>= m_tabs
.GetPageCount()) 
3322     // update our own tab catalog 
3323     wxAuiNotebookPage
& page_info 
= m_tabs
.GetPage(page_idx
); 
3324     page_info
.bitmap 
= bitmap
; 
3326     // tab height might have changed 
3327     UpdateTabCtrlHeight(); 
3329     // update what's on screen 
3332     if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
)) 
3334         wxAuiNotebookPage
& info 
= ctrl
->GetPage(ctrl_idx
); 
3335         info
.bitmap 
= bitmap
; 
3343 // returns the page bitmap 
3344 wxBitmap 
wxAuiNotebook::GetPageBitmap(size_t page_idx
) const 
3346     if (page_idx 
>= m_tabs
.GetPageCount()) 
3349     // update our own tab catalog 
3350     const wxAuiNotebookPage
& page_info 
= m_tabs
.GetPage(page_idx
); 
3351     return page_info
.bitmap
; 
3354 // GetSelection() returns the index of the currently active page 
3355 int wxAuiNotebook::GetSelection() const 
3360 // SetSelection() sets the currently active page 
3361 size_t wxAuiNotebook::SetSelection(size_t new_page
) 
3363     wxWindow
* wnd 
= m_tabs
.GetWindowFromIdx(new_page
); 
3367     // don't change the page unless necessary; 
3368     // however, clicking again on a tab should give it the focus. 
3369     if ((int)new_page 
== m_curpage
) 
3373         if (FindTab(wnd
, &ctrl
, &ctrl_idx
)) 
3375             if (FindFocus() != ctrl
) 
3381     wxAuiNotebookEvent 
evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
); 
3382     evt
.SetSelection(new_page
); 
3383     evt
.SetOldSelection(m_curpage
); 
3384     evt
.SetEventObject(this); 
3385     if (!GetEventHandler()->ProcessEvent(evt
) || evt
.IsAllowed()) 
3387         int old_curpage 
= m_curpage
; 
3388         m_curpage 
= new_page
; 
3390         // program allows the page change 
3391         evt
.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
); 
3392         (void)GetEventHandler()->ProcessEvent(evt
); 
3397         if (FindTab(wnd
, &ctrl
, &ctrl_idx
)) 
3399             m_tabs
.SetActivePage(wnd
); 
3401             ctrl
->SetActivePage(ctrl_idx
); 
3405             ctrl
->MakeTabVisible(ctrl_idx
, ctrl
); 
3408             wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
3409             size_t i
, pane_count 
= all_panes
.GetCount(); 
3410             for (i 
= 0; i 
< pane_count
; ++i
) 
3412                 wxAuiPaneInfo
& pane 
= all_panes
.Item(i
); 
3413                 if (pane
.name 
== wxT("dummy")) 
3415                 wxAuiTabCtrl
* tabctrl 
= ((wxTabFrame
*)pane
.window
)->m_tabs
; 
3416                 if (tabctrl 
!= ctrl
) 
3417                     tabctrl
->SetSelectedFont(m_normal_font
); 
3419                     tabctrl
->SetSelectedFont(m_selected_font
); 
3423             // Set the focus to the page if we're not currently focused on the tab. 
3424             // This is Firefox-like behaviour. 
3425             if (wnd
->IsShownOnScreen() && FindFocus() != ctrl
) 
3435 void wxAuiNotebook::SetSelectionToWindow(wxWindow 
*win
) 
3437     const int idx 
= m_tabs
.GetIdxFromWindow(win
); 
3438     wxCHECK_RET( idx 
!= wxNOT_FOUND
, _T("invalid notebook page") ); 
3443 // GetPageCount() returns the total number of 
3444 // pages managed by the multi-notebook 
3445 size_t wxAuiNotebook::GetPageCount() const 
3447     return m_tabs
.GetPageCount(); 
3450 // GetPage() returns the wxWindow pointer of the 
3452 wxWindow
* wxAuiNotebook::GetPage(size_t page_idx
) const 
3454     wxASSERT(page_idx 
< m_tabs
.GetPageCount()); 
3456     return m_tabs
.GetWindowFromIdx(page_idx
); 
3459 // DoSizing() performs all sizing operations in each tab control 
3460 void wxAuiNotebook::DoSizing() 
3462     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
3463     size_t i
, pane_count 
= all_panes
.GetCount(); 
3464     for (i 
= 0; i 
< pane_count
; ++i
) 
3466         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
3469         wxTabFrame
* tabframe 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
3470         tabframe
->DoSizing(); 
3474 // GetActiveTabCtrl() returns the active tab control.  It is 
3475 // called to determine which control gets new windows being added 
3476 wxAuiTabCtrl
* wxAuiNotebook::GetActiveTabCtrl() 
3478     if (m_curpage 
>= 0 && m_curpage 
< (int)m_tabs
.GetPageCount()) 
3483         // find the tab ctrl with the current page 
3484         if (FindTab(m_tabs
.GetPage(m_curpage
).window
, 
3491     // no current page, just find the first tab ctrl 
3492     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
3493     size_t i
, pane_count 
= all_panes
.GetCount(); 
3494     for (i 
= 0; i 
< pane_count
; ++i
) 
3496         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
3499         wxTabFrame
* tabframe 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
3500         return tabframe
->m_tabs
; 
3503     // If there is no tabframe at all, create one 
3504     wxTabFrame
* tabframe 
= new wxTabFrame
; 
3505     tabframe
->SetTabCtrlHeight(m_tab_ctrl_height
); 
3506     tabframe
->m_tabs 
= new wxAuiTabCtrl(this, 
3510                                         wxNO_BORDER
|wxWANTS_CHARS
); 
3511     tabframe
->m_tabs
->SetFlags(m_flags
); 
3512     tabframe
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone()); 
3513     m_mgr
.AddPane(tabframe
, 
3514                   wxAuiPaneInfo().Center().CaptionVisible(false)); 
3518     return tabframe
->m_tabs
; 
3521 // FindTab() finds the tab control that currently contains the window as well 
3522 // as the index of the window in the tab control.  It returns true if the 
3523 // window was found, otherwise false. 
3524 bool wxAuiNotebook::FindTab(wxWindow
* page
, wxAuiTabCtrl
** ctrl
, int* idx
) 
3526     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
3527     size_t i
, pane_count 
= all_panes
.GetCount(); 
3528     for (i 
= 0; i 
< pane_count
; ++i
) 
3530         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
3533         wxTabFrame
* tabframe 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
3535         int page_idx 
= tabframe
->m_tabs
->GetIdxFromWindow(page
); 
3538             *ctrl 
= tabframe
->m_tabs
; 
3547 void wxAuiNotebook::Split(size_t page
, int direction
) 
3549     wxSize cli_size 
= GetClientSize(); 
3551     // get the page's window pointer 
3552     wxWindow
* wnd 
= GetPage(page
); 
3556     // notebooks with 1 or less pages can't be split 
3557     if (GetPageCount() < 2) 
3560     // find out which tab control the page currently belongs to 
3561     wxAuiTabCtrl 
*src_tabs
, *dest_tabs
; 
3564     if (!FindTab(wnd
, &src_tabs
, &src_idx
)) 
3566     if (!src_tabs 
|| src_idx 
== -1) 
3569     // choose a split size 
3571     if (GetPageCount() > 2) 
3573         split_size 
= CalculateNewSplitSize(); 
3577         // because there are two panes, always split them 
3579         split_size 
= GetClientSize(); 
3585     // create a new tab frame 
3586     wxTabFrame
* new_tabs 
= new wxTabFrame
; 
3587     new_tabs
->m_rect 
= wxRect(wxPoint(0,0), split_size
); 
3588     new_tabs
->SetTabCtrlHeight(m_tab_ctrl_height
); 
3589     new_tabs
->m_tabs 
= new wxAuiTabCtrl(this, 
3593                                         wxNO_BORDER
|wxWANTS_CHARS
); 
3594     new_tabs
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone()); 
3595     new_tabs
->m_tabs
->SetFlags(m_flags
); 
3596     dest_tabs 
= new_tabs
->m_tabs
; 
3598     // create a pane info structure with the information 
3599     // about where the pane should be added 
3600     wxAuiPaneInfo pane_info 
= wxAuiPaneInfo().Bottom().CaptionVisible(false); 
3603     if (direction 
== wxLEFT
) 
3606         mouse_pt 
= wxPoint(0, cli_size
.y
/2); 
3608     else if (direction 
== wxRIGHT
) 
3611         mouse_pt 
= wxPoint(cli_size
.x
, cli_size
.y
/2); 
3613     else if (direction 
== wxTOP
) 
3616         mouse_pt 
= wxPoint(cli_size
.x
/2, 0); 
3618     else if (direction 
== wxBOTTOM
) 
3621         mouse_pt 
= wxPoint(cli_size
.x
/2, cli_size
.y
); 
3624     m_mgr
.AddPane(new_tabs
, pane_info
, mouse_pt
); 
3627     // remove the page from the source tabs 
3628     wxAuiNotebookPage page_info 
= src_tabs
->GetPage(src_idx
); 
3629     page_info
.active 
= false; 
3630     src_tabs
->RemovePage(page_info
.window
); 
3631     if (src_tabs
->GetPageCount() > 0) 
3633         src_tabs
->SetActivePage((size_t)0); 
3634         src_tabs
->DoShowHide(); 
3635         src_tabs
->Refresh(); 
3639     // add the page to the destination tabs 
3640     dest_tabs
->InsertPage(page_info
.window
, page_info
, 0); 
3642     if (src_tabs
->GetPageCount() == 0) 
3644         RemoveEmptyTabFrames(); 
3648     dest_tabs
->DoShowHide(); 
3649     dest_tabs
->Refresh(); 
3651     // force the set selection function reset the selection 
3654     // set the active page to the one we just split off 
3655     SetSelectionToPage(page_info
); 
3657     UpdateHintWindowSize(); 
3661 void wxAuiNotebook::OnSize(wxSizeEvent
& evt
) 
3663     UpdateHintWindowSize(); 
3668 void wxAuiNotebook::OnTabClicked(wxCommandEvent
& command_evt
) 
3670     wxAuiNotebookEvent
& evt 
= (wxAuiNotebookEvent
&)command_evt
; 
3672     wxAuiTabCtrl
* ctrl 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
3673     wxASSERT(ctrl 
!= NULL
); 
3675     wxWindow
* wnd 
= ctrl
->GetWindowFromIdx(evt
.GetSelection()); 
3676     wxASSERT(wnd 
!= NULL
); 
3678     SetSelectionToWindow(wnd
); 
3681 void wxAuiNotebook::OnTabBgDClick(wxCommandEvent
& WXUNUSED(evt
)) 
3683     // notify owner that the tabbar background has been double-clicked 
3684     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
, m_windowId
); 
3685     e
.SetEventObject(this); 
3686     GetEventHandler()->ProcessEvent(e
); 
3689 void wxAuiNotebook::OnTabBeginDrag(wxCommandEvent
&) 
3694 void wxAuiNotebook::OnTabDragMotion(wxCommandEvent
& evt
) 
3696     wxPoint screen_pt 
= ::wxGetMousePosition(); 
3697     wxPoint client_pt 
= ScreenToClient(screen_pt
); 
3700     wxAuiTabCtrl
* src_tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
3701     wxAuiTabCtrl
* dest_tabs 
= GetTabCtrlFromPoint(client_pt
); 
3703     if (dest_tabs 
== src_tabs
) 
3707             src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
)); 
3710         // always hide the hint for inner-tabctrl drag 
3713         // if tab moving is not allowed, leave 
3714         if (!(m_flags 
& wxAUI_NB_TAB_MOVE
)) 
3719         wxPoint pt 
= dest_tabs
->ScreenToClient(screen_pt
); 
3720         wxWindow
* dest_location_tab
; 
3722         // this is an inner-tab drag/reposition 
3723         if (dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &dest_location_tab
)) 
3725             int src_idx 
= evt
.GetSelection(); 
3726             int dest_idx 
= dest_tabs
->GetIdxFromWindow(dest_location_tab
); 
3728             // prevent jumpy drag 
3729             if ((src_idx 
== dest_idx
) || dest_idx 
== -1 || 
3730                 (src_idx 
> dest_idx 
&& m_last_drag_x 
<= pt
.x
) || 
3731                 (src_idx 
< dest_idx 
&& m_last_drag_x 
>= pt
.x
)) 
3733                 m_last_drag_x 
= pt
.x
; 
3738             wxWindow
* src_tab 
= dest_tabs
->GetWindowFromIdx(src_idx
); 
3739             dest_tabs
->MovePage(src_tab
, dest_idx
); 
3740             dest_tabs
->SetActivePage((size_t)dest_idx
); 
3741             dest_tabs
->DoShowHide(); 
3742             dest_tabs
->Refresh(); 
3743             m_last_drag_x 
= pt
.x
; 
3751     // if external drag is allowed, check if the tab is being dragged 
3752     // over a different wxAuiNotebook control 
3753     if (m_flags 
& wxAUI_NB_TAB_EXTERNAL_MOVE
) 
3755         wxWindow
* tab_ctrl 
= ::wxFindWindowAtPoint(screen_pt
); 
3757         // if we aren't over any window, stop here 
3761         // make sure we are not over the hint window 
3762         if (!tab_ctrl
->IsKindOf(CLASSINFO(wxFrame
))) 
3766                 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
))) 
3768                 tab_ctrl 
= tab_ctrl
->GetParent(); 
3773                 wxAuiNotebook
* nb 
= (wxAuiNotebook
*)tab_ctrl
->GetParent(); 
3777                     wxRect hint_rect 
= tab_ctrl
->GetClientRect(); 
3778                     tab_ctrl
->ClientToScreen(&hint_rect
.x
, &hint_rect
.y
); 
3779                     m_mgr
.ShowHint(hint_rect
); 
3788                 // we are either over a hint window, or not over a tab 
3789                 // window, and there is no where to drag to, so exit 
3796     // if there are less than two panes, split can't happen, so leave 
3797     if (m_tabs
.GetPageCount() < 2) 
3800     // if tab moving is not allowed, leave 
3801     if (!(m_flags 
& wxAUI_NB_TAB_SPLIT
)) 
3807         src_tabs
->SetCursor(wxCursor(wxCURSOR_SIZING
)); 
3813         wxRect hint_rect 
= dest_tabs
->GetRect(); 
3814         ClientToScreen(&hint_rect
.x
, &hint_rect
.y
); 
3815         m_mgr
.ShowHint(hint_rect
); 
3819         m_mgr
.DrawHintRect(m_dummy_wnd
, client_pt
, zero
); 
3825 void wxAuiNotebook::OnTabEndDrag(wxCommandEvent
& command_evt
) 
3827     wxAuiNotebookEvent
& evt 
= (wxAuiNotebookEvent
&)command_evt
; 
3832     wxAuiTabCtrl
* src_tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
3833     wxCHECK_RET( src_tabs
, _T("no source object?") ); 
3835     src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
)); 
3837     // get the mouse position, which will be used to determine the drop point 
3838     wxPoint mouse_screen_pt 
= ::wxGetMousePosition(); 
3839     wxPoint mouse_client_pt 
= ScreenToClient(mouse_screen_pt
); 
3843     // check for an external move 
3844     if (m_flags 
& wxAUI_NB_TAB_EXTERNAL_MOVE
) 
3846         wxWindow
* tab_ctrl 
= ::wxFindWindowAtPoint(mouse_screen_pt
); 
3850             if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
))) 
3852             tab_ctrl 
= tab_ctrl
->GetParent(); 
3857             wxAuiNotebook
* nb 
= (wxAuiNotebook
*)tab_ctrl
->GetParent(); 
3861                 // find out from the destination control 
3862                 // if it's ok to drop this tab here 
3863                 wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
, m_windowId
); 
3864                 e
.SetSelection(evt
.GetSelection()); 
3865                 e
.SetOldSelection(evt
.GetSelection()); 
3866                 e
.SetEventObject(this); 
3867                 e
.SetDragSource(this); 
3868                 e
.Veto(); // dropping must be explicitly approved by control owner 
3870                 nb
->GetEventHandler()->ProcessEvent(e
); 
3874                     // no answer or negative answer 
3880                 int src_idx 
= evt
.GetSelection(); 
3881                 wxWindow
* src_page 
= src_tabs
->GetWindowFromIdx(src_idx
); 
3883                 // Check that it's not an impossible parent relationship 
3885                 while (p 
&& !p
->IsTopLevel()) 
3894                 // get main index of the page 
3895                 int main_idx 
= m_tabs
.GetIdxFromWindow(src_page
); 
3896                 wxCHECK_RET( main_idx 
!= wxNOT_FOUND
, _T("no source page?") ); 
3899                 // make a copy of the page info 
3900                 wxAuiNotebookPage page_info 
= m_tabs
.GetPage(main_idx
); 
3902                 // remove the page from the source notebook 
3903                 RemovePage(main_idx
); 
3905                 // reparent the page 
3906                 src_page
->Reparent(nb
); 
3909                 // found out the insert idx 
3910                 wxAuiTabCtrl
* dest_tabs 
= (wxAuiTabCtrl
*)tab_ctrl
; 
3911                 wxPoint pt 
= dest_tabs
->ScreenToClient(mouse_screen_pt
); 
3913                 wxWindow
* target 
= NULL
; 
3914                 int insert_idx 
= -1; 
3915                 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
); 
3918                     insert_idx 
= dest_tabs
->GetIdxFromWindow(target
); 
3922                 // add the page to the new notebook 
3923                 if (insert_idx 
== -1) 
3924                     insert_idx 
= dest_tabs
->GetPageCount(); 
3925                 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
); 
3926                 nb
->m_tabs
.AddPage(page_info
.window
, page_info
); 
3929                 dest_tabs
->DoShowHide(); 
3930                 dest_tabs
->Refresh(); 
3932                 // set the selection in the destination tab control 
3933                 nb
->SetSelectionToPage(page_info
); 
3935                 // notify owner that the tab has been dragged 
3936                 wxAuiNotebookEvent 
e2(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE
, m_windowId
); 
3937                 e2
.SetSelection(evt
.GetSelection()); 
3938                 e2
.SetOldSelection(evt
.GetSelection()); 
3939                 e2
.SetEventObject(this); 
3940                 GetEventHandler()->ProcessEvent(e2
); 
3950     // only perform a tab split if it's allowed 
3951     wxAuiTabCtrl
* dest_tabs 
= NULL
; 
3953     if ((m_flags 
& wxAUI_NB_TAB_SPLIT
) && m_tabs
.GetPageCount() >= 2) 
3955         // If the pointer is in an existing tab frame, do a tab insert 
3956         wxWindow
* hit_wnd 
= ::wxFindWindowAtPoint(mouse_screen_pt
); 
3957         wxTabFrame
* tab_frame 
= (wxTabFrame
*)GetTabFrameFromTabCtrl(hit_wnd
); 
3958         int insert_idx 
= -1; 
3961             dest_tabs 
= tab_frame
->m_tabs
; 
3963             if (dest_tabs 
== src_tabs
) 
3967             wxPoint pt 
= dest_tabs
->ScreenToClient(mouse_screen_pt
); 
3968             wxWindow
* target 
= NULL
; 
3969             dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
); 
3972                 insert_idx 
= dest_tabs
->GetIdxFromWindow(target
); 
3978             wxRect rect 
= m_mgr
.CalculateHintRect(m_dummy_wnd
, 
3983                 // there is no suitable drop location here, exit out 
3987             // If there is no tabframe at all, create one 
3988             wxTabFrame
* new_tabs 
= new wxTabFrame
; 
3989             new_tabs
->m_rect 
= wxRect(wxPoint(0,0), CalculateNewSplitSize()); 
3990             new_tabs
->SetTabCtrlHeight(m_tab_ctrl_height
); 
3991             new_tabs
->m_tabs 
= new wxAuiTabCtrl(this, 
3995                                                 wxNO_BORDER
|wxWANTS_CHARS
); 
3996             new_tabs
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone()); 
3997             new_tabs
->m_tabs
->SetFlags(m_flags
); 
3999             m_mgr
.AddPane(new_tabs
, 
4000                           wxAuiPaneInfo().Bottom().CaptionVisible(false), 
4003             dest_tabs 
= new_tabs
->m_tabs
; 
4008         // remove the page from the source tabs 
4009         wxAuiNotebookPage page_info 
= src_tabs
->GetPage(evt
.GetSelection()); 
4010         page_info
.active 
= false; 
4011         src_tabs
->RemovePage(page_info
.window
); 
4012         if (src_tabs
->GetPageCount() > 0) 
4014             src_tabs
->SetActivePage((size_t)0); 
4015             src_tabs
->DoShowHide(); 
4016             src_tabs
->Refresh(); 
4021         // add the page to the destination tabs 
4022         if (insert_idx 
== -1) 
4023             insert_idx 
= dest_tabs
->GetPageCount(); 
4024         dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
); 
4026         if (src_tabs
->GetPageCount() == 0) 
4028             RemoveEmptyTabFrames(); 
4032         dest_tabs
->DoShowHide(); 
4033         dest_tabs
->Refresh(); 
4035         // force the set selection function reset the selection 
4038         // set the active page to the one we just split off 
4039         SetSelectionToPage(page_info
); 
4041         UpdateHintWindowSize(); 
4044     // notify owner that the tab has been dragged 
4045     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE
, m_windowId
); 
4046     e
.SetSelection(evt
.GetSelection()); 
4047     e
.SetOldSelection(evt
.GetSelection()); 
4048     e
.SetEventObject(this); 
4049     GetEventHandler()->ProcessEvent(e
); 
4054 wxAuiTabCtrl
* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint
& pt
) 
4056     // if we've just removed the last tab from the source 
4057     // tab set, the remove the tab control completely 
4058     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
4059     size_t i
, pane_count 
= all_panes
.GetCount(); 
4060     for (i 
= 0; i 
< pane_count
; ++i
) 
4062         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
4065         wxTabFrame
* tabframe 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
4066         if (tabframe
->m_tab_rect
.Contains(pt
)) 
4067             return tabframe
->m_tabs
; 
4073 wxWindow
* wxAuiNotebook::GetTabFrameFromTabCtrl(wxWindow
* tab_ctrl
) 
4075     // if we've just removed the last tab from the source 
4076     // tab set, the remove the tab control completely 
4077     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
4078     size_t i
, pane_count 
= all_panes
.GetCount(); 
4079     for (i 
= 0; i 
< pane_count
; ++i
) 
4081         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
4084         wxTabFrame
* tabframe 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
4085         if (tabframe
->m_tabs 
== tab_ctrl
) 
4094 void wxAuiNotebook::RemoveEmptyTabFrames() 
4096     // if we've just removed the last tab from the source 
4097     // tab set, the remove the tab control completely 
4098     wxAuiPaneInfoArray all_panes 
= m_mgr
.GetAllPanes(); 
4099     size_t i
, pane_count 
= all_panes
.GetCount(); 
4100     for (i 
= 0; i 
< pane_count
; ++i
) 
4102         if (all_panes
.Item(i
).name 
== wxT("dummy")) 
4105         wxTabFrame
* tab_frame 
= (wxTabFrame
*)all_panes
.Item(i
).window
; 
4106         if (tab_frame
->m_tabs
->GetPageCount() == 0) 
4108             m_mgr
.DetachPane(tab_frame
); 
4110             // use pending delete because sometimes during 
4111             // window closing, refreshs are pending 
4112             if (!wxPendingDelete
.Member(tab_frame
->m_tabs
)) 
4113                 wxPendingDelete
.Append(tab_frame
->m_tabs
); 
4115             tab_frame
->m_tabs 
= NULL
; 
4122     // check to see if there is still a center pane; 
4123     // if there isn't, make a frame the center pane 
4124     wxAuiPaneInfoArray panes 
= m_mgr
.GetAllPanes(); 
4125     pane_count 
= panes
.GetCount(); 
4126     wxWindow
* first_good 
= NULL
; 
4127     bool center_found 
= false; 
4128     for (i 
= 0; i 
< pane_count
; ++i
) 
4130         if (panes
.Item(i
).name 
== wxT("dummy")) 
4132         if (panes
.Item(i
).dock_direction 
== wxAUI_DOCK_CENTRE
) 
4133             center_found 
= true; 
4135             first_good 
= panes
.Item(i
).window
; 
4138     if (!center_found 
&& first_good
) 
4140         m_mgr
.GetPane(first_good
).Centre(); 
4143     if (!m_isBeingDeleted
) 
4147 void wxAuiNotebook::OnChildFocusNotebook(wxChildFocusEvent
& evt
) 
4149     // if we're dragging a tab, don't change the current selection. 
4150     // This code prevents a bug that used to happen when the hint window 
4151     // was hidden.  In the bug, the focus would return to the notebook 
4152     // child, which would then enter this handler and call 
4153     // SetSelection, which is not desired turn tab dragging. 
4155     wxAuiPaneInfoArray
& all_panes 
= m_mgr
.GetAllPanes(); 
4156     size_t i
, pane_count 
= all_panes
.GetCount(); 
4157     for (i 
= 0; i 
< pane_count
; ++i
) 
4159         wxAuiPaneInfo
& pane 
= all_panes
.Item(i
); 
4160         if (pane
.name 
== wxT("dummy")) 
4162         wxTabFrame
* tabframe 
= (wxTabFrame
*)pane
.window
; 
4163         if (tabframe
->m_tabs
->IsDragging()) 
4168     // change the tab selection to the child 
4169     // which was focused 
4170     int idx 
= m_tabs
.GetIdxFromWindow(evt
.GetWindow()); 
4171     if (idx 
!= -1 && idx 
!= m_curpage
) 
4177 void wxAuiNotebook::OnNavigationKeyNotebook(wxNavigationKeyEvent
& event
) 
4179     if ( event
.IsWindowChange() ) { 
4181         // FIXME: the problem with this is that if we have a split notebook, 
4182         // we selection may go all over the place. 
4183         AdvanceSelection(event
.GetDirection()); 
4186         // we get this event in 3 cases 
4188         // a) one of our pages might have generated it because the user TABbed 
4189         // out from it in which case we should propagate the event upwards and 
4190         // our parent will take care of setting the focus to prev/next sibling 
4194         // b) the parent panel wants to give the focus to us so that we 
4195         // forward it to our selected page. We can't deal with this in 
4196         // OnSetFocus() because we don't know which direction the focus came 
4197         // from in this case and so can't choose between setting the focus to 
4198         // first or last panel child 
4202         // c) we ourselves (see MSWTranslateMessage) generated the event 
4204         wxWindow 
* const parent 
= GetParent(); 
4206         // the wxObject* casts are required to avoid MinGW GCC 2.95.3 ICE 
4207         const bool isFromParent 
= event
.GetEventObject() == (wxObject
*) parent
; 
4208         const bool isFromSelf 
= event
.GetEventObject() == (wxObject
*) this; 
4210         if ( isFromParent 
|| isFromSelf 
) 
4212             // no, it doesn't come from child, case (b) or (c): forward to a 
4213             // page but only if direction is backwards (TAB) or from ourselves, 
4214             if ( GetSelection() != wxNOT_FOUND 
&& 
4215                     (!event
.GetDirection() || isFromSelf
) ) 
4217                 // so that the page knows that the event comes from it's parent 
4218                 // and is being propagated downwards 
4219                 event
.SetEventObject(this); 
4221                 wxWindow 
*page 
= GetPage(GetSelection()); 
4222                 if ( !page
->GetEventHandler()->ProcessEvent(event
) ) 
4226                 //else: page manages focus inside it itself 
4228             else // otherwise set the focus to the notebook itself 
4235             // it comes from our child, case (a), pass to the parent, but only 
4236             // if the direction is forwards. Otherwise set the focus to the 
4237             // notebook itself. The notebook is always the 'first' control of a 
4239             if ( !event
.GetDirection() ) 
4245                 event
.SetCurrentFocus(this); 
4246                 parent
->GetEventHandler()->ProcessEvent(event
); 
4252 void wxAuiNotebook::OnTabButton(wxCommandEvent
& command_evt
) 
4254     wxAuiNotebookEvent
& evt 
= (wxAuiNotebookEvent
&)command_evt
; 
4255     wxAuiTabCtrl
* tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
4257     int button_id 
= evt
.GetInt(); 
4259     if (button_id 
== wxAUI_BUTTON_CLOSE
) 
4261         int selection 
= evt
.GetSelection(); 
4263         if (selection 
== -1) 
4265             // if the close button is to the right, use the active 
4266             // page selection to determine which page to close 
4267             selection 
= tabs
->GetActivePage(); 
4270         if (selection 
!= -1) 
4272             wxWindow
* close_wnd 
= tabs
->GetWindowFromIdx(selection
); 
4274             // ask owner if it's ok to close the tab 
4275             wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
, m_windowId
); 
4276             e
.SetSelection(m_tabs
.GetIdxFromWindow(close_wnd
)); 
4277             const int idx 
= m_tabs
.GetIdxFromWindow(close_wnd
); 
4278             e
.SetSelection(idx
); 
4279             e
.SetOldSelection(evt
.GetSelection()); 
4280             e
.SetEventObject(this); 
4281             GetEventHandler()->ProcessEvent(e
); 
4287             if (close_wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
))) 
4294                 int main_idx 
= m_tabs
.GetIdxFromWindow(close_wnd
); 
4295                 wxCHECK_RET( main_idx 
!= wxNOT_FOUND
, _T("no page to delete?") ); 
4297                 DeletePage(main_idx
); 
4300             // notify owner that the tab has been closed 
4301             wxAuiNotebookEvent 
e2(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED
, m_windowId
); 
4302             e2
.SetSelection(idx
); 
4303             e2
.SetEventObject(this); 
4304             GetEventHandler()->ProcessEvent(e2
); 
4310 void wxAuiNotebook::OnTabMiddleDown(wxCommandEvent
& evt
) 
4312     // patch event through to owner 
4313     wxAuiTabCtrl
* tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
4314     wxWindow
* wnd 
= tabs
->GetWindowFromIdx(evt
.GetSelection()); 
4316     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
, m_windowId
); 
4317     e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
)); 
4318     e
.SetEventObject(this); 
4319     GetEventHandler()->ProcessEvent(e
); 
4322 void wxAuiNotebook::OnTabMiddleUp(wxCommandEvent
& evt
) 
4324     // if the wxAUI_NB_MIDDLE_CLICK_CLOSE is specified, middle 
4325     // click should act like a tab close action.  However, first 
4326     // give the owner an opportunity to handle the middle up event 
4327     // for custom action 
4329     wxAuiTabCtrl
* tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
4330     wxWindow
* wnd 
= tabs
->GetWindowFromIdx(evt
.GetSelection()); 
4332     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
, m_windowId
); 
4333     e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
)); 
4334     e
.SetEventObject(this); 
4335     if (GetEventHandler()->ProcessEvent(e
)) 
4340     // check if we are supposed to close on middle-up 
4341     if ((m_flags 
& wxAUI_NB_MIDDLE_CLICK_CLOSE
) == 0) 
4344     // simulate the user pressing the close button on the tab 
4345     evt
.SetInt(wxAUI_BUTTON_CLOSE
); 
4349 void wxAuiNotebook::OnTabRightDown(wxCommandEvent
& evt
) 
4351     // patch event through to owner 
4352     wxAuiTabCtrl
* tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
4353     wxWindow
* wnd 
= tabs
->GetWindowFromIdx(evt
.GetSelection()); 
4355     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
, m_windowId
); 
4356     e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
)); 
4357     e
.SetEventObject(this); 
4358     GetEventHandler()->ProcessEvent(e
); 
4361 void wxAuiNotebook::OnTabRightUp(wxCommandEvent
& evt
) 
4363     // patch event through to owner 
4364     wxAuiTabCtrl
* tabs 
= (wxAuiTabCtrl
*)evt
.GetEventObject(); 
4365     wxWindow
* wnd 
= tabs
->GetWindowFromIdx(evt
.GetSelection()); 
4367     wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
, m_windowId
); 
4368     e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
)); 
4369     e
.SetEventObject(this); 
4370     GetEventHandler()->ProcessEvent(e
); 
4373 // Sets the normal font 
4374 void wxAuiNotebook::SetNormalFont(const wxFont
& font
) 
4376     m_normal_font 
= font
; 
4377     GetArtProvider()->SetNormalFont(font
); 
4380 // Sets the selected tab font 
4381 void wxAuiNotebook::SetSelectedFont(const wxFont
& font
) 
4383     m_selected_font 
= font
; 
4384     GetArtProvider()->SetSelectedFont(font
); 
4387 // Sets the measuring font 
4388 void wxAuiNotebook::SetMeasuringFont(const wxFont
& font
) 
4390     GetArtProvider()->SetMeasuringFont(font
); 
4393 // Sets the tab font 
4394 bool wxAuiNotebook::SetFont(const wxFont
& font
) 
4396     wxControl::SetFont(font
); 
4398     wxFont 
normalFont(font
); 
4399     wxFont 
selectedFont(normalFont
); 
4400     selectedFont
.SetWeight(wxBOLD
); 
4402     SetNormalFont(normalFont
); 
4403     SetSelectedFont(selectedFont
); 
4404     SetMeasuringFont(selectedFont
); 
4409 // Gets the tab control height 
4410 int wxAuiNotebook::GetTabCtrlHeight() const 
4412     return m_tab_ctrl_height
; 
4415 // Gets the height of the notebook for a given page height 
4416 int wxAuiNotebook::GetHeightForPageHeight(int pageHeight
) 
4418     UpdateTabCtrlHeight(); 
4420     int tabCtrlHeight 
= GetTabCtrlHeight(); 
4421     int decorHeight 
= 2; 
4422     return tabCtrlHeight 
+ pageHeight 
+ decorHeight
; 
4425 // Advances the selection, generation page selection events 
4426 void wxAuiNotebook::AdvanceSelection(bool forward
) 
4428     if (GetPageCount() <= 1) 
4431     int currentSelection 
= GetSelection(); 
4435         if (currentSelection 
== (int) (GetPageCount() - 1)) 
4437         else if (currentSelection 
== -1) 
4438             currentSelection 
= 0; 
4440             currentSelection 
++; 
4444         if (currentSelection 
<= 0) 
4447             currentSelection 
--; 
4450     SetSelection(currentSelection
); 
4453 // Shows the window menu 
4454 bool wxAuiNotebook::ShowWindowMenu() 
4456     wxAuiTabCtrl
* tabCtrl 
= GetActiveTabCtrl(); 
4458     int idx 
= tabCtrl
->GetArtProvider()->ShowDropDown(tabCtrl
, tabCtrl
->GetPages(), tabCtrl
->GetActivePage()); 
4462         wxAuiNotebookEvent 
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, tabCtrl
->GetId()); 
4463         e
.SetSelection(idx
); 
4464         e
.SetOldSelection(tabCtrl
->GetActivePage()); 
4465         e
.SetEventObject(tabCtrl
); 
4466         GetEventHandler()->ProcessEvent(e
);