Chromium Code Reviews| Index: ui/views/controls/slider.cc |
| diff --git a/ui/views/controls/slider.cc b/ui/views/controls/slider.cc |
| index d35b8046959d0b7ad361f8af97e7808cf462341f..a53f541c304cd8e750a9682dee35ece58c8db57d 100644 |
| --- a/ui/views/controls/slider.cc |
| +++ b/ui/views/controls/slider.cc |
| @@ -10,20 +10,18 @@ |
| #include "base/message_loop/message_loop.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/strings/utf_string_conversions.h" |
| +#include "cc/paint/paint_flags.h" |
| #include "third_party/skia/include/core/SkCanvas.h" |
| #include "third_party/skia/include/core/SkColor.h" |
| #include "third_party/skia/include/core/SkPaint.h" |
| #include "ui/accessibility/ax_node_data.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/events/event.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/native_theme/native_theme.h" |
| #include "ui/resources/grit/ui_resources.h" |
| -#include "ui/views/controls/md_slider.h" |
| -#include "ui/views/controls/non_md_slider.h" |
| #include "ui/views/resources/grit/views_resources.h" |
| #include "ui/views/widget/widget.h" |
| @@ -41,20 +39,51 @@ enum BorderElements { |
| namespace views { |
| +namespace { |
| + |
| +// 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); |
| +constexpr uint8_t kHighlightColorAlpha = 0x4D; |
| + |
| +// The thickness of the slider. |
| +constexpr int kLineThickness = 2; |
| + |
| +// The radius used to draw rounded slider ends. |
| +constexpr float kSliderRoundedRadius = 2.f; |
| + |
| +// The radius of the thumb and the highlighted thumb of the slider, |
| +// respectively. |
| +constexpr float kThumbRadius = 6.f; |
| +constexpr float kThumbWidth = 2 * kThumbRadius; |
| +constexpr float kThumbHighlightRadius = 10.f; |
| + |
| +// The stroke of the thumb when the slider is disabled. |
| +constexpr int kThumbStroke = 2; |
| + |
| +// Duration of the thumb highlight growing effect animation. |
| +constexpr int kSlideHighlightChangeDurationMs = 150; |
| + |
| +} // namespace |
| + |
| // static |
| const char Slider::kViewClassName[] = "Slider"; |
| -// static |
| -Slider* Slider::CreateSlider(bool is_material_design, |
| - SliderListener* listener) { |
| - if (is_material_design) |
| - return new MdSlider(listener); |
| - return new NonMdSlider(listener); |
| -} |
| +Slider::Slider(SliderListener* listener) |
| + : listener_(listener), highlight_animation_(this) { |
| + highlight_animation_.SetSlideDuration(kSlideHighlightChangeDurationMs); |
| + EnableCanvasFlippingForRTLUI(true); |
| +#if defined(OS_MACOSX) |
| + SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); |
| +#else |
| + SetFocusBehavior(FocusBehavior::ALWAYS); |
| +#endif |
| -Slider::~Slider() { |
| + SchedulePaint(); |
|
msw
2017/02/16 21:08:20
q: needed? (presumably it'll schedule a paint when
Evan Stade
2017/02/16 22:48:01
yea, this is weird. I don't know why it's here (ju
|
| } |
| +Slider::~Slider() {} |
| + |
| void Slider::SetValue(float value) { |
| SetValueInternal(value, VALUE_CHANGED_BY_API); |
| } |
| @@ -63,20 +92,9 @@ void Slider::SetAccessibleName(const base::string16& name) { |
| accessible_name_ = name; |
| } |
| -Slider::Slider(SliderListener* listener) |
| - : listener_(listener), |
| - value_(0.f), |
| - keyboard_increment_(0.1f), |
| - initial_animating_value_(0.f), |
| - value_is_valid_(false), |
| - accessibility_events_enabled_(true), |
| - initial_button_offset_(0) { |
| - EnableCanvasFlippingForRTLUI(true); |
| -#if defined(OS_MACOSX) |
| - SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); |
| -#else |
| - SetFocusBehavior(FocusBehavior::ALWAYS); |
| -#endif |
| +void Slider::UpdateState(bool control_on) { |
| + is_active_ = control_on; |
| + SchedulePaint(); |
| } |
| float Slider::GetAnimatingValue() const{ |
| @@ -86,21 +104,82 @@ float Slider::GetAnimatingValue() const{ |
| : value_; |
| } |
| -void Slider::SetHighlighted(bool is_highlighted) {} |
| +void Slider::SetHighlighted(bool is_highlighted) { |
| + if (is_highlighted) |
| + highlight_animation_.Show(); |
| + else |
| + highlight_animation_.Hide(); |
| +} |
| void Slider::OnPaint(gfx::Canvas* canvas) { |
| - View::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; |
| + |
| + cc::PaintFlags slider_flags; |
| + slider_flags.setAntiAlias(true); |
| + slider_flags.setColor(current_thumb_color); |
| + canvas->DrawRoundRect( |
| + gfx::Rect(content.x(), y, full + extra_padding, kLineThickness), |
| + kSliderRoundedRadius, slider_flags); |
| + slider_flags.setColor(kDisabledColor); |
| + canvas->DrawRoundRect(gfx::Rect(x + kThumbRadius - extra_padding, y, |
| + empty + extra_padding, kLineThickness), |
| + kSliderRoundedRadius, slider_flags); |
| + |
| + gfx::Point thumb_center(x, content.height() / 2); |
| + |
| + // Paint the thumb highlight if it exists. |
| + const int thumb_highlight_radius = |
| + HasFocus() ? kThumbHighlightRadius : thumb_highlight_radius_; |
| + if (is_active_ && thumb_highlight_radius > kThumbRadius) { |
| + cc::PaintFlags highlight; |
| + SkColor kHighlightColor = SkColorSetA(kActiveColor, kHighlightColorAlpha); |
| + highlight.setColor(kHighlightColor); |
| + highlight.setFlags(cc::PaintFlags::kAntiAlias_Flag); |
| + canvas->DrawCircle(thumb_center, thumb_highlight_radius, highlight); |
| + } |
| + |
| + // Paint the thumb of the slider. |
| + cc::PaintFlags flags; |
| + flags.setColor(current_thumb_color); |
| + flags.setFlags(cc::PaintFlags::kAntiAlias_Flag); |
| + |
| + if (!is_active_) { |
| + flags.setStrokeWidth(kThumbStroke); |
| + flags.setStyle(cc::PaintFlags::kStroke_Style); |
| + } |
| + canvas->DrawCircle( |
| + thumb_center, |
| + is_active_ ? kThumbRadius : (kThumbRadius - kThumbStroke / 2), flags); |
| + |
| OnPaintFocus(canvas); |
| } |
| void Slider::AnimationProgressed(const gfx::Animation* animation) { |
| - if (animation == move_animation_.get()) |
| - SchedulePaint(); |
| + if (animation == &highlight_animation_) { |
| + thumb_highlight_radius_ = |
| + animation->CurrentValueBetween(kThumbRadius, kThumbHighlightRadius); |
| + } |
| + |
| + SchedulePaint(); |
| } |
| void Slider::AnimationEnded(const gfx::Animation* animation) { |
| - if (animation == move_animation_.get()) |
| + if (animation == move_animation_.get()) { |
| move_animation_.reset(); |
| + return; |
| + } |
| + DCHECK_EQ(animation, &highlight_animation_); |
| } |
| void Slider::SetValueInternal(float value, SliderChangeReason reason) { |
| @@ -140,26 +219,24 @@ void Slider::PrepareForMove(const int new_x) { |
| gfx::Rect content = GetContentsBounds(); |
| float value = GetAnimatingValue(); |
| - const int thumb_width = GetThumbWidth(); |
| - const int thumb_x = value * (content.width() - thumb_width); |
| + const int thumb_x = value * (content.width() - kThumbWidth); |
| const int candidate_x = (base::i18n::IsRTL() ? |
| width() - (new_x - inset.left()) : |
| new_x - inset.left()) - thumb_x; |
| - if (candidate_x >= 0 && candidate_x < thumb_width) |
| + if (candidate_x >= 0 && candidate_x < kThumbWidth) |
| initial_button_offset_ = candidate_x; |
| else |
| - initial_button_offset_ = thumb_width / 2; |
| + initial_button_offset_ = kThumbRadius; |
| } |
| void Slider::MoveButtonTo(const gfx::Point& point) { |
| const gfx::Insets inset = GetInsets(); |
| - const int thumb_width = GetThumbWidth(); |
| // Calculate the value. |
| int amount = base::i18n::IsRTL() |
| ? width() - inset.left() - point.x() - initial_button_offset_ |
| : point.x() - inset.left() - initial_button_offset_; |
| SetValueInternal( |
| - static_cast<float>(amount) / (width() - inset.width() - thumb_width), |
| + static_cast<float>(amount) / (width() - inset.width() - kThumbWidth), |
| VALUE_CHANGED_BY_USER); |
| } |