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

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

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

Powered by Google App Engine
This is Rietveld 408576698