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. 4 5#include "chrome/browser/ui/views/location_bar/page_action_image_view.h" 6 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/ui/browser.h" 12#include "chrome/browser/ui/views/location_bar/location_bar_view.h" 13#include "extensions/browser/extension_registry.h" 14#include "ui/accessibility/ax_view_state.h" 15#include "ui/events/event.h" 16#include "ui/gfx/canvas.h" 17#include "ui/gfx/image/image.h" 18 19// static 20const char PageActionImageView::kViewClassName[] = "PageActionImageView"; 21 22PageActionImageView::PageActionImageView(LocationBarView* owner, 23 ExtensionAction* page_action, 24 Browser* browser) 25 : view_controller_(new ExtensionActionViewController( 26 extensions::ExtensionRegistry::Get(browser->profile())-> 27 enabled_extensions().GetByID(page_action->extension_id()), 28 browser, 29 page_action, 30 this)), 31 owner_(owner), 32 preview_enabled_(false) { 33 // There should be an associated focus manager so that we can safely register 34 // accelerators for commands. 35 DCHECK(GetFocusManagerForAccelerator()); 36 SetAccessibilityFocusable(true); 37 view_controller_->RegisterCommand(); 38 set_context_menu_controller(view_controller_.get()); 39} 40 41PageActionImageView::~PageActionImageView() { 42} 43 44const char* PageActionImageView::GetClassName() const { 45 return kViewClassName; 46} 47 48void PageActionImageView::GetAccessibleState(ui::AXViewState* state) { 49 state->role = ui::AX_ROLE_BUTTON; 50 state->name = base::UTF8ToUTF16(tooltip_); 51} 52 53bool PageActionImageView::OnMousePressed(const ui::MouseEvent& event) { 54 // We want to show the bubble on mouse release; that is the standard behavior 55 // for buttons. (Also, triggering on mouse press causes bugs like 56 // http://crbug.com/33155.) 57 return true; 58} 59 60void PageActionImageView::OnMouseReleased(const ui::MouseEvent& event) { 61 if (!HitTestPoint(event.location())) 62 return; 63 64 if (event.IsRightMouseButton()) { 65 // Don't show a menu here, its handled in View::ProcessMouseReleased. We 66 // show the context menu by way of being the ContextMenuController. 67 return; 68 } 69 70 view_controller_->ExecuteActionByUser(); 71} 72 73bool PageActionImageView::OnKeyPressed(const ui::KeyEvent& event) { 74 if (event.key_code() == ui::VKEY_SPACE || 75 event.key_code() == ui::VKEY_RETURN) { 76 view_controller_->ExecuteActionByUser(); 77 return true; 78 } 79 return false; 80} 81 82void PageActionImageView::OnGestureEvent(ui::GestureEvent* event) { 83 if (event->type() == ui::ET_GESTURE_TAP) { 84 view_controller_->ExecuteActionByUser(); 85 event->SetHandled(); 86 } 87} 88 89void PageActionImageView::UpdateVisibility(content::WebContents* contents) { 90 int tab_id = view_controller_->GetCurrentTabId(); 91 92 if (!contents || 93 tab_id == -1 || 94 (!preview_enabled_ && !extension_action()->GetIsVisible(tab_id))) { 95 SetVisible(false); 96 return; 97 } 98 99 // Set the tooltip. 100 tooltip_ = extension_action()->GetTitle(tab_id); 101 SetTooltipText(base::UTF8ToUTF16(tooltip_)); 102 103 // Set the image. 104 gfx::Image icon = view_controller_->GetIcon(tab_id); 105 if (!icon.IsEmpty()) 106 SetImage(*icon.ToImageSkia()); 107 108 SetVisible(true); 109} 110 111void PageActionImageView::PaintChildren(gfx::Canvas* canvas, 112 const views::CullSet& cull_set) { 113 View::PaintChildren(canvas, cull_set); 114 int tab_id = view_controller_->GetCurrentTabId(); 115 if (tab_id >= 0) { 116 view_controller_->extension_action()->PaintBadge( 117 canvas, GetLocalBounds(), tab_id); 118 } 119} 120 121void PageActionImageView::OnIconUpdated() { 122 UpdateVisibility(GetCurrentWebContents()); 123} 124 125views::View* PageActionImageView::GetAsView() { 126 return this; 127} 128 129bool PageActionImageView::IsShownInMenu() { 130 return false; 131} 132 133views::FocusManager* PageActionImageView::GetFocusManagerForAccelerator() { 134 return owner_->GetFocusManager(); 135} 136 137views::Widget* PageActionImageView::GetParentForContextMenu() { 138 return GetWidget(); 139} 140 141ExtensionActionViewController* 142PageActionImageView::GetPreferredPopupViewController() { 143 return view_controller_.get(); 144} 145 146views::View* PageActionImageView::GetReferenceViewForPopup() { 147 return this; 148} 149 150views::MenuButton* PageActionImageView::GetContextMenuButton() { 151 return NULL; // No menu button for page action views. 152} 153 154content::WebContents* PageActionImageView::GetCurrentWebContents() { 155 return owner_->GetWebContents(); 156} 157 158void PageActionImageView::HideActivePopup() { 159 // The only popup that will be active is this popup. 160 view_controller_->HidePopup(); 161} 162