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

Side by Side Diff: ui/views/controls/button/toggle_button.cc

Issue 2396133005: [ash-md] Animates ToggleButton highlight to move it in sync with the thumb (Closed)
Patch Set: [ash-md] Animates ToggleButton highlight to move it in sync with the thumb (thumb in its own layer) 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/button/toggle_button.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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/button/toggle_button.h" 5 #include "ui/views/controls/button/toggle_button.h"
6 6
7 #include "third_party/skia/include/core/SkDrawLooper.h" 7 #include "third_party/skia/include/core/SkDrawLooper.h"
8 #include "third_party/skia/include/core/SkPaint.h" 8 #include "third_party/skia/include/core/SkPaint.h"
9 #include "ui/gfx/canvas.h" 9 #include "ui/gfx/canvas.h"
10 #include "ui/gfx/color_palette.h" 10 #include "ui/gfx/color_palette.h"
(...skipping 14 matching lines...) Expand all
25 // Margin from edge of thumb to closest edge of view. Note that the thumb 25 // Margin from edge of thumb to closest edge of view. Note that the thumb
26 // margins must be sufficiently large to allow space for the shadow. 26 // margins must be sufficiently large to allow space for the shadow.
27 const int kThumbHorizontalMargin = 4; 27 const int kThumbHorizontalMargin = 4;
28 // Margin from top/bottom edge of thumb to top/bottom edge of view. 28 // Margin from top/bottom edge of thumb to top/bottom edge of view.
29 const int kThumbVerticalMargin = 3; 29 const int kThumbVerticalMargin = 3;
30 30
31 // TODO(estade): get the base color (black) from the theme? 31 // TODO(estade): get the base color (black) from the theme?
32 const SkColor kTrackOffColor = 32 const SkColor kTrackOffColor =
33 SkColorSetA(SK_ColorBLACK, gfx::kDisabledControlAlpha); 33 SkColorSetA(SK_ColorBLACK, gfx::kDisabledControlAlpha);
34 34
35 // Paints the circular thumb at |bounds| on |canvas|. The thumb color is set
36 // between white and |thumb_on_color| mixed with |ratio|. This utility function
37 // is used both whether the thumb is animating or not.
38 void PaintThumb(gfx::Canvas* canvas, gfx::Rect bounds, double value,
39 SkColor thumb_on_color) {
40 std::vector<gfx::ShadowValue> shadows;
41 shadows.emplace_back(gfx::Vector2d(0, 1), 4.f,
42 SkColorSetA(SK_ColorBLACK, 0x99));
43 SkPaint thumb_paint;
44 thumb_paint.setLooper(gfx::CreateShadowDrawLooperCorrectBlur(shadows));
45 thumb_paint.setStyle(SkPaint::kFill_Style);
46 thumb_paint.setAntiAlias(true);
47 // TODO(estade): get this color from the theme?
48 const SkColor thumb_off_color = SK_ColorWHITE;
49 const SkAlpha blend = static_cast<SkAlpha>(SK_AlphaOPAQUE * value);
50 thumb_paint.setColor(
51 color_utils::AlphaBlend(thumb_on_color, thumb_off_color, blend));
52 canvas->DrawCircle(gfx::RectF(bounds).CenterPoint(),
53 bounds.height() / 2.f, thumb_paint);
54 }
55
35 } // namespace 56 } // namespace
36 57
58 // Class representing the thumb when ink drop animation is active. In static
59 // case the thumb is painted by the ToggleButton. When the thumb is clicked it
60 // is separated into its own layer and the ink drop layer is made a child of
61 // the thumb layer allowing the two to animate in sync.
62 class ToggleButton::ThumbView : public views::View {
63 public:
64 ThumbView(ui::Layer* ink_drop_layer, double value) : value_(value) {
65 SetPaintToLayer(true);
66 layer()->SetFillsBoundsOpaquely(false);
67 layer()->Add(ink_drop_layer);
68 }
69 ~ThumbView() override {}
70
71 void Update(const gfx::Rect& bounds, double value) {
72 SetBoundsRect(bounds);
73 value_ = value;
74 SchedulePaint();
75 }
76
77 private:
78 // views::View:
79 void OnPaint(gfx::Canvas* canvas) override {
80 gfx::Rect thumb_bounds = GetLocalBounds();
81 thumb_bounds.Inset(gfx::Insets(kThumbVerticalMargin));
82 const SkColor thumb_on_color = GetNativeTheme()->GetSystemColor(
83 ui::NativeTheme::kColorId_ProminentButtonColor);
84 PaintThumb(canvas, thumb_bounds, value_, thumb_on_color);
85 }
86
87 // Value between 0 and 1 that controls the thumb color.
88 double value_;
89
90 DISALLOW_COPY_AND_ASSIGN(ThumbView);
91 };
92
37 ToggleButton::ToggleButton(ButtonListener* listener) 93 ToggleButton::ToggleButton(ButtonListener* listener)
38 : CustomButton(listener), is_on_(false), slide_animation_(this) { 94 : CustomButton(listener), is_on_(false), slide_animation_(this) {
39 slide_animation_.SetSlideDuration(80 /* ms */); 95 slide_animation_.SetSlideDuration(80 /* ms */);
40 slide_animation_.SetTweenType(gfx::Tween::LINEAR); 96 slide_animation_.SetTweenType(gfx::Tween::LINEAR);
41 SetBorder(Border::CreateEmptyBorder( 97 SetBorder(Border::CreateEmptyBorder(
42 gfx::Insets(kTrackVerticalMargin, kTrackHorizontalMargin))); 98 gfx::Insets(kTrackVerticalMargin, kTrackHorizontalMargin)));
43 SetInkDropMode(InkDropMode::ON); 99 SetInkDropMode(InkDropMode::ON);
44 set_has_ink_drop_action_on_click(true); 100 set_has_ink_drop_action_on_click(true);
45 } 101 }
46 102
(...skipping 13 matching lines...) Expand all
60 } 116 }
61 117
62 gfx::Size ToggleButton::GetPreferredSize() const { 118 gfx::Size ToggleButton::GetPreferredSize() const {
63 gfx::Rect rect(0, 0, kTrackWidth, kTrackHeight); 119 gfx::Rect rect(0, 0, kTrackWidth, kTrackHeight);
64 if (border()) 120 if (border())
65 rect.Inset(-border()->GetInsets()); 121 rect.Inset(-border()->GetInsets());
66 return rect.size(); 122 return rect.size();
67 } 123 }
68 124
69 void ToggleButton::OnPaint(gfx::Canvas* canvas) { 125 void ToggleButton::OnPaint(gfx::Canvas* canvas) {
70 SkAlpha blend = 126 const double value = slide_animation_.GetCurrentValue();
71 static_cast<SkAlpha>(SK_AlphaOPAQUE * slide_animation_.GetCurrentValue()); 127 SkAlpha blend = static_cast<SkAlpha>(SK_AlphaOPAQUE * value);
72 128
73 // Track. 129 // Track.
74 gfx::RectF track_rect(GetContentsBounds()); 130 gfx::RectF track_rect(GetContentsBounds());
75 SkPaint track_paint; 131 SkPaint track_paint;
76 track_paint.setAntiAlias(true); 132 track_paint.setAntiAlias(true);
77 const SkColor track_on_color = 133 const SkColor track_on_color =
78 SkColorSetA(GetNativeTheme()->GetSystemColor( 134 SkColorSetA(GetNativeTheme()->GetSystemColor(
79 ui::NativeTheme::kColorId_ProminentButtonColor), 135 ui::NativeTheme::kColorId_ProminentButtonColor),
80 0xFF / 2); 136 0xFF / 2);
81 track_paint.setColor( 137 track_paint.setColor(
82 color_utils::AlphaBlend(track_on_color, kTrackOffColor, blend)); 138 color_utils::AlphaBlend(track_on_color, kTrackOffColor, blend));
83 canvas->DrawRoundRect(track_rect, track_rect.height() / 2, track_paint); 139 canvas->DrawRoundRect(track_rect, track_rect.height() / 2, track_paint);
84 140
85 // Thumb. 141 if (thumb_view_)
142 return;
143
144 // Paint thumb when not animating.
86 gfx::Rect thumb_bounds = GetThumbBounds(); 145 gfx::Rect thumb_bounds = GetThumbBounds();
87 SkPaint thumb_paint;
88 std::vector<gfx::ShadowValue> shadows;
89 shadows.emplace_back(gfx::Vector2d(0, 1), 4.f,
90 SkColorSetA(SK_ColorBLACK, 0x99));
91 thumb_paint.setLooper(gfx::CreateShadowDrawLooperCorrectBlur(shadows));
92 thumb_paint.setStyle(SkPaint::kFill_Style);
93 thumb_paint.setAntiAlias(true);
94 const SkColor thumb_on_color = GetNativeTheme()->GetSystemColor( 146 const SkColor thumb_on_color = GetNativeTheme()->GetSystemColor(
95 ui::NativeTheme::kColorId_ProminentButtonColor); 147 ui::NativeTheme::kColorId_ProminentButtonColor);
96 // TODO(estade): get this color from the theme? 148 PaintThumb(canvas, thumb_bounds, value, thumb_on_color);
97 const SkColor thumb_off_color = SK_ColorWHITE;
98 thumb_paint.setColor(
99 color_utils::AlphaBlend(thumb_on_color, thumb_off_color, blend));
100 canvas->DrawCircle(gfx::RectF(thumb_bounds).CenterPoint(),
101 thumb_bounds.height() / 2.f, thumb_paint);
102 } 149 }
103 150
104 void ToggleButton::NotifyClick(const ui::Event& event) { 151 void ToggleButton::NotifyClick(const ui::Event& event) {
105 SetIsOn(!is_on(), true); 152 SetIsOn(!is_on(), true);
106 CustomButton::NotifyClick(event); 153 CustomButton::NotifyClick(event);
107 } 154 }
108 155
109 void ToggleButton::OnNativeThemeChanged(const ui::NativeTheme* theme) { 156 void ToggleButton::OnNativeThemeChanged(const ui::NativeTheme* theme) {
110 SchedulePaint(); 157 SchedulePaint();
111 } 158 }
112 159
160 void ToggleButton::AddInkDropLayer(ui::Layer* ink_drop_layer) {
161 CustomButton::AddInkDropLayer(ink_drop_layer);
162 thumb_view_.reset(
163 new ToggleButton::ThumbView(ink_drop_layer,
Evan Stade 2016/10/12 00:46:55 I was kind of expecting the thumb to just always b
varkha 2016/10/12 01:52:41 Done.
164 slide_animation_.GetCurrentValue()));
165 AddChildView(thumb_view_.get());
166 gfx::Rect thumb_bounds = GetThumbBounds();
167 thumb_bounds.Inset(gfx::Insets(-kThumbVerticalMargin));
168 thumb_view_->SetBoundsRect(thumb_bounds);
169 }
170
171 void ToggleButton::RemoveInkDropLayer(ui::Layer* ink_drop_layer) {
172 thumb_view_->layer()->Remove(ink_drop_layer);
173 thumb_view_.reset();
174 SchedulePaint();
175 }
176
113 std::unique_ptr<InkDropRipple> ToggleButton::CreateInkDropRipple() const { 177 std::unique_ptr<InkDropRipple> ToggleButton::CreateInkDropRipple() const {
114 return CreateDefaultInkDropRipple(GetThumbBounds().CenterPoint()); 178 const int radius = (kTrackHeight + kTrackVerticalMargin * 2) / 2;
179 return CreateDefaultInkDropRipple(gfx::Point(radius, radius));
115 } 180 }
116 181
117 SkColor ToggleButton::GetInkDropBaseColor() const { 182 SkColor ToggleButton::GetInkDropBaseColor() const {
118 return is_on() 183 return is_on()
119 ? GetNativeTheme()->GetSystemColor( 184 ? GetNativeTheme()->GetSystemColor(
120 ui::NativeTheme::kColorId_ProminentButtonColor) 185 ui::NativeTheme::kColorId_ProminentButtonColor)
121 : kTrackOffColor; 186 : kTrackOffColor;
122 } 187 }
123 188
124 bool ToggleButton::ShouldShowInkDropHighlight() const { 189 bool ToggleButton::ShouldShowInkDropHighlight() const {
125 return false; 190 return false;
126 } 191 }
127 192
128 void ToggleButton::AnimationProgressed(const gfx::Animation* animation) { 193 void ToggleButton::AnimationProgressed(const gfx::Animation* animation) {
129 if (animation == &slide_animation_) 194 if (animation == &slide_animation_) {
195 if (thumb_view_) {
196 gfx::Rect thumb_bounds = GetThumbBounds();
197 thumb_bounds.Inset(gfx::Insets(-kThumbVerticalMargin));
198 thumb_view_->Update(thumb_bounds, slide_animation_.GetCurrentValue());
199 }
130 SchedulePaint(); 200 SchedulePaint();
131 else 201 } else {
132 CustomButton::AnimationProgressed(animation); 202 CustomButton::AnimationProgressed(animation);
203 }
133 } 204 }
134 205
135 gfx::Rect ToggleButton::GetThumbBounds() const { 206 gfx::Rect ToggleButton::GetThumbBounds() const {
136 gfx::Rect thumb_bounds = GetLocalBounds(); 207 gfx::Rect thumb_bounds = GetLocalBounds();
137 thumb_bounds.Inset(gfx::Insets(kThumbVerticalMargin, kThumbHorizontalMargin)); 208 thumb_bounds.Inset(gfx::Insets(kThumbVerticalMargin, kThumbHorizontalMargin));
138 thumb_bounds.set_x(thumb_bounds.x() + 209 thumb_bounds.set_x(thumb_bounds.x() +
139 slide_animation_.GetCurrentValue() * 210 slide_animation_.GetCurrentValue() *
140 (thumb_bounds.width() - thumb_bounds.height())); 211 (thumb_bounds.width() - thumb_bounds.height()));
141 // The thumb is a circle, so the width should match the height. 212 // The thumb is a circle, so the width should match the height.
142 thumb_bounds.set_width(thumb_bounds.height()); 213 thumb_bounds.set_width(thumb_bounds.height());
143 thumb_bounds.set_x(GetMirroredXForRect(thumb_bounds)); 214 thumb_bounds.set_x(GetMirroredXForRect(thumb_bounds));
144 return thumb_bounds; 215 return thumb_bounds;
145 } 216 }
146 217
147 } // namespace views 218 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/button/toggle_button.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698