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.
5 #include "ash/system/chromeos/session/logout_button_tray.h"
7 #include "ash/shelf/shelf_types.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"
30 const int kLogoutButtonHorizontalExtraPadding
= 7;
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
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
56 class LogoutButton
: public views::LabelButton
{
58 LogoutButton(views::ButtonListener
* listener
);
59 ~LogoutButton() override
;
62 DISALLOW_COPY_AND_ASSIGN(LogoutButton
);
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
);
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
.Pass());
87 set_animate_on_state_change(false);
89 SetMinSize(gfx::Size(0, kShelfItemHeight
));
92 LogoutButton::~LogoutButton() {
95 LogoutButtonTray::LogoutButtonTray(StatusAreaWidget
* status_area_widget
)
96 : TrayBackgroundView(status_area_widget
),
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);
106 LogoutButtonTray::~LogoutButtonTray() {
107 Shell::GetInstance()->system_tray_notifier()->
108 RemoveLogoutButtonObserver(this);
111 void LogoutButtonTray::SetShelfAlignment(ShelfAlignment alignment
) {
112 TrayBackgroundView::SetShelfAlignment(alignment
);
113 tray_container()->SetBorder(views::Border::NullBorder());
116 base::string16
LogoutButtonTray::GetAccessibleNameForTray() {
117 return button_
->GetText();
120 void LogoutButtonTray::HideBubbleWithView(
121 const views::TrayBubbleView
* bubble_view
) {
124 bool LogoutButtonTray::ClickedOutsideBubble() {
128 void LogoutButtonTray::OnShowLogoutButtonInTrayChanged(bool show
) {
129 show_logout_button_in_tray_
= show
;
133 void LogoutButtonTray::OnLogoutDialogDurationChanged(base::TimeDelta duration
) {
134 dialog_duration_
= duration
;
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_
);
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
);
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
);