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

Side by Side Diff: chrome/browser/ui/views/message_center/web_notification_tray.cc

Issue 18003003: Message center re-organized (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Compile issues fixed Created 7 years, 5 months 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/message_center/web_notification_tray.h" 5 #include "chrome/browser/ui/views/message_center/web_notification_tray.h"
6 6
7 #include "base/i18n/number_formatting.h" 7 #include "base/i18n/number_formatting.h"
8 #include "base/strings/string16.h" 8 #include "base/strings/string16.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/status_icons/status_icon.h" 11 #include "chrome/browser/status_icons/status_icon.h"
12 #include "chrome/browser/status_icons/status_tray.h" 12 #include "chrome/browser/status_icons/status_tray.h"
13 #include "chrome/browser/ui/views/message_center/notification_bubble_wrapper.h"
14 #include "content/public/browser/user_metrics.h" 13 #include "content/public/browser/user_metrics.h"
15 #include "grit/chromium_strings.h" 14 #include "grit/chromium_strings.h"
16 #include "grit/theme_resources.h" 15 #include "grit/theme_resources.h"
17 #include "grit/ui_strings.h" 16 #include "grit/ui_strings.h"
18 #include "ui/base/l10n/l10n_util.h" 17 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/base/models/simple_menu_model.h"
20 #include "ui/base/resource/resource_bundle.h" 18 #include "ui/base/resource/resource_bundle.h"
21 #include "ui/gfx/canvas.h" 19 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/image/image_skia_operations.h" 20 #include "ui/gfx/image/image_skia_operations.h"
23 #include "ui/gfx/rect.h" 21 #include "ui/gfx/rect.h"
24 #include "ui/gfx/screen.h" 22 #include "ui/gfx/screen.h"
25 #include "ui/gfx/size.h" 23 #include "ui/gfx/size.h"
26 #include "ui/message_center/message_center_tray.h" 24 #include "ui/message_center/message_center_tray.h"
27 #include "ui/message_center/message_center_tray_delegate.h" 25 #include "ui/message_center/message_center_tray_delegate.h"
28 #include "ui/message_center/views/message_bubble_base.h"
29 #include "ui/message_center/views/message_center_bubble.h"
30 #include "ui/message_center/views/message_popup_collection.h" 26 #include "ui/message_center/views/message_popup_collection.h"
31 #include "ui/views/widget/widget.h" 27 #include "ui/views/widget/widget.h"
32 28
33 namespace { 29 namespace {
34 30
35 // Tray constants 31 // Tray constants
36 const int kScreenEdgePadding = 2; 32 const int kScreenEdgePadding = 2;
37 33
38 const int kSystemTrayWidth = 16; 34 const int kSystemTrayWidth = 16;
39 const int kSystemTrayHeight = 16; 35 const int kSystemTrayHeight = 16;
40 const int kNumberOfSystemTraySprites = 10; 36 const int kNumberOfSystemTraySprites = 10;
41 37
42 gfx::Rect GetCornerAnchorRect() {
43 // TODO(dewittj): Use the preference to determine which corner to anchor from.
44 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
45 gfx::Rect rect = screen->GetPrimaryDisplay().work_area();
46 rect.Inset(kScreenEdgePadding, kScreenEdgePadding);
47 return gfx::Rect(rect.bottom_right(), gfx::Size());
48 }
49
50 gfx::Point GetClosestCorner(gfx::Rect rect, gfx::Point query) {
51 gfx::Point center_point = rect.CenterPoint();
52 gfx::Point rv;
53
54 if (query.x() > center_point.x())
55 rv.set_x(rect.right());
56 else
57 rv.set_x(rect.x());
58
59 if (query.y() > center_point.y())
60 rv.set_y(rect.bottom());
61 else
62 rv.set_y(rect.y());
63
64 return rv;
65 }
66
67 // GetMouseAnchorRect returns a rectangle that has one corner where the mouse
68 // clicked, and the opposite corner at the closest corner of the work area
69 // (inset by an appropriate margin.)
70 gfx::Rect GetMouseAnchorRect(gfx::Point cursor) {
71 // TODO(dewittj): GetNativeScreen could be wrong for Aura.
72 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
73 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
74 work_area.Inset(kScreenEdgePadding, kScreenEdgePadding);
75 gfx::Point corner = GetClosestCorner(work_area, cursor);
76
77 gfx::Rect mouse_anchor_rect(gfx::BoundingRect(cursor, corner));
78 return mouse_anchor_rect;
79 }
80
81 gfx::ImageSkia GetIcon(int unread_count) { 38 gfx::ImageSkia GetIcon(int unread_count) {
82 bool has_unread = unread_count > 0; 39 bool has_unread = unread_count > 0;
83 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 40 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
84 if (!has_unread) 41 if (!has_unread)
85 return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY); 42 return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY);
86 43
87 // TODO(dewittj): Use scale factors other than 100P. 44 // TODO(dewittj): Use scale factors other than 100P.
88 scoped_ptr<gfx::Canvas> canvas( 45 scoped_ptr<gfx::Canvas> canvas(
89 new gfx::Canvas(gfx::Size(kSystemTrayWidth, kSystemTrayHeight), 46 new gfx::Canvas(gfx::Size(kSystemTrayWidth, kSystemTrayHeight),
90 ui::SCALE_FACTOR_100P, 47 ui::SCALE_FACTOR_100P,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 popup_collection_.reset(new message_center::MessagePopupCollection( 101 popup_collection_.reset(new message_center::MessagePopupCollection(
145 NULL, message_center(), message_center_tray_.get())); 102 NULL, message_center(), message_center_tray_.get()));
146 return true; 103 return true;
147 } 104 }
148 105
149 void WebNotificationTray::HidePopups() { popup_collection_.reset(); } 106 void WebNotificationTray::HidePopups() { popup_collection_.reset(); }
150 107
151 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { 108 bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) {
152 content::RecordAction(UserMetricsAction("Notifications.ShowMessageCenter")); 109 content::RecordAction(UserMetricsAction("Notifications.ShowMessageCenter"));
153 110
154 // Using MessageBubbleBase instead of MessageCenterBubble to 111 message_center_delegate_ = new MessageCenterWidgetDelegate(
155 // remove dependence on implicit type conversion 112 this, message_center_tray_.get(), show_settings /* settings initally
156 scoped_ptr<message_center::MessageCenterBubble> bubble( 113 invisible */);
157 new message_center::MessageCenterBubble(message_center(),
158 message_center_tray_.get()));
159 114
160 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
161 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
162 views::TrayBubbleView::AnchorAlignment alignment = GetAnchorAlignment();
163
164 int max_height = work_area.height();
165
166 // If the alignment is left- or right-oriented, the bubble can fill up the
167 // entire vertical height of the screen since the bubble is rendered to the
168 // side of the clicked icon. Otherwise we have to adjust for the arrow's
169 // height.
170 if (alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM ||
171 alignment == views::TrayBubbleView::ANCHOR_ALIGNMENT_TOP) {
172 max_height -= 2 * kScreenEdgePadding;
173
174 // If the work area contains the click point, then we know that the icon is
175 // not in the taskbar. Then we need to subtract the distance of the click
176 // point from the edge of the work area so we can see the whole bubble.
177 if (work_area.Contains(mouse_click_point_)) {
178 max_height -= std::min(mouse_click_point_.y() - work_area.y(),
179 work_area.bottom() - mouse_click_point_.y());
180 }
181 }
182 bubble->SetMaxHeight(max_height);
183 if (show_settings)
184 bubble->SetSettingsVisible();
185
186 message_center_bubble_.reset(new internal::NotificationBubbleWrapper(
187 this,
188 bubble.PassAs<message_center::MessageBubbleBase>(),
189 internal::NotificationBubbleWrapper::BUBBLE_TYPE_MESSAGE_CENTER));
190 return true; 115 return true;
191 } 116 }
192 117
193 bool WebNotificationTray::ShowMessageCenter() { 118 bool WebNotificationTray::ShowMessageCenter() {
194 return ShowMessageCenterInternal(false /* show_settings */); 119 return ShowMessageCenterInternal(false /* show_settings */);
195 } 120 }
196 121
197 void WebNotificationTray::HideMessageCenter() { 122 void WebNotificationTray::HideMessageCenter() {
198 message_center_bubble_.reset(); 123 if (message_center_delegate_) {
124 message_center_delegate_->CloseWidget();
125 }
199 } 126 }
200 127
201 void WebNotificationTray::UpdatePopups() { 128 void WebNotificationTray::UpdatePopups() {
202 // |popup_collection_| receives notification add/remove events and updates 129 // |popup_collection_| receives notification add/remove events and updates
203 // itself, so this method doesn't need to do anything. 130 // itself, so this method doesn't need to do anything.
204 // TODO(mukai): remove this method (currently this is used by 131 // TODO(mukai): remove this method (currently this is used by
205 // non-rich-notifications in ChromeOS). 132 // non-rich-notifications in ChromeOS).
206 }; 133 };
207 134
208 bool WebNotificationTray::ShowNotifierSettings() { 135 bool WebNotificationTray::ShowNotifierSettings() {
209 if (message_center_bubble_) { 136 if (message_center_delegate_) {
210 static_cast<MessageCenterBubble*>( 137 message_center_delegate_->SetSettingsVisible(true);
211 message_center_bubble_->bubble())->SetSettingsVisible();
212 return true; 138 return true;
213 } 139 }
214 return ShowMessageCenterInternal(true /* show_settings */); 140 return ShowMessageCenterInternal(true /* show_settings */);
215 } 141 }
216 142
217 void WebNotificationTray::OnMessageCenterTrayChanged() { 143 void WebNotificationTray::OnMessageCenterTrayChanged() {
218 // See the comments in ash/system/web_notification/web_notification_tray.cc 144 // See the comments in ash/system/web_notification/web_notification_tray.cc
219 // for why PostTask. 145 // for why PostTask.
220 should_update_tray_content_ = true; 146 should_update_tray_content_ = true;
221 base::MessageLoop::current()->PostTask( 147 base::MessageLoop::current()->PostTask(
222 FROM_HERE, 148 FROM_HERE,
223 base::Bind(&WebNotificationTray::UpdateStatusIcon, AsWeakPtr())); 149 base::Bind(&WebNotificationTray::UpdateStatusIcon, AsWeakPtr()));
224 } 150 }
225 151
226 gfx::Rect WebNotificationTray::GetMessageCenterAnchor() { 152 void WebNotificationTray::OnStatusIconClicked() {
227 return GetMouseAnchorRect(mouse_click_point_); 153 // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura.
154 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
155 mouse_click_point_ = screen->GetCursorScreenPoint();
156 message_center_tray_->ToggleMessageCenterBubble();
228 } 157 }
229 158
230 gfx::Rect WebNotificationTray::GetPopupAnchor() {
231 return GetCornerAnchorRect();
232 }
233
234 views::TrayBubbleView::AnchorAlignment
235 WebNotificationTray::GetAnchorAlignment() {
236 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
237 // TODO(dewittj): It's possible GetPrimaryDisplay is wrong.
238 gfx::Rect screen_bounds = screen->GetPrimaryDisplay().bounds();
239 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area();
240
241 // Comparing the work area to the screen bounds gives us the location of the
242 // taskbar. If the work area is less tall than the screen, assume the taskbar
243 // is on the bottom, and cause the arrow to be displayed on the bottom of the
244 // bubble. Otherwise, cause the arrow to be displayed on the side of the
245 // bubble that the taskbar is on.
246 if (work_area.width() < screen_bounds.width()) {
247 if (work_area.x() > screen_bounds.x())
248 return views::TrayBubbleView::ANCHOR_ALIGNMENT_LEFT;
249 return views::TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT;
250 }
251 return views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
252 }
253
254 gfx::NativeView WebNotificationTray::GetBubbleWindowContainer() { return NULL; }
255
256 void WebNotificationTray::UpdateStatusIcon() { 159 void WebNotificationTray::UpdateStatusIcon() {
257 if (!should_update_tray_content_) 160 if (!should_update_tray_content_)
258 return; 161 return;
259 should_update_tray_content_ = false; 162 should_update_tray_content_ = false;
260 163
261 int total_notifications = message_center()->NotificationCount(); 164 int total_notifications = message_center()->NotificationCount();
262 if (total_notifications == 0) { 165 if (total_notifications == 0) {
263 DestroyStatusIcon(); 166 DestroyStatusIcon();
264 return; 167 return;
265 } 168 }
266 169
267 int unread_notifications = message_center()->UnreadNotificationCount(); 170 int unread_notifications = message_center()->UnreadNotificationCount();
268 StatusIcon* status_icon = GetStatusIcon(); 171 StatusIcon* status_icon = GetStatusIcon();
269 if (!status_icon) 172 if (!status_icon)
270 return; 173 return;
271 174
272 status_icon->SetImage(GetIcon(unread_notifications)); 175 status_icon->SetImage(GetIcon(unread_notifications));
273 176
274 string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); 177 string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME));
275 if (unread_notifications > 0) { 178 if (unread_notifications > 0) {
276 string16 str_unread_count = base::FormatNumber(unread_notifications); 179 string16 str_unread_count = base::FormatNumber(unread_notifications);
277 status_icon->SetToolTip(l10n_util::GetStringFUTF16( 180 status_icon->SetToolTip(l10n_util::GetStringFUTF16(
278 IDS_MESSAGE_CENTER_TOOLTIP_UNREAD, product_name, str_unread_count)); 181 IDS_MESSAGE_CENTER_TOOLTIP_UNREAD, product_name, str_unread_count));
279 } else { 182 } else {
280 status_icon->SetToolTip( 183 status_icon->SetToolTip(
281 l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_TOOLTIP, product_name)); 184 l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_TOOLTIP, product_name));
282 } 185 }
283 } 186 }
284 187
285 void WebNotificationTray::OnStatusIconClicked() { 188 void WebNotificationTray::HideBubble() {
286 // TODO(dewittj): It's possible GetNativeScreen is wrong for win-aura. 189 if (message_center_delegate_) {
287 gfx::Screen* screen = gfx::Screen::GetNativeScreen();
288 mouse_click_point_ = screen->GetCursorScreenPoint();
289 message_center_tray_->ToggleMessageCenterBubble();
290 }
291
292 void WebNotificationTray::HideBubbleWithView(
293 const views::TrayBubbleView* bubble_view) {
294 if (message_center_bubble_.get() &&
295 bubble_view == message_center_bubble_->bubble_view()) {
296 message_center_tray_->HideMessageCenterBubble(); 190 message_center_tray_->HideMessageCenterBubble();
297 } 191 }
298 } 192 }
299 193
300 StatusIcon* WebNotificationTray::GetStatusIcon() { 194 StatusIcon* WebNotificationTray::GetStatusIcon() {
301 if (status_icon_) 195 if (status_icon_)
302 return status_icon_; 196 return status_icon_;
303 197
304 StatusTray* status_tray = g_browser_process->status_tray(); 198 StatusTray* status_tray = g_browser_process->status_tray();
305 if (!status_tray) 199 if (!status_tray)
(...skipping 19 matching lines...) Expand all
325 if (status_tray) 219 if (status_tray)
326 status_tray->RemoveStatusIcon(status_icon_); 220 status_tray->RemoveStatusIcon(status_icon_);
327 status_icon_ = NULL; 221 status_icon_ = NULL;
328 } 222 }
329 223
330 void WebNotificationTray::AddQuietModeMenu(StatusIcon* status_icon) { 224 void WebNotificationTray::AddQuietModeMenu(StatusIcon* status_icon) {
331 DCHECK(status_icon); 225 DCHECK(status_icon);
332 status_icon->SetContextMenu(message_center_tray_->CreateQuietModeMenu()); 226 status_icon->SetContextMenu(message_center_tray_->CreateQuietModeMenu());
333 } 227 }
334 228
335 message_center::MessageCenterBubble* 229 MessageCenterWidgetDelegate*
336 WebNotificationTray::GetMessageCenterBubbleForTest() { 230 WebNotificationTray::GetMessageCenterWidgetDelegateForTest() {
337 if (!message_center_bubble_.get()) 231 return message_center_delegate_;
338 return NULL;
339 return static_cast<message_center::MessageCenterBubble*>(
340 message_center_bubble_->bubble());
341 } 232 }
342 233
343 } // namespace message_center 234 } // namespace message_center
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698