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"
36 #include "wx/osx/private.h"
40 // -- GUI helper classes and functions --
42 class wxAuiCommandCapture
: public wxEvtHandler
46 wxAuiCommandCapture() { m_lastId
= 0; }
47 int GetCommandId() const { return m_lastId
; }
49 bool ProcessEvent(wxEvent
& evt
)
51 if (evt
.GetEventType() == wxEVT_COMMAND_MENU_SELECTED
)
53 m_lastId
= evt
.GetId();
58 return GetNextHandler()->ProcessEvent(evt
);
68 // these functions live in dockart.cpp -- they'll eventually
69 // be moved to a new utility cpp file
71 wxBitmap
wxAuiBitmapFromBits(const unsigned char bits
[], int w
, int h
,
72 const wxColour
& color
);
74 wxString
wxAuiChopText(wxDC
& dc
, const wxString
& text
, int max_size
);
76 static void DrawButtons(wxDC
& dc
,
79 const wxColour
& bkcolour
,
84 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
90 if (button_state
== wxAUI_BUTTON_STATE_HOVER
||
91 button_state
== wxAUI_BUTTON_STATE_PRESSED
)
93 dc
.SetBrush(wxBrush(bkcolour
.ChangeLightness(120)));
94 dc
.SetPen(wxPen(bkcolour
.ChangeLightness(75)));
96 // draw the background behind the button
97 dc
.DrawRectangle(rect
.x
, rect
.y
, 15, 15);
100 // draw the button itself
101 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
104 static void IndentPressedBitmap(wxRect
* rect
, int button_state
)
106 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
115 #if defined( __WXMAC__ )
116 static const unsigned char close_bits
[]={
117 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
118 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
119 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
120 #elif defined( __WXGTK__)
121 static const unsigned char close_bits
[]={
122 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
123 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
124 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
126 static const unsigned char close_bits
[]={
127 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9,
128 0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3,
129 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
132 static const unsigned char left_bits
[] = {
133 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe,
134 0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe,
135 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
137 static const unsigned char right_bits
[] = {
138 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff,
139 0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff,
140 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
142 static const unsigned char list_bits
[] = {
143 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
144 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff,
145 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
152 // -- wxAuiGenericTabArt class implementation --
154 wxAuiGenericTabArt::wxAuiGenericTabArt()
156 m_normalFont
= *wxNORMAL_FONT
;
157 m_selectedFont
= *wxNORMAL_FONT
;
158 m_selectedFont
.SetWeight(wxBOLD
);
159 m_measuringFont
= m_selectedFont
;
161 m_fixedTabWidth
= 100;
164 #if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON
165 wxColor baseColour
= wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground
));
167 wxColor baseColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
170 // the baseColour is too pale to use as our base colour,
171 // so darken it a bit --
172 if ((255-baseColour
.Red()) +
173 (255-baseColour
.Green()) +
174 (255-baseColour
.Blue()) < 60)
176 baseColour
= baseColour
.ChangeLightness(92);
179 m_activeColour
= baseColour
;
180 m_baseColour
= baseColour
;
181 wxColor borderColour
= baseColour
.ChangeLightness(75);
183 m_borderPen
= wxPen(borderColour
);
184 m_baseColourPen
= wxPen(m_baseColour
);
185 m_baseColourBrush
= wxBrush(m_baseColour
);
187 m_activeCloseBmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
188 m_disabledCloseBmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
190 m_activeLeftBmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
191 m_disabledLeftBmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
193 m_activeRightBmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
194 m_disabledRightBmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
196 m_activeWindowListBmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
197 m_disabledWindowListBmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
202 wxAuiGenericTabArt::~wxAuiGenericTabArt()
206 wxAuiTabArt
* wxAuiGenericTabArt::Clone()
208 return new wxAuiGenericTabArt(*this);
211 void wxAuiGenericTabArt::SetFlags(unsigned int flags
)
216 void wxAuiGenericTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
,
219 m_fixedTabWidth
= 100;
221 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
223 if (m_flags
& wxAUI_NB_CLOSE_BUTTON
)
224 tot_width
-= m_activeCloseBmp
.GetWidth();
225 if (m_flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
226 tot_width
-= m_activeWindowListBmp
.GetWidth();
230 m_fixedTabWidth
= tot_width
/(int)tab_count
;
234 if (m_fixedTabWidth
< 100)
235 m_fixedTabWidth
= 100;
237 if (m_fixedTabWidth
> tot_width
/2)
238 m_fixedTabWidth
= tot_width
/2;
240 if (m_fixedTabWidth
> 220)
241 m_fixedTabWidth
= 220;
243 m_tabCtrlHeight
= tab_ctrl_size
.y
;
247 void wxAuiGenericTabArt::DrawBackground(wxDC
& dc
,
248 wxWindow
* WXUNUSED(wnd
),
253 wxColor top_color
= m_baseColour
.ChangeLightness(90);
254 wxColor bottom_color
= m_baseColour
.ChangeLightness(170);
257 if (m_flags
&wxAUI_NB_BOTTOM
)
258 r
= wxRect(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
);
259 // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
260 // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
261 else //for wxAUI_NB_TOP
262 r
= wxRect(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
-3);
264 dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
);
269 dc
.SetPen(m_borderPen
);
270 int y
= rect
.GetHeight();
271 int w
= rect
.GetWidth();
273 if (m_flags
&wxAUI_NB_BOTTOM
)
275 dc
.SetBrush(wxBrush(bottom_color
));
276 dc
.DrawRectangle(-1, 0, w
+2, 4);
278 // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
279 // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
280 else //for wxAUI_NB_TOP
282 dc
.SetBrush(m_baseColourBrush
);
283 dc
.DrawRectangle(-1, y
-4, w
+2, 4);
288 // DrawTab() draws an individual tab.
291 // in_rect - rectangle the tab should be confined to
292 // caption - tab's caption
293 // active - whether or not the tab is active
294 // out_rect - actual output rectangle
295 // x_extent - the advance x; where the next tab should start
297 void wxAuiGenericTabArt::DrawTab(wxDC
& dc
,
299 const wxAuiNotebookPage
& page
,
300 const wxRect
& in_rect
,
301 int close_button_state
,
302 wxRect
* out_tab_rect
,
303 wxRect
* out_button_rect
,
306 wxCoord normal_textx
, normal_texty
;
307 wxCoord selected_textx
, selected_texty
;
310 // if the caption is empty, measure some temporary text
311 wxString caption
= page
.caption
;
315 dc
.SetFont(m_selectedFont
);
316 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
318 dc
.SetFont(m_normalFont
);
319 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
321 // figure out the size of the tab
322 wxSize tab_size
= GetTabSize(dc
,
330 wxCoord tab_height
= m_tabCtrlHeight
- 3;
331 wxCoord tab_width
= tab_size
.x
;
332 wxCoord tab_x
= in_rect
.x
;
333 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
336 caption
= page
.caption
;
339 // select pen, brush and font for the tab to be drawn
343 dc
.SetFont(m_selectedFont
);
344 texty
= selected_texty
;
348 dc
.SetFont(m_normalFont
);
349 texty
= normal_texty
;
353 // create points that will make the tab outline
355 int clip_width
= tab_width
;
356 if (tab_x
+ clip_width
> in_rect
.x
+ in_rect
.width
)
357 clip_width
= (in_rect
.x
+ in_rect
.width
) - tab_x
;
360 wxPoint clip_points[6];
361 clip_points[0] = wxPoint(tab_x, tab_y+tab_height-3);
362 clip_points[1] = wxPoint(tab_x, tab_y+2);
363 clip_points[2] = wxPoint(tab_x+2, tab_y);
364 clip_points[3] = wxPoint(tab_x+clip_width-1, tab_y);
365 clip_points[4] = wxPoint(tab_x+clip_width+1, tab_y+2);
366 clip_points[5] = wxPoint(tab_x+clip_width+1, tab_y+tab_height-3);
368 // FIXME: these ports don't provide wxRegion ctor from array of points
369 #if !defined(__WXDFB__) && !defined(__WXCOCOA__)
370 // set the clipping region for the tab --
371 wxRegion clipping_region(WXSIZEOF(clip_points), clip_points);
372 dc.SetClippingRegion(clipping_region);
373 #endif // !wxDFB && !wxCocoa
375 // since the above code above doesn't play well with WXDFB or WXCOCOA,
376 // we'll just use a rectangle for the clipping region for now --
377 dc
.SetClippingRegion(tab_x
, tab_y
, clip_width
+1, tab_height
-3);
380 wxPoint border_points
[6];
381 if (m_flags
&wxAUI_NB_BOTTOM
)
383 border_points
[0] = wxPoint(tab_x
, tab_y
);
384 border_points
[1] = wxPoint(tab_x
, tab_y
+tab_height
-6);
385 border_points
[2] = wxPoint(tab_x
+2, tab_y
+tab_height
-4);
386 border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
+tab_height
-4);
387 border_points
[4] = wxPoint(tab_x
+tab_width
, tab_y
+tab_height
-6);
388 border_points
[5] = wxPoint(tab_x
+tab_width
, tab_y
);
390 else //if (m_flags & wxAUI_NB_TOP) {}
392 border_points
[0] = wxPoint(tab_x
, tab_y
+tab_height
-4);
393 border_points
[1] = wxPoint(tab_x
, tab_y
+2);
394 border_points
[2] = wxPoint(tab_x
+2, tab_y
);
395 border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
);
396 border_points
[4] = wxPoint(tab_x
+tab_width
, tab_y
+2);
397 border_points
[5] = wxPoint(tab_x
+tab_width
, tab_y
+tab_height
-4);
399 // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
400 // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
402 int drawn_tab_yoff
= border_points
[1].y
;
403 int drawn_tab_height
= border_points
[0].y
- border_points
[1].y
;
410 // draw base background color
411 wxRect
r(tab_x
, tab_y
, tab_width
, tab_height
);
412 dc
.SetPen(wxPen(m_activeColour
));
413 dc
.SetBrush(wxBrush(m_activeColour
));
414 dc
.DrawRectangle(r
.x
+1, r
.y
+1, r
.width
-1, r
.height
-4);
416 // this white helps fill out the gradient at the top of the tab
417 dc
.SetPen(*wxWHITE_PEN
);
418 dc
.SetBrush(*wxWHITE_BRUSH
);
419 dc
.DrawRectangle(r
.x
+2, r
.y
+1, r
.width
-3, r
.height
-4);
421 // these two points help the rounded corners appear more antialiased
422 dc
.SetPen(wxPen(m_activeColour
));
423 dc
.DrawPoint(r
.x
+2, r
.y
+1);
424 dc
.DrawPoint(r
.x
+r
.width
-2, r
.y
+1);
426 // set rectangle down a bit for gradient drawing
427 r
.SetHeight(r
.GetHeight()/2);
433 // draw gradient background
434 wxColor top_color
= *wxWHITE
;
435 wxColor bottom_color
= m_activeColour
;
436 dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
);
442 wxRect
r(tab_x
, tab_y
+1, tab_width
, tab_height
-3);
444 // start the gradent up a bit and leave the inside border inset
445 // by a pixel for a 3D look. Only the top half of the inactive
446 // tab will have a slight gradient
453 // -- draw top gradient fill for glossy look
454 wxColor top_color
= m_baseColour
;
455 wxColor bottom_color
= top_color
.ChangeLightness(160);
456 dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
);
461 // -- draw bottom fill for glossy look
462 top_color
= m_baseColour
;
463 bottom_color
= m_baseColour
;
464 dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
);
468 dc
.SetPen(m_borderPen
);
469 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
470 dc
.DrawPolygon(WXSIZEOF(border_points
), border_points
);
472 // there are two horizontal grey lines at the bottom of the tab control,
473 // this gets rid of the top one of those lines in the tab control
476 if (m_flags
&wxAUI_NB_BOTTOM
)
477 dc
.SetPen(wxPen(m_baseColour
.ChangeLightness(170)));
478 // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
479 // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
480 else //for wxAUI_NB_TOP
481 dc
.SetPen(m_baseColourPen
);
482 dc
.DrawLine(border_points
[0].x
+1,
489 int text_offset
= tab_x
+ 8;
490 int close_button_width
= 0;
491 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
493 close_button_width
= m_activeCloseBmp
.GetWidth();
496 int bitmap_offset
= 0;
497 if (page
.bitmap
.IsOk())
499 bitmap_offset
= tab_x
+ 8;
502 dc
.DrawBitmap(page
.bitmap
,
504 drawn_tab_yoff
+ (drawn_tab_height
/2) - (page
.bitmap
.GetHeight()/2),
507 text_offset
= bitmap_offset
+ page
.bitmap
.GetWidth();
508 text_offset
+= 3; // bitmap padding
513 text_offset
= tab_x
+ 8;
517 wxString draw_text
= wxAuiChopText(dc
,
519 tab_width
- (text_offset
-tab_x
) - close_button_width
);
522 dc
.DrawText(draw_text
,
524 drawn_tab_yoff
+ (drawn_tab_height
)/2 - (texty
/2) - 1);
526 // draw focus rectangle
527 if (page
.active
&& (wnd
->FindFocus() == wnd
))
529 wxRect
focusRectText(text_offset
, (drawn_tab_yoff
+ (drawn_tab_height
)/2 - (texty
/2) - 1),
530 selected_textx
, selected_texty
);
533 wxRect focusRectBitmap
;
535 if (page
.bitmap
.IsOk())
536 focusRectBitmap
= wxRect(bitmap_offset
, drawn_tab_yoff
+ (drawn_tab_height
/2) - (page
.bitmap
.GetHeight()/2),
537 page
.bitmap
.GetWidth(), page
.bitmap
.GetHeight());
539 if (page
.bitmap
.IsOk() && draw_text
.IsEmpty())
540 focusRect
= focusRectBitmap
;
541 else if (!page
.bitmap
.IsOk() && !draw_text
.IsEmpty())
542 focusRect
= focusRectText
;
543 else if (page
.bitmap
.IsOk() && !draw_text
.IsEmpty())
544 focusRect
= focusRectText
.Union(focusRectBitmap
);
546 focusRect
.Inflate(2, 2);
548 wxRendererNative::Get().DrawFocusRect(wnd
, dc
, focusRect
, 0);
551 // draw close button if necessary
552 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
554 wxBitmap bmp
= m_disabledCloseBmp
;
556 if (close_button_state
== wxAUI_BUTTON_STATE_HOVER
||
557 close_button_state
== wxAUI_BUTTON_STATE_PRESSED
)
559 bmp
= m_activeCloseBmp
;
562 int offsetY
= tab_y
-1;
563 if (m_flags
& wxAUI_NB_BOTTOM
)
566 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
567 offsetY
+ (tab_height
/2) - (bmp
.GetHeight()/2),
571 IndentPressedBitmap(&rect
, close_button_state
);
572 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
574 *out_button_rect
= rect
;
577 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
579 dc
.DestroyClippingRegion();
582 int wxAuiGenericTabArt::GetIndentSize()
587 wxSize
wxAuiGenericTabArt::GetTabSize(wxDC
& dc
,
588 wxWindow
* WXUNUSED(wnd
),
589 const wxString
& caption
,
590 const wxBitmap
& bitmap
,
591 bool WXUNUSED(active
),
592 int close_button_state
,
595 wxCoord measured_textx
, measured_texty
, tmp
;
597 dc
.SetFont(m_measuringFont
);
598 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
600 dc
.GetTextExtent(wxT("ABCDEFXj"), &tmp
, &measured_texty
);
602 // add padding around the text
603 wxCoord tab_width
= measured_textx
;
604 wxCoord tab_height
= measured_texty
;
606 // if the close button is showing, add space for it
607 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
608 tab_width
+= m_activeCloseBmp
.GetWidth() + 3;
610 // if there's a bitmap, add space for it
613 tab_width
+= bitmap
.GetWidth();
614 tab_width
+= 3; // right side bitmap padding
615 tab_height
= wxMax(tab_height
, bitmap
.GetHeight());
622 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
624 tab_width
= m_fixedTabWidth
;
627 *x_extent
= tab_width
;
629 return wxSize(tab_width
, tab_height
);
633 void wxAuiGenericTabArt::DrawButton(wxDC
& dc
,
634 wxWindow
* WXUNUSED(wnd
),
635 const wxRect
& in_rect
,
646 case wxAUI_BUTTON_CLOSE
:
647 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
648 bmp
= m_disabledCloseBmp
;
650 bmp
= m_activeCloseBmp
;
652 case wxAUI_BUTTON_LEFT
:
653 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
654 bmp
= m_disabledLeftBmp
;
656 bmp
= m_activeLeftBmp
;
658 case wxAUI_BUTTON_RIGHT
:
659 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
660 bmp
= m_disabledRightBmp
;
662 bmp
= m_activeRightBmp
;
664 case wxAUI_BUTTON_WINDOWLIST
:
665 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
666 bmp
= m_disabledWindowListBmp
;
668 bmp
= m_activeWindowListBmp
;
678 if (orientation
== wxLEFT
)
680 rect
.SetX(in_rect
.x
);
681 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
682 rect
.SetWidth(bmp
.GetWidth());
683 rect
.SetHeight(bmp
.GetHeight());
687 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
688 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
689 bmp
.GetWidth(), bmp
.GetHeight());
692 IndentPressedBitmap(&rect
, button_state
);
693 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
698 int wxAuiGenericTabArt::ShowDropDown(wxWindow
* wnd
,
699 const wxAuiNotebookPageArray
& pages
,
704 size_t i
, count
= pages
.GetCount();
705 for (i
= 0; i
< count
; ++i
)
707 const wxAuiNotebookPage
& page
= pages
.Item(i
);
708 wxString caption
= page
.caption
;
710 // if there is no caption, make it a space. This will prevent
711 // an assert in the menu code.
712 if (caption
.IsEmpty())
715 wxMenuItem
* item
= new wxMenuItem(NULL
, 1000+i
, caption
);
716 if (page
.bitmap
.IsOk())
717 item
->SetBitmap(page
.bitmap
);
718 menuPopup
.Append(item
);
721 // find out where to put the popup menu of window items
722 wxPoint pt
= ::wxGetMousePosition();
723 pt
= wnd
->ScreenToClient(pt
);
725 // find out the screen coordinate at the bottom of the tab ctrl
726 wxRect cli_rect
= wnd
->GetClientRect();
727 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
729 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
730 wnd
->PushEventHandler(cc
);
731 wnd
->PopupMenu(&menuPopup
, pt
);
732 int command
= cc
->GetCommandId();
733 wnd
->PopEventHandler(true);
741 int wxAuiGenericTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
742 const wxAuiNotebookPageArray
& pages
,
743 const wxSize
& requiredBmp_size
)
746 dc
.SetFont(m_measuringFont
);
748 // sometimes a standard bitmap size needs to be enforced, especially
749 // if some tabs have bitmaps and others don't. This is important because
750 // it prevents the tab control from resizing when tabs are added.
752 if (requiredBmp_size
.IsFullySpecified())
754 measureBmp
.Create(requiredBmp_size
.x
,
760 size_t i
, page_count
= pages
.GetCount();
761 for (i
= 0; i
< page_count
; ++i
)
763 wxAuiNotebookPage
& page
= pages
.Item(i
);
766 if (measureBmp
.IsOk())
771 // we don't use the caption text because we don't
772 // want tab heights to be different in the case
773 // of a very short piece of text on one tab and a very
774 // tall piece of text on another tab
776 wxSize s
= GetTabSize(dc
,
781 wxAUI_BUTTON_STATE_HIDDEN
,
784 max_y
= wxMax(max_y
, s
.y
);
790 void wxAuiGenericTabArt::SetNormalFont(const wxFont
& font
)
795 void wxAuiGenericTabArt::SetSelectedFont(const wxFont
& font
)
797 m_selectedFont
= font
;
800 void wxAuiGenericTabArt::SetMeasuringFont(const wxFont
& font
)
802 m_measuringFont
= font
;
805 void wxAuiGenericTabArt::SetColour(const wxColour
& colour
)
807 m_baseColour
= colour
;
808 m_borderPen
= wxPen(m_baseColour
.ChangeLightness(75));
809 m_baseColourPen
= wxPen(m_baseColour
);
810 m_baseColourBrush
= wxBrush(m_baseColour
);
813 void wxAuiGenericTabArt::SetActiveColour(const wxColour
& colour
)
815 m_activeColour
= colour
;
818 // -- wxAuiSimpleTabArt class implementation --
820 wxAuiSimpleTabArt::wxAuiSimpleTabArt()
822 m_normalFont
= *wxNORMAL_FONT
;
823 m_selectedFont
= *wxNORMAL_FONT
;
824 m_selectedFont
.SetWeight(wxBOLD
);
825 m_measuringFont
= m_selectedFont
;
828 m_fixedTabWidth
= 100;
830 wxColour baseColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
832 wxColour backgroundColour
= baseColour
;
833 wxColour normaltabColour
= baseColour
;
834 wxColour selectedtabColour
= *wxWHITE
;
836 m_bkBrush
= wxBrush(backgroundColour
);
837 m_normalBkBrush
= wxBrush(normaltabColour
);
838 m_normalBkPen
= wxPen(normaltabColour
);
839 m_selectedBkBrush
= wxBrush(selectedtabColour
);
840 m_selectedBkPen
= wxPen(selectedtabColour
);
842 m_activeCloseBmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
843 m_disabledCloseBmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
845 m_activeLeftBmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
846 m_disabledLeftBmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
848 m_activeRightBmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
849 m_disabledRightBmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
851 m_activeWindowListBmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
852 m_disabledWindowListBmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
856 wxAuiSimpleTabArt::~wxAuiSimpleTabArt()
860 wxAuiTabArt
* wxAuiSimpleTabArt::Clone()
862 return new wxAuiSimpleTabArt(*this);
865 void wxAuiSimpleTabArt::SetFlags(unsigned int flags
)
870 void wxAuiSimpleTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
,
873 m_fixedTabWidth
= 100;
875 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
877 if (m_flags
& wxAUI_NB_CLOSE_BUTTON
)
878 tot_width
-= m_activeCloseBmp
.GetWidth();
879 if (m_flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
880 tot_width
-= m_activeWindowListBmp
.GetWidth();
884 m_fixedTabWidth
= tot_width
/(int)tab_count
;
888 if (m_fixedTabWidth
< 100)
889 m_fixedTabWidth
= 100;
891 if (m_fixedTabWidth
> tot_width
/2)
892 m_fixedTabWidth
= tot_width
/2;
894 if (m_fixedTabWidth
> 220)
895 m_fixedTabWidth
= 220;
898 void wxAuiSimpleTabArt::SetColour(const wxColour
& colour
)
900 m_bkBrush
= wxBrush(colour
);
901 m_normalBkBrush
= wxBrush(colour
);
902 m_normalBkPen
= wxPen(colour
);
905 void wxAuiSimpleTabArt::SetActiveColour(const wxColour
& colour
)
907 m_selectedBkBrush
= wxBrush(colour
);
908 m_selectedBkPen
= wxPen(colour
);
911 void wxAuiSimpleTabArt::DrawBackground(wxDC
& dc
,
912 wxWindow
* WXUNUSED(wnd
),
916 dc
.SetBrush(m_bkBrush
);
917 dc
.SetPen(*wxTRANSPARENT_PEN
);
918 dc
.DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2);
921 dc
.SetPen(*wxGREY_PEN
);
922 dc
.DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1);
926 // DrawTab() draws an individual tab.
929 // in_rect - rectangle the tab should be confined to
930 // caption - tab's caption
931 // active - whether or not the tab is active
932 // out_rect - actual output rectangle
933 // x_extent - the advance x; where the next tab should start
935 void wxAuiSimpleTabArt::DrawTab(wxDC
& dc
,
937 const wxAuiNotebookPage
& page
,
938 const wxRect
& in_rect
,
939 int close_button_state
,
940 wxRect
* out_tab_rect
,
941 wxRect
* out_button_rect
,
944 wxCoord normal_textx
, normal_texty
;
945 wxCoord selected_textx
, selected_texty
;
946 wxCoord textx
, texty
;
948 // if the caption is empty, measure some temporary text
949 wxString caption
= page
.caption
;
953 dc
.SetFont(m_selectedFont
);
954 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
956 dc
.SetFont(m_normalFont
);
957 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
959 // figure out the size of the tab
960 wxSize tab_size
= GetTabSize(dc
,
968 wxCoord tab_height
= tab_size
.y
;
969 wxCoord tab_width
= tab_size
.x
;
970 wxCoord tab_x
= in_rect
.x
;
971 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
973 caption
= page
.caption
;
975 // select pen, brush and font for the tab to be drawn
979 dc
.SetPen(m_selectedBkPen
);
980 dc
.SetBrush(m_selectedBkBrush
);
981 dc
.SetFont(m_selectedFont
);
982 textx
= selected_textx
;
983 texty
= selected_texty
;
987 dc
.SetPen(m_normalBkPen
);
988 dc
.SetBrush(m_normalBkBrush
);
989 dc
.SetFont(m_normalFont
);
990 textx
= normal_textx
;
991 texty
= normal_texty
;
999 points
[0].y
= tab_y
+ tab_height
- 1;
1000 points
[1].x
= tab_x
+ tab_height
- 3;
1001 points
[1].y
= tab_y
+ 2;
1002 points
[2].x
= tab_x
+ tab_height
+ 3;
1003 points
[2].y
= tab_y
;
1004 points
[3].x
= tab_x
+ tab_width
- 2;
1005 points
[3].y
= tab_y
;
1006 points
[4].x
= tab_x
+ tab_width
;
1007 points
[4].y
= tab_y
+ 2;
1008 points
[5].x
= tab_x
+ tab_width
;
1009 points
[5].y
= tab_y
+ tab_height
- 1;
1010 points
[6] = points
[0];
1012 dc
.SetClippingRegion(in_rect
);
1014 dc
.DrawPolygon(WXSIZEOF(points
) - 1, points
);
1016 dc
.SetPen(*wxGREY_PEN
);
1018 //dc.DrawLines(active ? WXSIZEOF(points) - 1 : WXSIZEOF(points), points);
1019 dc
.DrawLines(WXSIZEOF(points
), points
);
1024 int close_button_width
= 0;
1025 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1027 close_button_width
= m_activeCloseBmp
.GetWidth();
1028 text_offset
= tab_x
+ (tab_height
/2) + ((tab_width
-close_button_width
)/2) - (textx
/2);
1032 text_offset
= tab_x
+ (tab_height
/3) + (tab_width
/2) - (textx
/2);
1035 // set minimum text offset
1036 if (text_offset
< tab_x
+ tab_height
)
1037 text_offset
= tab_x
+ tab_height
;
1039 // chop text if necessary
1040 wxString draw_text
= wxAuiChopText(dc
,
1042 tab_width
- (text_offset
-tab_x
) - close_button_width
);
1045 dc
.DrawText(draw_text
,
1047 (tab_y
+ tab_height
)/2 - (texty
/2) + 1);
1050 // draw focus rectangle
1051 if (page
.active
&& (wnd
->FindFocus() == wnd
))
1053 wxRect
focusRect(text_offset
, ((tab_y
+ tab_height
)/2 - (texty
/2) + 1),
1054 selected_textx
, selected_texty
);
1056 focusRect
.Inflate(2, 2);
1058 wxRendererNative::Get().DrawFocusRect(wnd
, dc
, focusRect
, 0);
1061 // draw close button if necessary
1062 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1066 bmp
= m_activeCloseBmp
;
1068 bmp
= m_disabledCloseBmp
;
1070 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
1071 tab_y
+ (tab_height
/2) - (bmp
.GetHeight()/2) + 1,
1074 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, close_button_state
);
1076 *out_button_rect
= rect
;
1080 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
1082 dc
.DestroyClippingRegion();
1085 int wxAuiSimpleTabArt::GetIndentSize()
1090 wxSize
wxAuiSimpleTabArt::GetTabSize(wxDC
& dc
,
1091 wxWindow
* WXUNUSED(wnd
),
1092 const wxString
& caption
,
1093 const wxBitmap
& WXUNUSED(bitmap
),
1094 bool WXUNUSED(active
),
1095 int close_button_state
,
1098 wxCoord measured_textx
, measured_texty
;
1100 dc
.SetFont(m_measuringFont
);
1101 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
1103 wxCoord tab_height
= measured_texty
+ 4;
1104 wxCoord tab_width
= measured_textx
+ tab_height
+ 5;
1106 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1107 tab_width
+= m_activeCloseBmp
.GetWidth();
1109 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
1111 tab_width
= m_fixedTabWidth
;
1114 *x_extent
= tab_width
- (tab_height
/2) - 1;
1116 return wxSize(tab_width
, tab_height
);
1120 void wxAuiSimpleTabArt::DrawButton(wxDC
& dc
,
1121 wxWindow
* WXUNUSED(wnd
),
1122 const wxRect
& in_rect
,
1133 case wxAUI_BUTTON_CLOSE
:
1134 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1135 bmp
= m_disabledCloseBmp
;
1137 bmp
= m_activeCloseBmp
;
1139 case wxAUI_BUTTON_LEFT
:
1140 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1141 bmp
= m_disabledLeftBmp
;
1143 bmp
= m_activeLeftBmp
;
1145 case wxAUI_BUTTON_RIGHT
:
1146 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1147 bmp
= m_disabledRightBmp
;
1149 bmp
= m_activeRightBmp
;
1151 case wxAUI_BUTTON_WINDOWLIST
:
1152 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1153 bmp
= m_disabledWindowListBmp
;
1155 bmp
= m_activeWindowListBmp
;
1164 if (orientation
== wxLEFT
)
1166 rect
.SetX(in_rect
.x
);
1167 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
1168 rect
.SetWidth(bmp
.GetWidth());
1169 rect
.SetHeight(bmp
.GetHeight());
1173 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
1174 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
1175 bmp
.GetWidth(), bmp
.GetHeight());
1179 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, button_state
);
1184 int wxAuiSimpleTabArt::ShowDropDown(wxWindow
* wnd
,
1185 const wxAuiNotebookPageArray
& pages
,
1190 size_t i
, count
= pages
.GetCount();
1191 for (i
= 0; i
< count
; ++i
)
1193 const wxAuiNotebookPage
& page
= pages
.Item(i
);
1194 menuPopup
.AppendCheckItem(1000+i
, page
.caption
);
1197 if (active_idx
!= -1)
1199 menuPopup
.Check(1000+active_idx
, true);
1202 // find out where to put the popup menu of window
1203 // items. Subtract 100 for now to center the menu
1204 // a bit, until a better mechanism can be implemented
1205 wxPoint pt
= ::wxGetMousePosition();
1206 pt
= wnd
->ScreenToClient(pt
);
1212 // find out the screen coordinate at the bottom of the tab ctrl
1213 wxRect cli_rect
= wnd
->GetClientRect();
1214 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
1216 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
1217 wnd
->PushEventHandler(cc
);
1218 wnd
->PopupMenu(&menuPopup
, pt
);
1219 int command
= cc
->GetCommandId();
1220 wnd
->PopEventHandler(true);
1222 if (command
>= 1000)
1223 return command
-1000;
1228 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
1229 const wxAuiNotebookPageArray
& WXUNUSED(pages
),
1230 const wxSize
& WXUNUSED(requiredBmp_size
))
1233 dc
.SetFont(m_measuringFont
);
1235 wxSize s
= GetTabSize(dc
,
1240 wxAUI_BUTTON_STATE_HIDDEN
,
1245 void wxAuiSimpleTabArt::SetNormalFont(const wxFont
& font
)
1247 m_normalFont
= font
;
1250 void wxAuiSimpleTabArt::SetSelectedFont(const wxFont
& font
)
1252 m_selectedFont
= font
;
1255 void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont
& font
)
1257 m_measuringFont
= font
;