]> git.saurik.com Git - wxWidgets.git/blob - src/generic/renderg.cpp
some compilers (Watcom) don't like it if wxBase library PCH file contains
[wxWidgets.git] / src / generic / renderg.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: generic/renderg.cpp
3 // Purpose: generic implementation of wxRendererNative (for any platform)
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 20.07.2003
7 // RCS-ID: $Id$
8 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // License: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #ifndef WX_PRECOMP
28 #include "wx/string.h"
29 #endif //WX_PRECOMP
30
31 #include "wx/gdicmn.h"
32 #include "wx/dc.h"
33
34 #include "wx/settings.h"
35 #include "wx/splitter.h"
36
37 #include "wx/dcmirror.h"
38
39 #include "wx/renderer.h"
40
41 // ----------------------------------------------------------------------------
42 // wxRendererGeneric: our wxRendererNative implementation
43 // ----------------------------------------------------------------------------
44
45 class WXDLLEXPORT wxRendererGeneric : public wxRendererNative
46 {
47 public:
48 wxRendererGeneric();
49
50 virtual void DrawHeaderButton(wxWindow *win,
51 wxDC& dc,
52 const wxRect& rect,
53 int flags = 0);
54
55 virtual void DrawTreeItemButton(wxWindow *win,
56 wxDC& dc,
57 const wxRect& rect,
58 int flags = 0);
59
60 virtual void DrawSplitterBorder(wxWindow *win,
61 wxDC& dc,
62 const wxRect& rect,
63 int flags = 0);
64
65 virtual void DrawSplitterSash(wxWindow *win,
66 wxDC& dc,
67 const wxSize& size,
68 wxCoord position,
69 wxOrientation orient,
70 int flags = 0);
71
72
73 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
74
75
76 protected:
77 // draw the rectange using the first pen for the left and top sides and
78 // the second one for the bottom and right ones
79 void DrawShadedRect(wxDC& dc, wxRect *rect,
80 const wxPen& pen1, const wxPen& pen2);
81
82 // the standard pens
83 wxPen m_penBlack,
84 m_penDarkGrey,
85 m_penLightGrey,
86 m_penHighlight;
87 };
88
89 // ============================================================================
90 // wxRendererGeneric implementation
91 // ============================================================================
92
93 // ----------------------------------------------------------------------------
94 // wxRendererGeneric creation
95 // ----------------------------------------------------------------------------
96
97 /* static */
98 wxRendererNative& wxRendererNative::GetGeneric()
99 {
100 static wxRendererGeneric s_rendererGeneric;
101
102 return s_rendererGeneric;
103 }
104
105 wxRendererGeneric::wxRendererGeneric()
106 : m_penBlack(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW)),
107 m_penDarkGrey(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW)),
108 m_penLightGrey(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)),
109 m_penHighlight(wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT))
110 {
111 }
112
113 // ----------------------------------------------------------------------------
114 // wxRendererGeneric helpers
115 // ----------------------------------------------------------------------------
116
117 void
118 wxRendererGeneric::DrawShadedRect(wxDC& dc,
119 wxRect *rect,
120 const wxPen& pen1,
121 const wxPen& pen2)
122 {
123 // draw the rectangle
124 dc.SetPen(pen1);
125 dc.DrawLine(rect->GetLeft(), rect->GetTop(),
126 rect->GetLeft(), rect->GetBottom());
127 dc.DrawLine(rect->GetLeft() + 1, rect->GetTop(),
128 rect->GetRight(), rect->GetTop());
129 dc.SetPen(pen2);
130 dc.DrawLine(rect->GetRight(), rect->GetTop(),
131 rect->GetRight(), rect->GetBottom());
132 dc.DrawLine(rect->GetLeft(), rect->GetBottom(),
133 rect->GetRight() + 1, rect->GetBottom());
134
135 // adjust the rect
136 rect->Inflate(-1);
137 }
138
139 // ----------------------------------------------------------------------------
140 // tree/list ctrl drawing
141 // ----------------------------------------------------------------------------
142
143 void
144 wxRendererGeneric::DrawHeaderButton(wxWindow * WXUNUSED(win),
145 wxDC& dc,
146 const wxRect& rect,
147 int WXUNUSED(flags))
148 {
149 const int CORNER = 1;
150
151 const wxCoord x = rect.x,
152 y = rect.y,
153 w = rect.width,
154 h = rect.height;
155
156 dc.SetBrush(*wxTRANSPARENT_BRUSH);
157
158 dc.SetPen(m_penBlack);
159 dc.DrawLine( x+w-CORNER+1, y, x+w, y+h ); // right (outer)
160 dc.DrawRectangle( x, y+h, w+1, 1 ); // bottom (outer)
161
162 dc.SetPen(m_penDarkGrey);
163 dc.DrawLine( x+w-CORNER, y, x+w-1, y+h ); // right (inner)
164 dc.DrawRectangle( x+1, y+h-1, w-2, 1 ); // bottom (inner)
165
166 dc.SetPen(m_penHighlight);
167 dc.DrawRectangle( x, y, w-CORNER+1, 1 ); // top (outer)
168 dc.DrawRectangle( x, y, 1, h ); // left (outer)
169 dc.DrawLine( x, y+h-1, x+1, y+h-1 );
170 dc.DrawLine( x+w-1, y, x+w-1, y+1 );
171 }
172
173 // draw the plus or minus sign
174 void
175 wxRendererGeneric::DrawTreeItemButton(wxWindow * WXUNUSED(win),
176 wxDC& dc,
177 const wxRect& rect,
178 int flags)
179 {
180 // white background
181 dc.SetPen(*wxGREY_PEN);
182 dc.SetBrush(*wxWHITE_BRUSH);
183 dc.DrawRectangle(rect.Deflate(1, 2));
184
185 // black lines
186 const wxCoord xMiddle = rect.x + rect.width/2;
187 const wxCoord yMiddle = rect.y + rect.height/2;
188
189 dc.SetPen(*wxBLACK_PEN);
190 dc.DrawLine(xMiddle - 2, yMiddle, xMiddle + 3, yMiddle);
191 if ( !(flags & wxCONTROL_EXPANDED) )
192 {
193 // turn "-" into "+"
194 dc.DrawLine(xMiddle, yMiddle - 2, xMiddle, yMiddle + 3);
195 }
196 }
197
198 // ----------------------------------------------------------------------------
199 // sash drawing
200 // ----------------------------------------------------------------------------
201
202 wxSplitterRenderParams
203 wxRendererGeneric::GetSplitterParams(const wxWindow *win)
204 {
205 // see below
206 wxCoord sashWidth,
207 border;
208
209 if ( win->HasFlag(wxSP_3D) )
210 {
211 sashWidth = 7;
212 border = 2;
213 }
214 else // no 3D effect
215 {
216 sashWidth = 3;
217 border = 0;
218 }
219
220 return wxSplitterRenderParams(sashWidth, border, false);
221 }
222
223 void
224 wxRendererGeneric::DrawSplitterBorder(wxWindow *win,
225 wxDC& dc,
226 const wxRect& rectOrig,
227 int WXUNUSED(falgs))
228 {
229 if ( win->HasFlag(wxSP_3D) )
230 {
231 wxRect rect = rectOrig;
232 DrawShadedRect(dc, &rect, m_penDarkGrey, m_penHighlight);
233 DrawShadedRect(dc, &rect, m_penBlack, m_penLightGrey);
234 }
235 }
236
237 void
238 wxRendererGeneric::DrawSplitterSash(wxWindow *win,
239 wxDC& dcReal,
240 const wxSize& sizeReal,
241 wxCoord position,
242 wxOrientation orient,
243 int WXUNUSED(flags))
244 {
245 // to avoid duplicating the same code for horizontal and vertical sashes,
246 // simply mirror the DC instead if needed (i.e. if horz splitter)
247 wxMirrorDC dc(dcReal, orient != wxVERTICAL);
248 wxSize size = dc.Reflect(sizeReal);
249
250
251 // we draw a Win32-like grey sash with possible 3D border here:
252 //
253 // ---- this is position
254 // /
255 // v
256 // dWGGGDd
257 // GWGGGDB
258 // GWGGGDB where G is light grey (face)
259 // GWGGGDB W white (light)
260 // GWGGGDB D dark grey (shadow)
261 // GWGGGDB B black (dark shadow)
262 // GWGGGDB
263 // GWGGGDB and lower letters are our border (already drawn)
264 // GWGGGDB
265 // wWGGGDd
266 //
267 // only the middle 3 columns are drawn unless wxSP_3D is specified
268
269 const wxCoord h = size.y;
270 wxCoord offset = 0;
271
272 // If we're not drawing the border, droppings will
273 // be left unless we make the sash shorter
274 if ( !win->HasFlag(wxSP_3DBORDER) )
275 {
276 offset = 3;
277 }
278
279 // from left to right
280 if ( win->HasFlag(wxSP_3D) )
281 {
282 dc.SetPen(m_penLightGrey);
283 dc.DrawLine(position, 1 + offset, position, h - 1 - offset);
284
285 dc.SetPen(m_penHighlight);
286 dc.DrawLine(position + 1, offset, position + 1, h - offset);
287 }
288
289 dc.SetPen(*wxTRANSPARENT_PEN);
290 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)));
291 dc.DrawRectangle(position + 2, offset, 3, h - 2*offset);
292
293 if ( win->HasFlag(wxSP_3D) )
294 {
295 dc.SetPen(m_penDarkGrey);
296 dc.DrawLine(position + 5, offset, position + 5, h - offset);
297
298 dc.SetPen(m_penBlack);
299 dc.DrawLine(position + 6, offset, position + 6, h - 1 - offset);
300 }
301 }
302