OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 "content/child/webthemeengine_impl_win.h" | |
6 | |
7 #include <vsstyle.h> // To convert to ui::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/public/platform/WebRect.h" | |
13 #include "ui/gfx/win/dpi.h" | |
14 #include "ui/native_theme/native_theme.h" | |
15 | |
16 using blink::WebCanvas; | |
17 using blink::WebColor; | |
18 using blink::WebRect; | |
19 using blink::WebSize; | |
20 | |
21 namespace content { | |
22 | |
23 static RECT WebRectToRECT(const WebRect& rect) { | |
24 RECT result; | |
25 result.left = rect.x; | |
26 result.top = rect.y; | |
27 result.right = rect.x + rect.width; | |
28 result.bottom = rect.y + rect.height; | |
29 return result; | |
30 } | |
31 | |
32 static ui::NativeTheme::State WebButtonStateToGfx( | |
33 int part, int state, ui::NativeTheme::ButtonExtraParams* extra) { | |
34 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal; | |
35 // Native buttons have a different focus style. | |
36 extra->is_focused = false; | |
37 extra->has_border = false; | |
38 extra->background_color = ui::NativeTheme::instance()->GetSystemColor( | |
39 ui::NativeTheme::kColorId_ButtonBackgroundColor); | |
40 | |
41 if (part == BP_PUSHBUTTON) { | |
42 switch (state) { | |
43 case PBS_NORMAL: | |
44 gfx_state = ui::NativeTheme::kNormal; | |
45 extra->checked = false; | |
46 extra->indeterminate = false; | |
47 extra->is_default = false; | |
48 break; | |
49 case PBS_HOT: | |
50 gfx_state = ui::NativeTheme::kHovered; | |
51 extra->checked = false; | |
52 extra->indeterminate = false; | |
53 extra->is_default = false; | |
54 break; | |
55 case PBS_PRESSED: | |
56 gfx_state = ui::NativeTheme::kPressed; | |
57 extra->checked = false; | |
58 extra->indeterminate = false; | |
59 extra->is_default = false; | |
60 break; | |
61 case PBS_DISABLED: | |
62 gfx_state = ui::NativeTheme::kDisabled; | |
63 extra->checked = false; | |
64 extra->indeterminate = false; | |
65 extra->is_default = false; | |
66 break; | |
67 case PBS_DEFAULTED: | |
68 gfx_state = ui::NativeTheme::kNormal; | |
69 extra->checked = false; | |
70 extra->indeterminate = false; | |
71 extra->is_default = true; | |
72 break; | |
73 case PBS_DEFAULTED_ANIMATING: | |
74 gfx_state = ui::NativeTheme::kNormal; | |
75 extra->checked = false; | |
76 extra->indeterminate = false; | |
77 extra->is_default = true; | |
78 break; | |
79 default: | |
80 NOTREACHED() << "Invalid state: " << state; | |
81 } | |
82 } else if (part == BP_RADIOBUTTON) { | |
83 switch (state) { | |
84 case RBS_UNCHECKEDNORMAL: | |
85 gfx_state = ui::NativeTheme::kNormal; | |
86 extra->checked = false; | |
87 extra->indeterminate = false; | |
88 extra->is_default = false; | |
89 break; | |
90 case RBS_UNCHECKEDHOT: | |
91 gfx_state = ui::NativeTheme::kHovered; | |
92 extra->checked = false; | |
93 extra->indeterminate = false; | |
94 extra->is_default = false; | |
95 break; | |
96 case RBS_UNCHECKEDPRESSED: | |
97 gfx_state = ui::NativeTheme::kPressed; | |
98 extra->checked = false; | |
99 extra->indeterminate = false; | |
100 extra->is_default = false; | |
101 break; | |
102 case RBS_UNCHECKEDDISABLED: | |
103 gfx_state = ui::NativeTheme::kDisabled; | |
104 extra->checked = false; | |
105 extra->indeterminate = false; | |
106 extra->is_default = false; | |
107 break; | |
108 case RBS_CHECKEDNORMAL: | |
109 gfx_state = ui::NativeTheme::kNormal; | |
110 extra->checked = true; | |
111 extra->indeterminate = false; | |
112 extra->is_default = false; | |
113 break; | |
114 case RBS_CHECKEDHOT: | |
115 gfx_state = ui::NativeTheme::kHovered; | |
116 extra->checked = true; | |
117 extra->indeterminate = false; | |
118 extra->is_default = false; | |
119 break; | |
120 case RBS_CHECKEDPRESSED: | |
121 gfx_state = ui::NativeTheme::kPressed; | |
122 extra->checked = true; | |
123 extra->indeterminate = false; | |
124 extra->is_default = false; | |
125 break; | |
126 case RBS_CHECKEDDISABLED: | |
127 gfx_state = ui::NativeTheme::kDisabled; | |
128 extra->checked = true; | |
129 extra->indeterminate = false; | |
130 extra->is_default = false; | |
131 break; | |
132 default: | |
133 NOTREACHED() << "Invalid state: " << state; | |
134 break; | |
135 } | |
136 } else if (part == BP_CHECKBOX) { | |
137 switch (state) { | |
138 case CBS_UNCHECKEDNORMAL: | |
139 gfx_state = ui::NativeTheme::kNormal; | |
140 extra->checked = false; | |
141 extra->indeterminate = false; | |
142 extra->is_default = false; | |
143 break; | |
144 case CBS_UNCHECKEDHOT: | |
145 gfx_state = ui::NativeTheme::kHovered; | |
146 extra->checked = false; | |
147 extra->indeterminate = false; | |
148 extra->is_default = false; | |
149 break; | |
150 case CBS_UNCHECKEDPRESSED: | |
151 gfx_state = ui::NativeTheme::kPressed; | |
152 extra->checked = false; | |
153 extra->indeterminate = false; | |
154 extra->is_default = false; | |
155 break; | |
156 case CBS_UNCHECKEDDISABLED: | |
157 gfx_state = ui::NativeTheme::kDisabled; | |
158 extra->checked = false; | |
159 extra->indeterminate = false; | |
160 extra->is_default = false; | |
161 break; | |
162 case CBS_CHECKEDNORMAL: | |
163 gfx_state = ui::NativeTheme::kNormal; | |
164 extra->checked = true; | |
165 extra->indeterminate = false; | |
166 extra->is_default = false; | |
167 break; | |
168 case CBS_CHECKEDHOT: | |
169 gfx_state = ui::NativeTheme::kHovered; | |
170 extra->checked = true; | |
171 extra->indeterminate = false; | |
172 extra->is_default = false; | |
173 break; | |
174 case CBS_CHECKEDPRESSED: | |
175 gfx_state = ui::NativeTheme::kPressed; | |
176 extra->checked = true; | |
177 extra->indeterminate = false; | |
178 extra->is_default = false; | |
179 break; | |
180 case CBS_CHECKEDDISABLED: | |
181 gfx_state = ui::NativeTheme::kDisabled; | |
182 extra->checked = true; | |
183 extra->indeterminate = false; | |
184 extra->is_default = false; | |
185 break; | |
186 case CBS_MIXEDNORMAL: | |
187 gfx_state = ui::NativeTheme::kNormal; | |
188 extra->checked = false; | |
189 extra->indeterminate = true; | |
190 extra->is_default = false; | |
191 break; | |
192 case CBS_MIXEDHOT: | |
193 gfx_state = ui::NativeTheme::kHovered; | |
194 extra->checked = false; | |
195 extra->indeterminate = true; | |
196 extra->is_default = false; | |
197 break; | |
198 case CBS_MIXEDPRESSED: | |
199 gfx_state = ui::NativeTheme::kPressed; | |
200 extra->checked = false; | |
201 extra->indeterminate = true; | |
202 extra->is_default = false; | |
203 break; | |
204 case CBS_MIXEDDISABLED: | |
205 gfx_state = ui::NativeTheme::kDisabled; | |
206 extra->checked = false; | |
207 extra->indeterminate = true; | |
208 extra->is_default = false; | |
209 break; | |
210 case CBS_IMPLICITNORMAL: | |
211 gfx_state = ui::NativeTheme::kNormal; | |
212 extra->checked = false; | |
213 extra->indeterminate = false; | |
214 extra->is_default = false; | |
215 break; | |
216 case CBS_IMPLICITHOT: | |
217 gfx_state = ui::NativeTheme::kHovered; | |
218 extra->checked = false; | |
219 extra->indeterminate = false; | |
220 extra->is_default = false; | |
221 break; | |
222 case CBS_IMPLICITPRESSED: | |
223 gfx_state = ui::NativeTheme::kPressed; | |
224 extra->checked = false; | |
225 extra->indeterminate = false; | |
226 extra->is_default = false; | |
227 break; | |
228 case CBS_IMPLICITDISABLED: | |
229 gfx_state = ui::NativeTheme::kDisabled; | |
230 extra->checked = false; | |
231 extra->indeterminate = false; | |
232 extra->is_default = false; | |
233 break; | |
234 case CBS_EXCLUDEDNORMAL: | |
235 gfx_state = ui::NativeTheme::kNormal; | |
236 extra->checked = false; | |
237 extra->indeterminate = false; | |
238 extra->is_default = false; | |
239 break; | |
240 case CBS_EXCLUDEDHOT: | |
241 gfx_state = ui::NativeTheme::kHovered; | |
242 extra->checked = false; | |
243 extra->indeterminate = false; | |
244 extra->is_default = false; | |
245 break; | |
246 case CBS_EXCLUDEDPRESSED: | |
247 gfx_state = ui::NativeTheme::kPressed; | |
248 extra->checked = false; | |
249 extra->indeterminate = false; | |
250 extra->is_default = false; | |
251 break; | |
252 case CBS_EXCLUDEDDISABLED: | |
253 gfx_state = ui::NativeTheme::kDisabled; | |
254 extra->checked = false; | |
255 extra->indeterminate = false; | |
256 extra->is_default = false; | |
257 break; | |
258 default: | |
259 NOTREACHED() << "Invalid state: " << state; | |
260 break; | |
261 } | |
262 } else if (part == BP_GROUPBOX) { | |
263 switch (state) { | |
264 case GBS_NORMAL: | |
265 gfx_state = ui::NativeTheme::kNormal; | |
266 extra->checked = false; | |
267 extra->indeterminate = false; | |
268 extra->is_default = false; | |
269 break; | |
270 case GBS_DISABLED: | |
271 gfx_state = ui::NativeTheme::kDisabled; | |
272 extra->checked = false; | |
273 extra->indeterminate = false; | |
274 extra->is_default = false; | |
275 break; | |
276 default: | |
277 NOTREACHED() << "Invalid state: " << state; | |
278 break; | |
279 } | |
280 } else if (part == BP_COMMANDLINK) { | |
281 switch (state) { | |
282 case CMDLS_NORMAL: | |
283 gfx_state = ui::NativeTheme::kNormal; | |
284 extra->checked = false; | |
285 extra->indeterminate = false; | |
286 extra->is_default = false; | |
287 break; | |
288 case CMDLS_HOT: | |
289 gfx_state = ui::NativeTheme::kHovered; | |
290 extra->checked = false; | |
291 extra->indeterminate = false; | |
292 extra->is_default = false; | |
293 break; | |
294 case CMDLS_PRESSED: | |
295 gfx_state = ui::NativeTheme::kPressed; | |
296 extra->checked = false; | |
297 extra->indeterminate = false; | |
298 extra->is_default = false; | |
299 break; | |
300 case CMDLS_DISABLED: | |
301 gfx_state = ui::NativeTheme::kDisabled; | |
302 extra->checked = false; | |
303 extra->indeterminate = false; | |
304 extra->is_default = false; | |
305 break; | |
306 case CMDLS_DEFAULTED: | |
307 gfx_state = ui::NativeTheme::kNormal; | |
308 extra->checked = false; | |
309 extra->indeterminate = false; | |
310 extra->is_default = true; | |
311 break; | |
312 case CMDLS_DEFAULTED_ANIMATING: | |
313 gfx_state = ui::NativeTheme::kNormal; | |
314 extra->checked = false; | |
315 extra->indeterminate = false; | |
316 extra->is_default = true; | |
317 break; | |
318 default: | |
319 NOTREACHED() << "Invalid state: " << state; | |
320 break; | |
321 } | |
322 } else if (part == BP_COMMANDLINKGLYPH) { | |
323 switch (state) { | |
324 case CMDLGS_NORMAL: | |
325 gfx_state = ui::NativeTheme::kNormal; | |
326 extra->checked = false; | |
327 extra->indeterminate = false; | |
328 extra->is_default = false; | |
329 break; | |
330 case CMDLGS_HOT: | |
331 gfx_state = ui::NativeTheme::kHovered; | |
332 extra->checked = false; | |
333 extra->indeterminate = false; | |
334 extra->is_default = false; | |
335 break; | |
336 case CMDLGS_PRESSED: | |
337 gfx_state = ui::NativeTheme::kPressed; | |
338 extra->checked = false; | |
339 extra->indeterminate = false; | |
340 extra->is_default = false; | |
341 break; | |
342 case CMDLGS_DISABLED: | |
343 gfx_state = ui::NativeTheme::kDisabled; | |
344 extra->checked = false; | |
345 extra->indeterminate = false; | |
346 extra->is_default = false; | |
347 break; | |
348 case CMDLGS_DEFAULTED: | |
349 gfx_state = ui::NativeTheme::kNormal; | |
350 extra->checked = false; | |
351 extra->indeterminate = false; | |
352 extra->is_default = true; | |
353 break; | |
354 default: | |
355 NOTREACHED() << "Invalid state: " << state; | |
356 break; | |
357 } | |
358 } | |
359 return gfx_state; | |
360 } | |
361 | |
362 void WebThemeEngineImpl::paintButton( | |
363 WebCanvas* canvas, int part, int state, int classic_state, | |
364 const WebRect& rect) { | |
365 ui::NativeTheme::Part native_part = ui::NativeTheme::kPushButton; | |
366 switch (part) { | |
367 case BP_PUSHBUTTON: | |
368 native_part = ui::NativeTheme::kPushButton; | |
369 break; | |
370 case BP_CHECKBOX: | |
371 native_part = ui::NativeTheme::kCheckbox; | |
372 break; | |
373 case BP_RADIOBUTTON: | |
374 native_part = ui::NativeTheme::kRadio; | |
375 break; | |
376 default: | |
377 NOTREACHED() << "Invalid part: " << part; | |
378 break; | |
379 } | |
380 ui::NativeTheme::ExtraParams extra; | |
381 ui::NativeTheme::State native_state = WebButtonStateToGfx(part, state, | |
382 &extra.button); | |
383 extra.button.classic_state = classic_state; | |
384 gfx::Rect gfx_rect(rect.x, rect.y, rect.width, rect.height); | |
385 ui::NativeTheme::instance()->Paint(canvas, native_part, | |
386 native_state, gfx_rect, extra); | |
387 } | |
388 | |
389 static ui::NativeTheme::State WebListMenuStateToGfx(int part, int state) { | |
390 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal; | |
391 | |
392 switch (part) { | |
393 case CP_DROPDOWNBUTTON: | |
394 switch (state) { | |
395 case CBXS_NORMAL: | |
396 gfx_state = ui::NativeTheme::kNormal; | |
397 break; | |
398 case CBXS_HOT: | |
399 gfx_state = ui::NativeTheme::kHovered; | |
400 break; | |
401 case CBXS_PRESSED: | |
402 gfx_state = ui::NativeTheme::kPressed; | |
403 break; | |
404 case CBXS_DISABLED: | |
405 gfx_state = ui::NativeTheme::kDisabled; | |
406 break; | |
407 default: | |
408 NOTREACHED() << "Invalid state: " << state; | |
409 break; | |
410 } | |
411 break; | |
412 default: | |
413 NOTREACHED() << "Invalid part: " << part; | |
414 break; | |
415 } | |
416 return gfx_state; | |
417 } | |
418 | |
419 void WebThemeEngineImpl::paintMenuList( | |
420 WebCanvas* canvas, int part, int state, int classic_state, | |
421 const WebRect& rect) { | |
422 ui::NativeTheme::Part native_part = ui::NativeTheme::kMenuList; | |
423 switch (part) { | |
424 case CP_DROPDOWNBUTTON: | |
425 native_part = ui::NativeTheme::kMenuList; | |
426 break; | |
427 default: | |
428 NOTREACHED() << "Invalid part: " << part; | |
429 break; | |
430 } | |
431 ui::NativeTheme::State native_state = WebListMenuStateToGfx(part, state); | |
432 gfx::Rect gfx_rect(rect.x, rect.y, rect.width, rect.height); | |
433 ui::NativeTheme::ExtraParams extra; | |
434 extra.menu_list.classic_state = classic_state; | |
435 ui::NativeTheme::instance()->Paint(canvas, native_part, | |
436 native_state, gfx_rect, extra); | |
437 } | |
438 | |
439 static ui::NativeTheme::State WebScrollbarArrowStateToGfx( | |
440 int state, ui::NativeTheme::Part* part, | |
441 ui::NativeTheme::ScrollbarArrowExtraParams* extra) { | |
442 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal; | |
443 switch (state) { | |
444 case ABS_UPNORMAL: | |
445 gfx_state = ui::NativeTheme::kNormal; | |
446 *part = ui::NativeTheme::kScrollbarUpArrow; | |
447 extra->is_hovering = false; | |
448 break; | |
449 case ABS_UPHOT: | |
450 gfx_state = ui::NativeTheme::kHovered; | |
451 *part = ui::NativeTheme::kScrollbarUpArrow; | |
452 extra->is_hovering = false; | |
453 break; | |
454 case ABS_UPPRESSED: | |
455 gfx_state = ui::NativeTheme::kPressed; | |
456 *part = ui::NativeTheme::kScrollbarUpArrow; | |
457 extra->is_hovering = false; | |
458 break; | |
459 case ABS_UPDISABLED: | |
460 gfx_state = ui::NativeTheme::kDisabled; | |
461 *part = ui::NativeTheme::kScrollbarUpArrow; | |
462 extra->is_hovering = false; | |
463 break; | |
464 case ABS_DOWNNORMAL: | |
465 gfx_state = ui::NativeTheme::kNormal; | |
466 *part = ui::NativeTheme::kScrollbarDownArrow; | |
467 extra->is_hovering = false; | |
468 break; | |
469 case ABS_DOWNHOT: | |
470 gfx_state = ui::NativeTheme::kHovered; | |
471 *part = ui::NativeTheme::kScrollbarDownArrow; | |
472 extra->is_hovering = false; | |
473 break; | |
474 case ABS_DOWNPRESSED: | |
475 gfx_state = ui::NativeTheme::kPressed; | |
476 *part = ui::NativeTheme::kScrollbarDownArrow; | |
477 extra->is_hovering = false; | |
478 break; | |
479 case ABS_DOWNDISABLED: | |
480 gfx_state = ui::NativeTheme::kDisabled; | |
481 *part = ui::NativeTheme::kScrollbarDownArrow; | |
482 extra->is_hovering = false; | |
483 break; | |
484 case ABS_LEFTNORMAL: | |
485 gfx_state = ui::NativeTheme::kNormal; | |
486 *part = ui::NativeTheme::kScrollbarLeftArrow; | |
487 extra->is_hovering = false; | |
488 break; | |
489 case ABS_LEFTHOT: | |
490 gfx_state = ui::NativeTheme::kHovered; | |
491 *part = ui::NativeTheme::kScrollbarLeftArrow; | |
492 extra->is_hovering = false; | |
493 break; | |
494 case ABS_LEFTPRESSED: | |
495 gfx_state = ui::NativeTheme::kPressed; | |
496 *part = ui::NativeTheme::kScrollbarLeftArrow; | |
497 extra->is_hovering = false; | |
498 break; | |
499 case ABS_LEFTDISABLED: | |
500 gfx_state = ui::NativeTheme::kDisabled; | |
501 *part = ui::NativeTheme::kScrollbarLeftArrow; | |
502 extra->is_hovering = false; | |
503 break; | |
504 case ABS_RIGHTNORMAL: | |
505 gfx_state = ui::NativeTheme::kNormal; | |
506 *part = ui::NativeTheme::kScrollbarRightArrow; | |
507 extra->is_hovering = false; | |
508 break; | |
509 case ABS_RIGHTHOT: | |
510 gfx_state = ui::NativeTheme::kHovered; | |
511 *part = ui::NativeTheme::kScrollbarRightArrow; | |
512 extra->is_hovering = false; | |
513 break; | |
514 case ABS_RIGHTPRESSED: | |
515 gfx_state = ui::NativeTheme::kPressed; | |
516 *part = ui::NativeTheme::kScrollbarRightArrow; | |
517 extra->is_hovering = false; | |
518 break; | |
519 case ABS_RIGHTDISABLED: | |
520 gfx_state = ui::NativeTheme::kDisabled; | |
521 *part = ui::NativeTheme::kScrollbarRightArrow; | |
522 extra->is_hovering = false; | |
523 break; | |
524 case ABS_UPHOVER: | |
525 gfx_state = ui::NativeTheme::kHovered; | |
526 *part = ui::NativeTheme::kScrollbarUpArrow; | |
527 extra->is_hovering = true; | |
528 break; | |
529 case ABS_DOWNHOVER: | |
530 gfx_state = ui::NativeTheme::kHovered; | |
531 *part = ui::NativeTheme::kScrollbarDownArrow; | |
532 extra->is_hovering = true; | |
533 break; | |
534 case ABS_LEFTHOVER: | |
535 gfx_state = ui::NativeTheme::kHovered; | |
536 *part = ui::NativeTheme::kScrollbarLeftArrow; | |
537 extra->is_hovering = true; | |
538 break; | |
539 case ABS_RIGHTHOVER: | |
540 gfx_state = ui::NativeTheme::kHovered; | |
541 *part = ui::NativeTheme::kScrollbarRightArrow; | |
542 extra->is_hovering = true; | |
543 break; | |
544 default: | |
545 NOTREACHED() << "Invalid state: " << state; | |
546 break; | |
547 } | |
548 return gfx_state; | |
549 } | |
550 | |
551 void WebThemeEngineImpl::paintScrollbarArrow( | |
552 WebCanvas* canvas, int state, int classic_state, const WebRect& rect) { | |
553 ui::NativeTheme::Part native_part; | |
554 ui::NativeTheme::ExtraParams extra; | |
555 ui::NativeTheme::State native_state = WebScrollbarArrowStateToGfx( | |
556 state, &native_part, &extra.scrollbar_arrow); | |
557 gfx::Rect gfx_rect(rect.x, rect.y, rect.width, rect.height); | |
558 ui::NativeTheme::instance()->Paint(canvas, native_part, | |
559 native_state, gfx_rect, extra); | |
560 } | |
561 | |
562 static ui::NativeTheme::State WebScrollbarThumbStateToGfx( | |
563 int state, ui::NativeTheme::ScrollbarThumbExtraParams* extra) { | |
564 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal; | |
565 switch (state) { | |
566 case SCRBS_NORMAL: | |
567 gfx_state = ui::NativeTheme::kNormal; | |
568 extra->is_hovering = false; | |
569 break; | |
570 case SCRBS_HOVER: | |
571 gfx_state = ui::NativeTheme::kHovered; | |
572 extra->is_hovering = true; | |
573 break; | |
574 case SCRBS_HOT: | |
575 gfx_state = ui::NativeTheme::kHovered; | |
576 extra->is_hovering = false; | |
577 break; | |
578 case SCRBS_PRESSED: | |
579 gfx_state = ui::NativeTheme::kPressed; | |
580 extra->is_hovering = false; | |
581 break; | |
582 case SCRBS_DISABLED: | |
583 gfx_state = ui::NativeTheme::kDisabled; | |
584 extra->is_hovering = false; | |
585 break; | |
586 default: | |
587 NOTREACHED() << "Invalid state: " << state; | |
588 break; | |
589 } | |
590 return gfx_state; | |
591 } | |
592 | |
593 void WebThemeEngineImpl::paintScrollbarThumb( | |
594 WebCanvas* canvas, int part, int state, int classic_state, | |
595 const WebRect& rect) { | |
596 ui::NativeTheme::Part native_part; | |
597 if (part == SBP_THUMBBTNHORZ) { | |
598 native_part = ui::NativeTheme::kScrollbarHorizontalThumb; | |
599 } else if (part == SBP_THUMBBTNVERT) { | |
600 native_part = ui::NativeTheme::kScrollbarVerticalThumb; | |
601 } else if (part == SBP_GRIPPERHORZ) { | |
602 native_part = ui::NativeTheme::kScrollbarHorizontalGripper; | |
603 } else if (part == SBP_GRIPPERVERT) { | |
604 native_part = ui::NativeTheme::kScrollbarVerticalGripper; | |
605 } else { | |
606 NOTREACHED() << "Invalid part: " << part; | |
607 } | |
608 | |
609 ui::NativeTheme::ExtraParams extra; | |
610 ui::NativeTheme::State native_state = WebScrollbarThumbStateToGfx( | |
611 state, &extra.scrollbar_thumb); | |
612 | |
613 gfx::Rect gfx_rect(rect.x, rect.y, rect.width, rect.height); | |
614 ui::NativeTheme::instance()->Paint(canvas, native_part, | |
615 native_state, gfx_rect, extra); | |
616 } | |
617 | |
618 static ui::NativeTheme::State WebScrollbarTrackStateToGfx( | |
619 int part, int state, ui::NativeTheme::Part* gfx_part, | |
620 ui::NativeTheme::ScrollbarTrackExtraParams* extra) { | |
621 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal; | |
622 switch (part) { | |
623 case SBP_LOWERTRACKHORZ: | |
624 switch (state) { | |
625 case SCRBS_NORMAL: | |
626 gfx_state = ui::NativeTheme::kNormal; | |
627 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack; | |
628 extra->is_upper = false; | |
629 break; | |
630 case SCRBS_HOVER: | |
631 case SCRBS_HOT: | |
632 gfx_state = ui::NativeTheme::kHovered; | |
633 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack; | |
634 extra->is_upper = false; | |
635 break; | |
636 case SCRBS_PRESSED: | |
637 gfx_state = ui::NativeTheme::kPressed; | |
638 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack; | |
639 extra->is_upper = false; | |
640 break; | |
641 case SCRBS_DISABLED: | |
642 gfx_state = ui::NativeTheme::kDisabled; | |
643 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack; | |
644 extra->is_upper = false; | |
645 break; | |
646 default: | |
647 NOTREACHED() << "Invalid state: " << state; | |
648 break; | |
649 } | |
650 break; | |
651 case SBP_UPPERTRACKHORZ: | |
652 switch (state) { | |
653 case SCRBS_NORMAL: | |
654 gfx_state = ui::NativeTheme::kNormal; | |
655 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack; | |
656 extra->is_upper = true; | |
657 break; | |
658 case SCRBS_HOVER: | |
659 case SCRBS_HOT: | |
660 gfx_state = ui::NativeTheme::kHovered; | |
661 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack; | |
662 extra->is_upper = true; | |
663 break; | |
664 case SCRBS_PRESSED: | |
665 gfx_state = ui::NativeTheme::kPressed; | |
666 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack; | |
667 extra->is_upper = true; | |
668 break; | |
669 case SCRBS_DISABLED: | |
670 gfx_state = ui::NativeTheme::kDisabled; | |
671 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack; | |
672 extra->is_upper = true; | |
673 break; | |
674 default: | |
675 NOTREACHED() << "Invalid state: " << state; | |
676 break; | |
677 } | |
678 break; | |
679 case SBP_LOWERTRACKVERT: | |
680 switch (state) { | |
681 case SCRBS_NORMAL: | |
682 gfx_state = ui::NativeTheme::kNormal; | |
683 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack; | |
684 extra->is_upper = false; | |
685 break; | |
686 case SCRBS_HOVER: | |
687 case SCRBS_HOT: | |
688 gfx_state = ui::NativeTheme::kHovered; | |
689 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack; | |
690 extra->is_upper = false; | |
691 break; | |
692 case SCRBS_PRESSED: | |
693 gfx_state = ui::NativeTheme::kPressed; | |
694 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack; | |
695 extra->is_upper = false; | |
696 break; | |
697 case SCRBS_DISABLED: | |
698 gfx_state = ui::NativeTheme::kDisabled; | |
699 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack; | |
700 extra->is_upper = false; | |
701 break; | |
702 default: | |
703 NOTREACHED() << "Invalid state: " << state; | |
704 break; | |
705 } | |
706 break; | |
707 case SBP_UPPERTRACKVERT: | |
708 switch (state) { | |
709 case SCRBS_NORMAL: | |
710 gfx_state = ui::NativeTheme::kNormal; | |
711 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack; | |
712 extra->is_upper = true; | |
713 break; | |
714 case SCRBS_HOVER: | |
715 case SCRBS_HOT: | |
716 gfx_state = ui::NativeTheme::kHovered; | |
717 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack; | |
718 extra->is_upper = true; | |
719 break; | |
720 case SCRBS_PRESSED: | |
721 gfx_state = ui::NativeTheme::kPressed; | |
722 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack; | |
723 extra->is_upper = true; | |
724 break; | |
725 case SCRBS_DISABLED: | |
726 gfx_state = ui::NativeTheme::kDisabled; | |
727 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack; | |
728 extra->is_upper = true; | |
729 break; | |
730 default: | |
731 NOTREACHED() << "Invalid state: " << state; | |
732 break; | |
733 } | |
734 break; | |
735 default: | |
736 NOTREACHED() << "Invalid part: " << part; | |
737 break; | |
738 } | |
739 return gfx_state; | |
740 } | |
741 | |
742 void WebThemeEngineImpl::paintScrollbarTrack( | |
743 WebCanvas* canvas, int part, int state, int classic_state, | |
744 const WebRect& rect, const WebRect& align_rect) { | |
745 ui::NativeTheme::Part native_part; | |
746 ui::NativeTheme::ExtraParams extra; | |
747 ui::NativeTheme::State native_state = WebScrollbarTrackStateToGfx( | |
748 part, state, &native_part, &extra.scrollbar_track); | |
749 extra.scrollbar_track.classic_state = classic_state; | |
750 extra.scrollbar_track.track_x = align_rect.x; | |
751 extra.scrollbar_track.track_y = align_rect.y; | |
752 extra.scrollbar_track.track_width = align_rect.width; | |
753 extra.scrollbar_track.track_height = align_rect.height; | |
754 | |
755 gfx::Rect gfx_rect(rect.x, rect.y, rect.width, rect.height); | |
756 ui::NativeTheme::instance()->Paint(canvas, native_part, | |
757 native_state, gfx_rect, extra); | |
758 } | |
759 | |
760 static ui::NativeTheme::State WebSpinButtonStateToGfx( | |
761 int part, int state, ui::NativeTheme::InnerSpinButtonExtraParams* extra) { | |
762 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal; | |
763 switch (part) { | |
764 case SPNP_UP: | |
765 switch (state) { | |
766 case UPS_NORMAL: | |
767 gfx_state = ui::NativeTheme::kNormal; | |
768 extra->spin_up = true; | |
769 extra->read_only = false; | |
770 break; | |
771 case UPS_HOT: | |
772 gfx_state = ui::NativeTheme::kHovered; | |
773 extra->spin_up = true; | |
774 extra->read_only = false; | |
775 break; | |
776 case UPS_PRESSED: | |
777 gfx_state = ui::NativeTheme::kPressed; | |
778 extra->spin_up = true; | |
779 extra->read_only = false; | |
780 break; | |
781 case UPS_DISABLED: | |
782 gfx_state = ui::NativeTheme::kDisabled; | |
783 extra->spin_up = true; | |
784 extra->read_only = false; | |
785 break; | |
786 default: | |
787 NOTREACHED() << "Invalid state: " << state; | |
788 break; | |
789 } | |
790 break; | |
791 case SPNP_DOWN: | |
792 switch (state) { | |
793 case DNS_NORMAL: | |
794 gfx_state = ui::NativeTheme::kNormal; | |
795 extra->spin_up = false; | |
796 extra->read_only = false; | |
797 break; | |
798 case DNS_HOT: | |
799 gfx_state = ui::NativeTheme::kHovered; | |
800 extra->spin_up = false; | |
801 extra->read_only = false; | |
802 break; | |
803 case DNS_PRESSED: | |
804 gfx_state = ui::NativeTheme::kPressed; | |
805 extra->spin_up = false; | |
806 extra->read_only = false; | |
807 break; | |
808 case DNS_DISABLED: | |
809 gfx_state = ui::NativeTheme::kDisabled; | |
810 extra->spin_up = false; | |
811 extra->read_only = false; | |
812 break; | |
813 default: | |
814 NOTREACHED() << "Invalid state: " << state; | |
815 break; | |
816 } | |
817 break; | |
818 default: | |
819 NOTREACHED() << "Invalid part: " << part; | |
820 break; | |
821 } | |
822 return gfx_state; | |
823 } | |
824 | |
825 void WebThemeEngineImpl::paintSpinButton( | |
826 WebCanvas* canvas, int part, int state, int classic_state, | |
827 const WebRect& rect) { | |
828 ui::NativeTheme::ExtraParams extra; | |
829 ui::NativeTheme::State native_state = WebSpinButtonStateToGfx( | |
830 part, state, &extra.inner_spin); | |
831 extra.inner_spin.classic_state = classic_state; | |
832 gfx::Rect gfx_rect(rect.x, rect.y, rect.width, rect.height); | |
833 ui::NativeTheme::instance()->Paint(canvas, | |
834 ui::NativeTheme::kInnerSpinButton, | |
835 native_state, | |
836 gfx_rect, | |
837 extra); | |
838 } | |
839 | |
840 static ui::NativeTheme::State WebTextFieldStateToGfx( | |
841 int part, int state, ui::NativeTheme::TextFieldExtraParams* extra) { | |
842 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal; | |
843 switch (part) { | |
844 case EP_EDITTEXT: | |
845 switch (state) { | |
846 case ETS_NORMAL: | |
847 gfx_state = ui::NativeTheme::kNormal; | |
848 extra->is_read_only = false; | |
849 extra->is_focused = false; | |
850 break; | |
851 case ETS_HOT: | |
852 gfx_state = ui::NativeTheme::kHovered; | |
853 extra->is_read_only = false; | |
854 extra->is_focused = false; | |
855 break; | |
856 case ETS_SELECTED: | |
857 gfx_state = ui::NativeTheme::kPressed; | |
858 extra->is_read_only = false; | |
859 extra->is_focused = false; | |
860 break; | |
861 case ETS_DISABLED: | |
862 gfx_state = ui::NativeTheme::kDisabled; | |
863 extra->is_read_only = false; | |
864 extra->is_focused = false; | |
865 break; | |
866 case ETS_FOCUSED: | |
867 gfx_state = ui::NativeTheme::kNormal; | |
868 extra->is_read_only = false; | |
869 extra->is_focused = true; | |
870 break; | |
871 case ETS_READONLY: | |
872 gfx_state = ui::NativeTheme::kNormal; | |
873 extra->is_read_only = true; | |
874 extra->is_focused = false; | |
875 break; | |
876 default: | |
877 NOTREACHED() << "Invalid state: " << state; | |
878 break; | |
879 } | |
880 break; | |
881 default: | |
882 NOTREACHED() << "Invalid part: " << part; | |
883 break; | |
884 } | |
885 return gfx_state; | |
886 } | |
887 | |
888 void WebThemeEngineImpl::paintTextField( | |
889 WebCanvas* canvas, int part, int state, int classic_state, | |
890 const WebRect& rect, WebColor color, bool fill_content_area, | |
891 bool draw_edges) { | |
892 ui::NativeTheme::ExtraParams extra; | |
893 ui::NativeTheme::State native_state = WebTextFieldStateToGfx( | |
894 part, state, &extra.text_field); | |
895 extra.text_field.fill_content_area = fill_content_area; | |
896 extra.text_field.draw_edges = draw_edges; | |
897 extra.text_field.background_color = color; | |
898 extra.text_field.classic_state = classic_state; | |
899 gfx::Rect gfx_rect(rect.x, rect.y, rect.width, rect.height); | |
900 | |
901 ui::NativeTheme::instance()->Paint(canvas, | |
902 ui::NativeTheme::kTextField, native_state, gfx_rect, extra); | |
903 } | |
904 | |
905 static ui::NativeTheme::State WebTrackbarStateToGfx( | |
906 int part, | |
907 int state, | |
908 ui::NativeTheme::TrackbarExtraParams* extra) { | |
909 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal; | |
910 switch (state) { | |
911 case TUS_NORMAL: | |
912 gfx_state = ui::NativeTheme::kNormal; | |
913 break; | |
914 case TUS_HOT: | |
915 gfx_state = ui::NativeTheme::kHovered; | |
916 break; | |
917 case TUS_PRESSED: | |
918 gfx_state = ui::NativeTheme::kPressed; | |
919 break; | |
920 case TUS_DISABLED: | |
921 gfx_state = ui::NativeTheme::kDisabled; | |
922 break; | |
923 default: | |
924 NOTREACHED() << "Invalid state: " << state; | |
925 break; | |
926 } | |
927 | |
928 switch (part) { | |
929 case TKP_TRACK: | |
930 case TKP_THUMBBOTTOM: | |
931 extra->vertical = false; | |
932 break; | |
933 case TKP_TRACKVERT: | |
934 case TKP_THUMBVERT: | |
935 extra->vertical = true; | |
936 break; | |
937 default: | |
938 NOTREACHED() << "Invalid part: " << part; | |
939 break; | |
940 } | |
941 | |
942 return gfx_state; | |
943 } | |
944 | |
945 void WebThemeEngineImpl::paintTrackbar( | |
946 WebCanvas* canvas, int part, int state, int classic_state, | |
947 const WebRect& rect) { | |
948 ui::NativeTheme::Part native_part = ui::NativeTheme::kTrackbarTrack; | |
949 switch (part) { | |
950 case TKP_TRACK: | |
951 case TKP_TRACKVERT: | |
952 native_part = ui::NativeTheme::kTrackbarTrack; | |
953 break; | |
954 case TKP_THUMBBOTTOM: | |
955 case TKP_THUMBVERT: | |
956 native_part = ui::NativeTheme::kTrackbarThumb; | |
957 break; | |
958 default: | |
959 NOTREACHED() << "Invalid part: " << part; | |
960 break; | |
961 } | |
962 | |
963 ui::NativeTheme::ExtraParams extra; | |
964 ui::NativeTheme::State native_state = WebTrackbarStateToGfx(part, state, | |
965 &extra.trackbar); | |
966 gfx::Rect gfx_rect(rect.x, rect.y, rect.width, rect.height); | |
967 extra.trackbar.classic_state = classic_state; | |
968 ui::NativeTheme::instance()->Paint(canvas, native_part, | |
969 native_state, gfx_rect, extra); | |
970 } | |
971 | |
972 void WebThemeEngineImpl::paintProgressBar( | |
973 WebCanvas* canvas, const WebRect& barRect, const WebRect& valueRect, | |
974 bool determinate, double animatedSeconds) | |
975 { | |
976 gfx::Rect gfx_rect(barRect.x, barRect.y, barRect.width, barRect.height); | |
977 ui::NativeTheme::ExtraParams extra; | |
978 extra.progress_bar.animated_seconds = animatedSeconds; | |
979 extra.progress_bar.determinate = determinate; | |
980 extra.progress_bar.value_rect_x = valueRect.x; | |
981 extra.progress_bar.value_rect_y = valueRect.y; | |
982 extra.progress_bar.value_rect_width = valueRect.width; | |
983 extra.progress_bar.value_rect_height = valueRect.height; | |
984 ui::NativeTheme::instance()->Paint(canvas, ui::NativeTheme::kProgressBar, | |
985 ui::NativeTheme::kNormal, gfx_rect, | |
986 extra); | |
987 } | |
988 | |
989 WebSize WebThemeEngineImpl::getSize(int part) { | |
990 switch (part) { | |
991 case SBP_ARROWBTN: { | |
992 gfx::Size size = ui::NativeTheme::instance()->GetPartSize( | |
993 ui::NativeTheme::kScrollbarUpArrow, | |
994 ui::NativeTheme::kNormal, | |
995 ui::NativeTheme::ExtraParams()); | |
996 // GetPartSize returns a size of (0, 0) when not using a themed style | |
997 // (i.e. Windows Classic). Returning a non-zero size in this context | |
998 // creates repaint conflicts, particularly in the window titlebar area | |
999 // which significantly degrades performance. Fallback to using a system | |
1000 // metric if required. | |
1001 if (size.width() == 0) { | |
1002 int width = static_cast<int>(GetSystemMetrics(SM_CXVSCROLL) / | |
1003 gfx::win::GetDeviceScaleFactor()); | |
1004 size = gfx::Size(width, width); | |
1005 } | |
1006 return WebSize(size.width(), size.height()); | |
1007 } | |
1008 default: | |
1009 NOTREACHED() << "Unhandled part: " << part; | |
1010 } | |
1011 return WebSize(); | |
1012 } | |
1013 | |
1014 } // namespace content | |
OLD | NEW |