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