From 9979f5d4a25cab18fa10885c5c7b64ea9f8d8eeb Mon Sep 17 00:00:00 2001 From: "atwilson@chromium.org" Date: Fri, 20 Aug 2010 04:52:44 +0000 Subject: Added support for context menus to status icons. BUG=37375 TEST=updated StatusIcon unit tests Review URL: http://codereview.chromium.org/3189003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@56812 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/status_icons/status_icon.cc | 18 +++++++++++ chrome/browser/status_icons/status_icon.h | 35 +++++++++++++++++++--- .../browser/status_icons/status_icon_unittest.cc | 1 + .../browser/status_icons/status_tray_unittest.cc | 2 ++ 4 files changed, 52 insertions(+), 4 deletions(-) (limited to 'chrome/browser/status_icons') diff --git a/chrome/browser/status_icons/status_icon.cc b/chrome/browser/status_icons/status_icon.cc index 9fed83d..066419f 100644 --- a/chrome/browser/status_icons/status_icon.cc +++ b/chrome/browser/status_icons/status_icon.cc @@ -4,6 +4,15 @@ #include "chrome/browser/status_icons/status_icon.h" +#include "app/menus/menu_model.h" + +StatusIcon::StatusIcon() +{ +} + +StatusIcon::~StatusIcon() { +} + void StatusIcon::AddObserver(Observer* observer) { observers_.AddObserver(observer); } @@ -12,6 +21,15 @@ void StatusIcon::RemoveObserver(Observer* observer) { observers_.RemoveObserver(observer); } +bool StatusIcon::HasObservers() { + return observers_.size() > 0; +} + void StatusIcon::DispatchClickEvent() { FOR_EACH_OBSERVER(Observer, observers_, OnClicked()); } + +void StatusIcon::SetContextMenu(menus::MenuModel* menu) { + context_menu_contents_.reset(menu); + ResetContextMenu(menu); +} diff --git a/chrome/browser/status_icons/status_icon.h b/chrome/browser/status_icons/status_icon.h index 8245e12..8f868b5 100644 --- a/chrome/browser/status_icons/status_icon.h +++ b/chrome/browser/status_icons/status_icon.h @@ -7,14 +7,19 @@ #pragma once #include "base/observer_list.h" +#include "base/scoped_ptr.h" #include "base/string16.h" class SkBitmap; +namespace menus { +class MenuModel; +} + class StatusIcon { public: - StatusIcon() {} - virtual ~StatusIcon() {} + StatusIcon(); + virtual ~StatusIcon(); // Sets the image associated with this status icon. virtual void SetImage(const SkBitmap& image) = 0; @@ -25,23 +30,45 @@ class StatusIcon { // Sets the hover text for this status icon. virtual void SetToolTip(const string16& tool_tip) = 0; + // Set the context menu for this icon. The icon takes ownership of the passed + // context menu. Passing NULL results in no menu at all. + void SetContextMenu(menus::MenuModel* menu); + class Observer { public: virtual ~Observer() {} - // Called when the user clicks on the system tray icon. + // Called when the user clicks on the system tray icon. Clicks that result + // in the context menu being displayed will not be passed to this observer + // (i.e. if there's a context menu set on this status icon, and the user + // right clicks on the icon to display the context menu, OnClicked will not + // be called). virtual void OnClicked() = 0; }; - // Adds/Removes an observer for status bar events. + // Adds/Removes an observer for clicks on the status icon. If an observer is + // registered, then left clicks on the status icon will result in the observer + // being called, otherwise, both left and right clicks will display the + // context menu (if any). void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); + // Returns true if there are registered click observers. + bool HasObservers(); + // Dispatches a click event to the observers. void DispatchClickEvent(); + protected: + // Invoked after a call to SetContextMenu() to let the platform-specific + // subclass update the native context menu based on the new model. If NULL is + // passed, subclass should destroy the native context menu. + virtual void ResetContextMenu(menus::MenuModel* model) = 0; + private: ObserverList observers_; + // Context menu, if any. + scoped_ptr context_menu_contents_; DISALLOW_COPY_AND_ASSIGN(StatusIcon); }; diff --git a/chrome/browser/status_icons/status_icon_unittest.cc b/chrome/browser/status_icons/status_icon_unittest.cc index db8c529..1738ff7 100644 --- a/chrome/browser/status_icons/status_icon_unittest.cc +++ b/chrome/browser/status_icons/status_icon_unittest.cc @@ -18,6 +18,7 @@ class TestStatusIcon : public StatusIcon { virtual void SetImage(const SkBitmap& image) {} virtual void SetPressedImage(const SkBitmap& image) {} virtual void SetToolTip(const string16& tool_tip) {} + virtual void ResetContextMenu(menus::MenuModel* menu) {} }; TEST(StatusIconTest, ObserverAdd) { diff --git a/chrome/browser/status_icons/status_tray_unittest.cc b/chrome/browser/status_icons/status_tray_unittest.cc index 26219bd..1d43cdc 100644 --- a/chrome/browser/status_icons/status_tray_unittest.cc +++ b/chrome/browser/status_icons/status_tray_unittest.cc @@ -15,6 +15,7 @@ class MockStatusIcon : public StatusIcon { virtual void SetImage(const SkBitmap& image) {} virtual void SetPressedImage(const SkBitmap& image) {} virtual void SetToolTip(const string16& tool_tip) {} + virtual void ResetContextMenu(menus::MenuModel* menu) {} virtual void AddObserver(StatusIcon::Observer* observer) {} virtual void RemoveObserver(StatusIcon::Observer* observer) {} }; @@ -22,6 +23,7 @@ class MockStatusIcon : public StatusIcon { class TestStatusTray : public StatusTray { public: MOCK_METHOD0(CreatePlatformStatusIcon, StatusIcon*()); + MOCK_METHOD1(ResetContextMenu, void(menus::MenuModel*)); }; TEST(StatusTrayTest, Create) { -- cgit v1.1