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

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

Issue 2335513002: Adding ripple effect for clicks on MD slider (Closed)
Patch Set: 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/md_slider.cc ('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() {
55 }
56
57 void Slider::SetValue(float value) {
58 SetValueInternal(value, VALUE_CHANGED_BY_API);
59 }
60
61 void Slider::SetAccessibleName(const base::string16& name) {
62 accessible_name_ = name;
63 }
64
54 Slider::Slider(SliderListener* listener) 65 Slider::Slider(SliderListener* listener)
55 : listener_(listener), 66 : listener_(listener),
56 value_(0.f), 67 value_(0.f),
57 keyboard_increment_(0.1f), 68 keyboard_increment_(0.1f),
58 animating_value_(0.f), 69 initial_animating_value_(0.f),
59 value_is_valid_(false), 70 value_is_valid_(false),
60 accessibility_events_enabled_(true), 71 accessibility_events_enabled_(true),
61 focus_border_color_(0), 72 focus_border_color_(0),
62 initial_button_offset_(0) { 73 initial_button_offset_(0) {
63 EnableCanvasFlippingForRTLUI(true); 74 EnableCanvasFlippingForRTLUI(true);
64 #if defined(OS_MACOSX) 75 #if defined(OS_MACOSX)
65 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); 76 SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
66 #else 77 #else
67 SetFocusBehavior(FocusBehavior::ALWAYS); 78 SetFocusBehavior(FocusBehavior::ALWAYS);
68 #endif 79 #endif
69 } 80 }
70 81
71 Slider::~Slider() { 82 float Slider::GetAnimatingValue() const{
83 return move_animation_ && move_animation_->is_animating()
84 ? move_animation_->CurrentValueBetween(initial_animating_value_,
85 value_)
86 : value_;
72 } 87 }
73 88
74 void Slider::SetValue(float value) { 89 void Slider::SetHighlighted(bool is_highlighted) {}
75 SetValueInternal(value, VALUE_CHANGED_BY_API); 90
91 void Slider::OnPaint(gfx::Canvas* canvas) {
92 View::OnPaint(canvas);
93 OnPaintFocus(canvas);
94 }
95
96 void Slider::AnimationProgressed(const gfx::Animation* animation) {
97 SchedulePaint();
bruthig 2016/09/30 21:56:18 nit: You should be consistent with what you do her
yiyix 2016/10/03 16:06:50 Done.
98 }
99
100 void Slider::AnimationEnded(const gfx::Animation* animation) {
101 if (animation == move_animation_.get())
102 move_animation_.reset();
76 } 103 }
77 104
78 void Slider::SetValueInternal(float value, SliderChangeReason reason) { 105 void Slider::SetValueInternal(float value, SliderChangeReason reason) {
79 bool old_value_valid = value_is_valid_; 106 bool old_value_valid = value_is_valid_;
80 107
81 value_is_valid_ = true; 108 value_is_valid_ = true;
82 if (value < 0.0) 109 if (value < 0.0)
83 value = 0.0; 110 value = 0.0;
84 else if (value > 1.0) 111 else if (value > 1.0)
85 value = 1.0; 112 value = 1.0;
86 if (value_ == value) 113 if (value_ == value)
87 return; 114 return;
88 float old_value = value_; 115 float old_value = value_;
89 value_ = value; 116 value_ = value;
90 if (listener_) 117 if (listener_)
91 listener_->SliderValueChanged(this, value_, old_value, reason); 118 listener_->SliderValueChanged(this, value_, old_value, reason);
92 119
93 if (old_value_valid && base::MessageLoop::current()) { 120 if (old_value_valid && base::MessageLoop::current()) {
94 // Do not animate when setting the value of the slider for the first time. 121 // 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. 122 // There is no message-loop when running tests. So we cannot animate then.
96 animating_value_ = old_value; 123 if (!move_animation_) {
97 move_animation_.reset(new gfx::SlideAnimation(this)); 124 initial_animating_value_ = old_value;
98 move_animation_->SetSlideDuration(kSlideValueChangeDurationMS); 125 move_animation_.reset(new gfx::SlideAnimation(this));
99 move_animation_->Show(); 126 move_animation_->SetSlideDuration(kSlideValueChangeDurationMs);
100 AnimationProgressed(move_animation_.get()); 127 move_animation_->Show();
128 }
101 } else { 129 } else {
102 SchedulePaint(); 130 SchedulePaint();
103 } 131 }
104 if (accessibility_events_enabled_ && GetWidget()) { 132 if (accessibility_events_enabled_ && GetWidget())
105 NotifyAccessibilityEvent( 133 NotifyAccessibilityEvent(ui::AX_EVENT_VALUE_CHANGED, true);
106 ui::AX_EVENT_VALUE_CHANGED, true);
107 }
108 } 134 }
109 135
110 void Slider::PrepareForMove(const int new_x) { 136 void Slider::PrepareForMove(const int new_x) {
111 // Try to remember the position of the mouse cursor on the button. 137 // Try to remember the position of the mouse cursor on the button.
112 gfx::Insets inset = GetInsets(); 138 gfx::Insets inset = GetInsets();
113 gfx::Rect content = GetContentsBounds(); 139 gfx::Rect content = GetContentsBounds();
114 float value = move_animation_.get() && move_animation_->is_animating() ? 140 float value = GetAnimatingValue();
115 animating_value_ : value_;
116 141
117 const int thumb_width = GetThumbWidth(); 142 const int thumb_width = GetThumbWidth();
118 const int thumb_x = value * (content.width() - thumb_width); 143 const int thumb_x = value * (content.width() - thumb_width);
119 const int candidate_x = (base::i18n::IsRTL() ? 144 const int candidate_x = (base::i18n::IsRTL() ?
120 width() - (new_x - inset.left()) : 145 width() - (new_x - inset.left()) :
121 new_x - inset.left()) - thumb_x; 146 new_x - inset.left()) - thumb_x;
122 if (candidate_x >= 0 && candidate_x < thumb_width) 147 if (candidate_x >= 0 && candidate_x < thumb_width)
123 initial_button_offset_ = candidate_x; 148 initial_button_offset_ = candidate_x;
124 else 149 else
125 initial_button_offset_ = thumb_width / 2; 150 initial_button_offset_ = thumb_width / 2;
126 } 151 }
127 152
128 void Slider::MoveButtonTo(const gfx::Point& point) { 153 void Slider::MoveButtonTo(const gfx::Point& point) {
129 const gfx::Insets inset = GetInsets(); 154 const gfx::Insets inset = GetInsets();
130 const int thumb_width = GetThumbWidth(); 155 const int thumb_width = GetThumbWidth();
131 // Calculate the value. 156 // Calculate the value.
132 int amount = base::i18n::IsRTL() 157 int amount = base::i18n::IsRTL()
133 ? width() - inset.left() - point.x() - initial_button_offset_ 158 ? width() - inset.left() - point.x() - initial_button_offset_
134 : point.x() - inset.left() - initial_button_offset_; 159 : point.x() - inset.left() - initial_button_offset_;
135 SetValueInternal( 160 SetValueInternal(
136 static_cast<float>(amount) / (width() - inset.width() - thumb_width), 161 static_cast<float>(amount) / (width() - inset.width() - thumb_width),
137 VALUE_CHANGED_BY_USER); 162 VALUE_CHANGED_BY_USER);
138 } 163 }
139 164
140 void Slider::SetAccessibleName(const base::string16& name) {
141 accessible_name_ = name;
142 }
143
144 void Slider::OnPaintFocus(gfx::Canvas* canvas) { 165 void Slider::OnPaintFocus(gfx::Canvas* canvas) {
145 if (!HasFocus()) 166 if (!HasFocus())
146 return; 167 return;
147 168
148 if (!focus_border_color_) { 169 if (!focus_border_color_) {
149 canvas->DrawFocusRect(GetLocalBounds()); 170 canvas->DrawFocusRect(GetLocalBounds());
150 } else if (HasFocus()) { 171 } else if (HasFocus()) {
151 canvas->DrawSolidFocusRect( 172 canvas->DrawSolidFocusRect(
152 gfx::Rect(1, 1, width() - 3, height() - 3), 173 gfx::Rect(1, 1, width() - 3, height() - 3),
153 focus_border_color_); 174 focus_border_color_);
154 } 175 }
155 } 176 }
156 177
178 void Slider::OnSliderDragStarted() {
179 SetHighlighted(true);
180 if (listener_)
181 listener_->SliderDragStarted(this);
182 }
183
184 void Slider::OnSliderDragEnded() {
185 SetHighlighted(false);
186 if (listener_)
187 listener_->SliderDragEnded(this);
188 }
189
157 const char* Slider::GetClassName() const { 190 const char* Slider::GetClassName() const {
158 return kViewClassName; 191 return kViewClassName;
159 } 192 }
160 193
161 gfx::Size Slider::GetPreferredSize() const { 194 gfx::Size Slider::GetPreferredSize() const {
162 const int kSizeMajor = 200; 195 const int kSizeMajor = 200;
163 const int kSizeMinor = 40; 196 const int kSizeMinor = 40;
164 197
165 return gfx::Size(std::max(width(), kSizeMajor), kSizeMinor); 198 return gfx::Size(std::max(width(), kSizeMajor), kSizeMinor);
166 } 199 }
167 200
168 void Slider::OnPaint(gfx::Canvas* canvas) {
169 View::OnPaint(canvas);
170 OnPaintFocus(canvas);
171 }
172
173 float Slider::GetAnimatingValue() const{
174 return move_animation_.get() && move_animation_->is_animating()
175 ? animating_value_
176 : value_;
177 }
178
179 bool Slider::OnMousePressed(const ui::MouseEvent& event) { 201 bool Slider::OnMousePressed(const ui::MouseEvent& event) {
180 if (!event.IsOnlyLeftMouseButton()) 202 if (!event.IsOnlyLeftMouseButton())
181 return false; 203 return false;
182 OnSliderDragStarted(); 204 OnSliderDragStarted();
183 PrepareForMove(event.location().x()); 205 PrepareForMove(event.location().x());
184 MoveButtonTo(event.location()); 206 MoveButtonTo(event.location());
185 return true; 207 return true;
186 } 208 }
187 209
188 bool Slider::OnMouseDragged(const ui::MouseEvent& event) { 210 bool Slider::OnMouseDragged(const ui::MouseEvent& event) {
(...skipping 10 matching lines...) Expand all
199 if (event.key_code() == ui::VKEY_LEFT) 221 if (event.key_code() == ui::VKEY_LEFT)
200 new_value -= keyboard_increment_; 222 new_value -= keyboard_increment_;
201 else if (event.key_code() == ui::VKEY_RIGHT) 223 else if (event.key_code() == ui::VKEY_RIGHT)
202 new_value += keyboard_increment_; 224 new_value += keyboard_increment_;
203 else 225 else
204 return false; 226 return false;
205 SetValueInternal(new_value, VALUE_CHANGED_BY_USER); 227 SetValueInternal(new_value, VALUE_CHANGED_BY_USER);
206 return true; 228 return true;
207 } 229 }
208 230
231 void Slider::GetAccessibleState(ui::AXViewState* state) {
232 state->role = ui::AX_ROLE_SLIDER;
233 state->name = accessible_name_;
234 state->value = base::UTF8ToUTF16(
235 base::StringPrintf("%d%%", static_cast<int>(value_ * 100 + 0.5)));
236 }
237
209 void Slider::OnFocus() { 238 void Slider::OnFocus() {
210 View::OnFocus(); 239 View::OnFocus();
211 SchedulePaint(); 240 SchedulePaint();
212 } 241 }
213 242
214 void Slider::OnBlur() { 243 void Slider::OnBlur() {
215 View::OnBlur(); 244 View::OnBlur();
216 SchedulePaint(); 245 SchedulePaint();
217 } 246 }
218 247
(...skipping 14 matching lines...) Expand all
233 MoveButtonTo(event->location()); 262 MoveButtonTo(event->location());
234 event->SetHandled(); 263 event->SetHandled();
235 if (event->details().touch_points() <= 1) 264 if (event->details().touch_points() <= 1)
236 OnSliderDragEnded(); 265 OnSliderDragEnded();
237 break; 266 break;
238 default: 267 default:
239 break; 268 break;
240 } 269 }
241 } 270 }
242 271
243 void Slider::AnimationProgressed(const gfx::Animation* animation) {
244 animating_value_ = animation->CurrentValueBetween(animating_value_, value_);
245 SchedulePaint();
246 }
247
248 void Slider::GetAccessibleState(ui::AXViewState* state) {
249 state->role = ui::AX_ROLE_SLIDER;
250 state->name = accessible_name_;
251 state->value = base::UTF8ToUTF16(
252 base::StringPrintf("%d%%", static_cast<int>(value_ * 100 + 0.5)));
253 }
254
255 void Slider::OnSliderDragStarted() {
256 if (listener_)
257 listener_->SliderDragStarted(this);
258 }
259
260 void Slider::OnSliderDragEnded() {
261 if (listener_)
262 listener_->SliderDragEnded(this);
263 }
264
265 } // namespace views 272 } // namespace views
OLDNEW
« ui/views/controls/md_slider.cc ('K') | « ui/views/controls/slider.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698