screen_tray_item.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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
14namespace {
15const int kStopButtonRightPadding = 18;
16}  // namespace
17
18namespace ash {
19namespace tray {
20
21// ScreenTrayView implementations.
22ScreenTrayView::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
32ScreenTrayView::~ScreenTrayView() {
33}
34
35void ScreenTrayView::Update() {
36  SetVisible(screen_tray_item_->is_started());
37}
38
39
40// ScreenStatusView implementations.
41ScreenStatusView::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
56ScreenStatusView::~ScreenStatusView() {
57}
58
59void 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
78void ScreenStatusView::ButtonPressed(
79    views::Button* sender,
80    const ui::Event& event) {
81  DCHECK(sender == stop_button_);
82  screen_tray_item_->Stop();
83}
84
85void 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
105void 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
111ScreenNotificationDelegate::ScreenNotificationDelegate(
112    ScreenTrayItem* screen_tray)
113  : screen_tray_(screen_tray) {
114}
115
116ScreenNotificationDelegate::~ScreenNotificationDelegate() {
117}
118
119void ScreenNotificationDelegate::Display() {
120}
121
122void ScreenNotificationDelegate::Error() {
123}
124
125void ScreenNotificationDelegate::Close(bool by_user) {
126}
127
128void ScreenNotificationDelegate::Click() {
129}
130
131void ScreenNotificationDelegate::ButtonClick(int button_index) {
132  DCHECK_EQ(0, button_index);
133  screen_tray_->Stop();
134}
135
136}  // namespace tray
137
138ScreenTrayItem::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
146ScreenTrayItem::~ScreenTrayItem() {}
147
148void 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
161void 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
177void 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
189void ScreenTrayItem::DestroyTrayView() {
190  tray_view_ = NULL;
191}
192
193void ScreenTrayItem::DestroyDefaultView() {
194  default_view_ = NULL;
195}
196
197void 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