tray_bluetooth.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 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/bluetooth/tray_bluetooth.h" 6 7#include "ash/shell.h" 8#include "ash/system/tray/system_tray.h" 9#include "ash/system/tray/system_tray_delegate.h" 10#include "ash/system/tray/tray_constants.h" 11#include "ash/system/tray/tray_details_view.h" 12#include "ash/system/tray/tray_item_more.h" 13#include "ash/system/tray/tray_views.h" 14#include "grit/ash_resources.h" 15#include "grit/ash_strings.h" 16#include "ui/base/l10n/l10n_util.h" 17#include "ui/base/resource/resource_bundle.h" 18#include "ui/gfx/image/image.h" 19#include "ui/views/controls/image_view.h" 20#include "ui/views/controls/label.h" 21#include "ui/views/layout/box_layout.h" 22 23namespace { 24const int kDeviceListHeight = 276; 25} 26 27namespace ash { 28namespace internal { 29 30namespace tray { 31 32class BluetoothDefaultView : public TrayItemMore { 33 public: 34 explicit BluetoothDefaultView(SystemTrayItem* owner) 35 : TrayItemMore(owner, true) { 36 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); 37 SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_BLUETOOTH).ToImageSkia()); 38 UpdateLabel(); 39 } 40 41 virtual ~BluetoothDefaultView() {} 42 43 void UpdateLabel() { 44 ash::SystemTrayDelegate* delegate = 45 ash::Shell::GetInstance()->tray_delegate(); 46 if (delegate->GetBluetoothAvailable()) { 47 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 48 SetLabel(rb.GetLocalizedString(delegate->GetBluetoothEnabled() ? 49 IDS_ASH_STATUS_TRAY_BLUETOOTH_ENABLED : 50 IDS_ASH_STATUS_TRAY_BLUETOOTH_DISABLED)); 51 SetVisible(true); 52 } else { 53 SetVisible(false); 54 } 55 } 56 57 private: 58 DISALLOW_COPY_AND_ASSIGN(BluetoothDefaultView); 59}; 60 61class BluetoothDetailedView : public TrayDetailsView, 62 public ViewClickListener, 63 public views::ButtonListener { 64 public: 65 explicit BluetoothDetailedView(user::LoginStatus login) 66 : login_(login), 67 add_device_(NULL), 68 toggle_bluetooth_(NULL) { 69 BluetoothDeviceList list; 70 Shell::GetInstance()->tray_delegate()->GetAvailableBluetoothDevices(&list); 71 Update(list); 72 } 73 74 virtual ~BluetoothDetailedView() {} 75 76 void Update(const BluetoothDeviceList& list) { 77 Reset(); 78 79 add_device_ = NULL; 80 toggle_bluetooth_ = NULL; 81 82 AppendDeviceList(list); 83 AppendSettingsEntries(); 84 AppendHeaderEntry(); 85 86 Layout(); 87 } 88 89 private: 90 void AppendHeaderEntry() { 91 CreateSpecialRow(IDS_ASH_STATUS_TRAY_BLUETOOTH, this); 92 93 if (login_ == user::LOGGED_IN_LOCKED) 94 return; 95 96 // Do not allow toggling bluetooth in the lock screen. 97 ash::SystemTrayDelegate* delegate = 98 ash::Shell::GetInstance()->tray_delegate(); 99 toggle_bluetooth_ = new TrayPopupHeaderButton(this, 100 IDR_AURA_UBER_TRAY_BLUETOOTH_ENABLED, 101 IDR_AURA_UBER_TRAY_BLUETOOTH_DISABLED, 102 IDR_AURA_UBER_TRAY_BLUETOOTH_ENABLED_HOVER, 103 IDR_AURA_UBER_TRAY_BLUETOOTH_DISABLED_HOVER, 104 IDS_ASH_STATUS_TRAY_BLUETOOTH); 105 toggle_bluetooth_->SetToggled(!delegate->GetBluetoothEnabled()); 106 toggle_bluetooth_->SetTooltipText( 107 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISABLE_BLUETOOTH)); 108 toggle_bluetooth_->SetToggledTooltipText( 109 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ENABLE_BLUETOOTH)); 110 footer()->AddButton(toggle_bluetooth_); 111 } 112 113 void AppendDeviceList(const BluetoothDeviceList& list) { 114 device_map_.clear(); 115 CreateScrollableList(); 116 117 for (size_t i = 0; i < list.size(); i++) { 118 HoverHighlightView* container = 119 AddScrollListItem(list[i].display_name, 120 list[i].connected ? gfx::Font::BOLD : gfx::Font::NORMAL, 121 list[i].connected); 122 device_map_[container] = list[i].address; 123 } 124 125 // Show user Bluetooth state if there is no bluetooth devices in list. 126 if (list.size() == 0) { 127 ash::SystemTrayDelegate* delegate = 128 ash::Shell::GetInstance()->tray_delegate(); 129 int message_id; 130 if (delegate->GetBluetoothAvailable()) { 131 if (!delegate->GetBluetoothEnabled()) 132 message_id = IDS_ASH_STATUS_TRAY_BLUETOOTH_TURNED_OFF; 133 else if (delegate->IsBluetoothDiscovering()) 134 message_id = IDS_ASH_STATUS_TRAY_BLUETOOTH_DISCOVERING; 135 else 136 message_id = IDS_ASH_STATUS_TRAY_BLUETOOTH_NO_DEVICE; 137 AddScrollListItem(l10n_util::GetStringUTF16(message_id), 138 gfx::Font::NORMAL, false); 139 } 140 } 141 } 142 143 HoverHighlightView* AddScrollListItem(const string16& text, 144 gfx::Font::FontStyle style, 145 bool checked) { 146 HoverHighlightView* container = new HoverHighlightView(this); 147 container->set_fixed_height(kTrayPopupItemHeight); 148 container->AddCheckableLabel(text, style, checked); 149 scroll_content()->AddChildView(container); 150 return container; 151 } 152 153 // Add settings entries. 154 void AppendSettingsEntries() { 155 // Add bluetooth device requires a browser window, hide it for non logged in 156 // user. 157 if (login_ == user::LOGGED_IN_NONE || 158 login_ == user::LOGGED_IN_LOCKED) 159 return; 160 161 ash::SystemTrayDelegate* delegate = 162 ash::Shell::GetInstance()->tray_delegate(); 163 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 164 HoverHighlightView* container = new HoverHighlightView(this); 165 container->set_fixed_height(kTrayPopupItemHeight); 166 container->AddLabel(rb.GetLocalizedString( 167 IDS_ASH_STATUS_TRAY_BLUETOOTH_ADD_DEVICE), gfx::Font::NORMAL); 168 container->SetEnabled(delegate->GetBluetoothAvailable()); 169 AddChildView(container); 170 add_device_ = container; 171 } 172 173 // Overridden from ViewClickListener. 174 virtual void ClickedOn(views::View* sender) OVERRIDE { 175 ash::SystemTrayDelegate* delegate = 176 ash::Shell::GetInstance()->tray_delegate(); 177 if (sender == footer()->content()) { 178 Shell::GetInstance()->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING); 179 } else if (sender == add_device_) { 180 if (!delegate->GetBluetoothEnabled()) 181 delegate->ToggleBluetooth(); 182 delegate->AddBluetoothDevice(); 183 } else { 184 std::map<views::View*, std::string>::iterator find; 185 find = device_map_.find(sender); 186 if (find != device_map_.end()) { 187 std::string device_id = find->second; 188 delegate->ToggleBluetoothConnection(device_id); 189 } 190 } 191 } 192 193 // Overridden from ButtonListener. 194 virtual void ButtonPressed(views::Button* sender, 195 const ui::Event& event) OVERRIDE { 196 ash::SystemTrayDelegate* delegate = 197 ash::Shell::GetInstance()->tray_delegate(); 198 if (sender == toggle_bluetooth_) 199 delegate->ToggleBluetooth(); 200 else 201 NOTREACHED(); 202 } 203 204 user::LoginStatus login_; 205 206 std::map<views::View*, std::string> device_map_; 207 views::View* add_device_; 208 TrayPopupHeaderButton* toggle_bluetooth_; 209 views::View* settings_; 210 211 DISALLOW_COPY_AND_ASSIGN(BluetoothDetailedView); 212}; 213 214} // namespace tray 215 216TrayBluetooth::TrayBluetooth() 217 : default_(NULL), 218 detailed_(NULL) { 219} 220 221TrayBluetooth::~TrayBluetooth() { 222} 223 224views::View* TrayBluetooth::CreateTrayView(user::LoginStatus status) { 225 return NULL; 226} 227 228views::View* TrayBluetooth::CreateDefaultView(user::LoginStatus status) { 229 CHECK(default_ == NULL); 230 default_ = new tray::BluetoothDefaultView(this); 231 return default_; 232} 233 234views::View* TrayBluetooth::CreateDetailedView(user::LoginStatus status) { 235 if (!Shell::GetInstance()->tray_delegate()->GetBluetoothAvailable()) 236 return NULL; 237 CHECK(detailed_ == NULL); 238 detailed_ = new tray::BluetoothDetailedView(status); 239 return detailed_; 240} 241 242void TrayBluetooth::DestroyTrayView() { 243} 244 245void TrayBluetooth::DestroyDefaultView() { 246 default_ = NULL; 247} 248 249void TrayBluetooth::DestroyDetailedView() { 250 detailed_ = NULL; 251} 252 253void TrayBluetooth::UpdateAfterLoginStatusChange(user::LoginStatus status) { 254} 255 256void TrayBluetooth::OnBluetoothRefresh() { 257 BluetoothDeviceList list; 258 Shell::GetInstance()->tray_delegate()->GetAvailableBluetoothDevices(&list); 259 if (default_) 260 default_->UpdateLabel(); 261 else if (detailed_) 262 detailed_->Update(list); 263} 264 265void TrayBluetooth::OnBluetoothDiscoveringChanged() { 266 if (!detailed_) 267 return; 268 BluetoothDeviceList list; 269 Shell::GetInstance()->tray_delegate()->GetAvailableBluetoothDevices(&list); 270 detailed_->Update(list); 271} 272 273} // namespace internal 274} // namespace ash 275