Commit b3589492 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

Update CocoaScrollbarPainter in preparation for use in blink

Change interfaces to use cc::PaintCanvas and SkIRect. Immediately
convert back to gfx types.

Touch up colors so that the diffs in layout tests will be minimized.

Add code to paint the corner. Share this with the track painting code,
and split the track painting code into helper functions for this
purpose.

Bug: 961835
Change-Id: I451f16711afce8e4a0bff5e963f1dc3e06f22410
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1896044Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Commit-Queue: ccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#711935}
parent 84f4134a
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
namespace gfx { namespace gfx {
using Params = CocoaScrollbarPainter::Params;
using Orientation = CocoaScrollbarPainter::Orientation;
namespace { namespace {
// The width of the scroller track border. // The width of the scroller track border.
...@@ -19,8 +22,13 @@ constexpr int kTrackBorderWidth = 1; ...@@ -19,8 +22,13 @@ constexpr int kTrackBorderWidth = 1;
constexpr int kThumbInset = 3; constexpr int kThumbInset = 3;
constexpr int kThumbInsetOverlay = 2; constexpr int kThumbInsetOverlay = 2;
// The minimum sizes for the thumb. We will not inset the thumb if it will
// be smaller than this size.
constexpr int kThumbMinGirth = 8;
constexpr int kThumbMinLength = 18;
// Scrollbar thumb colors. // Scrollbar thumb colors.
constexpr SkColor kThumbColorDefault = SkColorSetARGB(0x38, 0, 0, 0); constexpr SkColor kThumbColorDefault = SkColorSetARGB(0x3A, 0, 0, 0);
constexpr SkColor kThumbColorHover = SkColorSetARGB(0x80, 0, 0, 0); constexpr SkColor kThumbColorHover = SkColorSetARGB(0x80, 0, 0, 0);
constexpr SkColor kThumbColorDarkMode = SkColorSetRGB(0x6B, 0x6B, 0x6B); constexpr SkColor kThumbColorDarkMode = SkColorSetRGB(0x6B, 0x6B, 0x6B);
constexpr SkColor kThumbColorDarkModeHover = SkColorSetRGB(0x93, 0x93, 0x93); constexpr SkColor kThumbColorDarkModeHover = SkColorSetRGB(0x93, 0x93, 0x93);
...@@ -31,8 +39,8 @@ constexpr SkColor kThumbColorOverlayDarkMode = ...@@ -31,8 +39,8 @@ constexpr SkColor kThumbColorOverlayDarkMode =
// Non-overlay scroller track colors are not transparent. On Safari, they are, // Non-overlay scroller track colors are not transparent. On Safari, they are,
// but on all other macOS applications they are not. // but on all other macOS applications they are not.
constexpr SkColor kTrackGradientColors[] = { constexpr SkColor kTrackGradientColors[] = {
SkColorSetRGB(0xF9, 0xF9, 0xF9), SkColorSetRGB(0xFA, 0xFA, 0xFA),
SkColorSetRGB(0xF9, 0xF9, 0xF9), SkColorSetRGB(0xFA, 0xFA, 0xFA),
}; };
constexpr SkColor kTrackInnerBorderColor = SkColorSetRGB(0xE8, 0xE8, 0xE8); constexpr SkColor kTrackInnerBorderColor = SkColorSetRGB(0xE8, 0xE8, 0xE8);
constexpr SkColor kTrackOuterBorderColor = SkColorSetRGB(0xED, 0xED, 0xED); constexpr SkColor kTrackOuterBorderColor = SkColorSetRGB(0xED, 0xED, 0xED);
...@@ -71,95 +79,215 @@ constexpr SkColor kTrackInnerBorderColorOverlayDarkMode = ...@@ -71,95 +79,215 @@ constexpr SkColor kTrackInnerBorderColorOverlayDarkMode =
constexpr SkColor kTrackOuterBorderColorOverlayDarkMode = constexpr SkColor kTrackOuterBorderColorOverlayDarkMode =
SkColorSetARGB(0x28, 0xD8, 0xD8, 0xD8); SkColorSetARGB(0x28, 0xD8, 0xD8, 0xD8);
} // namespace void ConstrainInsets(int old_width, int min_width, int* left, int* right) {
int requested_total_inset = *left + *right;
if (requested_total_inset == 0)
return;
int max_total_inset = old_width - min_width;
if (requested_total_inset < max_total_inset)
return;
if (max_total_inset < 0) {
*left = *right = 0;
return;
}
// Prefer to preserve the the left (or top) side's inset.
*left = std::min(max_total_inset, *left);
*right = max_total_inset - *left;
}
// static gfx::Rect ConstrainedInset(const gfx::Rect& rect,
void CocoaScrollbarPainter::PaintTrack(gfx::Canvas* canvas, int min_width,
const gfx::Rect& track_rect, int min_height,
const Params& params) { int inset_left,
// Set the colors based on overlay and dark mode. int inset_top,
SkColor inner_border_color = kTrackInnerBorderColor; int inset_right,
SkColor outer_border_color = kTrackOuterBorderColor; int inset_bottom) {
const SkColor* gradient_colors = kTrackGradientColors; ConstrainInsets(rect.width(), min_width, &inset_left, &inset_right);
size_t gradient_stops = base::size(kTrackGradientColors); ConstrainInsets(rect.height(), min_height, &inset_top, &inset_bottom);
gfx::Rect inset_rect = rect;
inset_rect.Inset(inset_left, inset_top, inset_right, inset_bottom);
return inset_rect;
}
void PaintTrackGradient(gfx::Canvas* canvas,
const gfx::Rect& rect,
const Params& params,
bool is_corner) {
// Select colors.
const SkColor* gradient_colors = nullptr;
size_t gradient_stops = 0;
if (params.overlay) { if (params.overlay) {
if (params.dark_mode) { if (params.dark_mode) {
inner_border_color = kTrackInnerBorderColorOverlayDarkMode;
outer_border_color = kTrackOuterBorderColorOverlayDarkMode;
gradient_colors = kTrackGradientColorsOverlayDarkMode; gradient_colors = kTrackGradientColorsOverlayDarkMode;
gradient_stops = base::size(kTrackGradientColorsOverlayDarkMode); gradient_stops = base::size(kTrackGradientColorsOverlayDarkMode);
} else { } else {
inner_border_color = kTrackInnerBorderColorOverlay;
outer_border_color = kTrackOuterBorderColorOverlay;
gradient_colors = kTrackGradientColorsOverlay; gradient_colors = kTrackGradientColorsOverlay;
gradient_stops = base::size(kTrackGradientColorsOverlay); gradient_stops = base::size(kTrackGradientColorsOverlay);
} }
} else { } else {
if (params.dark_mode) { if (params.dark_mode) {
inner_border_color = kTrackInnerBorderColorDarkMode;
outer_border_color = kTrackOuterBorderColorDarkMode;
gradient_colors = kTrackGradientColorsDarkMode; gradient_colors = kTrackGradientColorsDarkMode;
gradient_stops = base::size(kTrackGradientColorsDarkMode); gradient_stops = base::size(kTrackGradientColorsDarkMode);
} else {
gradient_colors = kTrackGradientColors;
gradient_stops = base::size(kTrackGradientColors);
} }
} }
// Paint the scrollbar track background. // Set the gradient direction.
{ const SkPoint gradient_bounds_vertical[] = {
const SkPoint gradient_bounds[] = { gfx::PointToSkPoint(rect.origin()),
gfx::PointToSkPoint(track_rect.origin()), gfx::PointToSkPoint(rect.bottom_left()),
gfx::PointToSkPoint(params.orientation == Orientation::kHorizontal };
? track_rect.bottom_left() const SkPoint gradient_bounds_horizontal[] = {
: track_rect.top_right()), gfx::PointToSkPoint(rect.origin()),
}; gfx::PointToSkPoint(rect.top_right()),
cc::PaintFlags gradient; };
gradient.setShader(cc::PaintShader::MakeLinearGradient( const SkPoint gradient_bounds_corner_right[] = {
gradient_bounds, gradient_colors, nullptr, gradient_stops, gfx::PointToSkPoint(rect.origin()),
SkTileMode::kClamp)); gfx::PointToSkPoint(rect.bottom_right()),
canvas->DrawRect(track_rect, gradient); };
const SkPoint gradient_bounds_corner_left[] = {
gfx::PointToSkPoint(rect.top_right()),
gfx::PointToSkPoint(rect.bottom_left()),
};
const SkPoint* gradient_bounds = nullptr;
if (is_corner) {
if (params.orientation == Orientation::kVerticalOnRight)
gradient_bounds = gradient_bounds_corner_right;
else
gradient_bounds = gradient_bounds_corner_left;
} else {
if (params.orientation == Orientation::kHorizontal)
gradient_bounds = gradient_bounds_horizontal;
else
gradient_bounds = gradient_bounds_vertical;
} }
// Draw the inner border: top if horizontal, left if vertical. // And draw.
{ cc::PaintFlags gradient;
cc::PaintFlags flags; gradient.setShader(cc::PaintShader::MakeLinearGradient(
flags.setColor(inner_border_color); gradient_bounds, gradient_colors, nullptr, gradient_stops,
gfx::Rect inner_border(track_rect); SkTileMode::kClamp));
if (params.orientation == Orientation::kHorizontal) canvas->DrawRect(rect, gradient);
inner_border.set_height(kTrackBorderWidth); }
void PaintTrackInnerBorder(gfx::Canvas* canvas,
const gfx::Rect& rect,
const Params& params,
bool is_corner) {
// Select the color.
SkColor inner_border_color = 0;
if (params.overlay) {
if (params.dark_mode)
inner_border_color = kTrackInnerBorderColorOverlayDarkMode;
else
inner_border_color = kTrackInnerBorderColorOverlay;
} else {
if (params.dark_mode)
inner_border_color = kTrackInnerBorderColorDarkMode;
else else
inner_border.set_width(kTrackBorderWidth); inner_border_color = kTrackInnerBorderColor;
canvas->DrawRect(inner_border, flags);
} }
// Draw the outer border: bottom if horizontal, right if veritcal. // Compute the rect for the border.
{ gfx::Rect inner_border(rect);
cc::PaintFlags flags; if (params.orientation == Orientation::kVerticalOnLeft)
flags.setColor(outer_border_color); inner_border.set_x(rect.right() - kTrackBorderWidth);
gfx::Rect outer_border(track_rect); if (is_corner || params.orientation == Orientation::kHorizontal)
if (params.orientation == Orientation::kHorizontal) { inner_border.set_height(kTrackBorderWidth);
outer_border.set_height(kTrackBorderWidth); if (is_corner || params.orientation != Orientation::kHorizontal)
outer_border.set_y(track_rect.bottom() - kTrackBorderWidth); inner_border.set_width(kTrackBorderWidth);
} else {
outer_border.set_width(kTrackBorderWidth); // And draw.
outer_border.set_x(track_rect.right() - kTrackBorderWidth); cc::PaintFlags flags;
} flags.setColor(inner_border_color);
canvas->DrawRect(inner_border, flags);
}
void PaintTrackOuterBorder(gfx::Canvas* canvas,
const gfx::Rect& rect,
const Params& params,
bool is_corner) {
// Select the color.
SkColor outer_border_color = 0;
if (params.overlay) {
if (params.dark_mode)
outer_border_color = kTrackOuterBorderColorOverlayDarkMode;
else
outer_border_color = kTrackOuterBorderColorOverlay;
} else {
if (params.dark_mode)
outer_border_color = kTrackOuterBorderColorDarkMode;
else
outer_border_color = kTrackOuterBorderColor;
}
cc::PaintFlags flags;
flags.setColor(outer_border_color);
// Draw the horizontal outer border.
if (is_corner || params.orientation == Orientation::kHorizontal) {
gfx::Rect outer_border(rect);
outer_border.set_height(kTrackBorderWidth);
outer_border.set_y(rect.bottom() - kTrackBorderWidth);
canvas->DrawRect(outer_border, flags); canvas->DrawRect(outer_border, flags);
} }
// Draw the vertial outer border.
if (is_corner || params.orientation != Orientation::kHorizontal) {
gfx::Rect outer_border(rect);
outer_border.set_width(kTrackBorderWidth);
if (params.orientation == Orientation::kVerticalOnRight)
outer_border.set_x(rect.right() - kTrackBorderWidth);
canvas->DrawRect(outer_border, flags);
}
}
} // namespace
// static
void CocoaScrollbarPainter::PaintTrack(cc::PaintCanvas* cc_canvas,
const SkIRect& sk_track_rect,
const Params& params) {
gfx::Canvas canvas(cc_canvas, 1.f);
const gfx::Rect track_rect(SkIRectToRect(sk_track_rect));
constexpr bool is_corner = false;
PaintTrackGradient(&canvas, track_rect, params, is_corner);
PaintTrackInnerBorder(&canvas, track_rect, params, is_corner);
PaintTrackOuterBorder(&canvas, track_rect, params, is_corner);
}
// static
void CocoaScrollbarPainter::PaintCorner(cc::PaintCanvas* cc_canvas,
const SkIRect& sk_corner_rect,
const Params& params) {
// Overlay scrollbars don't have a corner.
if (params.overlay)
return;
gfx::Canvas canvas(cc_canvas, 1.f);
const gfx::Rect corner_rect(SkIRectToRect(sk_corner_rect));
constexpr bool is_corner = true;
PaintTrackGradient(&canvas, corner_rect, params, is_corner);
PaintTrackInnerBorder(&canvas, corner_rect, params, is_corner);
PaintTrackOuterBorder(&canvas, corner_rect, params, is_corner);
} }
// static // static
void CocoaScrollbarPainter::PaintThumb(gfx::Canvas* canvas, void CocoaScrollbarPainter::PaintThumb(cc::PaintCanvas* cc_canvas,
const gfx::Rect& thumb_bounds, const SkIRect& sk_bounds,
const Params& params) { const Params& params) {
gfx::Rect bounds(thumb_bounds); gfx::Canvas canvas(cc_canvas, 1.f);
gfx::Rect bounds(SkIRectToRect(sk_bounds));
SkColor thumb_color = 0; SkColor thumb_color = 0;
int thumb_inset = 0;
if (params.overlay) { if (params.overlay) {
bounds.Inset(kThumbInsetOverlay, kThumbInsetOverlay); thumb_inset = kThumbInsetOverlay;
if (params.dark_mode) if (params.dark_mode)
thumb_color = kThumbColorOverlayDarkMode; thumb_color = kThumbColorOverlayDarkMode;
else else
thumb_color = kThumbColorOverlay; thumb_color = kThumbColorOverlay;
} else { } else {
bounds.Inset(kThumbInset, kThumbInset); thumb_inset = kThumbInset;
if (params.dark_mode) { if (params.dark_mode) {
if (params.hovered) if (params.hovered)
thumb_color = kThumbColorDarkModeHover; thumb_color = kThumbColorDarkModeHover;
...@@ -173,24 +301,39 @@ void CocoaScrollbarPainter::PaintThumb(gfx::Canvas* canvas, ...@@ -173,24 +301,39 @@ void CocoaScrollbarPainter::PaintThumb(gfx::Canvas* canvas,
} }
} }
// Shrink the thumb evenly in length and girth to fit within the track. Do not
// shrink beyond the minimum size.
if (params.orientation == Orientation::kHorizontal) {
bounds =
ConstrainedInset(bounds, kThumbMinLength, kThumbMinGirth, thumb_inset,
thumb_inset, thumb_inset, thumb_inset);
} else {
bounds =
ConstrainedInset(bounds, kThumbMinGirth, kThumbMinLength, thumb_inset,
thumb_inset, thumb_inset, thumb_inset);
}
// Shrink the thumb in girth to not touch the border. Note that this can
// shrink below the minimum girth.
switch (params.orientation) { switch (params.orientation) {
case Orientation::kHorizontal: case Orientation::kHorizontal:
bounds.Inset(0, kTrackBorderWidth, 0, 0); bounds.Inset(0, kTrackBorderWidth, 0, 0);
break; break;
case Orientation::kVerticalOnLeft: case Orientation::kVerticalOnLeft:
bounds.Inset(0, 0, kTrackBorderWidth, 0); bounds.Inset(kTrackBorderWidth, 0, 0, 0);
break; break;
case Orientation::kVerticalOnRight: case Orientation::kVerticalOnRight:
bounds.Inset(kTrackBorderWidth, 0, 0, 0); bounds.Inset(kTrackBorderWidth, 0, 0, 0);
break; break;
} }
// Draw.
cc::PaintFlags flags; cc::PaintFlags flags;
flags.setAntiAlias(true); flags.setAntiAlias(true);
flags.setStyle(cc::PaintFlags::kFill_Style); flags.setStyle(cc::PaintFlags::kFill_Style);
flags.setColor(thumb_color); flags.setColor(thumb_color);
const SkScalar radius = std::min(bounds.width(), bounds.height()); const SkScalar radius = std::min(bounds.width(), bounds.height());
canvas->DrawRoundRect(bounds, radius, flags); canvas.DrawRoundRect(bounds, radius, flags);
} }
} // namespace gfx } // namespace gfx
...@@ -5,13 +5,12 @@ ...@@ -5,13 +5,12 @@
#ifndef UI_GFX_MAC_COCOA_SCROLLBAR_PAINTER_H_ #ifndef UI_GFX_MAC_COCOA_SCROLLBAR_PAINTER_H_
#define UI_GFX_MAC_COCOA_SCROLLBAR_PAINTER_H_ #define UI_GFX_MAC_COCOA_SCROLLBAR_PAINTER_H_
#include "ui/gfx/geometry/rect.h" #include "cc/paint/paint_canvas.h"
#include "third_party/skia/include/core/SkRect.h"
#include "ui/gfx/gfx_export.h" #include "ui/gfx/gfx_export.h"
namespace gfx { namespace gfx {
class Canvas;
class GFX_EXPORT CocoaScrollbarPainter { class GFX_EXPORT CocoaScrollbarPainter {
public: public:
enum class Orientation { enum class Orientation {
...@@ -40,13 +39,17 @@ class GFX_EXPORT CocoaScrollbarPainter { ...@@ -40,13 +39,17 @@ class GFX_EXPORT CocoaScrollbarPainter {
// Paint the thumb. The |thumb_bounds| changes over time when the thumb // Paint the thumb. The |thumb_bounds| changes over time when the thumb
// engorges during hover. // engorges during hover.
static void PaintThumb(gfx::Canvas* canvas, static void PaintThumb(cc::PaintCanvas* canvas,
const gfx::Rect& thumb_bounds, const SkIRect& thumb_bounds,
const Params& params); const Params& params);
// Paint the track. |bounds| is the bounds for the track. // Paint the track. |track_bounds| is the bounds for the track.
static void PaintTrack(gfx::Canvas* canvas, static void PaintTrack(cc::PaintCanvas* canvas,
const gfx::Rect& track_bounds, const SkIRect& track_bounds,
const Params& params); const Params& params);
// Paint the corner. |corner_bounds| is the bounds for the corner.
static void PaintCorner(cc::PaintCanvas* canvas,
const SkIRect& corner_bounds,
const Params& params);
}; };
} // namespace gfx } // namespace gfx
......
...@@ -102,7 +102,8 @@ void CocoaScrollBarThumb::OnPaint(gfx::Canvas* canvas) { ...@@ -102,7 +102,8 @@ void CocoaScrollBarThumb::OnPaint(gfx::Canvas* canvas) {
auto params = cocoa_scroll_bar_->GetPainterParams(); auto params = cocoa_scroll_bar_->GetPainterParams();
// Set the hover state based only on the thumb. // Set the hover state based only on the thumb.
params.hovered = IsStateHovered() || IsStatePressed(); params.hovered = IsStateHovered() || IsStatePressed();
CocoaScrollbarPainter::PaintThumb(canvas, GetLocalBounds(), params); CocoaScrollbarPainter::PaintThumb(
canvas->sk_canvas(), gfx::RectToSkIRect(GetLocalBounds()), params);
} }
bool CocoaScrollBarThumb::OnMousePressed(const ui::MouseEvent& event) { bool CocoaScrollBarThumb::OnMousePressed(const ui::MouseEvent& event) {
...@@ -209,7 +210,8 @@ void CocoaScrollBar::OnPaint(gfx::Canvas* canvas) { ...@@ -209,7 +210,8 @@ void CocoaScrollBar::OnPaint(gfx::Canvas* canvas) {
// Transparency of the track is handled by the View opacity, so always draw // Transparency of the track is handled by the View opacity, so always draw
// using the non-overlay path. // using the non-overlay path.
params.overlay = false; params.overlay = false;
CocoaScrollbarPainter::PaintTrack(canvas, GetLocalBounds(), params); CocoaScrollbarPainter::PaintTrack(
canvas->sk_canvas(), gfx::RectToSkIRect(GetLocalBounds()), params);
} }
bool CocoaScrollBar::OnMousePressed(const ui::MouseEvent& event) { bool CocoaScrollBar::OnMousePressed(const ui::MouseEvent& event) {
......
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