blob: be702b458ede5f36401e3dc948c452a8e989eab5 [file] [log] [blame]
// Copyright 2013 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/toolbar/browser_app_menu_button.h"
#include <set>
#include "base/bind.h"
#include "base/location.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "build/chromeos_buildflags.h"
#include "cc/paint/paint_flags.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_otr_state.h"
#include "chrome/browser/ui/color/chrome_color_id.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/toolbar/app_menu_model.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/toolbar/app_menu.h"
#include "chrome/browser/ui/views/toolbar/toolbar_ink_drop_util.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
#include "components/feature_engagement/public/feature_constants.h"
#include "components/user_education/common/feature_promo_controller.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/animation/throb_animation.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/animation/animation_delegate_views.h"
#include "ui/views/animation/ink_drop.h"
#include "ui/views/animation/ink_drop_highlight.h"
#include "ui/views/animation/ink_drop_state.h"
#include "ui/views/controls/button/label_button_border.h"
#include "ui/views/metrics.h"
#include "ui/views/view.h"
#include "ui/views/view_class_properties.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
// static
bool BrowserAppMenuButton::g_open_app_immediately_for_testing = false;
BrowserAppMenuButton::BrowserAppMenuButton(ToolbarView* toolbar_view)
: AppMenuButton(base::BindRepeating(&BrowserAppMenuButton::ButtonPressed,
base::Unretained(this))),
toolbar_view_(toolbar_view) {
SetHorizontalAlignment(gfx::ALIGN_RIGHT);
}
BrowserAppMenuButton::~BrowserAppMenuButton() {}
void BrowserAppMenuButton::SetTypeAndSeverity(
AppMenuIconController::TypeAndSeverity type_and_severity) {
type_and_severity_ = type_and_severity;
UpdateIcon();
UpdateTextAndHighlightColor();
}
void BrowserAppMenuButton::ShowMenu(int run_types) {
if (IsMenuShowing())
return;
#if BUILDFLAG(IS_CHROMEOS_ASH)
auto* keyboard_client = ChromeKeyboardControllerClient::Get();
if (keyboard_client->is_keyboard_visible())
keyboard_client->HideKeyboard(ash::HideReason::kSystem);
#endif
Browser* browser = toolbar_view_->browser();
// If the menu was opened while reopen tab in-product help was
// showing, we continue the IPH into the menu. Notify the promo
// controller we are taking control of the promo.
reopen_tab_promo_handle_ = browser->window()->CloseFeaturePromoAndContinue(
feature_engagement::kIPHReopenTabFeature);
RunMenu(
std::make_unique<AppMenuModel>(toolbar_view_, browser,
toolbar_view_->app_menu_icon_controller()),
browser, run_types, reopen_tab_promo_handle_.is_valid());
}
void BrowserAppMenuButton::OnThemeChanged() {
UpdateTextAndHighlightColor();
AppMenuButton::OnThemeChanged();
}
void BrowserAppMenuButton::UpdateIcon() {
const gfx::VectorIcon& icon = ui::TouchUiController::Get()->touch_ui()
? kBrowserToolsTouchIcon
: kBrowserToolsIcon;
for (auto state : kButtonStates) {
SkColor icon_color =
toolbar_view_->app_menu_icon_controller()->GetIconColor(
GetForegroundColor(state));
SetImageModel(state, ui::ImageModel::FromVectorIcon(icon, icon_color));
}
}
void BrowserAppMenuButton::HandleMenuClosed() {
// If we were showing a promo in the menu, drop the handle to notify
// FeaturePromoController we're done. This is a no-op if we weren't
// showing the promo.
reopen_tab_promo_handle_.Release();
}
void BrowserAppMenuButton::UpdateTextAndHighlightColor() {
int tooltip_message_id;
std::u16string text;
if (type_and_severity_.severity == AppMenuIconController::Severity::NONE) {
tooltip_message_id = IDS_APPMENU_TOOLTIP;
} else if (type_and_severity_.type ==
AppMenuIconController::IconType::UPGRADE_NOTIFICATION) {
tooltip_message_id = IDS_APPMENU_TOOLTIP_UPDATE_AVAILABLE;
text = l10n_util::GetStringUTF16(IDS_APP_MENU_BUTTON_UPDATE);
} else {
tooltip_message_id = IDS_APPMENU_TOOLTIP_ALERT;
text = l10n_util::GetStringUTF16(IDS_APP_MENU_BUTTON_ERROR);
}
absl::optional<SkColor> color;
const auto* const color_provider = GetColorProvider();
switch (type_and_severity_.severity) {
case AppMenuIconController::Severity::NONE:
break;
case AppMenuIconController::Severity::LOW:
color = color_provider->GetColor(kColorAppMenuHighlightSeverityLow);
break;
case AppMenuIconController::Severity::MEDIUM:
color = color_provider->GetColor(kColorAppMenuHighlightSeverityMedium);
break;
case AppMenuIconController::Severity::HIGH:
color = color_provider->GetColor(kColorAppMenuHighlightSeverityHigh);
break;
}
SetTooltipText(l10n_util::GetStringUTF16(tooltip_message_id));
SetHighlight(text, color);
}
void BrowserAppMenuButton::OnTouchUiChanged() {
UpdateColorsAndInsets();
PreferredSizeChanged();
}
void BrowserAppMenuButton::ButtonPressed(const ui::Event& event) {
ShowMenu(event.IsKeyEvent() ? views::MenuRunner::SHOULD_SHOW_MNEMONICS
: views::MenuRunner::NO_FLAGS);
}
BEGIN_METADATA(BrowserAppMenuButton, AppMenuButton)
END_METADATA