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