Chromium Code Reviews| Index: ash/system/network/tray_network.cc |
| diff --git a/ash/system/network/tray_network.cc b/ash/system/network/tray_network.cc |
| index 95e588ea584402e113d41cd5a3003f7c0b09cf22..4b07c2012af1c9b5f98aeb5b9d7f2cf4b9712963 100644 |
| --- a/ash/system/network/tray_network.cc |
| +++ b/ash/system/network/tray_network.cc |
| @@ -23,16 +23,19 @@ |
| #include "ui/gfx/font.h" |
| #include "ui/gfx/image/image.h" |
| #include "ui/gfx/skia_util.h" |
| +#include "ui/views/bubble/bubble_border.h" |
| +#include "ui/views/bubble/bubble_delegate.h" |
| #include "ui/views/controls/button/button.h" |
| #include "ui/views/controls/button/image_button.h" |
| #include "ui/views/controls/image_view.h" |
| #include "ui/views/controls/label.h" |
| +#include "ui/views/controls/link.h" |
| +#include "ui/views/controls/link_listener.h" |
| #include "ui/views/controls/scroll_view.h" |
| -#include "ui/views/layout/fill_layout.h" |
| #include "ui/views/layout/box_layout.h" |
| +#include "ui/views/layout/fill_layout.h" |
| +#include "ui/views/layout/grid_layout.h" |
| #include "ui/views/view.h" |
| -#include "ui/views/bubble/bubble_border.h" |
| -#include "ui/views/bubble/bubble_delegate.h" |
| #include "ui/views/widget/widget.h" |
| namespace { |
| @@ -95,6 +98,32 @@ enum ColorTheme { |
| DARK, |
| }; |
| +class NetworkErrors { |
| + public: |
| + struct Message { |
| + Message() : delegate(NULL) {} |
| + Message(NetworkTrayDelegate* in_delegate, |
| + const string16& in_title, |
| + const string16& in_message, |
| + const string16& in_link_text) : |
| + delegate(in_delegate), |
| + title(in_title), |
| + message(in_message), |
| + link_text(in_link_text) {} |
| + NetworkTrayDelegate* delegate; |
| + string16 title; |
| + string16 message; |
| + string16 link_text; |
| + }; |
| + typedef std::map<TrayNetwork::ErrorType, Message> ErrorMap; |
| + |
| + ErrorMap& messages() { return messages_; } |
| + const ErrorMap& messages() const { return messages_; } |
| + |
| + private: |
| + ErrorMap messages_; |
| +}; |
| + |
| class NetworkTrayView : public TrayItemView { |
| public: |
| NetworkTrayView(ColorTheme size, bool tray_icon) |
| @@ -517,12 +546,154 @@ class NetworkDetailedView : public TrayDetailsView, |
| DISALLOW_COPY_AND_ASSIGN(NetworkDetailedView); |
| }; |
| +class NetworkErrorView : public views::View, |
| + public views::LinkListener { |
| + public: |
| + NetworkErrorView(TrayNetwork* tray, |
| + TrayNetwork::ErrorType error_type, |
| + const NetworkErrors::Message& error) |
| + : tray_(tray), |
| + error_type_(error_type) { |
| + set_border(views::Border::CreateEmptyBorder( |
| + kTrayPopupPaddingBetweenItems, kTrayPopupPaddingHorizontal, |
| + kTrayPopupPaddingBetweenItems, kTrayPopupPaddingHorizontal)); |
| + |
| + const int msg_width = kTrayPopupWidth - kNotificationCloseButtonWidth - |
| + kTrayPopupPaddingHorizontal - kNotificationIconWidth; |
| + |
| + views::ImageView* icon = new views::ImageView; |
| + icon->SetImage(ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| + GetErrorIcon(error_type))); |
| + |
| + int num_rows = 0; |
| + views::Label* title = new views::Label(error.title); |
| + title->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| + title->SetFont(title->font().DeriveFont(0, gfx::Font::BOLD)); |
| + ++num_rows; |
| + |
| + views::Label* message = new views::Label(error.message); |
| + message->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| + message->SetMultiLine(true); |
| + message->SizeToFit(msg_width); |
| + ++num_rows; |
| + |
| + views::Link* link = NULL; |
| + if (!error.link_text.empty()) { |
| + link = new views::Link(error.link_text); |
| + link->set_listener(this); |
| + link->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
| + link->SetMultiLine(true); |
| + link->SizeToFit(msg_width); |
| + ++num_rows; |
| + } |
| + |
| + views::GridLayout* layout = new views::GridLayout(this); |
| + SetLayoutManager(layout); |
| + |
| + views::ColumnSet* columns = layout->AddColumnSet(0); |
| + |
| + // Icon |
| + columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, |
| + 0 /* resize percent */, |
| + views::GridLayout::FIXED, |
| + kNotificationIconWidth, kNotificationIconWidth); |
| + |
| + columns->AddPaddingColumn(0, kTrayPopupPaddingHorizontal/2); |
| + |
| + // Title + message + link |
| + columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, |
| + 0 /* resize percent */, |
| + views::GridLayout::FIXED, msg_width, msg_width); |
| + |
| + // Layout rows |
| + layout->AddPaddingRow(0, kTrayPopupPaddingBetweenItems); |
| + |
| + layout->StartRow(0, 0); |
| + layout->AddView(icon, 1, num_rows); |
| + layout->AddView(title); |
| + |
| + layout->StartRow(0, 0); |
| + layout->SkipColumns(1); |
| + layout->AddView(message); |
| + |
| + if (link) { |
| + layout->StartRow(0, 0); |
| + layout->SkipColumns(1); |
| + layout->AddView(link); |
| + } |
| + |
| + layout->AddPaddingRow(0, kTrayPopupPaddingBetweenItems); |
| + |
| + } |
| + |
| + virtual ~NetworkErrorView() { |
| + } |
| + |
| + 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.
|
| + tray_->LinkClicked(error_type_); |
| + } |
| + |
| + TrayNetwork::ErrorType error_type() const { return error_type_; } |
| + |
| + private: |
| + int GetErrorIcon(TrayNetwork::ErrorType error_type) { |
| + switch(error_type) { |
| + case TrayNetwork::ERROR_CONNECT_FAILED: |
| + return IDR_AURA_UBER_TRAY_NETWORK_FAILED; |
| + case TrayNetwork::ERROR_DATA_LOW: |
| + return IDR_AURA_UBER_TRAY_NETWORK_DATA_LOW; |
| + case TrayNetwork::ERROR_DATA_NONE: |
| + return IDR_AURA_UBER_TRAY_NETWORK_DATA_NONE; |
| + } |
| + NOTREACHED(); |
| + return 0; |
| + } |
| + |
| + TrayNetwork* tray_; |
| + TrayNetwork::ErrorType error_type_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(NetworkErrorView); |
| +}; |
| + |
| +class NetworkNotificationView : public TrayNotificationView { |
| + public: |
| + explicit NetworkNotificationView(TrayNetwork* tray) |
| + : tray_(tray) { |
| + CHECK(!tray->errors()->messages().empty()); |
| + // Display the first (highest priority) error. |
| + NetworkErrors::ErrorMap::const_iterator iter = |
| + tray->errors()->messages().begin(); |
| + network_error_view_ = |
| + new NetworkErrorView(tray, iter->first, iter->second); |
| + InitView(network_error_view_); |
| + } |
| + |
| + // Overridden from TrayNotificationView: |
| + virtual void OnClose() OVERRIDE { |
| + tray_->ClearNetworkError(network_error_view_->error_type()); |
| + } |
| + |
| + // Overridden from views::View. |
| + bool OnMousePressed(const views::MouseEvent& event) { |
|
sadrul
2012/05/22 19:05:17
+virtual, +OVERRIDE
stevenjb
2012/05/22 22:39:00
Done.
|
| + tray_->PopupDetailedView(0, true); |
| + return true; |
| + } |
| + |
| + private: |
| + TrayNetwork* tray_; |
| + tray::NetworkErrorView* network_error_view_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(NetworkNotificationView); |
| +}; |
| + |
| } // namespace tray |
| TrayNetwork::TrayNetwork() |
| : tray_(NULL), |
| default_(NULL), |
| - detailed_(NULL) { |
| + detailed_(NULL), |
| + notification_(NULL), |
| + errors_(new tray::NetworkErrors()) { |
| } |
| TrayNetwork::~TrayNetwork() { |
| @@ -546,6 +717,12 @@ views::View* TrayNetwork::CreateDetailedView(user::LoginStatus status) { |
| return detailed_; |
| } |
| +views::View* TrayNetwork::CreateNotificationView(user::LoginStatus status) { |
| + CHECK(notification_ == NULL); |
| + notification_ = new tray::NetworkNotificationView(this); |
| + return notification_; |
| +} |
| + |
| void TrayNetwork::DestroyTrayView() { |
| tray_ = NULL; |
| } |
| @@ -558,6 +735,10 @@ void TrayNetwork::DestroyDetailedView() { |
| detailed_ = NULL; |
| } |
| +void TrayNetwork::DestroyNotificationView() { |
| + notification_ = NULL; |
| +} |
| + |
| void TrayNetwork::UpdateAfterLoginStatusChange(user::LoginStatus status) { |
| } |
| @@ -570,5 +751,30 @@ void TrayNetwork::OnNetworkRefresh(const NetworkIconInfo& info) { |
| detailed_->Update(); |
| } |
| +void TrayNetwork::SetNetworkError(NetworkTrayDelegate* delegate, |
| + ErrorType error_type, |
| + const string16& title, |
| + const string16& message, |
| + const string16& link_text) { |
| + errors_->messages()[error_type] = |
| + tray::NetworkErrors::Message(delegate, title, message, link_text); |
| + HideNotificationView(); |
| + 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
|
| +} |
| + |
| +void TrayNetwork::ClearNetworkError(ErrorType error_type) { |
| + errors_->messages().erase(error_type); |
| + HideNotificationView(); |
| + 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.
|
| + ShowNotificationView(); |
| +} |
| + |
| +void TrayNetwork::LinkClicked(ErrorType error_type) { |
| + tray::NetworkErrors::ErrorMap::const_iterator iter = |
| + errors()->messages().find(error_type); |
| + if (iter != errors()->messages().end() && iter->second.delegate) |
| + iter->second.delegate->NotificationLinkClicked(); |
| +} |
| + |
| } // namespace internal |
| } // namespace ash |