Commit 08a8eeaf authored by Thomas Tangl's avatar Thomas Tangl Committed by Commit Bot

Add sync-error UI for DICE user menu

When DICE is enabled and there is a sync error, the user menu should
show a red field containing the profile photo, an action title and a
short overview of the error. This field should be clickable and
replace the current action button.

Mocks can be found in the bug report.

Additional changes:
 - The spacing in the HoverButton class for the badged
   profile photo is corrected.

Bug: 786369
Change-Id: I3165100d16dd75a57e5381edddfb56ae37668bbf
Reviewed-on: https://chromium-review.googlesource.com/781692Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Commit-Queue: Thomas Tangl <tangltom@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521656}
parent d153265e
......@@ -77,6 +77,7 @@ aggregate_vector_icons("chrome_vector_icons") {
"supervisor_account.icon",
"supervisor_account_circle.icon",
"sync_circle.icon",
"sync_error_circle.icon",
"sync_problem.icon",
"tab.icon",
"tab_audio.1x.icon",
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
CANVAS_DIMENSIONS, 16,
CIRCLE, 8, 8, 8,
MOVE_TO, 3.5f, 8,
R_CUBIC_TO, 0, 1.11f, 0.46f, 2.1f, 1.18f, 2.82f,
LINE_TO, 3.5f, 12,
R_H_LINE_TO, 3,
V_LINE_TO, 9,
R_LINE_TO, -1.12f, 1.12f,
CUBIC_TO, 4.84f, 9.57f, 4.5f, 8.83f, 4.5f, 8,
R_CUBIC_TO, 0, -1.3f, 0.84f, -2.41f, 2, -2.82f,
V_LINE_TO, 4.13f,
R_CUBIC_TO, -1.72f, 0.45f, -3, 2.01f, -3, 3.87f,
CLOSE,
R_MOVE_TO, 4, 2.5f,
R_H_LINE_TO, 1,
R_V_LINE_TO, -1,
R_H_LINE_TO, -1,
R_V_LINE_TO, 1,
CLOSE,
R_MOVE_TO, 5, -6.5f,
R_H_LINE_TO, -3,
R_V_LINE_TO, 3,
R_LINE_TO, 1.12f, -1.12f,
R_CUBIC_TO, 0.54f, 0.55f, 0.88f, 1.29f, 0.88f, 2.12f,
R_CUBIC_TO, 0, 1.31f, -0.83f, 2.42f, -2, 2.83f,
R_V_LINE_TO, 1.05f,
R_CUBIC_TO, 1.73f, -0.44f, 3, -2, 3, -3.87f,
R_CUBIC_TO, 0, -1.1f, -0.45f, -2.1f, -1.18f, -2.82f,
LINE_TO, 12.5f, 4,
CLOSE,
R_MOVE_TO, -5, 4.5f,
R_H_LINE_TO, 1,
R_V_LINE_TO, -3,
R_H_LINE_TO, -1,
R_V_LINE_TO, 3,
CLOSE,
END
......@@ -99,11 +99,11 @@ HoverButton::HoverButton(views::ButtonListener* button_listener,
// more vertical spacing.
constexpr int kLargeIconHeight = 20;
const int icon_height = icon_view->GetPreferredSize().height();
const bool is_small_icon = icon_height <= kLargeIconHeight;
int remaining_vert_spacing =
icon_height <= kLargeIconHeight
is_small_icon
? layout_provider->GetDistanceMetric(DISTANCE_CONTROL_LIST_VERTICAL)
: layout_provider->GetDistanceMetric(
views::DISTANCE_CONTROL_VERTICAL_TEXT_PADDING);
: 12;
const int total_height = icon_height + remaining_vert_spacing * 2;
// If the padding given to the top and bottom of the HoverButton (i.e., on
......@@ -115,14 +115,19 @@ HoverButton::HoverButton(views::ButtonListener* button_listener,
views::style::GetLineHeight(views::style::CONTEXT_LABEL,
views::style::STYLE_PRIMARY) *
num_labels;
if (combined_line_height > icon_view->GetPreferredSize().height())
if (combined_line_height > icon_height)
remaining_vert_spacing = (total_height - combined_line_height) / 2;
SetBorder(CreateBorderWithVerticalSpacing(remaining_vert_spacing));
views::GridLayout* grid_layout = views::GridLayout::CreateAndInstall(this);
// Badging may make the icon slightly wider (but not taller). However, the
// layout should be the same whether or not the icon is badged, so allow the
// badged part of the icon to extend into the padding.
const int badge_spacing = icon_view->GetPreferredSize().width() - icon_height;
const int icon_label_spacing = layout_provider->GetDistanceMetric(
views::DISTANCE_RELATED_LABEL_HORIZONTAL);
views::DISTANCE_RELATED_LABEL_HORIZONTAL) -
badge_spacing;
constexpr float kFixed = 0.f;
constexpr float kStretchy = 1.f;
......@@ -267,3 +272,13 @@ void HoverButton::OnBoundsChanged(const gfx::Rect& previous_bounds) {
taken_width_);
}
}
void HoverButton::SetTitleTextStyle(views::style::TextStyle text_style,
SkColor background_color) {
title_->SetDisplayedOnBackgroundColor(background_color);
title_->SetDefaultTextStyle(text_style);
}
void HoverButton::SetSubtitleColor(SkColor color) {
subtitle_->SetEnabledColor(color);
}
......@@ -54,6 +54,14 @@ class HoverButton : public views::LabelButton {
// non-empty subtitle.
void SetSubtitleElideBehavior(gfx::ElideBehavior elide_behavior);
// Sets the text style of the title considering the color of the background.
// Passing |background_color| makes sure that the text color will not be
// changed to a color that is not readable on the specified background.
void SetTitleTextStyle(views::style::TextStyle text_style,
SkColor background_color);
void SetSubtitleColor(SkColor color);
protected:
// views::LabelButton:
void StateChanged(ButtonState old_state) override;
......
......@@ -64,6 +64,9 @@ gfx::ImageSkia ImageForBadgeType(BadgedProfilePhoto::BadgeType badge_type) {
case BadgedProfilePhoto::BADGE_TYPE_SYNC_COMPLETE:
return gfx::CreateVectorIcon(kSyncCircleIcon, kBadgeIconSize,
gfx::kGoogleGreen700);
case BadgedProfilePhoto::BADGE_TYPE_SYNC_ERROR:
return gfx::CreateVectorIcon(kSyncErrorCircleIcon, kBadgeIconSize,
SK_ColorWHITE);
case BadgedProfilePhoto::BADGE_TYPE_NONE:
NOTREACHED();
return gfx::ImageSkia();
......
......@@ -20,6 +20,7 @@ class BadgedProfilePhoto : public views::View {
BADGE_TYPE_SUPERVISOR,
BADGE_TYPE_CHILD,
BADGE_TYPE_SYNC_COMPLETE,
BADGE_TYPE_SYNC_ERROR,
};
static const char kViewClassName[];
......
......@@ -28,7 +28,6 @@
#include "chrome/browser/signin/signin_promo.h"
#include "chrome/browser/signin/signin_ui_util.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/sync/sync_ui_util.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/browser/ui/browser.h"
......@@ -713,7 +712,7 @@ views::View* ProfileChooserView::CreateProfileChooserView(
current_profile_view = CreateCurrentProfileView(item, false);
if (!IsProfileChooser(view_mode_))
current_profile_accounts = CreateCurrentProfileAccountsView(item);
sync_error_view = CreateSyncErrorViewIfNeeded();
sync_error_view = CreateSyncErrorViewIfNeeded(item);
} else {
other_profiles.push_back(i);
}
......@@ -732,8 +731,11 @@ views::View* ProfileChooserView::CreateProfileChooserView(
option_buttons_view = CreateOptionsView(false, avatar_menu);
}
layout->StartRow(1, 0);
layout->AddView(current_profile_view);
if (!(signin::IsDiceEnabledForProfile(browser_->profile()->GetPrefs()) &&
sync_error_view)) {
layout->StartRow(1, 0);
layout->AddView(current_profile_view);
}
if (!IsProfileChooser(view_mode_)) {
DCHECK(current_profile_accounts);
......@@ -758,7 +760,8 @@ views::View* ProfileChooserView::CreateProfileChooserView(
return view;
}
views::View* ProfileChooserView::CreateSyncErrorViewIfNeeded() {
views::View* ProfileChooserView::CreateSyncErrorViewIfNeeded(
const AvatarMenu::Item& avatar_item) {
int content_string_id, button_string_id;
SigninManagerBase* signin_manager =
SigninManagerFactory::GetForProfile(browser_->profile());
......@@ -771,6 +774,12 @@ views::View* ProfileChooserView::CreateSyncErrorViewIfNeeded() {
ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
if (error != sync_ui_util::SUPERVISED_USER_AUTH_ERROR &&
signin::IsDiceEnabledForProfile(browser_->profile()->GetPrefs())) {
return CreateDiceSyncErrorView(avatar_item, error, button_string_id,
content_string_id);
}
// Sets an overall horizontal layout.
views::View* view = new views::View();
views::BoxLayout* layout = new views::BoxLayout(
......@@ -788,8 +797,8 @@ views::View* ProfileChooserView::CreateSyncErrorViewIfNeeded() {
// Adds a vertical view to organize the error title, message, and button.
views::View* vertical_view = new views::View();
const int small_vertical_spacing = provider->GetDistanceMetric(
DISTANCE_RELATED_CONTROL_VERTICAL_SMALL);
const int small_vertical_spacing =
provider->GetDistanceMetric(DISTANCE_RELATED_CONTROL_VERTICAL_SMALL);
views::BoxLayout* vertical_layout = new views::BoxLayout(
views::BoxLayout::kVertical, gfx::Insets(), small_vertical_spacing);
vertical_layout->set_cross_axis_alignment(
......@@ -832,6 +841,42 @@ views::View* ProfileChooserView::CreateSyncErrorViewIfNeeded() {
return view;
}
views::View* ProfileChooserView::CreateDiceSyncErrorView(
const AvatarMenu::Item& avatar_item,
sync_ui_util::AvatarSyncErrorType error,
int title_string_id,
int subtitle_string_id) {
// Creates a view containing a red hover button with a transparent border of
// width |kMenuEdgeMargin| around it. The hover button contains the profile
// photo, given by |avatar_item.icon|, badged with the sync-error icon. The
// title of the hover button describes the action to take and the subtitle
// gives more information about the error. A view has to be used here instead
// of hover_button->SetBorder() because the latter creates a border with the
// same color as the button.
views::View* view = new views::View();
view->SetLayoutManager(new views::FillLayout());
view->SetBorder(
views::CreateSolidBorder(kMenuEdgeMargin, SK_ColorTRANSPARENT));
auto current_profile_photo = std::make_unique<BadgedProfilePhoto>(
BadgedProfilePhoto::BADGE_TYPE_SYNC_ERROR, avatar_item.icon);
HoverButton* hover_button =
new HoverButton(this, std::move(current_profile_photo),
l10n_util::GetStringUTF16(title_string_id),
l10n_util::GetStringUTF16(subtitle_string_id));
hover_button->SetBackground(views::CreateSolidBackground(gfx::kGoogleRed700));
// The sync-error hover button is supposed to look similar to a default
// button, therefore the title should have the same style as the title of a
// default button.
hover_button->SetTitleTextStyle(views::style::STYLE_DIALOG_BUTTON_DEFAULT,
gfx::kGoogleRed700);
hover_button->SetSubtitleColor(SK_ColorWHITE);
view->AddChildView(hover_button);
sync_error_button_ = hover_button;
sync_error_button_->set_id(error);
return view;
}
views::View* ProfileChooserView::CreateCurrentProfileView(
const AvatarMenu::Item& avatar_item,
bool is_guest) {
......
......@@ -14,6 +14,7 @@
#include "chrome/browser/profiles/avatar_menu.h"
#include "chrome/browser/profiles/avatar_menu_observer.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/sync/sync_ui_util.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/profile_chooser_constants.h"
#include "components/signin/core/browser/signin_header_helper.h"
......@@ -155,7 +156,15 @@ class ProfileChooserView : public content::WebContentsDelegate,
void RemoveAccount();
// Creates a header for signin and sync error surfacing for the user menu.
views::View* CreateSyncErrorViewIfNeeded();
views::View* CreateSyncErrorViewIfNeeded(const AvatarMenu::Item& avatar_item);
// Creates a view with a red HoverButton, which displays the profile icon
// associated with |avatar_item| and the strings associated with
// |title_string_id| and |subtitle_string_id|.
views::View* CreateDiceSyncErrorView(const AvatarMenu::Item& avatar_item,
sync_ui_util::AvatarSyncErrorType error,
int title_string_id,
int subtitle_string_id);
bool ShouldShowGoIncognito() const;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment