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.
4
5#include "ui/native_theme/common_theme.h"
6
7#include "base/logging.h"
8#include "grit/ui_resources.h"
9#include "third_party/skia/include/core/SkCanvas.h"
10#include "ui/base/resource/resource_bundle.h"
11#include "ui/gfx/color_utils.h"
12#include "ui/gfx/image/image_skia.h"
13#include "ui/gfx/rect.h"
14#include "ui/gfx/skia_util.h"
15#include "ui/gfx/sys_color_change_listener.h"
16
17namespace {
18
19// Theme colors returned by GetSystemColor().
20
21// MenuItem:
22const SkColor kMenuBackgroundColor = SK_ColorWHITE;
23const SkColor kMenuHighlightBackgroundColor = SkColorSetRGB(0x42, 0x81, 0xF4);
24const SkColor kMenuInvertedSchemeHighlightBackgroundColor =
25    SkColorSetRGB(48, 48, 48);
26const SkColor kMenuBorderColor = SkColorSetRGB(0xBA, 0xBA, 0xBA);
27const SkColor kEnabledMenuButtonBorderColor = SkColorSetARGB(36, 0, 0, 0);
28const SkColor kFocusedMenuButtonBorderColor = SkColorSetARGB(72, 0, 0, 0);
29const SkColor kHoverMenuButtonBorderColor = SkColorSetARGB(72, 0, 0, 0);
30const SkColor kMenuSeparatorColor = SkColorSetRGB(0xE9, 0xE9, 0xE9);
31const SkColor kEnabledMenuItemForegroundColor = SK_ColorBLACK;
32const SkColor kDisabledMenuItemForegroundColor = SkColorSetRGB(161, 161, 146);
33const SkColor kHoverMenuItemBackgroundColor =
34    SkColorSetARGB(204, 255, 255, 255);
35
36}  // namespace
37
38namespace ui {
39
40bool CommonThemeGetSystemColor(NativeTheme::ColorId color_id, SkColor* color) {
41  switch (color_id) {
42    // MenuItem
43    case NativeTheme::kColorId_MenuBorderColor:
44      *color = kMenuBorderColor;
45      break;
46    case NativeTheme::kColorId_EnabledMenuButtonBorderColor:
47      *color = kEnabledMenuButtonBorderColor;
48      break;
49    case NativeTheme::kColorId_FocusedMenuButtonBorderColor:
50      *color = kFocusedMenuButtonBorderColor;
51      break;
52    case NativeTheme::kColorId_HoverMenuButtonBorderColor:
53      *color = kHoverMenuButtonBorderColor;
54      break;
55    case NativeTheme::kColorId_MenuSeparatorColor:
56      *color = kMenuSeparatorColor;
57      break;
58    case NativeTheme::kColorId_MenuBackgroundColor:
59      *color = kMenuBackgroundColor;
60      break;
61    case NativeTheme::kColorId_FocusedMenuItemBackgroundColor:
62      *color = kMenuHighlightBackgroundColor;
63      break;
64    case NativeTheme::kColorId_HoverMenuItemBackgroundColor:
65      *color = kHoverMenuItemBackgroundColor;
66      break;
67    case NativeTheme::kColorId_EnabledMenuItemForegroundColor:
68      *color = kEnabledMenuItemForegroundColor;
69      break;
70    case NativeTheme::kColorId_DisabledMenuItemForegroundColor:
71      *color = kDisabledMenuItemForegroundColor;
72      break;
73    case NativeTheme::kColorId_SelectedMenuItemForegroundColor:
74      *color = SK_ColorWHITE;
75      break;
76    case NativeTheme::kColorId_ButtonDisabledColor:
77      *color = kDisabledMenuItemForegroundColor;
78      break;
79    default:
80      return false;
81  }
82
83  if (gfx::IsInvertedColorScheme()) {
84    switch (color_id) {
85      case NativeTheme::kColorId_FocusedMenuItemBackgroundColor:
86        *color = kMenuInvertedSchemeHighlightBackgroundColor;
87        break;
88      default:
89        *color = color_utils::InvertColor(*color);
90    }
91  }
92  return true;
93}
94
95gfx::Size CommonThemeGetPartSize(NativeTheme::Part part,
96                                 NativeTheme::State state,
97                                 const NativeTheme::ExtraParams& extra) {
98  gfx::Size size;
99  switch (part) {
100    case NativeTheme::kMenuCheck: {
101      const gfx::ImageSkia* check =
102          ui::ResourceBundle::GetSharedInstance().GetImageNamed(
103              IDR_MENU_CHECK_CHECKED).ToImageSkia();
104      size.SetSize(check->width(), check->height());
105      break;
106    }
107    default:
108      break;
109  }
110
111  return size;
112}
113
114void CommonThemePaintMenuSeparator(
115    SkCanvas* canvas,
116    const gfx::Rect& rect,
117    const NativeTheme::MenuSeparatorExtraParams& extra) {
118  SkColor color;
119  CommonThemeGetSystemColor(NativeTheme::kColorId_MenuSeparatorColor, &color);
120  SkPaint paint;
121  paint.setColor(kMenuSeparatorColor);
122  int position_y = rect.y() + rect.height() / 2;
123  canvas->drawLine(rect.x(), position_y, rect.right(), position_y, paint);
124}
125
126void CommonThemePaintMenuGutter(SkCanvas* canvas, const gfx::Rect& rect) {
127  SkColor color;
128  CommonThemeGetSystemColor(NativeTheme::kColorId_MenuSeparatorColor, &color);
129  SkPaint paint;
130  paint.setColor(kMenuSeparatorColor);
131  int position_x = rect.x() + rect.width() / 2;
132  canvas->drawLine(position_x, rect.y(), position_x, rect.bottom(), paint);
133}
134
135void CommonThemePaintMenuBackground(SkCanvas* canvas, const gfx::Rect& rect) {
136  SkColor color;
137  CommonThemeGetSystemColor(NativeTheme::kColorId_MenuBackgroundColor, &color);
138  SkPaint paint;
139  paint.setColor(color);
140  canvas->drawRect(gfx::RectToSkRect(rect), paint);
141}
142
143void CommonThemePaintMenuItemBackground(SkCanvas* canvas,
144                                        NativeTheme::State state,
145                                        const gfx::Rect& rect) {
146  SkColor color;
147  SkPaint paint;
148  switch (state) {
149    case NativeTheme::kNormal:
150    case NativeTheme::kDisabled:
151      CommonThemeGetSystemColor(NativeTheme::kColorId_MenuBackgroundColor,
152                                &color);
153      paint.setColor(color);
154      break;
155    case NativeTheme::kHovered:
156      CommonThemeGetSystemColor(
157          NativeTheme::kColorId_FocusedMenuItemBackgroundColor, &color);
158      paint.setColor(color);
159      break;
160    default:
161      NOTREACHED() << "Invalid state " << state;
162      break;
163  }
164  canvas->drawRect(gfx::RectToSkRect(rect), paint);
165}
166
167}  // namespace ui
168