]> git.saurik.com Git - wxWidgets.git/blob - src/msw/renderer.cpp
Don't skip after writing tab or we could get another one in some circumstances
[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 #endif
49
50 // ----------------------------------------------------------------------------
51 // wxRendererMSW: wxRendererNative implementation for "old" Win32 systems
52 // ----------------------------------------------------------------------------
53
54 class WXDLLEXPORT wxRendererMSW : public wxDelegateRendererNative
55 {
56 public:
57 wxRendererMSW() { }
58
59 static wxRendererNative& Get();
60
61 virtual void DrawComboBoxDropButton(wxWindow *win,
62 wxDC& dc,
63 const wxRect& rect,
64 int flags = 0);
65
66 private:
67 DECLARE_NO_COPY_CLASS(wxRendererMSW)
68 };
69
70 // ----------------------------------------------------------------------------
71 // wxRendererXP: wxRendererNative implementation for Windows XP and later
72 // ----------------------------------------------------------------------------
73
74 #if wxUSE_UXTHEME
75
76 class WXDLLEXPORT wxRendererXP : public wxDelegateRendererNative
77 {
78 public:
79 wxRendererXP() : wxDelegateRendererNative(wxRendererMSW::Get()) { }
80
81 static wxRendererNative& Get();
82
83 virtual void DrawSplitterBorder(wxWindow *win,
84 wxDC& dc,
85 const wxRect& rect,
86 int flags = 0);
87 virtual void DrawSplitterSash(wxWindow *win,
88 wxDC& dc,
89 const wxSize& size,
90 wxCoord position,
91 wxOrientation orient,
92 int flags = 0);
93
94 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
95
96 virtual void DrawComboBoxDropButton(wxWindow *win,
97 wxDC& dc,
98 const wxRect& rect,
99 int flags = 0);
100 private:
101 DECLARE_NO_COPY_CLASS(wxRendererXP)
102 };
103
104 #endif // wxUSE_UXTHEME
105
106 // ============================================================================
107 // wxRendererNative and wxRendererMSW implementation
108 // ============================================================================
109
110 /* static */
111 wxRendererNative& wxRendererNative::GetDefault()
112 {
113 #if wxUSE_UXTHEME
114 wxUxThemeEngine *themeEngine = wxUxThemeEngine::Get();
115 if ( themeEngine && themeEngine->IsAppThemed() )
116 return wxRendererXP::Get();
117 #endif // wxUSE_UXTHEME
118
119 return wxRendererMSW::Get();
120 }
121
122 /* static */
123 wxRendererNative& wxRendererMSW::Get()
124 {
125 static wxRendererMSW s_rendererMSW;
126
127 return s_rendererMSW;
128 }
129
130 #if defined(__WXWINCE__) && !defined(DFCS_FLAT)
131 #define DFCS_FLAT 0
132 #endif
133
134 void
135 wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win),
136 wxDC& dc,
137 const wxRect& rect,
138 int flags)
139 {
140 RECT r;
141 r.left = rect.GetLeft();
142 r.top = rect.GetTop();
143 r.bottom = rect.y + rect.height;
144 r.right = rect.x + rect.width;
145
146 int style = DFCS_SCROLLCOMBOBOX;
147 if ( flags & wxCONTROL_DISABLED )
148 style |= DFCS_INACTIVE;
149 if ( flags & wxCONTROL_PRESSED )
150 style |= DFCS_PUSHED | DFCS_FLAT;
151
152 ::DrawFrameControl(GetHdcOf(dc), &r, DFC_SCROLL, style);
153 }
154
155 // ============================================================================
156 // wxRendererXP implementation
157 // ============================================================================
158
159 #if wxUSE_UXTHEME
160
161 /* static */
162 wxRendererNative& wxRendererXP::Get()
163 {
164 static wxRendererXP s_rendererXP;
165
166 return s_rendererXP;
167 }
168
169 // NOTE: There is no guarantee that the button drawn fills the entire rect (XP
170 // default theme, for example), so the caller should have cleared button's
171 // background before this call. This is quite likely a wxMSW-specific thing.
172 void
173 wxRendererXP::DrawComboBoxDropButton(wxWindow * win,
174 wxDC& dc,
175 const wxRect& rect,
176 int flags)
177 {
178 wxUxThemeHandle hTheme(win, L"COMBOBOX");
179 if ( hTheme )
180 {
181 RECT r;
182 r.left = rect.x;
183 r.top = rect.y;
184 r.right = rect.x + rect.width;
185 r.bottom = rect.y + rect.height;
186
187 int state;
188 if ( flags & wxCONTROL_PRESSED )
189 state = CBXS_PRESSED;
190 else if ( flags & wxCONTROL_CURRENT )
191 state = CBXS_HOT;
192 else if ( flags & wxCONTROL_DISABLED )
193 state = CBXS_DISABLED;
194 else
195 state = CBXS_NORMAL;
196
197 wxUxThemeEngine::Get()->DrawThemeBackground
198 (
199 hTheme,
200 (HDC) dc.GetHDC(),
201 CP_DROPDOWNBUTTON,
202 state,
203 &r,
204 NULL
205 );
206
207 }
208 }
209
210 // ----------------------------------------------------------------------------
211 // splitter drawing
212 // ----------------------------------------------------------------------------
213
214 // the width of the sash: this is the same as used by Explorer...
215 static const wxCoord SASH_WIDTH = 4;
216
217 wxSplitterRenderParams
218 wxRendererXP::GetSplitterParams(const wxWindow * win)
219 {
220 if (win->GetWindowStyle() & wxSP_NO_XP_THEME)
221 return m_rendererNative.GetSplitterParams(win);
222 else
223 return wxSplitterRenderParams(SASH_WIDTH, 0, false);
224 }
225
226 void
227 wxRendererXP::DrawSplitterBorder(wxWindow * win,
228 wxDC& dc,
229 const wxRect& rect,
230 int flags)
231 {
232 if (win->GetWindowStyle() & wxSP_NO_XP_THEME)
233 {
234 m_rendererNative.DrawSplitterBorder(win, dc, rect, flags);
235 }
236 }
237
238 void
239 wxRendererXP::DrawSplitterSash(wxWindow *win,
240 wxDC& dc,
241 const wxSize& size,
242 wxCoord position,
243 wxOrientation orient,
244 int flags)
245 {
246 if ( !win->HasFlag(wxSP_NO_XP_THEME) )
247 {
248 dc.SetPen(*wxTRANSPARENT_PEN);
249 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
250 if ( orient == wxVERTICAL )
251 {
252 dc.DrawRectangle(position, 0, SASH_WIDTH, size.y);
253 }
254 else // wxHORIZONTAL
255 {
256 dc.DrawRectangle(0, position, size.x, SASH_WIDTH);
257 }
258
259 return;
260 }
261
262 m_rendererNative.DrawSplitterSash(win, dc, size, position, orient, flags);
263 }
264
265 #endif // wxUSE_UXTHEME
266