1 // Copyright 2013 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/logout_button_tray.h" 6 7 #include "ash/shelf/shelf_types.h" 8 #include "ash/shell.h" 9 #include "ash/system/status_area_widget.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/tray/tray_utils.h" 14 #include "base/logging.h" 15 #include "grit/ash_resources.h" 16 #include "third_party/skia/include/core/SkColor.h" 17 #include "ui/events/event.h" 18 #include "ui/gfx/font.h" 19 #include "ui/gfx/insets.h" 20 #include "ui/gfx/size.h" 21 #include "ui/views/bubble/tray_bubble_view.h" 22 #include "ui/views/controls/button/label_button.h" 23 #include "ui/views/controls/button/label_button_border.h" 24 #include "ui/views/painter.h" 25 26 namespace ash { 27 28 namespace internal { 29 30 namespace { 31 32 const int kLogoutButtonHorizontalExtraPadding = 7; 33 34 const int kLogoutButtonNormalImages[] = { 35 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_TOP_LEFT, 36 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_TOP, 37 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_TOP_RIGHT, 38 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_LEFT, 39 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_CENTER, 40 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_RIGHT, 41 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_BOTTOM_LEFT, 42 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_BOTTOM, 43 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_BOTTOM_RIGHT 44 }; 45 46 const int kLogoutButtonPushedImages[] = { 47 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_TOP_LEFT, 48 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_TOP, 49 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_TOP_RIGHT, 50 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_LEFT, 51 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_CENTER, 52 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_RIGHT, 53 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_BOTTOM_LEFT, 54 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_BOTTOM, 55 IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_BOTTOM_RIGHT 56 }; 57 58 class LogoutButton : public views::LabelButton { 59 public: 60 LogoutButton(views::ButtonListener* listener); 61 virtual ~LogoutButton(); 62 63 private: 64 DISALLOW_COPY_AND_ASSIGN(LogoutButton); 65 }; 66 67 } // namespace 68 69 LogoutButton::LogoutButton(views::ButtonListener* listener) 70 : views::LabelButton(listener, base::string16()) { 71 SetupLabelForTray(label()); 72 SetFont(GetFont().DeriveFont(0, gfx::Font::NORMAL)); 73 for (size_t state = 0; state < views::Button::STATE_COUNT; ++state) 74 SetTextColor(static_cast<views::Button::ButtonState>(state), SK_ColorWHITE); 75 76 views::LabelButtonBorder* border = 77 new views::LabelButtonBorder(views::Button::STYLE_TEXTBUTTON); 78 border->SetPainter(false, views::Button::STATE_NORMAL, 79 views::Painter::CreateImageGridPainter(kLogoutButtonNormalImages)); 80 border->SetPainter(false, views::Button::STATE_HOVERED, 81 views::Painter::CreateImageGridPainter(kLogoutButtonNormalImages)); 82 border->SetPainter(false, views::Button::STATE_PRESSED, 83 views::Painter::CreateImageGridPainter(kLogoutButtonPushedImages)); 84 gfx::Insets insets = border->GetInsets(); 85 insets += gfx::Insets(0, kLogoutButtonHorizontalExtraPadding, 86 0, kLogoutButtonHorizontalExtraPadding); 87 border->set_insets(insets); 88 set_border(border); 89 set_animate_on_state_change(false); 90 91 set_min_size(gfx::Size(0, GetShelfItemHeight())); 92 } 93 94 LogoutButton::~LogoutButton() { 95 } 96 97 LogoutButtonTray::LogoutButtonTray(StatusAreaWidget* status_area_widget) 98 : TrayBackgroundView(status_area_widget), 99 button_(NULL), 100 login_status_(user::LOGGED_IN_NONE), 101 show_logout_button_in_tray_(false) { 102 button_ = new LogoutButton(this); 103 tray_container()->AddChildView(button_); 104 tray_container()->set_border(NULL); 105 Shell::GetInstance()->system_tray_notifier()->AddLogoutButtonObserver(this); 106 } 107 108 LogoutButtonTray::~LogoutButtonTray() { 109 Shell::GetInstance()->system_tray_notifier()-> 110 RemoveLogoutButtonObserver(this); 111 } 112 113 void LogoutButtonTray::SetShelfAlignment(ShelfAlignment alignment) { 114 TrayBackgroundView::SetShelfAlignment(alignment); 115 tray_container()->set_border(NULL); 116 } 117 118 base::string16 LogoutButtonTray::GetAccessibleNameForTray() { 119 return button_->GetText(); 120 } 121 122 void LogoutButtonTray::HideBubbleWithView( 123 const views::TrayBubbleView* bubble_view) { 124 } 125 126 bool LogoutButtonTray::ClickedOutsideBubble() { 127 return false; 128 } 129 130 void LogoutButtonTray::OnShowLogoutButtonInTrayChanged(bool show) { 131 show_logout_button_in_tray_ = show; 132 UpdateVisibility(); 133 } 134 135 void LogoutButtonTray::ButtonPressed(views::Button* sender, 136 const ui::Event& event) { 137 DCHECK_EQ(sender, button_); 138 Shell::GetInstance()->system_tray_delegate()->SignOut(); 139 } 140 141 void LogoutButtonTray::UpdateAfterLoginStatusChange( 142 user::LoginStatus login_status) { 143 login_status_ = login_status; 144 const base::string16 title = 145 GetLocalizedSignOutStringForStatus(login_status, false); 146 button_->SetText(title); 147 button_->SetAccessibleName(title); 148 UpdateVisibility(); 149 } 150 151 void LogoutButtonTray::UpdateVisibility() { 152 SetVisible(show_logout_button_in_tray_ && 153 login_status_ != user::LOGGED_IN_NONE && 154 login_status_ != user::LOGGED_IN_LOCKED); 155 } 156 157 } // namespace internal 158 } // namespace ash 159