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