1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 23551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 33551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// found in the LICENSE file. 43551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/chromeos/session/logout_button_tray.h" 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/shelf/shelf_types.h" 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/shell.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/system/chromeos/session/logout_confirmation_controller.h" 103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/system/status_area_widget.h" 113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/system/tray/system_tray_delegate.h" 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/system/tray/system_tray_notifier.h" 133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/system/tray/tray_constants.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ash/system/tray/tray_utils.h" 153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/logging.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "grit/ash_resources.h" 183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "third_party/skia/include/core/SkColor.h" 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/geometry/insets.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/geometry/size.h" 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/bubble/tray_bubble_view.h" 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/controls/button/label_button.h" 243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/controls/button/label_button_border.h" 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/views/painter.h" 263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace ash { 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace { 293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kLogoutButtonHorizontalExtraPadding = 7; 313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kLogoutButtonNormalImages[] = { 333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_TOP_LEFT, 343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_TOP, 353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_TOP_RIGHT, 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_LEFT, 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_CENTER, 383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_RIGHT, 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_BOTTOM_LEFT, 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_BOTTOM, 413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_NORMAL_BOTTOM_RIGHT 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const int kLogoutButtonPushedImages[] = { 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_TOP_LEFT, 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_TOP, 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_TOP_RIGHT, 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_LEFT, 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_CENTER, 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_RIGHT, 513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_BOTTOM_LEFT, 523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_BOTTOM, 533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) IDR_AURA_UBER_TRAY_LOGOUT_BUTTON_PUSHED_BOTTOM_RIGHT 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class LogoutButton : public views::LabelButton { 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public: 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LogoutButton(views::ButtonListener* listener); 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual ~LogoutButton(); 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private: 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LogoutButton); 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)LogoutButton::LogoutButton(views::ButtonListener* listener) 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : views::LabelButton(listener, base::string16()) { 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetupLabelForTray(label()); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetFontList(label()->font_list()); 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (size_t state = 0; state < views::Button::STATE_COUNT; ++state) 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetTextColor(static_cast<views::Button::ButtonState>(state), SK_ColorWHITE); 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<views::LabelButtonBorder> border( 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new views::LabelButtonBorder(views::Button::STYLE_TEXTBUTTON)); 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) border->SetPainter(false, views::Button::STATE_NORMAL, 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) views::Painter::CreateImageGridPainter(kLogoutButtonNormalImages)); 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) border->SetPainter(false, views::Button::STATE_HOVERED, 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) views::Painter::CreateImageGridPainter(kLogoutButtonNormalImages)); 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) border->SetPainter(false, views::Button::STATE_PRESSED, 813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) views::Painter::CreateImageGridPainter(kLogoutButtonPushedImages)); 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) gfx::Insets insets = border->GetInsets(); 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) insets += gfx::Insets(0, kLogoutButtonHorizontalExtraPadding, 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 0, kLogoutButtonHorizontalExtraPadding); 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) border->set_insets(insets); 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetBorder(border.PassAs<views::Border>()); 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) set_animate_on_state_change(false); 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetMinSize(gfx::Size(0, kShelfItemHeight)); 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)LogoutButton::~LogoutButton() { 933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)LogoutButtonTray::LogoutButtonTray(StatusAreaWidget* status_area_widget) 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : TrayBackgroundView(status_area_widget), 973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) button_(NULL), 983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) login_status_(user::LOGGED_IN_NONE), 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) show_logout_button_in_tray_(false) { 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) button_ = new LogoutButton(this); 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) tray_container()->AddChildView(button_); 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tray_container()->SetBorder(views::Border::NullBorder()); 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Shell::GetInstance()->system_tray_notifier()->AddLogoutButtonObserver(this); 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)LogoutButtonTray::~LogoutButtonTray() { 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Shell::GetInstance()->system_tray_notifier()-> 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RemoveLogoutButtonObserver(this); 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void LogoutButtonTray::SetShelfAlignment(ShelfAlignment alignment) { 1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TrayBackgroundView::SetShelfAlignment(alignment); 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tray_container()->SetBorder(views::Border::NullBorder()); 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::string16 LogoutButtonTray::GetAccessibleNameForTray() { 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return button_->GetText(); 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void LogoutButtonTray::HideBubbleWithView( 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const views::TrayBubbleView* bubble_view) { 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool LogoutButtonTray::ClickedOutsideBubble() { 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return false; 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void LogoutButtonTray::OnShowLogoutButtonInTrayChanged(bool show) { 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) show_logout_button_in_tray_ = show; 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateVisibility(); 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void LogoutButtonTray::OnLogoutDialogDurationChanged(base::TimeDelta duration) { 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dialog_duration_ = duration; 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void LogoutButtonTray::ButtonPressed(views::Button* sender, 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ui::Event& event) { 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK_EQ(sender, button_); 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (dialog_duration_ <= base::TimeDelta()) { 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Sign out immediately if |dialog_duration_| is non-positive. 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Shell::GetInstance()->system_tray_delegate()->SignOut(); 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (Shell::GetInstance()->logout_confirmation_controller()) { 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Shell::GetInstance()->logout_confirmation_controller()->ConfirmLogout( 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeTicks::Now() + dialog_duration_); 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void LogoutButtonTray::UpdateAfterLoginStatusChange( 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) user::LoginStatus login_status) { 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) login_status_ = login_status; 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const base::string16 title = 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GetLocalizedSignOutStringForStatus(login_status, false); 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) button_->SetText(title); 1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) button_->SetAccessibleName(title); 1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) UpdateVisibility(); 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void LogoutButtonTray::UpdateVisibility() { 1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetVisible(show_logout_button_in_tray_ && 1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) login_status_ != user::LOGGED_IN_NONE && 1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) login_status_ != user::LOGGED_IN_LOCKED); 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace ash 166