Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/common/system/chromeos/network/vpn_list_view.h" | 5 #include "ash/common/system/chromeos/network/vpn_list_view.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 103 DISALLOW_COPY_AND_ASSIGN(VPNListProviderEntry); | 103 DISALLOW_COPY_AND_ASSIGN(VPNListProviderEntry); |
| 104 }; | 104 }; |
| 105 | 105 |
| 106 // A list entry that represents a VPN provider with Material Design. | 106 // A list entry that represents a VPN provider with Material Design. |
| 107 class VPNListProviderEntryMd : public views::ButtonListener, | 107 class VPNListProviderEntryMd : public views::ButtonListener, |
| 108 public views::View { | 108 public views::View { |
| 109 public: | 109 public: |
| 110 VPNListProviderEntryMd(ViewClickListener* parent, | 110 VPNListProviderEntryMd(ViewClickListener* parent, |
| 111 const std::string& name, | 111 const std::string& name, |
| 112 int button_accessible_name_id) | 112 int button_accessible_name_id) |
| 113 : parent_(parent) { | 113 : parent_(parent), tri_view_(nullptr) { |
| 114 // TODO(varkha): Make this a sticky section header. | |
| 114 SetLayoutManager(new views::FillLayout); | 115 SetLayoutManager(new views::FillLayout); |
| 115 TriView* tri_view = TrayPopupUtils::CreateDefaultRowView(); | 116 tri_view_ = TrayPopupUtils::CreateDefaultRowView(); |
| 116 tri_view->SetContainerVisible(TriView::Container::START, false); | 117 tri_view_->SetContainerVisible(TriView::Container::START, false); |
| 117 AddChildView(tri_view); | 118 AddChildView(tri_view_); |
| 118 | 119 |
| 119 views::Label* label = TrayPopupUtils::CreateDefaultLabel(); | 120 views::Label* label = TrayPopupUtils::CreateDefaultLabel(); |
| 120 TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::SUB_HEADER); | 121 TrayPopupItemStyle style(TrayPopupItemStyle::FontStyle::SUB_HEADER); |
| 121 style.SetupLabel(label); | 122 style.SetupLabel(label); |
| 122 label->SetText(base::ASCIIToUTF16(name)); | 123 label->SetText(base::ASCIIToUTF16(name)); |
| 123 tri_view->AddView(TriView::Container::CENTER, label); | 124 tri_view_->AddView(TriView::Container::CENTER, label); |
| 125 auto box_layout = base::MakeUnique<views::BoxLayout>( | |
|
tdanderson
2016/11/24 23:37:53
Please add a TODO to consider making a factory fun
tdanderson
2016/11/24 23:59:52
Please also make sure Ben's change at https://chro
bruthig
2016/11/25 00:08:54
+1 to adding a factory function like TPU::CreateSu
varkha
2016/11/28 17:14:39
Acknowledged.
varkha
2016/11/28 17:14:39
Acknowledged.
varkha
2016/11/28 17:14:39
Acknowledged.
varkha
2016/11/28 21:24:49
Done. See if this is what you had in mind.
| |
| 126 views::BoxLayout::kHorizontal, 0, 0, 0); | |
| 127 box_layout->set_main_axis_alignment( | |
| 128 views::BoxLayout::MAIN_AXIS_ALIGNMENT_START); | |
| 129 box_layout->set_cross_axis_alignment( | |
| 130 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER); | |
| 131 tri_view_->SetContainerLayout(TriView::Container::CENTER, | |
| 132 std::move(box_layout)); | |
| 124 | 133 |
| 125 gfx::ImageSkia icon = gfx::CreateVectorIcon(kSystemMenuAddConnectionIcon, | 134 gfx::ImageSkia icon = gfx::CreateVectorIcon(kSystemMenuAddConnectionIcon, |
| 126 style.GetIconColor()); | 135 style.GetIconColor()); |
| 127 views::ImageButton* add_vpn_button = | 136 views::ImageButton* add_vpn_button = |
| 128 new SystemMenuButton(this, TrayPopupInkDropStyle::HOST_CENTERED, icon, | 137 new SystemMenuButton(this, TrayPopupInkDropStyle::HOST_CENTERED, icon, |
| 129 icon, button_accessible_name_id); | 138 icon, button_accessible_name_id); |
| 130 add_vpn_button->SetEnabled(true); | 139 add_vpn_button->SetEnabled(true); |
| 131 tri_view->AddView(TriView::Container::END, add_vpn_button); | 140 tri_view_->AddView(TriView::Container::END, add_vpn_button); |
| 141 } | |
| 142 | |
| 143 // Sets up the border. When the provider header is the first item in the | |
| 144 // list (i.e. when the list was empty before adding the provider row) there is | |
| 145 // already |kMenuSeparatorVerticalPadding| padding at the top of the scroll | |
| 146 // contents, so only add that padding when the list was not |empty|. | |
|
tdanderson
2016/11/24 23:37:53
So just to be sure, you are not doing any of this
varkha
2016/11/28 17:14:39
Yes, if configured as sticky this would not be nec
| |
| 147 // TODO(varkha): Remove this special handling when this header becomes sticky. | |
| 148 void SetBorderForHeader(bool empty) { | |
| 149 tri_view_->SetBorder(views::CreateEmptyBorder( | |
| 150 empty ? 0 : kMenuSeparatorVerticalPadding, | |
| 151 kTrayPopupPaddingHorizontal - | |
| 152 GetTrayConstant(TRAY_POPUP_ITEM_LEFT_INSET), | |
|
tdanderson
2016/11/24 23:37:53
So you're subtracting TRAY_POPUP_ITEM_LEFT_INSET f
varkha
2016/11/28 17:14:39
Yes. Let me see if adding a factory would isolate
| |
| 153 kMenuSeparatorVerticalPadding, 0)); | |
| 132 } | 154 } |
| 133 | 155 |
| 134 protected: | 156 protected: |
| 135 // views::ButtonListener: | 157 // views::ButtonListener: |
| 136 void ButtonPressed(views::Button* sender, const ui::Event& event) override { | 158 void ButtonPressed(views::Button* sender, const ui::Event& event) override { |
| 137 parent_->OnViewClicked(this); | 159 parent_->OnViewClicked(this); |
| 138 } | 160 } |
| 139 | 161 |
| 140 private: | 162 private: |
| 141 // Our parent to handle events. | 163 // Our parent to handle events. |
| 142 ViewClickListener* parent_; | 164 ViewClickListener* parent_; |
| 143 | 165 |
| 166 // Container that owns the child controls. | |
| 167 TriView* tri_view_; | |
| 168 | |
| 144 DISALLOW_COPY_AND_ASSIGN(VPNListProviderEntryMd); | 169 DISALLOW_COPY_AND_ASSIGN(VPNListProviderEntryMd); |
| 145 }; | 170 }; |
| 146 | 171 |
| 147 // A list entry that represents a network. If the network is currently | 172 // A list entry that represents a network. If the network is currently |
| 148 // connecting, the icon shown by this list entry will be animated. If the | 173 // connecting, the icon shown by this list entry will be animated. If the |
| 149 // network is currently connected, a disconnect button will be shown next to its | 174 // network is currently connected, a disconnect button will be shown next to its |
| 150 // name. | 175 // name. |
| 151 class VPNListNetworkEntry : public VPNListEntryBase, | 176 class VPNListNetworkEntry : public VPNListEntryBase, |
| 152 public network_icon::AnimationObserver { | 177 public network_icon::AnimationObserver { |
| 153 public: | 178 public: |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 250 | 275 |
| 251 void VPNListNetworkEntry::DisconnectButton::OnBoundsChanged( | 276 void VPNListNetworkEntry::DisconnectButton::OnBoundsChanged( |
| 252 const gfx::Rect& previous_bounds) { | 277 const gfx::Rect& previous_bounds) { |
| 253 TrayPopupLabelButton::OnBoundsChanged(previous_bounds); | 278 TrayPopupLabelButton::OnBoundsChanged(previous_bounds); |
| 254 if (IsMouseHovered()) { | 279 if (IsMouseHovered()) { |
| 255 SetState(STATE_HOVERED); | 280 SetState(STATE_HOVERED); |
| 256 parent_->SetHoverHighlight(false); | 281 parent_->SetHoverHighlight(false); |
| 257 } | 282 } |
| 258 } | 283 } |
| 259 | 284 |
| 260 void VPNListNetworkEntry::UpdateFromNetworkState( | 285 void VPNListNetworkEntry::UpdateFromNetworkState( |
|
tdanderson
2016/11/24 23:37:53
Please revert your changes to UpdateFromNetworkSta
varkha
2016/11/28 17:14:39
Done.
| |
| 261 const chromeos::NetworkState* network) { | 286 const chromeos::NetworkState* network) { |
| 262 if (network && network->IsConnectingState()) | 287 if (network && network->IsConnectingState()) |
| 263 network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this); | 288 network_icon::NetworkIconAnimation::GetInstance()->AddObserver(this); |
| 264 else | 289 else |
| 265 network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this); | 290 network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver(this); |
| 266 | 291 |
| 267 if (!network) { | 292 if (!network) { |
| 268 // This is a transient state where the network has been removed already but | 293 // This is a transient state where the network has been removed already but |
| 269 // the network list in the UI has not been updated yet. | 294 // the network list in the UI has not been updated yet. |
| 270 return; | 295 return; |
| 271 } | 296 } |
| 272 | 297 |
| 273 RemoveAllChildViews(true); | 298 RemoveAllChildViews(true); |
| 274 disconnect_button_ = nullptr; | 299 disconnect_button_ = nullptr; |
| 275 | 300 |
| 276 AddIconAndLabel( | 301 AddIconAndLabel( |
| 277 network_icon::GetImageForNetwork(network, network_icon::ICON_TYPE_LIST), | 302 network_icon::GetImageForNetwork(network, network_icon::ICON_TYPE_LIST), |
| 278 network_icon::GetLabelForNetwork(network, network_icon::ICON_TYPE_LIST), | 303 network_icon::GetLabelForNetwork(network, network_icon::ICON_TYPE_LIST), |
| 279 IsConnectedOrConnecting(network)); | 304 IsConnectedOrConnecting(network)); |
| 280 if (IsConnectedOrConnecting(network)) { | 305 if (IsConnectedOrConnecting(network)) { |
| 281 if (UseMd()) { | 306 if (UseMd()) { |
| 282 disconnect_button_ = TrayPopupUtils::CreateTrayPopupButton( | 307 disconnect_button_ = TrayPopupUtils::CreateTrayPopupButton( |
| 283 this, l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_VPN_DISCONNECT)); | 308 this, l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_VPN_DISCONNECT)); |
| 284 } else { | |
| 285 disconnect_button_ = new DisconnectButton(this); | |
| 286 } | |
| 287 if (UseMd()) { | |
| 288 DCHECK(tri_view()); | 309 DCHECK(tri_view()); |
| 289 tri_view()->AddView(TriView::Container::END, disconnect_button_); | 310 tri_view()->AddView(TriView::Container::END, disconnect_button_); |
| 290 tri_view()->SetContainerVisible(TriView::Container::END, true); | 311 tri_view()->SetContainerVisible(TriView::Container::END, true); |
| 291 } else { | 312 } else { |
| 313 disconnect_button_ = new DisconnectButton(this); | |
| 292 AddChildView(disconnect_button_); | 314 AddChildView(disconnect_button_); |
| 293 } | 315 } |
| 294 | 316 |
| 295 SetBorder( | 317 SetBorder( |
| 296 views::CreateEmptyBorder(0, kTrayPopupPaddingHorizontal, 0, | 318 views::CreateEmptyBorder(0, UseMd() ? 0 : kTrayPopupPaddingHorizontal, |
| 297 UseMd() ? kTrayPopupButtonEndMargin : 3)); | 319 0, UseMd() ? kTrayPopupButtonEndMargin : 3)); |
| 298 } else { | 320 } else { |
| 299 SetBorder(views::CreateEmptyBorder(0, kTrayPopupPaddingHorizontal, 0, 0)); | 321 SetBorder(views::CreateEmptyBorder( |
| 322 0, UseMd() ? 0 : kTrayPopupPaddingHorizontal, 0, 0)); | |
| 300 } | 323 } |
| 301 | 324 |
| 302 if (!UseMd()) { | 325 if (!UseMd()) { |
| 303 // The icon and the disconnect button are always set to their preferred | 326 // The icon and the disconnect button are always set to their preferred |
| 304 // size. All remaining space is used for the network name. | 327 // size. All remaining space is used for the network name. |
| 305 views::BoxLayout* layout = new views::BoxLayout( | 328 views::BoxLayout* layout = new views::BoxLayout( |
| 306 views::BoxLayout::kHorizontal, 0, 3, kTrayPopupPaddingBetweenItems); | 329 views::BoxLayout::kHorizontal, 0, 3, kTrayPopupPaddingBetweenItems); |
| 307 SetLayoutManager(layout); | 330 SetLayoutManager(layout); |
| 308 layout->SetDefaultFlex(0); | 331 layout->SetDefaultFlex(0); |
| 309 layout->SetFlexForView(text_label(), 1); | 332 layout->SetFlexForView(text_label(), 1); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 443 views::View* entry(new VPNListNetworkEntry(this, network)); | 466 views::View* entry(new VPNListNetworkEntry(this, network)); |
| 444 container()->AddChildView(entry); | 467 container()->AddChildView(entry); |
| 445 network_view_service_path_map_[entry] = network->path(); | 468 network_view_service_path_map_[entry] = network->path(); |
| 446 list_empty_ = false; | 469 list_empty_ = false; |
| 447 } | 470 } |
| 448 | 471 |
| 449 void VPNListView::AddProviderAndNetworks( | 472 void VPNListView::AddProviderAndNetworks( |
| 450 const VPNProvider& vpn_provider, | 473 const VPNProvider& vpn_provider, |
| 451 const chromeos::NetworkStateHandler::NetworkStateList& networks) { | 474 const chromeos::NetworkStateHandler::NetworkStateList& networks) { |
| 452 // Add a visual separator, unless this is the topmost entry in the list. | 475 // Add a visual separator, unless this is the topmost entry in the list. |
| 453 if (!list_empty_) { | 476 if (!list_empty_) |
| 454 views::Separator* const separator = | 477 container()->AddChildView(TrayPopupUtils::CreateListHeaderSeparator()); |
| 455 new views::Separator(views::Separator::HORIZONTAL); | |
| 456 separator->SetColor(kBorderLightColor); | |
| 457 container()->AddChildView(separator); | |
| 458 } else { | |
| 459 list_empty_ = false; | |
| 460 } | |
| 461 std::string vpn_name = | 478 std::string vpn_name = |
| 462 vpn_provider.third_party | 479 vpn_provider.third_party |
| 463 ? vpn_provider.third_party_provider_name | 480 ? vpn_provider.third_party_provider_name |
| 464 : l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_VPN_BUILT_IN_PROVIDER); | 481 : l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_VPN_BUILT_IN_PROVIDER); |
| 465 | 482 |
| 466 // Add a list entry for the VPN provider. | 483 // Add a list entry for the VPN provider. |
| 467 views::View* provider_view = nullptr; | 484 views::View* view = nullptr; |
| 468 if (UseMd()) { | 485 if (UseMd()) { |
| 469 provider_view = new VPNListProviderEntryMd( | 486 VPNListProviderEntryMd* provider_view = new VPNListProviderEntryMd( |
| 470 this, vpn_name, IDS_ASH_STATUS_TRAY_ADD_CONNECTION); | 487 this, vpn_name, IDS_ASH_STATUS_TRAY_ADD_CONNECTION); |
| 488 provider_view->SetBorderForHeader(list_empty_); | |
| 489 view = provider_view; | |
| 471 } else { | 490 } else { |
| 472 provider_view = new VPNListProviderEntry(this, vpn_name); | 491 view = new VPNListProviderEntry(this, vpn_name); |
| 473 } | 492 } |
| 474 container()->AddChildView(provider_view); | 493 container()->AddChildView(view); |
| 475 provider_view_map_[provider_view] = vpn_provider; | 494 provider_view_map_[view] = vpn_provider; |
| 495 list_empty_ = false; | |
| 476 // Add the networks belonging to this provider, in the priority order returned | 496 // Add the networks belonging to this provider, in the priority order returned |
| 477 // by shill. | 497 // by shill. |
| 478 for (const chromeos::NetworkState* const& network : networks) { | 498 for (const chromeos::NetworkState* const& network : networks) { |
| 479 if (VpnProviderMatchesNetwork(vpn_provider, *network)) | 499 if (VpnProviderMatchesNetwork(vpn_provider, *network)) |
| 480 AddNetwork(network); | 500 AddNetwork(network); |
| 481 } | 501 } |
| 482 } | 502 } |
| 483 | 503 |
| 484 void VPNListView::AddProvidersAndNetworks( | 504 void VPNListView::AddProvidersAndNetworks( |
| 485 const chromeos::NetworkStateHandler::NetworkStateList& networks) { | 505 const chromeos::NetworkStateHandler::NetworkStateList& networks) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 501 } | 521 } |
| 502 } | 522 } |
| 503 | 523 |
| 504 // Add providers without any configured networks, in the order that the | 524 // Add providers without any configured networks, in the order that the |
| 505 // providers were returned by the extensions system. | 525 // providers were returned by the extensions system. |
| 506 for (const VPNProvider& provider : providers) | 526 for (const VPNProvider& provider : providers) |
| 507 AddProviderAndNetworks(provider, networks); | 527 AddProviderAndNetworks(provider, networks); |
| 508 } | 528 } |
| 509 | 529 |
| 510 } // namespace ash | 530 } // namespace ash |
| OLD | NEW |