blob: 298654030d87dea886bf0f82dcd2edb352acb586 [file] [log] [blame]
// Copyright 2016 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/toolbar_actions_bar_bubble_views.h"
#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h"
#include "chrome/grit/locale_settings.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/link.h"
#include "ui/views/layout/box_layout.h"
namespace {
const int kIconSize = 16;
}
ToolbarActionsBarBubbleViews::ToolbarActionsBarBubbleViews(
views::View* anchor_view,
const gfx::Point& anchor_point,
bool anchored_to_action,
std::unique_ptr<ToolbarActionsBarBubbleDelegate> delegate)
: views::BubbleDialogDelegateView(anchor_view,
views::BubbleBorder::TOP_RIGHT),
delegate_(std::move(delegate)),
delegate_notified_of_close_(false),
item_list_(nullptr),
link_(nullptr),
anchored_to_action_(anchored_to_action) {
set_close_on_deactivate(delegate_->ShouldCloseOnDeactivate());
if (!anchor_view)
SetAnchorRect(gfx::Rect(anchor_point, gfx::Size()));
}
ToolbarActionsBarBubbleViews::~ToolbarActionsBarBubbleViews() {}
void ToolbarActionsBarBubbleViews::Show() {
delegate_->OnBubbleShown();
GetWidget()->Show();
}
views::View* ToolbarActionsBarBubbleViews::CreateExtraView() {
std::unique_ptr<ToolbarActionsBarBubbleDelegate::ExtraViewInfo>
extra_view_info = delegate_->GetExtraViewInfo();
if (!extra_view_info)
return nullptr;
std::unique_ptr<views::ImageView> icon;
if (extra_view_info->resource) {
icon.reset(new views::ImageView);
icon->SetImage(gfx::CreateVectorIcon(*extra_view_info->resource, kIconSize,
gfx::kChromeIconGrey));
}
std::unique_ptr<views::Label> label;
const base::string16& text = extra_view_info->text;
if (!text.empty()) {
if (extra_view_info->is_text_linked) {
link_ = new views::Link(text);
link_->set_listener(this);
label.reset(link_);
} else {
label.reset(new views::Label(text));
}
}
if (icon && label) {
views::View* parent = new views::View();
parent->SetLayoutManager(
new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0,
ChromeLayoutProvider::Get()->GetDistanceMetric(
views::DISTANCE_RELATED_CONTROL_VERTICAL)));
parent->AddChildView(icon.release());
parent->AddChildView(label.release());
return parent;
}
return icon ? static_cast<views::View*>(icon.release())
: static_cast<views::View*>(label.release());
}
base::string16 ToolbarActionsBarBubbleViews::GetWindowTitle() const {
return delegate_->GetHeadingText();
}
bool ToolbarActionsBarBubbleViews::Cancel() {
DCHECK(!delegate_notified_of_close_);
delegate_notified_of_close_ = true;
delegate_->OnBubbleClosed(
ToolbarActionsBarBubbleDelegate::CLOSE_DISMISS_USER_ACTION);
return true;
}
bool ToolbarActionsBarBubbleViews::Accept() {
DCHECK(!delegate_notified_of_close_);
delegate_notified_of_close_ = true;
delegate_->OnBubbleClosed(ToolbarActionsBarBubbleDelegate::CLOSE_EXECUTE);
return true;
}
bool ToolbarActionsBarBubbleViews::Close() {
// If the user took any action, the delegate will have been notified already.
// Otherwise, this was dismissal due to deactivation.
if (!delegate_notified_of_close_) {
delegate_notified_of_close_ = true;
delegate_->OnBubbleClosed(
ToolbarActionsBarBubbleDelegate::CLOSE_DISMISS_DEACTIVATION);
}
return true;
}
void ToolbarActionsBarBubbleViews::Init() {
ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
SetLayoutManager(new views::BoxLayout(
views::BoxLayout::kVertical, 0, 0,
provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)));
// Add the content string.
views::Label* content_label =
new views::Label(delegate_->GetBodyText(anchored_to_action_));
content_label->SetMultiLine(true);
int width = views::Widget::GetLocalizedContentsWidth(
IDS_EXTENSION_TOOLBAR_REDESIGN_NOTIFICATION_BUBBLE_WIDTH_CHARS);
content_label->SizeToFit(width);
content_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
AddChildView(content_label);
base::string16 item_list = delegate_->GetItemListText();
if (!item_list.empty()) {
item_list_ = new views::Label(item_list);
item_list_->SetBorder(views::CreateEmptyBorder(
0,
provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_HORIZONTAL),
0, 0));
item_list_->SetMultiLine(true);
item_list_->SizeToFit(width);
item_list_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
AddChildView(item_list_);
}
}
int ToolbarActionsBarBubbleViews::GetDialogButtons() const {
int buttons = ui::DIALOG_BUTTON_NONE;
if (!delegate_->GetActionButtonText().empty())
buttons |= ui::DIALOG_BUTTON_OK;
if (!delegate_->GetDismissButtonText().empty())
buttons |= ui::DIALOG_BUTTON_CANCEL;
return buttons;
}
int ToolbarActionsBarBubbleViews::GetDefaultDialogButton() const {
// TODO(estade): we should set a default where approprite. See
// http://crbug.com/621122
return ui::DIALOG_BUTTON_NONE;
}
base::string16 ToolbarActionsBarBubbleViews::GetDialogButtonLabel(
ui::DialogButton button) const {
return button == ui::DIALOG_BUTTON_OK ? delegate_->GetActionButtonText()
: delegate_->GetDismissButtonText();
}
void ToolbarActionsBarBubbleViews::LinkClicked(views::Link* link,
int event_flags) {
DCHECK(!delegate_notified_of_close_);
delegate_notified_of_close_ = true;
delegate_->OnBubbleClosed(ToolbarActionsBarBubbleDelegate::CLOSE_LEARN_MORE);
// Note that the Widget may or may not already be closed at this point,
// depending on delegate_->ShouldCloseOnDeactivate(). Widget::Close() protects
// against multiple calls (so long as they are not nested), and Widget
// destruction is asynchronous, so it is safe to call Close() again.
GetWidget()->Close();
}