Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: ash/common/system/chromeos/network/vpn_list_view.cc

Issue 2530763002: [ash-md] Adjusts layout of lists with sticky header rows to match specs (Closed)
Patch Set: [ash-md] Adjusts layout of lists with sticky header rows to match specs (horizontal offsets) Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 const ui::NativeTheme* theme = GetNativeTheme(); 120 const ui::NativeTheme* theme = GetNativeTheme();
120 const SkColor prominent_color = 121 const SkColor prominent_color =
121 theme->GetSystemColor(ui::NativeTheme::kColorId_ProminentButtonColor); 122 theme->GetSystemColor(ui::NativeTheme::kColorId_ProminentButtonColor);
122 views::Label* label = TrayPopupUtils::CreateDefaultLabel(); 123 views::Label* label = TrayPopupUtils::CreateDefaultLabel();
123 TrayPopupItemStyle style( 124 TrayPopupItemStyle style(
124 theme, TrayPopupItemStyle::FontStyle::DETAILED_VIEW_LABEL); 125 theme, TrayPopupItemStyle::FontStyle::DETAILED_VIEW_LABEL);
125 style.SetupLabel(label); 126 style.SetupLabel(label);
126 label->SetText(base::ASCIIToUTF16(name)); 127 label->SetText(base::ASCIIToUTF16(name));
127 label->SetEnabledColor(prominent_color); 128 label->SetEnabledColor(prominent_color);
128 tri_view->AddView(TriView::Container::CENTER, label); 129 tri_view_->AddView(TriView::Container::CENTER, label);
130 auto box_layout = base::MakeUnique<views::BoxLayout>(
131 views::BoxLayout::kHorizontal, 0, 0, 0);
132 box_layout->set_main_axis_alignment(
133 views::BoxLayout::MAIN_AXIS_ALIGNMENT_START);
134 box_layout->set_cross_axis_alignment(
135 views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
136 tri_view_->SetContainerLayout(TriView::Container::CENTER,
137 std::move(box_layout));
129 138
130 gfx::ImageSkia icon = 139 gfx::ImageSkia icon =
131 gfx::CreateVectorIcon(kSystemMenuAddConnectionIcon, prominent_color); 140 gfx::CreateVectorIcon(kSystemMenuAddConnectionIcon, prominent_color);
132 views::ImageButton* add_vpn_button = 141 views::ImageButton* add_vpn_button =
133 new SystemMenuButton(this, TrayPopupInkDropStyle::HOST_CENTERED, icon, 142 new SystemMenuButton(this, TrayPopupInkDropStyle::HOST_CENTERED, icon,
134 icon, button_accessible_name_id); 143 icon, button_accessible_name_id);
135 add_vpn_button->set_ink_drop_base_color(prominent_color); 144 add_vpn_button->set_ink_drop_base_color(prominent_color);
136 add_vpn_button->SetEnabled(true); 145 add_vpn_button->SetEnabled(true);
137 tri_view->AddView(TriView::Container::END, add_vpn_button); 146 tri_view_->AddView(TriView::Container::END, add_vpn_button);
147 }
148
149 // Sets up the border. When the provider header is the first item in the
150 // list (i.e. when the list was empty before adding the provider row) there is
151 // already |kMenuSeparatorVerticalPadding| padding at the top of the scroll
152 // contents, so only add that padding when the list was not |empty|.
153 // TODO(varkha): Remove this special handling when this header becomes sticky.
154 void SetBorderForHeader(bool empty) {
155 tri_view_->SetBorder(views::CreateEmptyBorder(
156 empty ? 0 : kMenuSeparatorVerticalPadding,
157 kTrayPopupPaddingHorizontal -
158 GetTrayConstant(TRAY_POPUP_ITEM_LEFT_INSET),
159 kMenuSeparatorVerticalPadding, 0));
138 } 160 }
139 161
140 protected: 162 protected:
141 // views::ButtonListener: 163 // views::ButtonListener:
142 void ButtonPressed(views::Button* sender, const ui::Event& event) override { 164 void ButtonPressed(views::Button* sender, const ui::Event& event) override {
143 parent_->OnViewClicked(this); 165 parent_->OnViewClicked(this);
144 } 166 }
145 167
146 private: 168 private:
147 // Our parent to handle events. 169 // Our parent to handle events.
148 ViewClickListener* parent_; 170 ViewClickListener* parent_;
149 171
172 // Container that owns the child controls.
173 TriView* tri_view_;
174
150 DISALLOW_COPY_AND_ASSIGN(VPNListProviderEntryMd); 175 DISALLOW_COPY_AND_ASSIGN(VPNListProviderEntryMd);
151 }; 176 };
152 177
153 // A list entry that represents a network. If the network is currently 178 // A list entry that represents a network. If the network is currently
154 // connecting, the icon shown by this list entry will be animated. If the 179 // connecting, the icon shown by this list entry will be animated. If the
155 // network is currently connected, a disconnect button will be shown next to its 180 // network is currently connected, a disconnect button will be shown next to its
156 // name. 181 // name.
157 class VPNListNetworkEntry : public VPNListEntryBase, 182 class VPNListNetworkEntry : public VPNListEntryBase,
158 public network_icon::AnimationObserver { 183 public network_icon::AnimationObserver {
159 public: 184 public:
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 disconnect_button_ = nullptr; 305 disconnect_button_ = nullptr;
281 306
282 AddIconAndLabel( 307 AddIconAndLabel(
283 network_icon::GetImageForNetwork(network, network_icon::ICON_TYPE_LIST), 308 network_icon::GetImageForNetwork(network, network_icon::ICON_TYPE_LIST),
284 network_icon::GetLabelForNetwork(network, network_icon::ICON_TYPE_LIST), 309 network_icon::GetLabelForNetwork(network, network_icon::ICON_TYPE_LIST),
285 IsConnectedOrConnecting(network)); 310 IsConnectedOrConnecting(network));
286 if (IsConnectedOrConnecting(network)) { 311 if (IsConnectedOrConnecting(network)) {
287 if (UseMd()) { 312 if (UseMd()) {
288 disconnect_button_ = TrayPopupUtils::CreateTrayPopupButton( 313 disconnect_button_ = TrayPopupUtils::CreateTrayPopupButton(
289 this, l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_VPN_DISCONNECT)); 314 this, l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_VPN_DISCONNECT));
290 } else {
291 disconnect_button_ = new DisconnectButton(this);
292 }
293 if (UseMd()) {
294 DCHECK(tri_view()); 315 DCHECK(tri_view());
295 tri_view()->AddView(TriView::Container::END, disconnect_button_); 316 tri_view()->AddView(TriView::Container::END, disconnect_button_);
296 tri_view()->SetContainerVisible(TriView::Container::END, true); 317 tri_view()->SetContainerVisible(TriView::Container::END, true);
297 } else { 318 } else {
319 disconnect_button_ = new DisconnectButton(this);
298 AddChildView(disconnect_button_); 320 AddChildView(disconnect_button_);
299 } 321 }
300 322
301 SetBorder( 323 SetBorder(
302 views::CreateEmptyBorder(0, kTrayPopupPaddingHorizontal, 0, 324 views::CreateEmptyBorder(0, UseMd() ? 0 : kTrayPopupPaddingHorizontal,
303 UseMd() ? kTrayPopupButtonEndMargin : 3)); 325 0, UseMd() ? kTrayPopupButtonEndMargin : 3));
304 } else { 326 } else {
305 SetBorder(views::CreateEmptyBorder(0, kTrayPopupPaddingHorizontal, 0, 0)); 327 SetBorder(views::CreateEmptyBorder(
328 0, UseMd() ? 0 : kTrayPopupPaddingHorizontal, 0, 0));
306 } 329 }
307 330
308 if (!UseMd()) { 331 if (!UseMd()) {
309 // The icon and the disconnect button are always set to their preferred 332 // The icon and the disconnect button are always set to their preferred
310 // size. All remaining space is used for the network name. 333 // size. All remaining space is used for the network name.
311 views::BoxLayout* layout = new views::BoxLayout( 334 views::BoxLayout* layout = new views::BoxLayout(
312 views::BoxLayout::kHorizontal, 0, 3, kTrayPopupPaddingBetweenItems); 335 views::BoxLayout::kHorizontal, 0, 3, kTrayPopupPaddingBetweenItems);
313 SetLayoutManager(layout); 336 SetLayoutManager(layout);
314 layout->SetDefaultFlex(0); 337 layout->SetDefaultFlex(0);
315 layout->SetFlexForView(text_label(), 1); 338 layout->SetFlexForView(text_label(), 1);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 views::View* entry(new VPNListNetworkEntry(this, network)); 472 views::View* entry(new VPNListNetworkEntry(this, network));
450 container()->AddChildView(entry); 473 container()->AddChildView(entry);
451 network_view_service_path_map_[entry] = network->path(); 474 network_view_service_path_map_[entry] = network->path();
452 list_empty_ = false; 475 list_empty_ = false;
453 } 476 }
454 477
455 void VPNListView::AddProviderAndNetworks( 478 void VPNListView::AddProviderAndNetworks(
456 const VPNProvider& vpn_provider, 479 const VPNProvider& vpn_provider,
457 const chromeos::NetworkStateHandler::NetworkStateList& networks) { 480 const chromeos::NetworkStateHandler::NetworkStateList& networks) {
458 // Add a visual separator, unless this is the topmost entry in the list. 481 // Add a visual separator, unless this is the topmost entry in the list.
459 if (!list_empty_) { 482 if (!list_empty_)
460 views::Separator* const separator = 483 container()->AddChildView(TrayPopupUtils::CreateListHeaderSeparator());
461 new views::Separator(views::Separator::HORIZONTAL);
462 separator->SetColor(kBorderLightColor);
463 container()->AddChildView(separator);
464 } else {
465 list_empty_ = false;
466 }
467 std::string vpn_name = 484 std::string vpn_name =
468 vpn_provider.third_party 485 vpn_provider.third_party
469 ? vpn_provider.third_party_provider_name 486 ? vpn_provider.third_party_provider_name
470 : l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_VPN_BUILT_IN_PROVIDER); 487 : l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_VPN_BUILT_IN_PROVIDER);
471 488
472 // Add a list entry for the VPN provider. 489 // Add a list entry for the VPN provider.
473 views::View* provider_view = nullptr; 490 views::View* view = nullptr;
474 if (UseMd()) { 491 if (UseMd()) {
475 provider_view = new VPNListProviderEntryMd( 492 VPNListProviderEntryMd* provider_view = new VPNListProviderEntryMd(
476 this, vpn_name, IDS_ASH_STATUS_TRAY_ADD_CONNECTION); 493 this, vpn_name, IDS_ASH_STATUS_TRAY_ADD_CONNECTION);
494 provider_view->SetBorderForHeader(list_empty_);
495 view = provider_view;
477 } else { 496 } else {
478 provider_view = new VPNListProviderEntry(this, vpn_name); 497 view = new VPNListProviderEntry(this, vpn_name);
479 } 498 }
480 container()->AddChildView(provider_view); 499 container()->AddChildView(view);
481 provider_view_map_[provider_view] = vpn_provider; 500 provider_view_map_[view] = vpn_provider;
501 list_empty_ = false;
482 // Add the networks belonging to this provider, in the priority order returned 502 // Add the networks belonging to this provider, in the priority order returned
483 // by shill. 503 // by shill.
484 for (const chromeos::NetworkState* const& network : networks) { 504 for (const chromeos::NetworkState* const& network : networks) {
485 if (VpnProviderMatchesNetwork(vpn_provider, *network)) 505 if (VpnProviderMatchesNetwork(vpn_provider, *network))
486 AddNetwork(network); 506 AddNetwork(network);
487 } 507 }
488 } 508 }
489 509
490 void VPNListView::AddProvidersAndNetworks( 510 void VPNListView::AddProvidersAndNetworks(
491 const chromeos::NetworkStateHandler::NetworkStateList& networks) { 511 const chromeos::NetworkStateHandler::NetworkStateList& networks) {
(...skipping 15 matching lines...) Expand all
507 } 527 }
508 } 528 }
509 529
510 // Add providers without any configured networks, in the order that the 530 // Add providers without any configured networks, in the order that the
511 // providers were returned by the extensions system. 531 // providers were returned by the extensions system.
512 for (const VPNProvider& provider : providers) 532 for (const VPNProvider& provider : providers)
513 AddProviderAndNetworks(provider, networks); 533 AddProviderAndNetworks(provider, networks);
514 } 534 }
515 535
516 } // namespace ash 536 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698