OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/status/network_menu.h" | 5 #include "chrome/browser/chromeos/status/network_menu.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
12 #include "chrome/browser/chromeos/choose_mobile_network_dialog.h" | 12 #include "chrome/browser/chromeos/choose_mobile_network_dialog.h" |
13 #include "chrome/browser/chromeos/cros/cros_library.h" | 13 #include "chrome/browser/chromeos/cros/cros_library.h" |
14 #include "chrome/browser/chromeos/sim_unlock_dialog_delegate.h" | 14 #include "chrome/browser/chromeos/sim_unlock_dialog_delegate.h" |
15 #include "chrome/browser/ui/browser.h" | 15 #include "chrome/browser/ui/browser.h" |
16 #include "chrome/browser/ui/browser_list.h" | 16 #include "chrome/browser/ui/browser_list.h" |
17 #include "chrome/browser/ui/views/window.h" | 17 #include "chrome/browser/ui/views/window.h" |
18 #include "chrome/common/url_constants.h" | 18 #include "chrome/common/url_constants.h" |
19 #include "grit/generated_resources.h" | 19 #include "grit/generated_resources.h" |
20 #include "grit/theme_resources.h" | 20 #include "grit/theme_resources.h" |
21 #include "net/base/escape.h" | 21 #include "net/base/escape.h" |
22 #include "ui/base/l10n/l10n_util.h" | 22 #include "ui/base/l10n/l10n_util.h" |
23 #include "ui/base/resource/resource_bundle.h" | 23 #include "ui/base/resource/resource_bundle.h" |
24 #include "ui/gfx/canvas_skia.h" | 24 #include "ui/gfx/canvas_skia.h" |
25 #include "ui/gfx/skbitmap_operations.h" | 25 #include "ui/gfx/skbitmap_operations.h" |
26 #include "views/controls/menu/menu_2.h" | 26 #include "views/controls/menu/menu_item_view.h" |
| 27 #include "views/controls/menu/submenu_view.h" |
| 28 #include "views/widget/widget.h" |
27 #include "views/window/window.h" | 29 #include "views/window/window.h" |
28 | 30 |
| 31 using views::MenuItemView; |
| 32 |
29 namespace chromeos { | 33 namespace chromeos { |
30 | 34 |
31 //////////////////////////////////////////////////////////////////////////////// | 35 //////////////////////////////////////////////////////////////////////////////// |
32 // NetworkMenu | 36 // NetworkMenu |
33 | 37 |
34 // static | 38 // static |
35 const int NetworkMenu::kNumBarsImages = 4; | 39 const int NetworkMenu::kNumBarsImages = 4; |
36 | 40 |
37 // NOTE: Use an array rather than just calculating a resource number to avoid | 41 // NOTE: Use an array rather than just calculating a resource number to avoid |
38 // creating implicit ordering dependencies on the resource values. | 42 // creating implicit ordering dependencies on the resource values. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 const int NetworkMenu::kNumAnimatingImages = 10; | 75 const int NetworkMenu::kNumAnimatingImages = 10; |
72 | 76 |
73 // static | 77 // static |
74 SkBitmap NetworkMenu::kAnimatingImages[kNumAnimatingImages]; | 78 SkBitmap NetworkMenu::kAnimatingImages[kNumAnimatingImages]; |
75 | 79 |
76 // static | 80 // static |
77 SkBitmap NetworkMenu::kAnimatingImagesBlack[kNumAnimatingImages]; | 81 SkBitmap NetworkMenu::kAnimatingImagesBlack[kNumAnimatingImages]; |
78 | 82 |
79 NetworkMenu::NetworkMenu() | 83 NetworkMenu::NetworkMenu() |
80 : min_width_(-1) { | 84 : min_width_(-1) { |
81 network_menu_.reset(new views::Menu2(this)); | 85 network_menu_.reset(new views::MenuItemView(this)); |
| 86 network_menu_->set_has_icons(true); |
82 } | 87 } |
83 | 88 |
84 NetworkMenu::~NetworkMenu() { | 89 NetworkMenu::~NetworkMenu() { |
85 } | 90 } |
86 | 91 |
87 bool NetworkMenu::ConnectToNetworkAt(int index, | 92 bool NetworkMenu::ConnectToNetworkAt(int index, |
88 const std::string& passphrase, | 93 const std::string& passphrase, |
89 const std::string& ssid, | 94 const std::string& ssid, |
90 int auto_connect) const { | 95 int auto_connect) const { |
91 int flags = menu_items_[index].flags; | 96 int flags = menu_items_[index].flags; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 } | 146 } |
142 } else if (flags & FLAG_OTHER_WIFI_NETWORK) { | 147 } else if (flags & FLAG_OTHER_WIFI_NETWORK) { |
143 ShowOtherWifi(); | 148 ShowOtherWifi(); |
144 } else if (flags & FLAG_OTHER_CELLULAR_NETWORK) { | 149 } else if (flags & FLAG_OTHER_CELLULAR_NETWORK) { |
145 ShowOtherCellular(); | 150 ShowOtherCellular(); |
146 } | 151 } |
147 return true; | 152 return true; |
148 } | 153 } |
149 | 154 |
150 //////////////////////////////////////////////////////////////////////////////// | 155 //////////////////////////////////////////////////////////////////////////////// |
151 // NetworkMenu, ui::MenuModel implementation: | 156 // NetworkMenu, views::MenuItemView implementation: |
152 | 157 std::wstring NetworkMenu::GetLabel(int id) const { |
153 int NetworkMenu::GetItemCount() const { | 158 DCHECK_LE(0, id); |
154 return static_cast<int>(menu_items_.size()); | 159 DCHECK_GT(static_cast<int>(menu_items_.size()), id); |
| 160 return UTF16ToWide(menu_items_[id].label); |
155 } | 161 } |
156 | 162 |
157 ui::MenuModel::ItemType NetworkMenu::GetTypeAt(int index) const { | 163 const gfx::Font* NetworkMenu::GetLabelFont(int id) const { |
158 return menu_items_[index].type; | 164 return (menu_items_[id].flags & FLAG_ASSOCIATED) ? |
| 165 &ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BoldFont) : |
| 166 &ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont); |
159 } | 167 } |
160 | 168 |
161 string16 NetworkMenu::GetLabelAt(int index) const { | 169 bool NetworkMenu::IsCommandEnabled(int id) const { |
162 return menu_items_[index].label; | 170 if (id < static_cast<int>(menu_items_.size())) |
| 171 return !(menu_items_[id].flags & FLAG_DISABLED); |
| 172 else |
| 173 return false; |
163 } | 174 } |
164 | 175 |
165 const gfx::Font* NetworkMenu::GetLabelFontAt(int index) const { | 176 bool NetworkMenu::IsItemChecked(int id) const { |
166 return (menu_items_[index].flags & FLAG_ASSOCIATED) ? | 177 DCHECK_LE(0, id); |
167 &ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BoldFont) : | 178 DCHECK_GT(static_cast<int>(menu_items_.size()), id); |
168 NULL; | 179 return menu_items_[id].type == ui::MenuModel::TYPE_CHECK; |
169 } | 180 } |
170 | 181 |
171 bool NetworkMenu::IsItemCheckedAt(int index) const { | 182 void NetworkMenu::ExecuteCommand(int id) { |
172 // All ui::MenuModel::TYPE_CHECK menu items are checked. | 183 DCHECK_LE(0, id); |
173 return true; | 184 DCHECK_GT(static_cast<int>(menu_items_.size()), id); |
174 } | |
175 | 185 |
176 bool NetworkMenu::GetIconAt(int index, SkBitmap* icon) { | |
177 if (!menu_items_[index].icon.empty()) { | |
178 *icon = menu_items_[index].icon; | |
179 return true; | |
180 } | |
181 return false; | |
182 } | |
183 | |
184 bool NetworkMenu::IsEnabledAt(int index) const { | |
185 return !(menu_items_[index].flags & FLAG_DISABLED); | |
186 } | |
187 | |
188 void NetworkMenu::ActivatedAt(int index) { | |
189 // When we are refreshing the menu, ignore menu item activation. | 186 // When we are refreshing the menu, ignore menu item activation. |
190 if (refreshing_menu_) | 187 if (refreshing_menu_) |
191 return; | 188 return; |
192 | 189 |
193 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); | 190 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
194 int flags = menu_items_[index].flags; | 191 int flags = menu_items_[id].flags; |
195 if (flags & FLAG_OPTIONS) { | 192 if (flags & FLAG_OPTIONS) { |
196 OpenButtonOptions(); | 193 OpenButtonOptions(); |
197 } else if (flags & FLAG_TOGGLE_ETHERNET) { | 194 } else if (flags & FLAG_TOGGLE_ETHERNET) { |
198 cros->EnableEthernetNetworkDevice(!cros->ethernet_enabled()); | 195 cros->EnableEthernetNetworkDevice(!cros->ethernet_enabled()); |
199 } else if (flags & FLAG_TOGGLE_WIFI) { | 196 } else if (flags & FLAG_TOGGLE_WIFI) { |
200 cros->EnableWifiNetworkDevice(!cros->wifi_enabled()); | 197 cros->EnableWifiNetworkDevice(!cros->wifi_enabled()); |
201 } else if (flags & FLAG_TOGGLE_CELLULAR) { | 198 } else if (flags & FLAG_TOGGLE_CELLULAR) { |
202 const NetworkDevice* cellular = cros->FindCellularDevice(); | 199 const NetworkDevice* cellular = cros->FindCellularDevice(); |
203 if (!cellular) { | 200 if (!cellular) { |
204 LOG(ERROR) << "Not found cellular device, it should be available."; | 201 LOG(ERROR) << "Not found cellular device, it should be available."; |
205 cros->EnableCellularNetworkDevice(!cros->cellular_enabled()); | 202 cros->EnableCellularNetworkDevice(!cros->cellular_enabled()); |
206 } else { | 203 } else { |
207 if (cellular->sim_lock_state() == SIM_UNLOCKED || | 204 if (cellular->sim_lock_state() == SIM_UNLOCKED || |
208 cellular->sim_lock_state() == SIM_UNKNOWN) { | 205 cellular->sim_lock_state() == SIM_UNKNOWN) { |
209 cros->EnableCellularNetworkDevice(!cros->cellular_enabled()); | 206 cros->EnableCellularNetworkDevice(!cros->cellular_enabled()); |
210 } else { | 207 } else { |
211 SimUnlockDialogDelegate::ShowDialog(GetNativeWindow()); | 208 SimUnlockDialogDelegate::ShowDialog(GetNativeWindow()); |
212 } | 209 } |
213 } | 210 } |
214 } else if (flags & FLAG_TOGGLE_OFFLINE) { | 211 } else if (flags & FLAG_TOGGLE_OFFLINE) { |
215 cros->EnableOfflineMode(!cros->offline_mode()); | 212 cros->EnableOfflineMode(!cros->offline_mode()); |
216 } else if (flags & FLAG_ETHERNET) { | 213 } else if (flags & FLAG_ETHERNET) { |
217 if (cros->ethernet_connected()) { | 214 if (cros->ethernet_connected()) { |
218 ShowTabbedNetworkSettings(cros->ethernet_network()); | 215 ShowTabbedNetworkSettings(cros->ethernet_network()); |
219 } | 216 } |
220 } else if (flags & FLAG_WIFI) { | 217 } else if (flags & FLAG_WIFI) { |
221 ConnectToNetworkAt(index, std::string(), std::string(), -1); | 218 ConnectToNetworkAt(id, std::string(), std::string(), -1); |
222 } else if (flags & FLAG_OTHER_WIFI_NETWORK) { | 219 } else if (flags & FLAG_OTHER_WIFI_NETWORK) { |
223 ConnectToNetworkAt(index, std::string(), std::string(), -1); | 220 ConnectToNetworkAt(id, std::string(), std::string(), -1); |
224 } else if (flags & FLAG_CELLULAR) { | 221 } else if (flags & FLAG_CELLULAR) { |
225 ConnectToNetworkAt(index, std::string(), std::string(), -1); | 222 ConnectToNetworkAt(id, std::string(), std::string(), -1); |
226 } else if (flags & FLAG_OTHER_CELLULAR_NETWORK) { | 223 } else if (flags & FLAG_OTHER_CELLULAR_NETWORK) { |
227 ConnectToNetworkAt(index, std::string(), std::string(), -1); | 224 ConnectToNetworkAt(id, std::string(), std::string(), -1); |
228 } | 225 } |
229 } | 226 } |
230 | 227 |
231 void NetworkMenu::SetFirstLevelMenuWidth(int width) { | 228 void NetworkMenu::SetFirstLevelMenuWidth(int width) { |
232 min_width_ = width; | 229 min_width_ = width; |
233 // This actually has no effect since menu is rebuilt before showing. | 230 // This actually has no effect since menu is rebuilt before showing. |
234 network_menu_->SetMinimumWidth(width); | |
235 } | 231 } |
236 | 232 |
237 void NetworkMenu::CancelMenu() { | 233 void NetworkMenu::CancelMenu() { |
238 network_menu_->CancelMenu(); | 234 network_menu_->Cancel(); |
239 } | 235 } |
240 | 236 |
241 void NetworkMenu::UpdateMenu() { | 237 void NetworkMenu::UpdateMenu() { |
242 refreshing_menu_ = true; | 238 refreshing_menu_ = true; |
| 239 |
| 240 // Rebuild list of available networks. |
243 InitMenuItems(); | 241 InitMenuItems(); |
244 network_menu_->Rebuild(); | 242 |
| 243 // Clear and repopulate MenuItemView. |
| 244 network_menu_->CreateSubmenu()->RemoveAllChildViews(true); |
| 245 for (int i = 0, n = menu_items_.size(); i < n; ++i) { |
| 246 if (menu_items_[i].type == ui::MenuModel::TYPE_SEPARATOR) |
| 247 network_menu_->AppendSeparator(); |
| 248 else |
| 249 network_menu_->AppendMenuItemWithIcon( |
| 250 i, |
| 251 UTF16ToWide(menu_items_[i].label), |
| 252 menu_items_[i].icon); |
| 253 } |
| 254 |
| 255 network_menu_->ChildrenChanged(); |
245 refreshing_menu_ = false; | 256 refreshing_menu_ = false; |
246 } | 257 } |
247 | 258 |
248 // static | 259 // static |
249 const SkBitmap* NetworkMenu::IconForNetworkStrength(const WifiNetwork* wifi, | 260 const SkBitmap* NetworkMenu::IconForNetworkStrength(const WifiNetwork* wifi, |
250 bool black) { | 261 bool black) { |
251 DCHECK(wifi); | 262 DCHECK(wifi); |
252 if (wifi->strength() == 0) { | 263 if (wifi->strength() == 0) { |
253 return ResourceBundle::GetSharedInstance().GetBitmapNamed( | 264 return ResourceBundle::GetSharedInstance().GetBitmapNamed( |
254 black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK : | 265 black ? IDR_STATUSBAR_NETWORK_BARS0_BLACK : |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 kBottomRightBadgeY); | 428 kBottomRightBadgeY); |
418 if (top_left_badge != NULL) | 429 if (top_left_badge != NULL) |
419 canvas.DrawBitmapInt(*top_left_badge, kTopLeftBadgeX, kTopLeftBadgeY); | 430 canvas.DrawBitmapInt(*top_left_badge, kTopLeftBadgeX, kTopLeftBadgeY); |
420 return canvas.ExtractBitmap(); | 431 return canvas.ExtractBitmap(); |
421 } | 432 } |
422 | 433 |
423 //////////////////////////////////////////////////////////////////////////////// | 434 //////////////////////////////////////////////////////////////////////////////// |
424 // NetworkMenu, views::ViewMenuDelegate implementation: | 435 // NetworkMenu, views::ViewMenuDelegate implementation: |
425 | 436 |
426 void NetworkMenu::RunMenu(views::View* source, const gfx::Point& pt) { | 437 void NetworkMenu::RunMenu(views::View* source, const gfx::Point& pt) { |
427 refreshing_menu_ = true; | 438 DCHECK_EQ(GetMenuButton(), source); |
| 439 |
428 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); | 440 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
429 cros->RequestNetworkScan(); | 441 cros->RequestNetworkScan(); |
430 | 442 |
431 // Build initial menu items. They will be updated when UpdateMenu is | 443 UpdateMenu(); |
432 // called from NetworkChanged. | |
433 InitMenuItems(); | |
434 network_menu_->Rebuild(); | |
435 | 444 |
436 // Restore menu width, if it was set up. | 445 // TODO(rhashimoto): Remove this workaround when WebUI provides a |
437 // NOTE: width isn't checked for correctness here since all width-related | 446 // top-level widget on the ChromeOS login screen that is a window. |
438 // logic implemented inside |network_menu_|. | 447 // The current BackgroundView class for the ChromeOS login screen |
439 if (min_width_ != -1) | 448 // creates a owning Widget that has a native GtkWindow but is not a |
440 network_menu_->SetMinimumWidth(min_width_); | 449 // Window. This makes it impossible to get the NativeWindow via |
441 refreshing_menu_ = false; | 450 // the views API. This workaround casts the top-level NativeWidget |
442 network_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); | 451 // to a NativeWindow that we can pass to MenuItemView::RunMenuAt(). |
| 452 gfx::NativeWindow window; |
| 453 if (source->GetWindow()) |
| 454 window = source->GetWindow()->GetNativeWindow(); |
| 455 else |
| 456 window = GTK_WINDOW(source->GetWidget()->GetNativeView()); |
| 457 |
| 458 gfx::Point screen_loc; |
| 459 views::View::ConvertPointToScreen(source, &screen_loc); |
| 460 gfx::Rect bounds(screen_loc, source->size()); |
| 461 network_menu_->RunMenuAt( |
| 462 window, |
| 463 GetMenuButton(), |
| 464 bounds, |
| 465 base::i18n::IsRTL() ? MenuItemView::TOPLEFT : MenuItemView::TOPRIGHT, |
| 466 true); |
443 } | 467 } |
444 | 468 |
445 void NetworkMenu::InitMenuItems() { | 469 void NetworkMenu::InitMenuItems() { |
446 // This gets called on initialization, so any changes should be reflected | 470 // This gets called on initialization, so any changes should be reflected |
447 // in CrosMock::SetNetworkLibraryStatusAreaExpectations(). | 471 // in CrosMock::SetNetworkLibraryStatusAreaExpectations(). |
448 | 472 |
449 menu_items_.clear(); | 473 menu_items_.clear(); |
450 // Populate our MenuItems with the current list of wifi networks. | 474 // Populate our MenuItems with the current list of wifi networks. |
451 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); | 475 NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary(); |
452 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 476 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 | 772 |
749 void NetworkMenu::ShowOtherWifi() const { | 773 void NetworkMenu::ShowOtherWifi() const { |
750 ShowNetworkConfigView(new NetworkConfigView()); | 774 ShowNetworkConfigView(new NetworkConfigView()); |
751 } | 775 } |
752 | 776 |
753 void NetworkMenu::ShowOtherCellular() const { | 777 void NetworkMenu::ShowOtherCellular() const { |
754 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow()); | 778 ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow()); |
755 } | 779 } |
756 | 780 |
757 } // namespace chromeos | 781 } // namespace chromeos |
OLD | NEW |