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. 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 32 ScreenTrayView::~ScreenTrayView() { 33 } 34 35 void ScreenTrayView::Update() { 36 SetVisible(screen_tray_item_->is_started()); 37 } 38 39 40 // ScreenStatusView implementations. 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 56 ScreenStatusView::~ScreenStatusView() { 57 } 58 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 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 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 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 111 ScreenNotificationDelegate::ScreenNotificationDelegate( 112 ScreenTrayItem* screen_tray) 113 : screen_tray_(screen_tray) { 114 } 115 116 ScreenNotificationDelegate::~ScreenNotificationDelegate() { 117 } 118 119 void ScreenNotificationDelegate::Display() { 120 } 121 122 void ScreenNotificationDelegate::Error() { 123 } 124 125 void ScreenNotificationDelegate::Close(bool by_user) { 126 } 127 128 void ScreenNotificationDelegate::Click() { 129 } 130 131 void ScreenNotificationDelegate::ButtonClick(int button_index) { 132 DCHECK_EQ(0, button_index); 133 screen_tray_->Stop(); 134 } 135 136 } // namespace tray 137 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 146 ScreenTrayItem::~ScreenTrayItem() {} 147 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 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 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 189 void ScreenTrayItem::DestroyTrayView() { 190 tray_view_ = NULL; 191 } 192 193 void ScreenTrayItem::DestroyDefaultView() { 194 default_view_ = NULL; 195 } 196 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