]> git.saurik.com Git - wxWidgets.git/blame - src/msw/renderer.cpp
Fix two harmless gcc warnings about missing initializers.
[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>
526954c5 9// Licence: 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
066bd251 34#include "wx/dcgraph.h"
51c42fc5 35#include "wx/scopeguard.h"
3c2544bb 36#include "wx/splitter.h"
9c7f49f5 37#include "wx/renderer.h"
03f01e63 38#include "wx/msw/private.h"
4614c8e5 39#include "wx/msw/uxtheme.h"
8b97949e 40
7cf3223a
VZ
41// tmschema.h is in Win32 Platform SDK and might not be available with earlier
42// compilers
43#ifndef CP_DROPDOWNBUTTON
2209baae 44 #define BP_PUSHBUTTON 1
e4131985 45 #define BP_RADIOBUTTON 2
9f93b45e 46 #define BP_CHECKBOX 3
e4131985
KO
47 #define RBS_UNCHECKEDNORMAL 1
48 #define RBS_CHECKEDNORMAL (RBS_UNCHECKEDNORMAL + 4)
49 #define RBS_MIXEDNORMAL (RBS_CHECKEDNORMAL + 4)
9f93b45e
VZ
50 #define CBS_UNCHECKEDNORMAL 1
51 #define CBS_CHECKEDNORMAL (CBS_UNCHECKEDNORMAL + 4)
52 #define CBS_MIXEDNORMAL (CBS_CHECKEDNORMAL + 4)
53
2209baae
RR
54 #define PBS_NORMAL 1
55 #define PBS_HOT 2
56 #define PBS_PRESSED 3
57 #define PBS_DISABLED 4
58 #define PBS_DEFAULTED 5
59
7cf3223a
VZ
60 #define CP_DROPDOWNBUTTON 1
61
62 #define CBXS_NORMAL 1
63 #define CBXS_HOT 2
64 #define CBXS_PRESSED 3
65 #define CBXS_DISABLED 4
a9d9e2f2 66
9f93b45e
VZ
67 #define TVP_GLYPH 2
68
69 #define GLPS_CLOSED 1
a9d9e2f2
JS
70 #define GLPS_OPENED 2
71
72 #define HP_HEADERITEM 1
73
74 #define HIS_NORMAL 1
75 #define HIS_HOT 2
76 #define HIS_PRESSED 3
4b94ddc4
RD
77
78 #define TMT_HEIGHT 2417
79
80 #define HP_HEADERSORTARROW 4
81 #define HSAS_SORTEDUP 1
82 #define HSAS_SORTEDDOWN 2
e4131985
KO
83
84 #define EP_EDITTEXT 1
85 #define ETS_NORMAL 1
86 #define ETS_HOT 2
87 #define ETS_SELECTED 3
88 #define ETS_DISABLED 4
89 #define ETS_FOCUSED 5
90 #define ETS_READONLY 6
91 #define ETS_ASSIST 7
92 #define TMT_FILLCOLOR 3802
93 #define TMT_TEXTCOLOR 3803
94 #define TMT_BORDERCOLOR 3801
95 #define TMT_EDGEFILLCOLOR 3808
b50d93d1
VZ
96
97 #define WP_MINBUTTON 15
98 #define WP_MAXBUTTON 17
99 #define WP_CLOSEBUTTON 18
100 #define WP_RESTOREBUTTON 21
101 #define WP_HELPBUTTON 23
7cf3223a
VZ
102#endif
103
d6f2a891
VZ
104#if defined(__WXWINCE__)
105 #ifndef DFCS_FLAT
106 #define DFCS_FLAT 0
107 #endif
108 #ifndef DFCS_MONO
109 #define DFCS_MONO 0
110 #endif
9f93b45e
VZ
111#endif
112
59ee63e9
VZ
113#ifndef DFCS_HOT
114 #define DFCS_HOT 0x1000
115#endif
116
066bd251
RD
117// When we're using GDI+, the DC might have transforms applied to it,
118// but the renderer APIs don't respect them. So we need to apply
119// the transforms to the rect ourselves.
120inline
121wxRect applyGDIPlusTransformsToRect(wxDC& dc, const wxRect& r)
122{
123 wxRect rect = r;
124#if wxUSE_GRAPHICS_CONTEXT
125 wxGCDC* gcdc = dynamic_cast<wxGCDC*>(&dc);
126 if (gcdc)
127 {
128 double xtrans = 0;
129 double ytrans = 0;
130 wxGraphicsContext* gc = gcdc->GetGraphicsContext();
131 gc->GetTransform().TransformPoint(&xtrans, &ytrans);
132 rect.x = rect.x + (int)xtrans;
133 rect.y = rect.y + (int)ytrans;
134 }
135#endif
136 return rect;
137}
138
de4bf0b3
FM
139// ----------------------------------------------------------------------------
140// methods common to wxRendererMSW and wxRendererXP
141// ----------------------------------------------------------------------------
142
143class wxRendererMSWBase : public wxDelegateRendererNative
144{
145public:
146 wxRendererMSWBase() { }
147 wxRendererMSWBase(wxRendererNative& rendererNative)
148 : wxDelegateRendererNative(rendererNative) { }
149
150 void DrawFocusRect(wxWindow * win,
151 wxDC& dc,
152 const wxRect& rect,
153 int flags = 0);
154
155 void DrawItemSelectionRect(wxWindow *win,
156 wxDC& dc,
157 const wxRect& rect,
158 int flags = 0);
159};
160
9c7f49f5 161// ----------------------------------------------------------------------------
8b97949e 162// wxRendererMSW: wxRendererNative implementation for "old" Win32 systems
9c7f49f5
VZ
163// ----------------------------------------------------------------------------
164
5aac6f3f 165class wxRendererMSW : public wxRendererMSWBase
9c7f49f5 166{
2eb10e2a
VZ
167public:
168 wxRendererMSW() { }
169
8b97949e
VZ
170 static wxRendererNative& Get();
171
7402677a
VZ
172 virtual void DrawComboBoxDropButton(wxWindow *win,
173 wxDC& dc,
174 const wxRect& rect,
175 int flags = 0);
176
59ee63e9
VZ
177 virtual void DrawCheckBox(wxWindow *win,
178 wxDC& dc,
179 const wxRect& rect,
081b3342
VZ
180 int flags = 0)
181 {
182 DoDrawButton(DFCS_BUTTONCHECK, win, dc, rect, flags);
183 }
59ee63e9 184
2209baae
RR
185 virtual void DrawPushButton(wxWindow *win,
186 wxDC& dc,
187 const wxRect& rect,
188 int flags = 0);
189
7280c828
VZ
190 virtual void DrawChoice(wxWindow* win,
191 wxDC& dc,
192 const wxRect& rect,
081b3342 193 int flags = 0);
e4131985 194
7280c828 195 virtual void DrawComboBox(wxWindow* win,
081b3342
VZ
196 wxDC& dc,
197 const wxRect& rect,
198 int flags = 0);
e4131985 199
7280c828 200 virtual void DrawTextCtrl(wxWindow* win,
081b3342
VZ
201 wxDC& dc,
202 const wxRect& rect,
203 int flags = 0);
e4131985 204
6e6b532c 205 virtual void DrawRadioBitmap(wxWindow* win,
081b3342
VZ
206 wxDC& dc,
207 const wxRect& rect,
208 int flags = 0)
209 {
210 DoDrawButton(DFCS_BUTTONRADIO, win, dc, rect, flags);
211 }
e4131985 212
b50d93d1
VZ
213 virtual void DrawTitleBarBitmap(wxWindow *win,
214 wxDC& dc,
215 const wxRect& rect,
216 wxTitleBarButton button,
217 int flags = 0);
218
191e43fd 219 virtual wxSize GetCheckBoxSize(wxWindow *win);
e8759560 220
51c42fc5
VZ
221 virtual int GetHeaderButtonHeight(wxWindow *win);
222
9aebcb5e
VS
223 virtual int GetHeaderButtonMargin(wxWindow *win);
224
2eb10e2a 225private:
b50d93d1
VZ
226 // wrapper of DrawFrameControl()
227 void DoDrawFrameControl(UINT type,
228 UINT kind,
229 wxWindow *win,
230 wxDC& dc,
231 const wxRect& rect,
232 int flags);
233
081b3342
VZ
234 // common part of Draw{PushButton,CheckBox,RadioBitmap}(): wraps
235 // DrawFrameControl(DFC_BUTTON)
236 void DoDrawButton(UINT kind,
237 wxWindow *win,
238 wxDC& dc,
239 const wxRect& rect,
b50d93d1
VZ
240 int flags)
241 {
242 DoDrawFrameControl(DFC_BUTTON, kind, win, dc, rect, flags);
243 }
081b3342 244
c0c133e1 245 wxDECLARE_NO_COPY_CLASS(wxRendererMSW);
9c7f49f5
VZ
246};
247
8b97949e
VZ
248// ----------------------------------------------------------------------------
249// wxRendererXP: wxRendererNative implementation for Windows XP and later
250// ----------------------------------------------------------------------------
251
7cf3223a
VZ
252#if wxUSE_UXTHEME
253
5aac6f3f 254class wxRendererXP : public wxRendererMSWBase
8b97949e
VZ
255{
256public:
de4bf0b3 257 wxRendererXP() : wxRendererMSWBase(wxRendererMSW::Get()) { }
8b97949e
VZ
258
259 static wxRendererNative& Get();
260
c97c9952 261 virtual int DrawHeaderButton(wxWindow *win,
4b94ddc4
RD
262 wxDC& dc,
263 const wxRect& rect,
264 int flags = 0,
80752b57 265 wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE,
4b94ddc4 266 wxHeaderButtonParams* params = NULL);
f4322df6 267
9f93b45e
VZ
268 virtual void DrawTreeItemButton(wxWindow *win,
269 wxDC& dc,
270 const wxRect& rect,
271 int flags = 0);
8b97949e
VZ
272 virtual void DrawSplitterBorder(wxWindow *win,
273 wxDC& dc,
c4e6c15e
VZ
274 const wxRect& rect,
275 int flags = 0);
8b97949e
VZ
276 virtual void DrawSplitterSash(wxWindow *win,
277 wxDC& dc,
278 const wxSize& size,
279 wxCoord position,
c4e6c15e
VZ
280 wxOrientation orient,
281 int flags = 0);
7cf3223a
VZ
282 virtual void DrawComboBoxDropButton(wxWindow *win,
283 wxDC& dc,
284 const wxRect& rect,
285 int flags = 0);
90b903c2
WS
286 virtual void DrawCheckBox(wxWindow *win,
287 wxDC& dc,
288 const wxRect& rect,
6c9aaf7d
VZ
289 int flags = 0)
290 {
291 if ( !DoDrawXPButton(BP_CHECKBOX, win, dc, rect, flags) )
292 m_rendererNative.DrawCheckBox(win, dc, rect, flags);
293 }
9f93b45e 294
2209baae
RR
295 virtual void DrawPushButton(wxWindow *win,
296 wxDC& dc,
297 const wxRect& rect,
6c9aaf7d
VZ
298 int flags = 0)
299 {
300 if ( !DoDrawXPButton(BP_PUSHBUTTON, win, dc, rect, flags) )
301 m_rendererNative.DrawPushButton(win, dc, rect, flags);
302 }
2209baae 303
081b3342
VZ
304 virtual void DrawRadioBitmap(wxWindow *win,
305 wxDC& dc,
306 const wxRect& rect,
6c9aaf7d
VZ
307 int flags = 0)
308 {
309 if ( !DoDrawXPButton(BP_RADIOBUTTON, win, dc, rect, flags) )
310 m_rendererNative.DrawRadioBitmap(win, dc, rect, flags);
311 }
081b3342 312
b50d93d1
VZ
313 virtual void DrawTitleBarBitmap(wxWindow *win,
314 wxDC& dc,
315 const wxRect& rect,
316 wxTitleBarButton button,
317 int flags = 0);
318
9f93b45e 319 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
081b3342 320
8b97949e 321private:
b50d93d1
VZ
322 // wrapper around DrawThemeBackground() translating flags to NORMAL/HOT/
323 // PUSHED/DISABLED states (and so suitable for drawing anything
324 // button-like)
325 void DoDrawButtonLike(HTHEME htheme,
326 int part,
327 wxDC& dc,
328 const wxRect& rect,
329 int flags);
330
6c9aaf7d
VZ
331 // common part of DrawCheckBox(), DrawPushButton() and DrawRadioBitmap()
332 bool DoDrawXPButton(int kind,
333 wxWindow *win,
334 wxDC& dc,
335 const wxRect& rect,
336 int flags);
337
c0c133e1 338 wxDECLARE_NO_COPY_CLASS(wxRendererXP);
8b97949e
VZ
339};
340
7cf3223a
VZ
341#endif // wxUSE_UXTHEME
342
de4bf0b3
FM
343
344// ============================================================================
345// wxRendererMSWBase implementation
346// ============================================================================
347
348void wxRendererMSWBase::DrawFocusRect(wxWindow * WXUNUSED(win),
349 wxDC& dc,
350 const wxRect& rect,
351 int WXUNUSED(flags))
352{
353 RECT rc;
354 wxCopyRectToRECT(rect, rc);
355
942d5e2d 356 ::DrawFocusRect(GetHdcOf(dc.GetTempHDC()), &rc);
de4bf0b3
FM
357}
358
359void wxRendererMSWBase::DrawItemSelectionRect(wxWindow *win,
360 wxDC& dc,
361 const wxRect& rect,
362 int flags)
363{
364 wxBrush brush;
365 if ( flags & wxCONTROL_SELECTED )
366 {
367 if ( flags & wxCONTROL_FOCUSED )
368 {
369 brush = wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
370 }
371 else // !focused
372 {
373 brush = wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
374 }
375 }
376 else // !selected
377 {
378 brush = *wxTRANSPARENT_BRUSH;
379 }
380
381 dc.SetBrush(brush);
382 dc.SetPen(*wxTRANSPARENT_PEN);
383 dc.DrawRectangle( rect );
384
385 if ((flags & wxCONTROL_FOCUSED) && (flags & wxCONTROL_CURRENT))
386 DrawFocusRect( win, dc, rect, flags );
387}
388
389
9c7f49f5 390// ============================================================================
8b97949e 391// wxRendererNative and wxRendererMSW implementation
9c7f49f5
VZ
392// ============================================================================
393
394/* static */
f0244295 395wxRendererNative& wxRendererNative::GetDefault()
8b97949e 396{
7cf3223a 397#if wxUSE_UXTHEME
8b97949e 398 wxUxThemeEngine *themeEngine = wxUxThemeEngine::Get();
7cf3223a
VZ
399 if ( themeEngine && themeEngine->IsAppThemed() )
400 return wxRendererXP::Get();
401#endif // wxUSE_UXTHEME
402
403 return wxRendererMSW::Get();
8b97949e
VZ
404}
405
406/* static */
407wxRendererNative& wxRendererMSW::Get()
9c7f49f5
VZ
408{
409 static wxRendererMSW s_rendererMSW;
410
411 return s_rendererMSW;
412}
413
7402677a
VZ
414void
415wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win),
416 wxDC& dc,
417 const wxRect& rect,
418 int flags)
419{
066bd251
RD
420 wxRect adjustedRect = applyGDIPlusTransformsToRect(dc, rect);
421
7402677a 422 RECT r;
066bd251 423 wxCopyRectToRECT(adjustedRect, r);
7402677a
VZ
424
425 int style = DFCS_SCROLLCOMBOBOX;
426 if ( flags & wxCONTROL_DISABLED )
427 style |= DFCS_INACTIVE;
428 if ( flags & wxCONTROL_PRESSED )
7cf3223a 429 style |= DFCS_PUSHED | DFCS_FLAT;
7402677a 430
942d5e2d 431 ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, DFC_SCROLL, style);
7402677a
VZ
432}
433
59ee63e9 434void
b50d93d1
VZ
435wxRendererMSW::DoDrawFrameControl(UINT type,
436 UINT kind,
437 wxWindow * WXUNUSED(win),
438 wxDC& dc,
439 const wxRect& rect,
440 int flags)
59ee63e9 441{
066bd251
RD
442 wxRect adjustedRect = applyGDIPlusTransformsToRect(dc, rect);
443
59ee63e9 444 RECT r;
066bd251 445 wxCopyRectToRECT(adjustedRect, r);
59ee63e9 446
081b3342 447 int style = kind;
59ee63e9
VZ
448 if ( flags & wxCONTROL_CHECKED )
449 style |= DFCS_CHECKED;
450 if ( flags & wxCONTROL_DISABLED )
451 style |= DFCS_INACTIVE;
8a461249
VZ
452 if ( flags & wxCONTROL_FLAT )
453 style |= DFCS_MONO;
59ee63e9
VZ
454 if ( flags & wxCONTROL_PRESSED )
455 style |= DFCS_PUSHED;
456 if ( flags & wxCONTROL_CURRENT )
457 style |= DFCS_HOT;
458
b50d93d1 459 ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, type, style);
59ee63e9
VZ
460}
461
2209baae 462void
081b3342 463wxRendererMSW::DrawPushButton(wxWindow *win,
2209baae 464 wxDC& dc,
f2ea4255 465 const wxRect& rectOrig,
2209baae
RR
466 int flags)
467{
f2ea4255 468 wxRect rect(rectOrig);
f2ea4255
VZ
469 if ( flags & wxCONTROL_ISDEFAULT )
470 {
471 // DrawFrameControl() doesn't seem to support default buttons so we
472 // have to draw the border ourselves
473 wxDCPenChanger pen(dc, *wxBLACK_PEN);
474 wxDCBrushChanger brush(dc, *wxTRANSPARENT_BRUSH);
475 dc.DrawRectangle(rect);
844b9f5f 476 rect.Deflate(1);
f2ea4255
VZ
477 }
478
081b3342 479 DoDrawButton(DFCS_BUTTONPUSH, win, dc, rect, flags);
2209baae
RR
480}
481
b50d93d1
VZ
482void
483wxRendererMSW::DrawTitleBarBitmap(wxWindow *win,
484 wxDC& dc,
485 const wxRect& rect,
486 wxTitleBarButton button,
487 int flags)
488{
489 UINT kind;
490 switch ( button )
491 {
492 case wxTITLEBAR_BUTTON_CLOSE:
493 kind = DFCS_CAPTIONCLOSE;
494 break;
495
496 case wxTITLEBAR_BUTTON_MAXIMIZE:
497 kind = DFCS_CAPTIONMAX;
498 break;
499
500 case wxTITLEBAR_BUTTON_ICONIZE:
501 kind = DFCS_CAPTIONMIN;
502 break;
503
504 case wxTITLEBAR_BUTTON_RESTORE:
505 kind = DFCS_CAPTIONRESTORE;
506 break;
507
508 case wxTITLEBAR_BUTTON_HELP:
509 kind = DFCS_CAPTIONHELP;
510 break;
511
512 default:
513 wxFAIL_MSG( "unsupported title bar button" );
514 return;
515 }
516
517 DoDrawFrameControl(DFC_CAPTION, kind, win, dc, rect, flags);
518}
519
191e43fd 520wxSize wxRendererMSW::GetCheckBoxSize(wxWindow * WXUNUSED(win))
e8759560
VZ
521{
522 return wxSize(::GetSystemMetrics(SM_CXMENUCHECK),
523 ::GetSystemMetrics(SM_CYMENUCHECK));
524}
525
51c42fc5
VZ
526int wxRendererMSW::GetHeaderButtonHeight(wxWindow * WXUNUSED(win))
527{
528 // some "reasonable" value returned in case of error, it doesn't really
529 // correspond to anything but it's better than returning 0
530 static const int DEFAULT_HEIGHT = 20;
531
532
533 // create a temporary header window just to get its geometry
a268f4b7 534 HWND hwndHeader = ::CreateWindow(WC_HEADER, NULL, 0,
51c42fc5
VZ
535 0, 0, 0, 0, NULL, NULL, NULL, NULL);
536 if ( !hwndHeader )
537 return DEFAULT_HEIGHT;
538
539 wxON_BLOCK_EXIT1( ::DestroyWindow, hwndHeader );
540
541 // initialize the struct filled with the values by Header_Layout()
542 RECT parentRect = { 0, 0, 100, 100 };
11fa6e63 543 WINDOWPOS wp = { 0, 0, 0, 0, 0, 0, 0 };
51c42fc5
VZ
544 HDLAYOUT hdl = { &parentRect, &wp };
545
546 return Header_Layout(hwndHeader, &hdl) ? wp.cy : DEFAULT_HEIGHT;
547}
548
9aebcb5e
VS
549int wxRendererMSW::GetHeaderButtonMargin(wxWindow *WXUNUSED(win))
550{
551 return 10;
552}
553
e4131985
KO
554// Uses the theme to draw the border and fill for something like a wxTextCtrl
555void wxRendererMSW::DrawTextCtrl(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
556{
557 wxColour fill;
558 wxColour bdr;
559 COLORREF cref;
7280c828 560
e4131985
KO
561#if wxUSE_UXTHEME
562 wxUxThemeHandle hTheme(win, L"EDIT");
563 if (hTheme)
564 {
565 wxUxThemeEngine::Get()->GetThemeColor(hTheme, EP_EDITTEXT,
566 ETS_NORMAL, TMT_FILLCOLOR, &cref);
567 fill = wxRGBToColour(cref);
568
569 int etsState;
570 if ( flags & wxCONTROL_DISABLED )
571 etsState = ETS_DISABLED;
572 else
573 etsState = ETS_NORMAL;
7280c828 574
e4131985
KO
575 wxUxThemeEngine::Get()->GetThemeColor(hTheme, EP_EDITTEXT,
576 etsState, TMT_BORDERCOLOR, &cref);
7280c828 577 bdr = wxRGBToColour(cref);
e4131985
KO
578 }
579 else
580#endif
581 {
582 fill = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
583 bdr = *wxBLACK;
584 }
7280c828 585
e4131985
KO
586 dc.SetPen( bdr );
587 dc.SetBrush( fill );
588 dc.DrawRectangle(rect);
589}
590
591
081b3342 592// Draw the equivalent of a wxComboBox
e4131985
KO
593void wxRendererMSW::DrawComboBox(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
594{
595 // Draw the main part of the control same as TextCtrl
7280c828
VZ
596 DrawTextCtrl(win, dc, rect, flags);
597
e4131985
KO
598 // Draw the button inside the border, on the right side
599 wxRect br(rect);
600 br.height -= 2;
601 br.x += br.width - br.height - 1;
602 br.width = br.height;
603 br.y += 1;
604
605 DrawComboBoxDropButton(win, dc, br, flags);
606}
607
608
609void wxRendererMSW::DrawChoice(wxWindow* win, wxDC& dc,
610 const wxRect& rect, int flags)
611{
612 DrawComboBox(win, dc, rect, flags);
613}
614
8b97949e
VZ
615// ============================================================================
616// wxRendererXP implementation
617// ============================================================================
618
7cf3223a
VZ
619#if wxUSE_UXTHEME
620
8b97949e
VZ
621/* static */
622wxRendererNative& wxRendererXP::Get()
623{
624 static wxRendererXP s_rendererXP;
625
626 return s_rendererXP;
627}
628
7cf3223a
VZ
629// NOTE: There is no guarantee that the button drawn fills the entire rect (XP
630// default theme, for example), so the caller should have cleared button's
631// background before this call. This is quite likely a wxMSW-specific thing.
632void
633wxRendererXP::DrawComboBoxDropButton(wxWindow * win,
634 wxDC& dc,
635 const wxRect& rect,
636 int flags)
637{
638 wxUxThemeHandle hTheme(win, L"COMBOBOX");
9f93b45e 639 if ( !hTheme )
7cf3223a 640 {
9f93b45e
VZ
641 m_rendererNative.DrawComboBoxDropButton(win, dc, rect, flags);
642 return;
643 }
644
066bd251
RD
645 wxRect adjustedRect = applyGDIPlusTransformsToRect(dc, rect);
646
9f93b45e 647 RECT r;
066bd251 648 wxCopyRectToRECT(adjustedRect, r);
7cf3223a 649
9f93b45e
VZ
650 int state;
651 if ( flags & wxCONTROL_PRESSED )
652 state = CBXS_PRESSED;
653 else if ( flags & wxCONTROL_CURRENT )
654 state = CBXS_HOT;
655 else if ( flags & wxCONTROL_DISABLED )
656 state = CBXS_DISABLED;
657 else
658 state = CBXS_NORMAL;
659
660 wxUxThemeEngine::Get()->DrawThemeBackground
661 (
662 hTheme,
942d5e2d 663 GetHdcOf(dc.GetTempHDC()),
9f93b45e
VZ
664 CP_DROPDOWNBUTTON,
665 state,
666 &r,
667 NULL
668 );
669
670}
671
c97c9952 672int
9f93b45e
VZ
673wxRendererXP::DrawHeaderButton(wxWindow *win,
674 wxDC& dc,
675 const wxRect& rect,
4b94ddc4 676 int flags,
80752b57 677 wxHeaderSortIconType sortArrow,
4b94ddc4 678 wxHeaderButtonParams* params)
9f93b45e
VZ
679{
680 wxUxThemeHandle hTheme(win, L"HEADER");
681 if ( !hTheme )
682 {
c97c9952 683 return m_rendererNative.DrawHeaderButton(win, dc, rect, flags, sortArrow, params);
7cf3223a 684 }
9f93b45e 685
066bd251
RD
686 wxRect adjustedRect = applyGDIPlusTransformsToRect(dc, rect);
687
9f93b45e 688 RECT r;
066bd251 689 wxCopyRectToRECT(adjustedRect, r);
9f93b45e
VZ
690
691 int state;
692 if ( flags & wxCONTROL_PRESSED )
693 state = HIS_PRESSED;
694 else if ( flags & wxCONTROL_CURRENT )
695 state = HIS_HOT;
696 else
697 state = HIS_NORMAL;
698 wxUxThemeEngine::Get()->DrawThemeBackground
699 (
700 hTheme,
942d5e2d 701 GetHdcOf(dc.GetTempHDC()),
9f93b45e
VZ
702 HP_HEADERITEM,
703 state,
704 &r,
705 NULL
706 );
4b94ddc4
RD
707
708 // NOTE: Using the theme to draw HP_HEADERSORTARROW doesn't do anything.
709 // Why? If this can be fixed then draw the sort arrows using the theme
710 // and then clear those flags before calling DrawHeaderButtonContents.
f4322df6 711
4b94ddc4 712 // Add any extras that are specified in flags and params
c97c9952 713 return DrawHeaderButtonContents(win, dc, rect, flags, sortArrow, params);
9f93b45e
VZ
714}
715
4b94ddc4 716
9f93b45e
VZ
717void
718wxRendererXP::DrawTreeItemButton(wxWindow *win,
719 wxDC& dc,
720 const wxRect& rect,
721 int flags)
722{
723 wxUxThemeHandle hTheme(win, L"TREEVIEW");
724 if ( !hTheme )
725 {
726 m_rendererNative.DrawTreeItemButton(win, dc, rect, flags);
727 return;
728 }
729
066bd251
RD
730 wxRect adjustedRect = applyGDIPlusTransformsToRect(dc, rect);
731
9f93b45e 732 RECT r;
066bd251 733 wxCopyRectToRECT(adjustedRect, r);
9f93b45e
VZ
734
735 int state = flags & wxCONTROL_EXPANDED ? GLPS_OPENED : GLPS_CLOSED;
736 wxUxThemeEngine::Get()->DrawThemeBackground
737 (
738 hTheme,
942d5e2d 739 GetHdcOf(dc.GetTempHDC()),
9f93b45e
VZ
740 TVP_GLYPH,
741 state,
742 &r,
743 NULL
744 );
745}
746
6c9aaf7d
VZ
747bool
748wxRendererXP::DoDrawXPButton(int kind,
749 wxWindow *win,
750 wxDC& dc,
751 const wxRect& rect,
752 int flags)
9f93b45e
VZ
753{
754 wxUxThemeHandle hTheme(win, L"BUTTON");
755 if ( !hTheme )
6c9aaf7d 756 return false;
9f93b45e 757
b50d93d1 758 DoDrawButtonLike(hTheme, kind, dc, rect, flags);
59ee63e9 759
b50d93d1
VZ
760 return true;
761}
9f93b45e 762
b50d93d1
VZ
763void
764wxRendererXP::DoDrawButtonLike(HTHEME htheme,
765 int part,
766 wxDC& dc,
767 const wxRect& rect,
768 int flags)
769{
066bd251
RD
770 wxRect adjustedRect = applyGDIPlusTransformsToRect(dc, rect);
771
b50d93d1 772 RECT r;
066bd251 773 wxCopyRectToRECT(adjustedRect, r);
7cf3223a 774
b50d93d1
VZ
775 // the base state is always 1, whether it is PBS_NORMAL,
776 // {CBS,RBS}_UNCHECKEDNORMAL or CBS_NORMAL
777 int state = 1;
081b3342 778
6c9aaf7d
VZ
779 // XBS_XXX is followed by XBX_XXXHOT, then XBS_XXXPRESSED and DISABLED
780 enum
781 {
782 NORMAL_OFFSET,
783 HOT_OFFSET,
784 PRESSED_OFFSET,
785 DISABLED_OFFSET,
786 STATES_COUNT
787 };
081b3342 788
6c9aaf7d
VZ
789 // in both RBS_ and CBS_ enums CHECKED elements are offset by 4 from base
790 // (UNCHECKED) ones and MIXED are offset by 4 again as there are all states
791 // from the above enum in between them
081b3342 792 if ( flags & wxCONTROL_CHECKED )
6c9aaf7d 793 state += STATES_COUNT;
081b3342 794 else if ( flags & wxCONTROL_UNDETERMINED )
6c9aaf7d 795 state += 2*STATES_COUNT;
081b3342 796
6c9aaf7d
VZ
797 if ( flags & wxCONTROL_DISABLED )
798 state += DISABLED_OFFSET;
081b3342 799 else if ( flags & wxCONTROL_PRESSED )
6c9aaf7d 800 state += PRESSED_OFFSET;
2209baae 801 else if ( flags & wxCONTROL_CURRENT )
6c9aaf7d
VZ
802 state += HOT_OFFSET;
803 // wxCONTROL_ISDEFAULT flag is only valid for push buttons
b50d93d1 804 else if ( part == BP_PUSHBUTTON && (flags & wxCONTROL_ISDEFAULT) )
2209baae 805 state = PBS_DEFAULTED;
2209baae
RR
806
807 wxUxThemeEngine::Get()->DrawThemeBackground
808 (
b50d93d1 809 htheme,
942d5e2d 810 GetHdcOf(dc.GetTempHDC()),
b50d93d1 811 part,
2209baae
RR
812 state,
813 &r,
814 NULL
815 );
b50d93d1 816}
2209baae 817
b50d93d1
VZ
818void
819wxRendererXP::DrawTitleBarBitmap(wxWindow *win,
820 wxDC& dc,
821 const wxRect& rect,
822 wxTitleBarButton button,
823 int flags)
824{
825 wxUxThemeHandle hTheme(win, L"WINDOW");
826 if ( !hTheme )
827 {
828 m_rendererNative.DrawTitleBarBitmap(win, dc, rect, button, flags);
829 return;
830 }
831
832 int part;
833 switch ( button )
834 {
835 case wxTITLEBAR_BUTTON_CLOSE:
836 part = WP_CLOSEBUTTON;
837 break;
838
839 case wxTITLEBAR_BUTTON_MAXIMIZE:
840 part = WP_MAXBUTTON;
841 break;
842
843 case wxTITLEBAR_BUTTON_ICONIZE:
844 part = WP_MINBUTTON;
845 break;
846
847 case wxTITLEBAR_BUTTON_RESTORE:
848 part = WP_RESTOREBUTTON;
849 break;
850
851 case wxTITLEBAR_BUTTON_HELP:
852 part = WP_HELPBUTTON;
853 break;
854
855 default:
856 wxFAIL_MSG( "unsupported title bar button" );
857 return;
858 }
859
860 DoDrawButtonLike(hTheme, part, dc, rect, flags);
6c9aaf7d 861}
a9fdf824 862
8b97949e
VZ
863// ----------------------------------------------------------------------------
864// splitter drawing
865// ----------------------------------------------------------------------------
866
867// the width of the sash: this is the same as used by Explorer...
868static const wxCoord SASH_WIDTH = 4;
869
c4e6c15e 870wxSplitterRenderParams
3c2544bb 871wxRendererXP::GetSplitterParams(const wxWindow * win)
8b97949e 872{
9f93b45e 873 if ( win->HasFlag(wxSP_NO_XP_THEME) )
3c2544bb
JS
874 return m_rendererNative.GetSplitterParams(win);
875 else
876 return wxSplitterRenderParams(SASH_WIDTH, 0, false);
8b97949e
VZ
877}
878
879void
3c2544bb
JS
880wxRendererXP::DrawSplitterBorder(wxWindow * win,
881 wxDC& dc,
882 const wxRect& rect,
883 int flags)
8b97949e 884{
9f93b45e 885 if ( win->HasFlag(wxSP_NO_XP_THEME) )
3c2544bb
JS
886 {
887 m_rendererNative.DrawSplitterBorder(win, dc, rect, flags);
888 }
8b97949e
VZ
889}
890
891void
892wxRendererXP::DrawSplitterSash(wxWindow *win,
893 wxDC& dc,
894 const wxSize& size,
895 wxCoord position,
c4e6c15e 896 wxOrientation orient,
3c2544bb 897 int flags)
8b97949e 898{
6421119d 899 if ( !win->HasFlag(wxSP_NO_XP_THEME) )
8b97949e 900 {
fe404d1a
JS
901 dc.SetPen(*wxTRANSPARENT_PEN);
902 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
903 if ( orient == wxVERTICAL )
8b97949e 904 {
fe404d1a 905 dc.DrawRectangle(position, 0, SASH_WIDTH, size.y);
8b97949e 906 }
fe404d1a
JS
907 else // wxHORIZONTAL
908 {
909 dc.DrawRectangle(0, position, size.x, SASH_WIDTH);
910 }
911
912 return;
8b97949e 913 }
6421119d
VZ
914
915 m_rendererNative.DrawSplitterSash(win, dc, size, position, orient, flags);
8b97949e
VZ
916}
917
7cf3223a 918#endif // wxUSE_UXTHEME