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