]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/renderer.cpp
[ 1560860 ] wxComboCtrl EVT_TEXT filtering.
[wxWidgets.git] / src / msw / renderer.cpp
... / ...
CommitLineData
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/splitter.h"
35#include "wx/renderer.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 BP_PUSHBUTTON 1
43 #define BP_CHECKBOX 3
44 #define CBS_UNCHECKEDNORMAL 1
45 #define CBS_CHECKEDNORMAL (CBS_UNCHECKEDNORMAL + 4)
46 #define CBS_MIXEDNORMAL (CBS_CHECKEDNORMAL + 4)
47
48 #define PBS_NORMAL 1
49 #define PBS_HOT 2
50 #define PBS_PRESSED 3
51 #define PBS_DISABLED 4
52 #define PBS_DEFAULTED 5
53
54 #define CP_DROPDOWNBUTTON 1
55
56 #define CBXS_NORMAL 1
57 #define CBXS_HOT 2
58 #define CBXS_PRESSED 3
59 #define CBXS_DISABLED 4
60
61 #define TVP_GLYPH 2
62
63 #define GLPS_CLOSED 1
64 #define GLPS_OPENED 2
65
66 #define HP_HEADERITEM 1
67
68 #define HIS_NORMAL 1
69 #define HIS_HOT 2
70 #define HIS_PRESSED 3
71
72 #define TMT_HEIGHT 2417
73
74 #define HP_HEADERSORTARROW 4
75 #define HSAS_SORTEDUP 1
76 #define HSAS_SORTEDDOWN 2
77#endif
78
79#if defined(__WXWINCE__) && !defined(DFCS_FLAT)
80 #define DFCS_FLAT 0
81#endif
82
83// ----------------------------------------------------------------------------
84// wxRendererMSW: wxRendererNative implementation for "old" Win32 systems
85// ----------------------------------------------------------------------------
86
87class WXDLLEXPORT wxRendererMSW : public wxDelegateRendererNative
88{
89public:
90 wxRendererMSW() { }
91
92 static wxRendererNative& Get();
93
94 virtual void DrawComboBoxDropButton(wxWindow *win,
95 wxDC& dc,
96 const wxRect& rect,
97 int flags = 0);
98
99 virtual void DrawPushButton(wxWindow *win,
100 wxDC& dc,
101 const wxRect& rect,
102 int flags = 0);
103
104private:
105 DECLARE_NO_COPY_CLASS(wxRendererMSW)
106};
107
108// ----------------------------------------------------------------------------
109// wxRendererXP: wxRendererNative implementation for Windows XP and later
110// ----------------------------------------------------------------------------
111
112#if wxUSE_UXTHEME
113
114class WXDLLEXPORT wxRendererXP : public wxDelegateRendererNative
115{
116public:
117 wxRendererXP() : wxDelegateRendererNative(wxRendererMSW::Get()) { }
118
119 static wxRendererNative& Get();
120
121 virtual void DrawHeaderButton(wxWindow *win,
122 wxDC& dc,
123 const wxRect& rect,
124 int flags = 0,
125 wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE,
126 wxHeaderButtonParams* params = NULL);
127 virtual int GetHeaderButtonHeight(wxWindow *win);
128
129 virtual void DrawTreeItemButton(wxWindow *win,
130 wxDC& dc,
131 const wxRect& rect,
132 int flags = 0);
133 virtual void DrawSplitterBorder(wxWindow *win,
134 wxDC& dc,
135 const wxRect& rect,
136 int flags = 0);
137 virtual void DrawSplitterSash(wxWindow *win,
138 wxDC& dc,
139 const wxSize& size,
140 wxCoord position,
141 wxOrientation orient,
142 int flags = 0);
143 virtual void DrawComboBoxDropButton(wxWindow *win,
144 wxDC& dc,
145 const wxRect& rect,
146 int flags = 0);
147 virtual void DrawCheckBox(wxWindow *win,
148 wxDC& dc,
149 const wxRect& rect,
150 int flags = 0);
151
152 virtual void DrawPushButton(wxWindow *win,
153 wxDC& dc,
154 const wxRect& rect,
155 int flags = 0);
156
157 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
158private:
159 DECLARE_NO_COPY_CLASS(wxRendererXP)
160};
161
162#endif // wxUSE_UXTHEME
163
164// ============================================================================
165// wxRendererNative and wxRendererMSW implementation
166// ============================================================================
167
168/* static */
169wxRendererNative& wxRendererNative::GetDefault()
170{
171#if wxUSE_UXTHEME
172 wxUxThemeEngine *themeEngine = wxUxThemeEngine::Get();
173 if ( themeEngine && themeEngine->IsAppThemed() )
174 return wxRendererXP::Get();
175#endif // wxUSE_UXTHEME
176
177 return wxRendererMSW::Get();
178}
179
180/* static */
181wxRendererNative& wxRendererMSW::Get()
182{
183 static wxRendererMSW s_rendererMSW;
184
185 return s_rendererMSW;
186}
187
188void
189wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win),
190 wxDC& dc,
191 const wxRect& rect,
192 int flags)
193{
194 RECT r;
195 r.left = rect.GetLeft();
196 r.top = rect.GetTop();
197 r.bottom = rect.y + rect.height;
198 r.right = rect.x + rect.width;
199
200 int style = DFCS_SCROLLCOMBOBOX;
201 if ( flags & wxCONTROL_DISABLED )
202 style |= DFCS_INACTIVE;
203 if ( flags & wxCONTROL_PRESSED )
204 style |= DFCS_PUSHED | DFCS_FLAT;
205
206 ::DrawFrameControl(GetHdcOf(dc), &r, DFC_SCROLL, style);
207}
208
209void
210wxRendererMSW::DrawPushButton(wxWindow * WXUNUSED(win),
211 wxDC& dc,
212 const wxRect& rect,
213 int flags)
214{
215 RECT r;
216 r.left = rect.GetLeft();
217 r.top = rect.GetTop();
218 r.bottom = rect.y + rect.height;
219 r.right = rect.x + rect.width;
220
221 int style = DFCS_BUTTONPUSH;
222 if ( flags & wxCONTROL_DISABLED )
223 style |= DFCS_INACTIVE;
224 if ( flags & wxCONTROL_PRESSED )
225 style |= DFCS_PUSHED | DFCS_FLAT;
226
227 ::DrawFrameControl(GetHdcOf(dc), &r, DFC_BUTTON, style);
228}
229
230// ============================================================================
231// wxRendererXP implementation
232// ============================================================================
233
234#if wxUSE_UXTHEME
235
236/* static */
237wxRendererNative& wxRendererXP::Get()
238{
239 static wxRendererXP s_rendererXP;
240
241 return s_rendererXP;
242}
243
244// NOTE: There is no guarantee that the button drawn fills the entire rect (XP
245// default theme, for example), so the caller should have cleared button's
246// background before this call. This is quite likely a wxMSW-specific thing.
247void
248wxRendererXP::DrawComboBoxDropButton(wxWindow * win,
249 wxDC& dc,
250 const wxRect& rect,
251 int flags)
252{
253 wxUxThemeHandle hTheme(win, L"COMBOBOX");
254 if ( !hTheme )
255 {
256 m_rendererNative.DrawComboBoxDropButton(win, dc, rect, flags);
257 return;
258 }
259
260 RECT r;
261 wxCopyRectToRECT(rect, r);
262
263 int state;
264 if ( flags & wxCONTROL_PRESSED )
265 state = CBXS_PRESSED;
266 else if ( flags & wxCONTROL_CURRENT )
267 state = CBXS_HOT;
268 else if ( flags & wxCONTROL_DISABLED )
269 state = CBXS_DISABLED;
270 else
271 state = CBXS_NORMAL;
272
273 wxUxThemeEngine::Get()->DrawThemeBackground
274 (
275 hTheme,
276 GetHdcOf(dc),
277 CP_DROPDOWNBUTTON,
278 state,
279 &r,
280 NULL
281 );
282
283}
284
285void
286wxRendererXP::DrawHeaderButton(wxWindow *win,
287 wxDC& dc,
288 const wxRect& rect,
289 int flags,
290 wxHeaderSortIconType sortArrow,
291 wxHeaderButtonParams* params)
292{
293 wxUxThemeHandle hTheme(win, L"HEADER");
294 if ( !hTheme )
295 {
296 m_rendererNative.DrawHeaderButton(win, dc, rect, flags, sortArrow, params);
297 return;
298 }
299
300 RECT r;
301 wxCopyRectToRECT(rect, r);
302
303 int state;
304 if ( flags & wxCONTROL_PRESSED )
305 state = HIS_PRESSED;
306 else if ( flags & wxCONTROL_CURRENT )
307 state = HIS_HOT;
308 else
309 state = HIS_NORMAL;
310 wxUxThemeEngine::Get()->DrawThemeBackground
311 (
312 hTheme,
313 GetHdcOf(dc),
314 HP_HEADERITEM,
315 state,
316 &r,
317 NULL
318 );
319
320 // NOTE: Using the theme to draw HP_HEADERSORTARROW doesn't do anything.
321 // Why? If this can be fixed then draw the sort arrows using the theme
322 // and then clear those flags before calling DrawHeaderButtonContents.
323
324 // Add any extras that are specified in flags and params
325 DrawHeaderButtonContents(win, dc, rect, flags, sortArrow, params);
326}
327
328
329int
330wxRendererXP::GetHeaderButtonHeight(wxWindow *win)
331{
332 wxUxThemeHandle hTheme(win, L"HEADER");
333 if ( !hTheme )
334 {
335 return m_rendererNative.GetHeaderButtonHeight(win);
336 }
337
338 HRESULT hr;
339 int value = -1;
340
341 hr = wxUxThemeEngine::Get()->GetThemeMetric( hTheme,
342 NULL,
343 HP_HEADERITEM,
344 HIS_NORMAL,
345 TMT_HEIGHT,
346 &value );
347 if ( hr == S_OK )
348 return value;
349 else
350 return 20;
351}
352
353
354void
355wxRendererXP::DrawTreeItemButton(wxWindow *win,
356 wxDC& dc,
357 const wxRect& rect,
358 int flags)
359{
360 wxUxThemeHandle hTheme(win, L"TREEVIEW");
361 if ( !hTheme )
362 {
363 m_rendererNative.DrawTreeItemButton(win, dc, rect, flags);
364 return;
365 }
366
367 RECT r;
368 wxCopyRectToRECT(rect, r);
369
370 int state = flags & wxCONTROL_EXPANDED ? GLPS_OPENED : GLPS_CLOSED;
371 wxUxThemeEngine::Get()->DrawThemeBackground
372 (
373 hTheme,
374 GetHdcOf(dc),
375 TVP_GLYPH,
376 state,
377 &r,
378 NULL
379 );
380}
381
382void
383wxRendererXP::DrawCheckBox(wxWindow *win,
384 wxDC& dc,
385 const wxRect& rect,
386 int flags)
387{
388 wxUxThemeHandle hTheme(win, L"BUTTON");
389 if ( !hTheme )
390 {
391 m_rendererNative.DrawCheckBox(win, dc, rect, flags);
392 return;
393 }
394
395 RECT r;
396 wxCopyRectToRECT(rect, r);
397
398 int state;
399 if ( flags & wxCONTROL_CHECKED )
400 state = CBS_CHECKEDNORMAL;
401 else if ( flags & wxCONTROL_UNDETERMINED )
402 state = CBS_MIXEDNORMAL;
403 else
404 state = CBS_UNCHECKEDNORMAL;
405
406 // CBS_XXX is followed by CBX_XXXGOT, then CBS_XXXPRESSED and DISABLED
407 if ( flags & wxCONTROL_CURRENT )
408 state += 1;
409 else if ( flags & wxCONTROL_PRESSED )
410 state += 2;
411 else if ( flags & wxCONTROL_DISABLED )
412 state += 3;
413
414 wxUxThemeEngine::Get()->DrawThemeBackground
415 (
416 hTheme,
417 GetHdcOf(dc),
418 BP_CHECKBOX,
419 state,
420 &r,
421 NULL
422 );
423}
424
425void
426wxRendererXP::DrawPushButton(wxWindow * win,
427 wxDC& dc,
428 const wxRect& rect,
429 int flags)
430{
431 wxUxThemeHandle hTheme(win, L"BUTTON");
432 if ( !hTheme )
433 {
434 m_rendererNative.DrawPushButton(win, dc, rect, flags);
435 return;
436 }
437
438 RECT r;
439 wxCopyRectToRECT(rect, r);
440
441 int state;
442 if ( flags & wxCONTROL_PRESSED )
443 state = PBS_PRESSED;
444 else if ( flags & wxCONTROL_CURRENT )
445 state = PBS_HOT;
446 else if ( flags & wxCONTROL_DISABLED )
447 state = PBS_DISABLED;
448 else if ( flags & wxCONTROL_ISDEFAULT )
449 state = PBS_DEFAULTED;
450 else
451 state = PBS_NORMAL;
452
453 wxUxThemeEngine::Get()->DrawThemeBackground
454 (
455 hTheme,
456 GetHdcOf(dc),
457 BP_PUSHBUTTON,
458 state,
459 &r,
460 NULL
461 );
462
463}
464
465// ----------------------------------------------------------------------------
466// splitter drawing
467// ----------------------------------------------------------------------------
468
469// the width of the sash: this is the same as used by Explorer...
470static const wxCoord SASH_WIDTH = 4;
471
472wxSplitterRenderParams
473wxRendererXP::GetSplitterParams(const wxWindow * win)
474{
475 if ( win->HasFlag(wxSP_NO_XP_THEME) )
476 return m_rendererNative.GetSplitterParams(win);
477 else
478 return wxSplitterRenderParams(SASH_WIDTH, 0, false);
479}
480
481void
482wxRendererXP::DrawSplitterBorder(wxWindow * win,
483 wxDC& dc,
484 const wxRect& rect,
485 int flags)
486{
487 if ( win->HasFlag(wxSP_NO_XP_THEME) )
488 {
489 m_rendererNative.DrawSplitterBorder(win, dc, rect, flags);
490 }
491}
492
493void
494wxRendererXP::DrawSplitterSash(wxWindow *win,
495 wxDC& dc,
496 const wxSize& size,
497 wxCoord position,
498 wxOrientation orient,
499 int flags)
500{
501 if ( !win->HasFlag(wxSP_NO_XP_THEME) )
502 {
503 dc.SetPen(*wxTRANSPARENT_PEN);
504 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
505 if ( orient == wxVERTICAL )
506 {
507 dc.DrawRectangle(position, 0, SASH_WIDTH, size.y);
508 }
509 else // wxHORIZONTAL
510 {
511 dc.DrawRectangle(0, position, size.x, SASH_WIDTH);
512 }
513
514 return;
515 }
516
517 m_rendererNative.DrawSplitterSash(win, dc, size, position, orient, flags);
518}
519
520#endif // wxUSE_UXTHEME