1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/renderg.cpp
3 // Purpose: generic implementation of wxRendererNative (for any platform)
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // License: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 #include "wx/renderer.h"
30 #include "wx/string.h"
34 #include "wx/gdicmn.h"
36 #include "wx/settings.h"
37 #include "wx/splitter.h"
38 #include "wx/dcmirror.h"
39 #include "wx/module.h"
41 // ----------------------------------------------------------------------------
42 // wxRendererGeneric: our wxRendererNative implementation
43 // ----------------------------------------------------------------------------
45 class WXDLLEXPORT wxRendererGeneric
: public wxRendererNative
50 virtual void DrawHeaderButton(wxWindow
*win
,
55 virtual void DrawTreeItemButton(wxWindow
*win
,
60 virtual void DrawSplitterBorder(wxWindow
*win
,
65 virtual void DrawSplitterSash(wxWindow
*win
,
72 virtual void DrawComboBoxDropButton(wxWindow
*win
,
77 virtual void DrawDropArrow(wxWindow
*win
,
82 virtual void DrawCheckBox(wxWindow
*win
,
87 virtual void DrawPushButton(wxWindow
*win
,
92 virtual void DrawItemSelectionRect(wxWindow
*win
,
97 virtual wxSplitterRenderParams
GetSplitterParams(const wxWindow
*win
);
99 virtual wxRendererVersion
GetVersion() const
101 return wxRendererVersion(wxRendererVersion::Current_Version
,
102 wxRendererVersion::Current_Age
);
106 // Cleanup by deleting standard renderer
107 static void Cleanup();
109 // Get the generic object
110 static wxRendererGeneric
* DoGetGeneric();
113 // draw the rectange using the first pen for the left and top sides and
114 // the second one for the bottom and right ones
115 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
116 const wxPen
& pen1
, const wxPen
& pen2
);
124 static wxRendererGeneric
* sm_rendererGeneric
;
127 // ============================================================================
128 // wxRendererGeneric implementation
129 // ============================================================================
131 // Get the generic object
132 wxRendererGeneric
* wxRendererGeneric::DoGetGeneric()
134 if (!sm_rendererGeneric
)
135 sm_rendererGeneric
= new wxRendererGeneric
;
136 return sm_rendererGeneric
;
139 // ----------------------------------------------------------------------------
140 // wxRendererGeneric creation
141 // ----------------------------------------------------------------------------
144 wxRendererNative
& wxRendererNative::GetGeneric()
146 return * wxRendererGeneric::DoGetGeneric();
149 void wxRendererGeneric::Cleanup()
151 if (sm_rendererGeneric
)
152 delete sm_rendererGeneric
;
154 sm_rendererGeneric
= NULL
;
157 wxRendererGeneric
* wxRendererGeneric::sm_rendererGeneric
= NULL
;
159 wxRendererGeneric::wxRendererGeneric()
160 : m_penBlack(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW
)),
161 m_penDarkGrey(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW
)),
162 m_penLightGrey(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)),
163 m_penHighlight(wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT
))
167 // ----------------------------------------------------------------------------
168 // wxRendererGeneric helpers
169 // ----------------------------------------------------------------------------
172 wxRendererGeneric::DrawShadedRect(wxDC
& dc
,
177 // draw the rectangle
179 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
180 rect
->GetLeft(), rect
->GetBottom());
181 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
182 rect
->GetRight(), rect
->GetTop());
184 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
185 rect
->GetRight(), rect
->GetBottom());
186 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
187 rect
->GetRight() + 1, rect
->GetBottom());
193 // ----------------------------------------------------------------------------
194 // tree/list ctrl drawing
195 // ----------------------------------------------------------------------------
198 wxRendererGeneric::DrawHeaderButton(wxWindow
* WXUNUSED(win
),
203 const int CORNER
= 1;
205 const wxCoord x
= rect
.x
,
210 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
212 dc
.SetPen(m_penBlack
);
213 dc
.DrawLine( x
+w
-CORNER
+1, y
, x
+w
, y
+h
); // right (outer)
214 dc
.DrawRectangle( x
, y
+h
, w
+1, 1 ); // bottom (outer)
216 dc
.SetPen(m_penDarkGrey
);
217 dc
.DrawLine( x
+w
-CORNER
, y
, x
+w
-1, y
+h
); // right (inner)
218 dc
.DrawRectangle( x
+1, y
+h
-1, w
-2, 1 ); // bottom (inner)
220 dc
.SetPen(m_penHighlight
);
221 dc
.DrawRectangle( x
, y
, w
-CORNER
+1, 1 ); // top (outer)
222 dc
.DrawRectangle( x
, y
, 1, h
); // left (outer)
223 dc
.DrawLine( x
, y
+h
-1, x
+1, y
+h
-1 );
224 dc
.DrawLine( x
+w
-1, y
, x
+w
-1, y
+1 );
227 // draw the plus or minus sign
229 wxRendererGeneric::DrawTreeItemButton(wxWindow
* WXUNUSED(win
),
235 wxDCPenChanger
penChanger(dc
);
236 wxDCBrushChanger
brushChanger(dc
);
239 penChanger
.Set(*wxGREY_PEN
);
240 brushChanger
.Set(*wxWHITE_BRUSH
);
242 dc
.DrawRectangle(rect
);
245 const wxCoord xMiddle
= rect
.x
+ rect
.width
/2;
246 const wxCoord yMiddle
= rect
.y
+ rect
.height
/2;
248 // half of the length of the horz lines in "-" and "+"
249 const wxCoord halfWidth
= rect
.width
/2 - 2;
250 dc
.SetPen(*wxBLACK_PEN
);
251 dc
.DrawLine(xMiddle
- halfWidth
, yMiddle
,
252 xMiddle
+ halfWidth
+ 1, yMiddle
);
254 if ( !(flags
& wxCONTROL_EXPANDED
) )
257 const wxCoord halfHeight
= rect
.height
/2 - 2;
258 dc
.DrawLine(xMiddle
, yMiddle
- halfHeight
,
259 xMiddle
, yMiddle
+ halfHeight
+ 1);
263 // ----------------------------------------------------------------------------
265 // ----------------------------------------------------------------------------
267 wxSplitterRenderParams
268 wxRendererGeneric::GetSplitterParams(const wxWindow
*win
)
274 if ( win
->HasFlag(wxSP_3DSASH
) )
276 else if ( win
->HasFlag(wxSP_NOSASH
) )
281 if ( win
->HasFlag(wxSP_3DBORDER
) )
286 return wxSplitterRenderParams(sashWidth
, border
, false);
290 wxRendererGeneric::DrawSplitterBorder(wxWindow
*win
,
292 const wxRect
& rectOrig
,
295 if ( win
->HasFlag(wxSP_3DBORDER
) )
297 wxRect rect
= rectOrig
;
298 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
299 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
304 wxRendererGeneric::DrawSplitterSash(wxWindow
*win
,
306 const wxSize
& sizeReal
,
308 wxOrientation orient
,
311 // to avoid duplicating the same code for horizontal and vertical sashes,
312 // simply mirror the DC instead if needed (i.e. if horz splitter)
313 wxMirrorDC
dc(dcReal
, orient
!= wxVERTICAL
);
314 wxSize size
= dc
.Reflect(sizeReal
);
317 // we draw a Win32-like grey sash with possible 3D border here:
319 // ---- this is position
324 // GWGGGDB where G is light grey (face)
325 // GWGGGDB W white (light)
326 // GWGGGDB D dark grey (shadow)
327 // GWGGGDB B black (dark shadow)
329 // GWGGGDB and lower letters are our border (already drawn)
333 // only the middle 3 columns are drawn unless wxSP_3D is specified
335 const wxCoord h
= size
.y
;
338 // If we're drawing the border, draw the sash 3d lines shorter
339 if ( win
->HasFlag(wxSP_3DBORDER
) )
344 dc
.SetPen(*wxTRANSPARENT_PEN
);
345 dc
.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)));
347 if ( win
->HasFlag(wxSP_3DSASH
) )
350 dc
.DrawRectangle(position
+ 2, 0, 3, h
);
352 dc
.SetPen(m_penLightGrey
);
353 dc
.DrawLine(position
, offset
, position
, h
- offset
);
355 dc
.SetPen(m_penHighlight
);
356 dc
.DrawLine(position
+ 1, 0, position
+ 1, h
);
358 dc
.SetPen(m_penDarkGrey
);
359 dc
.DrawLine(position
+ 5, 0, position
+ 5, h
);
361 dc
.SetPen(m_penBlack
);
362 dc
.DrawLine(position
+ 6, offset
, position
+ 6, h
- offset
);
367 dc
.DrawRectangle(position
, 0, 3, h
);
371 // ----------------------------------------------------------------------------
373 // ----------------------------------------------------------------------------
376 wxRendererGeneric::DrawComboBoxDropButton(wxWindow
*win
,
381 DrawPushButton(win
,dc
,rect
,flags
);
382 DrawDropArrow(win
,dc
,rect
,flags
);
386 wxRendererGeneric::DrawDropArrow(wxWindow
*win
,
391 // This generic implementation should be good
392 // enough for Windows platforms (including XP).
394 int arrowHalf
= rect
.width
/5;
395 int rectMid
= rect
.width
/ 2;
396 int arrowTopY
= (rect
.height
/2) - (arrowHalf
/2);
398 // This should always result in arrow with odd width.
401 wxPoint(rectMid
- arrowHalf
, arrowTopY
),
402 wxPoint(rectMid
+ arrowHalf
, arrowTopY
),
403 wxPoint(rectMid
, arrowTopY
+ arrowHalf
)
405 dc
.SetBrush(wxBrush(win
->GetForegroundColour()));
406 dc
.SetPen(wxPen(win
->GetForegroundColour()));
407 dc
.DrawPolygon(WXSIZEOF(pt
), pt
, rect
.x
, rect
.y
);
411 wxRendererGeneric::DrawCheckBox(wxWindow
*WXUNUSED(win
),
416 dc
.SetPen(*(flags
& wxCONTROL_DISABLED
? wxGREY_PEN
: wxBLACK_PEN
));
417 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
418 dc
.DrawRectangle(rect
);
420 if ( flags
& wxCONTROL_CHECKED
)
422 dc
.DrawCheckMark(rect
.Deflate(2, 2));
427 wxRendererGeneric::DrawPushButton(wxWindow
*win
,
432 // Don't try anything too fancy. It'll just turn out looking
433 // out-of-place on most platforms.
434 wxColour bgCol
= flags
& wxCONTROL_DISABLED
?
435 wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE
) :
436 win
->GetBackgroundColour();
437 dc
.SetBrush(wxBrush(bgCol
));
438 dc
.SetPen(wxPen(bgCol
));
439 dc
.DrawRectangle(rect
);
443 wxRendererGeneric::DrawItemSelectionRect(wxWindow
* WXUNUSED(win
),
449 if ( flags
& wxCONTROL_SELECTED
)
451 if ( flags
& wxCONTROL_FOCUSED
)
453 brush
= wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT
));
457 brush
= wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW
));
462 brush
= *wxTRANSPARENT_BRUSH
;
466 dc
.SetPen(flags
& wxCONTROL_CURRENT
? *wxBLACK_PEN
: *wxTRANSPARENT_PEN
);
468 dc
.DrawRectangle( rect
);
472 // ----------------------------------------------------------------------------
473 // A module to allow cleanup of generic renderer.
474 // ----------------------------------------------------------------------------
476 class wxGenericRendererModule
: public wxModule
478 DECLARE_DYNAMIC_CLASS(wxGenericRendererModule
)
480 wxGenericRendererModule() {}
481 bool OnInit() { return true; };
482 void OnExit() { wxRendererGeneric::Cleanup(); };
485 IMPLEMENT_DYNAMIC_CLASS(wxGenericRendererModule
, wxModule
)