Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(530)

Unified Diff: chrome/browser/ui/views/status_icons/status_icon_chromeos.cc

Issue 8476003: Implement the status tray/icon API for ChromeOS. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixing gyp problems in the bots that led to reverting. Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/views/status_icons/status_icon_chromeos.cc
diff --git a/chrome/browser/ui/views/status_icons/status_icon_chromeos.cc b/chrome/browser/ui/views/status_icons/status_icon_chromeos.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e4979314499871c09ed3849799e9c10c8fdb92cf
--- /dev/null
+++ b/chrome/browser/ui/views/status_icons/status_icon_chromeos.cc
@@ -0,0 +1,203 @@
+// Copyright (c) 2011 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/ui/views/status_icons/status_icon_chromeos.h"
+
+#include "chrome/browser/chromeos/frame/browser_view.h"
+#include "chrome/browser/chromeos/status/status_area_button.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "content/public/browser/notification_service.h"
+#include "views/controls/menu/menu_delegate.h"
+#include "views/controls/menu/menu_model_adapter.h"
+#include "views/controls/menu/menu_runner.h"
+#include "views/controls/menu/view_menu_delegate.h"
+
+class StatusIconChromeOS::NotificationTrayButton
+ : public StatusAreaButton,
+ public views::MenuDelegate,
+ public views::ViewMenuDelegate {
+ public:
+ NotificationTrayButton(StatusIconChromeOS* status_icon,
+ StatusAreaButton::Delegate* delegate)
+ : StatusAreaButton(delegate, this),
+ status_icon_(status_icon) {
+ }
+ virtual ~NotificationTrayButton() {}
+
+ void SetImage(const SkBitmap& image) {
+ SetIcon(image);
+ SetVisible(true);
+ PreferredSizeChanged();
+ SchedulePaint();
+ }
+
+ void Hide() {
+ SetVisible(false);
+ SchedulePaint();
+ }
+
+ // views::MenuButton overrides.
+ virtual bool Activate() OVERRIDE {
+ // All tray buttons are removed on status icon destruction.
+ // This should never be called afterwards.
+ bool retval = views::MenuButton::Activate();
+ status_icon_->Clicked();
+ return retval;
+ }
+
+ // views::ViewMenuDelegate implementation.
+ virtual void RunMenu(views::View* source, const gfx::Point& pt)
+ OVERRIDE {
+ views::MenuRunner* menu_runner = status_icon_->menu_runner();
+ if (!menu_runner)
+ return;
+
+ gfx::Point screen_location;
+ views::View::ConvertPointToScreen(source, &screen_location);
+ gfx::Rect bounds(screen_location, source->size());
+ if (menu_runner->RunMenuAt(
+ source->GetWidget()->GetTopLevelWidget(), this, bounds,
+ views::MenuItemView::TOPRIGHT, views::MenuRunner::HAS_MNEMONICS) ==
+ views::MenuRunner::MENU_DELETED)
+ return;
+ }
+
+ private:
+ StatusIconChromeOS* status_icon_;
+};
+
+StatusIconChromeOS::StatusIconChromeOS()
+ : last_image_(new SkBitmap()) {
+ // This class adds a tray icon in the status area of all browser windows
+ // in Chrome OS. This is the closest we can get to a system tray icon.
+ for (BrowserList::BrowserVector::const_iterator it = BrowserList::begin();
+ it != BrowserList::end(); ++it) {
+ AddIconToBrowser(*it);
+ }
+
+ // Listen to all browser open/close events to keep our map up to date.
+ registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
+ content::NotificationService::AllSources());
+ registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED,
+ content::NotificationService::AllSources());
+}
+
+StatusIconChromeOS::~StatusIconChromeOS() {
+ for (TrayButtonMap::const_iterator it = tray_button_map_.begin();
+ it != tray_button_map_.end(); ++it) {
+ it->first->RemoveTrayButton(it->second);
+ }
+}
+
+void StatusIconChromeOS::Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ switch (type) {
+ case chrome::NOTIFICATION_BROWSER_WINDOW_READY: {
+ Browser* browser = content::Source<Browser>(source).ptr();
+ AddIconToBrowser(browser);
+ break;
+ }
+
+ case chrome::NOTIFICATION_BROWSER_CLOSED: {
+ chromeos::BrowserView* browser_view =
+ chromeos::BrowserView::GetBrowserViewForBrowser(
+ content::Source<Browser>(source).ptr());
+ DCHECK(browser_view);
+ tray_button_map_.erase(browser_view);
+ break;
+ }
+
+ default:
+ NOTREACHED();
+ }
+}
+
+void StatusIconChromeOS::AddIconToBrowser(Browser* browser) {
+ chromeos::BrowserView* browser_view =
+ chromeos::BrowserView::GetBrowserViewForBrowser(browser);
+ DCHECK(browser_view);
+
+ if (tray_button_map_.find(browser_view) != tray_button_map_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ NotificationTrayButton* tray_button =
+ new NotificationTrayButton(this, browser_view);
+ tray_button_map_[browser_view] = tray_button;
+ browser_view->AddTrayButton(tray_button, false);
+ if (!last_image_->empty())
+ tray_button->SetImage(*last_image_.get());
+}
+
+void StatusIconChromeOS::SetImage(const SkBitmap& image) {
+ if (image.isNull())
+ return;
+
+ for (TrayButtonMap::const_iterator it = tray_button_map_.begin();
+ it != tray_button_map_.end(); ++it) {
+ it->second->SetImage(image);
+ }
+ *last_image_.get() = image;
+}
+
+void StatusIconChromeOS::SetPressedImage(const SkBitmap& image) {
+ // Not supported. Chrome OS shows the context menu on left clicks.
+}
+
+void StatusIconChromeOS::SetToolTip(const string16& tool_tip) {
+ for (TrayButtonMap::const_iterator it = tray_button_map_.begin();
+ it != tray_button_map_.end(); ++it) {
+ it->second->SetTooltipText(tool_tip);
+ }
+}
+
+void StatusIconChromeOS::DisplayBalloon(const SkBitmap& icon,
+ const string16& title,
+ const string16& contents) {
+ notification_.DisplayBalloon(icon, title, contents);
+}
+
+void StatusIconChromeOS::Clicked() {
+ // Chrome OS shows the context menu on left button clicks, and this event
+ // should only be dispatched when the click doesn't show the context menu.
+ if (!menu_runner_.get())
+ DispatchClickEvent();
+}
+
+StatusAreaButton* StatusIconChromeOS::GetButtonForBrowser(Browser* browser) {
+ DCHECK(browser);
+ chromeos::BrowserView* browser_view =
+ chromeos::BrowserView::GetBrowserViewForBrowser(browser);
+ DCHECK(browser_view);
+
+ if (tray_button_map_.find(browser_view) == tray_button_map_.end()) {
+ NOTREACHED();
+ return NULL;
+ }
+
+ return tray_button_map_[browser_view];
+}
+
+void StatusIconChromeOS::UpdatePlatformContextMenu(ui::MenuModel* menu) {
+ // If no items are passed, blow away our context menu.
+ if (!menu) {
+ context_menu_adapter_.reset();
+ menu_runner_.reset();
+ return;
+ }
+
+ // Create context menu with the new contents.
+ views::MenuModelAdapter* adapter = new views::MenuModelAdapter(menu);
+ context_menu_adapter_.reset(adapter);
+ views::MenuItemView* menu_view = new views::MenuItemView(adapter);
+ adapter->BuildMenu(menu_view);
+
+ // menu_runner_ takes ownership of menu.
+ menu_runner_.reset(new views::MenuRunner(menu_view));
+}

Powered by Google App Engine
This is Rietveld 408576698