• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "webkit/glue/webthemeengine_impl_win.h"
6 
7 #include <vsstyle.h>  // To convert to gfx::NativeTheme::State
8 
9 #include "base/logging.h"
10 #include "skia/ext/platform_canvas.h"
11 #include "skia/ext/skia_utils_win.h"
12 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h"
13 #include "ui/gfx/native_theme_win.h"
14 
15 using WebKit::WebCanvas;
16 using WebKit::WebColor;
17 using WebKit::WebRect;
18 
19 namespace webkit_glue {
20 
WebRectToRECT(const WebRect & rect)21 static RECT WebRectToRECT(const WebRect& rect) {
22   RECT result;
23   result.left = rect.x;
24   result.top = rect.y;
25   result.right = rect.x + rect.width;
26   result.bottom = rect.y + rect.height;
27   return result;
28 }
29 
WebButtonStateToGfx(int part,int state,gfx::NativeTheme::ButtonExtraParams * extra)30 static gfx::NativeTheme::State WebButtonStateToGfx(
31     int part,
32     int state,
33     gfx::NativeTheme::ButtonExtraParams* extra) {
34   gfx::NativeTheme::State gfx_state = gfx::NativeTheme::kNormal;
35 
36   if (part == BP_PUSHBUTTON) {
37     switch(state) {
38       case PBS_NORMAL:
39         gfx_state = gfx::NativeTheme::kNormal;
40         extra->checked = false;
41         extra->indeterminate = false;
42         extra->is_default = false;
43         break;
44       case PBS_HOT:
45         gfx_state = gfx::NativeTheme::kHovered;
46         extra->checked = false;
47         extra->indeterminate = false;
48         extra->is_default = false;
49         break;
50       case PBS_PRESSED:
51         gfx_state = gfx::NativeTheme::kPressed;
52         extra->checked = false;
53         extra->indeterminate = false;
54         extra->is_default = false;
55         break;
56       case PBS_DISABLED:
57         gfx_state = gfx::NativeTheme::kDisabled;
58         extra->checked = false;
59         extra->indeterminate = false;
60         extra->is_default = false;
61         break;
62       case PBS_DEFAULTED:
63         gfx_state = gfx::NativeTheme::kNormal;
64         extra->checked = false;
65         extra->indeterminate = false;
66         extra->is_default = true;
67         break;
68       case PBS_DEFAULTED_ANIMATING:
69         gfx_state = gfx::NativeTheme::kNormal;
70         extra->checked = false;
71         extra->indeterminate = false;
72         extra->is_default = true;
73         break;
74       default:
75         NOTREACHED() << "Invalid state: " << state;
76     }
77   } else if (part == BP_RADIOBUTTON) {
78     switch(state) {
79       case RBS_UNCHECKEDNORMAL:
80         gfx_state = gfx::NativeTheme::kNormal;
81         extra->checked = false;
82         extra->indeterminate = false;
83         extra->is_default = false;
84         break;
85       case RBS_UNCHECKEDHOT:
86         gfx_state = gfx::NativeTheme::kHovered;
87         extra->checked = false;
88         extra->indeterminate = false;
89         extra->is_default = false;
90         break;
91       case RBS_UNCHECKEDPRESSED:
92         gfx_state = gfx::NativeTheme::kPressed;
93         extra->checked = false;
94         extra->indeterminate = false;
95         extra->is_default = false;
96         break;
97       case RBS_UNCHECKEDDISABLED:
98         gfx_state = gfx::NativeTheme::kDisabled;
99         extra->checked = false;
100         extra->indeterminate = false;
101         extra->is_default = false;
102         break;
103       case RBS_CHECKEDNORMAL:
104         gfx_state = gfx::NativeTheme::kNormal;
105         extra->checked = true;
106         extra->indeterminate = false;
107         extra->is_default = false;
108         break;
109       case RBS_CHECKEDHOT:
110         gfx_state = gfx::NativeTheme::kHovered;
111         extra->checked = true;
112         extra->indeterminate = false;
113         extra->is_default = false;
114         break;
115       case RBS_CHECKEDPRESSED:
116         gfx_state = gfx::NativeTheme::kPressed;
117         extra->checked = true;
118         extra->indeterminate = false;
119         extra->is_default = false;
120         break;
121       case RBS_CHECKEDDISABLED:
122         gfx_state = gfx::NativeTheme::kDisabled;
123         extra->checked = true;
124         extra->indeterminate = false;
125         extra->is_default = false;
126         break;
127       default:
128         NOTREACHED() << "Invalid state: " << state;
129         break;
130     }
131   } else if (part == BP_CHECKBOX) {
132     switch(state) {
133       case CBS_UNCHECKEDNORMAL:
134         gfx_state = gfx::NativeTheme::kNormal;
135         extra->checked = false;
136         extra->indeterminate = false;
137         extra->is_default = false;
138         break;
139       case CBS_UNCHECKEDHOT:
140         gfx_state = gfx::NativeTheme::kHovered;
141         extra->checked = false;
142         extra->indeterminate = false;
143         extra->is_default = false;
144         break;
145       case CBS_UNCHECKEDPRESSED:
146         gfx_state = gfx::NativeTheme::kPressed;
147         extra->checked = false;
148         extra->indeterminate = false;
149         extra->is_default = false;
150         break;
151       case CBS_UNCHECKEDDISABLED:
152         gfx_state = gfx::NativeTheme::kDisabled;
153         extra->checked = false;
154         extra->indeterminate = false;
155         extra->is_default = false;
156         break;
157       case CBS_CHECKEDNORMAL:
158         gfx_state = gfx::NativeTheme::kNormal;
159         extra->checked = true;
160         extra->indeterminate = false;
161         extra->is_default = false;
162         break;
163       case CBS_CHECKEDHOT:
164         gfx_state = gfx::NativeTheme::kHovered;
165         extra->checked = true;
166         extra->indeterminate = false;
167         extra->is_default = false;
168         break;
169       case CBS_CHECKEDPRESSED:
170         gfx_state = gfx::NativeTheme::kPressed;
171         extra->checked = true;
172         extra->indeterminate = false;
173         extra->is_default = false;
174         break;
175       case CBS_CHECKEDDISABLED:
176         gfx_state = gfx::NativeTheme::kDisabled;
177         extra->checked = true;
178         extra->indeterminate = false;
179         extra->is_default = false;
180         break;
181       case CBS_MIXEDNORMAL:
182         gfx_state = gfx::NativeTheme::kNormal;
183         extra->checked = false;
184         extra->indeterminate = true;
185         extra->is_default = false;
186         break;
187       case CBS_MIXEDHOT:
188         gfx_state = gfx::NativeTheme::kHovered;
189         extra->checked = false;
190         extra->indeterminate = true;
191         extra->is_default = false;
192         break;
193       case CBS_MIXEDPRESSED:
194         gfx_state = gfx::NativeTheme::kPressed;
195         extra->checked = false;
196         extra->indeterminate = true;
197         extra->is_default = false;
198         break;
199       case CBS_MIXEDDISABLED:
200         gfx_state = gfx::NativeTheme::kDisabled;
201         extra->checked = false;
202         extra->indeterminate = true;
203         extra->is_default = false;
204         break;
205       case CBS_IMPLICITNORMAL:
206         gfx_state = gfx::NativeTheme::kNormal;
207         extra->checked = false;
208         extra->indeterminate = false;
209         extra->is_default = false;
210         break;
211       case CBS_IMPLICITHOT:
212         gfx_state = gfx::NativeTheme::kHovered;
213         extra->checked = false;
214         extra->indeterminate = false;
215         extra->is_default = false;
216         break;
217       case CBS_IMPLICITPRESSED:
218         gfx_state = gfx::NativeTheme::kPressed;
219         extra->checked = false;
220         extra->indeterminate = false;
221         extra->is_default = false;
222         break;
223       case CBS_IMPLICITDISABLED:
224         gfx_state = gfx::NativeTheme::kDisabled;
225         extra->checked = false;
226         extra->indeterminate = false;
227         extra->is_default = false;
228         break;
229       case CBS_EXCLUDEDNORMAL:
230         gfx_state = gfx::NativeTheme::kNormal;
231         extra->checked = false;
232         extra->indeterminate = false;
233         extra->is_default = false;
234         break;
235       case CBS_EXCLUDEDHOT:
236         gfx_state = gfx::NativeTheme::kHovered;
237         extra->checked = false;
238         extra->indeterminate = false;
239         extra->is_default = false;
240         break;
241       case CBS_EXCLUDEDPRESSED:
242         gfx_state = gfx::NativeTheme::kPressed;
243         extra->checked = false;
244         extra->indeterminate = false;
245         extra->is_default = false;
246         break;
247       case CBS_EXCLUDEDDISABLED:
248         gfx_state = gfx::NativeTheme::kDisabled;
249         extra->checked = false;
250         extra->indeterminate = false;
251         extra->is_default = false;
252         break;
253       default:
254         NOTREACHED() << "Invalid state: " << state;
255         break;
256     }
257   } else if (part == BP_GROUPBOX) {
258     switch(state) {
259       case GBS_NORMAL:
260         gfx_state = gfx::NativeTheme::kNormal;
261         extra->checked = false;
262         extra->indeterminate = false;
263         extra->is_default = false;
264         break;
265       case GBS_DISABLED:
266         gfx_state = gfx::NativeTheme::kDisabled;
267         extra->checked = false;
268         extra->indeterminate = false;
269         extra->is_default = false;
270         break;
271       default:
272         NOTREACHED() << "Invalid state: " << state;
273         break;
274     }
275   } else if (part == BP_COMMANDLINK) {
276     switch(state) {
277       case CMDLS_NORMAL:
278         gfx_state = gfx::NativeTheme::kNormal;
279         extra->checked = false;
280         extra->indeterminate = false;
281         extra->is_default = false;
282         break;
283       case CMDLS_HOT:
284         gfx_state = gfx::NativeTheme::kHovered;
285         extra->checked = false;
286         extra->indeterminate = false;
287         extra->is_default = false;
288         break;
289       case CMDLS_PRESSED:
290         gfx_state = gfx::NativeTheme::kPressed;
291         extra->checked = false;
292         extra->indeterminate = false;
293         extra->is_default = false;
294         break;
295       case CMDLS_DISABLED:
296         gfx_state = gfx::NativeTheme::kDisabled;
297         extra->checked = false;
298         extra->indeterminate = false;
299         extra->is_default = false;
300         break;
301       case CMDLS_DEFAULTED:
302         gfx_state = gfx::NativeTheme::kNormal;
303         extra->checked = false;
304         extra->indeterminate = false;
305         extra->is_default = true;
306         break;
307       case CMDLS_DEFAULTED_ANIMATING:
308         gfx_state = gfx::NativeTheme::kNormal;
309         extra->checked = false;
310         extra->indeterminate = false;
311         extra->is_default = true;
312         break;
313       default:
314         NOTREACHED() << "Invalid state: " << state;
315         break;
316     }
317   } else if (part == BP_COMMANDLINKGLYPH) {
318     switch(state) {
319       case CMDLGS_NORMAL:
320         gfx_state = gfx::NativeTheme::kNormal;
321         extra->checked = false;
322         extra->indeterminate = false;
323         extra->is_default = false;
324         break;
325       case CMDLGS_HOT:
326         gfx_state = gfx::NativeTheme::kHovered;
327         extra->checked = false;
328         extra->indeterminate = false;
329         extra->is_default = false;
330         break;
331       case CMDLGS_PRESSED:
332         gfx_state = gfx::NativeTheme::kPressed;
333         extra->checked = false;
334         extra->indeterminate = false;
335         extra->is_default = false;
336         break;
337       case CMDLGS_DISABLED:
338         gfx_state = gfx::NativeTheme::kDisabled;
339         extra->checked = false;
340         extra->indeterminate = false;
341         extra->is_default = false;
342         break;
343       case CMDLGS_DEFAULTED:
344         gfx_state = gfx::NativeTheme::kNormal;
345         extra->checked = false;
346         extra->indeterminate = false;
347         extra->is_default = true;
348         break;
349       default:
350         NOTREACHED() << "Invalid state: " << state;
351         break;
352     }
353   }
354   return gfx_state;
355 }
356 
paintButton(WebCanvas * canvas,int part,int state,int classic_state,const WebRect & rect)357 void WebThemeEngineImpl::paintButton(
358     WebCanvas* canvas, int part, int state, int classic_state,
359     const WebRect& rect) {
360   gfx::NativeTheme::Part native_part = gfx::NativeTheme::kPushButton;
361   switch(part) {
362     case BP_PUSHBUTTON:
363       native_part = gfx::NativeTheme::kPushButton;
364       break;
365     case BP_CHECKBOX:
366       native_part = gfx::NativeTheme::kCheckbox;
367       break;
368     case BP_RADIOBUTTON:
369       native_part = gfx::NativeTheme::kRadio;
370       break;
371     default:
372       break;
373   }
374   gfx::NativeTheme::ExtraParams extra;
375   gfx::NativeTheme::State native_state = WebButtonStateToGfx(part, state,
376                                                              &extra.button);
377   extra.button.classic_state = classic_state;
378   gfx::Rect gfx_rect(rect.x, rect.y, rect.width, rect.height);
379   gfx::NativeTheme::instance()->Paint(canvas, native_part,
380                                       native_state, gfx_rect, extra);
381 }
382 
paintMenuList(WebCanvas * canvas,int part,int state,int classic_state,const WebRect & rect)383 void WebThemeEngineImpl::paintMenuList(
384     WebCanvas* canvas, int part, int state, int classic_state,
385     const WebRect& rect) {
386   HDC hdc = skia::BeginPlatformPaint(canvas);
387 
388   RECT native_rect = WebRectToRECT(rect);
389   gfx::NativeThemeWin::instance()->PaintMenuList(
390       hdc, part, state, classic_state, &native_rect);
391 
392   skia::EndPlatformPaint(canvas);
393 }
394 
paintScrollbarArrow(WebCanvas * canvas,int state,int classic_state,const WebRect & rect)395 void WebThemeEngineImpl::paintScrollbarArrow(
396     WebCanvas* canvas, int state, int classic_state,
397     const WebRect& rect) {
398   HDC hdc = skia::BeginPlatformPaint(canvas);
399 
400   RECT native_rect = WebRectToRECT(rect);
401   gfx::NativeThemeWin::instance()->PaintScrollbarArrow(
402       hdc, state, classic_state, &native_rect);
403 
404   skia::EndPlatformPaint(canvas);
405 }
406 
paintScrollbarThumb(WebCanvas * canvas,int part,int state,int classic_state,const WebRect & rect)407 void WebThemeEngineImpl::paintScrollbarThumb(
408     WebCanvas* canvas, int part, int state, int classic_state,
409     const WebRect& rect) {
410   HDC hdc = skia::BeginPlatformPaint(canvas);
411 
412   RECT native_rect = WebRectToRECT(rect);
413   gfx::NativeThemeWin::instance()->PaintScrollbarThumb(
414       hdc, part, state, classic_state, &native_rect);
415 
416   skia::EndPlatformPaint(canvas);
417 }
418 
paintScrollbarTrack(WebCanvas * canvas,int part,int state,int classic_state,const WebRect & rect,const WebRect & align_rect)419 void WebThemeEngineImpl::paintScrollbarTrack(
420     WebCanvas* canvas, int part, int state, int classic_state,
421     const WebRect& rect, const WebRect& align_rect) {
422   HDC hdc = skia::BeginPlatformPaint(canvas);
423 
424   RECT native_rect = WebRectToRECT(rect);
425   RECT native_align_rect = WebRectToRECT(align_rect);
426   gfx::NativeThemeWin::instance()->PaintScrollbarTrack(
427       hdc, part, state, classic_state, &native_rect, &native_align_rect,
428       canvas);
429 
430   skia::EndPlatformPaint(canvas);
431 }
432 
paintSpinButton(WebCanvas * canvas,int part,int state,int classic_state,const WebRect & rect)433 void WebThemeEngineImpl::paintSpinButton(
434     WebCanvas* canvas, int part, int state, int classic_state,
435     const WebRect& rect) {
436   HDC hdc = skia::BeginPlatformPaint(canvas);
437 
438   RECT native_rect = WebRectToRECT(rect);
439   gfx::NativeThemeWin::instance()->PaintSpinButton(
440       hdc, part, state, classic_state, &native_rect);
441 
442   skia::EndPlatformPaint(canvas);
443 }
444 
paintTextField(WebCanvas * canvas,int part,int state,int classic_state,const WebRect & rect,WebColor color,bool fill_content_area,bool draw_edges)445 void WebThemeEngineImpl::paintTextField(
446     WebCanvas* canvas, int part, int state, int classic_state,
447     const WebRect& rect, WebColor color, bool fill_content_area,
448     bool draw_edges) {
449   HDC hdc = skia::BeginPlatformPaint(canvas);
450 
451   RECT native_rect = WebRectToRECT(rect);
452   COLORREF c = skia::SkColorToCOLORREF(color);
453 
454   gfx::NativeThemeWin::instance()->PaintTextField(
455       hdc, part, state, classic_state, &native_rect, c, fill_content_area,
456       draw_edges);
457 
458   skia::EndPlatformPaint(canvas);
459 }
460 
paintTrackbar(WebCanvas * canvas,int part,int state,int classic_state,const WebRect & rect)461 void WebThemeEngineImpl::paintTrackbar(
462     WebCanvas* canvas, int part, int state, int classic_state,
463     const WebRect& rect) {
464   HDC hdc = skia::BeginPlatformPaint(canvas);
465 
466   RECT native_rect = WebRectToRECT(rect);
467   gfx::NativeThemeWin::instance()->PaintTrackbar(
468       hdc, part, state, classic_state, &native_rect, canvas);
469 
470   skia::EndPlatformPaint(canvas);
471 }
472 
paintProgressBar(WebCanvas * canvas,const WebRect & barRect,const WebRect & valueRect,bool determinate,double animatedSeconds)473 void WebThemeEngineImpl::paintProgressBar(
474     WebCanvas* canvas, const WebRect& barRect, const WebRect& valueRect,
475     bool determinate, double animatedSeconds)
476 {
477   HDC hdc = skia::BeginPlatformPaint(canvas);
478 
479   RECT native_bar_rect = WebRectToRECT(barRect);
480   RECT native_value_rect = WebRectToRECT(valueRect);
481   gfx::NativeThemeWin::instance()->PaintProgressBar(
482       hdc, &native_bar_rect,
483       &native_value_rect, determinate, animatedSeconds, canvas);
484 
485   skia::EndPlatformPaint(canvas);
486 }
487 
488 }  // namespace webkit_glue
489