Home | History | Annotate | Download | only in brightness
      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/brightness/tray_brightness.h"
      6 
      7 #include "ash/accelerators/accelerator_controller.h"
      8 #include "ash/ash_constants.h"
      9 #include "ash/shell.h"
     10 #include "ash/system/brightness/brightness_control_delegate.h"
     11 #include "ash/system/tray/fixed_sized_image_view.h"
     12 #include "ash/system/tray/system_tray_delegate.h"
     13 #include "ash/system/tray/system_tray_notifier.h"
     14 #include "ash/system/tray/tray_constants.h"
     15 #include "base/bind.h"
     16 #include "base/message_loop/message_loop.h"
     17 #include "base/strings/utf_string_conversions.h"
     18 #include "grit/ash_resources.h"
     19 #include "grit/ash_strings.h"
     20 #include "ui/base/resource/resource_bundle.h"
     21 #include "ui/gfx/image/image.h"
     22 #include "ui/views/controls/button/image_button.h"
     23 #include "ui/views/controls/image_view.h"
     24 #include "ui/views/controls/label.h"
     25 #include "ui/views/controls/slider.h"
     26 #include "ui/views/layout/box_layout.h"
     27 #include "ui/views/view.h"
     28 
     29 namespace ash {
     30 namespace internal {
     31 
     32 namespace tray {
     33 
     34 namespace {
     35 
     36 // We don't let the screen brightness go lower than this when it's being
     37 // adjusted via the slider.  Otherwise, if the user doesn't know about the
     38 // brightness keys, they may turn the backlight off and not know how to turn it
     39 // back on.
     40 const double kMinBrightnessPercent = 5.0;
     41 
     42 }  // namespace
     43 
     44 class BrightnessView : public views::View,
     45                        public views::SliderListener {
     46  public:
     47   explicit BrightnessView(double initial_percent)
     48       : dragging_(false),
     49         last_percent_(initial_percent) {
     50     SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
     51           kTrayPopupPaddingHorizontal, 0, kTrayPopupPaddingBetweenItems));
     52 
     53     views::ImageView* icon = new FixedSizedImageView(0, kTrayPopupItemHeight);
     54     gfx::Image image = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
     55         IDR_AURA_UBER_TRAY_BRIGHTNESS);
     56     icon->SetImage(image.ToImageSkia());
     57     AddChildView(icon);
     58 
     59     slider_ = new views::Slider(this, views::Slider::HORIZONTAL);
     60     slider_->set_focus_border_color(kFocusBorderColor);
     61     slider_->SetValue(static_cast<float>(initial_percent / 100.0));
     62     slider_->SetAccessibleName(
     63         ui::ResourceBundle::GetSharedInstance().GetLocalizedString(
     64             IDS_ASH_STATUS_TRAY_BRIGHTNESS));
     65     AddChildView(slider_);
     66   }
     67 
     68   virtual ~BrightnessView() {}
     69 
     70   // |percent| is in the range [0.0, 100.0].
     71   void SetBrightnessPercent(double percent) {
     72     last_percent_ = percent;
     73     if (!dragging_)
     74       slider_->SetValue(static_cast<float>(percent / 100.0));
     75   }
     76 
     77  private:
     78   // Overridden from views::View.
     79   virtual void OnBoundsChanged(const gfx::Rect& old_bounds) OVERRIDE {
     80     int w = width() - slider_->x();
     81     slider_->SetSize(gfx::Size(w, slider_->height()));
     82   }
     83 
     84   // Overridden from views:SliderListener.
     85   virtual void SliderValueChanged(views::Slider* sender,
     86                                   float value,
     87                                   float old_value,
     88                                   views::SliderChangeReason reason) OVERRIDE {
     89     DCHECK_EQ(sender, slider_);
     90     if (reason != views::VALUE_CHANGED_BY_USER)
     91       return;
     92 #if !defined(OS_MACOSX)
     93     AcceleratorController* ac = Shell::GetInstance()->accelerator_controller();
     94     if (ac->brightness_control_delegate()) {
     95       double percent = std::max(value * 100.0, kMinBrightnessPercent);
     96       ac->brightness_control_delegate()->SetBrightnessPercent(percent, true);
     97     }
     98 #endif  // OS_MACOSX
     99   }
    100 
    101   // Overridden from views:SliderListener.
    102   virtual void SliderDragStarted(views::Slider* slider) OVERRIDE {
    103     DCHECK_EQ(slider, slider_);
    104     dragging_ = true;
    105   }
    106 
    107   // Overridden from views:SliderListener.
    108   virtual void SliderDragEnded(views::Slider* slider) OVERRIDE {
    109     DCHECK_EQ(slider, slider_);
    110     dragging_ = false;
    111     slider_->SetValue(static_cast<float>(last_percent_ / 100.0));
    112   }
    113 
    114   views::Slider* slider_;
    115 
    116   // Is |slider_| currently being dragged?
    117   bool dragging_;
    118 
    119   // Last brightness level that we observed, in the range [0.0, 100.0].
    120   double last_percent_;
    121 
    122   DISALLOW_COPY_AND_ASSIGN(BrightnessView);
    123 };
    124 
    125 }  // namespace tray
    126 
    127 TrayBrightness::TrayBrightness(SystemTray* system_tray)
    128     : SystemTrayItem(system_tray),
    129       weak_ptr_factory_(this),
    130       brightness_view_(NULL),
    131       is_default_view_(false),
    132       current_percent_(100.0),
    133       got_current_percent_(false) {
    134   // Post a task to get the initial brightness; the BrightnessControlDelegate
    135   // isn't created yet.
    136   base::MessageLoopForUI::current()->PostTask(
    137       FROM_HERE,
    138       base::Bind(&TrayBrightness::GetInitialBrightness,
    139                  weak_ptr_factory_.GetWeakPtr()));
    140   Shell::GetInstance()->system_tray_notifier()->AddBrightnessObserver(this);
    141 }
    142 
    143 TrayBrightness::~TrayBrightness() {
    144   Shell::GetInstance()->system_tray_notifier()->RemoveBrightnessObserver(this);
    145 }
    146 
    147 void TrayBrightness::GetInitialBrightness() {
    148   BrightnessControlDelegate* delegate =
    149       Shell::GetInstance()->accelerator_controller()->
    150       brightness_control_delegate();
    151   // Worrisome, but happens in unit tests, so don't log anything.
    152   if (!delegate)
    153     return;
    154   delegate->GetBrightnessPercent(
    155       base::Bind(&TrayBrightness::HandleInitialBrightness,
    156                  weak_ptr_factory_.GetWeakPtr()));
    157 }
    158 
    159 void TrayBrightness::HandleInitialBrightness(double percent) {
    160   if (!got_current_percent_)
    161     OnBrightnessChanged(percent, false);
    162 }
    163 
    164 views::View* TrayBrightness::CreateTrayView(user::LoginStatus status) {
    165   return NULL;
    166 }
    167 
    168 views::View* TrayBrightness::CreateDefaultView(user::LoginStatus status) {
    169   return NULL;
    170 }
    171 
    172 views::View* TrayBrightness::CreateDetailedView(user::LoginStatus status) {
    173   CHECK(brightness_view_ == NULL);
    174   brightness_view_ = new tray::BrightnessView(current_percent_);
    175   is_default_view_ = false;
    176   return brightness_view_;
    177 }
    178 
    179 void TrayBrightness::DestroyTrayView() {
    180 }
    181 
    182 void TrayBrightness::DestroyDefaultView() {
    183   if (is_default_view_)
    184     brightness_view_ = NULL;
    185 }
    186 
    187 void TrayBrightness::DestroyDetailedView() {
    188   if (!is_default_view_)
    189     brightness_view_ = NULL;
    190 }
    191 
    192 void TrayBrightness::UpdateAfterLoginStatusChange(user::LoginStatus status) {
    193 }
    194 
    195 bool TrayBrightness::ShouldHideArrow() const {
    196   return true;
    197 }
    198 
    199 bool TrayBrightness::ShouldShowLauncher() const {
    200   return false;
    201 }
    202 
    203 void TrayBrightness::OnBrightnessChanged(double percent, bool user_initiated) {
    204   current_percent_ = percent;
    205   got_current_percent_ = true;
    206 
    207   if (brightness_view_)
    208     brightness_view_->SetBrightnessPercent(percent);
    209   if (!user_initiated)
    210     return;
    211 
    212   if (brightness_view_)
    213     SetDetailedViewCloseDelay(kTrayPopupAutoCloseDelayInSeconds);
    214   else
    215     PopupDetailedView(kTrayPopupAutoCloseDelayInSeconds, false);
    216 }
    217 
    218 }  // namespace internal
    219 }  // namespace ash
    220