diff options
Diffstat (limited to 'chrome/browser/status_icons')
-rw-r--r-- | chrome/browser/status_icons/status_icon.cc | 18 | ||||
-rw-r--r-- | chrome/browser/status_icons/status_icon.h | 36 | ||||
-rw-r--r-- | chrome/browser/status_icons/status_icon_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/status_icons/status_tray.cc | 26 | ||||
-rw-r--r-- | chrome/browser/status_icons/status_tray.h | 36 | ||||
-rw-r--r-- | chrome/browser/status_icons/status_tray_manager.cc | 56 | ||||
-rw-r--r-- | chrome/browser/status_icons/status_tray_manager.h | 30 | ||||
-rw-r--r-- | chrome/browser/status_icons/status_tray_unittest.cc | 40 |
8 files changed, 98 insertions, 146 deletions
diff --git a/chrome/browser/status_icons/status_icon.cc b/chrome/browser/status_icons/status_icon.cc index 9fed83d..baaa6cc 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); + UpdatePlatformContextMenu(menu); +} diff --git a/chrome/browser/status_icons/status_icon.h b/chrome/browser/status_icons/status_icon.h index ffe0f5f..5398eb3 100644 --- a/chrome/browser/status_icons/status_icon.h +++ b/chrome/browser/status_icons/status_icon.h @@ -4,16 +4,22 @@ #ifndef CHROME_BROWSER_STATUS_ICONS_STATUS_ICON_H_ #define CHROME_BROWSER_STATUS_ICONS_STATUS_ICON_H_ +#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; @@ -24,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 UpdatePlatformContextMenu(menus::MenuModel* model) = 0; + private: ObserverList<Observer> observers_; + // Context menu, if any. + scoped_ptr<menus::MenuModel> 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..48fbc20 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 UpdatePlatformContextMenu(menus::MenuModel* menu) {} }; TEST(StatusIconTest, ObserverAdd) { @@ -44,4 +45,3 @@ TEST(StatusIconTest, ObserverRemove) { icon.RemoveObserver(&observer); icon.DispatchClickEvent(); } - diff --git a/chrome/browser/status_icons/status_tray.cc b/chrome/browser/status_icons/status_tray.cc index b7ae49c..8648351 100644 --- a/chrome/browser/status_icons/status_tray.cc +++ b/chrome/browser/status_icons/status_tray.cc @@ -4,6 +4,8 @@ #include "chrome/browser/status_icons/status_tray.h" +#include <algorithm> + #include "base/stl_util-inl.h" #include "chrome/browser/status_icons/status_icon.h" @@ -16,29 +18,23 @@ StatusTray::~StatusTray() { void StatusTray::RemoveAllIcons() { // Walk any active status icons and delete them. - STLDeleteContainerPairSecondPointers(status_icons_.begin(), - status_icons_.end()); + STLDeleteContainerPointers(status_icons_.begin(), status_icons_.end()); status_icons_.clear(); } -StatusIcon* StatusTray::GetStatusIcon(const string16& identifier) { - StatusIconMap::const_iterator iter = status_icons_.find(identifier); - if (iter != status_icons_.end()) - return iter->second; - - // No existing StatusIcon, create a new one. - StatusIcon* icon = CreateStatusIcon(); +StatusIcon* StatusTray::CreateStatusIcon() { + StatusIcon* icon = CreatePlatformStatusIcon(); if (icon) - status_icons_[identifier] = icon; + status_icons_.push_back(icon); return icon; } -void StatusTray::RemoveStatusIcon(const string16& identifier) { - StatusIconMap::iterator iter = status_icons_.find(identifier); +void StatusTray::RemoveStatusIcon(StatusIcon* icon) { + StatusIconList::iterator iter = std::find( + status_icons_.begin(), status_icons_.end(), icon); if (iter != status_icons_.end()) { - // Free the StatusIcon from the map (can't put scoped_ptr in a map, so we - // have to do it manually). - delete iter->second; + // Free the StatusIcon from the list. + delete *iter; status_icons_.erase(iter); } } diff --git a/chrome/browser/status_icons/status_tray.h b/chrome/browser/status_icons/status_tray.h index 30a60aa..a0da771 100644 --- a/chrome/browser/status_icons/status_tray.h +++ b/chrome/browser/status_icons/status_tray.h @@ -4,9 +4,12 @@ #ifndef CHROME_BROWSER_STATUS_ICONS_STATUS_TRAY_H_ #define CHROME_BROWSER_STATUS_ICONS_STATUS_TRAY_H_ +#pragma once -#include "base/hash_tables.h" -#include "base/scoped_ptr.h" +#include <vector> + +#include "base/basictypes.h" +#include "base/gtest_prod_util.h" class StatusIcon; @@ -15,38 +18,37 @@ class StatusIcon; class StatusTray { public: // Static factory method that is implemented separately for each platform to - // produce the appropriate platform-specific instance. + // produce the appropriate platform-specific instance. Returns NULL if this + // platform does not support status icons. static StatusTray* Create(); virtual ~StatusTray(); - // Gets the current status icon associated with this identifier, or creates - // a new one if none exists. The StatusTray retains ownership of the - // StatusIcon. Returns NULL if the status tray icon could not be created. - StatusIcon* GetStatusIcon(const string16& identifier); + // Creates a new StatusIcon. The StatusTray retains ownership of the + // StatusIcon. Returns NULL if the StatusIcon could not be created. + StatusIcon* CreateStatusIcon(); // Removes the current status icon associated with this identifier, if any. - void RemoveStatusIcon(const string16& identifier); + void RemoveStatusIcon(StatusIcon* icon); protected: StatusTray(); - // Factory method for creating a status icon. - virtual StatusIcon* CreateStatusIcon() = 0; + // Factory method for creating a status icon for this platform. + virtual StatusIcon* CreatePlatformStatusIcon() = 0; // Removes all StatusIcons (used by derived classes to clean up in case they // track external state used by the StatusIcons). void RemoveAllIcons(); - typedef base::hash_map<string16, StatusIcon*> StatusIconMap; + typedef std::vector<StatusIcon*> StatusIconList; // Returns the list of active status icons so subclasses can operate on them. - const StatusIconMap& status_icons() { return status_icons_; } + const StatusIconList& status_icons() { return status_icons_; } private: - // Map containing all active StatusIcons. - // Key: String identifiers (passed in to GetStatusIcon) - // Value: The StatusIcon associated with that identifier (strong pointer - - // StatusIcons are freed when the StatusTray destructor is called). - StatusIconMap status_icons_; + FRIEND_TEST_ALL_PREFIXES(StatusTrayTest, CreateRemove); + + // List containing all active StatusIcons. + StatusIconList status_icons_; DISALLOW_COPY_AND_ASSIGN(StatusTray); }; diff --git a/chrome/browser/status_icons/status_tray_manager.cc b/chrome/browser/status_icons/status_tray_manager.cc deleted file mode 100644 index 7a8a779..0000000 --- a/chrome/browser/status_icons/status_tray_manager.cc +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2010 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/status_icons/status_tray_manager.h" - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/logging.h" -#include "base/string_util.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" -#include "chrome/browser/browser_window.h" -#include "chrome/browser/status_icons/status_tray.h" -#include "grit/browser_resources.h" -#include "grit/chromium_strings.h" -#include "grit/theme_resources.h" - -StatusTrayManager::StatusTrayManager() { -} - -StatusTrayManager::~StatusTrayManager() { -} - -void StatusTrayManager::Init(Profile* profile) { -#if !(defined(OS_LINUX) && defined(TOOLKIT_VIEWS)) - DCHECK(profile); - profile_ = profile; - status_tray_.reset(StatusTray::Create()); - StatusIcon* icon = status_tray_->GetStatusIcon(ASCIIToUTF16("chrome_main")); - if (icon) { - // Create an icon and add ourselves as a click observer on it - SkBitmap* bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_STATUS_TRAY_ICON); - SkBitmap* pressed = ResourceBundle::GetSharedInstance().GetBitmapNamed( - IDR_STATUS_TRAY_ICON_PRESSED); - icon->SetImage(*bitmap); - icon->SetPressedImage(*pressed); - icon->SetToolTip(l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); - icon->AddObserver(this); - } -#endif -} - -void StatusTrayManager::OnClicked() { - // When the tray icon is clicked, bring up the extensions page for now. - Browser* browser = BrowserList::GetLastActiveWithProfile(profile_); - if (browser) { - // Bring up the existing browser window and show the extensions tab. - browser->window()->Activate(); - browser->ShowExtensionsTab(); - } else { - // No windows are currently open, so open a new one. - Browser::OpenExtensionsWindow(profile_); - } -} diff --git a/chrome/browser/status_icons/status_tray_manager.h b/chrome/browser/status_icons/status_tray_manager.h deleted file mode 100644 index 2a880e4..0000000 --- a/chrome/browser/status_icons/status_tray_manager.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2010 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_STATUS_ICONS_STATUS_TRAY_MANAGER_H_ -#define CHROME_BROWSER_STATUS_ICONS_STATUS_TRAY_MANAGER_H_ - -#include "base/scoped_ptr.h" -#include "chrome/browser/status_icons/status_icon.h" - -class Profile; -class StatusTray; - -// Manages the set of status tray icons and associated UI. -class StatusTrayManager : private StatusIcon::Observer { - public: - StatusTrayManager(); - virtual ~StatusTrayManager(); - - void Init(Profile* profile); - - private: - // Overriden from StatusIcon::Observer: - virtual void OnClicked(); - - scoped_ptr<StatusTray> status_tray_; - Profile* profile_; -}; - -#endif // CHROME_BROWSER_STATUS_ICONS_STATUS_TRAY_MANAGER_H_ diff --git a/chrome/browser/status_icons/status_tray_unittest.cc b/chrome/browser/status_icons/status_tray_unittest.cc index 9b60010..a047689 100644 --- a/chrome/browser/status_icons/status_tray_unittest.cc +++ b/chrome/browser/status_icons/status_tray_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/string_util.h" +#include "base/utf_string_conversions.h" #include "chrome/browser/status_icons/status_icon.h" #include "chrome/browser/status_icons/status_tray.h" #include "testing/gmock/include/gmock/gmock.h" @@ -14,41 +15,34 @@ 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 UpdatePlatformContextMenu(menus::MenuModel* menu) {} virtual void AddObserver(StatusIcon::Observer* observer) {} virtual void RemoveObserver(StatusIcon::Observer* observer) {} }; class TestStatusTray : public StatusTray { public: - MOCK_METHOD0(CreateStatusIcon, StatusIcon*()); + MOCK_METHOD0(CreatePlatformStatusIcon, StatusIcon*()); + MOCK_METHOD1(UpdatePlatformContextMenu, void(menus::MenuModel*)); }; TEST(StatusTrayTest, Create) { // Check for creation and leaks. TestStatusTray tray; - EXPECT_CALL(tray, CreateStatusIcon()).WillOnce(Return(new MockStatusIcon())); - tray.GetStatusIcon(ASCIIToUTF16("test")); + EXPECT_CALL(tray, + CreatePlatformStatusIcon()).WillOnce(Return(new MockStatusIcon())); + tray.CreateStatusIcon(); } -TEST(StatusTrayTest, GetIconTwice) { +// Make sure that removing an icon removes it from the list. +TEST(StatusTrayTest, CreateRemove) { TestStatusTray tray; - string16 id = ASCIIToUTF16("test"); - // We should not try to create a new icon if we get the same ID twice. - EXPECT_CALL(tray, CreateStatusIcon()).WillOnce(Return(new MockStatusIcon())); - StatusIcon* icon = tray.GetStatusIcon(id); - EXPECT_EQ(icon, tray.GetStatusIcon(id)); -} - -TEST(StatusTrayTest, GetIconAfterRemove) { - TestStatusTray tray; - string16 id = ASCIIToUTF16("test"); - EXPECT_CALL(tray, CreateStatusIcon()).Times(2) - .WillOnce(Return(new MockStatusIcon())) - .WillOnce(Return(new MockStatusIcon())); - StatusIcon* icon = tray.GetStatusIcon(id); - EXPECT_EQ(icon, tray.GetStatusIcon(id)); - - // If we remove the icon, then we should create a new one the next time in. - tray.RemoveStatusIcon(id); - tray.GetStatusIcon(id); + EXPECT_CALL(tray, + CreatePlatformStatusIcon()).WillOnce(Return(new MockStatusIcon())); + StatusIcon* icon = tray.CreateStatusIcon(); + EXPECT_EQ(1U, tray.status_icons_.size()); + tray.RemoveStatusIcon(icon); + EXPECT_EQ(0U, tray.status_icons_.size()); + // Calling again should do nothing. + tray.RemoveStatusIcon(icon); } |