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