]> git.saurik.com Git - wxWidgets.git/blame - src/msw/renderer.cpp
Compile fix for gcc on MSW
[wxWidgets.git] / src / msw / renderer.cpp
CommitLineData
9c7f49f5 1///////////////////////////////////////////////////////////////////////////////
90b903c2 2// Name: src/msw/renderer.cpp
38c4cb6a 3// Purpose: implementation of wxRendererNative for Windows
9c7f49f5
VZ
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>
65571936 9// License: wxWindows licence
9c7f49f5
VZ
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"
85b657c7
VS
29 #include "wx/window.h"
30 #include "wx/dc.h"
9eddec69 31 #include "wx/settings.h"
9c7f49f5
VZ
32#endif //WX_PRECOMP
33
3c2544bb 34#include "wx/splitter.h"
9c7f49f5 35#include "wx/renderer.h"
03f01e63 36#include "wx/msw/private.h"
4614c8e5 37#include "wx/msw/uxtheme.h"
8b97949e 38
7cf3223a
VZ
39// tmschema.h is in Win32 Platform SDK and might not be available with earlier
40// compilers
41#ifndef CP_DROPDOWNBUTTON
2209baae 42 #define BP_PUSHBUTTON 1
9f93b45e
VZ
43 #define BP_CHECKBOX 3
44 #define CBS_UNCHECKEDNORMAL 1
45 #define CBS_CHECKEDNORMAL (CBS_UNCHECKEDNORMAL + 4)
46 #define CBS_MIXEDNORMAL (CBS_CHECKEDNORMAL + 4)
47
2209baae
RR
48 #define PBS_NORMAL 1
49 #define PBS_HOT 2
50 #define PBS_PRESSED 3
51 #define PBS_DISABLED 4
52 #define PBS_DEFAULTED 5
53
7cf3223a
VZ
54 #define CP_DROPDOWNBUTTON 1
55
56 #define CBXS_NORMAL 1
57 #define CBXS_HOT 2
58 #define CBXS_PRESSED 3
59 #define CBXS_DISABLED 4
a9d9e2f2 60
9f93b45e
VZ
61 #define TVP_GLYPH 2
62
63 #define GLPS_CLOSED 1
a9d9e2f2
JS
64 #define GLPS_OPENED 2
65
66 #define HP_HEADERITEM 1
67
68 #define HIS_NORMAL 1
69 #define HIS_HOT 2
70 #define HIS_PRESSED 3
4b94ddc4
RD
71
72 #define TMT_HEIGHT 2417
73
74 #define HP_HEADERSORTARROW 4
75 #define HSAS_SORTEDUP 1
76 #define HSAS_SORTEDDOWN 2
7cf3223a
VZ
77#endif
78
9f93b45e
VZ
79#if defined(__WXWINCE__) && !defined(DFCS_FLAT)
80 #define DFCS_FLAT 0
81#endif
82
9c7f49f5 83// ----------------------------------------------------------------------------
8b97949e 84// wxRendererMSW: wxRendererNative implementation for "old" Win32 systems
9c7f49f5
VZ
85// ----------------------------------------------------------------------------
86
38c4cb6a 87class WXDLLEXPORT wxRendererMSW : public wxDelegateRendererNative
9c7f49f5 88{
2eb10e2a
VZ
89public:
90 wxRendererMSW() { }
91
8b97949e
VZ
92 static wxRendererNative& Get();
93
7402677a
VZ
94 virtual void DrawComboBoxDropButton(wxWindow *win,
95 wxDC& dc,
96 const wxRect& rect,
97 int flags = 0);
98
2209baae
RR
99 virtual void DrawPushButton(wxWindow *win,
100 wxDC& dc,
101 const wxRect& rect,
102 int flags = 0);
103
2eb10e2a
VZ
104private:
105 DECLARE_NO_COPY_CLASS(wxRendererMSW)
9c7f49f5
VZ
106};
107
8b97949e
VZ
108// ----------------------------------------------------------------------------
109// wxRendererXP: wxRendererNative implementation for Windows XP and later
110// ----------------------------------------------------------------------------
111
7cf3223a
VZ
112#if wxUSE_UXTHEME
113
8b97949e
VZ
114class WXDLLEXPORT wxRendererXP : public wxDelegateRendererNative
115{
116public:
117 wxRendererXP() : wxDelegateRendererNative(wxRendererMSW::Get()) { }
118
119 static wxRendererNative& Get();
120
c97c9952 121 virtual int DrawHeaderButton(wxWindow *win,
4b94ddc4
RD
122 wxDC& dc,
123 const wxRect& rect,
124 int flags = 0,
80752b57 125 wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE,
4b94ddc4
RD
126 wxHeaderButtonParams* params = NULL);
127 virtual int GetHeaderButtonHeight(wxWindow *win);
f4322df6 128
9f93b45e
VZ
129 virtual void DrawTreeItemButton(wxWindow *win,
130 wxDC& dc,
131 const wxRect& rect,
132 int flags = 0);
8b97949e
VZ
133 virtual void DrawSplitterBorder(wxWindow *win,
134 wxDC& dc,
c4e6c15e
VZ
135 const wxRect& rect,
136 int flags = 0);
8b97949e
VZ
137 virtual void DrawSplitterSash(wxWindow *win,
138 wxDC& dc,
139 const wxSize& size,
140 wxCoord position,
c4e6c15e
VZ
141 wxOrientation orient,
142 int flags = 0);
7cf3223a
VZ
143 virtual void DrawComboBoxDropButton(wxWindow *win,
144 wxDC& dc,
145 const wxRect& rect,
146 int flags = 0);
90b903c2
WS
147 virtual void DrawCheckBox(wxWindow *win,
148 wxDC& dc,
149 const wxRect& rect,
150 int flags = 0);
9f93b45e 151
2209baae
RR
152 virtual void DrawPushButton(wxWindow *win,
153 wxDC& dc,
154 const wxRect& rect,
155 int flags = 0);
156
a9fdf824
RR
157 virtual void DrawItemSelectionRect(wxWindow *win,
158 wxDC& dc,
159 const wxRect& rect,
160 int flags = 0 );
161
162
9f93b45e 163 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
8b97949e
VZ
164private:
165 DECLARE_NO_COPY_CLASS(wxRendererXP)
166};
167
7cf3223a
VZ
168#endif // wxUSE_UXTHEME
169
9c7f49f5 170// ============================================================================
8b97949e 171// wxRendererNative and wxRendererMSW implementation
9c7f49f5
VZ
172// ============================================================================
173
174/* static */
f0244295 175wxRendererNative& wxRendererNative::GetDefault()
8b97949e 176{
7cf3223a 177#if wxUSE_UXTHEME
8b97949e 178 wxUxThemeEngine *themeEngine = wxUxThemeEngine::Get();
7cf3223a
VZ
179 if ( themeEngine && themeEngine->IsAppThemed() )
180 return wxRendererXP::Get();
181#endif // wxUSE_UXTHEME
182
183 return wxRendererMSW::Get();
8b97949e
VZ
184}
185
186/* static */
187wxRendererNative& wxRendererMSW::Get()
9c7f49f5
VZ
188{
189 static wxRendererMSW s_rendererMSW;
190
191 return s_rendererMSW;
192}
193
7402677a
VZ
194void
195wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win),
196 wxDC& dc,
197 const wxRect& rect,
198 int flags)
199{
200 RECT r;
201 r.left = rect.GetLeft();
202 r.top = rect.GetTop();
7cf3223a
VZ
203 r.bottom = rect.y + rect.height;
204 r.right = rect.x + rect.width;
7402677a
VZ
205
206 int style = DFCS_SCROLLCOMBOBOX;
207 if ( flags & wxCONTROL_DISABLED )
208 style |= DFCS_INACTIVE;
209 if ( flags & wxCONTROL_PRESSED )
7cf3223a 210 style |= DFCS_PUSHED | DFCS_FLAT;
7402677a
VZ
211
212 ::DrawFrameControl(GetHdcOf(dc), &r, DFC_SCROLL, style);
213}
214
2209baae
RR
215void
216wxRendererMSW::DrawPushButton(wxWindow * WXUNUSED(win),
217 wxDC& dc,
f2ea4255 218 const wxRect& rectOrig,
2209baae
RR
219 int flags)
220{
f2ea4255 221 wxRect rect(rectOrig);
2209baae
RR
222
223 int style = DFCS_BUTTONPUSH;
224 if ( flags & wxCONTROL_DISABLED )
225 style |= DFCS_INACTIVE;
226 if ( flags & wxCONTROL_PRESSED )
227 style |= DFCS_PUSHED | DFCS_FLAT;
f2ea4255
VZ
228 if ( flags & wxCONTROL_ISDEFAULT )
229 {
230 // DrawFrameControl() doesn't seem to support default buttons so we
231 // have to draw the border ourselves
232 wxDCPenChanger pen(dc, *wxBLACK_PEN);
233 wxDCBrushChanger brush(dc, *wxTRANSPARENT_BRUSH);
234 dc.DrawRectangle(rect);
844b9f5f 235 rect.Deflate(1);
f2ea4255
VZ
236 }
237
238 RECT rc;
239 wxCopyRectToRECT(rect, rc);
240
241 ::DrawFrameControl(GetHdcOf(dc), &rc, DFC_BUTTON, style);
2209baae
RR
242}
243
8b97949e
VZ
244// ============================================================================
245// wxRendererXP implementation
246// ============================================================================
247
7cf3223a
VZ
248#if wxUSE_UXTHEME
249
8b97949e
VZ
250/* static */
251wxRendererNative& wxRendererXP::Get()
252{
253 static wxRendererXP s_rendererXP;
254
255 return s_rendererXP;
256}
257
7cf3223a
VZ
258// NOTE: There is no guarantee that the button drawn fills the entire rect (XP
259// default theme, for example), so the caller should have cleared button's
260// background before this call. This is quite likely a wxMSW-specific thing.
261void
262wxRendererXP::DrawComboBoxDropButton(wxWindow * win,
263 wxDC& dc,
264 const wxRect& rect,
265 int flags)
266{
267 wxUxThemeHandle hTheme(win, L"COMBOBOX");
9f93b45e 268 if ( !hTheme )
7cf3223a 269 {
9f93b45e
VZ
270 m_rendererNative.DrawComboBoxDropButton(win, dc, rect, flags);
271 return;
272 }
273
274 RECT r;
275 wxCopyRectToRECT(rect, r);
7cf3223a 276
9f93b45e
VZ
277 int state;
278 if ( flags & wxCONTROL_PRESSED )
279 state = CBXS_PRESSED;
280 else if ( flags & wxCONTROL_CURRENT )
281 state = CBXS_HOT;
282 else if ( flags & wxCONTROL_DISABLED )
283 state = CBXS_DISABLED;
284 else
285 state = CBXS_NORMAL;
286
287 wxUxThemeEngine::Get()->DrawThemeBackground
288 (
289 hTheme,
290 GetHdcOf(dc),
291 CP_DROPDOWNBUTTON,
292 state,
293 &r,
294 NULL
295 );
296
297}
298
c97c9952 299int
9f93b45e
VZ
300wxRendererXP::DrawHeaderButton(wxWindow *win,
301 wxDC& dc,
302 const wxRect& rect,
4b94ddc4 303 int flags,
80752b57 304 wxHeaderSortIconType sortArrow,
4b94ddc4 305 wxHeaderButtonParams* params)
9f93b45e
VZ
306{
307 wxUxThemeHandle hTheme(win, L"HEADER");
308 if ( !hTheme )
309 {
c97c9952 310 return m_rendererNative.DrawHeaderButton(win, dc, rect, flags, sortArrow, params);
7cf3223a 311 }
9f93b45e
VZ
312
313 RECT r;
314 wxCopyRectToRECT(rect, r);
315
316 int state;
317 if ( flags & wxCONTROL_PRESSED )
318 state = HIS_PRESSED;
319 else if ( flags & wxCONTROL_CURRENT )
320 state = HIS_HOT;
321 else
322 state = HIS_NORMAL;
323 wxUxThemeEngine::Get()->DrawThemeBackground
324 (
325 hTheme,
326 GetHdcOf(dc),
327 HP_HEADERITEM,
328 state,
329 &r,
330 NULL
331 );
4b94ddc4
RD
332
333 // NOTE: Using the theme to draw HP_HEADERSORTARROW doesn't do anything.
334 // Why? If this can be fixed then draw the sort arrows using the theme
335 // and then clear those flags before calling DrawHeaderButtonContents.
f4322df6 336
4b94ddc4 337 // Add any extras that are specified in flags and params
c97c9952 338 return DrawHeaderButtonContents(win, dc, rect, flags, sortArrow, params);
9f93b45e
VZ
339}
340
4b94ddc4
RD
341
342int
343wxRendererXP::GetHeaderButtonHeight(wxWindow *win)
344{
345 wxUxThemeHandle hTheme(win, L"HEADER");
346 if ( !hTheme )
347 {
348 return m_rendererNative.GetHeaderButtonHeight(win);
349 }
f4322df6 350
4b94ddc4
RD
351 HRESULT hr;
352 int value = -1;
f4322df6 353
4b94ddc4
RD
354 hr = wxUxThemeEngine::Get()->GetThemeMetric( hTheme,
355 NULL,
356 HP_HEADERITEM,
357 HIS_NORMAL,
358 TMT_HEIGHT,
359 &value );
360 if ( hr == S_OK )
361 return value;
362 else
363 return 20;
364}
365
366
9f93b45e
VZ
367void
368wxRendererXP::DrawTreeItemButton(wxWindow *win,
369 wxDC& dc,
370 const wxRect& rect,
371 int flags)
372{
373 wxUxThemeHandle hTheme(win, L"TREEVIEW");
374 if ( !hTheme )
375 {
376 m_rendererNative.DrawTreeItemButton(win, dc, rect, flags);
377 return;
378 }
379
380 RECT r;
381 wxCopyRectToRECT(rect, r);
382
383 int state = flags & wxCONTROL_EXPANDED ? GLPS_OPENED : GLPS_CLOSED;
384 wxUxThemeEngine::Get()->DrawThemeBackground
385 (
386 hTheme,
387 GetHdcOf(dc),
388 TVP_GLYPH,
389 state,
390 &r,
391 NULL
392 );
393}
394
395void
90b903c2
WS
396wxRendererXP::DrawCheckBox(wxWindow *win,
397 wxDC& dc,
398 const wxRect& rect,
399 int flags)
9f93b45e
VZ
400{
401 wxUxThemeHandle hTheme(win, L"BUTTON");
402 if ( !hTheme )
403 {
90b903c2 404 m_rendererNative.DrawCheckBox(win, dc, rect, flags);
9f93b45e
VZ
405 return;
406 }
407
408 RECT r;
409 wxCopyRectToRECT(rect, r);
410
411 int state;
412 if ( flags & wxCONTROL_CHECKED )
413 state = CBS_CHECKEDNORMAL;
414 else if ( flags & wxCONTROL_UNDETERMINED )
415 state = CBS_MIXEDNORMAL;
416 else
417 state = CBS_UNCHECKEDNORMAL;
418
419 // CBS_XXX is followed by CBX_XXXGOT, then CBS_XXXPRESSED and DISABLED
420 if ( flags & wxCONTROL_CURRENT )
421 state += 1;
422 else if ( flags & wxCONTROL_PRESSED )
423 state += 2;
424 else if ( flags & wxCONTROL_DISABLED )
425 state += 3;
426
427 wxUxThemeEngine::Get()->DrawThemeBackground
428 (
429 hTheme,
430 GetHdcOf(dc),
431 BP_CHECKBOX,
432 state,
433 &r,
434 NULL
435 );
7cf3223a
VZ
436}
437
2209baae
RR
438void
439wxRendererXP::DrawPushButton(wxWindow * win,
440 wxDC& dc,
441 const wxRect& rect,
442 int flags)
443{
444 wxUxThemeHandle hTheme(win, L"BUTTON");
445 if ( !hTheme )
446 {
447 m_rendererNative.DrawPushButton(win, dc, rect, flags);
448 return;
449 }
450
451 RECT r;
452 wxCopyRectToRECT(rect, r);
453
454 int state;
455 if ( flags & wxCONTROL_PRESSED )
456 state = PBS_PRESSED;
457 else if ( flags & wxCONTROL_CURRENT )
458 state = PBS_HOT;
459 else if ( flags & wxCONTROL_DISABLED )
460 state = PBS_DISABLED;
461 else if ( flags & wxCONTROL_ISDEFAULT )
462 state = PBS_DEFAULTED;
463 else
464 state = PBS_NORMAL;
465
466 wxUxThemeEngine::Get()->DrawThemeBackground
467 (
468 hTheme,
469 GetHdcOf(dc),
470 BP_PUSHBUTTON,
471 state,
472 &r,
473 NULL
474 );
475
476}
477
a9fdf824
RR
478void
479wxRendererXP::DrawItemSelectionRect(wxWindow * WXUNUSED(win),
480 wxDC& dc,
481 const wxRect& rect,
482 int flags)
483{
484 wxBrush brush;
485 if ( flags & wxCONTROL_SELECTED )
486 {
487 if ( flags & wxCONTROL_FOCUSED )
488 {
489 brush = wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
490 }
491 else // !focused
492 {
493 brush = wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW));
494 }
495 }
496 else // !selected
497 {
498 brush = *wxTRANSPARENT_BRUSH;
499 }
500
501 dc.SetBrush(brush);
502
503 // unlike for wxRendererGeneric, on windows we _never_ want to draw
504 // the outline of the rectangle:
505 dc.SetPen(*wxTRANSPARENT_PEN);
506
507 dc.DrawRectangle( rect );
508}
509
510
511
8b97949e
VZ
512// ----------------------------------------------------------------------------
513// splitter drawing
514// ----------------------------------------------------------------------------
515
516// the width of the sash: this is the same as used by Explorer...
517static const wxCoord SASH_WIDTH = 4;
518
c4e6c15e 519wxSplitterRenderParams
3c2544bb 520wxRendererXP::GetSplitterParams(const wxWindow * win)
8b97949e 521{
9f93b45e 522 if ( win->HasFlag(wxSP_NO_XP_THEME) )
3c2544bb
JS
523 return m_rendererNative.GetSplitterParams(win);
524 else
525 return wxSplitterRenderParams(SASH_WIDTH, 0, false);
8b97949e
VZ
526}
527
528void
3c2544bb
JS
529wxRendererXP::DrawSplitterBorder(wxWindow * win,
530 wxDC& dc,
531 const wxRect& rect,
532 int flags)
8b97949e 533{
9f93b45e 534 if ( win->HasFlag(wxSP_NO_XP_THEME) )
3c2544bb
JS
535 {
536 m_rendererNative.DrawSplitterBorder(win, dc, rect, flags);
537 }
8b97949e
VZ
538}
539
540void
541wxRendererXP::DrawSplitterSash(wxWindow *win,
542 wxDC& dc,
543 const wxSize& size,
544 wxCoord position,
c4e6c15e 545 wxOrientation orient,
3c2544bb 546 int flags)
8b97949e 547{
6421119d 548 if ( !win->HasFlag(wxSP_NO_XP_THEME) )
8b97949e 549 {
fe404d1a
JS
550 dc.SetPen(*wxTRANSPARENT_PEN);
551 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
552 if ( orient == wxVERTICAL )
8b97949e 553 {
fe404d1a 554 dc.DrawRectangle(position, 0, SASH_WIDTH, size.y);
8b97949e 555 }
fe404d1a
JS
556 else // wxHORIZONTAL
557 {
558 dc.DrawRectangle(0, position, size.x, SASH_WIDTH);
559 }
560
561 return;
8b97949e 562 }
6421119d
VZ
563
564 m_rendererNative.DrawSplitterSash(win, dc, size, position, orient, flags);
8b97949e
VZ
565}
566
7cf3223a 567#endif // wxUSE_UXTHEME