Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / location_bar / page_action_image_view.cc
blob1ba65d46cae8d2348fa382578da7df1704a3c625
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/location_bar/page_action_image_view.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/extensions/extension_action.h"
9 #include "chrome/browser/platform_util.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/sessions/session_tab_helper.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
14 #include "extensions/browser/extension_registry.h"
15 #include "extensions/common/constants.h"
16 #include "ui/accessibility/ax_view_state.h"
17 #include "ui/compositor/paint_recorder.h"
18 #include "ui/events/event.h"
19 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/image/image.h"
21 #include "ui/views/controls/menu/menu_runner.h"
23 // static
24 const char PageActionImageView::kViewClassName[] = "PageActionImageView";
26 PageActionImageView::PageActionImageView(LocationBarView* owner,
27 ExtensionAction* page_action,
28 Browser* browser)
29 : view_controller_(new ExtensionActionViewController(
30 extensions::ExtensionRegistry::Get(browser->profile())->
31 enabled_extensions().GetByID(page_action->extension_id()),
32 browser,
33 page_action,
34 nullptr)),
35 owner_(owner),
36 preview_enabled_(false) {
37 // There should be an associated focus manager so that we can safely register
38 // accelerators for commands.
39 DCHECK(GetFocusManagerForAccelerator());
40 SetAccessibilityFocusable(true);
41 view_controller_->SetDelegate(this);
42 view_controller_->RegisterCommand();
43 set_context_menu_controller(this);
46 PageActionImageView::~PageActionImageView() {
49 const char* PageActionImageView::GetClassName() const {
50 return kViewClassName;
53 void PageActionImageView::GetAccessibleState(ui::AXViewState* state) {
54 state->role = ui::AX_ROLE_BUTTON;
55 state->name = base::UTF8ToUTF16(tooltip_);
58 bool PageActionImageView::OnMousePressed(const ui::MouseEvent& event) {
59 // We want to show the bubble on mouse release; that is the standard behavior
60 // for buttons. (Also, triggering on mouse press causes bugs like
61 // http://crbug.com/33155.)
62 return true;
65 void PageActionImageView::OnMouseReleased(const ui::MouseEvent& event) {
66 if (!HitTestPoint(event.location()))
67 return;
69 if (event.IsRightMouseButton()) {
70 // Don't show a menu here, its handled in View::ProcessMouseReleased. We
71 // show the context menu by way of being the ContextMenuController.
72 return;
75 view_controller_->ExecuteAction(true);
78 bool PageActionImageView::OnKeyPressed(const ui::KeyEvent& event) {
79 if (event.key_code() == ui::VKEY_SPACE ||
80 event.key_code() == ui::VKEY_RETURN) {
81 view_controller_->ExecuteAction(true);
82 return true;
84 return false;
87 void PageActionImageView::OnGestureEvent(ui::GestureEvent* event) {
88 if (event->type() == ui::ET_GESTURE_TAP) {
89 view_controller_->ExecuteAction(true);
90 event->SetHandled();
94 void PageActionImageView::UpdateVisibility(content::WebContents* contents) {
95 int tab_id = SessionTabHelper::IdForTab(contents);
96 if (!contents ||
97 tab_id == -1 ||
98 (!preview_enabled_ && !extension_action()->GetIsVisible(tab_id))) {
99 SetVisible(false);
100 return;
103 // Set the tooltip.
104 tooltip_ = extension_action()->GetTitle(tab_id);
105 SetTooltipText(base::UTF8ToUTF16(tooltip_));
107 // Set the image.
108 gfx::Size size(extension_misc::EXTENSION_ICON_ACTION,
109 extension_misc::EXTENSION_ICON_ACTION);
110 gfx::Image icon = view_controller_->GetIcon(contents, size);
111 if (!icon.IsEmpty())
112 SetImage(*icon.ToImageSkia());
114 SetVisible(true);
117 void PageActionImageView::UpdateState() {
118 UpdateVisibility(GetCurrentWebContents());
121 views::View* PageActionImageView::GetAsView() {
122 return this;
125 bool PageActionImageView::IsMenuRunning() const {
126 return menu_runner_.get() != nullptr;
129 views::FocusManager* PageActionImageView::GetFocusManagerForAccelerator() {
130 return owner_->GetFocusManager();
133 views::View* PageActionImageView::GetReferenceViewForPopup() {
134 return this;
137 content::WebContents* PageActionImageView::GetCurrentWebContents() const {
138 return owner_->GetWebContents();
141 void PageActionImageView::ShowContextMenuForView(
142 views::View* source,
143 const gfx::Point& point,
144 ui::MenuSourceType source_type) {
145 ui::MenuModel* context_menu_model = view_controller_->GetContextMenu();
146 // It's possible the action doesn't have a context menu.
147 if (!context_menu_model)
148 return;
150 gfx::Point screen_loc;
151 ConvertPointToScreen(this, &screen_loc);
152 int run_types =
153 views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU;
154 menu_runner_.reset(new views::MenuRunner(context_menu_model, run_types));
156 if (menu_runner_->RunMenuAt(GetWidget(),
157 nullptr, // No menu button for page action views.
158 gfx::Rect(screen_loc, size()),
159 views::MENU_ANCHOR_TOPLEFT,
160 source_type) == views::MenuRunner::MENU_DELETED) {
161 return;
164 menu_runner_.reset();
165 view_controller_->OnContextMenuClosed();