OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/native_theme_win.h" | 5 #include "ui/gfx/native_theme_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <uxtheme.h> | 8 #include <uxtheme.h> |
9 #include <vsstyle.h> | 9 #include <vsstyle.h> |
10 #include <vssym32.h> | 10 #include <vssym32.h> |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 const ExtraParams& extra) const { | 119 const ExtraParams& extra) const { |
120 SIZE size; | 120 SIZE size; |
121 int part_id = GetWindowsPart(part, state, extra); | 121 int part_id = GetWindowsPart(part, state, extra); |
122 int state_id = GetWindowsState(part, state, extra); | 122 int state_id = GetWindowsState(part, state, extra); |
123 | 123 |
124 HDC hdc = GetDC(NULL); | 124 HDC hdc = GetDC(NULL); |
125 HRESULT hr = GetThemePartSize(GetThemeName(part), hdc, part_id, state_id, | 125 HRESULT hr = GetThemePartSize(GetThemeName(part), hdc, part_id, state_id, |
126 NULL, TS_TRUE, &size); | 126 NULL, TS_TRUE, &size); |
127 ReleaseDC(NULL, hdc); | 127 ReleaseDC(NULL, hdc); |
128 | 128 |
129 return SUCCEEDED(hr) ? Size(size.cx, size.cy) : Size(); | 129 if (FAILED(hr)) { |
| 130 // TODO(rogerta): For now, we need to support radio buttons and checkboxes |
| 131 // when theming is not enabled. Support for other parts can be added |
| 132 // if/when needed. |
| 133 switch (part) { |
| 134 case kCheckbox: |
| 135 case kRadio: |
| 136 // TODO(rogerta): I was not able to find any API to get the default |
| 137 // size of these controls, so determined these values empirically. |
| 138 size.cx = 13; |
| 139 size.cy = 13; |
| 140 break; |
| 141 default: |
| 142 size.cx = 0; |
| 143 size.cy = 0; |
| 144 break; |
| 145 } |
| 146 } |
| 147 |
| 148 return Size(size.cx, size.cy); |
130 } | 149 } |
131 | 150 |
132 void NativeThemeWin::PaintToNonPlatformCanvas(SkCanvas* canvas, | 151 void NativeThemeWin::PaintToNonPlatformCanvas(SkCanvas* canvas, |
133 Part part, | 152 Part part, |
134 State state, | 153 State state, |
135 const gfx::Rect& rect, | 154 const gfx::Rect& rect, |
136 const ExtraParams& extra) const { | 155 const ExtraParams& extra) const { |
137 // TODO(asvitkine): This path is pretty inefficient - for each paint operation | 156 // TODO(asvitkine): This path is pretty inefficient - for each paint operation |
138 // it creates a new offscreen bitmap Skia canvas. This can | 157 // it creates a new offscreen bitmap Skia canvas. This can |
139 // be sped up by doing it only once per part/state and | 158 // be sped up by doing it only once per part/state and |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 break; | 509 break; |
491 case kPressed: | 510 case kPressed: |
492 state_id = PBS_PRESSED; | 511 state_id = PBS_PRESSED; |
493 break; | 512 break; |
494 default: | 513 default: |
495 NOTREACHED() << "Invalid state: " << state; | 514 NOTREACHED() << "Invalid state: " << state; |
496 break; | 515 break; |
497 } | 516 } |
498 | 517 |
499 RECT rect_win = rect.ToRECT(); | 518 RECT rect_win = rect.ToRECT(); |
500 return PaintButton(hdc, BP_PUSHBUTTON, state_id, extra.classic_state, | 519 return PaintButton(hdc, state, extra, BP_PUSHBUTTON, state_id, &rect_win); |
501 &rect_win); | |
502 } | 520 } |
503 | 521 |
504 HRESULT NativeThemeWin::PaintRadioButton(HDC hdc, | 522 HRESULT NativeThemeWin::PaintRadioButton(HDC hdc, |
505 Part part, | 523 Part part, |
506 State state, | 524 State state, |
507 const gfx::Rect& rect, | 525 const gfx::Rect& rect, |
508 const ButtonExtraParams& extra) const { | 526 const ButtonExtraParams& extra) const { |
509 int state_id; | 527 int state_id; |
510 switch(state) { | 528 switch(state) { |
511 case kDisabled: | 529 case kDisabled: |
512 state_id = extra.checked ? RBS_CHECKEDDISABLED : RBS_UNCHECKEDDISABLED; | 530 state_id = extra.checked ? RBS_CHECKEDDISABLED : RBS_UNCHECKEDDISABLED; |
513 break; | 531 break; |
514 case kHovered: | 532 case kHovered: |
515 state_id = extra.checked ? RBS_CHECKEDHOT : RBS_UNCHECKEDHOT; | 533 state_id = extra.checked ? RBS_CHECKEDHOT : RBS_UNCHECKEDHOT; |
516 break; | 534 break; |
517 case kNormal: | 535 case kNormal: |
518 state_id = extra.checked ? RBS_CHECKEDNORMAL : RBS_UNCHECKEDNORMAL; | 536 state_id = extra.checked ? RBS_CHECKEDNORMAL : RBS_UNCHECKEDNORMAL; |
519 break; | 537 break; |
520 case kPressed: | 538 case kPressed: |
521 state_id = extra.checked ? RBS_CHECKEDPRESSED : RBS_UNCHECKEDPRESSED; | 539 state_id = extra.checked ? RBS_CHECKEDPRESSED : RBS_UNCHECKEDPRESSED; |
522 break; | 540 break; |
523 default: | 541 default: |
524 NOTREACHED() << "Invalid state: " << state; | 542 NOTREACHED() << "Invalid state: " << state; |
525 break; | 543 break; |
526 } | 544 } |
527 | 545 |
528 RECT rect_win = rect.ToRECT(); | 546 RECT rect_win = rect.ToRECT(); |
529 return PaintButton(hdc, BP_RADIOBUTTON, state_id, extra.classic_state, | 547 return PaintButton(hdc, state, extra, BP_RADIOBUTTON, state_id, &rect_win); |
530 &rect_win); | |
531 } | 548 } |
532 | 549 |
533 HRESULT NativeThemeWin::PaintCheckbox(HDC hdc, | 550 HRESULT NativeThemeWin::PaintCheckbox(HDC hdc, |
534 Part part, | 551 Part part, |
535 State state, | 552 State state, |
536 const gfx::Rect& rect, | 553 const gfx::Rect& rect, |
537 const ButtonExtraParams& extra) const { | 554 const ButtonExtraParams& extra) const { |
538 int state_id; | 555 int state_id; |
539 switch(state) { | 556 switch(state) { |
540 case kDisabled: | 557 case kDisabled: |
(...skipping 15 matching lines...) Expand all Loading... |
556 state_id = extra.checked ? CBS_CHECKEDPRESSED : | 573 state_id = extra.checked ? CBS_CHECKEDPRESSED : |
557 extra.indeterminate ? CBS_MIXEDPRESSED : | 574 extra.indeterminate ? CBS_MIXEDPRESSED : |
558 CBS_UNCHECKEDPRESSED; | 575 CBS_UNCHECKEDPRESSED; |
559 break; | 576 break; |
560 default: | 577 default: |
561 NOTREACHED() << "Invalid state: " << state; | 578 NOTREACHED() << "Invalid state: " << state; |
562 break; | 579 break; |
563 } | 580 } |
564 | 581 |
565 RECT rect_win = rect.ToRECT(); | 582 RECT rect_win = rect.ToRECT(); |
566 return PaintButton(hdc, BP_CHECKBOX, state_id, extra.classic_state, | 583 return PaintButton(hdc, state, extra, BP_CHECKBOX, state_id, &rect_win); |
567 &rect_win); | |
568 } | 584 } |
569 | 585 |
570 HRESULT NativeThemeWin::PaintButton(HDC hdc, | 586 HRESULT NativeThemeWin::PaintButton(HDC hdc, |
| 587 State state, |
| 588 const ButtonExtraParams& extra, |
571 int part_id, | 589 int part_id, |
572 int state_id, | 590 int state_id, |
573 int classic_state, | |
574 RECT* rect) const { | 591 RECT* rect) const { |
575 HANDLE handle = GetThemeHandle(BUTTON); | 592 HANDLE handle = GetThemeHandle(BUTTON); |
576 if (handle && draw_theme_) | 593 if (handle && draw_theme_) |
577 return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); | 594 return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); |
578 | 595 |
| 596 // Adjust classic_state based on part, state, and extras. |
| 597 int classic_state = extra.classic_state; |
| 598 switch(part_id) { |
| 599 case BP_CHECKBOX: |
| 600 classic_state |= DFCS_BUTTONCHECK; |
| 601 break; |
| 602 case BP_RADIOBUTTON: |
| 603 classic_state |= DFCS_BUTTONRADIO; |
| 604 break; |
| 605 case BP_PUSHBUTTON: |
| 606 classic_state |= DFCS_BUTTONPUSH; |
| 607 break; |
| 608 default: |
| 609 NOTREACHED() << "Unknown part_id: " << part_id; |
| 610 break; |
| 611 } |
| 612 |
| 613 switch(state) { |
| 614 case kDisabled: |
| 615 classic_state |= DFCS_INACTIVE; |
| 616 break; |
| 617 case kPressed: |
| 618 classic_state |= DFCS_PUSHED; |
| 619 break; |
| 620 case kNormal: |
| 621 case kHovered: |
| 622 break; |
| 623 default: |
| 624 NOTREACHED() << "Unknown state: " << state; |
| 625 break; |
| 626 } |
| 627 |
| 628 if (extra.checked) |
| 629 classic_state |= DFCS_CHECKED; |
| 630 |
579 // Draw it manually. | 631 // Draw it manually. |
580 // All pressed states have both low bits set, and no other states do. | 632 // All pressed states have both low bits set, and no other states do. |
581 const bool focused = ((state_id & ETS_FOCUSED) == ETS_FOCUSED); | 633 const bool focused = ((state_id & ETS_FOCUSED) == ETS_FOCUSED); |
582 const bool pressed = ((state_id & PBS_PRESSED) == PBS_PRESSED); | 634 const bool pressed = ((state_id & PBS_PRESSED) == PBS_PRESSED); |
583 if ((BP_PUSHBUTTON == part_id) && (pressed || focused)) { | 635 if ((BP_PUSHBUTTON == part_id) && (pressed || focused)) { |
584 // BP_PUSHBUTTON has a focus rect drawn around the outer edge, and the | 636 // BP_PUSHBUTTON has a focus rect drawn around the outer edge, and the |
585 // button itself is shrunk by 1 pixel. | 637 // button itself is shrunk by 1 pixel. |
586 HBRUSH brush = GetSysColorBrush(COLOR_3DDKSHADOW); | 638 HBRUSH brush = GetSysColorBrush(COLOR_3DDKSHADOW); |
587 if (brush) { | 639 if (brush) { |
588 FrameRect(hdc, rect, brush); | 640 FrameRect(hdc, rect, brush); |
(...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 } | 1648 } |
1597 break; | 1649 break; |
1598 default: | 1650 default: |
1599 NOTREACHED() << "Invalid part: " << part; | 1651 NOTREACHED() << "Invalid part: " << part; |
1600 break; | 1652 break; |
1601 } | 1653 } |
1602 return state_id; | 1654 return state_id; |
1603 } | 1655 } |
1604 | 1656 |
1605 } // namespace gfx | 1657 } // namespace gfx |
OLD | NEW |