| // Copyright (c) 2011 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/gfx/native_theme_chromeos.h" |
| |
| #include "base/logging.h" |
| #include "grit/gfx_resources.h" |
| #include "third_party/skia/include/effects/SkGradientShader.h" |
| #include "third_party/skia/include/core/SkPaint.h" |
| #include "third_party/skia/include/core/SkPath.h" |
| #include "third_party/skia/include/core/SkShader.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/gfx/insets.h" |
| #include "ui/gfx/rect.h" |
| #include "ui/gfx/size.h" |
| #include "ui/gfx/skbitmap_operations.h" |
| |
| namespace { |
| |
| // Color constants. See theme_draw for details. |
| |
| // Border color used for many widgets. |
| const SkColor kBaseStroke = SkColorSetRGB(0x8F, 0x8F, 0x8F); |
| |
| // Disabled border color used for many widgets. |
| const SkColor kDisabledBaseStroke = SkColorSetRGB(0xB7, 0xB7, 0xB7); |
| |
| // Common gradient stop and colors. |
| const SkColor kBaseGradient0 = SkColorSetRGB(255, 255, 255); |
| const SkColor kBaseGradient1 = SkColorSetRGB(255, 255, 255); |
| const SkColor kBaseGradient2 = SkColorSetRGB(0xD8, 0xD8, 0xD8); |
| |
| const SkColor kPressedGradient0 = SkColorSetRGB(0x95, 0x95, 0x95); |
| const SkColor kPressedGradient1 = SkColorSetRGB(0xE3, 0xE3, 0xE3); |
| |
| const SkColor kIndicatorStrokeDisabledColor = SkColorSetRGB(0xB4, 0xB4, 0xB4); |
| // TODO: these are wrong, what should they be? |
| const SkColor kIndicatorStrokePressedColor = SkColorSetRGB(0, 0, 0); |
| const SkColor kIndicatorStrokeColor = SkColorSetRGB(0, 0, 0); |
| |
| const SkColor kRadioIndicatorGradient0 = SkColorSetRGB(0, 0, 0); |
| const SkColor kRadioIndicatorGradient1 = SkColorSetRGB(0x83, 0x83, 0x83); |
| |
| const SkColor kRadioIndicatorDisabledGradient0 = |
| SkColorSetRGB(0xB4, 0xB4, 0xB4); |
| const SkColor kRadioIndicatorDisabledGradient1 = |
| SkColorSetRGB(0xB7, 0xB7, 0xB7); |
| |
| // Progressbar colors |
| const SkColor kProgressBarBackgroundGradient0 = SkColorSetRGB(0xBB, 0xBB, 0xBB); |
| const SkColor kProgressBarBackgroundGradient1 = SkColorSetRGB(0xE7, 0xE7, 0xE7); |
| const SkColor kProgressBarBackgroundGradient2 = SkColorSetRGB(0xFE, 0xFE, 0xFE); |
| const SkColor kProgressBarBorderStroke = SkColorSetRGB(0xA1, 0xA1, 0xA1); |
| |
| const SkColor kProgressBarIndicatorGradient0 = SkColorSetRGB(100, 116, 147); |
| const SkColor kProgressBarIndicatorGradient1 = SkColorSetRGB(65, 73, 87); |
| |
| const SkColor kProgressBarIndicatorDisabledGradient0 = |
| SkColorSetRGB(229, 232, 237); |
| const SkColor kProgressBarIndicatorDisabledGradient1 = |
| SkColorSetRGB(224, 225, 227); |
| |
| const SkColor kProgressBarIndicatorStroke = SkColorSetRGB(0x4A, 0x4A, 0x4A); |
| const SkColor kProgressBarIndicatorDisabledStroke = |
| SkColorSetARGB(0x80, 0x4A, 0x4A, 0x4A); |
| |
| const SkColor kProgressBarIndicatorInnerStroke = |
| SkColorSetARGB(0x3F, 0xFF, 0xFF, 0xFF); // 0.25 white |
| const SkColor kProgressBarIndicatorInnerShadow = |
| SkColorSetARGB(0x54, 0xFF, 0xFF, 0xFF); // 0.33 white |
| |
| // Geometry constants |
| |
| const int kBorderCornerRadius = 3; |
| |
| const int kRadioIndicatorSize = 7; |
| |
| const int kSliderThumbWidth = 16; |
| const int kSliderThumbHeight = 16; |
| const int kSliderTrackSize = 6; |
| |
| void GetRoundRectPathWithPadding(const gfx::Rect rect, |
| int corner_radius, |
| SkScalar padding, |
| SkPath* path) { |
| SkRect bounds = { SkDoubleToScalar(rect.x()) + padding, |
| SkDoubleToScalar(rect.y()) + padding, |
| SkDoubleToScalar(rect.right()) - padding, |
| SkDoubleToScalar(rect.bottom()) - padding }; |
| path->addRoundRect(bounds, |
| SkIntToScalar(corner_radius) - padding, |
| SkIntToScalar(corner_radius) - padding); |
| } |
| |
| void GetRoundRectPath(const gfx::Rect rect, |
| int corner_radius, |
| SkPath* path) { |
| // Add 0.5 pixel padding so that antialias paint does not touch extra pixels. |
| GetRoundRectPathWithPadding(rect, corner_radius, SkIntToScalar(1) / 2, |
| path); |
| } |
| |
| void GetGradientPaintForRect(const gfx::Rect& rect, |
| const SkColor* colors, |
| const SkScalar* stops, |
| int count, |
| SkPaint* paint) { |
| paint->setStyle(SkPaint::kFill_Style); |
| paint->setAntiAlias(true); |
| |
| SkPoint points[2]; |
| points[0].set(SkIntToScalar(rect.x()), SkIntToScalar(rect.y())); |
| points[1].set(SkIntToScalar(rect.x()), SkIntToScalar(rect.bottom())); |
| |
| SkShader* shader = SkGradientShader::CreateLinear(points, |
| colors, stops, count, SkShader::kClamp_TileMode); |
| |
| paint->setShader(shader); |
| // Unref shader after paint takes ownership, otherwise never deleted. |
| shader->unref(); |
| } |
| |
| void GetGradientPaintForRect(const gfx::Rect& rect, |
| SkColor start_color, |
| SkColor end_color, |
| SkPaint* paint) { |
| SkColor colors[2] = { start_color, end_color }; |
| GetGradientPaintForRect(rect, colors, NULL, 2, paint); |
| } |
| |
| void GetButtonGradientPaint(const gfx::Rect bounds, |
| gfx::NativeThemeLinux::State state, |
| SkPaint* paint) { |
| if (state == gfx::NativeThemeLinux::kPressed) { |
| static const SkColor kGradientColors[2] = { |
| kPressedGradient0, |
| kPressedGradient1 |
| }; |
| |
| static const SkScalar kGradientPoints[2] = { |
| SkIntToScalar(0), |
| SkIntToScalar(1) |
| }; |
| |
| GetGradientPaintForRect(bounds, |
| kGradientColors, kGradientPoints, arraysize(kGradientPoints), |
| paint); |
| } else { |
| static const SkColor kGradientColors[3] = { |
| kBaseGradient0, |
| kBaseGradient1, |
| kBaseGradient2 |
| }; |
| |
| static const SkScalar kGradientPoints[3] = { |
| SkIntToScalar(0), |
| SkDoubleToScalar(0.5), |
| SkIntToScalar(1) |
| }; |
| |
| GetGradientPaintForRect(bounds, |
| kGradientColors, kGradientPoints, arraysize(kGradientPoints), |
| paint); |
| } |
| } |
| |
| void GetStrokePaint(SkColor color, SkPaint* paint) { |
| paint->setStyle(SkPaint::kStroke_Style); |
| paint->setAntiAlias(true); |
| paint->setColor(color); |
| } |
| |
| void GetStrokePaint(gfx::NativeThemeLinux::State state, SkPaint* paint) { |
| |
| if (state == gfx::NativeThemeLinux::kDisabled) |
| GetStrokePaint(kDisabledBaseStroke, paint); |
| else |
| GetStrokePaint(kBaseStroke, paint); |
| } |
| |
| void GetIndicatorStrokePaint(gfx::NativeThemeLinux::State state, |
| SkPaint* paint) { |
| paint->setStyle(SkPaint::kStroke_Style); |
| paint->setAntiAlias(true); |
| |
| if (state == gfx::NativeThemeLinux::kDisabled) |
| paint->setColor(kIndicatorStrokeDisabledColor); |
| else if (state == gfx::NativeThemeLinux::kPressed) |
| paint->setColor(kIndicatorStrokePressedColor); |
| else |
| paint->setColor(kIndicatorStrokeColor); |
| } |
| |
| void GetRadioIndicatorGradientPaint(const gfx::Rect bounds, |
| gfx::NativeThemeLinux::State state, |
| SkPaint* paint) { |
| paint->setStyle(SkPaint::kFill_Style); |
| paint->setAntiAlias(true); |
| |
| SkPoint points[2]; |
| points[0].set(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y())); |
| points[1].set(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.bottom())); |
| |
| static const SkScalar kGradientPoints[2] = { |
| SkIntToScalar(0), |
| SkIntToScalar(1) |
| }; |
| |
| if (state == gfx::NativeThemeLinux::kDisabled) { |
| static const SkColor kGradientColors[2] = { |
| kRadioIndicatorDisabledGradient0, |
| kRadioIndicatorDisabledGradient1 |
| }; |
| |
| GetGradientPaintForRect(bounds, |
| kGradientColors, kGradientPoints, arraysize(kGradientPoints), |
| paint); |
| } else { |
| static const SkColor kGradientColors[2] = { |
| kRadioIndicatorGradient0, |
| kRadioIndicatorGradient1 |
| }; |
| |
| GetGradientPaintForRect(bounds, |
| kGradientColors, kGradientPoints, arraysize(kGradientPoints), |
| paint); |
| } |
| } |
| |
| } // namespace |
| |
| /* static */ |
| const gfx::NativeThemeLinux* gfx::NativeThemeLinux::instance() { |
| // The global NativeThemeChromeos instance. |
| static NativeThemeChromeos s_native_theme; |
| return &s_native_theme; |
| } |
| |
| NativeThemeChromeos::NativeThemeChromeos() { |
| } |
| |
| NativeThemeChromeos::~NativeThemeChromeos() { |
| } |
| |
| gfx::Size NativeThemeChromeos::GetPartSize(Part part, |
| State state, |
| const ExtraParams& extra) const { |
| // This function might be called from Worker process during html layout |
| // without calling GfxModule::SetResourceProvider. So using dimension |
| // constants instead of getting it from resource images. |
| #if defined(TOUCH_UI) |
| static const int kScrollbarWidth = 0; |
| #else |
| static const int kScrollbarWidth = 13; |
| #endif |
| static const int kScrollbarArrowUpHeight = 12; |
| static const int kScrollbarArrowDownHeight = 12; |
| |
| int width = 0, height = 0; |
| switch (part) { |
| case kScrollbarUpArrow: |
| width = kScrollbarWidth; |
| height = kScrollbarArrowUpHeight; |
| break; |
| case kScrollbarDownArrow: |
| width = kScrollbarWidth; |
| height = kScrollbarArrowDownHeight; |
| break; |
| case kScrollbarLeftArrow: |
| width = kScrollbarArrowUpHeight; |
| height = kScrollbarWidth; |
| break; |
| case kScrollbarRightArrow: |
| width = kScrollbarArrowDownHeight; |
| height = kScrollbarWidth; |
| break; |
| case kScrollbarHorizontalTrack: |
| width = 0; |
| height = kScrollbarWidth; |
| break; |
| case kScrollbarVerticalTrack: |
| width = kScrollbarWidth; |
| height = 0; |
| break; |
| case kScrollbarHorizontalThumb: |
| case kScrollbarVerticalThumb: |
| // allow thumb to be square but no shorter. |
| width = kScrollbarWidth; |
| height = kScrollbarWidth; |
| break; |
| case kSliderThumb: |
| width = kSliderThumbWidth; |
| height = kSliderThumbHeight; |
| break; |
| case kInnerSpinButton: |
| return gfx::Size(kScrollbarWidth, 0); |
| default: |
| return NativeThemeLinux::GetPartSize(part, state, extra); |
| } |
| return gfx::Size(width, height); |
| } |
| |
| void NativeThemeChromeos::PaintScrollbarTrack( |
| SkCanvas* canvas, |
| Part part, |
| State state, |
| const ScrollbarTrackExtraParams& extra_params, |
| const gfx::Rect& rect) const { |
| ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| if (part == kScrollbarVerticalTrack) { |
| SkBitmap* background = rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND); |
| SkBitmap* border_up = rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_UP); |
| SkBitmap* border_down = |
| rb.GetBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_DOWN); |
| // Draw track background. |
| DrawBitmapInt( |
| canvas, *background, |
| 0, 0, background->width(), 1, |
| rect.x(), rect.y(), rect.width(), rect.height()); |
| // Draw up button lower border. |
| canvas->drawBitmap(*border_up, extra_params.track_x, extra_params.track_y); |
| // Draw down button upper border. |
| canvas->drawBitmap( |
| *border_down, |
| extra_params.track_x, |
| extra_params.track_y + extra_params.track_height - border_down->height() |
| ); |
| } else { |
| SkBitmap* background = |
| GetHorizontalBitmapNamed(IDR_SCROLL_BACKGROUND); |
| SkBitmap* border_left = |
| GetHorizontalBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_UP); |
| SkBitmap* border_right = |
| GetHorizontalBitmapNamed(IDR_SCROLL_BACKGROUND_BORDER_DOWN); |
| // Draw track background. |
| DrawBitmapInt( |
| canvas, *background, |
| 0, 0, 1, background->height(), |
| rect.x(), rect.y(), rect.width(), rect.height()); |
| // Draw left button right border. |
| canvas->drawBitmap(*border_left,extra_params.track_x, extra_params.track_y); |
| // Draw right button left border. |
| canvas->drawBitmap( |
| *border_right, |
| extra_params.track_x + extra_params.track_width - border_right->width(), |
| extra_params.track_y); |
| } |
| } |
| |
| void NativeThemeChromeos::PaintScrollbarThumb(SkCanvas* canvas, |
| Part part, State state, const gfx::Rect& rect) const { |
| ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| int resource_id = IDR_SCROLL_THUMB; |
| if (state == kHovered) |
| resource_id++; |
| else if (state == kPressed) |
| resource_id += 2; |
| if (part == kScrollbarVerticalThumb) { |
| SkBitmap* bitmap = rb.GetBitmapNamed(resource_id); |
| // Top |
| DrawBitmapInt( |
| canvas, *bitmap, |
| 0, 1, bitmap->width(), 5, |
| rect.x(), rect.y(), rect.width(), 5); |
| // Middle |
| DrawBitmapInt( |
| canvas, *bitmap, |
| 0, 7, bitmap->width(), 1, |
| rect.x(), rect.y() + 5, rect.width(), rect.height() - 10); |
| // Bottom |
| DrawBitmapInt( |
| canvas, *bitmap, |
| 0, 8, bitmap->width(), 5, |
| rect.x(), rect.y() + rect.height() - 5, rect.width(), 5); |
| } else { |
| SkBitmap* bitmap = GetHorizontalBitmapNamed(resource_id); |
| // Left |
| DrawBitmapInt( |
| canvas, *bitmap, |
| 1, 0, 5, bitmap->height(), |
| rect.x(), rect.y(), 5, rect.height()); |
| // Middle |
| DrawBitmapInt( |
| canvas, *bitmap, |
| 7, 0, 1, bitmap->height(), |
| rect.x() + 5, rect.y(), rect.width() - 10, rect.height()); |
| // Right |
| DrawBitmapInt( |
| canvas, *bitmap, |
| 8, 0, 5, bitmap->height(), |
| rect.x() + rect.width() - 5, rect.y(), 5, rect.height()); |
| } |
| } |
| |
| void NativeThemeChromeos::PaintArrowButton(SkCanvas* canvas, |
| const gfx::Rect& rect, Part part, State state) const { |
| ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| int resource_id = |
| (part == kScrollbarUpArrow || part == kScrollbarLeftArrow) ? |
| IDR_SCROLL_ARROW_UP : IDR_SCROLL_ARROW_DOWN; |
| if (state == kHovered) |
| resource_id++; |
| else if (state == kPressed) |
| resource_id += 2; |
| SkBitmap* bitmap; |
| if (part == kScrollbarUpArrow || part == kScrollbarDownArrow) |
| bitmap = rb.GetBitmapNamed(resource_id); |
| else |
| bitmap = GetHorizontalBitmapNamed(resource_id); |
| DrawBitmapInt(canvas, *bitmap, |
| 0, 0, bitmap->width(), bitmap->height(), |
| rect.x(), rect.y(), rect.width(), rect.height()); |
| } |
| |
| void NativeThemeChromeos::PaintCheckbox(SkCanvas* canvas, |
| State state, const gfx::Rect& rect, |
| const ButtonExtraParams& button) const { |
| PaintButtonLike(canvas, state, rect, true); |
| |
| if (button.checked) { |
| SkPaint indicator_paint; |
| GetIndicatorStrokePaint(state, &indicator_paint); |
| indicator_paint.setStrokeWidth(2); |
| |
| const int kMidX = rect.x() + rect.width() / 2; |
| const int kMidY = rect.y() + rect.height() / 2; |
| canvas->drawLine(SkIntToScalar(rect.x() + 3), SkIntToScalar(kMidY), |
| SkIntToScalar(kMidX - 1), SkIntToScalar(rect.bottom() - 3), |
| indicator_paint); |
| canvas->drawLine(SkIntToScalar(kMidX - 1), SkIntToScalar(rect.bottom() - 3), |
| SkIntToScalar(rect.right() - 3), SkIntToScalar(rect.y() + 3), |
| indicator_paint); |
| } |
| } |
| |
| void NativeThemeChromeos::PaintRadio(SkCanvas* canvas, |
| State state, |
| const gfx::Rect& rect, |
| const ButtonExtraParams& button) const { |
| gfx::Point center = rect.CenterPoint(); |
| SkPath border; |
| border.addCircle(SkIntToScalar(center.x()), SkIntToScalar(center.y()), |
| SkDoubleToScalar(rect.width() / 2.0)); |
| |
| SkPaint fill_paint; |
| GetButtonGradientPaint(rect, state, &fill_paint); |
| canvas->drawPath(border, fill_paint); |
| |
| SkPaint stroke_paint; |
| GetStrokePaint(state, &stroke_paint); |
| canvas->drawPath(border, stroke_paint); |
| |
| if (button.checked) { |
| SkPath indicator_border; |
| indicator_border.addCircle(SkIntToScalar(center.x()), |
| SkIntToScalar(center.y()), |
| SkDoubleToScalar(kRadioIndicatorSize / 2.0)); |
| |
| SkPaint indicator_fill_paint; |
| GetRadioIndicatorGradientPaint(rect, state, &indicator_fill_paint); |
| canvas->drawPath(indicator_border, indicator_fill_paint); |
| |
| SkPaint indicator_paint; |
| GetIndicatorStrokePaint(state, &indicator_paint); |
| canvas->drawPath(indicator_border, indicator_paint); |
| } |
| } |
| |
| void NativeThemeChromeos::PaintButton(SkCanvas* canvas, |
| State state, |
| const gfx::Rect& rect, |
| const ButtonExtraParams& button) const { |
| PaintButtonLike(canvas, state, rect, button.has_border); |
| } |
| |
| void NativeThemeChromeos::PaintTextField(SkCanvas* canvas, |
| State state, |
| const gfx::Rect& rect, |
| const TextFieldExtraParams& text) const { |
| if (rect.height() == 0) |
| return; |
| |
| SkColor background_color = text.background_color; |
| |
| SkPaint fill_paint; |
| fill_paint.setStyle(SkPaint::kFill_Style); |
| if (state == kDisabled) { |
| fill_paint.setColor(background_color); |
| } else { |
| SkScalar base_hsv[3]; |
| SkColorToHSV(background_color, base_hsv); |
| |
| const SkColor gradient_colors[3] = { |
| SaturateAndBrighten(base_hsv, 0, -0.18), |
| background_color, |
| background_color |
| }; |
| |
| const SkScalar gradient_points[3] = { |
| SkIntToScalar(0), |
| SkDoubleToScalar(4.0 / rect.height()), |
| SkIntToScalar(1) |
| }; |
| |
| SkPoint points[2]; |
| points[0].set(SkIntToScalar(rect.x()), SkIntToScalar(rect.y())); |
| points[1].set(SkIntToScalar(rect.x()), SkIntToScalar(rect.bottom())); |
| |
| GetGradientPaintForRect(rect, |
| gradient_colors, gradient_points, arraysize(gradient_points), |
| &fill_paint); |
| } |
| |
| SkPath border; |
| GetRoundRectPath(rect, kBorderCornerRadius, &border); |
| canvas->drawPath(border, fill_paint); |
| |
| SkPaint stroke_paint; |
| GetStrokePaint(state, &stroke_paint); |
| canvas->drawPath(border, stroke_paint); |
| } |
| |
| void NativeThemeChromeos::PaintSliderTrack(SkCanvas* canvas, |
| State state, |
| const gfx::Rect& rect, |
| const SliderExtraParams& slider) const { |
| const int kMidX = rect.x() + rect.width() / 2; |
| const int kMidY = rect.y() + rect.height() / 2; |
| |
| gfx::Rect track_bounds; |
| if (slider.vertical) { |
| track_bounds.SetRect(std::max(rect.x(), kMidX - kSliderTrackSize / 2), |
| rect.y(), |
| std::min(rect.width(), kSliderTrackSize), |
| rect.height()); |
| } else { |
| track_bounds.SetRect(rect.x(), |
| std::max(rect.y(), kMidY - kSliderTrackSize / 2), |
| rect.width(), |
| std::min(rect.height(), kSliderTrackSize)); |
| } |
| |
| SkPath border; |
| GetRoundRectPath(track_bounds, kBorderCornerRadius, &border); |
| |
| SkPaint fill_paint; |
| // Use normal button background. |
| GetButtonGradientPaint(rect, kNormal, &fill_paint); |
| canvas->drawPath(border, fill_paint); |
| |
| SkPaint stroke_paint; |
| GetStrokePaint(state, &stroke_paint); |
| canvas->drawPath(border, stroke_paint); |
| } |
| |
| void NativeThemeChromeos::PaintSliderThumb(SkCanvas* canvas, |
| State state, |
| const gfx::Rect& rect, |
| const SliderExtraParams& slider) const { |
| if (state != kDisabled && slider.in_drag) |
| state = kPressed; |
| |
| PaintButtonLike(canvas, state, rect, true); |
| } |
| |
| void NativeThemeChromeos::PaintInnerSpinButton(SkCanvas* canvas, |
| State state, |
| const gfx::Rect& rect, |
| const InnerSpinButtonExtraParams& spin_button) const { |
| // Adjust bounds to compensate the overridden "2px inset" parent border. |
| gfx::Rect bounds = rect; |
| bounds.Inset(0, -1, -1, -1); |
| |
| NativeThemeLinux::PaintInnerSpinButton(canvas, state, bounds, spin_button); |
| } |
| |
| void NativeThemeChromeos::PaintProgressBar(SkCanvas* canvas, |
| State state, |
| const gfx::Rect& rect, |
| const ProgressBarExtraParams& progress_bar) const { |
| static const int kBorderWidth = 1; |
| static const SkColor kBackgroundColors[] = { |
| kProgressBarBackgroundGradient0, |
| kProgressBarBackgroundGradient1, |
| kProgressBarBackgroundGradient2 |
| }; |
| |
| static const SkScalar kBackgroundPoints[] = { |
| SkDoubleToScalar(0), |
| SkDoubleToScalar(0.1), |
| SkDoubleToScalar(1) |
| }; |
| static const SkColor kBackgroundBorderColor = kProgressBarBorderStroke; |
| |
| // Draw background. |
| SkPath border; |
| GetRoundRectPath(rect, kBorderCornerRadius, &border); |
| |
| SkPaint fill_paint; |
| GetGradientPaintForRect(rect, |
| kBackgroundColors, kBackgroundPoints, arraysize(kBackgroundPoints), |
| &fill_paint); |
| canvas->drawPath(border, fill_paint); |
| |
| SkPaint stroke_paint; |
| GetStrokePaint(kBackgroundBorderColor, &stroke_paint); |
| canvas->drawPath(border, stroke_paint); |
| |
| if (progress_bar.value_rect_width > 1) { |
| bool enabled = state != kDisabled; |
| gfx::Rect value_rect(progress_bar.value_rect_x, |
| progress_bar.value_rect_y, |
| progress_bar.value_rect_width, |
| progress_bar.value_rect_height); |
| |
| const SkColor bar_color_start = enabled ? |
| kProgressBarIndicatorGradient0 : |
| kProgressBarIndicatorDisabledGradient0; |
| const SkColor bar_color_end = enabled ? |
| kProgressBarIndicatorGradient1 : |
| kProgressBarIndicatorDisabledGradient1; |
| |
| const SkColor bar_outer_color = enabled ? |
| kProgressBarIndicatorStroke : |
| kProgressBarIndicatorDisabledStroke; |
| |
| const SkColor bar_inner_border_color = kProgressBarIndicatorInnerStroke; |
| const SkColor bar_inner_shadow_color = kProgressBarIndicatorInnerShadow; |
| |
| // Draw bar background |
| SkPath value_border; |
| GetRoundRectPath(value_rect, kBorderCornerRadius, &value_border); |
| |
| SkPaint value_fill_paint; |
| GetGradientPaintForRect(rect,bar_color_start, bar_color_end, |
| &value_fill_paint); |
| canvas->drawPath(value_border, value_fill_paint); |
| |
| // Draw inner stroke and shadow if wide enough. |
| if (progress_bar.value_rect_width > 2 * kBorderWidth) { |
| canvas->save(); |
| |
| SkPath inner_path; |
| GetRoundRectPathWithPadding(value_rect, kBorderCornerRadius, |
| SkIntToScalar(kBorderWidth), &inner_path); |
| canvas->clipPath(inner_path); |
| |
| // Draw bar inner stroke |
| gfx::Rect inner_stroke_rect = value_rect; |
| inner_stroke_rect.Inset(kBorderWidth, kBorderWidth); |
| |
| SkPath inner_stroke_path; |
| GetRoundRectPath(inner_stroke_rect, kBorderCornerRadius - kBorderWidth, |
| &inner_stroke_path); |
| |
| SkPaint inner_stroke_paint; |
| GetStrokePaint(bar_inner_border_color, &inner_stroke_paint); |
| |
| canvas->drawPath(inner_stroke_path, inner_stroke_paint); |
| |
| // Draw bar inner shadow |
| gfx::Rect inner_shadow_rect(progress_bar.value_rect_x, |
| progress_bar.value_rect_y + kBorderWidth, |
| progress_bar.value_rect_width, |
| progress_bar.value_rect_height); |
| SkPath inner_shadow_path; |
| GetRoundRectPath(inner_shadow_rect, kBorderCornerRadius, |
| &inner_shadow_path); |
| |
| SkPaint inner_shadow_paint; |
| GetStrokePaint(bar_inner_shadow_color, &inner_shadow_paint); |
| |
| canvas->drawPath(inner_shadow_path, inner_shadow_paint); |
| |
| canvas->restore(); |
| } |
| |
| // Draw bar stroke |
| SkPaint value_stroke_paint; |
| GetStrokePaint(bar_outer_color, &value_stroke_paint); |
| canvas->drawPath(value_border, value_stroke_paint); |
| } |
| } |
| |
| SkBitmap* NativeThemeChromeos::GetHorizontalBitmapNamed(int resource_id) const { |
| SkImageMap::const_iterator found = horizontal_bitmaps_.find(resource_id); |
| if (found != horizontal_bitmaps_.end()) |
| return found->second; |
| |
| ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| SkBitmap* vertical_bitmap = rb.GetBitmapNamed(resource_id); |
| |
| if (vertical_bitmap) { |
| SkBitmap transposed_bitmap = |
| SkBitmapOperations::CreateTransposedBtmap(*vertical_bitmap); |
| SkBitmap* horizontal_bitmap = new SkBitmap(transposed_bitmap); |
| |
| horizontal_bitmaps_[resource_id] = horizontal_bitmap; |
| return horizontal_bitmap; |
| } |
| return NULL; |
| } |
| |
| void NativeThemeChromeos::PaintButtonLike(SkCanvas* canvas, |
| State state, const gfx::Rect& rect, bool stroke_border) const { |
| SkPath border; |
| GetRoundRectPath(rect, kBorderCornerRadius, &border); |
| |
| SkPaint fill_paint; |
| GetButtonGradientPaint(rect, state, &fill_paint); |
| canvas->drawPath(border, fill_paint); |
| |
| if (stroke_border) { |
| SkPaint stroke_paint; |
| GetStrokePaint(state, &stroke_paint); |
| canvas->drawPath(border, stroke_paint); |
| } |
| } |