blob: eb6b7ce2eaa45ea4aac665395ef3e4339c87e39f [file] [log] [blame]
// Copyright 2020 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/location_bar/omnibox_chip_button.h"
#include "base/location.h"
#include "base/time/time.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/controls/highlight_path_generator.h"
#include "ui/views/metadata/metadata_impl_macros.h"
OmniboxChipButton::OmniboxChipButton(PressedCallback callback,
int button_context)
: MdTextButton(std::move(callback), std::u16string(), button_context) {
views::InstallPillHighlightPathGenerator(this);
SetCornerRadius(GetIconSize());
SetHorizontalAlignment(gfx::ALIGN_LEFT);
SetElideBehavior(gfx::ElideBehavior::FADE_TAIL);
SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
// Equalizing padding on the left, right and between icon and label.
SetImageLabelSpacing(
GetLayoutInsets(LOCATION_BAR_ICON_INTERIOR_PADDING).left());
SetCustomPadding(
gfx::Insets(GetLayoutConstant(LOCATION_BAR_CHILD_INTERIOR_PADDING),
GetLayoutInsets(LOCATION_BAR_ICON_INTERIOR_PADDING).left()));
constexpr auto kAnimationDuration = base::TimeDelta::FromMilliseconds(350);
animation_ = std::make_unique<gfx::SlideAnimation>(this);
animation_->SetSlideDuration(kAnimationDuration);
}
OmniboxChipButton::~OmniboxChipButton() = default;
void OmniboxChipButton::AnimateCollapse() {
constexpr auto kAnimationDuration = base::TimeDelta::FromMilliseconds(250);
animation_->SetSlideDuration(kAnimationDuration);
animation_->Hide();
}
void OmniboxChipButton::AnimateExpand() {
constexpr auto kAnimationDuration = base::TimeDelta::FromMilliseconds(350);
animation_->SetSlideDuration(kAnimationDuration);
animation_->Show();
}
void OmniboxChipButton::ResetAnimation(double value) {
animation_->Reset(value);
}
void OmniboxChipButton::SetIcon(const gfx::VectorIcon* icon) {
icon_ = icon;
UpdateColors();
}
void OmniboxChipButton::SetExpandAnimationEndedCallback(
base::RepeatingCallback<void()> callback) {
expand_animation_ended_callback_ = callback;
}
gfx::Size OmniboxChipButton::CalculatePreferredSize() const {
const int fixed_width = GetIconSize() + GetInsets().width();
const int collapsable_width =
label()->GetPreferredSize().width() + GetInsets().right();
const double animation_value =
force_expanded_for_testing_ ? 1.0 : animation_->GetCurrentValue();
const int width =
std::round(collapsable_width * animation_value) + fixed_width;
return gfx::Size(width, GetHeightForWidth(width));
}
void OmniboxChipButton::OnThemeChanged() {
View::OnThemeChanged();
UpdateColors();
}
void OmniboxChipButton::AnimationEnded(const gfx::Animation* animation) {
if (animation != animation_.get())
return;
fully_collapsed_ = animation->GetCurrentValue() != 1.0;
if (animation->GetCurrentValue() == 1.0)
expand_animation_ended_callback_.Run();
}
void OmniboxChipButton::AnimationProgressed(const gfx::Animation* animation) {
if (animation == animation_.get())
PreferredSizeChanged();
}
void OmniboxChipButton::SetTheme(Theme theme) {
theme_ = theme;
UpdateColors();
}
void OmniboxChipButton::SetProminent(bool is_prominent) {
views::MdTextButton::SetProminent(is_prominent);
UpdateColors();
}
int OmniboxChipButton::GetIconSize() const {
return GetLayoutConstant(LOCATION_BAR_ICON_SIZE);
}
void OmniboxChipButton::UpdateColors() {
if (!icon_)
return;
SetEnabledTextColors(GetForegroundColor());
SetImageModel(views::Button::STATE_NORMAL,
ui::ImageModel::FromVectorIcon(*icon_, GetForegroundColor(),
GetIconSize()));
SetBgColorOverride(GetBackgroundColor());
}
SkColor OmniboxChipButton::GetMainColor() {
ui::NativeTheme* native_theme = GetNativeTheme();
switch (theme_) {
case Theme::kBlue:
// TODO(crbug.com/1003612): ui::NativeTheme::kColorId_ProminentButtonColor
// does not always represent the blue color we need, but it is OK to use
// for now.
return native_theme->GetSystemColor(
ui::NativeTheme::kColorId_ProminentButtonColor);
}
}
SkColor OmniboxChipButton::GetNeutralColor() {
return views::style::GetColor(*this, label()->GetTextContext(),
views::style::STYLE_DIALOG_BUTTON_DEFAULT);
}
SkColor OmniboxChipButton::GetForegroundColor() {
return GetProminent() ? GetNeutralColor() : GetMainColor();
}
SkColor OmniboxChipButton::GetBackgroundColor() {
return GetProminent() ? GetMainColor() : GetNeutralColor();
}
void OmniboxChipButton::SetForceExpandedForTesting(
bool force_expanded_for_testing) {
force_expanded_for_testing_ = force_expanded_for_testing;
}
BEGIN_METADATA(OmniboxChipButton, views::MdTextButton)
ADD_READONLY_PROPERTY_METADATA(int, IconSize)
END_METADATA