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

Side by Side Diff: chrome/browser/ui/views/tabs/alert_indicator_button.cc

Issue 1827083004: UI: Rename MediaState to AlertState (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth-tab-indicator
Patch Set: Keep gypi ordered Created 4 years, 8 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/browser/ui/views/tabs/media_indicator_button.h" 5 #include "chrome/browser/ui/views/tabs/alert_indicator_button.h"
6 6
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "chrome/browser/ui/views/tabs/tab.h" 8 #include "chrome/browser/ui/views/tabs/tab.h"
9 #include "chrome/browser/ui/views/tabs/tab_controller.h" 9 #include "chrome/browser/ui/views/tabs/tab_controller.h"
10 #include "chrome/browser/ui/views/tabs/tab_renderer_data.h" 10 #include "chrome/browser/ui/views/tabs/tab_renderer_data.h"
11 #include "content/public/browser/user_metrics.h" 11 #include "content/public/browser/user_metrics.h"
12 #include "ui/gfx/animation/animation_delegate.h" 12 #include "ui/gfx/animation/animation_delegate.h"
13 #include "ui/gfx/canvas.h" 13 #include "ui/gfx/canvas.h"
14 #include "ui/gfx/image/image.h" 14 #include "ui/gfx/image/image.h"
15 15
16 using base::UserMetricsAction; 16 using base::UserMetricsAction;
17 17
18 namespace { 18 namespace {
19 19
20 // The minimum required click-to-select area of an inactive Tab before allowing 20 // The minimum required click-to-select area of an inactive Tab before allowing
21 // the click-to-mute functionality to be enabled. These values are in terms of 21 // the click-to-mute functionality to be enabled. These values are in terms of
22 // some percentage of the MediaIndicatorButton's width. See comments in 22 // some percentage of the AlertIndicatorButton's width. See comments in
23 // UpdateEnabledForMuteToggle(). 23 // UpdateEnabledForMuteToggle().
24 const int kMinMouseSelectableAreaPercent = 250; 24 const int kMinMouseSelectableAreaPercent = 250;
25 const int kMinGestureSelectableAreaPercent = 400; 25 const int kMinGestureSelectableAreaPercent = 400;
26 26
27 // Returns true if either Shift or Control are being held down. In this case, 27 // Returns true if either Shift or Control are being held down. In this case,
28 // mouse events are delegated to the Tab, to perform tab selection in the tab 28 // mouse events are delegated to the Tab, to perform tab selection in the tab
29 // strip instead. 29 // strip instead.
30 bool IsShiftOrControlDown(const ui::Event& event) { 30 bool IsShiftOrControlDown(const ui::Event& event) {
31 return (event.flags() & (ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)) != 0; 31 return (event.flags() & (ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN)) != 0;
32 } 32 }
33 33
34 } // namespace 34 } // namespace
35 35
36 const char MediaIndicatorButton::kViewClassName[] = "MediaIndicatorButton"; 36 const char AlertIndicatorButton::kViewClassName[] = "AlertIndicatorButton";
37 37
38 class MediaIndicatorButton::FadeAnimationDelegate 38 class AlertIndicatorButton::FadeAnimationDelegate
39 : public gfx::AnimationDelegate { 39 : public gfx::AnimationDelegate {
40 public: 40 public:
41 explicit FadeAnimationDelegate(MediaIndicatorButton* button) 41 explicit FadeAnimationDelegate(AlertIndicatorButton* button)
42 : button_(button) {} 42 : button_(button) {}
43 ~FadeAnimationDelegate() override {} 43 ~FadeAnimationDelegate() override {}
44 44
45 private: 45 private:
46 // gfx::AnimationDelegate 46 // gfx::AnimationDelegate
47 void AnimationProgressed(const gfx::Animation* animation) override { 47 void AnimationProgressed(const gfx::Animation* animation) override {
48 button_->SchedulePaint(); 48 button_->SchedulePaint();
49 } 49 }
50 50
51 void AnimationCanceled(const gfx::Animation* animation) override { 51 void AnimationCanceled(const gfx::Animation* animation) override {
52 AnimationEnded(animation); 52 AnimationEnded(animation);
53 } 53 }
54 54
55 void AnimationEnded(const gfx::Animation* animation) override { 55 void AnimationEnded(const gfx::Animation* animation) override {
56 button_->showing_media_state_ = button_->media_state_; 56 button_->showing_alert_state_ = button_->alert_state_;
57 button_->parent_tab_->MediaStateChanged(); 57 button_->parent_tab_->AlertStateChanged();
58 } 58 }
59 59
60 MediaIndicatorButton* const button_; 60 AlertIndicatorButton* const button_;
61 61
62 DISALLOW_COPY_AND_ASSIGN(FadeAnimationDelegate); 62 DISALLOW_COPY_AND_ASSIGN(FadeAnimationDelegate);
63 }; 63 };
64 64
65 MediaIndicatorButton::MediaIndicatorButton(Tab* parent_tab) 65 AlertIndicatorButton::AlertIndicatorButton(Tab* parent_tab)
66 : views::ImageButton(NULL), 66 : views::ImageButton(NULL),
67 parent_tab_(parent_tab), 67 parent_tab_(parent_tab),
68 media_state_(TAB_MEDIA_STATE_NONE), 68 alert_state_(TabAlertState::NONE),
69 showing_media_state_(TAB_MEDIA_STATE_NONE) { 69 showing_alert_state_(TabAlertState::NONE) {
70 DCHECK(parent_tab_); 70 DCHECK(parent_tab_);
71 SetEventTargeter( 71 SetEventTargeter(
72 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); 72 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this)));
73 } 73 }
74 74
75 MediaIndicatorButton::~MediaIndicatorButton() {} 75 AlertIndicatorButton::~AlertIndicatorButton() {}
76 76
77 void MediaIndicatorButton::TransitionToMediaState(TabMediaState next_state) { 77 void AlertIndicatorButton::TransitionToAlertState(TabAlertState next_state) {
78 if (next_state == media_state_) 78 if (next_state == alert_state_)
79 return; 79 return;
80 80
81 TabMediaState previous_media_showing_state = showing_media_state_; 81 TabAlertState previous_alert_showing_state = showing_alert_state_;
82 82
83 if (next_state != TAB_MEDIA_STATE_NONE) 83 if (next_state != TabAlertState::NONE)
84 ResetImages(next_state); 84 ResetImages(next_state);
85 85
86 if ((media_state_ == TAB_MEDIA_STATE_AUDIO_PLAYING && 86 if ((alert_state_ == TabAlertState::AUDIO_PLAYING &&
87 next_state == TAB_MEDIA_STATE_AUDIO_MUTING) || 87 next_state == TabAlertState::AUDIO_MUTING) ||
88 (media_state_ == TAB_MEDIA_STATE_AUDIO_MUTING && 88 (alert_state_ == TabAlertState::AUDIO_MUTING &&
89 next_state == TAB_MEDIA_STATE_AUDIO_PLAYING) || 89 next_state == TabAlertState::AUDIO_PLAYING) ||
90 (media_state_ == TAB_MEDIA_STATE_AUDIO_MUTING && 90 (alert_state_ == TabAlertState::AUDIO_MUTING &&
91 next_state == TAB_MEDIA_STATE_NONE)) { 91 next_state == TabAlertState::NONE)) {
92 // Instant user feedback: No fade animation. 92 // Instant user feedback: No fade animation.
93 showing_media_state_ = next_state; 93 showing_alert_state_ = next_state;
94 fade_animation_.reset(); 94 fade_animation_.reset();
95 } else { 95 } else {
96 if (next_state == TAB_MEDIA_STATE_NONE) 96 if (next_state == TabAlertState::NONE)
97 showing_media_state_ = media_state_; // Fading-out indicator. 97 showing_alert_state_ = alert_state_; // Fading-out indicator.
98 else 98 else
99 showing_media_state_ = next_state; // Fading-in to next indicator. 99 showing_alert_state_ = next_state; // Fading-in to next indicator.
100 fade_animation_ = chrome::CreateTabMediaIndicatorFadeAnimation(next_state); 100 fade_animation_ = chrome::CreateTabAlertIndicatorFadeAnimation(next_state);
101 if (!fade_animation_delegate_) 101 if (!fade_animation_delegate_)
102 fade_animation_delegate_.reset(new FadeAnimationDelegate(this)); 102 fade_animation_delegate_.reset(new FadeAnimationDelegate(this));
103 fade_animation_->set_delegate(fade_animation_delegate_.get()); 103 fade_animation_->set_delegate(fade_animation_delegate_.get());
104 fade_animation_->Start(); 104 fade_animation_->Start();
105 } 105 }
106 106
107 media_state_ = next_state; 107 alert_state_ = next_state;
108 108
109 if (previous_media_showing_state != showing_media_state_) 109 if (previous_alert_showing_state != showing_alert_state_)
110 parent_tab_->MediaStateChanged(); 110 parent_tab_->AlertStateChanged();
111 111
112 UpdateEnabledForMuteToggle(); 112 UpdateEnabledForMuteToggle();
113 113
114 // An indicator state change should be made visible immediately, instead of 114 // An indicator state change should be made visible immediately, instead of
115 // the user being surprised when their mouse leaves the button. 115 // the user being surprised when their mouse leaves the button.
116 if (state() == views::CustomButton::STATE_HOVERED) { 116 if (state() == views::CustomButton::STATE_HOVERED) {
117 SetState(enabled() ? views::CustomButton::STATE_NORMAL : 117 SetState(enabled() ? views::CustomButton::STATE_NORMAL
118 views::CustomButton::STATE_DISABLED); 118 : views::CustomButton::STATE_DISABLED);
119 } 119 }
120 120
121 // Note: The calls to SetImage(), SetEnabled(), and SetState() above will call 121 // Note: The calls to SetImage(), SetEnabled(), and SetState() above will call
122 // SchedulePaint() if necessary. 122 // SchedulePaint() if necessary.
123 } 123 }
124 124
125 void MediaIndicatorButton::UpdateEnabledForMuteToggle() { 125 void AlertIndicatorButton::UpdateEnabledForMuteToggle() {
126 bool enable = chrome::AreExperimentalMuteControlsEnabled() && 126 bool enable = chrome::AreExperimentalMuteControlsEnabled() &&
127 (media_state_ == TAB_MEDIA_STATE_AUDIO_PLAYING || 127 (alert_state_ == TabAlertState::AUDIO_PLAYING ||
128 media_state_ == TAB_MEDIA_STATE_AUDIO_MUTING); 128 alert_state_ == TabAlertState::AUDIO_MUTING);
129 129
130 // If the tab is not the currently-active tab, make sure it is wide enough 130 // If the tab is not the currently-active tab, make sure it is wide enough
131 // before enabling click-to-mute. This ensures that there is enough click 131 // before enabling click-to-mute. This ensures that there is enough click
132 // area for the user to activate a tab rather than unintentionally muting it. 132 // area for the user to activate a tab rather than unintentionally muting it.
133 // Note that IsTriggerableEvent() is also overridden to provide an even wider 133 // Note that IsTriggerableEvent() is also overridden to provide an even wider
134 // requirement for tap gestures. 134 // requirement for tap gestures.
135 if (enable && !GetTab()->IsActive()) { 135 if (enable && !GetTab()->IsActive()) {
136 const int required_width = width() * kMinMouseSelectableAreaPercent / 100; 136 const int required_width = width() * kMinMouseSelectableAreaPercent / 100;
137 enable = (GetTab()->GetWidthOfLargestSelectableRegion() >= required_width); 137 enable = (GetTab()->GetWidthOfLargestSelectableRegion() >= required_width);
138 } 138 }
139 139
140 SetEnabled(enable); 140 SetEnabled(enable);
141 } 141 }
142 142
143 void MediaIndicatorButton::OnParentTabButtonColorChanged() { 143 void AlertIndicatorButton::OnParentTabButtonColorChanged() {
144 if (media_state_ == TAB_MEDIA_STATE_AUDIO_PLAYING || 144 if (alert_state_ == TabAlertState::AUDIO_PLAYING ||
145 media_state_ == TAB_MEDIA_STATE_AUDIO_MUTING) 145 alert_state_ == TabAlertState::AUDIO_MUTING)
146 ResetImages(media_state_); 146 ResetImages(alert_state_);
147 } 147 }
148 148
149 const char* MediaIndicatorButton::GetClassName() const { 149 const char* AlertIndicatorButton::GetClassName() const {
150 return kViewClassName; 150 return kViewClassName;
151 } 151 }
152 152
153 views::View* MediaIndicatorButton::GetTooltipHandlerForPoint( 153 views::View* AlertIndicatorButton::GetTooltipHandlerForPoint(
154 const gfx::Point& point) { 154 const gfx::Point& point) {
155 return NULL; // Tab (the parent View) provides the tooltip. 155 return NULL; // Tab (the parent View) provides the tooltip.
156 } 156 }
157 157
158 bool MediaIndicatorButton::OnMousePressed(const ui::MouseEvent& event) { 158 bool AlertIndicatorButton::OnMousePressed(const ui::MouseEvent& event) {
159 // Do not handle this mouse event when anything but the left mouse button is 159 // Do not handle this mouse event when anything but the left mouse button is
160 // pressed or when any modifier keys are being held down. Instead, the Tab 160 // pressed or when any modifier keys are being held down. Instead, the Tab
161 // should react (e.g., middle-click for close, right-click for context menu). 161 // should react (e.g., middle-click for close, right-click for context menu).
162 if (!event.IsOnlyLeftMouseButton() || IsShiftOrControlDown(event)) { 162 if (!event.IsOnlyLeftMouseButton() || IsShiftOrControlDown(event)) {
163 if (state() != views::CustomButton::STATE_DISABLED) 163 if (state() != views::CustomButton::STATE_DISABLED)
164 SetState(views::CustomButton::STATE_NORMAL); // Turn off hover. 164 SetState(views::CustomButton::STATE_NORMAL); // Turn off hover.
165 return false; // Event to be handled by Tab. 165 return false; // Event to be handled by Tab.
166 } 166 }
167 return ImageButton::OnMousePressed(event); 167 return ImageButton::OnMousePressed(event);
168 } 168 }
169 169
170 bool MediaIndicatorButton::OnMouseDragged(const ui::MouseEvent& event) { 170 bool AlertIndicatorButton::OnMouseDragged(const ui::MouseEvent& event) {
171 const ButtonState previous_state = state(); 171 const ButtonState previous_state = state();
172 const bool ret = ImageButton::OnMouseDragged(event); 172 const bool ret = ImageButton::OnMouseDragged(event);
173 if (previous_state != views::CustomButton::STATE_NORMAL && 173 if (previous_state != views::CustomButton::STATE_NORMAL &&
174 state() == views::CustomButton::STATE_NORMAL) 174 state() == views::CustomButton::STATE_NORMAL)
175 content::RecordAction(UserMetricsAction("MediaIndicatorButton_Dragged")); 175 content::RecordAction(UserMetricsAction("AlertIndicatorButton_Dragged"));
176 return ret; 176 return ret;
177 } 177 }
178 178
179 void MediaIndicatorButton::OnMouseEntered(const ui::MouseEvent& event) { 179 void AlertIndicatorButton::OnMouseEntered(const ui::MouseEvent& event) {
180 // If any modifier keys are being held down, do not turn on hover. 180 // If any modifier keys are being held down, do not turn on hover.
181 if (state() != views::CustomButton::STATE_DISABLED && 181 if (state() != views::CustomButton::STATE_DISABLED &&
182 IsShiftOrControlDown(event)) { 182 IsShiftOrControlDown(event)) {
183 SetState(views::CustomButton::STATE_NORMAL); 183 SetState(views::CustomButton::STATE_NORMAL);
184 return; 184 return;
185 } 185 }
186 ImageButton::OnMouseEntered(event); 186 ImageButton::OnMouseEntered(event);
187 } 187 }
188 188
189 void MediaIndicatorButton::OnMouseMoved(const ui::MouseEvent& event) { 189 void AlertIndicatorButton::OnMouseMoved(const ui::MouseEvent& event) {
190 // If any modifier keys are being held down, turn off hover. 190 // If any modifier keys are being held down, turn off hover.
191 if (state() != views::CustomButton::STATE_DISABLED && 191 if (state() != views::CustomButton::STATE_DISABLED &&
192 IsShiftOrControlDown(event)) { 192 IsShiftOrControlDown(event)) {
193 SetState(views::CustomButton::STATE_NORMAL); 193 SetState(views::CustomButton::STATE_NORMAL);
194 return; 194 return;
195 } 195 }
196 ImageButton::OnMouseMoved(event); 196 ImageButton::OnMouseMoved(event);
197 } 197 }
198 198
199 void MediaIndicatorButton::OnBoundsChanged(const gfx::Rect& previous_bounds) { 199 void AlertIndicatorButton::OnBoundsChanged(const gfx::Rect& previous_bounds) {
200 UpdateEnabledForMuteToggle(); 200 UpdateEnabledForMuteToggle();
201 } 201 }
202 202
203 void MediaIndicatorButton::OnPaint(gfx::Canvas* canvas) { 203 void AlertIndicatorButton::OnPaint(gfx::Canvas* canvas) {
204 double opaqueness = 204 double opaqueness =
205 fade_animation_ ? fade_animation_->GetCurrentValue() : 1.0; 205 fade_animation_ ? fade_animation_->GetCurrentValue() : 1.0;
206 if (media_state_ == TAB_MEDIA_STATE_NONE) 206 if (alert_state_ == TabAlertState::NONE)
207 opaqueness = 1.0 - opaqueness; // Fading out, not in. 207 opaqueness = 1.0 - opaqueness; // Fading out, not in.
208 if (opaqueness < 1.0) 208 if (opaqueness < 1.0)
209 canvas->SaveLayerAlpha(opaqueness * SK_AlphaOPAQUE); 209 canvas->SaveLayerAlpha(opaqueness * SK_AlphaOPAQUE);
210 ImageButton::OnPaint(canvas); 210 ImageButton::OnPaint(canvas);
211 if (opaqueness < 1.0) 211 if (opaqueness < 1.0)
212 canvas->Restore(); 212 canvas->Restore();
213 } 213 }
214 214
215 bool MediaIndicatorButton::DoesIntersectRect(const views::View* target, 215 bool AlertIndicatorButton::DoesIntersectRect(const views::View* target,
216 const gfx::Rect& rect) const { 216 const gfx::Rect& rect) const {
217 // If this button is not enabled, Tab (the parent View) handles all mouse 217 // If this button is not enabled, Tab (the parent View) handles all mouse
218 // events. 218 // events.
219 return enabled() && 219 return enabled() &&
220 views::ViewTargeterDelegate::DoesIntersectRect(target, rect); 220 views::ViewTargeterDelegate::DoesIntersectRect(target, rect);
221 } 221 }
222 222
223 void MediaIndicatorButton::NotifyClick(const ui::Event& event) { 223 void AlertIndicatorButton::NotifyClick(const ui::Event& event) {
224 if (media_state_ == TAB_MEDIA_STATE_AUDIO_PLAYING) 224 if (alert_state_ == TabAlertState::AUDIO_PLAYING)
225 content::RecordAction(UserMetricsAction("MediaIndicatorButton_Mute")); 225 content::RecordAction(UserMetricsAction("AlertIndicatorButton_Mute"));
226 else if (media_state_ == TAB_MEDIA_STATE_AUDIO_MUTING) 226 else if (alert_state_ == TabAlertState::AUDIO_MUTING)
227 content::RecordAction(UserMetricsAction("MediaIndicatorButton_Unmute")); 227 content::RecordAction(UserMetricsAction("AlertIndicatorButton_Unmute"));
228 else 228 else
229 NOTREACHED(); 229 NOTREACHED();
230 230
231 GetTab()->controller()->ToggleTabAudioMute(GetTab()); 231 GetTab()->controller()->ToggleTabAudioMute(GetTab());
232 } 232 }
233 233
234 bool MediaIndicatorButton::IsTriggerableEvent(const ui::Event& event) { 234 bool AlertIndicatorButton::IsTriggerableEvent(const ui::Event& event) {
235 // For mouse events, only trigger on the left mouse button and when no 235 // For mouse events, only trigger on the left mouse button and when no
236 // modifier keys are being held down. 236 // modifier keys are being held down.
237 if (event.IsMouseEvent() && 237 if (event.IsMouseEvent() &&
238 (!static_cast<const ui::MouseEvent*>(&event)->IsOnlyLeftMouseButton() || 238 (!static_cast<const ui::MouseEvent*>(&event)->IsOnlyLeftMouseButton() ||
239 IsShiftOrControlDown(event))) 239 IsShiftOrControlDown(event)))
240 return false; 240 return false;
241 241
242 // For gesture events on an inactive tab, require an even wider tab before 242 // For gesture events on an inactive tab, require an even wider tab before
243 // click-to-mute can be triggered. See comments in 243 // click-to-mute can be triggered. See comments in
244 // UpdateEnabledForMuteToggle(). 244 // UpdateEnabledForMuteToggle().
245 if (event.IsGestureEvent() && !GetTab()->IsActive()) { 245 if (event.IsGestureEvent() && !GetTab()->IsActive()) {
246 const int required_width = width() * kMinGestureSelectableAreaPercent / 100; 246 const int required_width = width() * kMinGestureSelectableAreaPercent / 100;
247 if (GetTab()->GetWidthOfLargestSelectableRegion() < required_width) 247 if (GetTab()->GetWidthOfLargestSelectableRegion() < required_width)
248 return false; 248 return false;
249 } 249 }
250 250
251 return views::ImageButton::IsTriggerableEvent(event); 251 return views::ImageButton::IsTriggerableEvent(event);
252 } 252 }
253 253
254 Tab* MediaIndicatorButton::GetTab() const { 254 Tab* AlertIndicatorButton::GetTab() const {
255 DCHECK_EQ(static_cast<views::View*>(parent_tab_), parent()); 255 DCHECK_EQ(static_cast<views::View*>(parent_tab_), parent());
256 return parent_tab_; 256 return parent_tab_;
257 } 257 }
258 258
259 void MediaIndicatorButton::ResetImages(TabMediaState state) { 259 void AlertIndicatorButton::ResetImages(TabAlertState state) {
260 SkColor color = parent_tab_->button_color(); 260 SkColor color = parent_tab_->button_color();
261 gfx::ImageSkia indicator_image = 261 gfx::ImageSkia indicator_image =
262 chrome::GetTabMediaIndicatorImage(state, color).AsImageSkia(); 262 chrome::GetTabAlertIndicatorImage(state, color).AsImageSkia();
263 SetImage(views::CustomButton::STATE_NORMAL, &indicator_image); 263 SetImage(views::CustomButton::STATE_NORMAL, &indicator_image);
264 SetImage(views::CustomButton::STATE_DISABLED, &indicator_image); 264 SetImage(views::CustomButton::STATE_DISABLED, &indicator_image);
265 gfx::ImageSkia affordance_image = 265 gfx::ImageSkia affordance_image =
266 chrome::GetTabMediaIndicatorAffordanceImage(state, color).AsImageSkia(); 266 chrome::GetTabAlertIndicatorAffordanceImage(state, color).AsImageSkia();
267 SetImage(views::CustomButton::STATE_HOVERED, &affordance_image); 267 SetImage(views::CustomButton::STATE_HOVERED, &affordance_image);
268 SetImage(views::CustomButton::STATE_PRESSED, &affordance_image); 268 SetImage(views::CustomButton::STATE_PRESSED, &affordance_image);
269 } 269 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/tabs/alert_indicator_button.h ('k') | chrome/browser/ui/views/tabs/alert_indicator_button_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698