blob: 201450f62bb573a935faa4443fa9a45e4b838d44 [file] [log] [blame]
// Copyright 2016 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/views/controls/md_slider.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/slider.h"
namespace views {
// Color of slider at the active and the disabled state, respectively.
const SkColor kActiveColor = SkColorSetARGB(0xFF, 0x42, 0x85, 0xF4);
const SkColor kDisabledColor = SkColorSetARGB(0xFF, 0xBD, 0xBD, 0xBD);
const uint8_t kHighlightColorAlpha = 0x4D;
// The thickness of the slider.
const int kLineThickness = 2;
// The radius used to draw rounded slider ends.
const float kSliderRoundedRadius = 2.f;
// The radius of the thumb and the highlighted thumb of the slider,
// respectively.
const float kThumbRadius = 6.f;
const float kThumbHighlightRadius = 10.f;
// The stroke of the thumb when the slider is disabled.
const int kThumbStroke = 2;
// Duration of the thumb highlight growing effect animation.
const int kSlideHighlightChangeDurationMs = 150;
MdSlider::MdSlider(SliderListener* listener)
: Slider(listener), is_active_(true), thumb_highlight_radius_(0.f) {
SchedulePaint();
}
MdSlider::~MdSlider() {}
void MdSlider::OnPaint(gfx::Canvas* canvas) {
Slider::OnPaint(canvas);
// Paint the slider.
const gfx::Rect content = GetContentsBounds();
const int width = content.width() - kThumbRadius * 2;
const int full = GetAnimatingValue() * width;
const int empty = width - full;
const int y = content.height() / 2 - kLineThickness / 2;
const int x = content.x() + full + kThumbRadius;
const SkColor current_thumb_color =
is_active_ ? kActiveColor : kDisabledColor;
// Extra space used to hide slider ends behind the thumb.
const int extra_padding = 1;
SkPaint slider_paint;
slider_paint.setFlags(SkPaint::kAntiAlias_Flag);
slider_paint.setColor(current_thumb_color);
canvas->DrawRoundRect(
gfx::Rect(content.x(), y, full + extra_padding, kLineThickness),
kSliderRoundedRadius, slider_paint);
slider_paint.setColor(kDisabledColor);
canvas->DrawRoundRect(gfx::Rect(x + kThumbRadius - extra_padding, y,
empty + extra_padding, kLineThickness),
kSliderRoundedRadius, slider_paint);
gfx::Point thumb_center(x, content.height() / 2);
// Paint the thumb highlight if it exists.
if (is_active_ && thumb_highlight_radius_ > kThumbRadius) {
SkPaint highlight;
SkColor kHighlightColor = SkColorSetA(kActiveColor, kHighlightColorAlpha);
highlight.setColor(kHighlightColor);
highlight.setFlags(SkPaint::kAntiAlias_Flag);
canvas->DrawCircle(thumb_center, thumb_highlight_radius_, highlight);
}
// Paint the thumb of the slider.
SkPaint paint;
paint.setColor(current_thumb_color);
paint.setFlags(SkPaint::kAntiAlias_Flag);
if (!is_active_) {
paint.setStrokeWidth(kThumbStroke);
paint.setStyle(SkPaint::kStroke_Style);
}
canvas->DrawCircle(
thumb_center,
is_active_ ? kThumbRadius : (kThumbRadius - kThumbStroke / 2), paint);
}
const char* MdSlider::GetClassName() const {
return "MdSlider";
}
void MdSlider::UpdateState(bool control_on) {
is_active_ = control_on;
SchedulePaint();
}
int MdSlider::GetThumbWidth() {
return kThumbRadius * 2;
}
void MdSlider::SetHighlighted(bool is_highlighted) {
if (!highlight_animation_) {
if (!is_highlighted)
return;
highlight_animation_.reset(new gfx::SlideAnimation(this));
highlight_animation_->SetSlideDuration(kSlideHighlightChangeDurationMs);
}
if (is_highlighted)
highlight_animation_->Show();
else
highlight_animation_->Hide();
}
void MdSlider::AnimationProgressed(const gfx::Animation* animation) {
if (animation != highlight_animation_.get()) {
Slider::AnimationProgressed(animation);
return;
}
thumb_highlight_radius_ =
animation->CurrentValueBetween(kThumbRadius, kThumbHighlightRadius);
SchedulePaint();
}
void MdSlider::AnimationEnded(const gfx::Animation* animation) {
if (animation != highlight_animation_.get()) {
Slider::AnimationEnded(animation);
return;
}
if (animation == highlight_animation_.get() &&
!highlight_animation_->IsShowing()) {
highlight_animation_.reset();
}
}
} // namespace views