Applied patch [ 1389709 ] XP theme support for DrawHeaderButton, DrawTreeItemButton
[wxWidgets.git] / src / msw / renderer.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #endif //WX_PRECOMP
32
33 #include "wx/splitter.h"
34 #include "wx/renderer.h"
35 #include "wx/settings.h"
36 #include "wx/msw/uxtheme.h"
37 #include "wx/msw/private.h"
38
39 // tmschema.h is in Win32 Platform SDK and might not be available with earlier
40 // compilers
41 #ifndef CP_DROPDOWNBUTTON
42 #define CP_DROPDOWNBUTTON 1
43
44 #define CBXS_NORMAL 1
45 #define CBXS_HOT 2
46 #define CBXS_PRESSED 3
47 #define CBXS_DISABLED 4
48
49 #define TVP_GLYPH 2
50
51 #define GLPS_CLOSED 1
52 #define GLPS_OPENED 2
53
54 #define HP_HEADERITEM 1
55
56 #define HIS_NORMAL 1
57 #define HIS_HOT 2
58 #define HIS_PRESSED 3
59 #endif
60
61 // ----------------------------------------------------------------------------
62 // wxRendererMSW: wxRendererNative implementation for "old" Win32 systems
63 // ----------------------------------------------------------------------------
64
65 class WXDLLEXPORT wxRendererMSW : public wxDelegateRendererNative
66 {
67 public:
68 wxRendererMSW() { }
69
70 static wxRendererNative& Get();
71
72 virtual void DrawComboBoxDropButton(wxWindow *win,
73 wxDC& dc,
74 const wxRect& rect,
75 int flags = 0);
76
77 private:
78 DECLARE_NO_COPY_CLASS(wxRendererMSW)
79 };
80
81 // ----------------------------------------------------------------------------
82 // wxRendererXP: wxRendererNative implementation for Windows XP and later
83 // ----------------------------------------------------------------------------
84
85 #if wxUSE_UXTHEME
86
87 class WXDLLEXPORT wxRendererXP : public wxDelegateRendererNative
88 {
89 public:
90 wxRendererXP() : wxDelegateRendererNative(wxRendererMSW::Get()) { }
91
92 static wxRendererNative& Get();
93
94 virtual void DrawSplitterBorder(wxWindow *win,
95 wxDC& dc,
96 const wxRect& rect,
97 int flags = 0);
98 virtual void DrawSplitterSash(wxWindow *win,
99 wxDC& dc,
100 const wxSize& size,
101 wxCoord position,
102 wxOrientation orient,
103 int flags = 0);
104
105 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
106
107 virtual void DrawComboBoxDropButton(wxWindow *win,
108 wxDC& dc,
109 const wxRect& rect,
110 int flags = 0);
111 virtual void DrawTreeItemButton(wxWindow *win,
112 wxDC& dc,
113 const wxRect& rect,
114 int flags = 0);
115 virtual void DrawHeaderButton(wxWindow *win,
116 wxDC& dc,
117 const wxRect &rect,
118 int flags=0);
119 private:
120 DECLARE_NO_COPY_CLASS(wxRendererXP)
121 };
122
123 #endif // wxUSE_UXTHEME
124
125 // ============================================================================
126 // wxRendererNative and wxRendererMSW implementation
127 // ============================================================================
128
129 /* static */
130 wxRendererNative& wxRendererNative::GetDefault()
131 {
132 #if wxUSE_UXTHEME
133 wxUxThemeEngine *themeEngine = wxUxThemeEngine::Get();
134 if ( themeEngine && themeEngine->IsAppThemed() )
135 return wxRendererXP::Get();
136 #endif // wxUSE_UXTHEME
137
138 return wxRendererMSW::Get();
139 }
140
141 /* static */
142 wxRendererNative& wxRendererMSW::Get()
143 {
144 static wxRendererMSW s_rendererMSW;
145
146 return s_rendererMSW;
147 }
148
149 #if defined(__WXWINCE__) && !defined(DFCS_FLAT)
150 #define DFCS_FLAT 0
151 #endif
152
153 void
154 wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win),
155 wxDC& dc,
156 const wxRect& rect,
157 int flags)
158 {
159 RECT r;
160 r.left = rect.GetLeft();
161 r.top = rect.GetTop();
162 r.bottom = rect.y + rect.height;
163 r.right = rect.x + rect.width;
164
165 int style = DFCS_SCROLLCOMBOBOX;
166 if ( flags & wxCONTROL_DISABLED )
167 style |= DFCS_INACTIVE;
168 if ( flags & wxCONTROL_PRESSED )
169 style |= DFCS_PUSHED | DFCS_FLAT;
170
171 ::DrawFrameControl(GetHdcOf(dc), &r, DFC_SCROLL, style);
172 }
173
174 // ============================================================================
175 // wxRendererXP implementation
176 // ============================================================================
177
178 #if wxUSE_UXTHEME
179
180 /* static */
181 wxRendererNative& wxRendererXP::Get()
182 {
183 static wxRendererXP s_rendererXP;
184
185 return s_rendererXP;
186 }
187
188 // NOTE: There is no guarantee that the button drawn fills the entire rect (XP
189 // default theme, for example), so the caller should have cleared button's
190 // background before this call. This is quite likely a wxMSW-specific thing.
191 void
192 wxRendererXP::DrawComboBoxDropButton(wxWindow * win,
193 wxDC& dc,
194 const wxRect& rect,
195 int flags)
196 {
197 wxUxThemeHandle hTheme(win, L"COMBOBOX");
198 if ( hTheme )
199 {
200 RECT r;
201 r.left = rect.x;
202 r.top = rect.y;
203 r.right = rect.x + rect.width;
204 r.bottom = rect.y + rect.height;
205
206 int state;
207 if ( flags & wxCONTROL_PRESSED )
208 state = CBXS_PRESSED;
209 else if ( flags & wxCONTROL_CURRENT )
210 state = CBXS_HOT;
211 else if ( flags & wxCONTROL_DISABLED )
212 state = CBXS_DISABLED;
213 else
214 state = CBXS_NORMAL;
215
216 wxUxThemeEngine::Get()->DrawThemeBackground
217 (
218 hTheme,
219 (HDC) dc.GetHDC(),
220 CP_DROPDOWNBUTTON,
221 state,
222 &r,
223 NULL
224 );
225
226 }
227 }
228
229 // ----------------------------------------------------------------------------
230 // splitter drawing
231 // ----------------------------------------------------------------------------
232
233 // the width of the sash: this is the same as used by Explorer...
234 static const wxCoord SASH_WIDTH = 4;
235
236 wxSplitterRenderParams
237 wxRendererXP::GetSplitterParams(const wxWindow * win)
238 {
239 if (win->GetWindowStyle() & wxSP_NO_XP_THEME)
240 return m_rendererNative.GetSplitterParams(win);
241 else
242 return wxSplitterRenderParams(SASH_WIDTH, 0, false);
243 }
244
245 void
246 wxRendererXP::DrawSplitterBorder(wxWindow * win,
247 wxDC& dc,
248 const wxRect& rect,
249 int flags)
250 {
251 if (win->GetWindowStyle() & wxSP_NO_XP_THEME)
252 {
253 m_rendererNative.DrawSplitterBorder(win, dc, rect, flags);
254 }
255 }
256
257 void
258 wxRendererXP::DrawSplitterSash(wxWindow *win,
259 wxDC& dc,
260 const wxSize& size,
261 wxCoord position,
262 wxOrientation orient,
263 int flags)
264 {
265 if ( !win->HasFlag(wxSP_NO_XP_THEME) )
266 {
267 dc.SetPen(*wxTRANSPARENT_PEN);
268 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
269 if ( orient == wxVERTICAL )
270 {
271 dc.DrawRectangle(position, 0, SASH_WIDTH, size.y);
272 }
273 else // wxHORIZONTAL
274 {
275 dc.DrawRectangle(0, position, size.x, SASH_WIDTH);
276 }
277
278 return;
279 }
280
281 m_rendererNative.DrawSplitterSash(win, dc, size, position, orient, flags);
282 }
283
284 void
285 wxRendererXP::DrawTreeItemButton(wxWindow *win,
286 wxDC &dc,
287 const wxRect &rect,
288 int flags)
289 {
290 wxUxThemeHandle hTheme(win, L"TREEVIEW");
291 RECT r;
292 r.left = rect.x;
293 r.top = rect.y;
294 r.right = rect.x + rect.width;
295 r.bottom = rect.y + rect.height;
296 int state = (flags & wxCONTROL_EXPANDED) ? GLPS_OPENED : GLPS_CLOSED;
297 wxUxThemeEngine::Get()->DrawThemeBackground
298 (
299 hTheme,
300 (HDC) dc.GetHDC(),
301 TVP_GLYPH,
302 state,
303 &r,
304 NULL
305 );
306 }
307
308 void
309 wxRendererXP::DrawHeaderButton(wxWindow *win,
310 wxDC &dc,
311 const wxRect &rect,
312 int flags)
313 {
314 wxUxThemeHandle hTheme(win, L"HEADER");
315 RECT r;
316 r.left = rect.x;
317 r.top = rect.y;
318 r.right = rect.x + rect.width;
319 r.bottom = rect.y + rect.height;
320 int state;
321 if ( flags & wxCONTROL_PRESSED )
322 state = HIS_PRESSED;
323 else if ( flags & wxCONTROL_CURRENT )
324 state = HIS_HOT;
325 else
326 state = HIS_NORMAL;
327 wxUxThemeEngine::Get()->DrawThemeBackground
328 (
329 hTheme,
330 (HDC) dc.GetHDC(),
331 HP_HEADERITEM,
332 state,
333 &r,
334 NULL
335 );
336 }
337
338 #endif // wxUSE_UXTHEME
339