Improve wxAuiNotebook appearance when using some GTK themes.
[wxWidgets.git] / src / aui / dockart.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/aui/dockart.cpp
3 // Purpose: wxaui: wx advanced user interface - docking window manager
4 // Author: Benjamin I. Williams
5 // Modified by:
6 // Created: 2005-05-17
7 // RCS-ID: $Id$
8 // Copyright: (C) Copyright 2005-2006, Kirix Corporation, All Rights Reserved
9 // Licence: wxWindows Library Licence, Version 3.1
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_AUI
27
28 #include "wx/aui/framemanager.h"
29 #include "wx/aui/dockart.h"
30 #include "wx/aui/auibook.h"
31 #include "wx/aui/tabart.h"
32
33 #ifndef WX_PRECOMP
34 #include "wx/settings.h"
35 #include "wx/dcclient.h"
36 #include "wx/image.h"
37 #endif
38
39 #ifdef __WXMAC__
40 #include "wx/osx/private.h"
41 #include "wx/graphics.h"
42 #include "wx/dcgraph.h"
43 #endif
44
45 #ifdef __WXGTK__
46 #include <gtk/gtk.h>
47 #include "wx/renderer.h"
48 #ifdef __WXGTK20__
49 #include "wx/gtk/private/gtk2-compat.h"
50 #else
51 #define gtk_widget_is_drawable GTK_WIDGET_DRAWABLE
52 #endif
53 #ifdef __WXGTK3__
54 #include "wx/graphics.h"
55 #endif
56 #endif
57
58
59 // -- wxAuiDefaultDockArt class implementation --
60
61 // wxAuiDefaultDockArt is an art provider class which does all of the drawing for
62 // wxAuiManager. This allows the library caller to customize the dock art
63 // (probably by deriving from this class), or to completely replace all drawing
64 // with custom dock art (probably by writing a new stand-alone class derived
65 // from the wxAuiDockArt base class). The active dock art class can be set via
66 // wxAuiManager::SetDockArt()
67 wxColor wxAuiLightContrastColour(const wxColour& c)
68 {
69 int amount = 120;
70
71 // if the color is especially dark, then
72 // make the contrast even lighter
73 if (c.Red() < 128 && c.Green() < 128 && c.Blue() < 128)
74 amount = 160;
75
76 return c.ChangeLightness(amount);
77 }
78
79 // wxAuiBitmapFromBits() is a utility function that creates a
80 // masked bitmap from raw bits (XBM format)
81 wxBitmap wxAuiBitmapFromBits(const unsigned char bits[], int w, int h,
82 const wxColour& color)
83 {
84 wxImage img = wxBitmap((const char*)bits, w, h).ConvertToImage();
85 img.Replace(0,0,0,123,123,123);
86 img.Replace(255,255,255,color.Red(),color.Green(),color.Blue());
87 img.SetMaskColour(123,123,123);
88 return wxBitmap(img);
89 }
90
91
92 static void DrawGradientRectangle(wxDC& dc,
93 const wxRect& rect,
94 const wxColour& start_color,
95 const wxColour& end_color,
96 int direction)
97 {
98 int rd, gd, bd, high = 0;
99 rd = end_color.Red() - start_color.Red();
100 gd = end_color.Green() - start_color.Green();
101 bd = end_color.Blue() - start_color.Blue();
102
103 if (direction == wxAUI_GRADIENT_VERTICAL)
104 high = rect.GetHeight()-1;
105 else
106 high = rect.GetWidth()-1;
107
108 for (int i = 0; i <= high; ++i)
109 {
110 int r,g,b;
111
112
113 r = start_color.Red() + (high <= 0 ? 0 : (((i*rd*100)/high)/100));
114 g = start_color.Green() + (high <= 0 ? 0 : (((i*gd*100)/high)/100));
115 b = start_color.Blue() + (high <= 0 ? 0 : (((i*bd*100)/high)/100));
116
117 wxPen p(wxColor((unsigned char)r,
118 (unsigned char)g,
119 (unsigned char)b));
120 dc.SetPen(p);
121
122 if (direction == wxAUI_GRADIENT_VERTICAL)
123 dc.DrawLine(rect.x, rect.y+i, rect.x+rect.width, rect.y+i);
124 else
125 dc.DrawLine(rect.x+i, rect.y, rect.x+i, rect.y+rect.height);
126 }
127 }
128
129 wxString wxAuiChopText(wxDC& dc, const wxString& text, int max_size)
130 {
131 wxCoord x,y;
132
133 // first check if the text fits with no problems
134 dc.GetTextExtent(text, &x, &y);
135 if (x <= max_size)
136 return text;
137
138 size_t i, len = text.Length();
139 size_t last_good_length = 0;
140 for (i = 0; i < len; ++i)
141 {
142 wxString s = text.Left(i);
143 s += wxT("...");
144
145 dc.GetTextExtent(s, &x, &y);
146 if (x > max_size)
147 break;
148
149 last_good_length = i;
150 }
151
152 wxString ret = text.Left(last_good_length);
153 ret += wxT("...");
154 return ret;
155 }
156
157 wxAuiDefaultDockArt::wxAuiDefaultDockArt()
158 {
159 #if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON
160 wxColor baseColour = wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground));
161 #else
162 wxColor baseColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
163 #endif
164
165 // the baseColour is too pale to use as our base colour,
166 // so darken it a bit --
167 if ((255-baseColour.Red()) +
168 (255-baseColour.Green()) +
169 (255-baseColour.Blue()) < 60)
170 {
171 baseColour = baseColour.ChangeLightness(92);
172 }
173
174 m_baseColour = baseColour;
175 wxColor darker1Colour = baseColour.ChangeLightness(85);
176 wxColor darker2Colour = baseColour.ChangeLightness(75);
177 wxColor darker3Colour = baseColour.ChangeLightness(60);
178 //wxColor darker4Colour = baseColour.ChangeLightness(50);
179 wxColor darker5Colour = baseColour.ChangeLightness(40);
180
181 m_activeCaptionColour = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
182 m_activeCaptionGradientColour = wxAuiLightContrastColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
183 m_activeCaptionTextColour = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
184 m_inactiveCaptionColour = darker1Colour;
185 m_inactiveCaptionGradientColour = baseColour.ChangeLightness(97);
186 m_inactiveCaptionTextColour = *wxBLACK;
187
188 m_sashBrush = wxBrush(baseColour);
189 m_backgroundBrush = wxBrush(baseColour);
190 m_gripperBrush = wxBrush(baseColour);
191
192 m_borderPen = wxPen(darker2Colour);
193 m_gripperPen1 = wxPen(darker5Colour);
194 m_gripperPen2 = wxPen(darker3Colour);
195 m_gripperPen3 = *wxWHITE_PEN;
196
197 #ifdef __WXMAC__
198 m_captionFont = *wxSMALL_FONT;
199 #else
200 m_captionFont = wxFont(8, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE);
201 #endif
202
203 // default metric values
204 #if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON
205 SInt32 height;
206 GetThemeMetric( kThemeMetricSmallPaneSplitterHeight , &height );
207 m_sashSize = height;
208 #elif defined(__WXGTK__)
209 m_sashSize = wxRendererNative::Get().GetSplitterParams(NULL).widthSash;
210 #else
211 m_sashSize = 4;
212 #endif
213 m_captionSize = 17;
214 m_borderSize = 1;
215 m_buttonSize = 14;
216 m_gripperSize = 9;
217 m_gradientType = wxAUI_GRADIENT_VERTICAL;
218
219 InitBitmaps();
220 }
221
222 void
223 wxAuiDefaultDockArt::InitBitmaps ()
224 {
225 // some built in bitmaps
226 #if defined( __WXMAC__ )
227 static const unsigned char close_bits[]={
228 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
229 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
230 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
231 #elif defined(__WXGTK__)
232 static const unsigned char close_bits[]={
233 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
234 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
235 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
236 #else
237 static const unsigned char close_bits[]={
238 // reduced height, symmetric
239 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xf3, 0x9f, 0xf9,
240 0x3f, 0xfc, 0x7f, 0xfe, 0x3f, 0xfc, 0x9f, 0xf9, 0xcf, 0xf3, 0xff, 0xff,
241 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
242 /*
243 // same height as maximize/restore
244 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xe7, 0xcf, 0xf3, 0x9f, 0xf9,
245 0x3f, 0xfc, 0x7f, 0xfe, 0x3f, 0xfc, 0x9f, 0xf9, 0xcf, 0xf3, 0xe7, 0xe7,
246 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
247 */
248 #endif
249
250 static const unsigned char maximize_bits[] = {
251 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xf7, 0xf7, 0x07, 0xf0,
252 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0x07, 0xf0,
253 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
254
255 static const unsigned char restore_bits[]={
256 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xf0, 0x1f, 0xf0, 0xdf, 0xf7,
257 0x07, 0xf4, 0x07, 0xf4, 0xf7, 0xf5, 0xf7, 0xf1, 0xf7, 0xfd, 0xf7, 0xfd,
258 0x07, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
259
260 static const unsigned char pin_bits[]={
261 0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0xfc,0xdf,0xfc,0xdf,0xfc,
262 0xdf,0xfc,0xdf,0xfc,0xdf,0xfc,0x0f,0xf8,0x7f,0xff,0x7f,0xff,
263 0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
264
265 #ifdef __WXMAC__
266 m_inactiveCloseBitmap = wxAuiBitmapFromBits(close_bits, 16, 16, *wxWHITE);
267 m_activeCloseBitmap = wxAuiBitmapFromBits(close_bits, 16, 16, *wxWHITE );
268 #else
269 m_inactiveCloseBitmap = wxAuiBitmapFromBits(close_bits, 16, 16, m_inactiveCaptionTextColour);
270 m_activeCloseBitmap = wxAuiBitmapFromBits(close_bits, 16, 16, m_activeCaptionTextColour);
271 #endif
272
273 #ifdef __WXMAC__
274 m_inactiveMaximizeBitmap = wxAuiBitmapFromBits(maximize_bits, 16, 16, *wxWHITE);
275 m_activeMaximizeBitmap = wxAuiBitmapFromBits(maximize_bits, 16, 16, *wxWHITE );
276 #else
277 m_inactiveMaximizeBitmap = wxAuiBitmapFromBits(maximize_bits, 16, 16, m_inactiveCaptionTextColour);
278 m_activeMaximizeBitmap = wxAuiBitmapFromBits(maximize_bits, 16, 16, m_activeCaptionTextColour);
279 #endif
280
281 #ifdef __WXMAC__
282 m_inactiveRestoreBitmap = wxAuiBitmapFromBits(restore_bits, 16, 16, *wxWHITE);
283 m_activeRestoreBitmap = wxAuiBitmapFromBits(restore_bits, 16, 16, *wxWHITE );
284 #else
285 m_inactiveRestoreBitmap = wxAuiBitmapFromBits(restore_bits, 16, 16, m_inactiveCaptionTextColour);
286 m_activeRestoreBitmap = wxAuiBitmapFromBits(restore_bits, 16, 16, m_activeCaptionTextColour);
287 #endif
288
289 m_inactivePinBitmap = wxAuiBitmapFromBits(pin_bits, 16, 16, m_inactiveCaptionTextColour);
290 m_activePinBitmap = wxAuiBitmapFromBits(pin_bits, 16, 16, m_activeCaptionTextColour);
291 }
292
293 int wxAuiDefaultDockArt::GetMetric(int id)
294 {
295 switch (id)
296 {
297 case wxAUI_DOCKART_SASH_SIZE: return m_sashSize;
298 case wxAUI_DOCKART_CAPTION_SIZE: return m_captionSize;
299 case wxAUI_DOCKART_GRIPPER_SIZE: return m_gripperSize;
300 case wxAUI_DOCKART_PANE_BORDER_SIZE: return m_borderSize;
301 case wxAUI_DOCKART_PANE_BUTTON_SIZE: return m_buttonSize;
302 case wxAUI_DOCKART_GRADIENT_TYPE: return m_gradientType;
303 default: wxFAIL_MSG(wxT("Invalid Metric Ordinal")); break;
304 }
305
306 return 0;
307 }
308
309 void wxAuiDefaultDockArt::SetMetric(int id, int new_val)
310 {
311 switch (id)
312 {
313 case wxAUI_DOCKART_SASH_SIZE: m_sashSize = new_val; break;
314 case wxAUI_DOCKART_CAPTION_SIZE: m_captionSize = new_val; break;
315 case wxAUI_DOCKART_GRIPPER_SIZE: m_gripperSize = new_val; break;
316 case wxAUI_DOCKART_PANE_BORDER_SIZE: m_borderSize = new_val; break;
317 case wxAUI_DOCKART_PANE_BUTTON_SIZE: m_buttonSize = new_val; break;
318 case wxAUI_DOCKART_GRADIENT_TYPE: m_gradientType = new_val; break;
319 default: wxFAIL_MSG(wxT("Invalid Metric Ordinal")); break;
320 }
321 }
322
323 wxColour wxAuiDefaultDockArt::GetColour(int id)
324 {
325 switch (id)
326 {
327 case wxAUI_DOCKART_BACKGROUND_COLOUR: return m_backgroundBrush.GetColour();
328 case wxAUI_DOCKART_SASH_COLOUR: return m_sashBrush.GetColour();
329 case wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR: return m_inactiveCaptionColour;
330 case wxAUI_DOCKART_INACTIVE_CAPTION_GRADIENT_COLOUR: return m_inactiveCaptionGradientColour;
331 case wxAUI_DOCKART_INACTIVE_CAPTION_TEXT_COLOUR: return m_inactiveCaptionTextColour;
332 case wxAUI_DOCKART_ACTIVE_CAPTION_COLOUR: return m_activeCaptionColour;
333 case wxAUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR: return m_activeCaptionGradientColour;
334 case wxAUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR: return m_activeCaptionTextColour;
335 case wxAUI_DOCKART_BORDER_COLOUR: return m_borderPen.GetColour();
336 case wxAUI_DOCKART_GRIPPER_COLOUR: return m_gripperBrush.GetColour();
337 default: wxFAIL_MSG(wxT("Invalid Metric Ordinal")); break;
338 }
339
340 return wxColour();
341 }
342
343 void wxAuiDefaultDockArt::SetColour(int id, const wxColor& colour)
344 {
345 switch (id)
346 {
347 case wxAUI_DOCKART_BACKGROUND_COLOUR: m_backgroundBrush.SetColour(colour); break;
348 case wxAUI_DOCKART_SASH_COLOUR: m_sashBrush.SetColour(colour); break;
349 case wxAUI_DOCKART_INACTIVE_CAPTION_COLOUR: m_inactiveCaptionColour = colour; break;
350 case wxAUI_DOCKART_INACTIVE_CAPTION_GRADIENT_COLOUR: m_inactiveCaptionGradientColour = colour; break;
351 case wxAUI_DOCKART_INACTIVE_CAPTION_TEXT_COLOUR: m_inactiveCaptionTextColour = colour; break;
352 case wxAUI_DOCKART_ACTIVE_CAPTION_COLOUR: m_activeCaptionColour = colour; break;
353 case wxAUI_DOCKART_ACTIVE_CAPTION_GRADIENT_COLOUR: m_activeCaptionGradientColour = colour; break;
354 case wxAUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR: m_activeCaptionTextColour = colour; break;
355 case wxAUI_DOCKART_BORDER_COLOUR: m_borderPen.SetColour(colour); break;
356 case wxAUI_DOCKART_GRIPPER_COLOUR:
357 m_gripperBrush.SetColour(colour);
358 m_gripperPen1.SetColour(colour.ChangeLightness(40));
359 m_gripperPen2.SetColour(colour.ChangeLightness(60));
360 break;
361 default: wxFAIL_MSG(wxT("Invalid Metric Ordinal")); break;
362 }
363
364 InitBitmaps();
365 }
366
367 void wxAuiDefaultDockArt::SetFont(int id, const wxFont& font)
368 {
369 if (id == wxAUI_DOCKART_CAPTION_FONT)
370 m_captionFont = font;
371 }
372
373 wxFont wxAuiDefaultDockArt::GetFont(int id)
374 {
375 if (id == wxAUI_DOCKART_CAPTION_FONT)
376 return m_captionFont;
377 return wxNullFont;
378 }
379
380 void wxAuiDefaultDockArt::DrawSash(wxDC& dc, wxWindow *window, int orientation, const wxRect& rect)
381 {
382 #if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON
383 wxUnusedVar(window);
384 wxUnusedVar(orientation);
385
386 HIRect splitterRect = CGRectMake( rect.x , rect.y , rect.width , rect.height );
387 CGContextRef cgContext ;
388 wxGCDCImpl *impl = (wxGCDCImpl*) dc.GetImpl();
389 cgContext = (CGContextRef) impl->GetGraphicsContext()->GetNativeContext() ;
390
391 HIThemeSplitterDrawInfo drawInfo ;
392 drawInfo.version = 0 ;
393 drawInfo.state = kThemeStateActive ;
394 drawInfo.adornment = kHIThemeSplitterAdornmentNone ;
395 HIThemeDrawPaneSplitter( &splitterRect , &drawInfo , cgContext , kHIThemeOrientationNormal ) ;
396
397 #elif defined(__WXGTK__)
398 // clear out the rectangle first
399 dc.SetPen(*wxTRANSPARENT_PEN);
400 dc.SetBrush(m_sashBrush);
401 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
402
403 #if 0
404 GdkRectangle gdk_rect;
405 if (orientation == wxVERTICAL )
406 {
407 gdk_rect.x = rect.x;
408 gdk_rect.y = rect.y;
409 gdk_rect.width = m_sashSize;
410 gdk_rect.height = rect.height;
411 }
412 else
413 {
414 gdk_rect.x = rect.x;
415 gdk_rect.y = rect.y;
416 gdk_rect.width = rect.width;
417 gdk_rect.height = m_sashSize;
418 }
419 #endif
420
421 if (!window) return;
422 if (!window->m_wxwindow) return;
423 if (!gtk_widget_is_drawable(window->m_wxwindow)) return;
424
425 gtk_paint_handle
426 (
427 gtk_widget_get_style(window->m_wxwindow),
428 #ifdef __WXGTK3__
429 static_cast<cairo_t*>(dc.GetGraphicsContext()->GetNativeContext()),
430 #else
431 window->GTKGetDrawingWindow(),
432 #endif
433 // flags & wxCONTROL_CURRENT ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
434 GTK_STATE_NORMAL,
435 GTK_SHADOW_NONE,
436 #ifndef __WXGTK3__
437 NULL /* no clipping */,
438 #endif
439 window->m_wxwindow,
440 "paned",
441 rect.x,
442 rect.y,
443 rect.width,
444 rect.height,
445 (orientation == wxVERTICAL) ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL
446 );
447
448 #else
449 wxUnusedVar(window);
450 wxUnusedVar(orientation);
451 dc.SetPen(*wxTRANSPARENT_PEN);
452 dc.SetBrush(m_sashBrush);
453 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
454 #endif
455 }
456
457
458 void wxAuiDefaultDockArt::DrawBackground(wxDC& dc, wxWindow *WXUNUSED(window), int, const wxRect& rect)
459 {
460 dc.SetPen(*wxTRANSPARENT_PEN);
461 #ifdef __WXMAC__
462 // we have to clear first, otherwise we are drawing a light striped pattern
463 // over an already darker striped background
464 dc.SetBrush(*wxWHITE_BRUSH) ;
465 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
466 #endif
467 dc.SetBrush(m_backgroundBrush);
468 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
469 }
470
471 void wxAuiDefaultDockArt::DrawBorder(wxDC& dc, wxWindow* window, const wxRect& _rect,
472 wxAuiPaneInfo& pane)
473 {
474 dc.SetPen(m_borderPen);
475 dc.SetBrush(*wxTRANSPARENT_BRUSH);
476
477 wxRect rect = _rect;
478 int i, border_width = GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE);
479
480 if (pane.IsToolbar())
481 {
482 for (i = 0; i < border_width; ++i)
483 {
484 dc.SetPen(*wxWHITE_PEN);
485 dc.DrawLine(rect.x, rect.y, rect.x+rect.width, rect.y);
486 dc.DrawLine(rect.x, rect.y, rect.x, rect.y+rect.height);
487 dc.SetPen(m_borderPen);
488 dc.DrawLine(rect.x, rect.y+rect.height-1,
489 rect.x+rect.width, rect.y+rect.height-1);
490 dc.DrawLine(rect.x+rect.width-1, rect.y,
491 rect.x+rect.width-1, rect.y+rect.height);
492 rect.Deflate(1);
493 }
494 }
495 else
496 {
497 // notebooks draw the border themselves, so they can use native rendering (e.g. tabartgtk)
498 wxAuiTabArt* art = 0;
499 wxAuiNotebook* nb = wxDynamicCast(window, wxAuiNotebook);
500 if (nb)
501 art = nb->GetArtProvider();
502
503 if (art)
504 art->DrawBorder(dc, window, rect);
505 else
506 {
507 for (i = 0; i < border_width; ++i)
508 {
509 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
510 rect.Deflate(1);
511 }
512 }
513 }
514 }
515
516
517 void wxAuiDefaultDockArt::DrawCaptionBackground(wxDC& dc, const wxRect& rect, bool active)
518 {
519 if (m_gradientType == wxAUI_GRADIENT_NONE)
520 {
521 if (active)
522 dc.SetBrush(wxBrush(m_activeCaptionColour));
523 else
524 dc.SetBrush(wxBrush(m_inactiveCaptionColour));
525
526 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
527 }
528 else
529 {
530 if (active)
531 {
532 // on mac the gradients are expected to become darker from the top
533 #ifdef __WXMAC__
534 DrawGradientRectangle(dc, rect,
535 m_activeCaptionColour,
536 m_activeCaptionGradientColour,
537 m_gradientType);
538 #else
539 // on other platforms, active gradients become lighter at the top
540 DrawGradientRectangle(dc, rect,
541 m_activeCaptionGradientColour,
542 m_activeCaptionColour,
543 m_gradientType);
544 #endif
545 }
546 else
547 {
548 #ifdef __WXMAC__
549 // on mac the gradients are expected to become darker from the top
550 DrawGradientRectangle(dc, rect,
551 m_inactiveCaptionGradientColour,
552 m_inactiveCaptionColour,
553 m_gradientType);
554 #else
555 // on other platforms, inactive gradients become lighter at the bottom
556 DrawGradientRectangle(dc, rect,
557 m_inactiveCaptionColour,
558 m_inactiveCaptionGradientColour,
559 m_gradientType);
560 #endif
561 }
562 }
563 }
564
565
566 void wxAuiDefaultDockArt::DrawCaption(wxDC& dc, wxWindow *WXUNUSED(window),
567 const wxString& text,
568 const wxRect& rect,
569 wxAuiPaneInfo& pane)
570 {
571 dc.SetPen(*wxTRANSPARENT_PEN);
572 dc.SetFont(m_captionFont);
573
574 DrawCaptionBackground(dc, rect,
575 (pane.state & wxAuiPaneInfo::optionActive)?true:false);
576
577 int caption_offset = 0;
578 if ( pane.icon.IsOk() )
579 {
580 DrawIcon(dc, rect, pane);
581
582 caption_offset += pane.icon.GetWidth() + 3;
583 }
584
585 if (pane.state & wxAuiPaneInfo::optionActive)
586 dc.SetTextForeground(m_activeCaptionTextColour);
587 else
588 dc.SetTextForeground(m_inactiveCaptionTextColour);
589
590
591 wxCoord w,h;
592 dc.GetTextExtent(wxT("ABCDEFHXfgkj"), &w, &h);
593
594 wxRect clip_rect = rect;
595 clip_rect.width -= 3; // text offset
596 clip_rect.width -= 2; // button padding
597 if (pane.HasCloseButton())
598 clip_rect.width -= m_buttonSize;
599 if (pane.HasPinButton())
600 clip_rect.width -= m_buttonSize;
601 if (pane.HasMaximizeButton())
602 clip_rect.width -= m_buttonSize;
603
604 wxString draw_text = wxAuiChopText(dc, text, clip_rect.width);
605
606 dc.SetClippingRegion(clip_rect);
607 dc.DrawText(draw_text, rect.x+3 + caption_offset, rect.y+(rect.height/2)-(h/2)-1);
608 dc.DestroyClippingRegion();
609 }
610
611 void
612 wxAuiDefaultDockArt::DrawIcon(wxDC& dc, const wxRect& rect, wxAuiPaneInfo& pane)
613 {
614 // Draw the icon centered vertically
615 dc.DrawBitmap(pane.icon,
616 rect.x+2, rect.y+(rect.height-pane.icon.GetHeight())/2,
617 true);
618 }
619
620 void wxAuiDefaultDockArt::DrawGripper(wxDC& dc, wxWindow *WXUNUSED(window),
621 const wxRect& rect,
622 wxAuiPaneInfo& pane)
623 {
624 dc.SetPen(*wxTRANSPARENT_PEN);
625 dc.SetBrush(m_gripperBrush);
626
627 dc.DrawRectangle(rect.x, rect.y, rect.width,rect.height);
628
629 if (!pane.HasGripperTop())
630 {
631 int y = 5;
632 while (1)
633 {
634 dc.SetPen(m_gripperPen1);
635 dc.DrawPoint(rect.x+3, rect.y+y);
636 dc.SetPen(m_gripperPen2);
637 dc.DrawPoint(rect.x+3, rect.y+y+1);
638 dc.DrawPoint(rect.x+4, rect.y+y);
639 dc.SetPen(m_gripperPen3);
640 dc.DrawPoint(rect.x+5, rect.y+y+1);
641 dc.DrawPoint(rect.x+5, rect.y+y+2);
642 dc.DrawPoint(rect.x+4, rect.y+y+2);
643
644 y += 4;
645 if (y > rect.GetHeight()-5)
646 break;
647 }
648 }
649 else
650 {
651 int x = 5;
652 while (1)
653 {
654 dc.SetPen(m_gripperPen1);
655 dc.DrawPoint(rect.x+x, rect.y+3);
656 dc.SetPen(m_gripperPen2);
657 dc.DrawPoint(rect.x+x+1, rect.y+3);
658 dc.DrawPoint(rect.x+x, rect.y+4);
659 dc.SetPen(m_gripperPen3);
660 dc.DrawPoint(rect.x+x+1, rect.y+5);
661 dc.DrawPoint(rect.x+x+2, rect.y+5);
662 dc.DrawPoint(rect.x+x+2, rect.y+4);
663
664 x += 4;
665 if (x > rect.GetWidth()-5)
666 break;
667 }
668 }
669 }
670
671 void wxAuiDefaultDockArt::DrawPaneButton(wxDC& dc, wxWindow *WXUNUSED(window),
672 int button,
673 int button_state,
674 const wxRect& _rect,
675 wxAuiPaneInfo& pane)
676 {
677 wxBitmap bmp;
678 if (!(&pane))
679 return;
680 switch (button)
681 {
682 default:
683 case wxAUI_BUTTON_CLOSE:
684 if (pane.state & wxAuiPaneInfo::optionActive)
685 bmp = m_activeCloseBitmap;
686 else
687 bmp = m_inactiveCloseBitmap;
688 break;
689 case wxAUI_BUTTON_PIN:
690 if (pane.state & wxAuiPaneInfo::optionActive)
691 bmp = m_activePinBitmap;
692 else
693 bmp = m_inactivePinBitmap;
694 break;
695 case wxAUI_BUTTON_MAXIMIZE_RESTORE:
696 if (pane.IsMaximized())
697 {
698 if (pane.state & wxAuiPaneInfo::optionActive)
699 bmp = m_activeRestoreBitmap;
700 else
701 bmp = m_inactiveRestoreBitmap;
702 }
703 else
704 {
705 if (pane.state & wxAuiPaneInfo::optionActive)
706 bmp = m_activeMaximizeBitmap;
707 else
708 bmp = m_inactiveMaximizeBitmap;
709 }
710 break;
711 }
712
713
714 wxRect rect = _rect;
715
716 int old_y = rect.y;
717 rect.y = rect.y + (rect.height/2) - (bmp.GetHeight()/2);
718 rect.height = old_y + rect.height - rect.y - 1;
719
720
721 if (button_state == wxAUI_BUTTON_STATE_PRESSED)
722 {
723 rect.x++;
724 rect.y++;
725 }
726
727 if (button_state == wxAUI_BUTTON_STATE_HOVER ||
728 button_state == wxAUI_BUTTON_STATE_PRESSED)
729 {
730 if (pane.state & wxAuiPaneInfo::optionActive)
731 {
732 dc.SetBrush(wxBrush(m_activeCaptionColour.ChangeLightness(120)));
733 dc.SetPen(wxPen(m_activeCaptionColour.ChangeLightness(70)));
734 }
735 else
736 {
737 dc.SetBrush(wxBrush(m_inactiveCaptionColour.ChangeLightness(120)));
738 dc.SetPen(wxPen(m_inactiveCaptionColour.ChangeLightness(70)));
739 }
740
741 // draw the background behind the button
742 dc.DrawRectangle(rect.x, rect.y, 15, 15);
743 }
744
745
746 // draw the button itself
747 dc.DrawBitmap(bmp, rect.x, rect.y, true);
748 }
749
750
751 #endif // wxUSE_AUI