blob: 5ad7ee75f267b026820d29814840702fffb2ddb7 [file] [log] [blame]
// Copyright 2018 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 "ash/login/ui/login_public_account_user_view.h"
#include <memory>
#include "ash/login/ui/arrow_button_view.h"
#include "ash/login/ui/hover_notifier.h"
#include "ash/login/ui/login_display_style.h"
#include "ash/login/ui/views_utils.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/views/layout/box_layout.h"
namespace ash {
namespace {
constexpr char kLoginPublicAccountUserViewClassName[] =
"LoginPublicAccountUserView";
// Color of the user domain text.
constexpr SkColor kArrowButtonBackground =
SkColorSetARGB(0x2B, 0xFF, 0xFF, 0xFF);
// Distance from the top of the user view to the user icon.
constexpr int kDistanceFromTopOfBigUserViewToUserIconDp = 54;
// Distance from the top of the user view to the user icon.
constexpr int kDistanceFromUserViewToArrowButton = 44;
// Distance from the end of arrow button to the bottom of the big user view.
constexpr int kDistanceFromArrowButtonToBigUserViewBottom = 20;
constexpr int kArrowButtonSizeDp = 40;
// Non-empty width, useful for debugging/visualization.
constexpr int kNonEmptyWidth = 1;
constexpr int kArrowButtonFadeAnimationDurationMs = 180;
} // namespace
LoginPublicAccountUserView::TestApi::TestApi(LoginPublicAccountUserView* view)
: view_(view) {}
LoginPublicAccountUserView::TestApi::~TestApi() = default;
views::View* LoginPublicAccountUserView::TestApi::arrow_button() const {
return view_->arrow_button_;
}
LoginPublicAccountUserView::Callbacks::Callbacks() = default;
LoginPublicAccountUserView::Callbacks::Callbacks(const Callbacks& other) =
default;
LoginPublicAccountUserView::Callbacks::~Callbacks() = default;
LoginPublicAccountUserView::LoginPublicAccountUserView(
const mojom::LoginUserInfoPtr& user,
const Callbacks& callbacks)
: NonAccessibleView(kLoginPublicAccountUserViewClassName),
on_tap_(callbacks.on_tap),
on_public_account_tap_(callbacks.on_public_account_tapped) {
DCHECK_EQ(user->basic_user_info->type,
user_manager::USER_TYPE_PUBLIC_ACCOUNT);
DCHECK(callbacks.on_tap);
DCHECK(callbacks.on_public_account_tapped);
user_view_ = new LoginUserView(
LoginDisplayStyle::kLarge, false /*show_dropdown*/, true /*show_domain*/,
base::BindRepeating(&LoginPublicAccountUserView::OnUserViewTap,
base::Unretained(this)),
base::RepeatingClosure(), base::RepeatingClosure());
arrow_button_ = new ArrowButtonView(this, kArrowButtonSizeDp);
arrow_button_->SetBackgroundColor(kArrowButtonBackground);
arrow_button_->SetFocusPainter(nullptr);
SetPaintToLayer(ui::LayerType::LAYER_NOT_DRAWN);
// build layout for public account.
SetLayoutManager(
std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical));
views::View* wrapped_user_view =
login_views_utils::WrapViewForPreferredSize(user_view_);
auto add_padding = [&](int amount) {
auto* padding = new NonAccessibleView();
padding->SetPreferredSize(gfx::Size(kNonEmptyWidth, amount));
AddChildView(padding);
};
add_padding(kDistanceFromTopOfBigUserViewToUserIconDp);
AddChildView(wrapped_user_view);
add_padding(kDistanceFromUserViewToArrowButton);
AddChildView(arrow_button_);
add_padding(kDistanceFromArrowButtonToBigUserViewBottom);
// Update authentication UI.
SetAuthEnabled(auth_enabled_, false /*animate*/);
user_view_->UpdateForUser(user, false /*animate*/);
hover_notifier_ = std::make_unique<HoverNotifier>(
this, base::BindRepeating(&LoginPublicAccountUserView::OnHover,
base::Unretained(this)));
}
LoginPublicAccountUserView::~LoginPublicAccountUserView() = default;
void LoginPublicAccountUserView::SetAuthEnabled(bool enabled, bool animate) {
auth_enabled_ = enabled;
ignore_hover_ = enabled;
UpdateArrowButtonOpacity(enabled ? 1 : 0, animate);
arrow_button_->SetFocusBehavior(enabled ? FocusBehavior::ALWAYS
: FocusBehavior::NEVER);
// Only the active auth user view has auth enabled. If that is the
// case, then render the user view as if it was always focused, since clicking
// on it will not do anything (such as swapping users).
user_view_->SetForceOpaque(enabled);
user_view_->SetTapEnabled(!enabled);
if (enabled)
arrow_button_->RequestFocus();
PreferredSizeChanged();
}
void LoginPublicAccountUserView::UpdateForUser(
const mojom::LoginUserInfoPtr& user) {
user_view_->UpdateForUser(user, true /*animate*/);
}
const mojom::LoginUserInfoPtr& LoginPublicAccountUserView::current_user()
const {
return user_view_->current_user();
}
gfx::Size LoginPublicAccountUserView::CalculatePreferredSize() const {
gfx::Size size = views::View::CalculatePreferredSize();
// Make sure we are at least as big as the user view. If we do not do this the
// view will be below minimum size when no auth methods are displayed.
size.SetToMax(user_view_->GetPreferredSize());
return size;
}
void LoginPublicAccountUserView::ButtonPressed(views::Button* sender,
const ui::Event& event) {
if (sender == arrow_button_) {
DCHECK(arrow_button_);
on_public_account_tap_.Run();
}
}
void LoginPublicAccountUserView::OnUserViewTap() {
on_tap_.Run();
}
void LoginPublicAccountUserView::OnHover(bool has_hover) {
if (!ignore_hover_)
UpdateArrowButtonOpacity(has_hover ? 1 : 0, true /*animate*/);
}
void LoginPublicAccountUserView::UpdateArrowButtonOpacity(float target_opacity,
bool animate) {
if (!animate) {
arrow_button_->layer()->SetOpacity(target_opacity);
return;
}
// Set up animation.
{
ui::ScopedLayerAnimationSettings settings(
arrow_button_->layer()->GetAnimator());
settings.SetTransitionDuration(
base::TimeDelta::FromMilliseconds(kArrowButtonFadeAnimationDurationMs));
settings.SetTweenType(gfx::Tween::EASE_IN_OUT);
arrow_button_->layer()->SetOpacity(target_opacity);
}
}
} // namespace ash