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