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_COMMAND_MENU_SELECTED
)
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 wxSize
wxAuiGenericTabArt::GetTabSize(wxDC
& dc
,
614 wxWindow
* WXUNUSED(wnd
),
615 const wxString
& caption
,
616 const wxBitmap
& bitmap
,
617 bool WXUNUSED(active
),
618 int close_button_state
,
621 wxCoord measured_textx
, measured_texty
, tmp
;
623 dc
.SetFont(m_measuringFont
);
624 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
626 dc
.GetTextExtent(wxT("ABCDEFXj"), &tmp
, &measured_texty
);
628 // add padding around the text
629 wxCoord tab_width
= measured_textx
;
630 wxCoord tab_height
= measured_texty
;
632 // if the close button is showing, add space for it
633 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
634 tab_width
+= m_activeCloseBmp
.GetWidth() + 3;
636 // if there's a bitmap, add space for it
639 tab_width
+= bitmap
.GetWidth();
640 tab_width
+= 3; // right side bitmap padding
641 tab_height
= wxMax(tab_height
, bitmap
.GetHeight());
648 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
650 tab_width
= m_fixedTabWidth
;
653 *x_extent
= tab_width
;
655 return wxSize(tab_width
, tab_height
);
659 void wxAuiGenericTabArt::DrawButton(wxDC
& dc
,
660 wxWindow
* WXUNUSED(wnd
),
661 const wxRect
& in_rect
,
672 case wxAUI_BUTTON_CLOSE
:
673 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
674 bmp
= m_disabledCloseBmp
;
676 bmp
= m_activeCloseBmp
;
678 case wxAUI_BUTTON_LEFT
:
679 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
680 bmp
= m_disabledLeftBmp
;
682 bmp
= m_activeLeftBmp
;
684 case wxAUI_BUTTON_RIGHT
:
685 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
686 bmp
= m_disabledRightBmp
;
688 bmp
= m_activeRightBmp
;
690 case wxAUI_BUTTON_WINDOWLIST
:
691 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
692 bmp
= m_disabledWindowListBmp
;
694 bmp
= m_activeWindowListBmp
;
704 if (orientation
== wxLEFT
)
706 rect
.SetX(in_rect
.x
);
707 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
708 rect
.SetWidth(bmp
.GetWidth());
709 rect
.SetHeight(bmp
.GetHeight());
713 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
714 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
715 bmp
.GetWidth(), bmp
.GetHeight());
718 IndentPressedBitmap(&rect
, button_state
);
719 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
724 int wxAuiGenericTabArt::ShowDropDown(wxWindow
* wnd
,
725 const wxAuiNotebookPageArray
& pages
,
730 size_t i
, count
= pages
.GetCount();
731 for (i
= 0; i
< count
; ++i
)
733 const wxAuiNotebookPage
& page
= pages
.Item(i
);
734 wxString caption
= page
.caption
;
736 // if there is no caption, make it a space. This will prevent
737 // an assert in the menu code.
738 if (caption
.IsEmpty())
741 wxMenuItem
* item
= new wxMenuItem(NULL
, 1000+i
, caption
);
742 if (page
.bitmap
.IsOk())
743 item
->SetBitmap(page
.bitmap
);
744 menuPopup
.Append(item
);
747 // find out where to put the popup menu of window items
748 wxPoint pt
= ::wxGetMousePosition();
749 pt
= wnd
->ScreenToClient(pt
);
751 // find out the screen coordinate at the bottom of the tab ctrl
752 wxRect cli_rect
= wnd
->GetClientRect();
753 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
755 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
756 wnd
->PushEventHandler(cc
);
757 wnd
->PopupMenu(&menuPopup
, pt
);
758 int command
= cc
->GetCommandId();
759 wnd
->PopEventHandler(true);
767 int wxAuiGenericTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
768 const wxAuiNotebookPageArray
& pages
,
769 const wxSize
& requiredBmp_size
)
772 dc
.SetFont(m_measuringFont
);
774 // sometimes a standard bitmap size needs to be enforced, especially
775 // if some tabs have bitmaps and others don't. This is important because
776 // it prevents the tab control from resizing when tabs are added.
778 if (requiredBmp_size
.IsFullySpecified())
780 measureBmp
.Create(requiredBmp_size
.x
,
786 size_t i
, page_count
= pages
.GetCount();
787 for (i
= 0; i
< page_count
; ++i
)
789 wxAuiNotebookPage
& page
= pages
.Item(i
);
792 if (measureBmp
.IsOk())
797 // we don't use the caption text because we don't
798 // want tab heights to be different in the case
799 // of a very short piece of text on one tab and a very
800 // tall piece of text on another tab
802 wxSize s
= GetTabSize(dc
,
807 wxAUI_BUTTON_STATE_HIDDEN
,
810 max_y
= wxMax(max_y
, s
.y
);
816 void wxAuiGenericTabArt::SetNormalFont(const wxFont
& font
)
821 void wxAuiGenericTabArt::SetSelectedFont(const wxFont
& font
)
823 m_selectedFont
= font
;
826 void wxAuiGenericTabArt::SetMeasuringFont(const wxFont
& font
)
828 m_measuringFont
= font
;
831 void wxAuiGenericTabArt::SetColour(const wxColour
& colour
)
833 m_baseColour
= colour
;
834 m_borderPen
= wxPen(m_baseColour
.ChangeLightness(75));
835 m_baseColourPen
= wxPen(m_baseColour
);
836 m_baseColourBrush
= wxBrush(m_baseColour
);
839 void wxAuiGenericTabArt::SetActiveColour(const wxColour
& colour
)
841 m_activeColour
= colour
;
844 // -- wxAuiSimpleTabArt class implementation --
846 wxAuiSimpleTabArt::wxAuiSimpleTabArt()
848 m_normalFont
= *wxNORMAL_FONT
;
849 m_selectedFont
= *wxNORMAL_FONT
;
850 m_selectedFont
.SetWeight(wxBOLD
);
851 m_measuringFont
= m_selectedFont
;
854 m_fixedTabWidth
= 100;
856 wxColour baseColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
858 wxColour backgroundColour
= baseColour
;
859 wxColour normaltabColour
= baseColour
;
860 wxColour selectedtabColour
= *wxWHITE
;
862 m_bkBrush
= wxBrush(backgroundColour
);
863 m_normalBkBrush
= wxBrush(normaltabColour
);
864 m_normalBkPen
= wxPen(normaltabColour
);
865 m_selectedBkBrush
= wxBrush(selectedtabColour
);
866 m_selectedBkPen
= wxPen(selectedtabColour
);
868 m_activeCloseBmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
869 m_disabledCloseBmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
871 m_activeLeftBmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
872 m_disabledLeftBmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
874 m_activeRightBmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
875 m_disabledRightBmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
877 m_activeWindowListBmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
878 m_disabledWindowListBmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
882 wxAuiSimpleTabArt::~wxAuiSimpleTabArt()
886 wxAuiTabArt
* wxAuiSimpleTabArt::Clone()
888 return new wxAuiSimpleTabArt(*this);
891 void wxAuiSimpleTabArt::SetFlags(unsigned int flags
)
896 void wxAuiSimpleTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
,
899 m_fixedTabWidth
= 100;
901 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
903 if (m_flags
& wxAUI_NB_CLOSE_BUTTON
)
904 tot_width
-= m_activeCloseBmp
.GetWidth();
905 if (m_flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
906 tot_width
-= m_activeWindowListBmp
.GetWidth();
910 m_fixedTabWidth
= tot_width
/(int)tab_count
;
914 if (m_fixedTabWidth
< 100)
915 m_fixedTabWidth
= 100;
917 if (m_fixedTabWidth
> tot_width
/2)
918 m_fixedTabWidth
= tot_width
/2;
920 if (m_fixedTabWidth
> 220)
921 m_fixedTabWidth
= 220;
924 void wxAuiSimpleTabArt::SetColour(const wxColour
& colour
)
926 m_bkBrush
= wxBrush(colour
);
927 m_normalBkBrush
= wxBrush(colour
);
928 m_normalBkPen
= wxPen(colour
);
931 void wxAuiSimpleTabArt::SetActiveColour(const wxColour
& colour
)
933 m_selectedBkBrush
= wxBrush(colour
);
934 m_selectedBkPen
= wxPen(colour
);
937 void wxAuiSimpleTabArt::DrawBorder(wxDC
& dc
, wxWindow
* wnd
, const wxRect
& rect
)
939 int i
, border_width
= GetBorderWidth(wnd
);
941 wxRect
theRect(rect
);
942 for (i
= 0; i
< border_width
; ++i
)
944 dc
.DrawRectangle(theRect
.x
, theRect
.y
, theRect
.width
, theRect
.height
);
949 void wxAuiSimpleTabArt::DrawBackground(wxDC
& dc
,
950 wxWindow
* WXUNUSED(wnd
),
954 dc
.SetBrush(m_bkBrush
);
955 dc
.SetPen(*wxTRANSPARENT_PEN
);
956 dc
.DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2);
959 dc
.SetPen(*wxGREY_PEN
);
960 dc
.DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1);
964 // DrawTab() draws an individual tab.
967 // in_rect - rectangle the tab should be confined to
968 // caption - tab's caption
969 // active - whether or not the tab is active
970 // out_rect - actual output rectangle
971 // x_extent - the advance x; where the next tab should start
973 void wxAuiSimpleTabArt::DrawTab(wxDC
& dc
,
975 const wxAuiNotebookPage
& page
,
976 const wxRect
& in_rect
,
977 int close_button_state
,
978 wxRect
* out_tab_rect
,
979 wxRect
* out_button_rect
,
982 wxCoord normal_textx
, normal_texty
;
983 wxCoord selected_textx
, selected_texty
;
984 wxCoord textx
, texty
;
986 // if the caption is empty, measure some temporary text
987 wxString caption
= page
.caption
;
991 dc
.SetFont(m_selectedFont
);
992 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
994 dc
.SetFont(m_normalFont
);
995 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
997 // figure out the size of the tab
998 wxSize tab_size
= GetTabSize(dc
,
1006 wxCoord tab_height
= tab_size
.y
;
1007 wxCoord tab_width
= tab_size
.x
;
1008 wxCoord tab_x
= in_rect
.x
;
1009 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
1011 caption
= page
.caption
;
1013 // select pen, brush and font for the tab to be drawn
1017 dc
.SetPen(m_selectedBkPen
);
1018 dc
.SetBrush(m_selectedBkBrush
);
1019 dc
.SetFont(m_selectedFont
);
1020 textx
= selected_textx
;
1021 texty
= selected_texty
;
1025 dc
.SetPen(m_normalBkPen
);
1026 dc
.SetBrush(m_normalBkBrush
);
1027 dc
.SetFont(m_normalFont
);
1028 textx
= normal_textx
;
1029 texty
= normal_texty
;
1036 points
[0].x
= tab_x
;
1037 points
[0].y
= tab_y
+ tab_height
- 1;
1038 points
[1].x
= tab_x
+ tab_height
- 3;
1039 points
[1].y
= tab_y
+ 2;
1040 points
[2].x
= tab_x
+ tab_height
+ 3;
1041 points
[2].y
= tab_y
;
1042 points
[3].x
= tab_x
+ tab_width
- 2;
1043 points
[3].y
= tab_y
;
1044 points
[4].x
= tab_x
+ tab_width
;
1045 points
[4].y
= tab_y
+ 2;
1046 points
[5].x
= tab_x
+ tab_width
;
1047 points
[5].y
= tab_y
+ tab_height
- 1;
1048 points
[6] = points
[0];
1050 dc
.SetClippingRegion(in_rect
);
1052 dc
.DrawPolygon(WXSIZEOF(points
) - 1, points
);
1054 dc
.SetPen(*wxGREY_PEN
);
1056 //dc.DrawLines(active ? WXSIZEOF(points) - 1 : WXSIZEOF(points), points);
1057 dc
.DrawLines(WXSIZEOF(points
), points
);
1062 int close_button_width
= 0;
1063 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1065 close_button_width
= m_activeCloseBmp
.GetWidth();
1066 text_offset
= tab_x
+ (tab_height
/2) + ((tab_width
-close_button_width
)/2) - (textx
/2);
1070 text_offset
= tab_x
+ (tab_height
/3) + (tab_width
/2) - (textx
/2);
1073 // set minimum text offset
1074 if (text_offset
< tab_x
+ tab_height
)
1075 text_offset
= tab_x
+ tab_height
;
1077 // chop text if necessary
1078 wxString draw_text
= wxAuiChopText(dc
,
1080 tab_width
- (text_offset
-tab_x
) - close_button_width
);
1083 dc
.DrawText(draw_text
,
1085 (tab_y
+ tab_height
)/2 - (texty
/2) + 1);
1088 // draw focus rectangle
1089 if (page
.active
&& (wnd
->FindFocus() == wnd
))
1091 wxRect
focusRect(text_offset
, ((tab_y
+ tab_height
)/2 - (texty
/2) + 1),
1092 selected_textx
, selected_texty
);
1094 focusRect
.Inflate(2, 2);
1096 wxRendererNative::Get().DrawFocusRect(wnd
, dc
, focusRect
, 0);
1099 // draw close button if necessary
1100 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1104 bmp
= m_activeCloseBmp
;
1106 bmp
= m_disabledCloseBmp
;
1108 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
1109 tab_y
+ (tab_height
/2) - (bmp
.GetHeight()/2) + 1,
1112 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, close_button_state
);
1114 *out_button_rect
= rect
;
1118 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
1120 dc
.DestroyClippingRegion();
1123 int wxAuiSimpleTabArt::GetIndentSize()
1128 int wxAuiSimpleTabArt::GetBorderWidth(wxWindow
* wnd
)
1130 wxAuiManager
* mgr
= wxAuiManager::GetManager(wnd
);
1133 wxAuiDockArt
* art
= mgr
->GetArtProvider();
1135 return art
->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE
);
1140 wxSize
wxAuiSimpleTabArt::GetTabSize(wxDC
& dc
,
1141 wxWindow
* WXUNUSED(wnd
),
1142 const wxString
& caption
,
1143 const wxBitmap
& WXUNUSED(bitmap
),
1144 bool WXUNUSED(active
),
1145 int close_button_state
,
1148 wxCoord measured_textx
, measured_texty
;
1150 dc
.SetFont(m_measuringFont
);
1151 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
1153 wxCoord tab_height
= measured_texty
+ 4;
1154 wxCoord tab_width
= measured_textx
+ tab_height
+ 5;
1156 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1157 tab_width
+= m_activeCloseBmp
.GetWidth();
1159 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
1161 tab_width
= m_fixedTabWidth
;
1164 *x_extent
= tab_width
- (tab_height
/2) - 1;
1166 return wxSize(tab_width
, tab_height
);
1170 void wxAuiSimpleTabArt::DrawButton(wxDC
& dc
,
1171 wxWindow
* WXUNUSED(wnd
),
1172 const wxRect
& in_rect
,
1183 case wxAUI_BUTTON_CLOSE
:
1184 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1185 bmp
= m_disabledCloseBmp
;
1187 bmp
= m_activeCloseBmp
;
1189 case wxAUI_BUTTON_LEFT
:
1190 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1191 bmp
= m_disabledLeftBmp
;
1193 bmp
= m_activeLeftBmp
;
1195 case wxAUI_BUTTON_RIGHT
:
1196 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1197 bmp
= m_disabledRightBmp
;
1199 bmp
= m_activeRightBmp
;
1201 case wxAUI_BUTTON_WINDOWLIST
:
1202 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1203 bmp
= m_disabledWindowListBmp
;
1205 bmp
= m_activeWindowListBmp
;
1214 if (orientation
== wxLEFT
)
1216 rect
.SetX(in_rect
.x
);
1217 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
1218 rect
.SetWidth(bmp
.GetWidth());
1219 rect
.SetHeight(bmp
.GetHeight());
1223 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
1224 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
1225 bmp
.GetWidth(), bmp
.GetHeight());
1229 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, button_state
);
1234 int wxAuiSimpleTabArt::ShowDropDown(wxWindow
* wnd
,
1235 const wxAuiNotebookPageArray
& pages
,
1240 size_t i
, count
= pages
.GetCount();
1241 for (i
= 0; i
< count
; ++i
)
1243 const wxAuiNotebookPage
& page
= pages
.Item(i
);
1244 menuPopup
.AppendCheckItem(1000+i
, page
.caption
);
1247 if (active_idx
!= -1)
1249 menuPopup
.Check(1000+active_idx
, true);
1252 // find out where to put the popup menu of window
1253 // items. Subtract 100 for now to center the menu
1254 // a bit, until a better mechanism can be implemented
1255 wxPoint pt
= ::wxGetMousePosition();
1256 pt
= wnd
->ScreenToClient(pt
);
1262 // find out the screen coordinate at the bottom of the tab ctrl
1263 wxRect cli_rect
= wnd
->GetClientRect();
1264 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
1266 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
1267 wnd
->PushEventHandler(cc
);
1268 wnd
->PopupMenu(&menuPopup
, pt
);
1269 int command
= cc
->GetCommandId();
1270 wnd
->PopEventHandler(true);
1272 if (command
>= 1000)
1273 return command
-1000;
1278 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
1279 const wxAuiNotebookPageArray
& WXUNUSED(pages
),
1280 const wxSize
& WXUNUSED(requiredBmp_size
))
1283 dc
.SetFont(m_measuringFont
);
1285 wxSize s
= GetTabSize(dc
,
1290 wxAUI_BUTTON_STATE_HIDDEN
,
1295 void wxAuiSimpleTabArt::SetNormalFont(const wxFont
& font
)
1297 m_normalFont
= font
;
1300 void wxAuiSimpleTabArt::SetSelectedFont(const wxFont
& font
)
1302 m_selectedFont
= font
;
1305 void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont
& font
)
1307 m_measuringFont
= font
;