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/chromeos/screen_security/screen_tray_item.h"
6
7 #include "ash/system/tray/fixed_sized_image_view.h"
8 #include "ash/system/tray/tray_constants.h"
9 #include "ui/base/resource/resource_bundle.h"
10 #include "ui/message_center/message_center.h"
11 #include "ui/views/controls/label.h"
12 #include "ui/views/layout/box_layout.h"
13
14 namespace {
15 const int kStopButtonRightPadding = 18;
16 } // namespace
17
18 namespace ash {
19 namespace tray {
20
21 // ScreenTrayView implementations.
ScreenTrayView(ScreenTrayItem * screen_tray_item,int icon_id)22 ScreenTrayView::ScreenTrayView(ScreenTrayItem* screen_tray_item, int icon_id)
23 : TrayItemView(screen_tray_item),
24 screen_tray_item_(screen_tray_item) {
25 CreateImageView();
26 image_view()->SetImage(ui::ResourceBundle::GetSharedInstance()
27 .GetImageNamed(icon_id).ToImageSkia());
28
29 Update();
30 }
31
~ScreenTrayView()32 ScreenTrayView::~ScreenTrayView() {
33 }
34
Update()35 void ScreenTrayView::Update() {
36 SetVisible(screen_tray_item_->is_started());
37 }
38
39
40 // ScreenStatusView implementations.
ScreenStatusView(ScreenTrayItem * screen_tray_item,int icon_id,const base::string16 & label_text,const base::string16 & stop_button_text)41 ScreenStatusView::ScreenStatusView(ScreenTrayItem* screen_tray_item,
42 int icon_id,
43 const base::string16& label_text,
44 const base::string16& stop_button_text)
45 : screen_tray_item_(screen_tray_item),
46 icon_(NULL),
47 label_(NULL),
48 stop_button_(NULL),
49 icon_id_(icon_id),
50 label_text_(label_text),
51 stop_button_text_(stop_button_text) {
52 CreateItems();
53 Update();
54 }
55
~ScreenStatusView()56 ScreenStatusView::~ScreenStatusView() {
57 }
58
Layout()59 void ScreenStatusView::Layout() {
60 views::View::Layout();
61
62 // Give the stop button the space it requests.
63 gfx::Size stop_size = stop_button_->GetPreferredSize();
64 gfx::Rect stop_bounds(stop_size);
65 stop_bounds.set_x(width() - stop_size.width() - kStopButtonRightPadding);
66 stop_bounds.set_y((height() - stop_size.height()) / 2);
67 stop_button_->SetBoundsRect(stop_bounds);
68
69 // Adjust the label's bounds in case it got cut off by |stop_button_|.
70 if (label_->bounds().Intersects(stop_button_->bounds())) {
71 gfx::Rect label_bounds = label_->bounds();
72 label_bounds.set_width(
73 stop_button_->x() - kTrayPopupPaddingBetweenItems - label_->x());
74 label_->SetBoundsRect(label_bounds);
75 }
76 }
77
ButtonPressed(views::Button * sender,const ui::Event & event)78 void ScreenStatusView::ButtonPressed(
79 views::Button* sender,
80 const ui::Event& event) {
81 DCHECK(sender == stop_button_);
82 screen_tray_item_->Stop();
83 }
84
CreateItems()85 void ScreenStatusView::CreateItems() {
86 set_background(views::Background::CreateSolidBackground(kBackgroundColor));
87 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
88 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal,
89 kTrayPopupPaddingHorizontal,
90 0,
91 kTrayPopupPaddingBetweenItems));
92 icon_ = new FixedSizedImageView(0, kTrayPopupItemHeight);
93 icon_->SetImage(bundle.GetImageNamed(icon_id_).ToImageSkia());
94 AddChildView(icon_);
95 label_ = new views::Label;
96 label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
97 label_->SetMultiLine(true);
98 label_->SetText(label_text_);
99 AddChildView(label_);
100
101 stop_button_ = new TrayPopupLabelButton(this, stop_button_text_);
102 AddChildView(stop_button_);
103 }
104
Update()105 void ScreenStatusView::Update() {
106 // Hide the notification bubble when the ash tray bubble opens.
107 screen_tray_item_->HideNotificationView();
108 SetVisible(screen_tray_item_->is_started());
109 }
110
ScreenNotificationDelegate(ScreenTrayItem * screen_tray)111 ScreenNotificationDelegate::ScreenNotificationDelegate(
112 ScreenTrayItem* screen_tray)
113 : screen_tray_(screen_tray) {
114 }
115
~ScreenNotificationDelegate()116 ScreenNotificationDelegate::~ScreenNotificationDelegate() {
117 }
118
Display()119 void ScreenNotificationDelegate::Display() {
120 }
121
Error()122 void ScreenNotificationDelegate::Error() {
123 }
124
Close(bool by_user)125 void ScreenNotificationDelegate::Close(bool by_user) {
126 }
127
Click()128 void ScreenNotificationDelegate::Click() {
129 }
130
ButtonClick(int button_index)131 void ScreenNotificationDelegate::ButtonClick(int button_index) {
132 DCHECK_EQ(0, button_index);
133 screen_tray_->Stop();
134 }
135
136 } // namespace tray
137
ScreenTrayItem(SystemTray * system_tray)138 ScreenTrayItem::ScreenTrayItem(SystemTray* system_tray)
139 : SystemTrayItem(system_tray),
140 tray_view_(NULL),
141 default_view_(NULL),
142 is_started_(false),
143 stop_callback_(base::Bind(&base::DoNothing)) {
144 }
145
~ScreenTrayItem()146 ScreenTrayItem::~ScreenTrayItem() {}
147
Update()148 void ScreenTrayItem::Update() {
149 if (tray_view_)
150 tray_view_->Update();
151 if (default_view_)
152 default_view_->Update();
153 if (is_started_) {
154 CreateOrUpdateNotification();
155 } else {
156 message_center::MessageCenter::Get()->RemoveNotification(
157 GetNotificationId(), false /* by_user */);
158 }
159 }
160
Start(const base::Closure & stop_callback)161 void ScreenTrayItem::Start(const base::Closure& stop_callback) {
162 stop_callback_ = stop_callback;
163 is_started_ = true;
164
165 if (tray_view_)
166 tray_view_->Update();
167
168 if (default_view_)
169 default_view_->Update();
170
171 if (!system_tray()->HasSystemBubbleType(
172 SystemTrayBubble::BUBBLE_TYPE_DEFAULT)) {
173 CreateOrUpdateNotification();
174 }
175 }
176
Stop()177 void ScreenTrayItem::Stop() {
178 is_started_ = false;
179 Update();
180
181 if (stop_callback_.is_null())
182 return;
183
184 base::Closure callback = stop_callback_;
185 stop_callback_.Reset();
186 callback.Run();
187 }
188
DestroyTrayView()189 void ScreenTrayItem::DestroyTrayView() {
190 tray_view_ = NULL;
191 }
192
DestroyDefaultView()193 void ScreenTrayItem::DestroyDefaultView() {
194 default_view_ = NULL;
195 }
196
UpdateAfterShelfAlignmentChange(ShelfAlignment alignment)197 void ScreenTrayItem::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
198 if (!tray_view_)
199 return;
200
201 // Center the item dependent on the orientation of the shelf.
202 views::BoxLayout::Orientation layout =
203 (alignment == ash::SHELF_ALIGNMENT_BOTTOM ||
204 alignment == ash::SHELF_ALIGNMENT_TOP)
205 ? views::BoxLayout::kHorizontal
206 : views::BoxLayout::kVertical;
207 tray_view_->SetLayoutManager(new views::BoxLayout(layout, 0, 0, 0));
208 tray_view_->Layout();
209 }
210
211 } // namespace ash
212