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/canvas.h" 12 #include "ui/gfx/color_utils.h" 13 #include "ui/gfx/image/image_skia.h" 14 #include "ui/gfx/rect.h" 15 #include "ui/gfx/skia_util.h" 16 #include "ui/gfx/sys_color_change_listener.h" 17 18 namespace { 19 20 // Theme colors returned by GetSystemColor(). 21 22 // MenuItem: 23 const SkColor kMenuBackgroundColor = SK_ColorWHITE; 24 const SkColor kMenuHighlightBackgroundColor = SkColorSetRGB(0x42, 0x81, 0xF4); 25 const SkColor kMenuInvertedSchemeHighlightBackgroundColor = 26 SkColorSetRGB(48, 48, 48); 27 const SkColor kMenuBorderColor = SkColorSetRGB(0xBA, 0xBA, 0xBA); 28 const SkColor kEnabledMenuButtonBorderColor = SkColorSetARGB(36, 0, 0, 0); 29 const SkColor kFocusedMenuButtonBorderColor = SkColorSetARGB(72, 0, 0, 0); 30 const SkColor kHoverMenuButtonBorderColor = SkColorSetARGB(72, 0, 0, 0); 31 const SkColor kMenuSeparatorColor = SkColorSetRGB(0xE9, 0xE9, 0xE9); 32 const SkColor kEnabledMenuItemForegroundColor = SK_ColorBLACK; 33 const SkColor kDisabledMenuItemForegroundColor = SkColorSetRGB(161, 161, 146); 34 const SkColor kHoverMenuItemBackgroundColor = 35 SkColorSetARGB(204, 255, 255, 255); 36 // Button: 37 const SkColor kButtonHoverBackgroundColor = SkColorSetRGB(0xEA, 0xEA, 0xEA); 38 const SkColor kBlueButtonEnabledColor = SK_ColorWHITE; 39 const SkColor kBlueButtonDisabledColor = SK_ColorWHITE; 40 const SkColor kBlueButtonHighlightColor = SK_ColorWHITE; 41 const SkColor kBlueButtonHoverColor = SK_ColorWHITE; 42 43 } // namespace 44 45 namespace ui { 46 47 bool CommonThemeGetSystemColor(NativeTheme::ColorId color_id, SkColor* color) { 48 switch (color_id) { 49 // MenuItem 50 case NativeTheme::kColorId_MenuBorderColor: 51 *color = kMenuBorderColor; 52 break; 53 case NativeTheme::kColorId_EnabledMenuButtonBorderColor: 54 *color = kEnabledMenuButtonBorderColor; 55 break; 56 case NativeTheme::kColorId_FocusedMenuButtonBorderColor: 57 *color = kFocusedMenuButtonBorderColor; 58 break; 59 case NativeTheme::kColorId_HoverMenuButtonBorderColor: 60 *color = kHoverMenuButtonBorderColor; 61 break; 62 case NativeTheme::kColorId_MenuSeparatorColor: 63 *color = kMenuSeparatorColor; 64 break; 65 case NativeTheme::kColorId_MenuBackgroundColor: 66 *color = kMenuBackgroundColor; 67 break; 68 case NativeTheme::kColorId_FocusedMenuItemBackgroundColor: 69 *color = kMenuHighlightBackgroundColor; 70 break; 71 case NativeTheme::kColorId_HoverMenuItemBackgroundColor: 72 *color = kHoverMenuItemBackgroundColor; 73 break; 74 case NativeTheme::kColorId_EnabledMenuItemForegroundColor: 75 *color = kEnabledMenuItemForegroundColor; 76 break; 77 case NativeTheme::kColorId_DisabledMenuItemForegroundColor: 78 *color = kDisabledMenuItemForegroundColor; 79 break; 80 case NativeTheme::kColorId_DisabledEmphasizedMenuItemForegroundColor: 81 *color = SK_ColorBLACK; 82 break; 83 case NativeTheme::kColorId_SelectedMenuItemForegroundColor: 84 *color = SK_ColorWHITE; 85 break; 86 case NativeTheme::kColorId_ButtonDisabledColor: 87 *color = kDisabledMenuItemForegroundColor; 88 break; 89 // Button 90 case NativeTheme::kColorId_ButtonHoverBackgroundColor: 91 *color = kButtonHoverBackgroundColor; 92 break; 93 case NativeTheme::kColorId_BlueButtonEnabledColor: 94 *color = kBlueButtonEnabledColor; 95 break; 96 case NativeTheme::kColorId_BlueButtonDisabledColor: 97 *color = kBlueButtonDisabledColor; 98 break; 99 case NativeTheme::kColorId_BlueButtonHighlightColor: 100 *color = kBlueButtonHighlightColor; 101 break; 102 case NativeTheme::kColorId_BlueButtonHoverColor: 103 *color = kBlueButtonHoverColor; 104 break; 105 default: 106 return false; 107 } 108 109 if (gfx::IsInvertedColorScheme()) { 110 switch (color_id) { 111 case NativeTheme::kColorId_FocusedMenuItemBackgroundColor: 112 *color = kMenuInvertedSchemeHighlightBackgroundColor; 113 break; 114 default: 115 *color = color_utils::InvertColor(*color); 116 } 117 } 118 return true; 119 } 120 121 gfx::Size CommonThemeGetPartSize(NativeTheme::Part part, 122 NativeTheme::State state, 123 const NativeTheme::ExtraParams& extra) { 124 gfx::Size size; 125 switch (part) { 126 case NativeTheme::kComboboxArrow: 127 return ui::ResourceBundle::GetSharedInstance().GetImageNamed( 128 IDR_MENU_DROPARROW).Size(); 129 130 case NativeTheme::kMenuCheck: { 131 const gfx::ImageSkia* check = 132 ui::ResourceBundle::GetSharedInstance().GetImageNamed( 133 IDR_MENU_CHECK_CHECKED).ToImageSkia(); 134 size.SetSize(check->width(), check->height()); 135 break; 136 } 137 default: 138 break; 139 } 140 141 return size; 142 } 143 144 void CommonThemePaintComboboxArrow(SkCanvas* canvas, const gfx::Rect& rect) { 145 gfx::ImageSkia* arrow = ui::ResourceBundle::GetSharedInstance(). 146 GetImageSkiaNamed(IDR_MENU_DROPARROW); 147 CommonThemeCreateCanvas(canvas)->DrawImageInt(*arrow, rect.x(), rect.y()); 148 } 149 150 void CommonThemePaintMenuSeparator( 151 SkCanvas* canvas, 152 const gfx::Rect& rect, 153 const NativeTheme::MenuSeparatorExtraParams& extra) { 154 SkColor color; 155 CommonThemeGetSystemColor(NativeTheme::kColorId_MenuSeparatorColor, &color); 156 SkPaint paint; 157 paint.setColor(kMenuSeparatorColor); 158 int position_y = rect.y() + rect.height() / 2; 159 canvas->drawLine(rect.x(), position_y, rect.right(), position_y, paint); 160 } 161 162 void CommonThemePaintMenuGutter(SkCanvas* canvas, const gfx::Rect& rect) { 163 SkColor color; 164 CommonThemeGetSystemColor(NativeTheme::kColorId_MenuSeparatorColor, &color); 165 SkPaint paint; 166 paint.setColor(kMenuSeparatorColor); 167 int position_x = rect.x() + rect.width() / 2; 168 canvas->drawLine(position_x, rect.y(), position_x, rect.bottom(), paint); 169 } 170 171 void CommonThemePaintMenuBackground(SkCanvas* canvas, const gfx::Rect& rect) { 172 SkColor color; 173 CommonThemeGetSystemColor(NativeTheme::kColorId_MenuBackgroundColor, &color); 174 SkPaint paint; 175 paint.setColor(color); 176 canvas->drawRect(gfx::RectToSkRect(rect), paint); 177 } 178 179 void CommonThemePaintMenuItemBackground(SkCanvas* canvas, 180 NativeTheme::State state, 181 const gfx::Rect& rect) { 182 SkColor color; 183 SkPaint paint; 184 switch (state) { 185 case NativeTheme::kNormal: 186 case NativeTheme::kDisabled: 187 CommonThemeGetSystemColor(NativeTheme::kColorId_MenuBackgroundColor, 188 &color); 189 paint.setColor(color); 190 break; 191 case NativeTheme::kHovered: 192 CommonThemeGetSystemColor( 193 NativeTheme::kColorId_FocusedMenuItemBackgroundColor, &color); 194 paint.setColor(color); 195 break; 196 default: 197 NOTREACHED() << "Invalid state " << state; 198 break; 199 } 200 canvas->drawRect(gfx::RectToSkRect(rect), paint); 201 } 202 203 // static 204 scoped_ptr<gfx::Canvas> CommonThemeCreateCanvas(SkCanvas* sk_canvas) { 205 // TODO(pkotwicz): Do something better and don't infer device 206 // scale factor from canvas scale. 207 SkMatrix m = sk_canvas->getTotalMatrix(); 208 float device_scale = static_cast<float>(SkScalarAbs(m.getScaleX())); 209 return scoped_ptr<gfx::Canvas>( 210 gfx::Canvas::CreateCanvasWithoutScaling(sk_canvas, device_scale)); 211 } 212 213 } // namespace ui 214