blob: df761d081d45b787aa9322789a89a044b38a64f4 [file] [log] [blame]
// Copyright (c) 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 "chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/omnibox/omnibox_theme.h"
#include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h"
#include "chrome/browser/ui/views/omnibox/omnibox_result_view.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/omnibox/browser/vector_icons.h"
#include "components/strings/grit/components_strings.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/animation/ink_drop_mask.h"
#include "ui/views/controls/highlight_path_generator.h"
// static
bool OmniboxTabSwitchButton::calculated_widths_ = false;
int OmniboxTabSwitchButton::icon_only_width_;
int OmniboxTabSwitchButton::short_text_width_;
int OmniboxTabSwitchButton::full_text_width_;
OmniboxTabSwitchButton::OmniboxTabSwitchButton(
OmniboxPopupContentsView* popup_contents_view,
OmniboxResultView* result_view,
const base::string16& hint,
const base::string16& hint_short,
const gfx::VectorIcon& icon)
: MdTextButton(result_view, views::style::CONTEXT_BUTTON_MD),
popup_contents_view_(popup_contents_view),
result_view_(result_view),
hint_(hint),
hint_short_(hint_short) {
views::InstallPillHighlightPathGenerator(this);
SetImage(STATE_NORMAL, gfx::CreateVectorIcon(
icon, GetLayoutConstant(LOCATION_BAR_ICON_SIZE),
gfx::kChromeIconGrey));
SetImageLabelSpacing(8);
if (!calculated_widths_) {
icon_only_width_ = MdTextButton::CalculatePreferredSize().width();
SetText(hint_short_);
short_text_width_ = MdTextButton::CalculatePreferredSize().width();
SetText(hint_);
full_text_width_ = MdTextButton::CalculatePreferredSize().width();
calculated_widths_ = true;
} else {
SetText(hint_);
}
SetPreferredSize({full_text_width_, 32});
SetCornerRadius(views::LayoutProvider::Get()->GetCornerRadiusMetric(
views::EMPHASIS_MAXIMUM, GetPreferredSize()));
SetTooltipText(hint_);
SetElideBehavior(gfx::FADE_TAIL);
SetInstallFocusRingOnFocus(true);
focus_ring()->SetHasFocusPredicate([](View* view) {
auto* button = static_cast<OmniboxTabSwitchButton*>(view);
return button->IsSelected();
});
}
OmniboxTabSwitchButton::~OmniboxTabSwitchButton() = default;
void OmniboxTabSwitchButton::StateChanged(ButtonState old_state) {
if (state() == STATE_NORMAL && old_state == STATE_PRESSED) {
SetMouseHandler(parent());
if (popup_contents_view_->IsButtonSelected())
popup_contents_view_->UnselectButton();
}
MdTextButton::StateChanged(old_state);
}
void OmniboxTabSwitchButton::OnThemeChanged() {
views::MdTextButton::OnThemeChanged();
SetBgColorOverride(GetOmniboxColor(GetThemeProvider(),
OmniboxPart::RESULTS_BACKGROUND,
OmniboxPartState::NORMAL));
}
void OmniboxTabSwitchButton::GetAccessibleNodeData(ui::AXNodeData* node_data) {
node_data->SetName(l10n_util::GetStringUTF8(IDS_ACC_TAB_SWITCH_BUTTON));
// Although this appears visually as a button, expose as a list box option so
// that it matches the other options within its list box container.
node_data->role = ax::mojom::Role::kListBoxOption;
node_data->AddBoolAttribute(ax::mojom::BoolAttribute::kSelected,
IsSelected());
}
void OmniboxTabSwitchButton::UpdateBackground() {
focus_ring()->SchedulePaint();
}
void OmniboxTabSwitchButton::ProvideWidthHint(int parent_width) {
base::string16 text;
int preferred_width = CalculateGoalWidth(parent_width, &text);
SetText(text);
SetPreferredSize({preferred_width, GetPreferredSize().height()});
}
void OmniboxTabSwitchButton::ProvideFocusHint() {
NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true);
}
bool OmniboxTabSwitchButton::IsSelected() const {
// Is this result selected and is button selected?
return result_view_->IsSelected() && popup_contents_view_->IsButtonSelected();
}
int OmniboxTabSwitchButton::CalculateGoalWidth(int parent_width,
base::string16* goal_text) {
if (full_text_width_ * 5 <= parent_width) {
*goal_text = hint_;
return full_text_width_;
}
if (short_text_width_ * 5 <= parent_width) {
*goal_text = hint_short_;
return short_text_width_;
}
*goal_text = base::string16();
return (icon_only_width_ * 5 <= parent_width) ? icon_only_width_ : 0;
}