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

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 (rebased) 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 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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698