// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/native_theme/native_theme_aura.h" #include "base/logging.h" #include "grit/ui_resources.h" #include "ui/base/layout.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/path.h" #include "ui/gfx/rect.h" #include "ui/gfx/size.h" #include "ui/gfx/skbitmap_operations.h" #include "ui/native_theme/common_theme.h" namespace { const SkColor kMenuBackgroundColor = SK_ColorWHITE; // Theme colors returned by GetSystemColor(). const SkColor kInvalidColorIdColor = SkColorSetRGB(255, 0, 128); // Windows: const SkColor kWindowBackgroundColor = SK_ColorWHITE; // Dialogs: const SkColor kDialogBackgroundColor = SkColorSetRGB(251, 251, 251); // FocusableBorder: const SkColor kFocusedBorderColor = SkColorSetRGB(0x4D, 0x90, 0xFE); const SkColor kUnfocusedBorderColor = SkColorSetRGB(0xD9, 0xD9, 0xD9); // TextButton: const SkColor kTextButtonBackgroundColor = SkColorSetRGB(0xDE, 0xDE, 0xDE); const SkColor kTextButtonEnabledColor = SkColorSetRGB(0x22, 0x22, 0x22); const SkColor kTextButtonDisabledColor = SkColorSetRGB(0x99, 0x99, 0x99); const SkColor kTextButtonHighlightColor = SkColorSetRGB(0, 0, 0); const SkColor kTextButtonHoverColor = kTextButtonEnabledColor; // MenuItem: const SkColor kEnabledMenuItemForegroundColor = kTextButtonEnabledColor; const SkColor kDisabledMenuItemForegroundColor = kTextButtonDisabledColor; const SkColor kFocusedMenuItemBackgroundColor = SkColorSetRGB(0xF1, 0xF1, 0xF1); const SkColor kMenuSeparatorColor = SkColorSetRGB(0xED, 0xED, 0xED); // Label: const SkColor kLabelEnabledColor = kTextButtonEnabledColor; const SkColor kLabelDisabledColor = kTextButtonDisabledColor; const SkColor kLabelBackgroundColor = SK_ColorWHITE; // Textfield: const SkColor kTextfieldDefaultColor = SK_ColorBLACK; const SkColor kTextfieldDefaultBackground = SK_ColorWHITE; const SkColor kTextfieldReadOnlyColor = SK_ColorDKGRAY; const SkColor kTextfieldReadOnlyBackground = SK_ColorWHITE; const SkColor kTextfieldSelectionBackgroundFocused = SkColorSetARGB(0x54, 0x60, 0xA8, 0xEB); const SkColor kTextfieldSelectionBackgroundUnfocused = SK_ColorLTGRAY; const SkColor kTextfieldSelectionColor = color_utils::AlphaBlend(SK_ColorBLACK, kTextfieldSelectionBackgroundFocused, 0xdd); // Tree const SkColor kTreeBackground = SK_ColorWHITE; const SkColor kTreeTextColor = SK_ColorBLACK; const SkColor kTreeSelectedTextColor = SK_ColorBLACK; const SkColor kTreeSelectionBackgroundColor = SkColorSetRGB(0xEE, 0xEE, 0xEE); const SkColor kTreeArrowColor = SkColorSetRGB(0x7A, 0x7A, 0x7A); // Table const SkColor kTableBackground = SK_ColorWHITE; const SkColor kTableTextColor = SK_ColorBLACK; const SkColor kTableSelectedTextColor = SK_ColorBLACK; const SkColor kTableSelectionBackgroundColor = SkColorSetRGB(0xEE, 0xEE, 0xEE); const SkColor kTableGroupingIndicatorColor = SkColorSetRGB(0xCC, 0xCC, 0xCC); } // namespace namespace ui { // static NativeTheme* NativeTheme::instance() { return NativeThemeAura::instance(); } // static NativeThemeAura* NativeThemeAura::instance() { CR_DEFINE_STATIC_LOCAL(NativeThemeAura, s_native_theme, ()); return &s_native_theme; } NativeThemeAura::NativeThemeAura() { // We don't draw scrollbar buttons. set_scrollbar_button_length(0); } NativeThemeAura::~NativeThemeAura() { } SkColor NativeThemeAura::GetSystemColor(ColorId color_id) const { // This implementation returns hardcoded colors. SkColor color; if (IsNewMenuStyleEnabled() && CommonThemeGetSystemColor(color_id, &color)) return color; switch (color_id) { // Windows case kColorId_WindowBackground: return kWindowBackgroundColor; // Dialogs case kColorId_DialogBackground: return kDialogBackgroundColor; // FocusableBorder case kColorId_FocusedBorderColor: return kFocusedBorderColor; case kColorId_UnfocusedBorderColor: return kUnfocusedBorderColor; // TextButton case kColorId_TextButtonBackgroundColor: return kTextButtonBackgroundColor; case kColorId_TextButtonEnabledColor: return kTextButtonEnabledColor; case kColorId_TextButtonDisabledColor: return kTextButtonDisabledColor; case kColorId_TextButtonHighlightColor: return kTextButtonHighlightColor; case kColorId_TextButtonHoverColor: return kTextButtonHoverColor; // MenuItem case kColorId_EnabledMenuItemForegroundColor: return kEnabledMenuItemForegroundColor; case kColorId_DisabledMenuItemForegroundColor: return kDisabledMenuItemForegroundColor; case kColorId_FocusedMenuItemBackgroundColor: return kFocusedMenuItemBackgroundColor; case kColorId_MenuSeparatorColor: return kMenuSeparatorColor; // Label case kColorId_LabelEnabledColor: return kLabelEnabledColor; case kColorId_LabelDisabledColor: return kLabelDisabledColor; case kColorId_LabelBackgroundColor: return kLabelBackgroundColor; // Textfield case kColorId_TextfieldDefaultColor: return kTextfieldDefaultColor; case kColorId_TextfieldDefaultBackground: return kTextfieldDefaultBackground; case kColorId_TextfieldReadOnlyColor: return kTextfieldReadOnlyColor; case kColorId_TextfieldReadOnlyBackground: return kTextfieldReadOnlyBackground; case kColorId_TextfieldSelectionColor: return kTextfieldSelectionColor; case kColorId_TextfieldSelectionBackgroundFocused: return kTextfieldSelectionBackgroundFocused; case kColorId_TextfieldSelectionBackgroundUnfocused: return kTextfieldSelectionBackgroundUnfocused; // Tree case kColorId_TreeBackground: return kTreeBackground; case kColorId_TreeText: return kTreeTextColor; case kColorId_TreeSelectedText: case kColorId_TreeSelectedTextUnfocused: return kTreeSelectedTextColor; case kColorId_TreeSelectionBackgroundFocused: case kColorId_TreeSelectionBackgroundUnfocused: return kTreeSelectionBackgroundColor; case kColorId_TreeArrow: return kTreeArrowColor; // Table case kColorId_TableBackground: return kTableBackground; case kColorId_TableText: return kTableTextColor; case kColorId_TableSelectedText: case kColorId_TableSelectedTextUnfocused: return kTableSelectedTextColor; case kColorId_TableSelectionBackgroundFocused: case kColorId_TableSelectionBackgroundUnfocused: return kTableSelectionBackgroundColor; case kColorId_TableGroupingIndicatorColor: return kTableGroupingIndicatorColor; case kColorId_MenuBackgroundColor: case kColorId_MenuBorderColor: NOTREACHED(); break; } return kInvalidColorIdColor; } void NativeThemeAura::PaintMenuPopupBackground( SkCanvas* canvas, const gfx::Size& size, const MenuBackgroundExtraParams& menu_background) const { if (menu_background.corner_radius > 0) { SkPaint paint; paint.setStyle(SkPaint::kFill_Style); paint.setFlags(SkPaint::kAntiAlias_Flag); paint.setColor(kMenuBackgroundColor); gfx::Path path; SkRect rect = SkRect::MakeWH(SkIntToScalar(size.width()), SkIntToScalar(size.height())); SkScalar radius = SkIntToScalar(menu_background.corner_radius); SkScalar radii[8] = {radius, radius, radius, radius, radius, radius, radius, radius}; path.addRoundRect(rect, radii); canvas->drawPath(path, paint); } else { canvas->drawColor(kMenuBackgroundColor, SkXfermode::kSrc_Mode); } } void NativeThemeAura::PaintScrollbarTrack( SkCanvas* canvas, Part part, State state, const ScrollbarTrackExtraParams& extra_params, const gfx::Rect& rect) const { ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); if (part == kScrollbarVerticalTrack) { int center_offset = 0; int center_height = rect.height(); if (rect.y() == extra_params.track_y) { // TODO(derat): Honor |state| instead of only using the highlighted images // after updating WebKit so we can draw the entire track in one go instead // of as two separate pieces: otherwise, only the portion of the scrollbar // that the mouse is over gets the highlighted state. gfx::ImageSkia* top = rb.GetImageSkiaNamed( IDR_SCROLL_BASE_VERTICAL_TOP_H); DrawTiledImage(canvas, *top, 0, 0, 1.0, 1.0, rect.x(), rect.y(), top->width(), top->height()); center_offset += top->height(); center_height -= top->height(); } if (rect.y() + rect.height() == extra_params.track_y + extra_params.track_height) { gfx::ImageSkia* bottom = rb.GetImageSkiaNamed( IDR_SCROLL_BASE_VERTICAL_BOTTOM_H); DrawTiledImage(canvas, *bottom, 0, 0, 1.0, 1.0, rect.x(), rect.y() + rect.height() - bottom->height(), bottom->width(), bottom->height()); center_height -= bottom->height(); } if (center_height > 0) { gfx::ImageSkia* center = rb.GetImageSkiaNamed( IDR_SCROLL_BASE_VERTICAL_CENTER_H); DrawTiledImage(canvas, *center, 0, 0, 1.0, 1.0, rect.x(), rect.y() + center_offset, center->width(), center_height); } } else { int center_offset = 0; int center_width = rect.width(); if (rect.x() == extra_params.track_x) { gfx::ImageSkia* left = rb.GetImageSkiaNamed( IDR_SCROLL_BASE_HORIZONTAL_LEFT_H); DrawTiledImage(canvas, *left, 0, 0, 1.0, 1.0, rect.x(), rect.y(), left->width(), left->height()); center_offset += left->width(); center_width -= left->width(); } if (rect.x() + rect.width() == extra_params.track_x + extra_params.track_width) { gfx::ImageSkia* right = rb.GetImageSkiaNamed( IDR_SCROLL_BASE_HORIZONTAL_RIGHT_H); DrawTiledImage(canvas, *right, 0, 0, 1.0, 1.0, rect.x() + rect.width() - right->width(), rect.y(), right->width(), right->height()); center_width -= right->width(); } if (center_width > 0) { gfx::ImageSkia* center = rb.GetImageSkiaNamed( IDR_SCROLL_BASE_HORIZONTAL_CENTER_H); DrawTiledImage(canvas, *center, 0, 0, 1.0, 1.0, rect.x() + center_offset, rect.y(), center_width, center->height()); } } } void NativeThemeAura::PaintScrollbarThumb(SkCanvas* canvas, Part part, State state, const gfx::Rect& rect) const { ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); if (part == kScrollbarVerticalThumb) { int top_resource_id = state == kHovered ? IDR_SCROLL_THUMB_VERTICAL_TOP_H : state == kPressed ? IDR_SCROLL_THUMB_VERTICAL_TOP_P : IDR_SCROLL_THUMB_VERTICAL_TOP; gfx::ImageSkia* top = rb.GetImageSkiaNamed(top_resource_id); DrawTiledImage(canvas, *top, 0, 0, 1.0, 1.0, rect.x(), rect.y(), top->width(), top->height()); int bottom_resource_id = state == kHovered ? IDR_SCROLL_THUMB_VERTICAL_BOTTOM_H : state == kPressed ? IDR_SCROLL_THUMB_VERTICAL_BOTTOM_P : IDR_SCROLL_THUMB_VERTICAL_BOTTOM; gfx::ImageSkia* bottom = rb.GetImageSkiaNamed(bottom_resource_id); DrawTiledImage(canvas, *bottom, 0, 0, 1.0, 1.0, rect.x(), rect.y() + rect.height() - bottom->height(), bottom->width(), bottom->height()); if (rect.height() > top->height() + bottom->height()) { int center_resource_id = state == kHovered ? IDR_SCROLL_THUMB_VERTICAL_CENTER_H : state == kPressed ? IDR_SCROLL_THUMB_VERTICAL_CENTER_P : IDR_SCROLL_THUMB_VERTICAL_CENTER; gfx::ImageSkia* center = rb.GetImageSkiaNamed(center_resource_id); DrawTiledImage(canvas, *center, 0, 0, 1.0, 1.0, rect.x(), rect.y() + top->height(), center->width(), rect.height() - top->height() - bottom->height()); } } else { int left_resource_id = state == kHovered ? IDR_SCROLL_THUMB_HORIZONTAL_LEFT_H : state == kPressed ? IDR_SCROLL_THUMB_HORIZONTAL_LEFT_P : IDR_SCROLL_THUMB_HORIZONTAL_LEFT; gfx::ImageSkia* left = rb.GetImageSkiaNamed(left_resource_id); DrawTiledImage(canvas, *left, 0, 0, 1.0, 1.0, rect.x(), rect.y(), left->width(), left->height()); int right_resource_id = state == kHovered ? IDR_SCROLL_THUMB_HORIZONTAL_RIGHT_H : state == kPressed ? IDR_SCROLL_THUMB_HORIZONTAL_RIGHT_P : IDR_SCROLL_THUMB_HORIZONTAL_RIGHT; gfx::ImageSkia* right = rb.GetImageSkiaNamed(right_resource_id); DrawTiledImage(canvas, *right, 0, 0, 1.0, 1.0, rect.x() + rect.width() - right->width(), rect.y(), right->width(), right->height()); if (rect.width() > left->width() + right->width()) { int center_resource_id = state == kHovered ? IDR_SCROLL_THUMB_HORIZONTAL_CENTER_H : state == kPressed ? IDR_SCROLL_THUMB_HORIZONTAL_CENTER_P : IDR_SCROLL_THUMB_HORIZONTAL_CENTER; gfx::ImageSkia* center = rb.GetImageSkiaNamed(center_resource_id); DrawTiledImage(canvas, *center, 0, 0, 1.0, 1.0, rect.x() + left->width(), rect.y(), rect.width() - left->width() - right->width(), center->height()); } } } } // namespace ui