Home | History | Annotate | Download | only in logout_button
      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/logout_button/tray_logout_button.h"
      6 
      7 #include <cstddef>
      8 
      9 #include "ash/shell.h"
     10 #include "ash/system/tray/system_tray_delegate.h"
     11 #include "ash/system/tray/system_tray_notifier.h"
     12 #include "ash/system/tray/tray_constants.h"
     13 #include "ash/system/user/login_status.h"
     14 #include "base/logging.h"
     15 #include "base/strings/string16.h"
     16 #include "grit/ash_resources.h"
     17 #include "third_party/skia/include/core/SkColor.h"
     18 #include "ui/views/border.h"
     19 #include "ui/views/controls/button/button.h"
     20 #include "ui/views/controls/button/custom_button.h"
     21 #include "ui/views/controls/button/label_button.h"
     22 #include "ui/views/controls/button/label_button_border.h"
     23 #include "ui/views/layout/box_layout.h"
     24 #include "ui/views/view.h"
     25 
     26 namespace {
     27 
     28 const int kLogoutButtonNormalImages[] = {
     29   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_TOP_LEFT,
     30   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_TOP,
     31   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_TOP_RIGHT,
     32   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_LEFT,
     33   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_CENTER,
     34   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_RIGHT,
     35   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_BOTTOM_LEFT,
     36   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_BOTTOM,
     37   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_BOTTOM_RIGHT
     38 };
     39 const int kLogoutButtonHotImages[] = {
     40   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_HOT_TOP_LEFT,
     41   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_HOT_TOP,
     42   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_HOT_TOP_RIGHT,
     43   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_HOT_LEFT,
     44   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_HOT_CENTER,
     45   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_HOT_RIGHT,
     46   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_HOT_BOTTOM_LEFT,
     47   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_HOT_BOTTOM,
     48   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_HOT_BOTTOM_RIGHT
     49 };
     50 const int kLogoutButtonPushedImages[] = {
     51   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_TOP_LEFT,
     52   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_TOP,
     53   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_TOP_RIGHT,
     54   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_LEFT,
     55   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_CENTER,
     56   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_RIGHT,
     57   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_BOTTOM_LEFT,
     58   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_BOTTOM,
     59   IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_BOTTOM_RIGHT
     60 };
     61 
     62 }  // namespace
     63 
     64 namespace ash {
     65 namespace internal {
     66 
     67 namespace tray {
     68 
     69 class LogoutButton : public views::View,
     70                      public views::ButtonListener {
     71  public:
     72   LogoutButton(user::LoginStatus status) : button_(NULL),
     73                                            login_status_(user::LOGGED_IN_NONE),
     74                                            show_logout_button_in_tray_(false) {
     75     views::BoxLayout* layout = new views::BoxLayout(
     76         views::BoxLayout::kHorizontal, 0, 0, 0);
     77     layout->set_spread_blank_space(true);
     78     SetLayoutManager(layout);
     79     set_border(views::Border::CreateEmptyBorder(
     80         0, kTrayLabelItemHorizontalPaddingBottomAlignment, 0, 0));
     81 
     82     button_ = new views::LabelButton(this, base::string16());
     83     for (size_t state = 0; state < views::Button::STATE_COUNT; ++state) {
     84       button_->SetTextColor(
     85           static_cast<views::Button::ButtonState>(state), SK_ColorWHITE);
     86     }
     87     button_->SetFont(button_->GetFont().DeriveFont(1));
     88     views::LabelButtonBorder* border =
     89         new views::LabelButtonBorder(views::Button::STYLE_TEXTBUTTON);
     90     border->SetPainter(false, views::Button::STATE_NORMAL,
     91         views::Painter::CreateImageGridPainter(kLogoutButtonNormalImages));
     92     border->SetPainter(false, views::Button::STATE_HOVERED,
     93         views::Painter::CreateImageGridPainter(kLogoutButtonHotImages));
     94     border->SetPainter(false, views::Button::STATE_PRESSED,
     95         views::Painter::CreateImageGridPainter(kLogoutButtonPushedImages));
     96     button_->set_border(border);
     97     AddChildView(button_);
     98     OnLoginStatusChanged(status);
     99   }
    100 
    101   void OnLoginStatusChanged(user::LoginStatus status) {
    102     login_status_ = status;
    103     const base::string16 title = GetLocalizedSignOutStringForStatus(
    104         login_status_, false);
    105     button_->SetText(title);
    106     button_->SetAccessibleName(title);
    107     UpdateVisibility();
    108   }
    109 
    110   void OnShowLogoutButtonInTrayChanged(bool show) {
    111     show_logout_button_in_tray_ = show;
    112     UpdateVisibility();
    113   }
    114 
    115   // Overridden from views::ButtonListener.
    116   virtual void ButtonPressed(views::Button* sender,
    117                              const ui::Event& event) OVERRIDE {
    118     DCHECK_EQ(sender, button_);
    119     Shell::GetInstance()->system_tray_delegate()->SignOut();
    120   }
    121 
    122  private:
    123   void UpdateVisibility() {
    124     SetVisible(show_logout_button_in_tray_ &&
    125                login_status_ != user::LOGGED_IN_NONE &&
    126                login_status_ != user::LOGGED_IN_LOCKED);
    127   }
    128 
    129   views::LabelButton* button_;
    130   user::LoginStatus login_status_;
    131   bool show_logout_button_in_tray_;
    132 
    133   DISALLOW_COPY_AND_ASSIGN(LogoutButton);
    134 };
    135 
    136 }  // namespace tray
    137 
    138 TrayLogoutButton::TrayLogoutButton(SystemTray* system_tray)
    139     : SystemTrayItem(system_tray),
    140       logout_button_(NULL) {
    141   Shell::GetInstance()->system_tray_notifier()->AddLogoutButtonObserver(this);
    142 }
    143 
    144 TrayLogoutButton::~TrayLogoutButton() {
    145   Shell::GetInstance()->system_tray_notifier()->
    146       RemoveLogoutButtonObserver(this);
    147 }
    148 
    149 views::View* TrayLogoutButton::CreateTrayView(user::LoginStatus status) {
    150   CHECK(logout_button_ == NULL);
    151   logout_button_ = new tray::LogoutButton(status);
    152   return logout_button_;
    153 }
    154 
    155 void TrayLogoutButton::DestroyTrayView() {
    156   logout_button_ = NULL;
    157 }
    158 
    159 void TrayLogoutButton::UpdateAfterLoginStatusChange(user::LoginStatus status) {
    160   logout_button_->OnLoginStatusChanged(status);
    161 }
    162 
    163 void TrayLogoutButton::OnShowLogoutButtonInTrayChanged(bool show) {
    164   logout_button_->OnShowLogoutButtonInTrayChanged(show);
    165 }
    166 
    167 }  // namespace internal
    168 }  // namespace ash
    169