Index: ui/views/controls/button/toggle_button.cc |
diff --git a/ui/views/controls/button/toggle_button.cc b/ui/views/controls/button/toggle_button.cc |
index e7c656b641bfaaeb7eee4fe06c47f89abc99c3ea..c190946f30ce9649fab8792bbd3f8c06b0b53586 100644 |
--- a/ui/views/controls/button/toggle_button.cc |
+++ b/ui/views/controls/button/toggle_button.cc |
@@ -28,38 +28,30 @@ const int kThumbHorizontalMargin = 4; |
// Margin from top/bottom edge of thumb to top/bottom edge of view. |
const int kThumbVerticalMargin = 3; |
-// TODO(estade): get the base color (black) from the theme? |
-const SkColor kTrackOffColor = |
- SkColorSetA(SK_ColorBLACK, gfx::kDisabledControlAlpha); |
- |
} // namespace |
-// Class representing the thumb. When the thumb is clicked it is separated into |
-// its own layer and the ink drop layer is made a child of the thumb layer |
-// allowing the two to animate in sync. |
-class ToggleButton::ThumbView : public views::View { |
+// Class representing the thumb (the circle that slides horizontally). |
+class ToggleButton::ThumbView : public InkDropHostView { |
public: |
ThumbView() : color_ratio_(0.) {} |
~ThumbView() override {} |
- void AddInkDropLayer(ui::Layer* ink_drop_layer) { |
- SetPaintToLayer(true); |
- layer()->SetFillsBoundsOpaquely(false); |
- layer()->Add(ink_drop_layer); |
- } |
- |
- void RemoveInkDropLayer(ui::Layer* ink_drop_layer) { |
- layer()->Remove(ink_drop_layer); |
- SetPaintToLayer(false); |
- } |
- |
void Update(const gfx::Rect& bounds, double color_ratio) { |
SetBoundsRect(bounds); |
color_ratio_ = color_ratio; |
SchedulePaint(); |
} |
+ static gfx::Insets GetShadowInsets() { |
+ return gfx::Insets(kShadowBlur) + |
+ gfx::Vector2d(kShadowOffsetX, kShadowOffsetY); |
+ } |
+ |
private: |
+ static const int kShadowOffsetX = 0; |
+ static const int kShadowOffsetY = 1; |
+ static const int kShadowBlur = 2; |
+ |
// views::View: |
const char* GetClassName() const override { |
return "ToggleButton::ThumbView"; |
@@ -67,23 +59,34 @@ class ToggleButton::ThumbView : public views::View { |
void OnPaint(gfx::Canvas* canvas) override { |
std::vector<gfx::ShadowValue> shadows; |
- shadows.emplace_back(gfx::Vector2d(0, 1), 4.f, |
- SkColorSetA(SK_ColorBLACK, 0x99)); |
+ shadows.emplace_back( |
+ gfx::Vector2d(kShadowOffsetX, kShadowOffsetY), 2 * kShadowBlur, |
+ SkColorSetA(GetNativeTheme()->GetSystemColor( |
+ ui::NativeTheme::kColorId_LabelEnabledColor), |
+ 0x99)); |
SkPaint thumb_paint; |
thumb_paint.setLooper(gfx::CreateShadowDrawLooperCorrectBlur(shadows)); |
- thumb_paint.setStyle(SkPaint::kFill_Style); |
thumb_paint.setAntiAlias(true); |
const SkColor thumb_on_color = GetNativeTheme()->GetSystemColor( |
ui::NativeTheme::kColorId_ProminentButtonColor); |
- // TODO(estade): get this color from the theme? |
- const SkColor thumb_off_color = SK_ColorWHITE; |
+ const SkColor thumb_off_color = GetNativeTheme()->GetSystemColor( |
+ ui::NativeTheme::kColorId_DialogBackground); |
const SkAlpha blend = static_cast<SkAlpha>(SK_AlphaOPAQUE * color_ratio_); |
thumb_paint.setColor( |
color_utils::AlphaBlend(thumb_on_color, thumb_off_color, blend)); |
- gfx::Rect thumb_bounds = GetLocalBounds(); |
- thumb_bounds.Inset(gfx::Insets(kThumbVerticalMargin)); |
- canvas->DrawCircle(gfx::RectF(thumb_bounds).CenterPoint(), |
- thumb_bounds.height() / 2.f, thumb_paint); |
+ |
+ gfx::RectF thumb_bounds(GetLocalBounds()); |
+ thumb_bounds.Inset(GetShadowInsets()); |
+ thumb_bounds.Inset(gfx::InsetsF(0.5f)); |
+ gfx::RectF bounds_in_px = thumb_bounds; |
+ // We want the circle to have an integer pixel diameter and to be aligned |
+ // with pixel boundaries, so we scale dip bounds to pixel bounds, round, and |
+ // unscale back to dip bounds. |
+ bounds_in_px.Scale(canvas->image_scale()); |
+ gfx::RectF bounds_in_dip(gfx::ToEnclosingRect(bounds_in_px)); |
+ bounds_in_dip.Scale(1.f / canvas->image_scale()); |
+ canvas->DrawCircle(bounds_in_dip.CenterPoint(), |
+ bounds_in_dip.height() / 2.f, thumb_paint); |
} |
// Color ratio between 0 and 1 that controls the thumb color. |
@@ -99,12 +102,12 @@ ToggleButton::ToggleButton(ButtonListener* listener) |
: CustomButton(listener), |
is_on_(false), |
slide_animation_(this), |
- thumb_view_(new ToggleButton::ThumbView()) { |
+ thumb_view_(new ThumbView()) { |
slide_animation_.SetSlideDuration(80 /* ms */); |
slide_animation_.SetTweenType(gfx::Tween::LINEAR); |
SetBorder(Border::CreateEmptyBorder( |
gfx::Insets(kTrackVerticalMargin, kTrackHorizontalMargin))); |
- AddChildView(thumb_view_.get()); |
+ AddChildView(thumb_view_); |
SetInkDropMode(InkDropMode::ON); |
set_has_ink_drop_action_on_click(true); |
} |
@@ -136,13 +139,12 @@ gfx::Rect ToggleButton::GetThumbBounds() const { |
// The thumb is a circle, so the width should match the height. |
thumb_bounds.set_width(thumb_bounds.height()); |
thumb_bounds.set_x(GetMirroredXForRect(thumb_bounds)); |
+ thumb_bounds.Inset(-ThumbView::GetShadowInsets()); |
return thumb_bounds; |
} |
void ToggleButton::UpdateThumb() { |
- gfx::Rect thumb_bounds = GetThumbBounds(); |
- thumb_bounds.Inset(gfx::Insets(-kThumbVerticalMargin)); |
- thumb_view_->Update(thumb_bounds, slide_animation_.GetCurrentValue()); |
+ thumb_view_->Update(GetThumbBounds(), slide_animation_.GetCurrentValue()); |
} |
gfx::Size ToggleButton::GetPreferredSize() const { |
@@ -161,13 +163,9 @@ void ToggleButton::OnPaint(gfx::Canvas* canvas) { |
gfx::RectF track_rect(GetContentsBounds()); |
SkPaint track_paint; |
track_paint.setAntiAlias(true); |
- const SkColor track_on_color = |
- SkColorSetA(GetNativeTheme()->GetSystemColor( |
- ui::NativeTheme::kColorId_ProminentButtonColor), |
- 0xFF / 2); |
const double color_ratio = slide_animation_.GetCurrentValue(); |
track_paint.setColor(color_utils::AlphaBlend( |
- track_on_color, kTrackOffColor, |
+ GetTrackColor(true), GetTrackColor(false), |
static_cast<SkAlpha>(SK_AlphaOPAQUE * color_ratio))); |
canvas->DrawRoundRect(track_rect, track_rect.height() / 2, track_paint); |
} |
@@ -202,10 +200,7 @@ std::unique_ptr<InkDropRipple> ToggleButton::CreateInkDropRipple() const { |
} |
SkColor ToggleButton::GetInkDropBaseColor() const { |
- return is_on() |
- ? GetNativeTheme()->GetSystemColor( |
- ui::NativeTheme::kColorId_ProminentButtonColor) |
- : kTrackOffColor; |
+ return GetTrackColor(is_on()); |
} |
bool ToggleButton::ShouldShowInkDropHighlight() const { |
@@ -223,4 +218,14 @@ void ToggleButton::AnimationProgressed(const gfx::Animation* animation) { |
CustomButton::AnimationProgressed(animation); |
} |
+SkColor ToggleButton::GetTrackColor(bool is_on) const { |
+ const SkAlpha kOffTrackAlpha = 0x29; |
+ const SkAlpha kOnTrackAlpha = kOffTrackAlpha * 2; |
+ ui::NativeTheme::ColorId color_id = |
+ is_on ? ui::NativeTheme::kColorId_ProminentButtonColor |
+ : ui::NativeTheme::kColorId_LabelEnabledColor; |
+ return SkColorSetA(GetNativeTheme()->GetSystemColor(color_id), |
+ is_on ? kOnTrackAlpha : kOffTrackAlpha); |
+} |
+ |
} // namespace views |