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"
28 #include "wx/string.h"
31 #include "wx/gdicmn.h"
34 #include "wx/settings.h"
35 #include "wx/splitter.h"
36 #include "wx/dcmirror.h"
37 #include "wx/module.h"
38 #include "wx/renderer.h"
40 // ----------------------------------------------------------------------------
41 // wxRendererGeneric: our wxRendererNative implementation
42 // ----------------------------------------------------------------------------
44 class WXDLLEXPORT wxRendererGeneric
: public wxRendererNative
49 virtual void DrawHeaderButton(wxWindow
*win
,
54 virtual void DrawTreeItemButton(wxWindow
*win
,
59 virtual void DrawSplitterBorder(wxWindow
*win
,
64 virtual void DrawSplitterSash(wxWindow
*win
,
71 virtual void DrawComboBoxDropButton(wxWindow
*win
,
76 virtual void DrawDropArrow(wxWindow
*win
,
81 virtual void DrawCheckButton(wxWindow
*win
,
86 virtual void DrawPushButton(wxWindow
*win
,
91 virtual wxSplitterRenderParams
GetSplitterParams(const wxWindow
*win
);
93 virtual wxRendererVersion
GetVersion() const
95 return wxRendererVersion(wxRendererVersion::Current_Version
,
96 wxRendererVersion::Current_Age
);
100 // Cleanup by deleting standard renderer
101 static void Cleanup();
103 // Get the generic object
104 static wxRendererGeneric
* DoGetGeneric();
107 // draw the rectange using the first pen for the left and top sides and
108 // the second one for the bottom and right ones
109 void DrawShadedRect(wxDC
& dc
, wxRect
*rect
,
110 const wxPen
& pen1
, const wxPen
& pen2
);
118 static wxRendererGeneric
* sm_rendererGeneric
;
121 // ============================================================================
122 // wxRendererGeneric implementation
123 // ============================================================================
125 // Get the generic object
126 wxRendererGeneric
* wxRendererGeneric::DoGetGeneric()
128 if (!sm_rendererGeneric
)
129 sm_rendererGeneric
= new wxRendererGeneric
;
130 return sm_rendererGeneric
;
133 // ----------------------------------------------------------------------------
134 // wxRendererGeneric creation
135 // ----------------------------------------------------------------------------
138 wxRendererNative
& wxRendererNative::GetGeneric()
140 return * wxRendererGeneric::DoGetGeneric();
143 void wxRendererGeneric::Cleanup()
145 if (sm_rendererGeneric
)
146 delete sm_rendererGeneric
;
148 sm_rendererGeneric
= NULL
;
151 wxRendererGeneric
* wxRendererGeneric::sm_rendererGeneric
= NULL
;
153 wxRendererGeneric::wxRendererGeneric()
154 : m_penBlack(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW
)),
155 m_penDarkGrey(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW
)),
156 m_penLightGrey(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)),
157 m_penHighlight(wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT
))
161 // ----------------------------------------------------------------------------
162 // wxRendererGeneric helpers
163 // ----------------------------------------------------------------------------
166 wxRendererGeneric::DrawShadedRect(wxDC
& dc
,
171 // draw the rectangle
173 dc
.DrawLine(rect
->GetLeft(), rect
->GetTop(),
174 rect
->GetLeft(), rect
->GetBottom());
175 dc
.DrawLine(rect
->GetLeft() + 1, rect
->GetTop(),
176 rect
->GetRight(), rect
->GetTop());
178 dc
.DrawLine(rect
->GetRight(), rect
->GetTop(),
179 rect
->GetRight(), rect
->GetBottom());
180 dc
.DrawLine(rect
->GetLeft(), rect
->GetBottom(),
181 rect
->GetRight() + 1, rect
->GetBottom());
187 // ----------------------------------------------------------------------------
188 // tree/list ctrl drawing
189 // ----------------------------------------------------------------------------
192 wxRendererGeneric::DrawHeaderButton(wxWindow
* WXUNUSED(win
),
197 const int CORNER
= 1;
199 const wxCoord x
= rect
.x
,
204 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
206 dc
.SetPen(m_penBlack
);
207 dc
.DrawLine( x
+w
-CORNER
+1, y
, x
+w
, y
+h
); // right (outer)
208 dc
.DrawRectangle( x
, y
+h
, w
+1, 1 ); // bottom (outer)
210 dc
.SetPen(m_penDarkGrey
);
211 dc
.DrawLine( x
+w
-CORNER
, y
, x
+w
-1, y
+h
); // right (inner)
212 dc
.DrawRectangle( x
+1, y
+h
-1, w
-2, 1 ); // bottom (inner)
214 dc
.SetPen(m_penHighlight
);
215 dc
.DrawRectangle( x
, y
, w
-CORNER
+1, 1 ); // top (outer)
216 dc
.DrawRectangle( x
, y
, 1, h
); // left (outer)
217 dc
.DrawLine( x
, y
+h
-1, x
+1, y
+h
-1 );
218 dc
.DrawLine( x
+w
-1, y
, x
+w
-1, y
+1 );
221 // draw the plus or minus sign
223 wxRendererGeneric::DrawTreeItemButton(wxWindow
* WXUNUSED(win
),
229 dc
.SetPen(*wxGREY_PEN
);
230 dc
.SetBrush(*wxWHITE_BRUSH
);
231 dc
.DrawRectangle(rect
);
234 const wxCoord xMiddle
= rect
.x
+ rect
.width
/2;
235 const wxCoord yMiddle
= rect
.y
+ rect
.height
/2;
237 // half of the length of the horz lines in "-" and "+"
238 const wxCoord halfWidth
= rect
.width
/2 - 2;
239 dc
.SetPen(*wxBLACK_PEN
);
240 dc
.DrawLine(xMiddle
- halfWidth
, yMiddle
,
241 xMiddle
+ halfWidth
+ 1, yMiddle
);
243 if ( !(flags
& wxCONTROL_EXPANDED
) )
246 const wxCoord halfHeight
= rect
.height
/2 - 2;
247 dc
.DrawLine(xMiddle
, yMiddle
- halfHeight
,
248 xMiddle
, yMiddle
+ halfHeight
+ 1);
252 // ----------------------------------------------------------------------------
254 // ----------------------------------------------------------------------------
256 wxSplitterRenderParams
257 wxRendererGeneric::GetSplitterParams(const wxWindow
*win
)
263 if ( win
->HasFlag(wxSP_3DSASH
) )
265 else if ( win
->HasFlag(wxSP_NOSASH
) )
270 if ( win
->HasFlag(wxSP_3DBORDER
) )
275 return wxSplitterRenderParams(sashWidth
, border
, false);
279 wxRendererGeneric::DrawSplitterBorder(wxWindow
*win
,
281 const wxRect
& rectOrig
,
284 if ( win
->HasFlag(wxSP_3DBORDER
) )
286 wxRect rect
= rectOrig
;
287 DrawShadedRect(dc
, &rect
, m_penDarkGrey
, m_penHighlight
);
288 DrawShadedRect(dc
, &rect
, m_penBlack
, m_penLightGrey
);
293 wxRendererGeneric::DrawSplitterSash(wxWindow
*win
,
295 const wxSize
& sizeReal
,
297 wxOrientation orient
,
300 // to avoid duplicating the same code for horizontal and vertical sashes,
301 // simply mirror the DC instead if needed (i.e. if horz splitter)
302 wxMirrorDC
dc(dcReal
, orient
!= wxVERTICAL
);
303 wxSize size
= dc
.Reflect(sizeReal
);
306 // we draw a Win32-like grey sash with possible 3D border here:
308 // ---- this is position
313 // GWGGGDB where G is light grey (face)
314 // GWGGGDB W white (light)
315 // GWGGGDB D dark grey (shadow)
316 // GWGGGDB B black (dark shadow)
318 // GWGGGDB and lower letters are our border (already drawn)
322 // only the middle 3 columns are drawn unless wxSP_3D is specified
324 const wxCoord h
= size
.y
;
327 // If we're drawing the border, draw the sash 3d lines shorter
328 if ( win
->HasFlag(wxSP_3DBORDER
) )
333 dc
.SetPen(*wxTRANSPARENT_PEN
);
334 dc
.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
)));
336 if ( win
->HasFlag(wxSP_3DSASH
) )
339 dc
.DrawRectangle(position
+ 2, 0, 3, h
);
341 dc
.SetPen(m_penLightGrey
);
342 dc
.DrawLine(position
, offset
, position
, h
- offset
);
344 dc
.SetPen(m_penHighlight
);
345 dc
.DrawLine(position
+ 1, 0, position
+ 1, h
);
347 dc
.SetPen(m_penDarkGrey
);
348 dc
.DrawLine(position
+ 5, 0, position
+ 5, h
);
350 dc
.SetPen(m_penBlack
);
351 dc
.DrawLine(position
+ 6, offset
, position
+ 6, h
- offset
);
356 dc
.DrawRectangle(position
, 0, 3, h
);
360 // ----------------------------------------------------------------------------
362 // ----------------------------------------------------------------------------
365 wxRendererGeneric::DrawComboBoxDropButton(wxWindow
*win
,
370 DrawPushButton(win
,dc
,rect
,flags
);
371 DrawDropArrow(win
,dc
,rect
,flags
);
375 wxRendererGeneric::DrawDropArrow(wxWindow
*win
,
380 // This generic implementation should be good
381 // enough for Windows platforms (including XP).
383 int arrowHalf
= rect
.width
/5;
384 int rectMid
= rect
.width
/ 2;
385 int arrowTopY
= (rect
.height
/2) - (arrowHalf
/2);
387 // This should always result in arrow with odd width.
390 wxPoint(rectMid
- arrowHalf
, arrowTopY
),
391 wxPoint(rectMid
+ arrowHalf
, arrowTopY
),
392 wxPoint(rectMid
, arrowTopY
+ arrowHalf
)
394 dc
.SetBrush(wxBrush(win
->GetForegroundColour()));
395 dc
.SetPen(wxPen(win
->GetForegroundColour()));
396 dc
.DrawPolygon(WXSIZEOF(pt
), pt
, rect
.x
, rect
.y
);
400 wxRendererGeneric::DrawCheckButton(wxWindow
*WXUNUSED(win
),
405 dc
.SetPen(*(flags
& wxCONTROL_DISABLED
? wxGREY_PEN
: wxBLACK_PEN
));
406 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
407 dc
.DrawRectangle(rect
);
409 if ( flags
& wxCONTROL_CHECKED
)
411 dc
.DrawCheckMark(rect
.Deflate(2, 2));
416 wxRendererGeneric::DrawPushButton(wxWindow
*win
,
421 // Don't try anything too fancy. It'll just turn out looking
422 // out-of-place on most platforms.
423 wxColour bgCol
= flags
& wxCONTROL_DISABLED
?
424 wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE
) :
425 win
->GetBackgroundColour();
426 dc
.SetBrush(wxBrush(bgCol
));
427 dc
.SetPen(wxPen(bgCol
));
428 dc
.DrawRectangle(rect
);
431 // ----------------------------------------------------------------------------
432 // A module to allow cleanup of generic renderer.
433 // ----------------------------------------------------------------------------
435 class wxGenericRendererModule
: public wxModule
437 DECLARE_DYNAMIC_CLASS(wxGenericRendererModule
)
439 wxGenericRendererModule() {}
440 bool OnInit() { return true; };
441 void OnExit() { wxRendererGeneric::Cleanup(); };
444 IMPLEMENT_DYNAMIC_CLASS(wxGenericRendererModule
, wxModule
)