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
;