summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views
diff options
context:
space:
mode:
authorfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-17 05:55:32 +0000
committerfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-17 05:55:32 +0000
commitc690a981436bb6a6d69ab8df959ffa5b116bf356 (patch)
treedfb4134472778bdb6409679faec3fea2e4946633 /chrome/browser/views
parent5d39e314de21a384eaa226d4875b6a6e8e1bea17 (diff)
downloadchromium_src-c690a981436bb6a6d69ab8df959ffa5b116bf356.zip
chromium_src-c690a981436bb6a6d69ab8df959ffa5b116bf356.tar.gz
chromium_src-c690a981436bb6a6d69ab8df959ffa5b116bf356.tar.bz2
Add the right-click context menu for Browser actions and Page Actions.
BUG=29538 TEST=Right-click an extension icon and make sure all the options work for both Page and Browser actions (Options should be grayed out when there is no Options page specified in the manifest). Review URL: http://codereview.chromium.org/486022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34812 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views')
-rw-r--r--chrome/browser/views/browser_actions_container.cc35
-rw-r--r--chrome/browser/views/browser_actions_container.h16
-rw-r--r--chrome/browser/views/extensions/extension_action_context_menu.cc34
-rw-r--r--chrome/browser/views/extensions/extension_action_context_menu.h38
-rw-r--r--chrome/browser/views/location_bar_view.cc22
-rw-r--r--chrome/browser/views/location_bar_view.h4
6 files changed, 133 insertions, 16 deletions
diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc
index ccbc581..e593f83 100644
--- a/chrome/browser/views/browser_actions_container.cc
+++ b/chrome/browser/views/browser_actions_container.cc
@@ -56,10 +56,11 @@ BrowserActionButton::BrowserActionButton(Extension* extension,
browser_action_(extension->browser_action()),
extension_(extension),
tracker_(NULL),
+ showing_context_menu_(false),
panel_(panel) {
set_alignment(TextButton::ALIGN_CENTER);
- // No UpdateState() here because View heirarchy not setup yet. Our parent
+ // No UpdateState() here because View hierarchy not setup yet. Our parent
// should call UpdateState() after creation.
registrar_.Add(this, NotificationType::EXTENSION_BROWSER_ACTION_UPDATED,
@@ -155,14 +156,32 @@ bool BrowserActionButton::Activate() {
}
bool BrowserActionButton::OnMousePressed(const views::MouseEvent& e) {
- if (IsPopup())
+ showing_context_menu_ = e.IsRightMouseButton();
+ if (showing_context_menu_) {
+ SetButtonPushed();
+
+ // Get the top left point of this button in screen coordinates.
+ gfx::Point point = gfx::Point(0, 0);
+ ConvertPointToScreen(this, &point);
+
+ // Make the menu appear below the button.
+ point.Offset(0, height());
+
+ if (!context_menu_.get())
+ context_menu_.reset(new ExtensionActionContextMenu());
+ context_menu_->Run(extension(), point);
+
+ SetButtonNotPushed();
+ return false;
+ } else if (IsPopup()) {
return MenuButton::OnMousePressed(e);
+ }
return TextButton::OnMousePressed(e);
}
void BrowserActionButton::OnMouseReleased(const views::MouseEvent& e,
bool canceled) {
- if (IsPopup()) {
+ if (IsPopup() || showing_context_menu_) {
// TODO(erikkay) this never actually gets called (probably because of the
// loss of focus).
MenuButton::OnMouseReleased(e, canceled);
@@ -178,18 +197,18 @@ bool BrowserActionButton::OnKeyReleased(const views::KeyEvent& e) {
}
void BrowserActionButton::OnMouseExited(const views::MouseEvent& e) {
- if (IsPopup())
+ if (IsPopup() || showing_context_menu_)
MenuButton::OnMouseExited(e);
else
TextButton::OnMouseExited(e);
}
-void BrowserActionButton::PopupDidShow() {
+void BrowserActionButton::SetButtonPushed() {
SetState(views::CustomButton::BS_PUSHED);
menu_visible_ = true;
}
-void BrowserActionButton::PopupDidHide() {
+void BrowserActionButton::SetButtonNotPushed() {
SetState(views::CustomButton::BS_NORMAL);
menu_visible_ = false;
}
@@ -350,7 +369,7 @@ void BrowserActionsContainer::HidePopup() {
closing_popup->DetachFromBrowser();
delete closing_popup;
- closing_button->PopupDidHide();
+ closing_button->SetButtonNotPushed();
return;
}
}
@@ -396,7 +415,7 @@ void BrowserActionsContainer::OnBrowserActionExecuted(
true); // Activate the popup window.
popup_->set_delegate(this);
popup_button_ = button;
- popup_button_->PopupDidShow();
+ popup_button_->SetButtonPushed();
return;
}
diff --git a/chrome/browser/views/browser_actions_container.h b/chrome/browser/views/browser_actions_container.h
index 2499007..dbbd248 100644
--- a/chrome/browser/views/browser_actions_container.h
+++ b/chrome/browser/views/browser_actions_container.h
@@ -10,6 +10,7 @@
#include "base/task.h"
#include "chrome/browser/extensions/image_loading_tracker.h"
#include "chrome/browser/views/browser_bubble.h"
+#include "chrome/browser/views/extensions/extension_action_context_menu.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
#include "views/controls/button/menu_button.h"
@@ -42,7 +43,7 @@ class BrowserActionButton : public views::MenuButton,
// Called to update the display to match the browser action's state.
void UpdateState();
- // Overriden from views::View. Return a 0-inset so the icon can draw all the
+ // Overridden from views::View. Return a 0-inset so the icon can draw all the
// way to the edge of the view if it wants.
virtual gfx::Insets GetInsets() const;
@@ -71,9 +72,10 @@ class BrowserActionButton : public views::MenuButton,
// Does this button's action have a popup?
virtual bool IsPopup();
- // Notifications when the popup is hidden or shown by the container.
- virtual void PopupDidShow();
- virtual void PopupDidHide();
+ // Notifications when to set button state to pushed/not pushed (for when the
+ // popup/context menu is hidden or shown by the container).
+ virtual void SetButtonPushed();
+ virtual void SetButtonNotPushed();
private:
// The browser action this view represents. The ExtensionAction is not owned
@@ -88,6 +90,12 @@ class BrowserActionButton : public views::MenuButton,
// and takes care of deleting itself.
ImageLoadingTracker* tracker_;
+ // The context menu for browser action icons.
+ scoped_ptr<ExtensionActionContextMenu> context_menu_;
+
+ // Whether we are currently showing/just finished showing a context menu.
+ bool showing_context_menu_;
+
// The default icon for our browser action. This might be non-empty if the
// browser action had a value for default_icon in the manifest.
SkBitmap default_icon_;
diff --git a/chrome/browser/views/extensions/extension_action_context_menu.cc b/chrome/browser/views/extensions/extension_action_context_menu.cc
new file mode 100644
index 0000000..dbf7c07
--- /dev/null
+++ b/chrome/browser/views/extensions/extension_action_context_menu.cc
@@ -0,0 +1,34 @@
+// Copyright (c) 2009 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/views/extensions/extension_action_context_menu.h"
+
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/profile.h"
+
+ExtensionActionContextMenu::ExtensionActionContextMenu()
+ : extension_(NULL) {
+}
+
+ExtensionActionContextMenu::~ExtensionActionContextMenu() {
+}
+
+void ExtensionActionContextMenu::Run(Extension* extension,
+ const gfx::Point& point) {
+ extension_ = extension;
+
+ context_menu_contents_.reset(
+ new ExtensionActionContextMenuModel(extension, this));
+ context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get()));
+ context_menu_menu_->RunContextMenuAt(point);
+}
+
+void ExtensionActionContextMenu::InstallUIProceed() {
+ // TODO(finnur): GetLastActive returns NULL in unit tests.
+ Browser* browser = BrowserList::GetLastActive();
+ std::string id = extension_->id();
+ browser->profile()->GetExtensionsService()->UninstallExtension(id, false);
+}
diff --git a/chrome/browser/views/extensions/extension_action_context_menu.h b/chrome/browser/views/extensions/extension_action_context_menu.h
new file mode 100644
index 0000000..92ac97c
--- /dev/null
+++ b/chrome/browser/views/extensions/extension_action_context_menu.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_ACTION_CONTEXT_MENU_H_
+#define CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_ACTION_CONTEXT_MENU_H_
+
+#include "views/controls/menu/menu_2.h"
+#include "chrome/browser/extensions/extension_install_ui.h"
+#include "chrome/browser/extensions/extension_action_context_menu_model.h"
+
+class Extension;
+
+// Displays the context menu for extension action icons (browser/page actions).
+class ExtensionActionContextMenu : public ExtensionInstallUI::Delegate {
+ public:
+ ExtensionActionContextMenu();
+ ~ExtensionActionContextMenu();
+
+ // Display the context menu at a given point.
+ void Run(Extension* extension, const gfx::Point& point);
+
+ // ExtensionInstallUI::Delegate overrides.
+ virtual void InstallUIProceed();
+ virtual void InstallUIAbort() {}
+
+ private:
+ // The options menu.
+ scoped_ptr<ExtensionActionContextMenuModel> context_menu_contents_;
+ scoped_ptr<views::Menu2> context_menu_menu_;
+
+ // The extension we are showing the menu for.
+ Extension* extension_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionActionContextMenu);
+};
+
+#endif // CHROME_BROWSER_VIEWS_EXTENSIONS_EXTENSION_ACTION_CONTEXT_MENU_H_
diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc
index d8c41e0..004656d 100644
--- a/chrome/browser/views/location_bar_view.cc
+++ b/chrome/browser/views/location_bar_view.cc
@@ -1379,12 +1379,26 @@ void LocationBarView::PageActionImageView::OnMouseMoved(
bool LocationBarView::PageActionImageView::OnMousePressed(
const views::MouseEvent& event) {
int button = -1;
- if (event.IsLeftMouseButton())
+ if (event.IsLeftMouseButton()) {
button = 1;
- else if (event.IsMiddleMouseButton())
+ } else if (event.IsMiddleMouseButton()) {
button = 2;
- else if (event.IsRightMouseButton())
- button = 3;
+ } else if (event.IsRightMouseButton()) {
+ // Get the top left point of this button in screen coordinates.
+ gfx::Point point = gfx::Point(0,0);
+ ConvertPointToScreen(this, &point);
+
+ // Make the menu appear below the button.
+ point.Offset(0, height());
+
+ Extension* extension = profile_->GetExtensionsService()->GetExtensionById(
+ page_action()->extension_id(), false);
+
+ if (!context_menu_.get())
+ context_menu_.reset(new ExtensionActionContextMenu());
+ context_menu_->Run(extension, point);
+ return false;
+ }
ExecuteAction(button);
return true;
diff --git a/chrome/browser/views/location_bar_view.h b/chrome/browser/views/location_bar_view.h
index 85d1d89..3319c39 100644
--- a/chrome/browser/views/location_bar_view.h
+++ b/chrome/browser/views/location_bar_view.h
@@ -18,6 +18,7 @@
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/toolbar_model.h"
#include "chrome/browser/views/browser_bubble.h"
+#include "chrome/browser/views/extensions/extension_action_context_menu.h"
#include "chrome/browser/views/info_bubble.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
@@ -428,6 +429,9 @@ class LocationBarView : public LocationBar,
typedef std::map<std::string, SkBitmap> PageActionMap;
PageActionMap page_action_icons_;
+ // The context menu for this page action.
+ scoped_ptr<ExtensionActionContextMenu> context_menu_;
+
// The object that is waiting for the image loading to complete
// asynchronously.
ImageLoadingTracker* tracker_;