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