1 // Copyright (c) 2012 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.
5 #include "webkit/child/webthemeengine_impl_win.h"
7 #include <vsstyle.h> // To convert to ui::NativeTheme::State
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"
16 using WebKit::WebCanvas;
17 using WebKit::WebColor;
18 using WebKit::WebRect;
19 using WebKit::WebSize;
21 namespace webkit_glue {
23 static RECT WebRectToRECT(const WebRect& rect) {
27 result.right = rect.x + rect.width;
28 result.bottom = rect.y + rect.height;
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);
41 if (part == BP_PUSHBUTTON) {
44 gfx_state = ui::NativeTheme::kNormal;
45 extra->checked = false;
46 extra->indeterminate = false;
47 extra->is_default = false;
50 gfx_state = ui::NativeTheme::kHovered;
51 extra->checked = false;
52 extra->indeterminate = false;
53 extra->is_default = false;
56 gfx_state = ui::NativeTheme::kPressed;
57 extra->checked = false;
58 extra->indeterminate = false;
59 extra->is_default = false;
62 gfx_state = ui::NativeTheme::kDisabled;
63 extra->checked = false;
64 extra->indeterminate = false;
65 extra->is_default = false;
68 gfx_state = ui::NativeTheme::kNormal;
69 extra->checked = false;
70 extra->indeterminate = false;
71 extra->is_default = true;
73 case PBS_DEFAULTED_ANIMATING:
74 gfx_state = ui::NativeTheme::kNormal;
75 extra->checked = false;
76 extra->indeterminate = false;
77 extra->is_default = true;
80 NOTREACHED() << "Invalid state: " << state;
82 } else if (part == BP_RADIOBUTTON) {
84 case RBS_UNCHECKEDNORMAL:
85 gfx_state = ui::NativeTheme::kNormal;
86 extra->checked = false;
87 extra->indeterminate = false;
88 extra->is_default = false;
90 case RBS_UNCHECKEDHOT:
91 gfx_state = ui::NativeTheme::kHovered;
92 extra->checked = false;
93 extra->indeterminate = false;
94 extra->is_default = false;
96 case RBS_UNCHECKEDPRESSED:
97 gfx_state = ui::NativeTheme::kPressed;
98 extra->checked = false;
99 extra->indeterminate = false;
100 extra->is_default = false;
102 case RBS_UNCHECKEDDISABLED:
103 gfx_state = ui::NativeTheme::kDisabled;
104 extra->checked = false;
105 extra->indeterminate = false;
106 extra->is_default = false;
108 case RBS_CHECKEDNORMAL:
109 gfx_state = ui::NativeTheme::kNormal;
110 extra->checked = true;
111 extra->indeterminate = false;
112 extra->is_default = false;
115 gfx_state = ui::NativeTheme::kHovered;
116 extra->checked = true;
117 extra->indeterminate = false;
118 extra->is_default = false;
120 case RBS_CHECKEDPRESSED:
121 gfx_state = ui::NativeTheme::kPressed;
122 extra->checked = true;
123 extra->indeterminate = false;
124 extra->is_default = false;
126 case RBS_CHECKEDDISABLED:
127 gfx_state = ui::NativeTheme::kDisabled;
128 extra->checked = true;
129 extra->indeterminate = false;
130 extra->is_default = false;
133 NOTREACHED() << "Invalid state: " << state;
136 } else if (part == BP_CHECKBOX) {
138 case CBS_UNCHECKEDNORMAL:
139 gfx_state = ui::NativeTheme::kNormal;
140 extra->checked = false;
141 extra->indeterminate = false;
142 extra->is_default = false;
144 case CBS_UNCHECKEDHOT:
145 gfx_state = ui::NativeTheme::kHovered;
146 extra->checked = false;
147 extra->indeterminate = false;
148 extra->is_default = false;
150 case CBS_UNCHECKEDPRESSED:
151 gfx_state = ui::NativeTheme::kPressed;
152 extra->checked = false;
153 extra->indeterminate = false;
154 extra->is_default = false;
156 case CBS_UNCHECKEDDISABLED:
157 gfx_state = ui::NativeTheme::kDisabled;
158 extra->checked = false;
159 extra->indeterminate = false;
160 extra->is_default = false;
162 case CBS_CHECKEDNORMAL:
163 gfx_state = ui::NativeTheme::kNormal;
164 extra->checked = true;
165 extra->indeterminate = false;
166 extra->is_default = false;
169 gfx_state = ui::NativeTheme::kHovered;
170 extra->checked = true;
171 extra->indeterminate = false;
172 extra->is_default = false;
174 case CBS_CHECKEDPRESSED:
175 gfx_state = ui::NativeTheme::kPressed;
176 extra->checked = true;
177 extra->indeterminate = false;
178 extra->is_default = false;
180 case CBS_CHECKEDDISABLED:
181 gfx_state = ui::NativeTheme::kDisabled;
182 extra->checked = true;
183 extra->indeterminate = false;
184 extra->is_default = false;
186 case CBS_MIXEDNORMAL:
187 gfx_state = ui::NativeTheme::kNormal;
188 extra->checked = false;
189 extra->indeterminate = true;
190 extra->is_default = false;
193 gfx_state = ui::NativeTheme::kHovered;
194 extra->checked = false;
195 extra->indeterminate = true;
196 extra->is_default = false;
198 case CBS_MIXEDPRESSED:
199 gfx_state = ui::NativeTheme::kPressed;
200 extra->checked = false;
201 extra->indeterminate = true;
202 extra->is_default = false;
204 case CBS_MIXEDDISABLED:
205 gfx_state = ui::NativeTheme::kDisabled;
206 extra->checked = false;
207 extra->indeterminate = true;
208 extra->is_default = false;
210 case CBS_IMPLICITNORMAL:
211 gfx_state = ui::NativeTheme::kNormal;
212 extra->checked = false;
213 extra->indeterminate = false;
214 extra->is_default = false;
216 case CBS_IMPLICITHOT:
217 gfx_state = ui::NativeTheme::kHovered;
218 extra->checked = false;
219 extra->indeterminate = false;
220 extra->is_default = false;
222 case CBS_IMPLICITPRESSED:
223 gfx_state = ui::NativeTheme::kPressed;
224 extra->checked = false;
225 extra->indeterminate = false;
226 extra->is_default = false;
228 case CBS_IMPLICITDISABLED:
229 gfx_state = ui::NativeTheme::kDisabled;
230 extra->checked = false;
231 extra->indeterminate = false;
232 extra->is_default = false;
234 case CBS_EXCLUDEDNORMAL:
235 gfx_state = ui::NativeTheme::kNormal;
236 extra->checked = false;
237 extra->indeterminate = false;
238 extra->is_default = false;
240 case CBS_EXCLUDEDHOT:
241 gfx_state = ui::NativeTheme::kHovered;
242 extra->checked = false;
243 extra->indeterminate = false;
244 extra->is_default = false;
246 case CBS_EXCLUDEDPRESSED:
247 gfx_state = ui::NativeTheme::kPressed;
248 extra->checked = false;
249 extra->indeterminate = false;
250 extra->is_default = false;
252 case CBS_EXCLUDEDDISABLED:
253 gfx_state = ui::NativeTheme::kDisabled;
254 extra->checked = false;
255 extra->indeterminate = false;
256 extra->is_default = false;
259 NOTREACHED() << "Invalid state: " << state;
262 } else if (part == BP_GROUPBOX) {
265 gfx_state = ui::NativeTheme::kNormal;
266 extra->checked = false;
267 extra->indeterminate = false;
268 extra->is_default = false;
271 gfx_state = ui::NativeTheme::kDisabled;
272 extra->checked = false;
273 extra->indeterminate = false;
274 extra->is_default = false;
277 NOTREACHED() << "Invalid state: " << state;
280 } else if (part == BP_COMMANDLINK) {
283 gfx_state = ui::NativeTheme::kNormal;
284 extra->checked = false;
285 extra->indeterminate = false;
286 extra->is_default = false;
289 gfx_state = ui::NativeTheme::kHovered;
290 extra->checked = false;
291 extra->indeterminate = false;
292 extra->is_default = false;
295 gfx_state = ui::NativeTheme::kPressed;
296 extra->checked = false;
297 extra->indeterminate = false;
298 extra->is_default = false;
301 gfx_state = ui::NativeTheme::kDisabled;
302 extra->checked = false;
303 extra->indeterminate = false;
304 extra->is_default = false;
306 case CMDLS_DEFAULTED:
307 gfx_state = ui::NativeTheme::kNormal;
308 extra->checked = false;
309 extra->indeterminate = false;
310 extra->is_default = true;
312 case CMDLS_DEFAULTED_ANIMATING:
313 gfx_state = ui::NativeTheme::kNormal;
314 extra->checked = false;
315 extra->indeterminate = false;
316 extra->is_default = true;
319 NOTREACHED() << "Invalid state: " << state;
322 } else if (part == BP_COMMANDLINKGLYPH) {
325 gfx_state = ui::NativeTheme::kNormal;
326 extra->checked = false;
327 extra->indeterminate = false;
328 extra->is_default = false;
331 gfx_state = ui::NativeTheme::kHovered;
332 extra->checked = false;
333 extra->indeterminate = false;
334 extra->is_default = false;
337 gfx_state = ui::NativeTheme::kPressed;
338 extra->checked = false;
339 extra->indeterminate = false;
340 extra->is_default = false;
342 case CMDLGS_DISABLED:
343 gfx_state = ui::NativeTheme::kDisabled;
344 extra->checked = false;
345 extra->indeterminate = false;
346 extra->is_default = false;
348 case CMDLGS_DEFAULTED:
349 gfx_state = ui::NativeTheme::kNormal;
350 extra->checked = false;
351 extra->indeterminate = false;
352 extra->is_default = true;
355 NOTREACHED() << "Invalid state: " << state;
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;
368 native_part = ui::NativeTheme::kPushButton;
371 native_part = ui::NativeTheme::kCheckbox;
374 native_part = ui::NativeTheme::kRadio;
377 NOTREACHED() << "Invalid part: " << part;
380 ui::NativeTheme::ExtraParams extra;
381 ui::NativeTheme::State native_state = WebButtonStateToGfx(part, state,
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);
389 static ui::NativeTheme::State WebListMenuStateToGfx(int part, int state) {
390 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal;
393 case CP_DROPDOWNBUTTON:
396 gfx_state = ui::NativeTheme::kNormal;
399 gfx_state = ui::NativeTheme::kHovered;
402 gfx_state = ui::NativeTheme::kPressed;
405 gfx_state = ui::NativeTheme::kDisabled;
408 NOTREACHED() << "Invalid state: " << state;
413 NOTREACHED() << "Invalid part: " << part;
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;
424 case CP_DROPDOWNBUTTON:
425 native_part = ui::NativeTheme::kMenuList;
428 NOTREACHED() << "Invalid part: " << part;
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);
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;
445 gfx_state = ui::NativeTheme::kNormal;
446 *part = ui::NativeTheme::kScrollbarUpArrow;
447 extra->is_hovering = false;
450 gfx_state = ui::NativeTheme::kHovered;
451 *part = ui::NativeTheme::kScrollbarUpArrow;
452 extra->is_hovering = false;
455 gfx_state = ui::NativeTheme::kPressed;
456 *part = ui::NativeTheme::kScrollbarUpArrow;
457 extra->is_hovering = false;
460 gfx_state = ui::NativeTheme::kDisabled;
461 *part = ui::NativeTheme::kScrollbarUpArrow;
462 extra->is_hovering = false;
465 gfx_state = ui::NativeTheme::kNormal;
466 *part = ui::NativeTheme::kScrollbarDownArrow;
467 extra->is_hovering = false;
470 gfx_state = ui::NativeTheme::kHovered;
471 *part = ui::NativeTheme::kScrollbarDownArrow;
472 extra->is_hovering = false;
474 case ABS_DOWNPRESSED:
475 gfx_state = ui::NativeTheme::kPressed;
476 *part = ui::NativeTheme::kScrollbarDownArrow;
477 extra->is_hovering = false;
479 case ABS_DOWNDISABLED:
480 gfx_state = ui::NativeTheme::kDisabled;
481 *part = ui::NativeTheme::kScrollbarDownArrow;
482 extra->is_hovering = false;
485 gfx_state = ui::NativeTheme::kNormal;
486 *part = ui::NativeTheme::kScrollbarLeftArrow;
487 extra->is_hovering = false;
490 gfx_state = ui::NativeTheme::kHovered;
491 *part = ui::NativeTheme::kScrollbarLeftArrow;
492 extra->is_hovering = false;
494 case ABS_LEFTPRESSED:
495 gfx_state = ui::NativeTheme::kPressed;
496 *part = ui::NativeTheme::kScrollbarLeftArrow;
497 extra->is_hovering = false;
499 case ABS_LEFTDISABLED:
500 gfx_state = ui::NativeTheme::kDisabled;
501 *part = ui::NativeTheme::kScrollbarLeftArrow;
502 extra->is_hovering = false;
504 case ABS_RIGHTNORMAL:
505 gfx_state = ui::NativeTheme::kNormal;
506 *part = ui::NativeTheme::kScrollbarRightArrow;
507 extra->is_hovering = false;
510 gfx_state = ui::NativeTheme::kHovered;
511 *part = ui::NativeTheme::kScrollbarRightArrow;
512 extra->is_hovering = false;
514 case ABS_RIGHTPRESSED:
515 gfx_state = ui::NativeTheme::kPressed;
516 *part = ui::NativeTheme::kScrollbarRightArrow;
517 extra->is_hovering = false;
519 case ABS_RIGHTDISABLED:
520 gfx_state = ui::NativeTheme::kDisabled;
521 *part = ui::NativeTheme::kScrollbarRightArrow;
522 extra->is_hovering = false;
525 gfx_state = ui::NativeTheme::kHovered;
526 *part = ui::NativeTheme::kScrollbarUpArrow;
527 extra->is_hovering = true;
530 gfx_state = ui::NativeTheme::kHovered;
531 *part = ui::NativeTheme::kScrollbarDownArrow;
532 extra->is_hovering = true;
535 gfx_state = ui::NativeTheme::kHovered;
536 *part = ui::NativeTheme::kScrollbarLeftArrow;
537 extra->is_hovering = true;
540 gfx_state = ui::NativeTheme::kHovered;
541 *part = ui::NativeTheme::kScrollbarRightArrow;
542 extra->is_hovering = true;
545 NOTREACHED() << "Invalid state: " << state;
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);
562 static ui::NativeTheme::State WebScrollbarThumbStateToGfx(
563 int state, ui::NativeTheme::ScrollbarThumbExtraParams* extra) {
564 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal;
567 gfx_state = ui::NativeTheme::kNormal;
568 extra->is_hovering = false;
571 gfx_state = ui::NativeTheme::kHovered;
572 extra->is_hovering = true;
575 gfx_state = ui::NativeTheme::kHovered;
576 extra->is_hovering = false;
579 gfx_state = ui::NativeTheme::kPressed;
580 extra->is_hovering = false;
583 gfx_state = ui::NativeTheme::kDisabled;
584 extra->is_hovering = false;
587 NOTREACHED() << "Invalid state: " << state;
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;
606 NOTREACHED() << "Invalid part: " << part;
609 ui::NativeTheme::ExtraParams extra;
610 ui::NativeTheme::State native_state = WebScrollbarThumbStateToGfx(
611 state, &extra.scrollbar_thumb);
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);
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;
623 case SBP_LOWERTRACKHORZ:
626 gfx_state = ui::NativeTheme::kNormal;
627 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack;
628 extra->is_upper = false;
632 gfx_state = ui::NativeTheme::kHovered;
633 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack;
634 extra->is_upper = false;
637 gfx_state = ui::NativeTheme::kPressed;
638 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack;
639 extra->is_upper = false;
642 gfx_state = ui::NativeTheme::kDisabled;
643 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack;
644 extra->is_upper = false;
647 NOTREACHED() << "Invalid state: " << state;
651 case SBP_UPPERTRACKHORZ:
654 gfx_state = ui::NativeTheme::kNormal;
655 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack;
656 extra->is_upper = true;
660 gfx_state = ui::NativeTheme::kHovered;
661 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack;
662 extra->is_upper = true;
665 gfx_state = ui::NativeTheme::kPressed;
666 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack;
667 extra->is_upper = true;
670 gfx_state = ui::NativeTheme::kDisabled;
671 *gfx_part = ui::NativeTheme::kScrollbarHorizontalTrack;
672 extra->is_upper = true;
675 NOTREACHED() << "Invalid state: " << state;
679 case SBP_LOWERTRACKVERT:
682 gfx_state = ui::NativeTheme::kNormal;
683 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack;
684 extra->is_upper = false;
688 gfx_state = ui::NativeTheme::kHovered;
689 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack;
690 extra->is_upper = false;
693 gfx_state = ui::NativeTheme::kPressed;
694 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack;
695 extra->is_upper = false;
698 gfx_state = ui::NativeTheme::kDisabled;
699 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack;
700 extra->is_upper = false;
703 NOTREACHED() << "Invalid state: " << state;
707 case SBP_UPPERTRACKVERT:
710 gfx_state = ui::NativeTheme::kNormal;
711 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack;
712 extra->is_upper = true;
716 gfx_state = ui::NativeTheme::kHovered;
717 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack;
718 extra->is_upper = true;
721 gfx_state = ui::NativeTheme::kPressed;
722 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack;
723 extra->is_upper = true;
726 gfx_state = ui::NativeTheme::kDisabled;
727 *gfx_part = ui::NativeTheme::kScrollbarVerticalTrack;
728 extra->is_upper = true;
731 NOTREACHED() << "Invalid state: " << state;
736 NOTREACHED() << "Invalid part: " << part;
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;
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);
760 static ui::NativeTheme::State WebSpinButtonStateToGfx(
761 int part, int state, ui::NativeTheme::InnerSpinButtonExtraParams* extra) {
762 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal;
767 gfx_state = ui::NativeTheme::kNormal;
768 extra->spin_up = true;
769 extra->read_only = false;
772 gfx_state = ui::NativeTheme::kHovered;
773 extra->spin_up = true;
774 extra->read_only = false;
777 gfx_state = ui::NativeTheme::kPressed;
778 extra->spin_up = true;
779 extra->read_only = false;
782 gfx_state = ui::NativeTheme::kDisabled;
783 extra->spin_up = true;
784 extra->read_only = false;
787 NOTREACHED() << "Invalid state: " << state;
794 gfx_state = ui::NativeTheme::kNormal;
795 extra->spin_up = false;
796 extra->read_only = false;
799 gfx_state = ui::NativeTheme::kHovered;
800 extra->spin_up = false;
801 extra->read_only = false;
804 gfx_state = ui::NativeTheme::kPressed;
805 extra->spin_up = false;
806 extra->read_only = false;
809 gfx_state = ui::NativeTheme::kDisabled;
810 extra->spin_up = false;
811 extra->read_only = false;
814 NOTREACHED() << "Invalid state: " << state;
819 NOTREACHED() << "Invalid part: " << part;
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,
840 static ui::NativeTheme::State WebTextFieldStateToGfx(
841 int part, int state, ui::NativeTheme::TextFieldExtraParams* extra) {
842 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal;
847 gfx_state = ui::NativeTheme::kNormal;
848 extra->is_read_only = false;
849 extra->is_focused = false;
852 gfx_state = ui::NativeTheme::kHovered;
853 extra->is_read_only = false;
854 extra->is_focused = false;
857 gfx_state = ui::NativeTheme::kPressed;
858 extra->is_read_only = false;
859 extra->is_focused = false;
862 gfx_state = ui::NativeTheme::kDisabled;
863 extra->is_read_only = false;
864 extra->is_focused = false;
867 gfx_state = ui::NativeTheme::kNormal;
868 extra->is_read_only = false;
869 extra->is_focused = true;
872 gfx_state = ui::NativeTheme::kNormal;
873 extra->is_read_only = true;
874 extra->is_focused = false;
877 NOTREACHED() << "Invalid state: " << state;
882 NOTREACHED() << "Invalid part: " << part;
888 void WebThemeEngineImpl::paintTextField(
889 WebCanvas* canvas, int part, int state, int classic_state,
890 const WebRect& rect, WebColor color, bool fill_content_area,
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);
901 ui::NativeTheme::instance()->Paint(canvas,
902 ui::NativeTheme::kTextField, native_state, gfx_rect, extra);
905 static ui::NativeTheme::State WebTrackbarStateToGfx(
908 ui::NativeTheme::TrackbarExtraParams* extra) {
909 ui::NativeTheme::State gfx_state = ui::NativeTheme::kNormal;
912 gfx_state = ui::NativeTheme::kNormal;
915 gfx_state = ui::NativeTheme::kHovered;
918 gfx_state = ui::NativeTheme::kPressed;
921 gfx_state = ui::NativeTheme::kDisabled;
924 NOTREACHED() << "Invalid state: " << state;
930 case TKP_THUMBBOTTOM:
931 extra->vertical = false;
935 extra->vertical = true;
938 NOTREACHED() << "Invalid part: " << part;
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;
952 native_part = ui::NativeTheme::kTrackbarTrack;
954 case TKP_THUMBBOTTOM:
956 native_part = ui::NativeTheme::kTrackbarThumb;
959 NOTREACHED() << "Invalid part: " << part;
963 ui::NativeTheme::ExtraParams extra;
964 ui::NativeTheme::State native_state = WebTrackbarStateToGfx(part, state,
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);
972 void WebThemeEngineImpl::paintProgressBar(
973 WebCanvas* canvas, const WebRect& barRect, const WebRect& valueRect,
974 bool determinate, double animatedSeconds)
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,
989 WebSize WebThemeEngineImpl::getSize(int part) {
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);
1006 return WebSize(size.width(), size.height());
1009 NOTREACHED() << "Unhandled part: " << part;
1014 } // namespace webkit_glue