Index: ui/chromeos/network/network_list_md.cc |
diff --git a/ui/chromeos/network/network_list.cc b/ui/chromeos/network/network_list_md.cc |
similarity index 53% |
copy from ui/chromeos/network/network_list.cc |
copy to ui/chromeos/network/network_list_md.cc |
index 960cd8c932975ed8e26beb9254131f990d31863f..bb0a418dadb0a9d69874eeee47fd1869fe1a7cfe 100644 |
--- a/ui/chromeos/network/network_list.cc |
+++ b/ui/chromeos/network/network_list_md.cc |
@@ -2,7 +2,7 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "ui/chromeos/network/network_list.h" |
+#include "ui/chromeos/network/network_list_md.h" |
#include <stddef.h> |
@@ -24,7 +24,13 @@ |
#include "ui/chromeos/network/network_info.h" |
#include "ui/chromeos/network/network_list_delegate.h" |
#include "ui/gfx/font.h" |
+#include "ui/gfx/paint_vector_icon.h" |
+#include "ui/gfx/vector_icons_public.h" |
+#include "ui/views/border.h" |
+#include "ui/views/controls/button/image_button.h" |
+#include "ui/views/controls/button/toggle_button.h" |
#include "ui/views/controls/label.h" |
+#include "ui/views/layout/box_layout.h" |
#include "ui/views/view.h" |
using chromeos::LoginState; |
@@ -37,6 +43,10 @@ namespace ui { |
namespace { |
+const int kWiFiRowHeight = 48; |
+const int kWiFiIconSize = 10; |
+const SkColor kWifiRowSeparatorColor = SkColorSetA(SK_ColorBLACK, .12f * 0xFF); |
+ |
bool IsProhibitedByPolicy(const chromeos::NetworkState* network) { |
if (!NetworkTypePattern::WiFi().MatchesType(network->type())) |
return false; |
@@ -61,31 +71,127 @@ bool IsProhibitedByPolicy(const chromeos::NetworkState* network) { |
} // namespace |
-// NetworkListView: |
+class NetworkListViewMd::WiFiHeaderRowView : public views::View { |
+ public: |
+ WiFiHeaderRowView(views::ButtonListener* listener, bool enabled) |
+ : views::View(), |
+ listener_(listener), |
+ enabled_(enabled), |
+ label_(nullptr), |
+ toggle_(nullptr), |
+ join_(nullptr) { |
+ Init(); |
+ } |
+ |
+ ~WiFiHeaderRowView() override {} |
+ |
+ void Init() { |
+ SetBorder(views::Border::CreateSolidSidedBorder(1, 0, 0, 0, |
tdanderson
2016/09/20 14:44:33
Can you add a TODO(tdanderson) to eventually unify
varkha
2016/09/23 00:35:53
Done.
|
+ kWifiRowSeparatorColor)); |
+ views::View* container = new views::View; |
+ container->SetBorder(views::Border::CreateEmptyBorder(4, 18, 4, 10)); |
varkha
2016/09/19 20:19:23
[self review] Need to move those constants above o
varkha
2016/09/23 00:35:53
Done.
|
+ views::BoxLayout* layout1 = |
+ new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0); |
+ SetLayoutManager(layout1); |
+ AddChildView(container); |
+ layout1->SetFlexForView(container, 1); |
+ |
+ views::BoxLayout* layout = |
+ new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 8, 28); |
+ container->SetLayoutManager(layout); |
+ SkColor color = GetNativeTheme()->GetSystemColor( |
+ ui::NativeTheme::kColorId_CallToActionColor); |
+ label_ = new views::Label; |
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
+ base::string16 text = |
+ rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_NETWORK_WIFI); |
+ label_->SetText(text); |
+ label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
+ label_->SetEnabledColor(color); |
+ label_->SetFontList(rb.GetFontList(ui::ResourceBundle::BoldFont)); |
tdanderson
2016/09/20 14:44:33
Try using TrayPopupItemStyle to set the font style
varkha
2016/09/23 00:35:53
I can't - it is in ash and I cannot use ash here.
|
+ container->AddChildView(label_); |
+ layout->SetFlexForView(label_, 1); |
+ |
+ join_ = new views::ImageButton(listener_); |
+ join_image_ = network_icon::GetImageForHeaderWifiNetwork( |
+ SkColorSetA(color, 0xFF / 2)); |
+ join_image_pressed_ = network_icon::GetImageForHeaderWifiNetwork(color); |
+ join_->SetImage(views::CustomButton::STATE_NORMAL, &join_image_); |
+ join_->SetImage(views::CustomButton::STATE_HOVERED, &join_image_pressed_); |
+ join_->SetImage(views::CustomButton::STATE_PRESSED, &join_image_pressed_); |
+ join_->SetImageAlignment(views::ImageButton::ALIGN_CENTER, |
+ views::ImageButton::ALIGN_MIDDLE); |
+ join_->SetMinimumImageSize(gfx::Size(kWiFiIconSize, kWiFiIconSize)); |
+ container->AddChildView(join_); |
+ |
+ toggle_ = new views::ToggleButton(listener_); |
+ container->AddChildView(toggle_); |
+ SetEnabled(enabled_); |
+ } |
+ |
+ void SetEnabled(bool enabled) { |
+ enabled_ = enabled; |
+ join_->SetVisible(enabled_); |
+ toggle_->SetIsOn(enabled_, true); |
+ } |
+ |
+ const views::Button* toggle() const { return toggle_; } |
+ const views::Button* join() const { return join_; } |
+ bool is_toggled() const { return toggle_->is_on(); } |
+ |
+ // views::View: |
+ gfx::Size GetPreferredSize() const override { |
+ gfx::Size size = views::View::GetPreferredSize(); |
+ size.set_height(kWiFiRowHeight); |
+ return size; |
+ } |
+ |
+ int GetHeightForWidth(int width) const override { return kWiFiRowHeight; } |
-NetworkListView::NetworkListView(NetworkListDelegate* delegate) |
+ void Layout() override { |
+ views::View::Layout(); |
+ toggle_->SizeToPreferredSize(); |
+ } |
+ |
+ private: |
+ views::ButtonListener* listener_; |
+ bool enabled_; |
+ views::Label* label_; |
+ views::ToggleButton* toggle_; |
+ views::ImageButton* join_; |
+ gfx::ImageSkia join_image_; |
+ gfx::ImageSkia join_image_pressed_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(WiFiHeaderRowView); |
+}; |
+ |
+// NetworkListViewMd: |
+ |
+NetworkListViewMd::NetworkListViewMd(NetworkListDelegate* delegate) |
: delegate_(delegate), |
- no_wifi_networks_view_(NULL), |
- no_cellular_networks_view_(NULL) { |
+ no_wifi_networks_view_(nullptr), |
+ no_cellular_networks_view_(nullptr), |
+ wifi_header_view_(nullptr) { |
CHECK(delegate_); |
} |
-NetworkListView::~NetworkListView() { |
+NetworkListViewMd::~NetworkListViewMd() { |
network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this); |
} |
-void NetworkListView::Update() { |
+void NetworkListViewMd::Update() { |
CHECK(container_); |
NetworkStateHandler::NetworkStateList network_list; |
NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); |
handler->GetVisibleNetworkList(&network_list); |
UpdateNetworks(network_list); |
+ OrderNetworks(); |
UpdateNetworkIcons(); |
UpdateNetworkListInternal(); |
} |
-bool NetworkListView::IsNetworkEntry(views::View* view, |
- std::string* service_path) const { |
+bool NetworkListViewMd::IsNetworkEntry(views::View* view, |
+ std::string* service_path) const { |
std::map<views::View*, std::string>::const_iterator found = |
network_map_.find(view); |
if (found == network_map_.end()) |
@@ -94,15 +200,14 @@ bool NetworkListView::IsNetworkEntry(views::View* view, |
return true; |
} |
-void NetworkListView::UpdateNetworks( |
+void NetworkListViewMd::UpdateNetworks( |
const NetworkStateHandler::NetworkStateList& networks) { |
SCOPED_NET_LOG_IF_SLOW(); |
network_list_.clear(); |
const NetworkTypePattern pattern = delegate_->GetNetworkTypePattern(); |
for (NetworkStateHandler::NetworkStateList::const_iterator iter = |
networks.begin(); |
- iter != networks.end(); |
- ++iter) { |
+ iter != networks.end(); ++iter) { |
const chromeos::NetworkState* network = *iter; |
if (!pattern.MatchesType(network->type())) |
continue; |
@@ -110,7 +215,46 @@ void NetworkListView::UpdateNetworks( |
} |
} |
-void NetworkListView::UpdateNetworkIcons() { |
+void NetworkListViewMd::OrderNetworks() { |
+ struct CompareNetwork { |
+ explicit CompareNetwork(NetworkStateHandler* handler) : handler_(handler) {} |
+ |
+ // Returns true if |network1| is less than (i.e. is ordered before) |
+ // |network2|. |
+ bool operator()(const std::unique_ptr<NetworkInfo>& network1, |
+ const std::unique_ptr<NetworkInfo>& network2) { |
+ int order1 = GetOrder(handler_->GetNetworkState(network1->service_path)); |
+ int order2 = GetOrder(handler_->GetNetworkState(network2->service_path)); |
+ const bool above = |
+ (order1 < order2) || |
+ (order1 == order2 && network1->highlight && !network2->highlight) || |
+ (order1 == order2 && |
+ network1->service_path.compare(network2->service_path) < 0); |
+ return above; |
+ } |
+ |
+ private: |
+ static int GetOrder(const chromeos::NetworkState* network) { |
+ if (!network) |
+ return 999; |
+ if (network->Matches(NetworkTypePattern::Ethernet())) |
+ return 0; |
+ if (network->Matches(NetworkTypePattern::Cellular())) |
+ return 1; |
+ if (network->Matches(NetworkTypePattern::Mobile())) |
+ return 2; |
+ if (network->Matches(NetworkTypePattern::WiFi())) |
+ return 3; |
+ return 4; |
+ } |
+ |
+ NetworkStateHandler* handler_; |
+ }; |
+ std::sort(network_list_.begin(), network_list_.end(), |
+ CompareNetwork(NetworkHandler::Get()->network_state_handler())); |
+} |
+ |
+void NetworkListViewMd::UpdateNetworkIcons() { |
SCOPED_NET_LOG_IF_SLOW(); |
NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); |
@@ -123,15 +267,16 @@ void NetworkListView::UpdateNetworkIcons() { |
if (!network) |
continue; |
bool prohibited_by_policy = IsProhibitedByPolicy(network); |
- info->image = |
- network_icon::GetImageForNetwork(network, network_icon::ICON_TYPE_LIST); |
info->label = |
network_icon::GetLabelForNetwork(network, network_icon::ICON_TYPE_LIST); |
- info->highlight = |
- network->IsConnectedState() || network->IsConnectingState(); |
+ info->image = |
+ network_icon::GetImageForNetwork(network, network_icon::ICON_TYPE_LIST); |
info->disable = |
(network->activation_state() == shill::kActivationStateActivating) || |
prohibited_by_policy; |
+ info->highlight = |
+ network->IsConnectedState() || network->IsConnectingState(); |
+ info->wifi = network->Matches(NetworkTypePattern::WiFi()); |
if (prohibited_by_policy) { |
info->tooltip = |
l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_PROHIBITED); |
@@ -145,7 +290,7 @@ void NetworkListView::UpdateNetworkIcons() { |
network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this); |
} |
-void NetworkListView::UpdateNetworkListInternal() { |
+void NetworkListViewMd::UpdateNetworkListInternal() { |
SCOPED_NET_LOG_IF_SLOW(); |
// Get the updated list entries |
network_map_.clear(); |
@@ -155,8 +300,7 @@ void NetworkListView::UpdateNetworkListInternal() { |
// Remove old children |
std::set<std::string> remove_service_paths; |
for (ServicePathMap::const_iterator it = service_path_map_.begin(); |
- it != service_path_map_.end(); |
- ++it) { |
+ it != service_path_map_.end(); ++it) { |
if (new_service_paths.find(it->first) == new_service_paths.end()) { |
remove_service_paths.insert(it->first); |
network_map_.erase(it->second); |
@@ -167,8 +311,7 @@ void NetworkListView::UpdateNetworkListInternal() { |
for (std::set<std::string>::const_iterator remove_it = |
remove_service_paths.begin(); |
- remove_it != remove_service_paths.end(); |
- ++remove_it) { |
+ remove_it != remove_service_paths.end(); ++remove_it) { |
service_path_map_.erase(*remove_it); |
} |
@@ -176,8 +319,8 @@ void NetworkListView::UpdateNetworkListInternal() { |
HandleRelayout(); |
} |
-void NetworkListView::HandleRelayout() { |
- views::View* selected_view = NULL; |
+void NetworkListViewMd::HandleRelayout() { |
+ views::View* selected_view = nullptr; |
for (auto& iter : service_path_map_) { |
if (delegate_->IsViewHovered(iter.second)) { |
selected_view = iter.second; |
@@ -190,7 +333,7 @@ void NetworkListView::HandleRelayout() { |
container_->ScrollRectToVisible(selected_view->bounds()); |
} |
-bool NetworkListView::UpdateNetworkListEntries( |
+bool NetworkListViewMd::UpdateNetworkListEntries( |
std::set<std::string>* new_service_paths) { |
bool needs_relayout = false; |
NetworkStateHandler* handler = NetworkHandler::Get()->network_state_handler(); |
@@ -198,9 +341,9 @@ bool NetworkListView::UpdateNetworkListEntries( |
// Insert child views |
int index = 0; |
- // Highlighted networks |
+ // High-priority networks (not Wi-Fi) |
needs_relayout |= |
- UpdateNetworkChildren(new_service_paths, &index, true /* highlighted */); |
+ UpdateNetworkChildren(new_service_paths, &index, false /* not Wi-Fi */); |
const NetworkTypePattern pattern = delegate_->GetNetworkTypePattern(); |
if (pattern.MatchesPattern(NetworkTypePattern::Cellular())) { |
@@ -219,6 +362,11 @@ bool NetworkListView::UpdateNetworkListEntries( |
} |
if (pattern.MatchesPattern(NetworkTypePattern::WiFi())) { |
+ needs_relayout |= UpdateWiFiHeaderRow( |
+ handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()), index, |
+ &wifi_header_view_); |
+ ++index; |
+ |
// "Wifi Enabled / Disabled" |
int message_id = 0; |
if (network_list_.empty()) { |
@@ -230,11 +378,11 @@ bool NetworkListView::UpdateNetworkListEntries( |
UpdateInfoLabel(message_id, index, &no_wifi_networks_view_); |
if (message_id) |
++index; |
- } |
- // Un-highlighted networks |
- needs_relayout |= UpdateNetworkChildren(new_service_paths, &index, |
- false /* not highlighted */); |
+ // Wi-Fi networks |
+ needs_relayout |= |
+ UpdateNetworkChildren(new_service_paths, &index, true /* Wi-Fi */); |
+ } |
// No networks or other messages (fallback) |
if (index == 0) { |
@@ -245,14 +393,14 @@ bool NetworkListView::UpdateNetworkListEntries( |
return needs_relayout; |
} |
-bool NetworkListView::UpdateNetworkChildren( |
+bool NetworkListViewMd::UpdateNetworkChildren( |
std::set<std::string>* new_service_paths, |
int* child_index, |
- bool highlighted) { |
+ bool wifi) { |
bool needs_relayout = false; |
int index = *child_index; |
for (auto& info : network_list_) { |
- if (info->highlight != highlighted) |
+ if (info->wifi != wifi) |
continue; |
needs_relayout |= UpdateNetworkChild(index++, info.get()); |
new_service_paths->insert(info->service_path); |
@@ -261,9 +409,9 @@ bool NetworkListView::UpdateNetworkChildren( |
return needs_relayout; |
} |
-bool NetworkListView::UpdateNetworkChild(int index, const NetworkInfo* info) { |
+bool NetworkListViewMd::UpdateNetworkChild(int index, const NetworkInfo* info) { |
bool needs_relayout = false; |
- views::View* container = NULL; |
+ views::View* container = nullptr; |
ServicePathMap::const_iterator found = |
service_path_map_.find(info->service_path); |
if (found == service_path_map_.end()) { |
@@ -285,16 +433,16 @@ bool NetworkListView::UpdateNetworkChild(int index, const NetworkInfo* info) { |
return needs_relayout; |
} |
-bool NetworkListView::PlaceViewAtIndex(views::View* view, int index) { |
+bool NetworkListViewMd::PlaceViewAtIndex(views::View* view, int index) { |
if (container_->child_at(index) == view) |
return false; |
container_->ReorderChildView(view, index); |
return true; |
} |
-bool NetworkListView::UpdateInfoLabel(int message_id, |
- int index, |
- views::Label** label) { |
+bool NetworkListViewMd::UpdateInfoLabel(int message_id, |
+ int index, |
+ views::Label** label) { |
CHECK(label); |
bool needs_relayout = false; |
if (message_id) { |
@@ -312,14 +460,47 @@ bool NetworkListView::UpdateInfoLabel(int message_id, |
} else if (*label) { |
container_->RemoveChildView(*label); |
delete *label; |
- *label = NULL; |
+ *label = nullptr; |
needs_relayout = true; |
} |
return needs_relayout; |
} |
-void NetworkListView::NetworkIconChanged() { |
+bool NetworkListViewMd::UpdateWiFiHeaderRow(bool enabled, |
+ int index, |
+ WiFiHeaderRowView** view) { |
tdanderson
2016/09/20 14:44:33
*& preferable to **?
varkha
2016/09/23 00:35:53
I thought the style was to pass output parameters
|
+ CHECK(view); |
tdanderson
2016/09/20 14:44:33
Don't forget to remove / change to DCHECK
varkha
2016/09/23 00:35:53
|view| (unlike *view) should never be passed as nu
|
+ bool needs_relayout = false; |
+ if (!*view) { |
+ *view = new WiFiHeaderRowView(this, enabled); |
+ container_->AddChildViewAt(*view, index); |
+ needs_relayout = true; |
+ } else { |
+ (*view)->SetEnabled(enabled); |
+ needs_relayout = PlaceViewAtIndex(*view, index); |
+ } |
+ return needs_relayout; |
+} |
+ |
+void NetworkListViewMd::NetworkIconChanged() { |
Update(); |
} |
+void NetworkListViewMd::ButtonPressed(views::Button* sender, |
+ const ui::Event& event) { |
+ if (sender == wifi_header_view_->toggle()) { |
+ NetworkStateHandler* handler = |
+ NetworkHandler::Get()->network_state_handler(); |
+ handler->SetTechnologyEnabled(NetworkTypePattern::WiFi(), |
+ wifi_header_view_->is_toggled(), |
+ chromeos::network_handler::ErrorCallback()); |
+ return; |
+ } else if (sender == wifi_header_view_->join()) { |
+ delegate_->OnOtherWifiClicked(); |
+ return; |
+ } |
+ NOTREACHED(); |
+ return; |
tdanderson
2016/09/20 14:44:33
nit: not needed.
varkha
2016/09/23 00:35:53
Done.
|
+} |
+ |
} // namespace ui |