blob: b1f41e42fe8b9443b6d4066c791b6dce8d6d826f [file] [log] [blame]
// 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