browser_action_view.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
1902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com// Copyright 2013 The Chromium Authors. All rights reserved. 2902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com// Use of this source code is governed by a BSD-style license that can be 3902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com// found in the LICENSE file. 4902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 5902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "chrome/browser/ui/views/toolbar/browser_action_view.h" 6902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 7902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "base/strings/utf_string_conversions.h" 8902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "chrome/browser/chrome_notification_types.h" 9902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "chrome/browser/extensions/api/commands/command_service.h" 10902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "chrome/browser/extensions/extension_action.h" 11902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "chrome/browser/extensions/extension_action_manager.h" 12902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "chrome/browser/extensions/extension_context_menu_model.h" 13902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "chrome/browser/extensions/extension_service.h" 14902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "chrome/browser/profiles/profile.h" 152a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org#include "chrome/browser/themes/theme_service.h" 16902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "chrome/browser/themes/theme_service_factory.h" 178a1cdaece7e1d009befb84f21bb82370025bf4d6robertphillips@google.com#include "chrome/browser/ui/browser.h" 1897cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com#include "chrome/browser/ui/view_ids.h" 19902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "chrome/browser/ui/views/toolbar/browser_actions_container.h" 2032bbcf828d66ad244fa25b468bc3a229e531491frobertphillips@google.com#include "chrome/browser/ui/views/toolbar/toolbar_view.h" 2132bbcf828d66ad244fa25b468bc3a229e531491frobertphillips@google.com#include "extensions/common/extension.h" 2286681b37bd20204e47a492119b345c01d00bc939fmalita@google.com#include "extensions/common/manifest_constants.h" 23902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "grit/generated_resources.h" 2480a4a60f96c33ccd850f9b0eb4b69ab08c198196chudy@google.com#include "grit/theme_resources.h" 25f4741c1322944e194ca34a8f5cf8188fe2c0efe2robertphillips@google.com#include "ui/accessibility/ax_view_state.h" 26902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "ui/base/l10n/l10n_util.h" 27768ac85655017d4106444bf3ad044680a575ccaacommit-bot@chromium.org#include "ui/base/resource/resource_bundle.h" 28768ac85655017d4106444bf3ad044680a575ccaacommit-bot@chromium.org#include "ui/events/event.h" 29768ac85655017d4106444bf3ad044680a575ccaacommit-bot@chromium.org#include "ui/gfx/image/image_skia.h" 3057f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org#include "ui/gfx/image/image_skia_operations.h" 31902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "ui/gfx/image/image_skia_source.h" 32902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com#include "ui/views/controls/menu/menu_item_view.h" 33f4741c1322944e194ca34a8f5cf8188fe2c0efe2robertphillips@google.com#include "ui/views/controls/menu/menu_runner.h" 34f4741c1322944e194ca34a8f5cf8188fe2c0efe2robertphillips@google.com 35f4741c1322944e194ca34a8f5cf8188fe2c0efe2robertphillips@google.comusing extensions::Extension; 3657f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org 3757f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org//////////////////////////////////////////////////////////////////////////////// 3857f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org// BrowserActionView 3957f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org 4057f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.orgbool BrowserActionView::Delegate::NeedToShowMultipleIconStates() const { 412a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org return true; 422a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org} 4357f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org 44f4741c1322944e194ca34a8f5cf8188fe2c0efe2robertphillips@google.combool BrowserActionView::Delegate::NeedToShowTooltip() const { 45f4741c1322944e194ca34a8f5cf8188fe2c0efe2robertphillips@google.com return true; 4632bbcf828d66ad244fa25b468bc3a229e531491frobertphillips@google.com} 4732bbcf828d66ad244fa25b468bc3a229e531491frobertphillips@google.com 48f84ad8f7fc0194389a8099da2c5e8fff9f092890skia.committer@gmail.comBrowserActionView::BrowserActionView(const Extension* extension, 4932bbcf828d66ad244fa25b468bc3a229e531491frobertphillips@google.com Browser* browser, 5032bbcf828d66ad244fa25b468bc3a229e531491frobertphillips@google.com BrowserActionView::Delegate* delegate) 51902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com : browser_(browser), 52902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com delegate_(delegate), 53902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com button_(NULL), 54902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com extension_(extension) { 55902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com set_id(VIEW_ID_BROWSER_ACTION); 56902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com button_ = new BrowserActionButton(extension_, browser_, delegate_); 57902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com button_->set_drag_controller(delegate_); 58902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com button_->set_owned_by_client(); 59902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com AddChildView(button_); 60902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com button_->UpdateState(); 610b5bbb0f82e022c8acfbcb6312f0ed18e1ab90cechudy@google.com} 620b5bbb0f82e022c8acfbcb6312f0ed18e1ab90cechudy@google.com 630b5bbb0f82e022c8acfbcb6312f0ed18e1ab90cechudy@google.comBrowserActionView::~BrowserActionView() { 64a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com button_->Destroy(); 65a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com} 66a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com 67a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.comgfx::ImageSkia BrowserActionView::GetIconWithBadge() { 68a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com return button_->GetIconWithBadge(); 69a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com} 70a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com 71a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.comvoid BrowserActionView::Layout() { 72a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com button_->SetBounds(0, y(), width(), height()); 73a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com} 74a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com 75a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.comvoid BrowserActionView::GetAccessibleState(ui::AXViewState* state) { 76a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com state->name = l10n_util::GetStringUTF16( 77a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com IDS_ACCNAME_EXTENSIONS_BROWSER_ACTION); 780b5bbb0f82e022c8acfbcb6312f0ed18e1ab90cechudy@google.com state->role = ui::AX_ROLE_GROUP; 790b5bbb0f82e022c8acfbcb6312f0ed18e1ab90cechudy@google.com} 80830b8793bb1646bb76817bdc228dd8e2a92bef7dchudy@google.com 81902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.comgfx::Size BrowserActionView::GetPreferredSize() const { 82902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com return gfx::Size(BrowserActionsContainer::IconWidth(false), 8350c84da68b17647371a81593402e897d639989e4robertphillips@google.com BrowserActionsContainer::IconHeight()); 8450c84da68b17647371a81593402e897d639989e4robertphillips@google.com} 8550c84da68b17647371a81593402e897d639989e4robertphillips@google.com 8650c84da68b17647371a81593402e897d639989e4robertphillips@google.comvoid BrowserActionView::PaintChildren(gfx::Canvas* canvas, 8750c84da68b17647371a81593402e897d639989e4robertphillips@google.com const views::CullSet& cull_set) { 8850c84da68b17647371a81593402e897d639989e4robertphillips@google.com View::PaintChildren(canvas, cull_set); 89902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com ExtensionAction* action = button()->browser_action(); 90902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com int tab_id = delegate_->GetCurrentTabId(); 91902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com if (tab_id >= 0) 92902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com action->PaintBadge(canvas, GetLocalBounds(), tab_id); 93902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com} 94902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 9550c84da68b17647371a81593402e897d639989e4robertphillips@google.com//////////////////////////////////////////////////////////////////////////////// 9650c84da68b17647371a81593402e897d639989e4robertphillips@google.com// BrowserActionButton 9750c84da68b17647371a81593402e897d639989e4robertphillips@google.com 9850c84da68b17647371a81593402e897d639989e4robertphillips@google.comBrowserActionButton::BrowserActionButton(const Extension* extension, 9950c84da68b17647371a81593402e897d639989e4robertphillips@google.com Browser* browser, 10050c84da68b17647371a81593402e897d639989e4robertphillips@google.com BrowserActionView::Delegate* delegate) 10150c84da68b17647371a81593402e897d639989e4robertphillips@google.com : MenuButton(this, base::string16(), NULL, false), 102902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com browser_(browser), 103902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com browser_action_( 104902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com extensions::ExtensionActionManager::Get(browser->profile())-> 10597cee9735350cb472249ce1a827ba1aa6b2a5f59chudy@google.com GetBrowserAction(*extension)), 106902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com extension_(extension), 107902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com icon_factory_(browser->profile(), extension, browser_action_, this), 1087e4cfbf144af7d530d552946cee2a21d30b9b50fchudy@google.com delegate_(delegate), 1097e4cfbf144af7d530d552946cee2a21d30b9b50fchudy@google.com context_menu_(NULL), 1107e4cfbf144af7d530d552946cee2a21d30b9b50fchudy@google.com called_registered_extension_command_(false), 1117e4cfbf144af7d530d552946cee2a21d30b9b50fchudy@google.com icon_observer_(NULL) { 1127e4cfbf144af7d530d552946cee2a21d30b9b50fchudy@google.com SetBorder(views::Border::NullBorder()); 1137e4cfbf144af7d530d552946cee2a21d30b9b50fchudy@google.com set_alignment(TextButton::ALIGN_CENTER); 114902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com set_context_menu_controller(this); 115902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 1164469938e92d779dff05e745559e67907bbf21e78reed@google.com // No UpdateState() here because View hierarchy not setup yet. Our parent 1178a1cdaece7e1d009befb84f21bb82370025bf4d6robertphillips@google.com // should call UpdateState() after creation. 1182e71f1619d9a2c51c1292e618f42a56ad2da1de8skia.committer@gmail.com 119febc0ec41b4cff6ea69f2b89d72c0d330d198283robertphillips@google.com content::NotificationSource notification_source = 120febc0ec41b4cff6ea69f2b89d72c0d330d198283robertphillips@google.com content::Source<Profile>(browser_->profile()->GetOriginalProfile()); 121febc0ec41b4cff6ea69f2b89d72c0d330d198283robertphillips@google.com registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED, 122febc0ec41b4cff6ea69f2b89d72c0d330d198283robertphillips@google.com content::Source<ExtensionAction>(browser_action_)); 123febc0ec41b4cff6ea69f2b89d72c0d330d198283robertphillips@google.com registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_COMMAND_ADDED, 124902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com notification_source); 125902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_COMMAND_REMOVED, 126902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com notification_source); 127902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 1288a1cdaece7e1d009befb84f21bb82370025bf4d6robertphillips@google.com // We also listen for browser theme changes on linux because a switch from or 129902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com // to GTK requires that we regrab our browser action images. 130902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com registrar_.Add( 13157f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org this, 13257f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org chrome::NOTIFICATION_BROWSER_THEME_CHANGED, 13357f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org content::Source<ThemeService>( 13457f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org ThemeServiceFactory::GetForProfile(browser->profile()))); 13557f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org} 136f14143226acf209615c4dd841aa6632aff112ab3chudy@google.com 137f14143226acf209615c4dd841aa6632aff112ab3chudy@google.comvoid BrowserActionButton::Destroy() { 1380d4fe14a41bd04535310f8b2edee9e30191fdd79commit-bot@chromium.org MaybeUnregisterExtensionCommand(false); 13967baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com 140f14143226acf209615c4dd841aa6632aff112ab3chudy@google.com if (context_menu_) { 141f14143226acf209615c4dd841aa6632aff112ab3chudy@google.com context_menu_->Cancel(); 142902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 143902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com } else { 144902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com delete this; 145902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com } 146902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com} 147902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 148b9ddd4e9f184f4a4545eca69c55ec1ad1ce59170chudy@google.comvoid BrowserActionButton::ViewHierarchyChanged( 149b9ddd4e9f184f4a4545eca69c55ec1ad1ce59170chudy@google.com const ViewHierarchyChangedDetails& details) { 150b9ddd4e9f184f4a4545eca69c55ec1ad1ce59170chudy@google.com if (details.is_add && !called_registered_extension_command_ && 151b9ddd4e9f184f4a4545eca69c55ec1ad1ce59170chudy@google.com GetFocusManager()) { 152b9ddd4e9f184f4a4545eca69c55ec1ad1ce59170chudy@google.com MaybeRegisterExtensionCommand(); 153e8cc6e8071935339a06548b13a0668b56a7540f5bungeman@google.com called_registered_extension_command_ = true; 154e8cc6e8071935339a06548b13a0668b56a7540f5bungeman@google.com } 155830b8793bb1646bb76817bdc228dd8e2a92bef7dchudy@google.com 156830b8793bb1646bb76817bdc228dd8e2a92bef7dchudy@google.com MenuButton::ViewHierarchyChanged(details); 1572a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org} 1582a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org 159902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.combool BrowserActionButton::CanHandleAccelerators() const { 160902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com // View::CanHandleAccelerators() checks to see if the view is visible before 161902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com // allowing it to process accelerators. This is not appropriate for browser 162902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com // actions buttons, which can be hidden inside the overflow area. 163902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com return true; 164902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com} 165902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 166902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.comvoid BrowserActionButton::GetAccessibleState(ui::AXViewState* state) { 167902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com views::MenuButton::GetAccessibleState(state); 1687112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.com state->role = ui::AX_ROLE_BUTTON; 169eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org} 170eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org 171902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.comvoid BrowserActionButton::ButtonPressed(views::Button* sender, 172902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com const ui::Event& event) { 173902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com delegate_->OnBrowserActionExecuted(this); 174902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com} 175902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 176902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.comvoid BrowserActionButton::ShowContextMenuForView( 177902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com View* source, 178902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com const gfx::Point& point, 179902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com ui::MenuSourceType source_type) { 1800a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com if (!extension()->ShowConfigureContextMenus()) 1810a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com return; 1820a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com 1830a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com SetButtonPushed(); 1840a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com 1850a4805e33f8ddb445a2fd061462e715e1707f049robertphillips@google.com // Reconstructs the menu every time because the menu's contents are dynamic. 18667baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com scoped_refptr<ExtensionContextMenuModel> context_menu_contents_( 18767baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com new ExtensionContextMenuModel(extension(), browser_, delegate_)); 188902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com menu_runner_.reset(new views::MenuRunner(context_menu_contents_.get())); 189902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 1907ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.com context_menu_ = menu_runner_->GetMenu(); 1917ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.com gfx::Point screen_loc; 192902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com views::View::ConvertPointToScreen(this, &screen_loc); 193902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com if (menu_runner_->RunMenuAt( 194902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com GetWidget(), 195902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com NULL, 196902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com gfx::Rect(screen_loc, size()), 1977ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.com views::MENU_ANCHOR_TOPLEFT, 1987ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.com source_type, 19967baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU) == 20067baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com views::MenuRunner::MENU_DELETED) { 201902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com return; 202902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com } 203902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 204902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com menu_runner_.reset(); 20567baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com SetButtonNotPushed(); 20667baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com context_menu_ = NULL; 20767baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com} 208902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 209902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.comvoid BrowserActionButton::UpdateState() { 2103b0a9fe5672e7339ec3e5e6d3986b15f57ae24e7robertphillips@google.com int tab_id = delegate_->GetCurrentTabId(); 2113b0a9fe5672e7339ec3e5e6d3986b15f57ae24e7robertphillips@google.com if (tab_id < 0) 2123b0a9fe5672e7339ec3e5e6d3986b15f57ae24e7robertphillips@google.com return; 2138f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 2145c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SetShowMultipleIconStates(delegate_->NeedToShowMultipleIconStates()); 2155c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org 216370a89980b2d38a6d01903b484bf404d6c48b496skia.committer@gmail.com if (!IsEnabled(tab_id)) { 217370a89980b2d38a6d01903b484bf404d6c48b496skia.committer@gmail.com SetState(views::CustomButton::STATE_DISABLED); 2188f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com } else { 2195c70cdca5efe541b70d010e91607bf8626ea49cacommit-bot@chromium.org SetState(menu_visible_ ? 2208f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com views::CustomButton::STATE_PRESSED : 2218f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com views::CustomButton::STATE_NORMAL); 222370a89980b2d38a6d01903b484bf404d6c48b496skia.committer@gmail.com } 223370a89980b2d38a6d01903b484bf404d6c48b496skia.committer@gmail.com 2248f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com gfx::ImageSkia icon = *icon_factory_.GetIcon(tab_id).ToImageSkia(); 2258f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 2268f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!icon.isNull()) { 2278f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com if (!browser_action()->GetIsVisible(tab_id)) 2288f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25); 2298f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 2308f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ThemeService* theme = 2318f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com ThemeServiceFactory::GetForProfile(browser_->profile()); 2328f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 2338f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com gfx::ImageSkia bg = *theme->GetImageSkiaNamed(IDR_BROWSER_ACTION); 2348f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com SetIcon(gfx::ImageSkiaOperations::CreateSuperimposedImage(bg, icon)); 235ab5827354e2c23624acc3fc1fe4a83788bc99e96commit-bot@chromium.org 236e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org gfx::ImageSkia bg_h = *theme->GetImageSkiaNamed(IDR_BROWSER_ACTION_H); 237e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org SetHoverIcon(gfx::ImageSkiaOperations::CreateSuperimposedImage(bg_h, icon)); 238e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org 239e54a23fcfa42b2fc9d320650de72bcb2d9566b2dcommit-bot@chromium.org gfx::ImageSkia bg_p = *theme->GetImageSkiaNamed(IDR_BROWSER_ACTION_P); 24044c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org SetPushedIcon( 24144c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org gfx::ImageSkiaOperations::CreateSuperimposedImage(bg_p, icon)); 24244c48d062f7996b5b46917e1b312a32ad101f326commit-bot@chromium.org } 243ab5827354e2c23624acc3fc1fe4a83788bc99e96commit-bot@chromium.org 244e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com // If the browser action name is empty, show the extension name instead. 245e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com std::string title = browser_action()->GetTitle(tab_id); 246e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com base::string16 name = 247e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com base::UTF8ToUTF16(title.empty() ? extension()->name() : title); 248e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SetTooltipText(delegate_->NeedToShowTooltip() ? name : base::string16()); 249e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com SetAccessibleName(name); 250e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com 251e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com parent()->SchedulePaint(); 252210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org} 253210ae2a42613b9048e8e8c4096c5bf4fe2ddf838commit-bot@chromium.org 254ab5827354e2c23624acc3fc1fe4a83788bc99e96commit-bot@chromium.orgbool BrowserActionButton::IsPopup() { 2558f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com int tab_id = delegate_->GetCurrentTabId(); 2568f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com return (tab_id < 0) ? false : browser_action_->HasPopup(tab_id); 2578f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com} 2588f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.com 2598f90a892c5130d4d26b5588e1ff151d01a40688arobertphillips@google.comGURL BrowserActionButton::GetPopupUrl() { 2601643b2c9bc5adb4324bb459bb7811f58bc7c2d62commit-bot@chromium.org int tab_id = delegate_->GetCurrentTabId(); 261768ac85655017d4106444bf3ad044680a575ccaacommit-bot@chromium.org return (tab_id < 0) ? GURL() : browser_action_->GetPopupUrl(tab_id); 262902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com} 26367baba4892649fdb6fb0827c7d54e5adb7538443robertphillips@google.com 26457f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.orgvoid BrowserActionButton::Observe(int type, 265b9ddd4e9f184f4a4545eca69c55ec1ad1ce59170chudy@google.com const content::NotificationSource& source, 2661735d6696e9a941925e6ca352849307d698ef139commit-bot@chromium.org const content::NotificationDetails& details) { 2677e4cfbf144af7d530d552946cee2a21d30b9b50fchudy@google.com switch (type) { 268768ac85655017d4106444bf3ad044680a575ccaacommit-bot@chromium.org case chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED: 269830b8793bb1646bb76817bdc228dd8e2a92bef7dchudy@google.com UpdateState(); 270e8cc6e8071935339a06548b13a0668b56a7540f5bungeman@google.com // The browser action may have become visible/hidden so we need to make 271a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com // sure the state gets updated. 272a9e937c7b712b024de108fa963f92d0e70e4a296chudy@google.com delegate_->OnBrowserActionVisibilityChanged(); 27332bbcf828d66ad244fa25b468bc3a229e531491frobertphillips@google.com break; 2742a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org case chrome::NOTIFICATION_EXTENSION_COMMAND_ADDED: 2752a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org case chrome::NOTIFICATION_EXTENSION_COMMAND_REMOVED: { 2762a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org std::pair<const std::string, const std::string>* payload = 2772a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org content::Details<std::pair<const std::string, const std::string> >( 278f4741c1322944e194ca34a8f5cf8188fe2c0efe2robertphillips@google.com details).ptr(); 279f4741c1322944e194ca34a8f5cf8188fe2c0efe2robertphillips@google.com if (extension_->id() == payload->first && 280902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com payload->second == 28132bbcf828d66ad244fa25b468bc3a229e531491frobertphillips@google.com extensions::manifest_values::kBrowserActionCommandEvent) { 28232bbcf828d66ad244fa25b468bc3a229e531491frobertphillips@google.com if (type == chrome::NOTIFICATION_EXTENSION_COMMAND_ADDED) 28332bbcf828d66ad244fa25b468bc3a229e531491frobertphillips@google.com MaybeRegisterExtensionCommand(); 284902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com else 2850699e02101405623ad47f225729ed2521b2a0501tomhudson@google.com MaybeUnregisterExtensionCommand(true); 2860699e02101405623ad47f225729ed2521b2a0501tomhudson@google.com } 2870699e02101405623ad47f225729ed2521b2a0501tomhudson@google.com break; 2880699e02101405623ad47f225729ed2521b2a0501tomhudson@google.com } 2890699e02101405623ad47f225729ed2521b2a0501tomhudson@google.com case chrome::NOTIFICATION_BROWSER_THEME_CHANGED: 2900699e02101405623ad47f225729ed2521b2a0501tomhudson@google.com UpdateState(); 2910699e02101405623ad47f225729ed2521b2a0501tomhudson@google.com break; 292ade9a3485e78d471f5f0902e9e50a2ec74c88e76skia.committer@gmail.com default: 2931643b2c9bc5adb4324bb459bb7811f58bc7c2d62commit-bot@chromium.org NOTREACHED(); 2941643b2c9bc5adb4324bb459bb7811f58bc7c2d62commit-bot@chromium.org break; 2951643b2c9bc5adb4324bb459bb7811f58bc7c2d62commit-bot@chromium.org } 2961643b2c9bc5adb4324bb459bb7811f58bc7c2d62commit-bot@chromium.org} 2971643b2c9bc5adb4324bb459bb7811f58bc7c2d62commit-bot@chromium.org 298ade9a3485e78d471f5f0902e9e50a2ec74c88e76skia.committer@gmail.comvoid BrowserActionButton::OnIconUpdated() { 2991643b2c9bc5adb4324bb459bb7811f58bc7c2d62commit-bot@chromium.org UpdateState(); 3001643b2c9bc5adb4324bb459bb7811f58bc7c2d62commit-bot@chromium.org if (icon_observer_) 3011643b2c9bc5adb4324bb459bb7811f58bc7c2d62commit-bot@chromium.org icon_observer_->OnIconUpdated(GetIconWithBadge()); 3021643b2c9bc5adb4324bb459bb7811f58bc7c2d62commit-bot@chromium.org} 3031643b2c9bc5adb4324bb459bb7811f58bc7c2d62commit-bot@chromium.org 3040699e02101405623ad47f225729ed2521b2a0501tomhudson@google.combool BrowserActionButton::Activate() { 305902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com if (!IsPopup()) 306902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com return true; 307902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 308902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com delegate_->OnBrowserActionExecuted(this); 309830b8793bb1646bb76817bdc228dd8e2a92bef7dchudy@google.com 310830b8793bb1646bb76817bdc228dd8e2a92bef7dchudy@google.com // TODO(erikkay): Run a nested modal loop while the mouse is down to 311830b8793bb1646bb76817bdc228dd8e2a92bef7dchudy@google.com // enable menu-like drag-select behavior. 312830b8793bb1646bb76817bdc228dd8e2a92bef7dchudy@google.com 313830b8793bb1646bb76817bdc228dd8e2a92bef7dchudy@google.com // The return value of this method is returned via OnMousePressed. 314830b8793bb1646bb76817bdc228dd8e2a92bef7dchudy@google.com // We need to return false here since we're handing off focus to another 3153b0a9fe5672e7339ec3e5e6d3986b15f57ae24e7robertphillips@google.com // widget/view, and true will grab it right back and try to send events 31657f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org // to us. 31757f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org return false; 31857f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org} 31957f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org 32057f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.orgbool BrowserActionButton::OnMousePressed(const ui::MouseEvent& event) { 32157f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org if (!event.IsRightMouseButton()) { 32257f74e0aa931e7784d47cba3ecc83020aa8e72b2commit-bot@chromium.org return IsPopup() ? MenuButton::OnMousePressed(event) : 3232a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org TextButton::OnMousePressed(event); 3242a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org } 3252a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org 3262a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org if (!views::View::ShouldShowContextMenuOnMousePress()) { 3272a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org // See comments in MenuButton::Activate() as to why this is needed. 3282a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org SetMouseHandler(NULL); 3292a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org 3302a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org ShowContextMenu(gfx::Point(), ui::MENU_SOURCE_MOUSE); 3312a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org } 3322a67e123a3e559774a16a58cbe5106bc0fb86740commit-bot@chromium.org return false; 3333b0a9fe5672e7339ec3e5e6d3986b15f57ae24e7robertphillips@google.com} 334902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com 335902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.comvoid BrowserActionButton::OnMouseReleased(const ui::MouseEvent& event) { 336902ebe5eb41a350b766238b3b103c22fe9fc0fb5chudy@google.com if (IsPopup() || context_menu_) { 337 // TODO(erikkay) this never actually gets called (probably because of the 338 // loss of focus). 339 MenuButton::OnMouseReleased(event); 340 } else { 341 TextButton::OnMouseReleased(event); 342 } 343} 344 345void BrowserActionButton::OnMouseExited(const ui::MouseEvent& event) { 346 if (IsPopup() || context_menu_) 347 MenuButton::OnMouseExited(event); 348 else 349 TextButton::OnMouseExited(event); 350} 351 352bool BrowserActionButton::OnKeyReleased(const ui::KeyEvent& event) { 353 return IsPopup() ? MenuButton::OnKeyReleased(event) : 354 TextButton::OnKeyReleased(event); 355} 356 357void BrowserActionButton::OnGestureEvent(ui::GestureEvent* event) { 358 if (IsPopup()) 359 MenuButton::OnGestureEvent(event); 360 else 361 TextButton::OnGestureEvent(event); 362} 363 364bool BrowserActionButton::AcceleratorPressed( 365 const ui::Accelerator& accelerator) { 366 delegate_->OnBrowserActionExecuted(this); 367 return true; 368} 369 370void BrowserActionButton::SetButtonPushed() { 371 SetState(views::CustomButton::STATE_PRESSED); 372 menu_visible_ = true; 373} 374 375void BrowserActionButton::SetButtonNotPushed() { 376 SetState(views::CustomButton::STATE_NORMAL); 377 menu_visible_ = false; 378} 379 380bool BrowserActionButton::IsEnabled(int tab_id) const { 381 return browser_action_->GetIsVisible(tab_id); 382} 383 384gfx::ImageSkia BrowserActionButton::GetIconWithBadge() { 385 int tab_id = delegate_->GetCurrentTabId(); 386 gfx::Size spacing(0, ToolbarView::kVertSpacing); 387 gfx::ImageSkia icon = *icon_factory_.GetIcon(tab_id).ToImageSkia(); 388 if (!IsEnabled(tab_id)) 389 icon = gfx::ImageSkiaOperations::CreateTransparentImage(icon, .25); 390 return browser_action_->GetIconWithBadge(icon, tab_id, spacing); 391} 392 393gfx::ImageSkia BrowserActionButton::GetIconForTest() { 394 return icon(); 395} 396 397BrowserActionButton::~BrowserActionButton() { 398} 399 400void BrowserActionButton::MaybeRegisterExtensionCommand() { 401 extensions::CommandService* command_service = 402 extensions::CommandService::Get(browser_->profile()); 403 extensions::Command browser_action_command; 404 if (command_service->GetBrowserActionCommand( 405 extension_->id(), 406 extensions::CommandService::ACTIVE_ONLY, 407 &browser_action_command, 408 NULL)) { 409 keybinding_.reset(new ui::Accelerator( 410 browser_action_command.accelerator())); 411 GetFocusManager()->RegisterAccelerator( 412 *keybinding_.get(), ui::AcceleratorManager::kHighPriority, this); 413 } 414} 415 416void BrowserActionButton::MaybeUnregisterExtensionCommand(bool only_if_active) { 417 if (!keybinding_.get() || !GetFocusManager()) 418 return; 419 420 extensions::CommandService* command_service = 421 extensions::CommandService::Get(browser_->profile()); 422 423 extensions::Command browser_action_command; 424 if (!only_if_active || !command_service->GetBrowserActionCommand( 425 extension_->id(), 426 extensions::CommandService::ACTIVE_ONLY, 427 &browser_action_command, 428 NULL)) { 429 GetFocusManager()->UnregisterAccelerator(*keybinding_.get(), this); 430 keybinding_.reset(NULL); 431 } 432} 433