Commit 5377b50f authored by Thomas Tangl's avatar Thomas Tangl Committed by Commit Bot

Replace EditableProfilePhoto with BadgedProfilePhoto

The class EditableProfilePhoto is replaced with BadgedProfilePhoto because
the editable-option has been dropped from that class. The class
is moved to a separate file, so it is easier to maintain and extend
(which will happen in the implementation for the DICe UI).

Bug: 783152
Change-Id: I25fb7b1f3bf9f168ca23a90390365b13679c4eb6
Reviewed-on: https://chromium-review.googlesource.com/725293
Commit-Queue: Thomas Tangl <tangltom@chromium.org>
Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Reviewed-by: default avatarVasilii Sukhanov <vasilii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517112}
parent 10d30781
...@@ -1561,6 +1561,8 @@ split_static_library("ui") { ...@@ -1561,6 +1561,8 @@ split_static_library("ui") {
"views/external_protocol_dialog.cc", "views/external_protocol_dialog.cc",
"views/external_protocol_dialog.h", "views/external_protocol_dialog.h",
"views/profiles/avatar_button_style.h", "views/profiles/avatar_button_style.h",
"views/profiles/badged_profile_photo.cc",
"views/profiles/badged_profile_photo.h",
"views/profiles/profile_chooser_view.cc", "views/profiles/profile_chooser_view.cc",
"views/profiles/profile_chooser_view.h", "views/profiles/profile_chooser_view.h",
"webui/app_launcher_page_ui.cc", "webui/app_launcher_page_ui.cc",
......
// 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.
#include "chrome/browser/ui/views/profiles/badged_profile_photo.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/controls/image_view.h"
namespace {
constexpr int kBadgeIconSize = 16;
constexpr int kBadgeBorderWidth = 2;
// Width/Height of the current profile photo.
constexpr int kImageSize = 40;
// The space between the right/bottom edge of the profile badge and the
// right/bottom edge of the profile icon.
constexpr int kBadgeSpacing = 4;
// Width and Height of the badged profile photo. Doesn't include the badge
// border to the right and to the bottom.
constexpr int kBadgedProfilePhotoWidth = kImageSize + kBadgeSpacing;
constexpr int kBadgedProfilePhotoHeight = kImageSize;
// A custom ImageView that removes the part where the badge will be placed
// including the (transparent) border.
class CustomImageView : public views::ImageView {
public:
CustomImageView() = default;
private:
// views::ImageView:
void OnPaint(gfx::Canvas* canvas) override;
DISALLOW_COPY_AND_ASSIGN(CustomImageView);
};
void CustomImageView::OnPaint(gfx::Canvas* canvas) {
// Remove the part of the ImageView that contains the badge.
gfx::Path mask;
mask.addCircle(
GetMirroredXInView(kBadgedProfilePhotoWidth - kBadgeIconSize / 2),
kBadgedProfilePhotoHeight - kBadgeIconSize / 2,
kBadgeIconSize / 2 + kBadgeBorderWidth);
mask.toggleInverseFillType();
canvas->ClipPath(mask, true);
ImageView::OnPaint(canvas);
}
// Helpers --------------------------------------------------------------------
gfx::ImageSkia ImageForBadgeType(BadgedProfilePhoto::BadgeType badge_type) {
switch (badge_type) {
case BadgedProfilePhoto::BADGE_TYPE_SUPERVISOR:
return gfx::CreateVectorIcon(kSupervisorAccountCircleIcon, kBadgeIconSize,
gfx::kChromeIconGrey);
case BadgedProfilePhoto::BADGE_TYPE_CHILD:
return gfx::CreateVectorIcon(kAccountChildCircleIcon, kBadgeIconSize,
gfx::kChromeIconGrey);
case BadgedProfilePhoto::BADGE_TYPE_NONE:
NOTREACHED();
return gfx::ImageSkia();
}
NOTREACHED();
return gfx::ImageSkia();
}
} // namespace
// static
const char BadgedProfilePhoto::kViewClassName[] = "BadgedProfilePhoto";
// BadgedProfilePhoto -------------------------------------------------
BadgedProfilePhoto::BadgedProfilePhoto(BadgeType badge_type,
const gfx::Image& profile_photo) {
set_can_process_events_within_subtree(false);
// Create and add image view for profile icon.
gfx::Image profile_photo_circular = profiles::GetSizedAvatarIcon(
profile_photo, true, kImageSize, kImageSize, profiles::SHAPE_CIRCLE);
views::ImageView* profile_photo_view = badge_type == BADGE_TYPE_NONE
? new views::ImageView()
: new CustomImageView();
profile_photo_view->SetImage(*profile_photo_circular.ToImageSkia());
profile_photo_view->SizeToPreferredSize();
AddChildView(profile_photo_view);
if (badge_type != BADGE_TYPE_NONE) {
// Create and add image view for badge icon.
views::ImageView* badge_view = new views::ImageView();
badge_view->SetImage(ImageForBadgeType(badge_type));
badge_view->SizeToPreferredSize();
AddChildView(badge_view);
badge_view->SetPosition(
gfx::Point(kBadgedProfilePhotoWidth - kBadgeIconSize,
kBadgedProfilePhotoHeight - kBadgeIconSize));
}
SetPreferredSize(
gfx::Size(kBadgedProfilePhotoWidth, kBadgedProfilePhotoHeight));
}
const char* BadgedProfilePhoto::GetClassName() const {
return kViewClassName;
}
// 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.
#ifndef CHROME_BROWSER_UI_VIEWS_PROFILES_BADGED_PROFILE_PHOTO_H_
#define CHROME_BROWSER_UI_VIEWS_PROFILES_BADGED_PROFILE_PHOTO_H_
#include "ui/gfx/image/image.h"
#include "ui/views/view.h"
// Creates a bagded profile photo for the current profile card in the
// profile chooser menu. The view includes the photo and the badge itself,
// but not the bagde border to the right and to the bottom.
// More badges, e.g. for syncing, will be supported in the future (project
// DICE).
class BadgedProfilePhoto : public views::View {
public:
enum BadgeType {
BADGE_TYPE_NONE,
BADGE_TYPE_SUPERVISOR,
BADGE_TYPE_CHILD,
};
static const char kViewClassName[];
// Constructs a View hierarchy with the gfx::ImageSkia corresponding to
// |badge_type| positioned in the bottom-right corner of |profile_photo|. In
// RTL mode the badge is positioned in the bottom-left corner. The profile
// photo will be adjusted to be circular and of size 40x40 (kImageSize).
// If |badge_type| is BADGE_TYPE_NONE no badge will be placed on top of the
// profile photo. The size of the View is fixed.
// TODO(tangltom): Add accessibility features in the future.
BadgedProfilePhoto(BadgeType badge_type, const gfx::Image& profile_photo);
// views::View:
const char* GetClassName() const override;
private:
DISALLOW_COPY_AND_ASSIGN(BadgedProfilePhoto);
};
#endif // CHROME_BROWSER_UI_VIEWS_PROFILES_BADGED_PROFILE_PHOTO_H_
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h"
#include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/browser/ui/views/harmony/chrome_typography.h"
#include "chrome/browser/ui/views/hover_button.h" #include "chrome/browser/ui/views/hover_button.h"
#include "chrome/browser/ui/views/profiles/badged_profile_photo.h"
#include "chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h" #include "chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h"
#include "chrome/browser/ui/views/profiles/user_manager_view.h" #include "chrome/browser/ui/views/profiles/user_manager_view.h"
#include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h"
...@@ -100,14 +101,7 @@ namespace { ...@@ -100,14 +101,7 @@ namespace {
const int kButtonHeight = 32; const int kButtonHeight = 32;
const int kFixedAccountRemovalViewWidth = 280; const int kFixedAccountRemovalViewWidth = 280;
const int kImageSide = 40;
const int kProfileBadgeSize = 24;
const int kFixedMenuWidth = 240; const int kFixedMenuWidth = 240;
const int kSupervisedIconBadgeSize = 22;
// The space between the right/bottom edge of the profile badge and the
// right/bottom edge of the profile icon.
const int kBadgeSpacing = 4;
// Spacing between the edge of the material design user menu and the // Spacing between the edge of the material design user menu and the
// top/bottom or left/right of the menu items. // top/bottom or left/right of the menu items.
...@@ -172,109 +166,14 @@ views::ImageButton* CreateBackButton(views::ButtonListener* listener) { ...@@ -172,109 +166,14 @@ views::ImageButton* CreateBackButton(views::ButtonListener* listener) {
return back_button; return back_button;
} }
} // namespace BadgedProfilePhoto::BadgeType GetProfileBadgeType(const Profile* profile) {
if (!profile->IsSupervised())
// EditableProfilePhoto ------------------------------------------------- return BadgedProfilePhoto::BADGE_TYPE_NONE;
return profile->IsChild() ? BadgedProfilePhoto::BADGE_TYPE_CHILD
// A custom Image control that shows a "change" button when moused over. : BadgedProfilePhoto::BADGE_TYPE_SUPERVISOR;
class EditableProfilePhoto : public views::LabelButton { }
public:
EditableProfilePhoto(views::ButtonListener* listener,
const gfx::Image& icon,
bool is_editing_allowed,
Profile* profile)
: views::LabelButton(listener, base::string16()),
photo_overlay_(nullptr),
profile_(profile) {
set_can_process_events_within_subtree(false);
gfx::Image image =
profiles::GetSizedAvatarIcon(icon, true, kImageSide, kImageSide);
SetImage(views::LabelButton::STATE_NORMAL, *image.ToImageSkia());
SetBorder(views::NullBorder());
// Supervised users have a special badge, so add extra space for it.
const int extra_space = profile_->IsSupervised() ? kBadgeSpacing : 0;
SetMinSize(gfx::Size(GetPreferredSize().width() + extra_space,
GetPreferredSize().height() + extra_space));
SetEnabled(false);
}
void PaintChildren(const views::PaintInfo& paint_info) override {
{
// Display any children (the "change photo" overlay) as a circle.
ui::ClipRecorder clip_recorder(paint_info.context());
gfx::Rect clip_bounds = image()->GetMirroredBounds();
gfx::Path clip_mask;
clip_mask.addCircle(
clip_bounds.x() + clip_bounds.width() / 2,
clip_bounds.y() + clip_bounds.height() / 2,
clip_bounds.width() / 2);
clip_recorder.ClipPathWithAntiAliasing(clip_mask);
View::PaintChildren(paint_info);
}
if (profile_->IsSupervised()) {
ui::PaintRecorder paint_recorder(
paint_info.context(),
gfx::Size(kProfileBadgeSize, kProfileBadgeSize));
gfx::Canvas* canvas = paint_recorder.canvas();
gfx::Rect bounds(0, 0, kProfileBadgeSize, kProfileBadgeSize);
int badge_offset = kImageSide + kBadgeSpacing - kProfileBadgeSize;
gfx::Vector2d badge_offset_vector = gfx::Vector2d(
GetMirroredXWithWidthInView(badge_offset, kProfileBadgeSize),
badge_offset);
gfx::Point center_point = bounds.CenterPoint() + badge_offset_vector;
// Paint the circular background.
cc::PaintFlags flags;
flags.setAntiAlias(true);
flags.setColor(GetNativeTheme()->GetSystemColor(
ui::NativeTheme::kColorId_BubbleBackground));
canvas->DrawCircle(center_point, kProfileBadgeSize / 2, flags);
const gfx::VectorIcon* icon = profile_->IsChild()
? &kAccountChildCircleIcon
: &kSupervisorAccountCircleIcon;
// Paint the badge icon.
int offset = (kProfileBadgeSize - kSupervisedIconBadgeSize) / 2;
canvas->Translate(badge_offset_vector + gfx::Vector2d(offset, offset));
gfx::PaintVectorIcon(canvas, *icon, kSupervisedIconBadgeSize,
gfx::kChromeIconGrey);
}
}
private:
// views::Button:
void StateChanged(ButtonState old_state) override {
if (photo_overlay_) {
photo_overlay_->SetVisible(
state() == STATE_PRESSED || state() == STATE_HOVERED || HasFocus());
}
}
void OnFocus() override {
views::LabelButton::OnFocus();
if (photo_overlay_)
photo_overlay_->SetVisible(true);
}
void OnBlur() override {
views::LabelButton::OnBlur();
// Don't hide the overlay if it's being shown as a result of a mouseover.
if (photo_overlay_ && state() != STATE_HOVERED)
photo_overlay_->SetVisible(false);
}
// Image that is shown when hovering over the image button. Can be NULL if
// the photo isn't allowed to be edited (e.g. for guest profiles).
views::ImageView* photo_overlay_;
Profile* profile_;
DISALLOW_COPY_AND_ASSIGN(EditableProfilePhoto); } // namespace
};
// A title card with one back button left aligned and one label center aligned. // A title card with one back button left aligned and one label center aligned.
class TitleCard : public views::View { class TitleCard : public views::View {
...@@ -948,8 +847,8 @@ views::View* ProfileChooserView::CreateCurrentProfileView( ...@@ -948,8 +847,8 @@ views::View* ProfileChooserView::CreateCurrentProfileView(
new views::BoxLayout(views::BoxLayout::kVertical, new views::BoxLayout(views::BoxLayout::kVertical,
gfx::Insets(content_list_vert_spacing, 0), 0)); gfx::Insets(content_list_vert_spacing, 0), 0));
auto current_profile_photo = std::make_unique<EditableProfilePhoto>( auto current_profile_photo = std::make_unique<BadgedProfilePhoto>(
this, avatar_item.icon, !is_guest, browser_->profile()); GetProfileBadgeType(browser_->profile()), avatar_item.icon);
const base::string16 profile_name = const base::string16 profile_name =
profiles::GetAvatarNameForProfile(browser_->profile()->GetPath()); profiles::GetAvatarNameForProfile(browser_->profile()->GetPath());
......
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