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

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: review and gyp fixes. 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 class StatusIconChromeOS::NotificationTrayButton
20 : public StatusAreaButton,
21 public views::MenuDelegate,
22 public views::ViewMenuDelegate {
23 public:
24 NotificationTrayButton(StatusIconChromeOS* status_icon,
25 StatusAreaButton::Delegate* delegate)
26 : StatusAreaButton(delegate, this),
27 status_icon_(status_icon) {
28 }
29 virtual ~NotificationTrayButton() {}
30
31 void SetImage(const SkBitmap& image) {
32 SetIcon(image);
33 SetVisible(true);
34 PreferredSizeChanged();
35 SchedulePaint();
36 }
37
38 void Hide() {
39 SetVisible(false);
40 SchedulePaint();
41 }
42
43 // views::MenuButton overrides.
44 virtual bool Activate() OVERRIDE {
45 // All tray buttons are removed on status icon destruction.
46 // This should never be called afterwards.
47 bool retval = views::MenuButton::Activate();
48 status_icon_->Clicked();
49 return retval;
50 }
51
52 // views::ViewMenuDelegate implementation.
53 virtual void RunMenu(views::View* source, const gfx::Point& pt)
54 OVERRIDE {
55 views::MenuRunner* menu_runner = status_icon_->menu_runner();
56 if (!menu_runner)
57 return;
58
59 gfx::Point screen_location;
60 views::View::ConvertPointToScreen(source, &screen_location);
61 gfx::Rect bounds(screen_location, source->size());
62 if (menu_runner->RunMenuAt(
63 source->GetWidget()->GetTopLevelWidget(), this, bounds,
64 views::MenuItemView::TOPRIGHT, views::MenuRunner::HAS_MNEMONICS) ==
65 views::MenuRunner::MENU_DELETED)
66 return;
67 }
68
69 private:
70 StatusIconChromeOS* status_icon_;
71 };
72
73 StatusIconChromeOS::StatusIconChromeOS()
74 : last_image_(new SkBitmap()) {
75 // This class adds a tray icon in the status area of all browser windows
76 // in Chrome OS. This is the closest we can get to a system tray icon.
77 for (BrowserList::BrowserVector::const_iterator it = BrowserList::begin();
78 it != BrowserList::end(); ++it) {
79 AddIconToBrowser(*it);
80 }
81
82 // Listen to all browser open/close events to keep our map up to date.
83 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_WINDOW_READY,
84 content::NotificationService::AllSources());
85 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED,
86 content::NotificationService::AllSources());
87 }
88
89 StatusIconChromeOS::~StatusIconChromeOS() {
90 for (TrayButtonMap::const_iterator it = tray_button_map_.begin();
91 it != tray_button_map_.end(); ++it) {
92 it->first->RemoveTrayButton(it->second);
93 }
94 }
95
96 void StatusIconChromeOS::Observe(int type,
97 const content::NotificationSource& source,
98 const content::NotificationDetails& details) {
99 switch (type) {
100 case chrome::NOTIFICATION_BROWSER_WINDOW_READY: {
101 Browser* browser = content::Source<Browser>(source).ptr();
102 AddIconToBrowser(browser);
103 break;
104 }
105
106 case chrome::NOTIFICATION_BROWSER_CLOSED: {
107 chromeos::BrowserView* browser_view =
108 chromeos::BrowserView::GetBrowserViewForBrowser(
109 content::Source<Browser>(source).ptr());
110 DCHECK(browser_view);
111 tray_button_map_.erase(browser_view);
112 break;
113 }
114
115 default:
116 NOTREACHED();
117 }
118 }
119
120 void StatusIconChromeOS::AddIconToBrowser(Browser* browser) {
121 chromeos::BrowserView* browser_view =
122 chromeos::BrowserView::GetBrowserViewForBrowser(browser);
123 DCHECK(browser_view);
124
125 if (tray_button_map_.find(browser_view) != tray_button_map_.end()) {
126 NOTREACHED();
127 return;
128 }
129
130 NotificationTrayButton* tray_button =
131 new NotificationTrayButton(this, browser_view);
132 tray_button_map_[browser_view] = tray_button;
133 browser_view->AddTrayButton(tray_button, false);
134 if (!last_image_->empty())
135 tray_button->SetImage(*last_image_.get());
136 }
137
138 void StatusIconChromeOS::SetImage(const SkBitmap& image) {
139 if (image.isNull())
140 return;
141
142 for (TrayButtonMap::const_iterator it = tray_button_map_.begin();
143 it != tray_button_map_.end(); ++it) {
144 it->second->SetImage(image);
145 }
146 *last_image_.get() = image;
147 }
148
149 void StatusIconChromeOS::SetPressedImage(const SkBitmap& image) {
150 // Not supported. Chrome OS shows the context menu on left clicks.
151 }
152
153 void StatusIconChromeOS::SetToolTip(const string16& tool_tip) {
154 for (TrayButtonMap::const_iterator it = tray_button_map_.begin();
155 it != tray_button_map_.end(); ++it) {
156 it->second->SetTooltipText(tool_tip);
157 }
158 }
159
160 void StatusIconChromeOS::DisplayBalloon(const SkBitmap& icon,
161 const string16& title,
162 const string16& contents) {
163 notification_.DisplayBalloon(icon, title, contents);
164 }
165
166 void StatusIconChromeOS::Clicked() {
167 // Chrome OS shows the context menu on left button clicks, and this event
168 // should only be dispatched when the click doesn't show the context menu.
169 if (!menu_runner_.get())
170 DispatchClickEvent();
171 }
172
173 void StatusIconChromeOS::TestSendClick() {
174 Browser* browser = BrowserList::GetLastActive();
175 if (!browser)
176 return;
177
178 chromeos::BrowserView* browser_view =
179 chromeos::BrowserView::GetBrowserViewForBrowser(browser);
180 DCHECK(browser_view);
181
182 if (tray_button_map_.find(browser_view) == tray_button_map_.end()) {
183 NOTREACHED();
184 return;
185 }
186
187 tray_button_map_[browser_view]->Activate();
188 }
189
190 bool StatusIconChromeOS::TestIsIconContainedInView() {
191 Browser* browser = BrowserList::GetLastActive();
192 if (!browser)
193 return false;
194
195 chromeos::BrowserView* browser_view =
196 chromeos::BrowserView::GetBrowserViewForBrowser(browser);
197 DCHECK(browser_view);
198
199 if (tray_button_map_.find(browser_view) == tray_button_map_.end()) {
200 NOTREACHED();
201 return false;
202 }
203
204 return browser_view->ContainsButton(tray_button_map_[browser_view]);
205 }
206
207 void StatusIconChromeOS::UpdatePlatformContextMenu(ui::MenuModel* menu) {
208 // If no items are passed, blow away our context menu.
209 if (!menu) {
210 context_menu_adapter_.reset();
211 menu_runner_.reset();
212 return;
213 }
214
215 // Create context menu with the new contents.
216 views::MenuModelAdapter* adapter = new views::MenuModelAdapter(menu);
217 context_menu_adapter_.reset(adapter);
218 views::MenuItemView* menu_view = new views::MenuItemView(adapter);
219 adapter->BuildMenu(menu_view);
220
221 // menu_runner_ takes ownership of menu.
222 menu_runner_.reset(new views::MenuRunner(menu_view));
223 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698