| 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 |