MacViews: Implement scrollbar theming.

The default views scrollbars look out of place on Mac OS X.
As a start, theme the scrollbar drawing to look like the native non-overlay
scrollbars. It looks like a simple round-rect that is inset from the track,
with a line border next to the content area.

BUG=401346

Review URL: https://codereview.chromium.org/456473002

Cr-Commit-Position: refs/heads/master@{#289486}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289486 0039d316-1c4b-4281-b951-d872f2087c98
parent 944882db
......@@ -236,7 +236,8 @@ void NativeThemeBase::Paint(SkCanvas* canvas,
case kScrollbarUpArrow:
case kScrollbarLeftArrow:
case kScrollbarRightArrow:
PaintArrowButton(canvas, rect, part, state);
if (scrollbar_button_length_ > 0)
PaintArrowButton(canvas, rect, part, state);
break;
case kScrollbarHorizontalThumb:
case kScrollbarVerticalThumb:
......
......@@ -200,6 +200,8 @@ class NATIVE_THEME_EXPORT NativeThemeBase : public NativeTheme {
const SkScalar borderRadius) const;
unsigned int scrollbar_width_;
// The length of the arrow buttons, 0 means no buttons are drawn.
unsigned int scrollbar_button_length_;
DISALLOW_COPY_AND_ASSIGN(NativeThemeBase);
......
......@@ -20,6 +20,19 @@ class NativeThemeMac : public FallbackTheme {
virtual SkColor GetSystemColor(ColorId color_id) const OVERRIDE;
// Overridden from NativeThemeBase:
virtual void PaintScrollbarTrack(
SkCanvas* canvas,
Part part,
State state,
const ScrollbarTrackExtraParams& extra_params,
const gfx::Rect& rect) const OVERRIDE;
virtual void PaintScrollbarThumb(SkCanvas* sk_canvas,
Part part,
State state,
const gfx::Rect& rect) const OVERRIDE;
virtual void PaintScrollbarCorner(SkCanvas* canvas,
State state,
const gfx::Rect& rect) const OVERRIDE;
virtual void PaintMenuPopupBackground(
SkCanvas* canvas,
const gfx::Size& size,
......
......@@ -12,10 +12,26 @@
#include "base/mac/sdk_forward_declarations.h"
#include "ui/native_theme/common_theme.h"
#import "skia/ext/skia_utils_mac.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/skia_util.h"
namespace {
const SkColor kScrollerTrackGradientColors[] = {
SkColorSetRGB(0xEF, 0xEF, 0xEF),
SkColorSetRGB(0xF9, 0xF9, 0xF9),
SkColorSetRGB(0xFD, 0xFD, 0xFD),
SkColorSetRGB(0xF6, 0xF6, 0xF6) };
const SkColor kScrollerTrackInnerBorderColor = SkColorSetRGB(0xE4, 0xE4, 0xE4);
const SkColor kScrollerTrackOuterBorderColor = SkColorSetRGB(0xEF, 0xEF, 0xEF);
const SkColor kScrollerThumbColor = SkColorSetARGB(0x38, 0, 0, 0);
const SkColor kScrollerThumbHoverColor = SkColorSetARGB(0x80, 0, 0, 0);
const int kScrollerTrackBorderWidth = 1;
// The amount the thumb is inset from both the ends and the sides of the track.
const int kScrollerThumbInset = 3;
// Values calculated by reading pixels and solving simultaneous equations
// derived from "A over B" alpha compositing. Steps: Sample the semi-transparent
// pixel over two backgrounds; P1, P2 over backgrounds B1, B2. Use the color
......@@ -184,6 +200,131 @@ SkColor NativeThemeMac::GetSystemColor(ColorId color_id) const {
return FallbackTheme::GetSystemColor(color_id);
}
void NativeThemeMac::PaintScrollbarTrack(
SkCanvas* canvas,
Part part,
State state,
const ScrollbarTrackExtraParams& extra_params,
const gfx::Rect& rect) const {
// Emulate the non-overlay scroller style from OSX 10.7 and later.
SkPoint gradient_bounds[2];
if (part == kScrollbarVerticalTrack) {
gradient_bounds[0].set(rect.x(), rect.y());
gradient_bounds[1].set(rect.right(), rect.y());
} else {
DCHECK_EQ(part, kScrollbarHorizontalTrack);
gradient_bounds[0].set(rect.x(), rect.y());
gradient_bounds[1].set(rect.x(), rect.bottom());
}
skia::RefPtr<SkShader> shader = skia::AdoptRef(
SkGradientShader::CreateLinear(gradient_bounds,
kScrollerTrackGradientColors,
NULL,
arraysize(kScrollerTrackGradientColors),
SkShader::kClamp_TileMode));
SkPaint gradient;
gradient.setShader(shader.get());
SkIRect track_rect = gfx::RectToSkIRect(rect);
canvas->drawIRect(track_rect, gradient);
// Draw inner and outer line borders.
if (part == kScrollbarVerticalTrack) {
SkPaint paint;
paint.setColor(kScrollerTrackInnerBorderColor);
canvas->drawRectCoords(track_rect.left(),
track_rect.top(),
track_rect.left() + kScrollerTrackBorderWidth,
track_rect.bottom(),
paint);
paint.setColor(kScrollerTrackOuterBorderColor);
canvas->drawRectCoords(track_rect.right() - kScrollerTrackBorderWidth,
track_rect.top(),
track_rect.right(),
track_rect.bottom(),
paint);
} else {
SkPaint paint;
paint.setColor(kScrollerTrackInnerBorderColor);
canvas->drawRectCoords(track_rect.left(),
track_rect.top(),
track_rect.right(),
track_rect.top() + kScrollerTrackBorderWidth,
paint);
paint.setColor(kScrollerTrackOuterBorderColor);
canvas->drawRectCoords(track_rect.left(),
track_rect.bottom() - kScrollerTrackBorderWidth,
track_rect.right(),
track_rect.bottom(),
paint);
}
}
void NativeThemeMac::PaintScrollbarThumb(SkCanvas* canvas,
Part part,
State state,
const gfx::Rect& rect) const {
gfx::Rect thumb_rect(rect);
switch (part) {
case kScrollbarHorizontalThumb:
thumb_rect.Inset(0, kScrollerTrackBorderWidth, 0, 0);
break;
case kScrollbarVerticalThumb:
thumb_rect.Inset(kScrollerTrackBorderWidth, 0, 0, 0);
break;
default:
NOTREACHED();
break;
}
thumb_rect.Inset(kScrollerThumbInset, kScrollerThumbInset);
SkPaint paint;
paint.setAntiAlias(true);
paint.setColor(state == kHovered ? thumb_active_color_
: thumb_inactive_color_);
const SkScalar radius = std::min(rect.width(), rect.height());
canvas->drawRoundRect(gfx::RectToSkRect(thumb_rect), radius, radius, paint);
}
void NativeThemeMac::PaintScrollbarCorner(SkCanvas* canvas,
State state,
const gfx::Rect& rect) const {
DCHECK_GT(rect.width(), 0);
DCHECK_GT(rect.height(), 0);
// Draw radial gradient from top-left corner.
skia::RefPtr<SkShader> shader = skia::AdoptRef(
SkGradientShader::CreateRadial(SkPoint::Make(rect.x(), rect.y()),
rect.width(),
kScrollerTrackGradientColors,
NULL,
arraysize(kScrollerTrackGradientColors),
SkShader::kClamp_TileMode));
SkPaint gradient;
gradient.setStyle(SkPaint::kFill_Style);
gradient.setAntiAlias(true);
gradient.setShader(shader.get());
canvas->drawRect(gfx::RectToSkRect(rect), gradient);
// Draw inner border corner point.
canvas->drawPoint(rect.x(), rect.y(), kScrollerTrackInnerBorderColor);
// Draw outer borders.
SkPaint paint;
paint.setColor(kScrollerTrackOuterBorderColor);
canvas->drawRectCoords(rect.right() - kScrollerTrackBorderWidth,
rect.y(),
rect.right(),
rect.bottom(),
paint);
canvas->drawRectCoords(rect.x(),
rect.bottom() - kScrollerTrackBorderWidth,
rect.right(),
rect.bottom(),
paint);
}
void NativeThemeMac::PaintMenuPopupBackground(
SkCanvas* canvas,
const gfx::Size& size,
......@@ -217,6 +358,10 @@ void NativeThemeMac::PaintMenuItemBackground(
}
NativeThemeMac::NativeThemeMac() {
set_scrollbar_button_length(0);
SetScrollbarColors(kScrollerThumbColor,
kScrollerThumbHoverColor,
kScrollerTrackGradientColors[0]);
}
NativeThemeMac::~NativeThemeMac() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment