15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/location_bar/page_action_image_view.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_action.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/platform_util.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/location_bar/location_bar_view.h" 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/extension_registry.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h" 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// static 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char PageActionImageView::kViewClassName[] = "PageActionImageView"; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PageActionImageView::PageActionImageView(LocationBarView* owner, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionAction* page_action, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser) 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : view_controller_(new ExtensionActionViewController( 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::ExtensionRegistry::Get(browser->profile())-> 275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) enabled_extensions().GetByID(page_action->extension_id()), 285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) browser, 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) page_action, 305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this)), 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) owner_(owner), 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) preview_enabled_(false) { 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // There should be an associated focus manager so that we can safely register 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // accelerators for commands. 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(GetFocusManagerForAccelerator()); 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetAccessibilityFocusable(true); 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) view_controller_->RegisterCommand(); 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) set_context_menu_controller(view_controller_.get()); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PageActionImageView::~PageActionImageView() { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char* PageActionImageView::GetClassName() const { 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return kViewClassName; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PageActionImageView::GetAccessibleState(ui::AXViewState* state) { 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state->role = ui::AX_ROLE_BUTTON; 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state->name = base::UTF8ToUTF16(tooltip_); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PageActionImageView::OnMousePressed(const ui::MouseEvent& event) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want to show the bubble on mouse release; that is the standard behavior 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for buttons. (Also, triggering on mouse press causes bugs like 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/33155.) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageActionImageView::OnMouseReleased(const ui::MouseEvent& event) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HitTestPoint(event.location())) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.IsRightMouseButton()) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't show a menu here, its handled in View::ProcessMouseReleased. We 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // show the context menu by way of being the ContextMenuController. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) view_controller_->ExecuteActionByUser(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PageActionImageView::OnKeyPressed(const ui::KeyEvent& event) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.key_code() == ui::VKEY_SPACE || 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.key_code() == ui::VKEY_RETURN) { 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) view_controller_->ExecuteActionByUser(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PageActionImageView::OnGestureEvent(ui::GestureEvent* event) { 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (event->type() == ui::ET_GESTURE_TAP) { 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) view_controller_->ExecuteActionByUser(); 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) event->SetHandled(); 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PageActionImageView::UpdateVisibility(content::WebContents* contents) { 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int tab_id = view_controller_->GetCurrentTabId(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!contents || 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tab_id == -1 || 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (!preview_enabled_ && !extension_action()->GetIsVisible(tab_id))) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetVisible(false); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the tooltip. 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tooltip_ = extension_action()->GetTitle(tab_id); 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetTooltipText(base::UTF8ToUTF16(tooltip_)); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the image. 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::Image icon = view_controller_->GetIcon(tab_id); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!icon.IsEmpty()) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetImage(*icon.ToImageSkia()); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetVisible(true); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PageActionImageView::PaintChildren(gfx::Canvas* canvas, 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const views::CullSet& cull_set) { 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) View::PaintChildren(canvas, cull_set); 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int tab_id = view_controller_->GetCurrentTabId(); 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (tab_id >= 0) { 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) view_controller_->extension_action()->PaintBadge( 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) canvas, GetLocalBounds(), tab_id); 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PageActionImageView::OnIconUpdated() { 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UpdateVisibility(GetCurrentWebContents()); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)views::View* PageActionImageView::GetAsView() { 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return this; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool PageActionImageView::IsShownInMenu() { 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)views::FocusManager* PageActionImageView::GetFocusManagerForAccelerator() { 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return owner_->GetFocusManager(); 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)views::Widget* PageActionImageView::GetParentForContextMenu() { 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return GetWidget(); 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciExtensionActionViewController* 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPageActionImageView::GetPreferredPopupViewController() { 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return view_controller_.get(); 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)views::View* PageActionImageView::GetReferenceViewForPopup() { 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return this; 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciviews::MenuButton* PageActionImageView::GetContextMenuButton() { 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return NULL; // No menu button for page action views. 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)content::WebContents* PageActionImageView::GetCurrentWebContents() { 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return owner_->GetWebContents(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void PageActionImageView::HideActivePopup() { 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The only popup that will be active is this popup. 1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) view_controller_->HidePopup(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 162