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