Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "ash/system/network/tray_network.h" | 5 #include "ash/system/network/tray_network.h" |
| 6 | 6 |
| 7 #include "ash/shell.h" | 7 #include "ash/shell.h" |
| 8 #include "ash/shell_window_ids.h" | 8 #include "ash/shell_window_ids.h" |
| 9 #include "ash/system/tray/system_tray.h" | 9 #include "ash/system/tray/system_tray.h" |
| 10 #include "ash/system/tray/system_tray_delegate.h" | 10 #include "ash/system/tray/system_tray_delegate.h" |
| 11 #include "ash/system/tray/tray_constants.h" | 11 #include "ash/system/tray/tray_constants.h" |
| 12 #include "ash/system/tray/tray_details_view.h" | 12 #include "ash/system/tray/tray_details_view.h" |
| 13 #include "ash/system/tray/tray_item_more.h" | 13 #include "ash/system/tray/tray_item_more.h" |
| 14 #include "ash/system/tray/tray_item_view.h" | 14 #include "ash/system/tray/tray_item_view.h" |
| 15 #include "ash/system/tray/tray_views.h" | 15 #include "ash/system/tray/tray_views.h" |
| 16 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
| 17 #include "grit/ash_strings.h" | 17 #include "grit/ash_strings.h" |
| 18 #include "grit/ui_resources.h" | 18 #include "grit/ui_resources.h" |
| 19 #include "third_party/skia/include/core/SkColor.h" | 19 #include "third_party/skia/include/core/SkColor.h" |
| 20 #include "ui/aura/window.h" | 20 #include "ui/aura/window.h" |
| 21 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
| 22 #include "ui/gfx/canvas.h" | 22 #include "ui/gfx/canvas.h" |
| 23 #include "ui/gfx/font.h" | 23 #include "ui/gfx/font.h" |
| 24 #include "ui/gfx/image/image.h" | 24 #include "ui/gfx/image/image.h" |
| 25 #include "ui/gfx/skia_util.h" | 25 #include "ui/gfx/skia_util.h" |
| 26 #include "ui/views/bubble/bubble_border.h" | |
| 27 #include "ui/views/bubble/bubble_delegate.h" | |
| 26 #include "ui/views/controls/button/button.h" | 28 #include "ui/views/controls/button/button.h" |
| 27 #include "ui/views/controls/button/image_button.h" | 29 #include "ui/views/controls/button/image_button.h" |
| 28 #include "ui/views/controls/image_view.h" | 30 #include "ui/views/controls/image_view.h" |
| 29 #include "ui/views/controls/label.h" | 31 #include "ui/views/controls/label.h" |
| 32 #include "ui/views/controls/link.h" | |
| 33 #include "ui/views/controls/link_listener.h" | |
| 30 #include "ui/views/controls/scroll_view.h" | 34 #include "ui/views/controls/scroll_view.h" |
| 35 #include "ui/views/layout/box_layout.h" | |
| 31 #include "ui/views/layout/fill_layout.h" | 36 #include "ui/views/layout/fill_layout.h" |
| 32 #include "ui/views/layout/box_layout.h" | 37 #include "ui/views/layout/grid_layout.h" |
| 33 #include "ui/views/view.h" | 38 #include "ui/views/view.h" |
| 34 #include "ui/views/bubble/bubble_border.h" | |
| 35 #include "ui/views/bubble/bubble_delegate.h" | |
| 36 #include "ui/views/widget/widget.h" | 39 #include "ui/views/widget/widget.h" |
| 37 | 40 |
| 38 namespace { | 41 namespace { |
| 39 | 42 |
| 40 // Height of the list of networks in the popup. | 43 // Height of the list of networks in the popup. |
| 41 const int kNetworkListHeight = 203; | 44 const int kNetworkListHeight = 203; |
| 42 | 45 |
| 43 // Create a label with the font size and color used in the network info bubble. | 46 // Create a label with the font size and color used in the network info bubble. |
| 44 views::Label* CreateInfoBubbleLabel(const string16& text) { | 47 views::Label* CreateInfoBubbleLabel(const string16& text) { |
| 45 const SkColor text_color = SkColorSetARGB(127, 0, 0, 0); | 48 const SkColor text_color = SkColorSetARGB(127, 0, 0, 0); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 88 namespace ash { | 91 namespace ash { |
| 89 namespace internal { | 92 namespace internal { |
| 90 | 93 |
| 91 namespace tray { | 94 namespace tray { |
| 92 | 95 |
| 93 enum ColorTheme { | 96 enum ColorTheme { |
| 94 LIGHT, | 97 LIGHT, |
| 95 DARK, | 98 DARK, |
| 96 }; | 99 }; |
| 97 | 100 |
| 101 class NetworkErrors { | |
| 102 public: | |
| 103 struct Message { | |
| 104 Message() : delegate(NULL) {} | |
| 105 Message(NetworkTrayDelegate* in_delegate, | |
| 106 const string16& in_title, | |
| 107 const string16& in_message, | |
| 108 const string16& in_link_text) : | |
| 109 delegate(in_delegate), | |
| 110 title(in_title), | |
| 111 message(in_message), | |
| 112 link_text(in_link_text) {} | |
| 113 NetworkTrayDelegate* delegate; | |
| 114 string16 title; | |
| 115 string16 message; | |
| 116 string16 link_text; | |
| 117 }; | |
| 118 typedef std::map<TrayNetwork::ErrorType, Message> ErrorMap; | |
| 119 | |
| 120 ErrorMap& messages() { return messages_; } | |
| 121 const ErrorMap& messages() const { return messages_; } | |
| 122 | |
| 123 private: | |
| 124 ErrorMap messages_; | |
| 125 }; | |
| 126 | |
| 98 class NetworkTrayView : public TrayItemView { | 127 class NetworkTrayView : public TrayItemView { |
| 99 public: | 128 public: |
| 100 NetworkTrayView(ColorTheme size, bool tray_icon) | 129 NetworkTrayView(ColorTheme size, bool tray_icon) |
| 101 : color_theme_(size), tray_icon_(tray_icon) { | 130 : color_theme_(size), tray_icon_(tray_icon) { |
| 102 SetLayoutManager(new views::FillLayout()); | 131 SetLayoutManager(new views::FillLayout()); |
| 103 | 132 |
| 104 image_view_ = color_theme_ == DARK ? | 133 image_view_ = color_theme_ == DARK ? |
| 105 new FixedSizedImageView(0, kTrayPopupItemHeight) : | 134 new FixedSizedImageView(0, kTrayPopupItemHeight) : |
| 106 new views::ImageView; | 135 new views::ImageView; |
| 107 AddChildView(image_view_); | 136 AddChildView(image_view_); |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 510 TrayPopupTextButton* other_wifi_; | 539 TrayPopupTextButton* other_wifi_; |
| 511 TrayPopupTextButton* other_mobile_; | 540 TrayPopupTextButton* other_mobile_; |
| 512 TrayPopupTextButton* settings_; | 541 TrayPopupTextButton* settings_; |
| 513 TrayPopupTextButton* proxy_settings_; | 542 TrayPopupTextButton* proxy_settings_; |
| 514 | 543 |
| 515 views::BubbleDelegateView* info_bubble_; | 544 views::BubbleDelegateView* info_bubble_; |
| 516 | 545 |
| 517 DISALLOW_COPY_AND_ASSIGN(NetworkDetailedView); | 546 DISALLOW_COPY_AND_ASSIGN(NetworkDetailedView); |
| 518 }; | 547 }; |
| 519 | 548 |
| 549 class NetworkErrorView : public views::View, | |
| 550 public views::LinkListener { | |
| 551 public: | |
| 552 NetworkErrorView(TrayNetwork* tray, | |
| 553 TrayNetwork::ErrorType error_type, | |
| 554 const NetworkErrors::Message& error) | |
| 555 : tray_(tray), | |
| 556 error_type_(error_type) { | |
| 557 set_border(views::Border::CreateEmptyBorder( | |
| 558 kTrayPopupPaddingBetweenItems, kTrayPopupPaddingHorizontal, | |
| 559 kTrayPopupPaddingBetweenItems, kTrayPopupPaddingHorizontal)); | |
| 560 | |
| 561 const int msg_width = kTrayPopupWidth - kNotificationCloseButtonWidth - | |
| 562 kTrayPopupPaddingHorizontal - kNotificationIconWidth; | |
| 563 | |
| 564 views::ImageView* icon = new views::ImageView; | |
| 565 icon->SetImage(ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | |
| 566 GetErrorIcon(error_type))); | |
| 567 | |
| 568 int num_rows = 0; | |
| 569 views::Label* title = new views::Label(error.title); | |
| 570 title->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | |
| 571 title->SetFont(title->font().DeriveFont(0, gfx::Font::BOLD)); | |
| 572 ++num_rows; | |
| 573 | |
| 574 views::Label* message = new views::Label(error.message); | |
| 575 message->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | |
| 576 message->SetMultiLine(true); | |
| 577 message->SizeToFit(msg_width); | |
| 578 ++num_rows; | |
| 579 | |
| 580 views::Link* link = NULL; | |
| 581 if (!error.link_text.empty()) { | |
| 582 link = new views::Link(error.link_text); | |
| 583 link->set_listener(this); | |
| 584 link->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | |
| 585 link->SetMultiLine(true); | |
| 586 link->SizeToFit(msg_width); | |
| 587 ++num_rows; | |
| 588 } | |
| 589 | |
| 590 views::GridLayout* layout = new views::GridLayout(this); | |
| 591 SetLayoutManager(layout); | |
| 592 | |
| 593 views::ColumnSet* columns = layout->AddColumnSet(0); | |
| 594 | |
| 595 // Icon | |
| 596 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, | |
| 597 0 /* resize percent */, | |
| 598 views::GridLayout::FIXED, | |
| 599 kNotificationIconWidth, kNotificationIconWidth); | |
| 600 | |
| 601 columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2); | |
| 602 | |
| 603 // Title + message + link | |
| 604 columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, | |
| 605 0 /* resize percent */, | |
| 606 views::GridLayout::FIXED, msg_width, msg_width); | |
| 607 | |
| 608 // Layout rows | |
| 609 layout->AddPaddingRow(0, kTrayPopupPaddingBetweenItems); | |
| 610 | |
| 611 layout->StartRow(0, 0); | |
| 612 layout->AddView(icon, 1, num_rows); | |
| 613 layout->AddView(title); | |
| 614 | |
| 615 layout->StartRow(0, 0); | |
| 616 layout->SkipColumns(1); | |
| 617 layout->AddView(message); | |
| 618 | |
| 619 if (link) { | |
| 620 layout->StartRow(0, 0); | |
| 621 layout->SkipColumns(1); | |
| 622 layout->AddView(link); | |
| 623 } | |
| 624 | |
| 625 layout->AddPaddingRow(0, kTrayPopupPaddingBetweenItems); | |
| 626 | |
| 627 } | |
| 628 | |
| 629 virtual ~NetworkErrorView() { | |
| 630 } | |
| 631 | |
| 632 void LinkClicked(views::Link* source, int event_flags) { | |
|
sadrul
2012/05/22 19:05:17
This is overridden from views::LinkListener, right
stevenjb
2012/05/22 22:39:00
Done.
| |
| 633 tray_->LinkClicked(error_type_); | |
| 634 } | |
| 635 | |
| 636 TrayNetwork::ErrorType error_type() const { return error_type_; } | |
| 637 | |
| 638 private: | |
| 639 int GetErrorIcon(TrayNetwork::ErrorType error_type) { | |
| 640 switch(error_type) { | |
| 641 case TrayNetwork::ERROR_CONNECT_FAILED: | |
| 642 return IDR_AURA_UBER_TRAY_NETWORK_FAILED; | |
| 643 case TrayNetwork::ERROR_DATA_LOW: | |
| 644 return IDR_AURA_UBER_TRAY_NETWORK_DATA_LOW; | |
| 645 case TrayNetwork::ERROR_DATA_NONE: | |
| 646 return IDR_AURA_UBER_TRAY_NETWORK_DATA_NONE; | |
| 647 } | |
| 648 NOTREACHED(); | |
| 649 return 0; | |
| 650 } | |
| 651 | |
| 652 TrayNetwork* tray_; | |
| 653 TrayNetwork::ErrorType error_type_; | |
| 654 | |
| 655 DISALLOW_COPY_AND_ASSIGN(NetworkErrorView); | |
| 656 }; | |
| 657 | |
| 658 class NetworkNotificationView : public TrayNotificationView { | |
| 659 public: | |
| 660 explicit NetworkNotificationView(TrayNetwork* tray) | |
| 661 : tray_(tray) { | |
| 662 CHECK(!tray->errors()->messages().empty()); | |
| 663 // Display the first (highest priority) error. | |
| 664 NetworkErrors::ErrorMap::const_iterator iter = | |
| 665 tray->errors()->messages().begin(); | |
| 666 network_error_view_ = | |
| 667 new NetworkErrorView(tray, iter->first, iter->second); | |
| 668 InitView(network_error_view_); | |
| 669 } | |
| 670 | |
| 671 // Overridden from TrayNotificationView: | |
| 672 virtual void OnClose() OVERRIDE { | |
| 673 tray_->ClearNetworkError(network_error_view_->error_type()); | |
| 674 } | |
| 675 | |
| 676 // Overridden from views::View. | |
| 677 bool OnMousePressed(const views::MouseEvent& event) { | |
|
sadrul
2012/05/22 19:05:17
+virtual, +OVERRIDE
stevenjb
2012/05/22 22:39:00
Done.
| |
| 678 tray_->PopupDetailedView(0, true); | |
| 679 return true; | |
| 680 } | |
| 681 | |
| 682 private: | |
| 683 TrayNetwork* tray_; | |
| 684 tray::NetworkErrorView* network_error_view_; | |
| 685 | |
| 686 DISALLOW_COPY_AND_ASSIGN(NetworkNotificationView); | |
| 687 }; | |
| 688 | |
| 520 } // namespace tray | 689 } // namespace tray |
| 521 | 690 |
| 522 TrayNetwork::TrayNetwork() | 691 TrayNetwork::TrayNetwork() |
| 523 : tray_(NULL), | 692 : tray_(NULL), |
| 524 default_(NULL), | 693 default_(NULL), |
| 525 detailed_(NULL) { | 694 detailed_(NULL), |
| 695 notification_(NULL), | |
| 696 errors_(new tray::NetworkErrors()) { | |
| 526 } | 697 } |
| 527 | 698 |
| 528 TrayNetwork::~TrayNetwork() { | 699 TrayNetwork::~TrayNetwork() { |
| 529 } | 700 } |
| 530 | 701 |
| 531 views::View* TrayNetwork::CreateTrayView(user::LoginStatus status) { | 702 views::View* TrayNetwork::CreateTrayView(user::LoginStatus status) { |
| 532 CHECK(tray_ == NULL); | 703 CHECK(tray_ == NULL); |
| 533 tray_ = new tray::NetworkTrayView(tray::LIGHT, true /*tray_icon*/); | 704 tray_ = new tray::NetworkTrayView(tray::LIGHT, true /*tray_icon*/); |
| 534 return tray_; | 705 return tray_; |
| 535 } | 706 } |
| 536 | 707 |
| 537 views::View* TrayNetwork::CreateDefaultView(user::LoginStatus status) { | 708 views::View* TrayNetwork::CreateDefaultView(user::LoginStatus status) { |
| 538 CHECK(default_ == NULL); | 709 CHECK(default_ == NULL); |
| 539 default_ = new tray::NetworkDefaultView(this); | 710 default_ = new tray::NetworkDefaultView(this); |
| 540 return default_; | 711 return default_; |
| 541 } | 712 } |
| 542 | 713 |
| 543 views::View* TrayNetwork::CreateDetailedView(user::LoginStatus status) { | 714 views::View* TrayNetwork::CreateDetailedView(user::LoginStatus status) { |
| 544 CHECK(detailed_ == NULL); | 715 CHECK(detailed_ == NULL); |
| 545 detailed_ = new tray::NetworkDetailedView(status); | 716 detailed_ = new tray::NetworkDetailedView(status); |
| 546 return detailed_; | 717 return detailed_; |
| 547 } | 718 } |
| 548 | 719 |
| 720 views::View* TrayNetwork::CreateNotificationView(user::LoginStatus status) { | |
| 721 CHECK(notification_ == NULL); | |
| 722 notification_ = new tray::NetworkNotificationView(this); | |
| 723 return notification_; | |
| 724 } | |
| 725 | |
| 549 void TrayNetwork::DestroyTrayView() { | 726 void TrayNetwork::DestroyTrayView() { |
| 550 tray_ = NULL; | 727 tray_ = NULL; |
| 551 } | 728 } |
| 552 | 729 |
| 553 void TrayNetwork::DestroyDefaultView() { | 730 void TrayNetwork::DestroyDefaultView() { |
| 554 default_ = NULL; | 731 default_ = NULL; |
| 555 } | 732 } |
| 556 | 733 |
| 557 void TrayNetwork::DestroyDetailedView() { | 734 void TrayNetwork::DestroyDetailedView() { |
| 558 detailed_ = NULL; | 735 detailed_ = NULL; |
| 559 } | 736 } |
| 560 | 737 |
| 738 void TrayNetwork::DestroyNotificationView() { | |
| 739 notification_ = NULL; | |
| 740 } | |
| 741 | |
| 561 void TrayNetwork::UpdateAfterLoginStatusChange(user::LoginStatus status) { | 742 void TrayNetwork::UpdateAfterLoginStatusChange(user::LoginStatus status) { |
| 562 } | 743 } |
| 563 | 744 |
| 564 void TrayNetwork::OnNetworkRefresh(const NetworkIconInfo& info) { | 745 void TrayNetwork::OnNetworkRefresh(const NetworkIconInfo& info) { |
| 565 if (tray_) | 746 if (tray_) |
| 566 tray_->Update(info); | 747 tray_->Update(info); |
| 567 if (default_) | 748 if (default_) |
| 568 default_->Update(); | 749 default_->Update(); |
| 569 if (detailed_) | 750 if (detailed_) |
| 570 detailed_->Update(); | 751 detailed_->Update(); |
| 571 } | 752 } |
| 572 | 753 |
| 754 void TrayNetwork::SetNetworkError(NetworkTrayDelegate* delegate, | |
| 755 ErrorType error_type, | |
| 756 const string16& title, | |
| 757 const string16& message, | |
| 758 const string16& link_text) { | |
| 759 errors_->messages()[error_type] = | |
| 760 tray::NetworkErrors::Message(delegate, title, message, link_text); | |
| 761 HideNotificationView(); | |
| 762 ShowNotificationView(); | |
|
sadrul
2012/05/22 19:05:17
Why do we hide first then show?
stevenjb
2012/05/22 22:39:00
To re-create the view. I added an Update() instead
| |
| 763 } | |
| 764 | |
| 765 void TrayNetwork::ClearNetworkError(ErrorType error_type) { | |
| 766 errors_->messages().erase(error_type); | |
| 767 HideNotificationView(); | |
| 768 if (!errors_->messages().empty()) | |
|
sadrul
2012/05/22 19:05:17
Same here. In both places, TrayNetwork should just
stevenjb
2012/05/22 22:39:00
ditto.
| |
| 769 ShowNotificationView(); | |
| 770 } | |
| 771 | |
| 772 void TrayNetwork::LinkClicked(ErrorType error_type) { | |
| 773 tray::NetworkErrors::ErrorMap::const_iterator iter = | |
| 774 errors()->messages().find(error_type); | |
| 775 if (iter != errors()->messages().end() && iter->second.delegate) | |
| 776 iter->second.delegate->NotificationLinkClicked(); | |
| 777 } | |
| 778 | |
| 573 } // namespace internal | 779 } // namespace internal |
| 574 } // namespace ash | 780 } // namespace ash |
| OLD | NEW |