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)
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"
25 #include "wx/dcclient.h"
26 #include "wx/settings.h"
27 #include "wx/bitmap.h"
31 #include "wx/renderer.h"
32 #include "wx/aui/auibook.h"
33 #include "wx/aui/framemanager.h"
34 #include "wx/aui/dockart.h"
37 #include "wx/osx/private.h"
41 // -- GUI helper classes and functions --
43 class wxAuiCommandCapture
: public wxEvtHandler
47 wxAuiCommandCapture() { m_lastId
= 0; }
48 int GetCommandId() const { return m_lastId
; }
50 bool ProcessEvent(wxEvent
& evt
)
52 if (evt
.GetEventType() == wxEVT_MENU
)
54 m_lastId
= evt
.GetId();
59 return GetNextHandler()->ProcessEvent(evt
);
69 // these functions live in dockart.cpp -- they'll eventually
70 // be moved to a new utility cpp file
72 wxBitmap
wxAuiBitmapFromBits(const unsigned char bits
[], int w
, int h
,
73 const wxColour
& color
);
75 wxString
wxAuiChopText(wxDC
& dc
, const wxString
& text
, int max_size
);
77 static void DrawButtons(wxDC
& dc
,
80 const wxColour
& bkcolour
,
85 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
91 if (button_state
== wxAUI_BUTTON_STATE_HOVER
||
92 button_state
== wxAUI_BUTTON_STATE_PRESSED
)
94 dc
.SetBrush(wxBrush(bkcolour
.ChangeLightness(120)));
95 dc
.SetPen(wxPen(bkcolour
.ChangeLightness(75)));
97 // draw the background behind the button
98 dc
.DrawRectangle(rect
.x
, rect
.y
, 15, 15);
101 // draw the button itself
102 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
105 static void IndentPressedBitmap(wxRect
* rect
, int button_state
)
107 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
116 #if defined( __WXMAC__ )
117 static const unsigned char close_bits
[]={
118 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
119 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
120 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
121 #elif defined( __WXGTK__)
122 static const unsigned char close_bits
[]={
123 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
124 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
125 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
127 static const unsigned char close_bits
[]={
128 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9,
129 0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3,
130 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
133 static const unsigned char left_bits
[] = {
134 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe,
135 0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe,
136 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
138 static const unsigned char right_bits
[] = {
139 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff,
140 0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff,
141 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
143 static const unsigned char list_bits
[] = {
144 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
145 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff,
146 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
153 // -- wxAuiGenericTabArt class implementation --
155 wxAuiGenericTabArt::wxAuiGenericTabArt()
157 m_normalFont
= *wxNORMAL_FONT
;
158 m_selectedFont
= *wxNORMAL_FONT
;
159 m_selectedFont
.SetWeight(wxBOLD
);
160 m_measuringFont
= m_selectedFont
;
162 m_fixedTabWidth
= 100;
165 #if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON
166 wxColor baseColour
= wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground
));
168 wxColor baseColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
171 // the baseColour is too pale to use as our base colour,
172 // so darken it a bit --
173 if ((255-baseColour
.Red()) +
174 (255-baseColour
.Green()) +
175 (255-baseColour
.Blue()) < 60)
177 baseColour
= baseColour
.ChangeLightness(92);
180 m_activeColour
= baseColour
;
181 m_baseColour
= baseColour
;
182 wxColor borderColour
= baseColour
.ChangeLightness(75);
184 m_borderPen
= wxPen(borderColour
);
185 m_baseColourPen
= wxPen(m_baseColour
);
186 m_baseColourBrush
= wxBrush(m_baseColour
);
188 m_activeCloseBmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
189 m_disabledCloseBmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
191 m_activeLeftBmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
192 m_disabledLeftBmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
194 m_activeRightBmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
195 m_disabledRightBmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
197 m_activeWindowListBmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
198 m_disabledWindowListBmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
203 wxAuiGenericTabArt::~wxAuiGenericTabArt()
207 wxAuiTabArt
* wxAuiGenericTabArt::Clone()
209 return new wxAuiGenericTabArt(*this);
212 void wxAuiGenericTabArt::SetFlags(unsigned int flags
)
217 void wxAuiGenericTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
,
220 m_fixedTabWidth
= 100;
222 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
224 if (m_flags
& wxAUI_NB_CLOSE_BUTTON
)
225 tot_width
-= m_activeCloseBmp
.GetWidth();
226 if (m_flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
227 tot_width
-= m_activeWindowListBmp
.GetWidth();
231 m_fixedTabWidth
= tot_width
/(int)tab_count
;
235 if (m_fixedTabWidth
< 100)
236 m_fixedTabWidth
= 100;
238 if (m_fixedTabWidth
> tot_width
/2)
239 m_fixedTabWidth
= tot_width
/2;
241 if (m_fixedTabWidth
> 220)
242 m_fixedTabWidth
= 220;
244 m_tabCtrlHeight
= tab_ctrl_size
.y
;
248 void wxAuiGenericTabArt::DrawBorder(wxDC
& dc
, wxWindow
* wnd
, const wxRect
& rect
)
250 int i
, border_width
= GetBorderWidth(wnd
);
252 wxRect
theRect(rect
);
253 for (i
= 0; i
< border_width
; ++i
)
255 dc
.DrawRectangle(theRect
.x
, theRect
.y
, theRect
.width
, theRect
.height
);
260 void wxAuiGenericTabArt::DrawBackground(wxDC
& dc
,
261 wxWindow
* WXUNUSED(wnd
),
266 wxColor top_color
= m_baseColour
.ChangeLightness(90);
267 wxColor bottom_color
= m_baseColour
.ChangeLightness(170);
270 if (m_flags
&wxAUI_NB_BOTTOM
)
271 r
= wxRect(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
);
272 // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
273 // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
274 else //for wxAUI_NB_TOP
275 r
= wxRect(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
-3);
277 dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
);
282 dc
.SetPen(m_borderPen
);
283 int y
= rect
.GetHeight();
284 int w
= rect
.GetWidth();
286 if (m_flags
&wxAUI_NB_BOTTOM
)
288 dc
.SetBrush(wxBrush(bottom_color
));
289 dc
.DrawRectangle(-1, 0, w
+2, 4);
291 // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
292 // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
293 else //for wxAUI_NB_TOP
295 dc
.SetBrush(m_baseColourBrush
);
296 dc
.DrawRectangle(-1, y
-4, w
+2, 4);
301 // DrawTab() draws an individual tab.
304 // in_rect - rectangle the tab should be confined to
305 // caption - tab's caption
306 // active - whether or not the tab is active
307 // out_rect - actual output rectangle
308 // x_extent - the advance x; where the next tab should start
310 void wxAuiGenericTabArt::DrawTab(wxDC
& dc
,
312 const wxAuiNotebookPage
& page
,
313 const wxRect
& in_rect
,
314 int close_button_state
,
315 wxRect
* out_tab_rect
,
316 wxRect
* out_button_rect
,
319 wxCoord normal_textx
, normal_texty
;
320 wxCoord selected_textx
, selected_texty
;
323 // if the caption is empty, measure some temporary text
324 wxString caption
= page
.caption
;
328 dc
.SetFont(m_selectedFont
);
329 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
331 dc
.SetFont(m_normalFont
);
332 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
334 // figure out the size of the tab
335 wxSize tab_size
= GetTabSize(dc
,
343 wxCoord tab_height
= m_tabCtrlHeight
- 3;
344 wxCoord tab_width
= tab_size
.x
;
345 wxCoord tab_x
= in_rect
.x
;
346 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
349 caption
= page
.caption
;
352 // select pen, brush and font for the tab to be drawn
356 dc
.SetFont(m_selectedFont
);
357 texty
= selected_texty
;
361 dc
.SetFont(m_normalFont
);
362 texty
= normal_texty
;
366 // create points that will make the tab outline
368 int clip_width
= tab_width
;
369 if (tab_x
+ clip_width
> in_rect
.x
+ in_rect
.width
)
370 clip_width
= (in_rect
.x
+ in_rect
.width
) - tab_x
;
373 wxPoint clip_points[6];
374 clip_points[0] = wxPoint(tab_x, tab_y+tab_height-3);
375 clip_points[1] = wxPoint(tab_x, tab_y+2);
376 clip_points[2] = wxPoint(tab_x+2, tab_y);
377 clip_points[3] = wxPoint(tab_x+clip_width-1, tab_y);
378 clip_points[4] = wxPoint(tab_x+clip_width+1, tab_y+2);
379 clip_points[5] = wxPoint(tab_x+clip_width+1, tab_y+tab_height-3);
381 // FIXME: these ports don't provide wxRegion ctor from array of points
382 #if !defined(__WXDFB__) && !defined(__WXCOCOA__)
383 // set the clipping region for the tab --
384 wxRegion clipping_region(WXSIZEOF(clip_points), clip_points);
385 dc.SetClippingRegion(clipping_region);
386 #endif // !wxDFB && !wxCocoa
388 // since the above code above doesn't play well with WXDFB or WXCOCOA,
389 // we'll just use a rectangle for the clipping region for now --
390 dc
.SetClippingRegion(tab_x
, tab_y
, clip_width
+1, tab_height
-3);
393 wxPoint border_points
[6];
394 if (m_flags
&wxAUI_NB_BOTTOM
)
396 border_points
[0] = wxPoint(tab_x
, tab_y
);
397 border_points
[1] = wxPoint(tab_x
, tab_y
+tab_height
-6);
398 border_points
[2] = wxPoint(tab_x
+2, tab_y
+tab_height
-4);
399 border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
+tab_height
-4);
400 border_points
[4] = wxPoint(tab_x
+tab_width
, tab_y
+tab_height
-6);
401 border_points
[5] = wxPoint(tab_x
+tab_width
, tab_y
);
403 else //if (m_flags & wxAUI_NB_TOP) {}
405 border_points
[0] = wxPoint(tab_x
, tab_y
+tab_height
-4);
406 border_points
[1] = wxPoint(tab_x
, tab_y
+2);
407 border_points
[2] = wxPoint(tab_x
+2, tab_y
);
408 border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
);
409 border_points
[4] = wxPoint(tab_x
+tab_width
, tab_y
+2);
410 border_points
[5] = wxPoint(tab_x
+tab_width
, tab_y
+tab_height
-4);
412 // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
413 // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
415 int drawn_tab_yoff
= border_points
[1].y
;
416 int drawn_tab_height
= border_points
[0].y
- border_points
[1].y
;
423 // draw base background color
424 wxRect
r(tab_x
, tab_y
, tab_width
, tab_height
);
425 dc
.SetPen(wxPen(m_activeColour
));
426 dc
.SetBrush(wxBrush(m_activeColour
));
427 dc
.DrawRectangle(r
.x
+1, r
.y
+1, r
.width
-1, r
.height
-4);
429 // this white helps fill out the gradient at the top of the tab
430 dc
.SetPen(*wxWHITE_PEN
);
431 dc
.SetBrush(*wxWHITE_BRUSH
);
432 dc
.DrawRectangle(r
.x
+2, r
.y
+1, r
.width
-3, r
.height
-4);
434 // these two points help the rounded corners appear more antialiased
435 dc
.SetPen(wxPen(m_activeColour
));
436 dc
.DrawPoint(r
.x
+2, r
.y
+1);
437 dc
.DrawPoint(r
.x
+r
.width
-2, r
.y
+1);
439 // set rectangle down a bit for gradient drawing
440 r
.SetHeight(r
.GetHeight()/2);
446 // draw gradient background
447 wxColor top_color
= *wxWHITE
;
448 wxColor bottom_color
= m_activeColour
;
449 dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
);
455 wxRect
r(tab_x
, tab_y
+1, tab_width
, tab_height
-3);
457 // start the gradent up a bit and leave the inside border inset
458 // by a pixel for a 3D look. Only the top half of the inactive
459 // tab will have a slight gradient
466 // -- draw top gradient fill for glossy look
467 wxColor top_color
= m_baseColour
;
468 wxColor bottom_color
= top_color
.ChangeLightness(160);
469 dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
);
474 // -- draw bottom fill for glossy look
475 top_color
= m_baseColour
;
476 bottom_color
= m_baseColour
;
477 dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
);
481 dc
.SetPen(m_borderPen
);
482 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
483 dc
.DrawPolygon(WXSIZEOF(border_points
), border_points
);
485 // there are two horizontal grey lines at the bottom of the tab control,
486 // this gets rid of the top one of those lines in the tab control
489 if (m_flags
&wxAUI_NB_BOTTOM
)
490 dc
.SetPen(wxPen(m_baseColour
.ChangeLightness(170)));
491 // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
492 // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
493 else //for wxAUI_NB_TOP
494 dc
.SetPen(m_baseColourPen
);
495 dc
.DrawLine(border_points
[0].x
+1,
502 int text_offset
= tab_x
+ 8;
503 int close_button_width
= 0;
504 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
506 close_button_width
= m_activeCloseBmp
.GetWidth();
509 int bitmap_offset
= 0;
510 if (page
.bitmap
.IsOk())
512 bitmap_offset
= tab_x
+ 8;
515 dc
.DrawBitmap(page
.bitmap
,
517 drawn_tab_yoff
+ (drawn_tab_height
/2) - (page
.bitmap
.GetHeight()/2),
520 text_offset
= bitmap_offset
+ page
.bitmap
.GetWidth();
521 text_offset
+= 3; // bitmap padding
526 text_offset
= tab_x
+ 8;
530 wxString draw_text
= wxAuiChopText(dc
,
532 tab_width
- (text_offset
-tab_x
) - close_button_width
);
535 dc
.DrawText(draw_text
,
537 drawn_tab_yoff
+ (drawn_tab_height
)/2 - (texty
/2) - 1);
539 // draw focus rectangle
540 if (page
.active
&& (wnd
->FindFocus() == wnd
))
542 wxRect
focusRectText(text_offset
, (drawn_tab_yoff
+ (drawn_tab_height
)/2 - (texty
/2) - 1),
543 selected_textx
, selected_texty
);
546 wxRect focusRectBitmap
;
548 if (page
.bitmap
.IsOk())
549 focusRectBitmap
= wxRect(bitmap_offset
, drawn_tab_yoff
+ (drawn_tab_height
/2) - (page
.bitmap
.GetHeight()/2),
550 page
.bitmap
.GetWidth(), page
.bitmap
.GetHeight());
552 if (page
.bitmap
.IsOk() && draw_text
.IsEmpty())
553 focusRect
= focusRectBitmap
;
554 else if (!page
.bitmap
.IsOk() && !draw_text
.IsEmpty())
555 focusRect
= focusRectText
;
556 else if (page
.bitmap
.IsOk() && !draw_text
.IsEmpty())
557 focusRect
= focusRectText
.Union(focusRectBitmap
);
559 focusRect
.Inflate(2, 2);
561 wxRendererNative::Get().DrawFocusRect(wnd
, dc
, focusRect
, 0);
564 // draw close button if necessary
565 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
567 wxBitmap bmp
= m_disabledCloseBmp
;
569 if (close_button_state
== wxAUI_BUTTON_STATE_HOVER
||
570 close_button_state
== wxAUI_BUTTON_STATE_PRESSED
)
572 bmp
= m_activeCloseBmp
;
575 int offsetY
= tab_y
-1;
576 if (m_flags
& wxAUI_NB_BOTTOM
)
579 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
580 offsetY
+ (tab_height
/2) - (bmp
.GetHeight()/2),
584 IndentPressedBitmap(&rect
, close_button_state
);
585 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
587 *out_button_rect
= rect
;
590 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
592 dc
.DestroyClippingRegion();
595 int wxAuiGenericTabArt::GetIndentSize()
600 int wxAuiGenericTabArt::GetBorderWidth(wxWindow
* wnd
)
602 wxAuiManager
* mgr
= wxAuiManager::GetManager(wnd
);
605 wxAuiDockArt
* art
= mgr
->GetArtProvider();
607 return art
->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE
);
612 int wxAuiGenericTabArt::GetAdditionalBorderSpace(wxWindow
* WXUNUSED(wnd
))
617 wxSize
wxAuiGenericTabArt::GetTabSize(wxDC
& dc
,
618 wxWindow
* WXUNUSED(wnd
),
619 const wxString
& caption
,
620 const wxBitmap
& bitmap
,
621 bool WXUNUSED(active
),
622 int close_button_state
,
625 wxCoord measured_textx
, measured_texty
, tmp
;
627 dc
.SetFont(m_measuringFont
);
628 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
630 dc
.GetTextExtent(wxT("ABCDEFXj"), &tmp
, &measured_texty
);
632 // add padding around the text
633 wxCoord tab_width
= measured_textx
;
634 wxCoord tab_height
= measured_texty
;
636 // if the close button is showing, add space for it
637 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
638 tab_width
+= m_activeCloseBmp
.GetWidth() + 3;
640 // if there's a bitmap, add space for it
643 tab_width
+= bitmap
.GetWidth();
644 tab_width
+= 3; // right side bitmap padding
645 tab_height
= wxMax(tab_height
, bitmap
.GetHeight());
652 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
654 tab_width
= m_fixedTabWidth
;
657 *x_extent
= tab_width
;
659 return wxSize(tab_width
, tab_height
);
663 void wxAuiGenericTabArt::DrawButton(wxDC
& dc
,
664 wxWindow
* WXUNUSED(wnd
),
665 const wxRect
& in_rect
,
676 case wxAUI_BUTTON_CLOSE
:
677 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
678 bmp
= m_disabledCloseBmp
;
680 bmp
= m_activeCloseBmp
;
682 case wxAUI_BUTTON_LEFT
:
683 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
684 bmp
= m_disabledLeftBmp
;
686 bmp
= m_activeLeftBmp
;
688 case wxAUI_BUTTON_RIGHT
:
689 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
690 bmp
= m_disabledRightBmp
;
692 bmp
= m_activeRightBmp
;
694 case wxAUI_BUTTON_WINDOWLIST
:
695 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
696 bmp
= m_disabledWindowListBmp
;
698 bmp
= m_activeWindowListBmp
;
708 if (orientation
== wxLEFT
)
710 rect
.SetX(in_rect
.x
);
711 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
712 rect
.SetWidth(bmp
.GetWidth());
713 rect
.SetHeight(bmp
.GetHeight());
717 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
718 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
719 bmp
.GetWidth(), bmp
.GetHeight());
722 IndentPressedBitmap(&rect
, button_state
);
723 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
728 int wxAuiGenericTabArt::ShowDropDown(wxWindow
* wnd
,
729 const wxAuiNotebookPageArray
& pages
,
734 size_t i
, count
= pages
.GetCount();
735 for (i
= 0; i
< count
; ++i
)
737 const wxAuiNotebookPage
& page
= pages
.Item(i
);
738 wxString caption
= page
.caption
;
740 // if there is no caption, make it a space. This will prevent
741 // an assert in the menu code.
742 if (caption
.IsEmpty())
745 wxMenuItem
* item
= new wxMenuItem(NULL
, 1000+i
, caption
);
746 if (page
.bitmap
.IsOk())
747 item
->SetBitmap(page
.bitmap
);
748 menuPopup
.Append(item
);
751 // find out where to put the popup menu of window items
752 wxPoint pt
= ::wxGetMousePosition();
753 pt
= wnd
->ScreenToClient(pt
);
755 // find out the screen coordinate at the bottom of the tab ctrl
756 wxRect cli_rect
= wnd
->GetClientRect();
757 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
759 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
760 wnd
->PushEventHandler(cc
);
761 wnd
->PopupMenu(&menuPopup
, pt
);
762 int command
= cc
->GetCommandId();
763 wnd
->PopEventHandler(true);
771 int wxAuiGenericTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
772 const wxAuiNotebookPageArray
& pages
,
773 const wxSize
& requiredBmp_size
)
776 dc
.SetFont(m_measuringFont
);
778 // sometimes a standard bitmap size needs to be enforced, especially
779 // if some tabs have bitmaps and others don't. This is important because
780 // it prevents the tab control from resizing when tabs are added.
782 if (requiredBmp_size
.IsFullySpecified())
784 measureBmp
.Create(requiredBmp_size
.x
,
790 size_t i
, page_count
= pages
.GetCount();
791 for (i
= 0; i
< page_count
; ++i
)
793 wxAuiNotebookPage
& page
= pages
.Item(i
);
796 if (measureBmp
.IsOk())
801 // we don't use the caption text because we don't
802 // want tab heights to be different in the case
803 // of a very short piece of text on one tab and a very
804 // tall piece of text on another tab
806 wxSize s
= GetTabSize(dc
,
811 wxAUI_BUTTON_STATE_HIDDEN
,
814 max_y
= wxMax(max_y
, s
.y
);
820 void wxAuiGenericTabArt::SetNormalFont(const wxFont
& font
)
825 void wxAuiGenericTabArt::SetSelectedFont(const wxFont
& font
)
827 m_selectedFont
= font
;
830 void wxAuiGenericTabArt::SetMeasuringFont(const wxFont
& font
)
832 m_measuringFont
= font
;
835 void wxAuiGenericTabArt::SetColour(const wxColour
& colour
)
837 m_baseColour
= colour
;
838 m_borderPen
= wxPen(m_baseColour
.ChangeLightness(75));
839 m_baseColourPen
= wxPen(m_baseColour
);
840 m_baseColourBrush
= wxBrush(m_baseColour
);
843 void wxAuiGenericTabArt::SetActiveColour(const wxColour
& colour
)
845 m_activeColour
= colour
;
848 // -- wxAuiSimpleTabArt class implementation --
850 wxAuiSimpleTabArt::wxAuiSimpleTabArt()
852 m_normalFont
= *wxNORMAL_FONT
;
853 m_selectedFont
= *wxNORMAL_FONT
;
854 m_selectedFont
.SetWeight(wxBOLD
);
855 m_measuringFont
= m_selectedFont
;
858 m_fixedTabWidth
= 100;
860 wxColour baseColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
862 wxColour backgroundColour
= baseColour
;
863 wxColour normaltabColour
= baseColour
;
864 wxColour selectedtabColour
= *wxWHITE
;
866 m_bkBrush
= wxBrush(backgroundColour
);
867 m_normalBkBrush
= wxBrush(normaltabColour
);
868 m_normalBkPen
= wxPen(normaltabColour
);
869 m_selectedBkBrush
= wxBrush(selectedtabColour
);
870 m_selectedBkPen
= wxPen(selectedtabColour
);
872 m_activeCloseBmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
873 m_disabledCloseBmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
875 m_activeLeftBmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
876 m_disabledLeftBmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
878 m_activeRightBmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
879 m_disabledRightBmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
881 m_activeWindowListBmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
882 m_disabledWindowListBmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
886 wxAuiSimpleTabArt::~wxAuiSimpleTabArt()
890 wxAuiTabArt
* wxAuiSimpleTabArt::Clone()
892 return new wxAuiSimpleTabArt(*this);
895 void wxAuiSimpleTabArt::SetFlags(unsigned int flags
)
900 void wxAuiSimpleTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
,
903 m_fixedTabWidth
= 100;
905 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
907 if (m_flags
& wxAUI_NB_CLOSE_BUTTON
)
908 tot_width
-= m_activeCloseBmp
.GetWidth();
909 if (m_flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
910 tot_width
-= m_activeWindowListBmp
.GetWidth();
914 m_fixedTabWidth
= tot_width
/(int)tab_count
;
918 if (m_fixedTabWidth
< 100)
919 m_fixedTabWidth
= 100;
921 if (m_fixedTabWidth
> tot_width
/2)
922 m_fixedTabWidth
= tot_width
/2;
924 if (m_fixedTabWidth
> 220)
925 m_fixedTabWidth
= 220;
928 void wxAuiSimpleTabArt::SetColour(const wxColour
& colour
)
930 m_bkBrush
= wxBrush(colour
);
931 m_normalBkBrush
= wxBrush(colour
);
932 m_normalBkPen
= wxPen(colour
);
935 void wxAuiSimpleTabArt::SetActiveColour(const wxColour
& colour
)
937 m_selectedBkBrush
= wxBrush(colour
);
938 m_selectedBkPen
= wxPen(colour
);
941 void wxAuiSimpleTabArt::DrawBorder(wxDC
& dc
, wxWindow
* wnd
, const wxRect
& rect
)
943 int i
, border_width
= GetBorderWidth(wnd
);
945 wxRect
theRect(rect
);
946 for (i
= 0; i
< border_width
; ++i
)
948 dc
.DrawRectangle(theRect
.x
, theRect
.y
, theRect
.width
, theRect
.height
);
953 void wxAuiSimpleTabArt::DrawBackground(wxDC
& dc
,
954 wxWindow
* WXUNUSED(wnd
),
958 dc
.SetBrush(m_bkBrush
);
959 dc
.SetPen(*wxTRANSPARENT_PEN
);
960 dc
.DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2);
963 dc
.SetPen(*wxGREY_PEN
);
964 dc
.DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1);
968 // DrawTab() draws an individual tab.
971 // in_rect - rectangle the tab should be confined to
972 // caption - tab's caption
973 // active - whether or not the tab is active
974 // out_rect - actual output rectangle
975 // x_extent - the advance x; where the next tab should start
977 void wxAuiSimpleTabArt::DrawTab(wxDC
& dc
,
979 const wxAuiNotebookPage
& page
,
980 const wxRect
& in_rect
,
981 int close_button_state
,
982 wxRect
* out_tab_rect
,
983 wxRect
* out_button_rect
,
986 wxCoord normal_textx
, normal_texty
;
987 wxCoord selected_textx
, selected_texty
;
988 wxCoord textx
, texty
;
990 // if the caption is empty, measure some temporary text
991 wxString caption
= page
.caption
;
995 dc
.SetFont(m_selectedFont
);
996 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
998 dc
.SetFont(m_normalFont
);
999 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
1001 // figure out the size of the tab
1002 wxSize tab_size
= GetTabSize(dc
,
1010 wxCoord tab_height
= tab_size
.y
;
1011 wxCoord tab_width
= tab_size
.x
;
1012 wxCoord tab_x
= in_rect
.x
;
1013 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
1015 caption
= page
.caption
;
1017 // select pen, brush and font for the tab to be drawn
1021 dc
.SetPen(m_selectedBkPen
);
1022 dc
.SetBrush(m_selectedBkBrush
);
1023 dc
.SetFont(m_selectedFont
);
1024 textx
= selected_textx
;
1025 texty
= selected_texty
;
1029 dc
.SetPen(m_normalBkPen
);
1030 dc
.SetBrush(m_normalBkBrush
);
1031 dc
.SetFont(m_normalFont
);
1032 textx
= normal_textx
;
1033 texty
= normal_texty
;
1040 points
[0].x
= tab_x
;
1041 points
[0].y
= tab_y
+ tab_height
- 1;
1042 points
[1].x
= tab_x
+ tab_height
- 3;
1043 points
[1].y
= tab_y
+ 2;
1044 points
[2].x
= tab_x
+ tab_height
+ 3;
1045 points
[2].y
= tab_y
;
1046 points
[3].x
= tab_x
+ tab_width
- 2;
1047 points
[3].y
= tab_y
;
1048 points
[4].x
= tab_x
+ tab_width
;
1049 points
[4].y
= tab_y
+ 2;
1050 points
[5].x
= tab_x
+ tab_width
;
1051 points
[5].y
= tab_y
+ tab_height
- 1;
1052 points
[6] = points
[0];
1054 dc
.SetClippingRegion(in_rect
);
1056 dc
.DrawPolygon(WXSIZEOF(points
) - 1, points
);
1058 dc
.SetPen(*wxGREY_PEN
);
1060 //dc.DrawLines(active ? WXSIZEOF(points) - 1 : WXSIZEOF(points), points);
1061 dc
.DrawLines(WXSIZEOF(points
), points
);
1066 int close_button_width
= 0;
1067 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1069 close_button_width
= m_activeCloseBmp
.GetWidth();
1070 text_offset
= tab_x
+ (tab_height
/2) + ((tab_width
-close_button_width
)/2) - (textx
/2);
1074 text_offset
= tab_x
+ (tab_height
/3) + (tab_width
/2) - (textx
/2);
1077 // set minimum text offset
1078 if (text_offset
< tab_x
+ tab_height
)
1079 text_offset
= tab_x
+ tab_height
;
1081 // chop text if necessary
1082 wxString draw_text
= wxAuiChopText(dc
,
1084 tab_width
- (text_offset
-tab_x
) - close_button_width
);
1087 dc
.DrawText(draw_text
,
1089 (tab_y
+ tab_height
)/2 - (texty
/2) + 1);
1092 // draw focus rectangle
1093 if (page
.active
&& (wnd
->FindFocus() == wnd
))
1095 wxRect
focusRect(text_offset
, ((tab_y
+ tab_height
)/2 - (texty
/2) + 1),
1096 selected_textx
, selected_texty
);
1098 focusRect
.Inflate(2, 2);
1100 wxRendererNative::Get().DrawFocusRect(wnd
, dc
, focusRect
, 0);
1103 // draw close button if necessary
1104 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1108 bmp
= m_activeCloseBmp
;
1110 bmp
= m_disabledCloseBmp
;
1112 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
1113 tab_y
+ (tab_height
/2) - (bmp
.GetHeight()/2) + 1,
1116 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, close_button_state
);
1118 *out_button_rect
= rect
;
1122 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
1124 dc
.DestroyClippingRegion();
1127 int wxAuiSimpleTabArt::GetIndentSize()
1132 int wxAuiSimpleTabArt::GetBorderWidth(wxWindow
* wnd
)
1134 wxAuiManager
* mgr
= wxAuiManager::GetManager(wnd
);
1137 wxAuiDockArt
* art
= mgr
->GetArtProvider();
1139 return art
->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE
);
1144 int wxAuiSimpleTabArt::GetAdditionalBorderSpace(wxWindow
* WXUNUSED(wnd
))
1149 wxSize
wxAuiSimpleTabArt::GetTabSize(wxDC
& dc
,
1150 wxWindow
* WXUNUSED(wnd
),
1151 const wxString
& caption
,
1152 const wxBitmap
& WXUNUSED(bitmap
),
1153 bool WXUNUSED(active
),
1154 int close_button_state
,
1157 wxCoord measured_textx
, measured_texty
;
1159 dc
.SetFont(m_measuringFont
);
1160 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
1162 wxCoord tab_height
= measured_texty
+ 4;
1163 wxCoord tab_width
= measured_textx
+ tab_height
+ 5;
1165 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1166 tab_width
+= m_activeCloseBmp
.GetWidth();
1168 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
1170 tab_width
= m_fixedTabWidth
;
1173 *x_extent
= tab_width
- (tab_height
/2) - 1;
1175 return wxSize(tab_width
, tab_height
);
1179 void wxAuiSimpleTabArt::DrawButton(wxDC
& dc
,
1180 wxWindow
* WXUNUSED(wnd
),
1181 const wxRect
& in_rect
,
1192 case wxAUI_BUTTON_CLOSE
:
1193 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1194 bmp
= m_disabledCloseBmp
;
1196 bmp
= m_activeCloseBmp
;
1198 case wxAUI_BUTTON_LEFT
:
1199 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1200 bmp
= m_disabledLeftBmp
;
1202 bmp
= m_activeLeftBmp
;
1204 case wxAUI_BUTTON_RIGHT
:
1205 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1206 bmp
= m_disabledRightBmp
;
1208 bmp
= m_activeRightBmp
;
1210 case wxAUI_BUTTON_WINDOWLIST
:
1211 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1212 bmp
= m_disabledWindowListBmp
;
1214 bmp
= m_activeWindowListBmp
;
1223 if (orientation
== wxLEFT
)
1225 rect
.SetX(in_rect
.x
);
1226 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
1227 rect
.SetWidth(bmp
.GetWidth());
1228 rect
.SetHeight(bmp
.GetHeight());
1232 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
1233 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
1234 bmp
.GetWidth(), bmp
.GetHeight());
1238 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, button_state
);
1243 int wxAuiSimpleTabArt::ShowDropDown(wxWindow
* wnd
,
1244 const wxAuiNotebookPageArray
& pages
,
1249 size_t i
, count
= pages
.GetCount();
1250 for (i
= 0; i
< count
; ++i
)
1252 const wxAuiNotebookPage
& page
= pages
.Item(i
);
1253 menuPopup
.AppendCheckItem(1000+i
, page
.caption
);
1256 if (active_idx
!= -1)
1258 menuPopup
.Check(1000+active_idx
, true);
1261 // find out where to put the popup menu of window
1262 // items. Subtract 100 for now to center the menu
1263 // a bit, until a better mechanism can be implemented
1264 wxPoint pt
= ::wxGetMousePosition();
1265 pt
= wnd
->ScreenToClient(pt
);
1271 // find out the screen coordinate at the bottom of the tab ctrl
1272 wxRect cli_rect
= wnd
->GetClientRect();
1273 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
1275 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
1276 wnd
->PushEventHandler(cc
);
1277 wnd
->PopupMenu(&menuPopup
, pt
);
1278 int command
= cc
->GetCommandId();
1279 wnd
->PopEventHandler(true);
1281 if (command
>= 1000)
1282 return command
-1000;
1287 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
1288 const wxAuiNotebookPageArray
& WXUNUSED(pages
),
1289 const wxSize
& WXUNUSED(requiredBmp_size
))
1292 dc
.SetFont(m_measuringFont
);
1294 wxSize s
= GetTabSize(dc
,
1299 wxAUI_BUTTON_STATE_HIDDEN
,
1304 void wxAuiSimpleTabArt::SetNormalFont(const wxFont
& font
)
1306 m_normalFont
= font
;
1309 void wxAuiSimpleTabArt::SetSelectedFont(const wxFont
& font
)
1311 m_selectedFont
= font
;
1314 void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont
& font
)
1316 m_measuringFont
= font
;