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

Side by Side 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: disabling the unit test for non-chromeos builds. 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/views/status_icons/status_icon_chromeos.h"
6
7 #include "chrome/browser/chromeos/frame/browser_view.h"
8 #include "chrome/browser/chromeos/status/status_area_button.h"
9 #include "chrome/browser/profiles/profile_manager.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/browser_list.h"
12 #include "chrome/common/chrome_notification_types.h"
13 #include "content/public/browser/notification_service.h"
14 #include "views/controls/menu/menu_delegate.h"
15 #include "views/controls/menu/menu_model_adapter.h"
16 #include "views/controls/menu/menu_runner.h"
17 #include "views/controls/menu/view_menu_delegate.h"
18
19 namespace {
20
21 chromeos::BrowserView* GetBrowserView(Browser* browser) {
22 chromeos::BrowserView* browser_view = static_cast<chromeos::BrowserView*>(
23 BrowserView::GetBrowserViewForBrowser(browser));
stevenjb 2011/11/14 19:03:22 We should really put this in chromeos/frame/browse
Leandro Graciá Gil 2011/11/15 22:23:31 Done.
24 DCHECK(browser_view);
25 return browser_view;
26 }
27
28 } // anonymous namespace
29
30 class StatusIconChromeOS::NotificationTrayButton
31 : public StatusAreaButton,
32 public views::MenuDelegate,
33 public views::ViewMenuDelegate {
34 public:
35 NotificationTrayButton(StatusIconChromeOS* status_icon,
36 StatusAreaButton::Delegate* delegate)
stevenjb 2011/11/14 19:03:22 nit: align parameters
Leandro Graciá Gil 2011/11/15 22:23:31 Done.
37 : StatusAreaButton(delegate, this),
38 status_icon_(status_icon) {
39 }
40 virtual ~NotificationTrayButton() {}
41
42 void SetImage(const SkBitmap& image) {
43 SetIcon(image);
44 SetVisible(true);
45 PreferredSizeChanged();
46 SchedulePaint();
47 }
48
49 void Hide() {
50 SetVisible(false);
51 SchedulePaint();
52 }
53
54 // views::MenuButton overrides.
55 virtual bool Activate() OVERRIDE {
56 // All tray buttons are removed on status icon destruction.
57 // This should never be called afterwards.
58 bool retval = views::MenuButton::Activate();
59 status_icon_->Clicked();
60 return retval;
61 }
62
63 // views::ViewMenuDelegate implementation.
64 virtual void RunMenu(views::View* source, const gfx::Point& pt)
65 OVERRIDE {
66 views::MenuRunner* menu_runner = status_icon_->menu_runner();
67 if (!menu_runner)
68 return;
69
70 gfx::Point screen_location;
71 views::View::ConvertPointToScreen(source, &screen_location);
72 gfx::Rect bounds(screen_location, source->size());
73 if (menu_runner->RunMenuAt(
74 source->GetWidget()->GetTopLevelWidget(), this, bounds,
75 views::MenuItemView::TOPRIGHT, views::MenuRunner::HAS_MNEMONICS) ==
76 views::MenuRunner::MENU_DELETED)
77 return;
stevenjb 2011/11/14 19:03:22 What is the purpose of the if statement here?
Leandro Graciá Gil 2011/11/15 22:23:31 RunMenuAt is defined using WARN_UNUSED_RESULT. So,
78 }
79
80 private:
81 StatusIconChromeOS* status_icon_;
82 };
83
84 StatusIconChromeOS::StatusIconChromeOS()
85 : last_image_(new SkBitmap()) {
86 // This class adds a tray icon in all browser windows for Chrome OS.
87 // Since the target of this API is to provide notification as much
stevenjb 2011/11/14 19:03:22 This sentence isn't clear to me.
Leandro Graciá Gil 2011/11/15 22:23:31 Done.
88 // "permanent" as possible, this is the closest we can get since
89 // there is no real system tray in Chrome OS, only browser windows.
90 for (BrowserList::BrowserVector::const_iterator it = BrowserList::begin();
Andrew T Wilson (Slow) 2011/11/14 23:46:03 Just to verify - do we want this on all browser wi
Leandro Graciá Gil 2011/11/15 22:23:31 Yes, I have discussed this with the Chrome OS UI d
91 it != BrowserList::end(); ++it) {
92 AddIconToBrowser(*it);
93 }
94
95 // Listen to all browser open/close events to keep our map up to date.
96 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
97 content::NotificationService::AllSources());
98 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED,
99 content::NotificationService::AllSources());
100 }
101
102 StatusIconChromeOS::~StatusIconChromeOS() {
103 for (TrayButtonMap::const_iterator it = tray_button_map_.begin();
104 it != tray_button_map_.end(); ++it) {
105 it->first->RemoveTrayButton(it->second);
106 }
107 }
108
109 void StatusIconChromeOS::Observe(int type,
110 const content::NotificationSource& source,
111 const content::NotificationDetails& details) {
112 switch (type) {
113 case chrome::NOTIFICATION_BROWSER_WINDOW_READY: {
114 Browser* browser = content::Source<Browser>(source).ptr();
115 AddIconToBrowser(browser);
116 break;
117 }
118
119 case chrome::NOTIFICATION_BROWSER_CLOSED: {
120 chromeos::BrowserView* browser_view = GetBrowserView(
121 content::Source<Browser>(source).ptr());
122 tray_button_map_.erase(browser_view);
123 break;
124 }
125
126 default:
127 NOTREACHED();
128 }
129 }
130
131 void StatusIconChromeOS::AddIconToBrowser(Browser* browser) {
132 chromeos::BrowserView* browser_view = GetBrowserView(browser);
133 DCHECK(tray_button_map_.find(browser_view) == tray_button_map_.end());
stevenjb 2011/11/14 19:03:22 We should probably do more than a DCHECK here, sin
Leandro Graciá Gil 2011/11/15 22:23:31 Done.
134
135 NotificationTrayButton* tray_button =
136 new NotificationTrayButton(this, browser_view);
137 tray_button_map_[browser_view] = tray_button;
138 browser_view->AddTrayButton(tray_button, false);
139 if (!last_image_->empty())
140 tray_button->SetImage(*last_image_.get());
141 }
142
143 void StatusIconChromeOS::SetImage(const SkBitmap& image) {
144 if (image.isNull())
145 return;
146
147 for (TrayButtonMap::const_iterator it = tray_button_map_.begin();
148 it != tray_button_map_.end(); ++it) {
149 it->second->SetImage(image);
150 }
151 *last_image_.get() = image;
152 }
153
154 void StatusIconChromeOS::SetPressedImage(const SkBitmap& image) {
155 // Not supported. Chrome OS shows the context menu on left clicks.
156 }
157
158 void StatusIconChromeOS::SetToolTip(const string16& tool_tip) {
159 for (TrayButtonMap::const_iterator it = tray_button_map_.begin();
160 it != tray_button_map_.end(); ++it) {
161 it->second->SetTooltipText(tool_tip);
162 }
163 }
164
165 void StatusIconChromeOS::DisplayBalloon(const SkBitmap& icon,
166 const string16& title,
167 const string16& contents) {
168 notification_.DisplayBalloon(icon, title, contents);
169 }
170
171 void StatusIconChromeOS::Clicked() {
172 // Chrome OS shows the context menu on left button clicks, and this event
173 // should only be dispatched when the click doesn't show the context menu.
174 if (!menu_runner_.get())
175 DispatchClickEvent();
176 }
177
178 void StatusIconChromeOS::UpdatePlatformContextMenu(ui::MenuModel* menu) {
179 // If no items are passed, blow away our context menu.
180 if (!menu) {
181 context_menu_adapter_.reset();
182 menu_runner_.reset();
183 return;
184 }
185
186 // Create context menu with the new contents.
187 views::MenuModelAdapter* adapter = new views::MenuModelAdapter(menu);
188 context_menu_adapter_.reset(adapter);
189 views::MenuItemView* menu_view = new views::MenuItemView(adapter);
190 adapter->BuildMenu(menu_view);
191
192 // menu_runner_ takes ownership of menu.
193 menu_runner_.reset(new views::MenuRunner(menu_view));
194 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698