OLD | NEW |
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 "ash/system/audio/tray_volume.h" | 5 #include "ash/system/audio/tray_volume.h" |
6 | 6 |
7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
8 #include "ash/system/tray/system_tray_delegate.h" | 8 #include "ash/system/tray/system_tray_delegate.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "grit/ui_resources.h" | 10 #include "grit/ui_resources.h" |
| 11 #include "third_party/skia/include/core/SkCanvas.h" |
| 12 #include "third_party/skia/include/core/SkPaint.h" |
| 13 #include "third_party/skia/include/core/SkRect.h" |
| 14 #include "third_party/skia/include/effects/SkGradientShader.h" |
11 #include "ui/base/resource/resource_bundle.h" | 15 #include "ui/base/resource/resource_bundle.h" |
| 16 #include "ui/gfx/canvas.h" |
12 #include "ui/gfx/image/image.h" | 17 #include "ui/gfx/image/image.h" |
13 #include "ui/views/controls/button/image_button.h" | 18 #include "ui/views/controls/button/image_button.h" |
14 #include "ui/views/controls/image_view.h" | 19 #include "ui/views/controls/image_view.h" |
15 #include "ui/views/controls/label.h" | 20 #include "ui/views/controls/label.h" |
16 #include "ui/views/controls/slider.h" | 21 #include "ui/views/controls/slider.h" |
17 #include "ui/views/layout/box_layout.h" | 22 #include "ui/views/layout/box_layout.h" |
18 #include "ui/views/view.h" | 23 #include "ui/views/view.h" |
19 | 24 |
| 25 namespace ash { |
| 26 namespace internal { |
| 27 |
| 28 namespace { |
| 29 const int kVolumeImageWidth = 44; |
| 30 const int kVolumeImageHeight = 44; |
| 31 const int kVolumeLevel = 5; |
| 32 } |
| 33 |
20 namespace tray { | 34 namespace tray { |
21 | 35 |
| 36 class VolumeButton : public views::ToggleImageButton { |
| 37 public: |
| 38 explicit VolumeButton(views::ButtonListener* listener) |
| 39 : views::ToggleImageButton(listener), |
| 40 image_index_(-1) { |
| 41 image_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
| 42 IDR_AURA_UBER_TRAY_VOLUME_LEVELS); |
| 43 Update(); |
| 44 } |
| 45 |
| 46 virtual ~VolumeButton() {} |
| 47 |
| 48 void Update() { |
| 49 ash::SystemTrayDelegate* delegate = |
| 50 ash::Shell::GetInstance()->tray_delegate(); |
| 51 int level = static_cast<int>(delegate->GetVolumeLevel() * 100); |
| 52 int image_index = level / (100 / kVolumeLevel); |
| 53 if (level > 0 && image_index == 0) |
| 54 ++image_index; |
| 55 if (level == 100) |
| 56 image_index = kVolumeLevel - 1; |
| 57 else if (image_index == kVolumeLevel - 1) |
| 58 --image_index; |
| 59 if (image_index != image_index_) { |
| 60 SkIRect region = SkIRect::MakeXYWH(0, image_index * kVolumeImageHeight, |
| 61 kVolumeImageWidth, kVolumeImageHeight); |
| 62 SkBitmap bitmap; |
| 63 image_.ToSkBitmap()->extractSubset(&bitmap, region); |
| 64 SetImage(views::CustomButton::BS_NORMAL, &bitmap); |
| 65 image_index_ = image_index; |
| 66 } |
| 67 SchedulePaint(); |
| 68 } |
| 69 |
| 70 private: |
| 71 // Overridden from views::View. |
| 72 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE { |
| 73 views::ToggleImageButton::OnPaint(canvas); |
| 74 |
| 75 ash::SystemTrayDelegate* delegate = |
| 76 ash::Shell::GetInstance()->tray_delegate(); |
| 77 if (!delegate->IsAudioMuted()) |
| 78 return; |
| 79 |
| 80 SkPaint paint; |
| 81 paint.setColor(SkColorSetARGB(63, 0, 0, 0)); |
| 82 paint.setStrokeWidth(SkIntToScalar(3)); |
| 83 canvas->GetSkCanvas()->drawLine(SkIntToScalar(width() - 10), |
| 84 SkIntToScalar(10), SkIntToScalar(10), SkIntToScalar(height() - 10), |
| 85 paint); |
| 86 } |
| 87 |
| 88 gfx::Image image_; |
| 89 int image_index_; |
| 90 |
| 91 DISALLOW_COPY_AND_ASSIGN(VolumeButton); |
| 92 }; |
| 93 |
22 class VolumeView : public views::View, | 94 class VolumeView : public views::View, |
23 public views::ButtonListener, | 95 public views::ButtonListener, |
24 public views::SliderListener { | 96 public views::SliderListener { |
25 public: | 97 public: |
26 VolumeView() { | 98 VolumeView() { |
27 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, | 99 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, |
28 0, 0, 5)); | 100 0, 0, 5)); |
29 | 101 |
30 gfx::Image image = ui::ResourceBundle::GetSharedInstance().GetImageNamed( | 102 icon_ = new VolumeButton(this); |
31 IDR_AURA_UBER_TRAY_VOLUME); | 103 AddChildView(icon_); |
32 icon_ = new views::ToggleImageButton(this); | |
33 icon_->SetImage(views::CustomButton::BS_NORMAL, image.ToSkBitmap()); | |
34 icon_->SetImage(views::CustomButton::BS_HOT, image.ToSkBitmap()); | |
35 icon_->SetImage(views::CustomButton::BS_PUSHED, image.ToSkBitmap()); | |
36 | |
37 image = ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
38 IDR_AURA_UBER_TRAY_VOLUME_MUTE); | |
39 icon_->SetToggledImage(views::CustomButton::BS_NORMAL, image.ToSkBitmap()); | |
40 icon_->SetToggledImage(views::CustomButton::BS_HOT, image.ToSkBitmap()); | |
41 icon_->SetToggledImage(views::CustomButton::BS_PUSHED, image.ToSkBitmap()); | |
42 | 104 |
43 ash::SystemTrayDelegate* delegate = | 105 ash::SystemTrayDelegate* delegate = |
44 ash::Shell::GetInstance()->tray_delegate(); | 106 ash::Shell::GetInstance()->tray_delegate(); |
45 icon_->SetToggled(delegate->IsAudioMuted()); | |
46 AddChildView(icon_); | |
47 | |
48 slider_ = new views::Slider(this, views::Slider::HORIZONTAL); | 107 slider_ = new views::Slider(this, views::Slider::HORIZONTAL); |
49 slider_->SetValue(delegate->GetVolumeLevel()); | 108 slider_->SetValue(delegate->GetVolumeLevel()); |
50 slider_->set_border(views::Border::CreateEmptyBorder(0, 0, 0, 20)); | 109 slider_->set_border(views::Border::CreateEmptyBorder(0, 0, 0, 20)); |
51 AddChildView(slider_); | 110 AddChildView(slider_); |
52 } | 111 } |
53 | 112 |
54 void SetVolumeLevel(float percent) { | 113 void SetVolumeLevel(float percent) { |
55 slider_->SetValue(percent); | 114 slider_->SetValue(percent); |
56 } | 115 } |
57 | 116 |
58 private: | 117 private: |
59 | |
60 // Overridden from views::ButtonListener. | 118 // Overridden from views::ButtonListener. |
61 virtual void ButtonPressed(views::Button* sender, | 119 virtual void ButtonPressed(views::Button* sender, |
62 const views::Event& event) OVERRIDE { | 120 const views::Event& event) OVERRIDE { |
63 CHECK(sender == icon_); | 121 CHECK(sender == icon_); |
64 ash::SystemTrayDelegate* delegate = | 122 ash::SystemTrayDelegate* delegate = |
65 ash::Shell::GetInstance()->tray_delegate(); | 123 ash::Shell::GetInstance()->tray_delegate(); |
66 delegate->SetAudioMuted(!delegate->IsAudioMuted()); | 124 delegate->SetAudioMuted(!delegate->IsAudioMuted()); |
67 | |
68 // TODO(sad): Should the icon auto-update its state when mute/unmute happens | |
69 // above? | |
70 icon_->SetToggled(delegate->IsAudioMuted()); | |
71 } | 125 } |
72 | 126 |
73 // Overridden from views:SliderListener. | 127 // Overridden from views:SliderListener. |
74 virtual void SliderValueChanged(views::Slider* sender, | 128 virtual void SliderValueChanged(views::Slider* sender, |
75 float value, | 129 float value, |
76 float old_value, | 130 float old_value, |
77 views::SliderChangeReason reason) OVERRIDE { | 131 views::SliderChangeReason reason) OVERRIDE { |
78 if (reason != views::VALUE_CHANGED_BY_USER) | 132 if (reason == views::VALUE_CHANGED_BY_USER) |
79 return; | 133 ash::Shell::GetInstance()->tray_delegate()->SetVolumeLevel(value); |
80 ash::Shell::GetInstance()->tray_delegate()->SetVolumeLevel(value); | 134 icon_->Update(); |
81 } | 135 } |
82 | 136 |
83 views::ToggleImageButton* icon_; | 137 VolumeButton* icon_; |
84 views::Slider* slider_; | 138 views::Slider* slider_; |
85 | 139 |
86 DISALLOW_COPY_AND_ASSIGN(VolumeView); | 140 DISALLOW_COPY_AND_ASSIGN(VolumeView); |
87 }; | 141 }; |
88 | 142 |
89 } // namespace tray | 143 } // namespace tray |
90 | 144 |
91 namespace ash { | |
92 namespace internal { | |
93 | |
94 TrayVolume::TrayVolume() { | 145 TrayVolume::TrayVolume() { |
95 } | 146 } |
96 | 147 |
97 TrayVolume::~TrayVolume() { | 148 TrayVolume::~TrayVolume() { |
98 } | 149 } |
99 | 150 |
100 views::View* TrayVolume::CreateTrayView() { | 151 views::View* TrayVolume::CreateTrayView() { |
101 tray_view_.reset(new views::ImageView()); | 152 return NULL; |
102 tray_view_->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
103 IDR_AURA_UBER_TRAY_VOLUME).ToSkBitmap()); | |
104 return tray_view_.get(); | |
105 } | 153 } |
106 | 154 |
107 views::View* TrayVolume::CreateDefaultView() { | 155 views::View* TrayVolume::CreateDefaultView() { |
108 volume_view_.reset(new tray::VolumeView); | 156 volume_view_.reset(new tray::VolumeView); |
109 return volume_view_.get(); | 157 return volume_view_.get(); |
110 } | 158 } |
111 | 159 |
112 views::View* TrayVolume::CreateDetailedView() { | 160 views::View* TrayVolume::CreateDetailedView() { |
113 volume_view_.reset(new tray::VolumeView); | 161 volume_view_.reset(new tray::VolumeView); |
114 return volume_view_.get(); | 162 return volume_view_.get(); |
115 } | 163 } |
116 | 164 |
117 void TrayVolume::DestroyTrayView() { | 165 void TrayVolume::DestroyTrayView() { |
118 tray_view_.reset(); | |
119 } | 166 } |
120 | 167 |
121 void TrayVolume::DestroyDefaultView() { | 168 void TrayVolume::DestroyDefaultView() { |
122 volume_view_.reset(); | 169 volume_view_.reset(); |
123 } | 170 } |
124 | 171 |
125 void TrayVolume::DestroyDetailedView() { | 172 void TrayVolume::DestroyDetailedView() { |
126 volume_view_.reset(); | 173 volume_view_.reset(); |
127 } | 174 } |
128 | 175 |
129 void TrayVolume::OnVolumeChanged(float percent) { | 176 void TrayVolume::OnVolumeChanged(float percent) { |
130 if (volume_view_.get()) { | 177 if (volume_view_.get()) { |
131 volume_view_->SetVolumeLevel(percent); | 178 volume_view_->SetVolumeLevel(percent); |
132 return; | 179 return; |
133 } | 180 } |
134 | 181 |
135 PopupDetailedView(); | 182 PopupDetailedView(); |
136 } | 183 } |
137 | 184 |
138 } // namespace internal | 185 } // namespace internal |
139 } // namespace ash | 186 } // namespace ash |
OLD | NEW |