• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
LogoutButton(views::ButtonListener * listener)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 
~LogoutButton()92 LogoutButton::~LogoutButton() {
93 }
94 
LogoutButtonTray(StatusAreaWidget * status_area_widget)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 
~LogoutButtonTray()106 LogoutButtonTray::~LogoutButtonTray() {
107   Shell::GetInstance()->system_tray_notifier()->
108       RemoveLogoutButtonObserver(this);
109 }
110 
SetShelfAlignment(ShelfAlignment alignment)111 void LogoutButtonTray::SetShelfAlignment(ShelfAlignment alignment) {
112   TrayBackgroundView::SetShelfAlignment(alignment);
113   tray_container()->SetBorder(views::Border::NullBorder());
114 }
115 
GetAccessibleNameForTray()116 base::string16 LogoutButtonTray::GetAccessibleNameForTray() {
117   return button_->GetText();
118 }
119 
HideBubbleWithView(const views::TrayBubbleView * bubble_view)120 void LogoutButtonTray::HideBubbleWithView(
121     const views::TrayBubbleView* bubble_view) {
122 }
123 
ClickedOutsideBubble()124 bool LogoutButtonTray::ClickedOutsideBubble() {
125   return false;
126 }
127 
OnShowLogoutButtonInTrayChanged(bool show)128 void LogoutButtonTray::OnShowLogoutButtonInTrayChanged(bool show) {
129   show_logout_button_in_tray_ = show;
130   UpdateVisibility();
131 }
132 
OnLogoutDialogDurationChanged(base::TimeDelta duration)133 void LogoutButtonTray::OnLogoutDialogDurationChanged(base::TimeDelta duration) {
134   dialog_duration_ = duration;
135 }
136 
ButtonPressed(views::Button * sender,const ui::Event & event)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 
UpdateAfterLoginStatusChange(user::LoginStatus login_status)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 
UpdateVisibility()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