1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/aui/tabart.cpp 
   3 // Purpose:     wxaui: wx advanced user interface - notebook-art 
   4 // Author:      Benjamin I. Williams 
   5 // Modified by: Jens Lody (moved from auibook.cpp in extra file) 
   8 // Copyright:   (C) Copyright 2006, Kirix Corporation, All Rights Reserved 
   9 // Licence:     wxWindows Library Licence, Version 3.1 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ---------------------------------------------------------------------------- 
  14 // ---------------------------------------------------------------------------- 
  16 #include "wx/wxprec.h" 
  26     #include "wx/dcclient.h" 
  27     #include "wx/settings.h" 
  28     #include "wx/bitmap.h" 
  32 #include "wx/renderer.h" 
  33 #include "wx/aui/auibook.h" 
  34 #include "wx/aui/framemanager.h" 
  35 #include "wx/aui/dockart.h" 
  38 #include "wx/osx/private.h" 
  42 // -- GUI helper classes and functions -- 
  44 class wxAuiCommandCapture 
: public wxEvtHandler
 
  48     wxAuiCommandCapture() { m_lastId 
= 0; } 
  49     int GetCommandId() const { return m_lastId
; } 
  51     bool ProcessEvent(wxEvent
& evt
) 
  53         if (evt
.GetEventType() == wxEVT_MENU
) 
  55             m_lastId 
= evt
.GetId(); 
  60             return GetNextHandler()->ProcessEvent(evt
); 
  70 // these functions live in dockart.cpp -- they'll eventually 
  71 // be moved to a new utility cpp file 
  73 wxBitmap 
wxAuiBitmapFromBits(const unsigned char bits
[], int w
, int h
, 
  74                              const wxColour
& color
); 
  76 wxString 
wxAuiChopText(wxDC
& dc
, const wxString
& text
, int max_size
); 
  78 static void DrawButtons(wxDC
& dc
, 
  81                         const wxColour
& bkcolour
, 
  86     if (button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
  92     if (button_state 
== wxAUI_BUTTON_STATE_HOVER 
|| 
  93         button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
  95         dc
.SetBrush(wxBrush(bkcolour
.ChangeLightness(120))); 
  96         dc
.SetPen(wxPen(bkcolour
.ChangeLightness(75))); 
  98         // draw the background behind the button 
  99         dc
.DrawRectangle(rect
.x
, rect
.y
, 15, 15); 
 102     // draw the button itself 
 103     dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true); 
 106 static void IndentPressedBitmap(wxRect
* rect
, int button_state
) 
 108     if (button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
 117 #if defined( __WXMAC__ ) 
 118  static const unsigned char close_bits
[]={ 
 119      0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3, 
 120      0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3, 
 121      0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF }; 
 122 #elif defined( __WXGTK__) 
 123  static const unsigned char close_bits
[]={ 
 124      0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8, 
 125      0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef, 
 126      0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 
 128  static const unsigned char close_bits
[]={ 
 129      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9, 
 130      0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3, 
 131      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 134 static const unsigned char left_bits
[] = { 
 135    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe, 
 136    0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe, 
 137    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 139 static const unsigned char right_bits
[] = { 
 140    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff, 
 141    0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff, 
 142    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 144 static const unsigned char list_bits
[] = { 
 145    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
 146    0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff, 
 147    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
 154 // -- wxAuiGenericTabArt class implementation -- 
 156 wxAuiGenericTabArt::wxAuiGenericTabArt() 
 158     m_normalFont 
= *wxNORMAL_FONT
; 
 159     m_selectedFont 
= *wxNORMAL_FONT
; 
 160     m_selectedFont
.SetWeight(wxBOLD
); 
 161     m_measuringFont 
= m_selectedFont
; 
 163     m_fixedTabWidth 
= 100; 
 166 #if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON 
 167     wxColor baseColour 
= wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground
)); 
 169     wxColor baseColour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 172     // the baseColour is too pale to use as our base colour, 
 173     // so darken it a bit -- 
 174     if ((255-baseColour
.Red()) + 
 175         (255-baseColour
.Green()) + 
 176         (255-baseColour
.Blue()) < 60) 
 178         baseColour 
= baseColour
.ChangeLightness(92); 
 181     m_activeColour 
= baseColour
; 
 182     m_baseColour 
= baseColour
; 
 183     wxColor borderColour 
= baseColour
.ChangeLightness(75); 
 185     m_borderPen 
= wxPen(borderColour
); 
 186     m_baseColourPen 
= wxPen(m_baseColour
); 
 187     m_baseColourBrush 
= wxBrush(m_baseColour
); 
 189     m_activeCloseBmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
); 
 190     m_disabledCloseBmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128)); 
 192     m_activeLeftBmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
); 
 193     m_disabledLeftBmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128)); 
 195     m_activeRightBmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
); 
 196     m_disabledRightBmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128)); 
 198     m_activeWindowListBmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
); 
 199     m_disabledWindowListBmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128)); 
 204 wxAuiGenericTabArt::~wxAuiGenericTabArt() 
 208 wxAuiTabArt
* wxAuiGenericTabArt::Clone() 
 210     return new wxAuiGenericTabArt(*this); 
 213 void wxAuiGenericTabArt::SetFlags(unsigned int flags
) 
 218 void wxAuiGenericTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
, 
 221     m_fixedTabWidth 
= 100; 
 223     int tot_width 
= (int)tab_ctrl_size
.x 
- GetIndentSize() - 4; 
 225     if (m_flags 
& wxAUI_NB_CLOSE_BUTTON
) 
 226         tot_width 
-= m_activeCloseBmp
.GetWidth(); 
 227     if (m_flags 
& wxAUI_NB_WINDOWLIST_BUTTON
) 
 228         tot_width 
-= m_activeWindowListBmp
.GetWidth(); 
 232         m_fixedTabWidth 
= tot_width
/(int)tab_count
; 
 236     if (m_fixedTabWidth 
< 100) 
 237         m_fixedTabWidth 
= 100; 
 239     if (m_fixedTabWidth 
> tot_width
/2) 
 240         m_fixedTabWidth 
= tot_width
/2; 
 242     if (m_fixedTabWidth 
> 220) 
 243         m_fixedTabWidth 
= 220; 
 245     m_tabCtrlHeight 
= tab_ctrl_size
.y
; 
 249 void wxAuiGenericTabArt::DrawBorder(wxDC
& dc
, wxWindow
* wnd
, const wxRect
& rect
) 
 251     int i
, border_width 
= GetBorderWidth(wnd
); 
 253     wxRect 
theRect(rect
); 
 254     for (i 
= 0; i 
< border_width
; ++i
) 
 256         dc
.DrawRectangle(theRect
.x
, theRect
.y
, theRect
.width
, theRect
.height
); 
 261 void wxAuiGenericTabArt::DrawBackground(wxDC
& dc
, 
 262                                         wxWindow
* WXUNUSED(wnd
), 
 267     wxColor top_color       
= m_baseColour
.ChangeLightness(90); 
 268     wxColor bottom_color   
= m_baseColour
.ChangeLightness(170); 
 271    if (m_flags 
&wxAUI_NB_BOTTOM
) 
 272        r 
= wxRect(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
); 
 273    // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 274    // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 275    else //for wxAUI_NB_TOP 
 276        r 
= wxRect(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
-3); 
 278     dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
); 
 283    dc
.SetPen(m_borderPen
); 
 284    int y 
= rect
.GetHeight(); 
 285    int w 
= rect
.GetWidth(); 
 287    if (m_flags 
&wxAUI_NB_BOTTOM
) 
 289        dc
.SetBrush(wxBrush(bottom_color
)); 
 290        dc
.DrawRectangle(-1, 0, w
+2, 4); 
 292    // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 293    // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 294    else //for wxAUI_NB_TOP 
 296        dc
.SetBrush(m_baseColourBrush
); 
 297        dc
.DrawRectangle(-1, y
-4, w
+2, 4); 
 302 // DrawTab() draws an individual tab. 
 305 // in_rect  - rectangle the tab should be confined to 
 306 // caption  - tab's caption 
 307 // active   - whether or not the tab is active 
 308 // out_rect - actual output rectangle 
 309 // x_extent - the advance x; where the next tab should start 
 311 void wxAuiGenericTabArt::DrawTab(wxDC
& dc
, 
 313                                  const wxAuiNotebookPage
& page
, 
 314                                  const wxRect
& in_rect
, 
 315                                  int close_button_state
, 
 316                                  wxRect
* out_tab_rect
, 
 317                                  wxRect
* out_button_rect
, 
 320     wxCoord normal_textx
, normal_texty
; 
 321     wxCoord selected_textx
, selected_texty
; 
 324     // if the caption is empty, measure some temporary text 
 325     wxString caption 
= page
.caption
; 
 329     dc
.SetFont(m_selectedFont
); 
 330     dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
); 
 332     dc
.SetFont(m_normalFont
); 
 333     dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
); 
 335     // figure out the size of the tab 
 336     wxSize tab_size 
= GetTabSize(dc
, 
 344     wxCoord tab_height 
= m_tabCtrlHeight 
- 3; 
 345     wxCoord tab_width 
= tab_size
.x
; 
 346     wxCoord tab_x 
= in_rect
.x
; 
 347     wxCoord tab_y 
= in_rect
.y 
+ in_rect
.height 
- tab_height
; 
 350     caption 
= page
.caption
; 
 353     // select pen, brush and font for the tab to be drawn 
 357         dc
.SetFont(m_selectedFont
); 
 358         texty 
= selected_texty
; 
 362         dc
.SetFont(m_normalFont
); 
 363         texty 
= normal_texty
; 
 367     // create points that will make the tab outline 
 369     int clip_width 
= tab_width
; 
 370     if (tab_x 
+ clip_width 
> in_rect
.x 
+ in_rect
.width
) 
 371         clip_width 
= (in_rect
.x 
+ in_rect
.width
) - tab_x
; 
 374     wxPoint clip_points[6]; 
 375     clip_points[0] = wxPoint(tab_x,              tab_y+tab_height-3); 
 376     clip_points[1] = wxPoint(tab_x,              tab_y+2); 
 377     clip_points[2] = wxPoint(tab_x+2,            tab_y); 
 378     clip_points[3] = wxPoint(tab_x+clip_width-1, tab_y); 
 379     clip_points[4] = wxPoint(tab_x+clip_width+1, tab_y+2); 
 380     clip_points[5] = wxPoint(tab_x+clip_width+1, tab_y+tab_height-3); 
 382     // FIXME: these ports don't provide wxRegion ctor from array of points 
 383 #if !defined(__WXDFB__) && !defined(__WXCOCOA__) 
 384     // set the clipping region for the tab -- 
 385     wxRegion clipping_region(WXSIZEOF(clip_points), clip_points); 
 386     dc.SetClippingRegion(clipping_region); 
 387 #endif // !wxDFB && !wxCocoa 
 389     // since the above code above doesn't play well with WXDFB or WXCOCOA, 
 390     // we'll just use a rectangle for the clipping region for now -- 
 391     dc
.SetClippingRegion(tab_x
, tab_y
, clip_width
+1, tab_height
-3); 
 394     wxPoint border_points
[6]; 
 395     if (m_flags 
&wxAUI_NB_BOTTOM
) 
 397         border_points
[0] = wxPoint(tab_x
,             tab_y
); 
 398         border_points
[1] = wxPoint(tab_x
,             tab_y
+tab_height
-6); 
 399         border_points
[2] = wxPoint(tab_x
+2,           tab_y
+tab_height
-4); 
 400         border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
+tab_height
-4); 
 401         border_points
[4] = wxPoint(tab_x
+tab_width
,   tab_y
+tab_height
-6); 
 402         border_points
[5] = wxPoint(tab_x
+tab_width
,   tab_y
); 
 404     else //if (m_flags & wxAUI_NB_TOP) {} 
 406         border_points
[0] = wxPoint(tab_x
,             tab_y
+tab_height
-4); 
 407         border_points
[1] = wxPoint(tab_x
,             tab_y
+2); 
 408         border_points
[2] = wxPoint(tab_x
+2,           tab_y
); 
 409         border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
); 
 410         border_points
[4] = wxPoint(tab_x
+tab_width
,   tab_y
+2); 
 411         border_points
[5] = wxPoint(tab_x
+tab_width
,   tab_y
+tab_height
-4); 
 413     // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 414     // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 416     int drawn_tab_yoff 
= border_points
[1].y
; 
 417     int drawn_tab_height 
= border_points
[0].y 
- border_points
[1].y
; 
 424         // draw base background color 
 425         wxRect 
r(tab_x
, tab_y
, tab_width
, tab_height
); 
 426         dc
.SetPen(wxPen(m_activeColour
)); 
 427         dc
.SetBrush(wxBrush(m_activeColour
)); 
 428         dc
.DrawRectangle(r
.x
+1, r
.y
+1, r
.width
-1, r
.height
-4); 
 430         // this white helps fill out the gradient at the top of the tab 
 431         dc
.SetPen(*wxWHITE_PEN
); 
 432         dc
.SetBrush(*wxWHITE_BRUSH
); 
 433         dc
.DrawRectangle(r
.x
+2, r
.y
+1, r
.width
-3, r
.height
-4); 
 435         // these two points help the rounded corners appear more antialiased 
 436         dc
.SetPen(wxPen(m_activeColour
)); 
 437         dc
.DrawPoint(r
.x
+2, r
.y
+1); 
 438         dc
.DrawPoint(r
.x
+r
.width
-2, r
.y
+1); 
 440         // set rectangle down a bit for gradient drawing 
 441         r
.SetHeight(r
.GetHeight()/2); 
 447         // draw gradient background 
 448         wxColor top_color 
= *wxWHITE
; 
 449         wxColor bottom_color 
= m_activeColour
; 
 450         dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
); 
 456         wxRect 
r(tab_x
, tab_y
+1, tab_width
, tab_height
-3); 
 458         // start the gradent up a bit and leave the inside border inset 
 459         // by a pixel for a 3D look.  Only the top half of the inactive 
 460         // tab will have a slight gradient 
 467         // -- draw top gradient fill for glossy look 
 468         wxColor top_color 
= m_baseColour
; 
 469         wxColor bottom_color 
= top_color
.ChangeLightness(160); 
 470         dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
); 
 475         // -- draw bottom fill for glossy look 
 476         top_color 
= m_baseColour
; 
 477         bottom_color 
= m_baseColour
; 
 478         dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
); 
 482     dc
.SetPen(m_borderPen
); 
 483     dc
.SetBrush(*wxTRANSPARENT_BRUSH
); 
 484     dc
.DrawPolygon(WXSIZEOF(border_points
), border_points
); 
 486     // there are two horizontal grey lines at the bottom of the tab control, 
 487     // this gets rid of the top one of those lines in the tab control 
 490         if (m_flags 
&wxAUI_NB_BOTTOM
) 
 491             dc
.SetPen(wxPen(m_baseColour
.ChangeLightness(170))); 
 492         // TODO: else if (m_flags &wxAUI_NB_LEFT) {} 
 493         // TODO: else if (m_flags &wxAUI_NB_RIGHT) {} 
 494         else //for wxAUI_NB_TOP 
 495             dc
.SetPen(m_baseColourPen
); 
 496         dc
.DrawLine(border_points
[0].x
+1, 
 503     int text_offset 
= tab_x 
+ 8; 
 504     int close_button_width 
= 0; 
 505     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
 507         close_button_width 
= m_activeCloseBmp
.GetWidth(); 
 510     int bitmap_offset 
= 0; 
 511     if (page
.bitmap
.IsOk()) 
 513         bitmap_offset 
= tab_x 
+ 8; 
 516         dc
.DrawBitmap(page
.bitmap
, 
 518                       drawn_tab_yoff 
+ (drawn_tab_height
/2) - (page
.bitmap
.GetHeight()/2), 
 521         text_offset 
= bitmap_offset 
+ page
.bitmap
.GetWidth(); 
 522         text_offset 
+= 3; // bitmap padding 
 527         text_offset 
= tab_x 
+ 8; 
 531     wxString draw_text 
= wxAuiChopText(dc
, 
 533                           tab_width 
- (text_offset
-tab_x
) - close_button_width
); 
 536     dc
.DrawText(draw_text
, 
 538                 drawn_tab_yoff 
+ (drawn_tab_height
)/2 - (texty
/2) - 1); 
 540     // draw focus rectangle 
 541     if (page
.active 
&& (wnd
->FindFocus() == wnd
)) 
 543         wxRect 
focusRectText(text_offset
, (drawn_tab_yoff 
+ (drawn_tab_height
)/2 - (texty
/2) - 1), 
 544             selected_textx
, selected_texty
); 
 547         wxRect focusRectBitmap
; 
 549         if (page
.bitmap
.IsOk()) 
 550             focusRectBitmap 
= wxRect(bitmap_offset
, drawn_tab_yoff 
+ (drawn_tab_height
/2) - (page
.bitmap
.GetHeight()/2), 
 551                                             page
.bitmap
.GetWidth(), page
.bitmap
.GetHeight()); 
 553         if (page
.bitmap
.IsOk() && draw_text
.IsEmpty()) 
 554             focusRect 
= focusRectBitmap
; 
 555         else if (!page
.bitmap
.IsOk() && !draw_text
.IsEmpty()) 
 556             focusRect 
= focusRectText
; 
 557         else if (page
.bitmap
.IsOk() && !draw_text
.IsEmpty()) 
 558             focusRect 
= focusRectText
.Union(focusRectBitmap
); 
 560         focusRect
.Inflate(2, 2); 
 562         wxRendererNative::Get().DrawFocusRect(wnd
, dc
, focusRect
, 0); 
 565     // draw close button if necessary 
 566     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
 568         wxBitmap bmp 
= m_disabledCloseBmp
; 
 570         if (close_button_state 
== wxAUI_BUTTON_STATE_HOVER 
|| 
 571             close_button_state 
== wxAUI_BUTTON_STATE_PRESSED
) 
 573             bmp 
= m_activeCloseBmp
; 
 576         int offsetY 
= tab_y
-1; 
 577         if (m_flags 
& wxAUI_NB_BOTTOM
) 
 580         wxRect 
rect(tab_x 
+ tab_width 
- close_button_width 
- 1, 
 581                     offsetY 
+ (tab_height
/2) - (bmp
.GetHeight()/2), 
 585         IndentPressedBitmap(&rect
, close_button_state
); 
 586         dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true); 
 588         *out_button_rect 
= rect
; 
 591     *out_tab_rect 
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
); 
 593     dc
.DestroyClippingRegion(); 
 596 int wxAuiGenericTabArt::GetIndentSize() 
 601 int wxAuiGenericTabArt::GetBorderWidth(wxWindow
* wnd
) 
 603     wxAuiManager
* mgr 
= wxAuiManager::GetManager(wnd
); 
 606        wxAuiDockArt
*  art 
= mgr
->GetArtProvider(); 
 608             return art
->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE
); 
 613 int wxAuiGenericTabArt::GetAdditionalBorderSpace(wxWindow
* WXUNUSED(wnd
)) 
 618 wxSize 
wxAuiGenericTabArt::GetTabSize(wxDC
& dc
, 
 619                                       wxWindow
* WXUNUSED(wnd
), 
 620                                       const wxString
& caption
, 
 621                                       const wxBitmap
& bitmap
, 
 622                                       bool WXUNUSED(active
), 
 623                                       int close_button_state
, 
 626     wxCoord measured_textx
, measured_texty
, tmp
; 
 628     dc
.SetFont(m_measuringFont
); 
 629     dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
); 
 631     dc
.GetTextExtent(wxT("ABCDEFXj"), &tmp
, &measured_texty
); 
 633     // add padding around the text 
 634     wxCoord tab_width 
= measured_textx
; 
 635     wxCoord tab_height 
= measured_texty
; 
 637     // if the close button is showing, add space for it 
 638     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
 639         tab_width 
+= m_activeCloseBmp
.GetWidth() + 3; 
 641     // if there's a bitmap, add space for it 
 644         tab_width 
+= bitmap
.GetWidth(); 
 645         tab_width 
+= 3; // right side bitmap padding 
 646         tab_height 
= wxMax(tab_height
, bitmap
.GetHeight()); 
 653     if (m_flags 
& wxAUI_NB_TAB_FIXED_WIDTH
) 
 655         tab_width 
= m_fixedTabWidth
; 
 658     *x_extent 
= tab_width
; 
 660     return wxSize(tab_width
, tab_height
); 
 664 void wxAuiGenericTabArt::DrawButton(wxDC
& dc
, 
 665                                     wxWindow
* WXUNUSED(wnd
), 
 666                                     const wxRect
& in_rect
, 
 677         case wxAUI_BUTTON_CLOSE
: 
 678             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 679                 bmp 
= m_disabledCloseBmp
; 
 681                 bmp 
= m_activeCloseBmp
; 
 683         case wxAUI_BUTTON_LEFT
: 
 684             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 685                 bmp 
= m_disabledLeftBmp
; 
 687                 bmp 
= m_activeLeftBmp
; 
 689         case wxAUI_BUTTON_RIGHT
: 
 690             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 691                 bmp 
= m_disabledRightBmp
; 
 693                 bmp 
= m_activeRightBmp
; 
 695         case wxAUI_BUTTON_WINDOWLIST
: 
 696             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
 697                 bmp 
= m_disabledWindowListBmp
; 
 699                 bmp 
= m_activeWindowListBmp
; 
 709     if (orientation 
== wxLEFT
) 
 711         rect
.SetX(in_rect
.x
); 
 712         rect
.SetY(((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2)); 
 713         rect
.SetWidth(bmp
.GetWidth()); 
 714         rect
.SetHeight(bmp
.GetHeight()); 
 718         rect 
= wxRect(in_rect
.x 
+ in_rect
.width 
- bmp
.GetWidth(), 
 719                       ((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2), 
 720                       bmp
.GetWidth(), bmp
.GetHeight()); 
 723     IndentPressedBitmap(&rect
, button_state
); 
 724     dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true); 
 729 int wxAuiGenericTabArt::ShowDropDown(wxWindow
* wnd
, 
 730                                      const wxAuiNotebookPageArray
& pages
, 
 735     size_t i
, count 
= pages
.GetCount(); 
 736     for (i 
= 0; i 
< count
; ++i
) 
 738         const wxAuiNotebookPage
& page 
= pages
.Item(i
); 
 739         wxString caption 
= page
.caption
; 
 741         // if there is no caption, make it a space.  This will prevent 
 742         // an assert in the menu code. 
 743         if (caption
.IsEmpty()) 
 746         wxMenuItem
* item 
= new wxMenuItem(NULL
, 1000+i
, caption
); 
 747         if (page
.bitmap
.IsOk()) 
 748             item
->SetBitmap(page
.bitmap
); 
 749         menuPopup
.Append(item
); 
 752     // find out where to put the popup menu of window items 
 753     wxPoint pt 
= ::wxGetMousePosition(); 
 754     pt 
= wnd
->ScreenToClient(pt
); 
 756     // find out the screen coordinate at the bottom of the tab ctrl 
 757     wxRect cli_rect 
= wnd
->GetClientRect(); 
 758     pt
.y 
= cli_rect
.y 
+ cli_rect
.height
; 
 760     wxAuiCommandCapture
* cc 
= new wxAuiCommandCapture
; 
 761     wnd
->PushEventHandler(cc
); 
 762     wnd
->PopupMenu(&menuPopup
, pt
); 
 763     int command 
= cc
->GetCommandId(); 
 764     wnd
->PopEventHandler(true); 
 772 int wxAuiGenericTabArt::GetBestTabCtrlSize(wxWindow
* wnd
, 
 773                                            const wxAuiNotebookPageArray
& pages
, 
 774                                            const wxSize
& requiredBmp_size
) 
 777     dc
.SetFont(m_measuringFont
); 
 779     // sometimes a standard bitmap size needs to be enforced, especially 
 780     // if some tabs have bitmaps and others don't.  This is important because 
 781     // it prevents the tab control from resizing when tabs are added. 
 783     if (requiredBmp_size
.IsFullySpecified()) 
 785         measureBmp
.Create(requiredBmp_size
.x
, 
 791     size_t i
, page_count 
= pages
.GetCount(); 
 792     for (i 
= 0; i 
< page_count
; ++i
) 
 794         wxAuiNotebookPage
& page 
= pages
.Item(i
); 
 797         if (measureBmp
.IsOk()) 
 802         // we don't use the caption text because we don't 
 803         // want tab heights to be different in the case 
 804         // of a very short piece of text on one tab and a very 
 805         // tall piece of text on another tab 
 807         wxSize s 
= GetTabSize(dc
, 
 812                               wxAUI_BUTTON_STATE_HIDDEN
, 
 815         max_y 
= wxMax(max_y
, s
.y
); 
 821 void wxAuiGenericTabArt::SetNormalFont(const wxFont
& font
) 
 826 void wxAuiGenericTabArt::SetSelectedFont(const wxFont
& font
) 
 828     m_selectedFont 
= font
; 
 831 void wxAuiGenericTabArt::SetMeasuringFont(const wxFont
& font
) 
 833     m_measuringFont 
= font
; 
 836 void wxAuiGenericTabArt::SetColour(const wxColour
& colour
) 
 838     m_baseColour 
= colour
; 
 839     m_borderPen 
= wxPen(m_baseColour
.ChangeLightness(75)); 
 840     m_baseColourPen 
= wxPen(m_baseColour
); 
 841     m_baseColourBrush 
= wxBrush(m_baseColour
); 
 844 void wxAuiGenericTabArt::SetActiveColour(const wxColour
& colour
) 
 846     m_activeColour 
= colour
; 
 849 // -- wxAuiSimpleTabArt class implementation -- 
 851 wxAuiSimpleTabArt::wxAuiSimpleTabArt() 
 853     m_normalFont 
= *wxNORMAL_FONT
; 
 854     m_selectedFont 
= *wxNORMAL_FONT
; 
 855     m_selectedFont
.SetWeight(wxBOLD
); 
 856     m_measuringFont 
= m_selectedFont
; 
 859     m_fixedTabWidth 
= 100; 
 861     wxColour baseColour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 863     wxColour backgroundColour 
= baseColour
; 
 864     wxColour normaltabColour 
= baseColour
; 
 865     wxColour selectedtabColour 
= *wxWHITE
; 
 867     m_bkBrush 
= wxBrush(backgroundColour
); 
 868     m_normalBkBrush 
= wxBrush(normaltabColour
); 
 869     m_normalBkPen 
= wxPen(normaltabColour
); 
 870     m_selectedBkBrush 
= wxBrush(selectedtabColour
); 
 871     m_selectedBkPen 
= wxPen(selectedtabColour
); 
 873     m_activeCloseBmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
); 
 874     m_disabledCloseBmp 
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128)); 
 876     m_activeLeftBmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
); 
 877     m_disabledLeftBmp 
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128)); 
 879     m_activeRightBmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
); 
 880     m_disabledRightBmp 
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128)); 
 882     m_activeWindowListBmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
); 
 883     m_disabledWindowListBmp 
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128)); 
 887 wxAuiSimpleTabArt::~wxAuiSimpleTabArt() 
 891 wxAuiTabArt
* wxAuiSimpleTabArt::Clone() 
 893     return new wxAuiSimpleTabArt(*this); 
 896 void wxAuiSimpleTabArt::SetFlags(unsigned int flags
) 
 901 void wxAuiSimpleTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
, 
 904     m_fixedTabWidth 
= 100; 
 906     int tot_width 
= (int)tab_ctrl_size
.x 
- GetIndentSize() - 4; 
 908     if (m_flags 
& wxAUI_NB_CLOSE_BUTTON
) 
 909         tot_width 
-= m_activeCloseBmp
.GetWidth(); 
 910     if (m_flags 
& wxAUI_NB_WINDOWLIST_BUTTON
) 
 911         tot_width 
-= m_activeWindowListBmp
.GetWidth(); 
 915         m_fixedTabWidth 
= tot_width
/(int)tab_count
; 
 919     if (m_fixedTabWidth 
< 100) 
 920         m_fixedTabWidth 
= 100; 
 922     if (m_fixedTabWidth 
> tot_width
/2) 
 923         m_fixedTabWidth 
= tot_width
/2; 
 925     if (m_fixedTabWidth 
> 220) 
 926         m_fixedTabWidth 
= 220; 
 929 void wxAuiSimpleTabArt::SetColour(const wxColour
& colour
) 
 931     m_bkBrush 
= wxBrush(colour
); 
 932     m_normalBkBrush 
= wxBrush(colour
); 
 933     m_normalBkPen 
= wxPen(colour
); 
 936 void wxAuiSimpleTabArt::SetActiveColour(const wxColour
& colour
) 
 938     m_selectedBkBrush 
= wxBrush(colour
); 
 939     m_selectedBkPen 
= wxPen(colour
); 
 942 void wxAuiSimpleTabArt::DrawBorder(wxDC
& dc
, wxWindow
* wnd
, const wxRect
& rect
) 
 944     int i
, border_width 
= GetBorderWidth(wnd
); 
 946     wxRect 
theRect(rect
); 
 947     for (i 
= 0; i 
< border_width
; ++i
) 
 949         dc
.DrawRectangle(theRect
.x
, theRect
.y
, theRect
.width
, theRect
.height
); 
 954 void wxAuiSimpleTabArt::DrawBackground(wxDC
& dc
, 
 955                                        wxWindow
* WXUNUSED(wnd
), 
 959     dc
.SetBrush(m_bkBrush
); 
 960     dc
.SetPen(*wxTRANSPARENT_PEN
); 
 961     dc
.DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2); 
 964     dc
.SetPen(*wxGREY_PEN
); 
 965     dc
.DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1); 
 969 // DrawTab() draws an individual tab. 
 972 // in_rect  - rectangle the tab should be confined to 
 973 // caption  - tab's caption 
 974 // active   - whether or not the tab is active 
 975 // out_rect - actual output rectangle 
 976 // x_extent - the advance x; where the next tab should start 
 978 void wxAuiSimpleTabArt::DrawTab(wxDC
& dc
, 
 980                                 const wxAuiNotebookPage
& page
, 
 981                                 const wxRect
& in_rect
, 
 982                                 int close_button_state
, 
 983                                 wxRect
* out_tab_rect
, 
 984                                 wxRect
* out_button_rect
, 
 987     wxCoord normal_textx
, normal_texty
; 
 988     wxCoord selected_textx
, selected_texty
; 
 989     wxCoord textx
, texty
; 
 991     // if the caption is empty, measure some temporary text 
 992     wxString caption 
= page
.caption
; 
 996     dc
.SetFont(m_selectedFont
); 
 997     dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
); 
 999     dc
.SetFont(m_normalFont
); 
1000     dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
); 
1002     // figure out the size of the tab 
1003     wxSize tab_size 
= GetTabSize(dc
, 
1011     wxCoord tab_height 
= tab_size
.y
; 
1012     wxCoord tab_width 
= tab_size
.x
; 
1013     wxCoord tab_x 
= in_rect
.x
; 
1014     wxCoord tab_y 
= in_rect
.y 
+ in_rect
.height 
- tab_height
; 
1016     caption 
= page
.caption
; 
1018     // select pen, brush and font for the tab to be drawn 
1022         dc
.SetPen(m_selectedBkPen
); 
1023         dc
.SetBrush(m_selectedBkBrush
); 
1024         dc
.SetFont(m_selectedFont
); 
1025         textx 
= selected_textx
; 
1026         texty 
= selected_texty
; 
1030         dc
.SetPen(m_normalBkPen
); 
1031         dc
.SetBrush(m_normalBkBrush
); 
1032         dc
.SetFont(m_normalFont
); 
1033         textx 
= normal_textx
; 
1034         texty 
= normal_texty
; 
1041     points
[0].x 
= tab_x
; 
1042     points
[0].y 
= tab_y 
+ tab_height 
- 1; 
1043     points
[1].x 
= tab_x 
+ tab_height 
- 3; 
1044     points
[1].y 
= tab_y 
+ 2; 
1045     points
[2].x 
= tab_x 
+ tab_height 
+ 3; 
1046     points
[2].y 
= tab_y
; 
1047     points
[3].x 
= tab_x 
+ tab_width 
- 2; 
1048     points
[3].y 
= tab_y
; 
1049     points
[4].x 
= tab_x 
+ tab_width
; 
1050     points
[4].y 
= tab_y 
+ 2; 
1051     points
[5].x 
= tab_x 
+ tab_width
; 
1052     points
[5].y 
= tab_y 
+ tab_height 
- 1; 
1053     points
[6] = points
[0]; 
1055     dc
.SetClippingRegion(in_rect
); 
1057     dc
.DrawPolygon(WXSIZEOF(points
) - 1, points
); 
1059     dc
.SetPen(*wxGREY_PEN
); 
1061     //dc.DrawLines(active ? WXSIZEOF(points) - 1 : WXSIZEOF(points), points); 
1062     dc
.DrawLines(WXSIZEOF(points
), points
); 
1067     int close_button_width 
= 0; 
1068     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
1070         close_button_width 
= m_activeCloseBmp
.GetWidth(); 
1071         text_offset 
= tab_x 
+ (tab_height
/2) + ((tab_width
-close_button_width
)/2) - (textx
/2); 
1075         text_offset 
= tab_x 
+ (tab_height
/3) + (tab_width
/2) - (textx
/2); 
1078     // set minimum text offset 
1079     if (text_offset 
< tab_x 
+ tab_height
) 
1080         text_offset 
= tab_x 
+ tab_height
; 
1082     // chop text if necessary 
1083     wxString draw_text 
= wxAuiChopText(dc
, 
1085                           tab_width 
- (text_offset
-tab_x
) - close_button_width
); 
1088     dc
.DrawText(draw_text
, 
1090                  (tab_y 
+ tab_height
)/2 - (texty
/2) + 1); 
1093     // draw focus rectangle 
1094     if (page
.active 
&& (wnd
->FindFocus() == wnd
)) 
1096         wxRect 
focusRect(text_offset
, ((tab_y 
+ tab_height
)/2 - (texty
/2) + 1), 
1097             selected_textx
, selected_texty
); 
1099         focusRect
.Inflate(2, 2); 
1101         wxRendererNative::Get().DrawFocusRect(wnd
, dc
, focusRect
, 0); 
1104     // draw close button if necessary 
1105     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
1109             bmp 
= m_activeCloseBmp
; 
1111             bmp 
= m_disabledCloseBmp
; 
1113         wxRect 
rect(tab_x 
+ tab_width 
- close_button_width 
- 1, 
1114                     tab_y 
+ (tab_height
/2) - (bmp
.GetHeight()/2) + 1, 
1117         DrawButtons(dc
, rect
, bmp
, *wxWHITE
, close_button_state
); 
1119         *out_button_rect 
= rect
; 
1123     *out_tab_rect 
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
); 
1125     dc
.DestroyClippingRegion(); 
1128 int wxAuiSimpleTabArt::GetIndentSize() 
1133 int wxAuiSimpleTabArt::GetBorderWidth(wxWindow
* wnd
) 
1135     wxAuiManager
* mgr 
= wxAuiManager::GetManager(wnd
); 
1138        wxAuiDockArt
*  art 
= mgr
->GetArtProvider(); 
1140             return art
->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE
); 
1145 int wxAuiSimpleTabArt::GetAdditionalBorderSpace(wxWindow
* WXUNUSED(wnd
)) 
1150 wxSize 
wxAuiSimpleTabArt::GetTabSize(wxDC
& dc
, 
1151                                      wxWindow
* WXUNUSED(wnd
), 
1152                                      const wxString
& caption
, 
1153                                      const wxBitmap
& WXUNUSED(bitmap
), 
1154                                      bool WXUNUSED(active
), 
1155                                      int close_button_state
, 
1158     wxCoord measured_textx
, measured_texty
; 
1160     dc
.SetFont(m_measuringFont
); 
1161     dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
); 
1163     wxCoord tab_height 
= measured_texty 
+ 4; 
1164     wxCoord tab_width 
= measured_textx 
+ tab_height 
+ 5; 
1166     if (close_button_state 
!= wxAUI_BUTTON_STATE_HIDDEN
) 
1167         tab_width 
+= m_activeCloseBmp
.GetWidth(); 
1169     if (m_flags 
& wxAUI_NB_TAB_FIXED_WIDTH
) 
1171         tab_width 
= m_fixedTabWidth
; 
1174     *x_extent 
= tab_width 
- (tab_height
/2) - 1; 
1176     return wxSize(tab_width
, tab_height
); 
1180 void wxAuiSimpleTabArt::DrawButton(wxDC
& dc
, 
1181                                    wxWindow
* WXUNUSED(wnd
), 
1182                                    const wxRect
& in_rect
, 
1193         case wxAUI_BUTTON_CLOSE
: 
1194             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1195                 bmp 
= m_disabledCloseBmp
; 
1197                 bmp 
= m_activeCloseBmp
; 
1199         case wxAUI_BUTTON_LEFT
: 
1200             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1201                 bmp 
= m_disabledLeftBmp
; 
1203                 bmp 
= m_activeLeftBmp
; 
1205         case wxAUI_BUTTON_RIGHT
: 
1206             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1207                 bmp 
= m_disabledRightBmp
; 
1209                 bmp 
= m_activeRightBmp
; 
1211         case wxAUI_BUTTON_WINDOWLIST
: 
1212             if (button_state 
& wxAUI_BUTTON_STATE_DISABLED
) 
1213                 bmp 
= m_disabledWindowListBmp
; 
1215                 bmp 
= m_activeWindowListBmp
; 
1224     if (orientation 
== wxLEFT
) 
1226         rect
.SetX(in_rect
.x
); 
1227         rect
.SetY(((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2)); 
1228         rect
.SetWidth(bmp
.GetWidth()); 
1229         rect
.SetHeight(bmp
.GetHeight()); 
1233         rect 
= wxRect(in_rect
.x 
+ in_rect
.width 
- bmp
.GetWidth(), 
1234                       ((in_rect
.y 
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2), 
1235                       bmp
.GetWidth(), bmp
.GetHeight()); 
1239     DrawButtons(dc
, rect
, bmp
, *wxWHITE
, button_state
); 
1244 int wxAuiSimpleTabArt::ShowDropDown(wxWindow
* wnd
, 
1245                                     const wxAuiNotebookPageArray
& pages
, 
1250     size_t i
, count 
= pages
.GetCount(); 
1251     for (i 
= 0; i 
< count
; ++i
) 
1253         const wxAuiNotebookPage
& page 
= pages
.Item(i
); 
1254         menuPopup
.AppendCheckItem(1000+i
, page
.caption
); 
1257     if (active_idx 
!= -1) 
1259         menuPopup
.Check(1000+active_idx
, true); 
1262     // find out where to put the popup menu of window 
1263     // items.  Subtract 100 for now to center the menu 
1264     // a bit, until a better mechanism can be implemented 
1265     wxPoint pt 
= ::wxGetMousePosition(); 
1266     pt 
= wnd
->ScreenToClient(pt
); 
1272     // find out the screen coordinate at the bottom of the tab ctrl 
1273     wxRect cli_rect 
= wnd
->GetClientRect(); 
1274     pt
.y 
= cli_rect
.y 
+ cli_rect
.height
; 
1276     wxAuiCommandCapture
* cc 
= new wxAuiCommandCapture
; 
1277     wnd
->PushEventHandler(cc
); 
1278     wnd
->PopupMenu(&menuPopup
, pt
); 
1279     int command 
= cc
->GetCommandId(); 
1280     wnd
->PopEventHandler(true); 
1282     if (command 
>= 1000) 
1283         return command
-1000; 
1288 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow
* wnd
, 
1289                                           const wxAuiNotebookPageArray
& WXUNUSED(pages
), 
1290                                           const wxSize
& WXUNUSED(requiredBmp_size
)) 
1293     dc
.SetFont(m_measuringFont
); 
1295     wxSize s 
= GetTabSize(dc
, 
1300                           wxAUI_BUTTON_STATE_HIDDEN
, 
1305 void wxAuiSimpleTabArt::SetNormalFont(const wxFont
& font
) 
1307     m_normalFont 
= font
; 
1310 void wxAuiSimpleTabArt::SetSelectedFont(const wxFont
& font
) 
1312     m_selectedFont 
= font
; 
1315 void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont
& font
) 
1317     m_measuringFont 
= font
;