Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(689)

Unified Diff: chrome/browser/chromeos/native_theme_chromeos.cc

Issue 6254004: Move more web widgets painting from webkit to chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/native_theme_chromeos.cc
diff --git a/chrome/browser/chromeos/native_theme_chromeos.cc b/chrome/browser/chromeos/native_theme_chromeos.cc
index c0cd0253d46cd44af3bbfd9d8a3005d15500351d..880861bb23669d488ccffa734da9610107d79bf9 100644
--- a/chrome/browser/chromeos/native_theme_chromeos.cc
+++ b/chrome/browser/chromeos/native_theme_chromeos.cc
@@ -13,10 +13,45 @@
#include "gfx/size.h"
#include "gfx/skbitmap_operations.h"
#include "grit/theme_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"
namespace {
+// Color and geometry 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 kGradient0 = SkColorSetRGB(255, 255, 255);
+const SkColor kGradient1 = SkColorSetRGB(255, 255, 255);
+const SkColor kGradient2 = 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);
+
+const int kBorderCornerRadius = 3;
+const int kRadioIndicatorSize = 7;
+
bool IntersectsClipRectInt(
skia::PlatformCanvas* canvas, int x, int y, int w, int h) {
SkRect clip;
@@ -74,6 +109,154 @@ void DrawBitmapInt(
canvas->drawRect(dest_rect, p);
}
+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] = {
+ kGradient0,
+ kGradient1,
+ kGradient2
+ };
+
+ 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);
+ }
+}
+
}
/* static */
@@ -124,6 +307,14 @@ gfx::Size NativeThemeChromeos::GetSize(Part part) const {
width = scrollbar_width;
height = scrollbar_width;
break;
+ case kSliderThumb:
+ width = 16;
+ height = 16;
+ break;
+ case kInnerSpinButton:
+ return gfx::Size(scrollbar_width, 0);
+ default:
+ return NativeThemeLinux::GetSize(part);
}
return gfx::Size(width, height);
}
@@ -234,7 +425,282 @@ void NativeThemeChromeos::PaintArrowButton(skia::PlatformCanvas* canvas,
bitmap = rb.GetBitmapNamed(resource_id);
else
bitmap = GetHorizontalBitmapNamed(resource_id);
- canvas->drawBitmap(*bitmap, rect.x(), rect.y());
+ DrawBitmapInt(canvas, *bitmap,
+ 0, 0, bitmap->width(), bitmap->height(),
+ rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+void NativeThemeChromeos::PaintCheckbox(skia::PlatformCanvas* canvas,
+ State state, const gfx::Rect& rect,
+ const ButtonExtraParams& button) {
+ PaintButtonLike(canvas, state, rect, button);
+
+ if (button.checked) {
+ SkPaint indicator_paint;
+ GetIndicatorStrokePaint(state, &indicator_paint);
+ indicator_paint.setStrokeWidth(2);
+
+ int midx = rect.x() + rect.width() / 2;
+ int midy = rect.y() + rect.height() / 2;
+ canvas->drawLine(SkIntToScalar(rect.x() + 3), SkIntToScalar(midy),
+ SkIntToScalar(midx - 1), SkIntToScalar(rect.bottom() - 3),
+ indicator_paint);
+ canvas->drawLine(SkIntToScalar(midx - 1), SkIntToScalar(rect.bottom() - 3),
+ SkIntToScalar(rect.right() - 3), SkIntToScalar(rect.y() + 3),
+ indicator_paint);
+ }
+}
+
+void NativeThemeChromeos::PaintRadio(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const ButtonExtraParams& button) {
+ 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(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const ButtonExtraParams& button) {
+ PaintButtonLike(canvas, state, rect, button);
+}
+
+void NativeThemeChromeos::PaintTextField(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const TextFieldExtraParams& text) {
+ 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(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const SliderExtraParams& slider) {
+ const int midx = rect.x() + rect.width() / 2;
+ const int midy = rect.y() + rect.height() / 2;
+
+ gfx::Rect track_bounds;
+ if (slider.vertical) {
+ track_bounds.SetRect(std::max(rect.x(), midx - 3),
+ rect.y(),
+ std::min(rect.width(), 6),
+ rect.height());
+ } else {
+ track_bounds.SetRect(rect.x(),
+ std::max(rect.y(), midy - 3),
+ rect.width(),
+ std::min(rect.height(), 6));
+ }
+
+ 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(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const SliderExtraParams& slider) {
+ if (state != kDisabled && slider.in_drag)
+ state = kPressed;
+
+ ButtonExtraParams button = { 0 };
+ PaintButtonLike(canvas, state, rect, button);
+}
+
+void NativeThemeChromeos::PaintInnerSpinButton(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const InnerSpinButtonExtraParams& spin_button) {
+ // 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(skia::PlatformCanvas* canvas,
+ State state,
+ const gfx::Rect& rect,
+ const ProgressBarExtraParams& progress_bar) {
+ static const int kBorderWidth = 1;
+ static const SkColor kBackgroundColors[] = {
+ SkColorSetRGB(0xBB, 0xBB, 0xBB),
+ SkColorSetRGB(0xE7, 0xE7, 0xE7),
+ SkColorSetRGB(0xFE, 0xFE, 0xFE)
+ };
+
+ static const SkScalar kBackgroundPoints[] = {
+ SkDoubleToScalar(0),
+ SkDoubleToScalar(0.1),
+ SkDoubleToScalar(1)
+ };
+ static const SkColor kBackgroundBorderColor = SkColorSetRGB(0xA1, 0xA1, 0xA1);
+
+ // 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 ?
+ SkColorSetRGB(100, 116, 147) :
+ SkColorSetRGB(229, 232, 237);
+ const SkColor bar_color_end = enabled ?
+ SkColorSetRGB(65, 73, 87) :
+ SkColorSetRGB(224, 225, 227);
+
+ const SkColor bar_outer_color = enabled ?
+ SkColorSetRGB(0x4A, 0x4A, 0x4A) :
+ SkColorSetARGB(0x80, 0x4A, 0x4A, 0x4A);
+
+ const SkColor bar_inner_border_color =
+ SkColorSetARGB(0x3F, 0xFF, 0xFF, 0xFF); // 0.25 white
+ const SkColor bar_inner_shadow_color =
+ SkColorSetARGB(0x54, 0xFF, 0xFF, 0xFF); // 0.33 white
+
+ // 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) {
@@ -256,3 +722,17 @@ SkBitmap* NativeThemeChromeos::GetHorizontalBitmapNamed(int resource_id) {
return NULL;
}
+void NativeThemeChromeos::PaintButtonLike(skia::PlatformCanvas* canvas,
+ State state, const gfx::Rect& rect,
+ const ButtonExtraParams& button) {
+ SkPath border;
+ GetRoundRectPath(rect, kBorderCornerRadius, &border);
+
+ 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);
+}

Powered by Google App Engine
This is Rietveld 408576698