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