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

Side by Side Diff: ash/system/audio/tray_volume.cc

Issue 14077010: Move ash tray audio UI code from ash/system/audio to ash/system/chromeos/audio. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Make audio code CHROMROS only in SystemTrayNotifier. Created 7 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 | Annotate | Revision Log
« no previous file with comments | « ash/system/audio/tray_volume.h ('k') | ash/system/chromeos/audio/audio_observer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ash/system/audio/tray_volume.h"
6
7 #include <cmath>
8
9 #include "ash/ash_constants.h"
10 #include "ash/shell.h"
11 #include "ash/system/tray/system_tray_delegate.h"
12 #include "ash/system/tray/system_tray_notifier.h"
13 #include "ash/system/tray/tray_bar_button_with_title.h"
14 #include "ash/system/tray/tray_constants.h"
15 #include "ash/volume_control_delegate.h"
16 #include "base/utf_string_conversions.h"
17 #include "grit/ash_resources.h"
18 #include "grit/ash_strings.h"
19 #include "third_party/skia/include/core/SkCanvas.h"
20 #include "third_party/skia/include/core/SkPaint.h"
21 #include "third_party/skia/include/core/SkRect.h"
22 #include "third_party/skia/include/effects/SkGradientShader.h"
23 #include "ui/base/resource/resource_bundle.h"
24 #include "ui/gfx/canvas.h"
25 #include "ui/gfx/image/image.h"
26 #include "ui/gfx/image/image_skia_operations.h"
27 #include "ui/views/controls/button/image_button.h"
28 #include "ui/views/controls/image_view.h"
29 #include "ui/views/controls/label.h"
30 #include "ui/views/controls/slider.h"
31 #include "ui/views/layout/box_layout.h"
32 #include "ui/views/view.h"
33
34 namespace ash {
35 namespace internal {
36
37 namespace {
38 const int kVolumeImageWidth = 25;
39 const int kVolumeImageHeight = 25;
40
41 // IDR_AURA_UBER_TRAY_VOLUME_LEVELS contains 5 images,
42 // The one for mute is at the 0 index and the other
43 // four are used for ascending volume levels.
44 const int kVolumeLevels = 4;
45
46 bool IsAudioMuted() {
47 return Shell::GetInstance()->system_tray_delegate()->
48 GetVolumeControlDelegate()->IsAudioMuted();
49 }
50
51 float GetVolumeLevel() {
52 return Shell::GetInstance()->system_tray_delegate()->
53 GetVolumeControlDelegate()->GetVolumeLevel();
54 }
55
56 } // namespace
57
58 namespace tray {
59
60 class VolumeButton : public views::ToggleImageButton {
61 public:
62 explicit VolumeButton(views::ButtonListener* listener)
63 : views::ToggleImageButton(listener),
64 image_index_(-1) {
65 SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
66 image_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
67 IDR_AURA_UBER_TRAY_VOLUME_LEVELS);
68 SetPreferredSize(gfx::Size(kTrayPopupItemHeight, kTrayPopupItemHeight));
69 Update();
70 }
71
72 virtual ~VolumeButton() {}
73
74 void Update() {
75 float level = GetVolumeLevel();
76 int image_index = IsAudioMuted() ?
77 0 : (level == 1.0 ?
78 kVolumeLevels :
79 std::max(1, int(std::ceil(level * (kVolumeLevels - 1)))));
80 if (image_index != image_index_) {
81 gfx::Rect region(0, image_index * kVolumeImageHeight,
82 kVolumeImageWidth, kVolumeImageHeight);
83 gfx::ImageSkia image_skia = gfx::ImageSkiaOperations::ExtractSubset(
84 *(image_.ToImageSkia()), region);
85 SetImage(views::CustomButton::STATE_NORMAL, &image_skia);
86 image_index_ = image_index;
87 }
88 SchedulePaint();
89 }
90
91 private:
92 // Overridden from views::View.
93 virtual gfx::Size GetPreferredSize() OVERRIDE {
94 gfx::Size size = views::ToggleImageButton::GetPreferredSize();
95 size.set_height(kTrayPopupItemHeight);
96 return size;
97 }
98
99 gfx::Image image_;
100 int image_index_;
101
102 DISALLOW_COPY_AND_ASSIGN(VolumeButton);
103 };
104
105 class MuteButton : public TrayBarButtonWithTitle {
106 public:
107 explicit MuteButton(views::ButtonListener* listener)
108 : TrayBarButtonWithTitle(listener,
109 -1, // no title under mute button
110 kTrayBarButtonWidth) {
111 Update();
112 }
113 virtual ~MuteButton() {}
114
115 void Update() {
116 UpdateButton(IsAudioMuted());
117 SchedulePaint();
118 }
119
120 private:
121 DISALLOW_COPY_AND_ASSIGN(MuteButton);
122 };
123
124 class VolumeSlider : public views::Slider {
125 public:
126 explicit VolumeSlider(views::SliderListener* listener)
127 : views::Slider(listener, views::Slider::HORIZONTAL) {
128 set_focus_border_color(kFocusBorderColor);
129 SetValue(GetVolumeLevel());
130 SetAccessibleName(
131 ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
132 IDS_ASH_STATUS_TRAY_VOLUME));
133 Update();
134 }
135 virtual ~VolumeSlider() {}
136
137 void Update() {
138 UpdateState(!IsAudioMuted());
139 }
140
141 DISALLOW_COPY_AND_ASSIGN(VolumeSlider);
142 };
143
144 class VolumeView : public views::View,
145 public views::ButtonListener,
146 public views::SliderListener {
147 public:
148 VolumeView() {
149 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
150 kTrayPopupPaddingHorizontal, 0, kTrayPopupPaddingBetweenItems));
151
152 icon_ = new VolumeButton(this);
153 AddChildView(icon_);
154
155 mute_ = new MuteButton(this);
156 AddChildView(mute_);
157
158 slider_ = new VolumeSlider(this);
159 AddChildView(slider_);
160 }
161
162 virtual ~VolumeView() {}
163
164 void Update() {
165 icon_->Update();
166 mute_->Update();
167 slider_->Update();
168 }
169
170 void SetVolumeLevel(float percent) {
171 // The change in volume will be reflected via accessibility system events,
172 // so we prevent the UI event from being sent here.
173 slider_->set_enable_accessibility_events(false);
174 slider_->SetValue(percent);
175 // It is possible that the volume was (un)muted, but the actual volume level
176 // did not change. In that case, setting the value of the slider won't
177 // trigger an update. So explicitly trigger an update.
178 Update();
179 slider_->set_enable_accessibility_events(true);
180 }
181
182 private:
183 // Overridden from views::View.
184 virtual void OnBoundsChanged(const gfx::Rect& old_bounds) OVERRIDE {
185 int w = width() - slider_->x();
186 slider_->SetSize(gfx::Size(w, slider_->height()));
187 }
188
189 // Overridden from views::ButtonListener.
190 virtual void ButtonPressed(views::Button* sender,
191 const ui::Event& event) OVERRIDE {
192 CHECK(sender == icon_ || sender == mute_);
193 ash::Shell::GetInstance()->system_tray_delegate()->
194 GetVolumeControlDelegate()->SetAudioMuted(!IsAudioMuted());
195 }
196
197 // Overridden from views:SliderListener.
198 virtual void SliderValueChanged(views::Slider* sender,
199 float value,
200 float old_value,
201 views::SliderChangeReason reason) OVERRIDE {
202 if (reason == views::VALUE_CHANGED_BY_USER) {
203 ash::Shell::GetInstance()->system_tray_delegate()->
204 GetVolumeControlDelegate()->SetVolumeLevel(value);
205 }
206 icon_->Update();
207 }
208
209 VolumeButton* icon_;
210 MuteButton* mute_;
211 VolumeSlider* slider_;
212
213 DISALLOW_COPY_AND_ASSIGN(VolumeView);
214 };
215
216 } // namespace tray
217
218 TrayVolume::TrayVolume(SystemTray* system_tray)
219 : TrayImageItem(system_tray, IDR_AURA_UBER_TRAY_VOLUME_MUTE),
220 volume_view_(NULL),
221 is_default_view_(false) {
222 Shell::GetInstance()->system_tray_notifier()->AddAudioObserver(this);
223 }
224
225 TrayVolume::~TrayVolume() {
226 Shell::GetInstance()->system_tray_notifier()->RemoveAudioObserver(this);
227 }
228
229 bool TrayVolume::GetInitialVisibility() {
230 return IsAudioMuted();
231 }
232
233 views::View* TrayVolume::CreateDefaultView(user::LoginStatus status) {
234 volume_view_ = new tray::VolumeView;
235 is_default_view_ = true;
236 return volume_view_;
237 }
238
239 views::View* TrayVolume::CreateDetailedView(user::LoginStatus status) {
240 volume_view_ = new tray::VolumeView;
241 is_default_view_ = false;
242 return volume_view_;
243 }
244
245 void TrayVolume::DestroyDefaultView() {
246 if (is_default_view_)
247 volume_view_ = NULL;
248 }
249
250 void TrayVolume::DestroyDetailedView() {
251 if (!is_default_view_)
252 volume_view_ = NULL;
253 }
254
255 bool TrayVolume::ShouldHideArrow() const {
256 return true;
257 }
258
259 bool TrayVolume::ShouldShowLauncher() const {
260 return false;
261 }
262
263 void TrayVolume::OnVolumeChanged(float percent) {
264 if (tray_view())
265 tray_view()->SetVisible(GetInitialVisibility());
266
267 if (volume_view_) {
268 if (IsAudioMuted())
269 percent = 0.0;
270 volume_view_->SetVolumeLevel(percent);
271 SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds);
272 return;
273 }
274 PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
275 }
276
277 void TrayVolume::OnMuteToggled() {
278 if (tray_view())
279 tray_view()->SetVisible(GetInitialVisibility());
280
281 if (volume_view_)
282 volume_view_->Update();
283 else
284 PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
285 }
286
287 } // namespace internal
288 } // namespace ash
OLDNEW
« no previous file with comments | « ash/system/audio/tray_volume.h ('k') | ash/system/chromeos/audio/audio_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698