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