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