summaryrefslogtreecommitdiffstats
path: root/ui/gfx/native_theme_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ui/gfx/native_theme_win.cc')
-rw-r--r--ui/gfx/native_theme_win.cc310
1 files changed, 302 insertions, 8 deletions
diff --git a/ui/gfx/native_theme_win.cc b/ui/gfx/native_theme_win.cc
index b22973c..83f339f 100644
--- a/ui/gfx/native_theme_win.cc
+++ b/ui/gfx/native_theme_win.cc
@@ -54,7 +54,12 @@ void SetCheckerboardShader(SkPaint* paint, const RECT& align_rect) {
namespace gfx {
-/* static */
+// static
+const NativeTheme* NativeTheme::instance() {
+ return NativeThemeWin::instance();
+}
+
+// static
const NativeThemeWin* NativeThemeWin::instance() {
// The global NativeThemeWin instance.
static const NativeThemeWin s_native_theme;
@@ -100,10 +105,222 @@ NativeThemeWin::NativeThemeWin()
NativeThemeWin::~NativeThemeWin() {
if (theme_dll_) {
- // todo (cpu): fix this soon.
- // CloseHandles();
+ CloseHandles();
+
+ draw_theme_ = NULL;
+ draw_theme_ex_ = NULL;
+ get_theme_color_ = NULL;
+ get_theme_content_rect_ = NULL;
+ get_theme_part_size_ = NULL;
+ open_theme_ = NULL;
+ close_theme_ = NULL;
+ set_theme_properties_ = NULL;
+ is_theme_active_ = NULL;
+ get_theme_int_ = NULL;
FreeLibrary(theme_dll_);
+ theme_dll_ = NULL;
+ }
+}
+
+gfx::Size NativeThemeWin::GetPartSize(Part part) const {
+ HDC hdc = GetDC(NULL);
+ SIZE size;
+ HANDLE handle = GetThemeHandle(GetThemeName(part));
+ int part_win = GetWindowsPart(part);
+ HRESULT hr = get_theme_part_size_(handle, hdc, part_win, 0, NULL, TS_TRUE,
+ &size);
+ ReleaseDC(NULL, hdc);
+ return SUCCEEDED(hr) ? Size(size.cx, size.cy) : Size();
+}
+
+void NativeThemeWin::Paint(skia::PlatformCanvas* canvas,
+ Part part,
+ State state,
+ const gfx::Rect& rect,
+ const ExtraParams& extra) const {
+ HDC hdc = canvas->beginPlatformPaint();
+
+ switch (part) {
+ case kCheckbox:
+ PaintCheckbox(hdc, part, state, rect, extra.button);
+ break;
+ case kRadio:
+ PaintRadioButton(hdc, part, state, rect, extra.button);
+ break;
+ case kPushButton:
+ PaintPushButton(hdc, part, state, rect, extra.button);
+ break;
+ case kScrollbarDownArrow:
+ case kScrollbarUpArrow:
+ case kScrollbarLeftArrow:
+ case kScrollbarRightArrow:
+ case kScrollbarHorizontalThumb:
+ case kScrollbarVerticalThumb:
+ case kScrollbarHorizontalTrack:
+ case kScrollbarVerticalTrack:
+ case kTextField:
+ case kMenuList:
+ case kSliderTrack:
+ case kSliderThumb:
+ case kInnerSpinButton:
+ case kProgressBar:
+ default:
+ // While transitioning NativeThemeWin to the single Paint() entry point,
+ // unsupported parts will DCHECK here.
+ DCHECK(false);
+ }
+
+ canvas->endPlatformPaint();
+}
+
+HRESULT NativeThemeWin::PaintScrollbarArrow(HDC hdc,
+ Part direction,
+ State state,
+ const gfx::Rect& rect) const {
+ static int state_id[4][kMaxState] = {
+ ABS_DOWNDISABLED, ABS_DOWNHOT, ABS_DOWNNORMAL, ABS_DOWNPRESSED,
+ ABS_LEFTDISABLED, ABS_LEFTHOT, ABS_LEFTNORMAL, ABS_LEFTPRESSED,
+ ABS_RIGHTDISABLED, ABS_RIGHTHOT, ABS_RIGHTNORMAL, ABS_RIGHTPRESSED,
+ ABS_UPDISABLED, ABS_UPHOT, ABS_UPNORMAL, ABS_UPPRESSED
+ };
+
+ HANDLE handle = GetThemeHandle(SCROLLBAR);
+ if (handle && draw_theme_) {
+ int index = direction - kScrollbarDownArrow;
+ DCHECK(index >=0 && index < 4);
+ return draw_theme_(handle, hdc, SBP_ARROWBTN, state_id[index][state],
+ &rect.ToRECT(), NULL);
+ }
+
+ // TODO: Draw it manually.
+ RECT rect_win = rect.ToRECT();
+ DrawFrameControl(hdc, &rect_win, DFC_SCROLL, 0);
+ return S_OK;
+}
+
+HRESULT NativeThemeWin::PaintScrollbarThumb(HDC hdc,
+ Part part,
+ State state,
+ const gfx::Rect& rect) const {
+ int part_id;
+ if (part == kScrollbarHorizontalThumb) {
+ part_id = SBP_THUMBBTNHORZ;
+ } else if (part == kScrollbarHorizontalThumb) {
+ part_id = SBP_THUMBBTNVERT;
+ } else {
+ DCHECK(false);
+ }
+
+ static int state_id[kMaxState] = {
+ SCRBS_DISABLED, SCRBS_HOT, SCRBS_NORMAL, SCRBS_PRESSED
+ };
+
+ HANDLE handle = GetThemeHandle(SCROLLBAR);
+ if (handle && draw_theme_) {
+ return draw_theme_(handle, hdc, part_id, state_id[state],
+ &rect.ToRECT(), NULL);
+ }
+
+
+ // TODO: Draw it manually.
+ if ((part_id == SBP_THUMBBTNHORZ) || (part_id == SBP_THUMBBTNVERT)) {
+ RECT rect_win = rect.ToRECT();
+ DrawEdge(hdc, &rect_win, EDGE_RAISED, BF_RECT | BF_MIDDLE);
+ // Classic mode doesn't have a gripper.
+ }
+ return S_OK;
+}
+
+HRESULT NativeThemeWin::PaintPushButton(HDC hdc,
+ Part part,
+ State state,
+ const gfx::Rect& rect,
+ const ButtonExtraParams& extra) const {
+ int state_id;
+ switch(state) {
+ case kDisabled:
+ state_id = PBS_DISABLED;
+ break;
+ case kHovered:
+ state_id = PBS_HOT;
+ break;
+ case kNormal:
+ state_id = extra.is_default ? PBS_DEFAULTED : PBS_NORMAL;
+ break;
+ case kPressed:
+ state_id = PBS_PRESSED;
+ break;
+ default:
+ DCHECK(false);
+ }
+
+ RECT rect_win = rect.ToRECT();
+ return PaintButton(hdc, BP_PUSHBUTTON, state_id, extra.classic_state,
+ &rect_win);
+}
+
+HRESULT NativeThemeWin::PaintRadioButton(HDC hdc,
+ Part part,
+ State state,
+ const gfx::Rect& rect,
+ const ButtonExtraParams& extra) const {
+ int state_id;
+ switch(state) {
+ case kDisabled:
+ state_id = extra.checked ? RBS_CHECKEDDISABLED : RBS_UNCHECKEDDISABLED;
+ break;
+ case kHovered:
+ state_id = extra.checked ? RBS_CHECKEDHOT : RBS_UNCHECKEDHOT;
+ break;
+ case kNormal:
+ state_id = extra.checked ? RBS_CHECKEDNORMAL : RBS_UNCHECKEDNORMAL;
+ break;
+ case kPressed:
+ state_id = extra.checked ? RBS_CHECKEDPRESSED : RBS_UNCHECKEDPRESSED;
+ break;
+ default:
+ DCHECK(false);
}
+
+ RECT rect_win = rect.ToRECT();
+ return PaintButton(hdc, BP_RADIOBUTTON, state_id, extra.classic_state,
+ &rect_win);
+}
+
+HRESULT NativeThemeWin::PaintCheckbox(HDC hdc,
+ Part part,
+ State state,
+ const gfx::Rect& rect,
+ const ButtonExtraParams& extra) const {
+ int state_id;
+ switch(state) {
+ case kDisabled:
+ state_id = extra.checked ? CBS_CHECKEDDISABLED :
+ extra.indeterminate ? CBS_MIXEDDISABLED :
+ CBS_UNCHECKEDDISABLED;
+ break;
+ case kHovered:
+ state_id = extra.checked ? CBS_CHECKEDHOT :
+ extra.indeterminate ? CBS_MIXEDHOT :
+ CBS_UNCHECKEDHOT;
+ break;
+ case kNormal:
+ state_id = extra.checked ? CBS_CHECKEDNORMAL :
+ extra.indeterminate ? CBS_MIXEDNORMAL :
+ CBS_UNCHECKEDNORMAL;
+ break;
+ case kPressed:
+ state_id = extra.checked ? CBS_CHECKEDPRESSED :
+ extra.indeterminate ? CBS_MIXEDPRESSED :
+ CBS_UNCHECKEDPRESSED;
+ break;
+ default:
+ DCHECK(false);
+ }
+
+ RECT rect_win = rect.ToRECT();
+ return PaintButton(hdc, BP_CHECKBOX, state_id, extra.classic_state,
+ &rect_win);
}
HRESULT NativeThemeWin::PaintButton(HDC hdc,
@@ -798,15 +1015,15 @@ HRESULT NativeThemeWin::PaintFrameControl(HDC hdc,
return S_OK;
}
-void NativeThemeWin::CloseHandles() const
-{
+void NativeThemeWin::CloseHandles() const {
if (!close_theme_)
return;
for (int i = 0; i < LAST; ++i) {
- if (theme_handles_[i])
+ if (theme_handles_[i]) {
close_theme_(theme_handles_[i]);
theme_handles_[i] = NULL;
+ }
}
}
@@ -817,8 +1034,7 @@ bool NativeThemeWin::IsClassicTheme(ThemeName name) const {
return !GetThemeHandle(name);
}
-HANDLE NativeThemeWin::GetThemeHandle(ThemeName theme_name) const
-{
+HANDLE NativeThemeWin::GetThemeHandle(ThemeName theme_name) const {
if (!open_theme_ || theme_name < 0 || theme_name >= LAST)
return 0;
@@ -871,4 +1087,82 @@ HANDLE NativeThemeWin::GetThemeHandle(ThemeName theme_name) const
return handle;
}
+// static
+NativeThemeWin::ThemeName NativeThemeWin::GetThemeName(Part part) {
+ ThemeName name;
+ switch(part) {
+ case kScrollbarDownArrow:
+ case kScrollbarLeftArrow:
+ case kScrollbarRightArrow:
+ case kScrollbarUpArrow:
+ case kScrollbarHorizontalThumb:
+ case kScrollbarVerticalThumb:
+ case kScrollbarHorizontalTrack:
+ case kScrollbarVerticalTrack:
+ name = SCROLLBAR;
+ break;
+ case kCheckbox:
+ case kRadio:
+ case kPushButton:
+ name = BUTTON;
+ break;
+ case kTextField:
+ name = TEXTFIELD;
+ break;
+ case kMenuList:
+ name = MENU;
+ break;
+ case kSliderTrack:
+ case kSliderThumb:
+ name = TRACKBAR;
+ break;
+ case kInnerSpinButton:
+ name = SPIN;
+ break;
+ case kProgressBar:
+ name = PROGRESS;
+ break;
+ default:
+ DCHECK(false);
+ break;
+ }
+ return name;
+}
+
+// static
+int NativeThemeWin::GetWindowsPart(Part part) {
+ int part_id;
+ switch(part) {
+ case kCheckbox:
+ part_id = BP_CHECKBOX;
+ break;
+ case kRadio:
+ part_id = BP_RADIOBUTTON;
+ break;
+ case kPushButton:
+ part_id = BP_PUSHBUTTON;
+ break;
+ case kTextField:
+ case kMenuList:
+ case kSliderTrack:
+ case kSliderThumb:
+ case kInnerSpinButton:
+ case kProgressBar:
+ case kScrollbarDownArrow:
+ case kScrollbarLeftArrow:
+ case kScrollbarRightArrow:
+ case kScrollbarUpArrow:
+ case kScrollbarHorizontalThumb:
+ case kScrollbarVerticalThumb:
+ case kScrollbarHorizontalTrack:
+ case kScrollbarVerticalTrack:
+ default:
+ // While transitioning NativeThemeWin to the single Paint() entry point,
+ // unsupported parts will DCHECK here.
+ DCHECK(false);
+ break;
+ }
+ return part_id;
+}
+
} // namespace gfx