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

Side by Side Diff: ui/views/controls/slider.cc

Issue 2335513002: Adding ripple effect for clicks on MD slider (Closed)
Patch Set: improve animation in slider and address comments Created 4 years, 2 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 unified diff | Download patch
« ui/views/controls/slider.h ('K') | « ui/views/controls/slider.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/slider.h" 5 #include "ui/views/controls/slider.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "third_party/skia/include/core/SkCanvas.h" 13 #include "third_party/skia/include/core/SkCanvas.h"
14 #include "third_party/skia/include/core/SkColor.h" 14 #include "third_party/skia/include/core/SkColor.h"
15 #include "third_party/skia/include/core/SkPaint.h" 15 #include "third_party/skia/include/core/SkPaint.h"
16 #include "ui/accessibility/ax_view_state.h" 16 #include "ui/accessibility/ax_view_state.h"
17 #include "ui/base/resource/resource_bundle.h" 17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/events/event.h" 18 #include "ui/events/event.h"
19 #include "ui/gfx/animation/slide_animation.h" 19 #include "ui/gfx/animation/slide_animation.h"
20 #include "ui/gfx/canvas.h" 20 #include "ui/gfx/canvas.h"
21 #include "ui/gfx/geometry/point.h" 21 #include "ui/gfx/geometry/point.h"
22 #include "ui/gfx/geometry/rect.h" 22 #include "ui/gfx/geometry/rect.h"
23 #include "ui/resources/grit/ui_resources.h" 23 #include "ui/resources/grit/ui_resources.h"
24 #include "ui/views/controls/md_slider.h" 24 #include "ui/views/controls/md_slider.h"
25 #include "ui/views/controls/non_md_slider.h" 25 #include "ui/views/controls/non_md_slider.h"
26 #include "ui/views/resources/grit/views_resources.h" 26 #include "ui/views/resources/grit/views_resources.h"
27 #include "ui/views/widget/widget.h" 27 #include "ui/views/widget/widget.h"
28 28
29 namespace { 29 namespace {
30 const int kSlideValueChangeDurationMS = 150; 30 const int kSlideValueChangeDurationMs = 150;
31 31
32 // The image chunks. 32 // The image chunks.
33 enum BorderElements { 33 enum BorderElements {
34 LEFT, 34 LEFT,
35 CENTER_LEFT, 35 CENTER_LEFT,
36 CENTER_RIGHT, 36 CENTER_RIGHT,
37 RIGHT, 37 RIGHT,
38 }; 38 };
39 } // namespace 39 } // namespace
40 40
41 namespace views { 41 namespace views {
42 42
43 // static 43 // static
44 const char Slider::kViewClassName[] = "Slider"; 44 const char Slider::kViewClassName[] = "Slider";
45 45
46 // static 46 // static
47 Slider* Slider::CreateSlider(bool is_material_design, 47 Slider* Slider::CreateSlider(bool is_material_design,
48 SliderListener* listener) { 48 SliderListener* listener) {
49 if (is_material_design) 49 if (is_material_design)
50 return new MdSlider(listener); 50 return new MdSlider(listener);
51 return new NonMdSlider(listener); 51 return new NonMdSlider(listener);
52 } 52 }
53 53
54 Slider::Slider(SliderListener* listener) 54 Slider::Slider(SliderListener* listener)
55 : listener_(listener), 55 : listener_(listener),
56 value_(0.f), 56 value_(0.f),
57 keyboard_increment_(0.1f), 57 keyboard_increment_(0.1f),
58 animating_value_(0.f), 58 initial_animating_value_(0.f),
59 value_is_valid_(false), 59 value_is_valid_(false),
60 accessibility_events_enabled_(true), 60 accessibility_events_enabled_(true),
61 focus_border_color_(0), 61 focus_border_color_(0),
62 initial_button_offset_(0) { 62 initial_button_offset_(0) {
63 EnableCanvasFlippingForRTLUI(true); 63 EnableCanvasFlippingForRTLUI(true);
64 #if defined(OS_MACOSX) 64 #if defined(OS_MACOSX)
65 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); 65 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
66 #else 66 #else
67 SetFocusBehavior(FocusBehavior::ALWAYS); 67 SetFocusBehavior(FocusBehavior::ALWAYS);
68 #endif 68 #endif
(...skipping 17 matching lines...) Expand all
86 if (value_ == value) 86 if (value_ == value)
87 return; 87 return;
88 float old_value = value_; 88 float old_value = value_;
89 value_ = value; 89 value_ = value;
90 if (listener_) 90 if (listener_)
91 listener_->SliderValueChanged(this, value_, old_value, reason); 91 listener_->SliderValueChanged(this, value_, old_value, reason);
92 92
93 if (old_value_valid && base::MessageLoop::current()) { 93 if (old_value_valid && base::MessageLoop::current()) {
94 // Do not animate when setting the value of the slider for the first time. 94 // Do not animate when setting the value of the slider for the first time.
95 // There is no message-loop when running tests. So we cannot animate then. 95 // There is no message-loop when running tests. So we cannot animate then.
96 animating_value_ = old_value; 96 if (!move_animation_.get() || !move_animation_->is_animating()) {
varkha 2016/09/23 22:30:25 I suspect you could remove ".get()".
yiyix 2016/09/24 06:24:36 right, i missed this after our discussion yesterda
97 move_animation_.reset(new gfx::SlideAnimation(this)); 97 initial_animating_value_ = old_value;
98 move_animation_->SetSlideDuration(kSlideValueChangeDurationMS); 98 move_animation_.reset(new gfx::SlideAnimation(this));
99 move_animation_->Show(); 99 move_animation_->SetSlideDuration(kSlideValueChangeDurationMs);
100 AnimationProgressed(move_animation_.get()); 100 move_animation_->Show();
101 }
101 } else { 102 } else {
102 SchedulePaint(); 103 SchedulePaint();
103 } 104 }
104 if (accessibility_events_enabled_ && GetWidget()) { 105 if (accessibility_events_enabled_ && GetWidget())
105 NotifyAccessibilityEvent( 106 NotifyAccessibilityEvent(ui::AX_EVENT_VALUE_CHANGED, true);
106 ui::AX_EVENT_VALUE_CHANGED, true);
107 }
108 } 107 }
109 108
110 void Slider::PrepareForMove(const int new_x) { 109 void Slider::PrepareForMove(const int new_x) {
111 // Try to remember the position of the mouse cursor on the button. 110 // Try to remember the position of the mouse cursor on the button.
112 gfx::Insets inset = GetInsets(); 111 gfx::Insets inset = GetInsets();
113 gfx::Rect content = GetContentsBounds(); 112 gfx::Rect content = GetContentsBounds();
114 float value = move_animation_.get() && move_animation_->is_animating() ? 113 float value = GetAnimatingValue();
115 animating_value_ : value_;
116 114
117 const int thumb_width = GetThumbWidth(); 115 const int thumb_width = GetThumbWidth();
118 const int thumb_x = value * (content.width() - thumb_width); 116 const int thumb_x = value * (content.width() - thumb_width);
119 const int candidate_x = (base::i18n::IsRTL() ? 117 const int candidate_x = (base::i18n::IsRTL() ?
120 width() - (new_x - inset.left()) : 118 width() - (new_x - inset.left()) :
121 new_x - inset.left()) - thumb_x; 119 new_x - inset.left()) - thumb_x;
122 if (candidate_x >= 0 && candidate_x < thumb_width) 120 if (candidate_x >= 0 && candidate_x < thumb_width)
123 initial_button_offset_ = candidate_x; 121 initial_button_offset_ = candidate_x;
124 else 122 else
125 initial_button_offset_ = thumb_width / 2; 123 initial_button_offset_ = thumb_width / 2;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 162
165 return gfx::Size(std::max(width(), kSizeMajor), kSizeMinor); 163 return gfx::Size(std::max(width(), kSizeMajor), kSizeMinor);
166 } 164 }
167 165
168 void Slider::OnPaint(gfx::Canvas* canvas) { 166 void Slider::OnPaint(gfx::Canvas* canvas) {
169 View::OnPaint(canvas); 167 View::OnPaint(canvas);
170 OnPaintFocus(canvas); 168 OnPaintFocus(canvas);
171 } 169 }
172 170
173 float Slider::GetAnimatingValue() const{ 171 float Slider::GetAnimatingValue() const{
174 return move_animation_.get() && move_animation_->is_animating() 172 return move_animation_.get() && move_animation_->is_animating()
varkha 2016/09/23 22:30:25 See if you don't need ".get()".
yiyix 2016/09/24 06:24:36 Done.
175 ? animating_value_ 173 ? move_animation_->CurrentValueBetween(initial_animating_value_,
174 value_)
176 : value_; 175 : value_;
177 } 176 }
178 177
179 bool Slider::OnMousePressed(const ui::MouseEvent& event) { 178 bool Slider::OnMousePressed(const ui::MouseEvent& event) {
180 if (!event.IsOnlyLeftMouseButton()) 179 if (!event.IsOnlyLeftMouseButton())
181 return false; 180 return false;
182 OnSliderDragStarted(); 181 OnSliderDragStarted();
183 PrepareForMove(event.location().x()); 182 PrepareForMove(event.location().x());
184 MoveButtonTo(event.location()); 183 MoveButtonTo(event.location());
185 return true; 184 return true;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 event->SetHandled(); 233 event->SetHandled();
235 if (event->details().touch_points() <= 1) 234 if (event->details().touch_points() <= 1)
236 OnSliderDragEnded(); 235 OnSliderDragEnded();
237 break; 236 break;
238 default: 237 default:
239 break; 238 break;
240 } 239 }
241 } 240 }
242 241
243 void Slider::AnimationProgressed(const gfx::Animation* animation) { 242 void Slider::AnimationProgressed(const gfx::Animation* animation) {
244 animating_value_ = animation->CurrentValueBetween(animating_value_, value_); 243 if (animation && animation != move_animation_.get())
244 return;
varkha 2016/09/23 22:30:25 So you are no longer doing exponential approximati
yiyix 2016/09/24 06:24:36 No, I like the default SlideAnimation behavior
245 SchedulePaint(); 245 SchedulePaint();
246 } 246 }
247 247
248 void Slider::AnimationEnded(const gfx::Animation* animation) {
249 if (animation == move_animation_.get() && !move_animation_->IsShowing()) {
tdanderson 2016/09/23 20:55:50 nit: no {}
yiyix 2016/09/23 21:39:57 Done.
250 move_animation_.reset();
251 }
252 }
253
248 void Slider::GetAccessibleState(ui::AXViewState* state) { 254 void Slider::GetAccessibleState(ui::AXViewState* state) {
249 state->role = ui::AX_ROLE_SLIDER; 255 state->role = ui::AX_ROLE_SLIDER;
250 state->name = accessible_name_; 256 state->name = accessible_name_;
251 state->value = base::UTF8ToUTF16( 257 state->value = base::UTF8ToUTF16(
252 base::StringPrintf("%d%%", static_cast<int>(value_ * 100 + 0.5))); 258 base::StringPrintf("%d%%", static_cast<int>(value_ * 100 + 0.5)));
253 } 259 }
254 260
255 void Slider::OnSliderDragStarted() { 261 void Slider::OnSliderDragStarted() {
262 SetHighlighted(true);
256 if (listener_) 263 if (listener_)
257 listener_->SliderDragStarted(this); 264 listener_->SliderDragStarted(this);
258 } 265 }
259 266
260 void Slider::OnSliderDragEnded() { 267 void Slider::OnSliderDragEnded() {
268 SetHighlighted(false);
261 if (listener_) 269 if (listener_)
262 listener_->SliderDragEnded(this); 270 listener_->SliderDragEnded(this);
263 } 271 }
264 272
265 } // namespace views 273 } // namespace views
OLDNEW
« ui/views/controls/slider.h ('K') | « ui/views/controls/slider.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698