OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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_win.h" | 5 #include "chrome/browser/ui/views/message_center/web_notification_tray_win.h" |
6 | 6 |
7 #include "base/i18n/number_formatting.h" | 7 #include "base/i18n/number_formatting.h" |
8 #include "base/string16.h" | 8 #include "base/string16.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/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_win
.h" | 13 #include "chrome/browser/ui/views/message_center/notification_bubble_wrapper_win
.h" |
14 #include "chrome/browser/ui/views/status_icons/status_icon_win.h" | 14 #include "chrome/browser/ui/views/status_icons/status_icon_win.h" |
15 #include "grit/chromium_strings.h" | 15 #include "grit/chromium_strings.h" |
16 #include "grit/theme_resources.h" | 16 #include "grit/theme_resources.h" |
17 #include "grit/ui_strings.h" | 17 #include "grit/ui_strings.h" |
18 #include "ui/base/l10n/l10n_util.h" | 18 #include "ui/base/l10n/l10n_util.h" |
19 #include "ui/base/models/simple_menu_model.h" | 19 #include "ui/base/models/simple_menu_model.h" |
20 #include "ui/base/resource/resource_bundle.h" | 20 #include "ui/base/resource/resource_bundle.h" |
21 #include "ui/base/win/hwnd_util.h" | 21 #include "ui/base/win/hwnd_util.h" |
| 22 #include "ui/gfx/canvas.h" |
22 #include "ui/gfx/image/image_skia_operations.h" | 23 #include "ui/gfx/image/image_skia_operations.h" |
| 24 #include "ui/gfx/rect.h" |
23 #include "ui/gfx/screen.h" | 25 #include "ui/gfx/screen.h" |
| 26 #include "ui/gfx/size.h" |
24 #include "ui/message_center/message_center_tray.h" | 27 #include "ui/message_center/message_center_tray.h" |
25 #include "ui/message_center/message_center_tray_delegate.h" | 28 #include "ui/message_center/message_center_tray_delegate.h" |
26 #include "ui/message_center/views/message_bubble_base.h" | 29 #include "ui/message_center/views/message_bubble_base.h" |
27 #include "ui/message_center/views/message_center_bubble.h" | 30 #include "ui/message_center/views/message_center_bubble.h" |
28 #include "ui/message_center/views/message_popup_collection.h" | 31 #include "ui/message_center/views/message_popup_collection.h" |
29 #include "ui/views/widget/widget.h" | 32 #include "ui/views/widget/widget.h" |
30 | 33 |
31 namespace { | 34 namespace { |
32 | 35 |
33 // Tray constants | 36 // Tray constants |
34 const int kScreenEdgePadding = 2; | 37 const int kScreenEdgePadding = 2; |
35 | 38 |
| 39 const int kSystemTrayWidth = 16; |
| 40 const int kSystemTrayHeight = 16; |
| 41 const int kNumberOfSystemTraySprites = 10; |
| 42 |
36 gfx::Rect GetCornerAnchorRect() { | 43 gfx::Rect GetCornerAnchorRect() { |
37 // TODO(dewittj): Use the preference to determine which corner to anchor from. | 44 // TODO(dewittj): Use the preference to determine which corner to anchor from. |
38 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | 45 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); |
39 gfx::Rect rect = screen->GetPrimaryDisplay().work_area(); | 46 gfx::Rect rect = screen->GetPrimaryDisplay().work_area(); |
40 rect.Inset(kScreenEdgePadding, kScreenEdgePadding); | 47 rect.Inset(kScreenEdgePadding, kScreenEdgePadding); |
41 return gfx::Rect(rect.bottom_right(), gfx::Size()); | 48 return gfx::Rect(rect.bottom_right(), gfx::Size()); |
42 } | 49 } |
43 | 50 |
44 gfx::Point GetClosestCorner(gfx::Rect rect, gfx::Point query) { | 51 gfx::Point GetClosestCorner(gfx::Rect rect, gfx::Point query) { |
45 gfx::Point center_point = rect.CenterPoint(); | 52 gfx::Point center_point = rect.CenterPoint(); |
(...skipping 19 matching lines...) Expand all Loading... |
65 // TODO(dewittj): GetNativeScreen could be wrong for Aura. | 72 // TODO(dewittj): GetNativeScreen could be wrong for Aura. |
66 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | 73 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); |
67 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); | 74 gfx::Rect work_area = screen->GetPrimaryDisplay().work_area(); |
68 work_area.Inset(kScreenEdgePadding, kScreenEdgePadding); | 75 work_area.Inset(kScreenEdgePadding, kScreenEdgePadding); |
69 gfx::Point corner = GetClosestCorner(work_area, cursor); | 76 gfx::Point corner = GetClosestCorner(work_area, cursor); |
70 | 77 |
71 gfx::Rect mouse_anchor_rect(gfx::BoundingRect(cursor, corner)); | 78 gfx::Rect mouse_anchor_rect(gfx::BoundingRect(cursor, corner)); |
72 return mouse_anchor_rect; | 79 return mouse_anchor_rect; |
73 } | 80 } |
74 | 81 |
75 gfx::ImageSkia GetIcon(bool has_unread) { | 82 gfx::ImageSkia GetIcon(int unread_count) { |
| 83 bool has_unread = unread_count > 0; |
76 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 84 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
77 gfx::ImageSkia* icon = rb.GetImageSkiaNamed( | 85 if (!has_unread) |
78 has_unread ? IDR_NOTIFICATION_TRAY_LIT : IDR_NOTIFICATION_TRAY_DIM); | 86 return *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_EMPTY); |
79 DCHECK(icon); | 87 |
80 return *icon; | 88 // TODO(dewittj): Use scale factors other than 100P. |
| 89 scoped_ptr<gfx::Canvas> canvas(new gfx::Canvas( |
| 90 gfx::Size(kSystemTrayWidth, kSystemTrayHeight), |
| 91 ui::SCALE_FACTOR_100P, |
| 92 false)); |
| 93 |
| 94 // Draw the attention-grabbing background image. |
| 95 canvas->DrawImageInt( |
| 96 *rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_ATTENTION), 0, 0); |
| 97 |
| 98 // |numbers| is a sprite map with the image of a number from 1-9 and 9+. They |
| 99 // are arranged horizontally, and have a transparent background. |
| 100 gfx::ImageSkia* numbers = rb.GetImageSkiaNamed(IDR_NOTIFICATION_TRAY_NUMBERS); |
| 101 |
| 102 // Assume that the last sprite is the catch-all for higher numbers of |
| 103 // notifications. |
| 104 int effective_unread = std::min(unread_count, kNumberOfSystemTraySprites); |
| 105 int x_offset = (effective_unread - 1) * kSystemTrayWidth; |
| 106 |
| 107 canvas->DrawImageInt(*numbers, |
| 108 x_offset, 0, kSystemTrayWidth, kSystemTrayHeight, |
| 109 0, 0, kSystemTrayWidth, kSystemTrayHeight, |
| 110 false); |
| 111 |
| 112 return gfx::ImageSkia(canvas->ExtractImageRep()); |
81 } | 113 } |
82 | 114 |
83 } // namespace | 115 } // namespace |
84 | 116 |
85 namespace message_center { | 117 namespace message_center { |
86 | 118 |
87 MessageCenterTrayDelegate* CreateMessageCenterTray() { | 119 MessageCenterTrayDelegate* CreateMessageCenterTray() { |
88 return new WebNotificationTrayWin(); | 120 return new WebNotificationTrayWin(); |
89 } | 121 } |
90 | 122 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 } | 238 } |
207 return views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM; | 239 return views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM; |
208 } | 240 } |
209 | 241 |
210 gfx::NativeView WebNotificationTrayWin::GetBubbleWindowContainer() { | 242 gfx::NativeView WebNotificationTrayWin::GetBubbleWindowContainer() { |
211 return NULL; | 243 return NULL; |
212 } | 244 } |
213 | 245 |
214 void WebNotificationTrayWin::UpdateStatusIcon() { | 246 void WebNotificationTrayWin::UpdateStatusIcon() { |
215 int unread_notifications = message_center()->UnreadNotificationCount(); | 247 int unread_notifications = message_center()->UnreadNotificationCount(); |
216 status_icon_->SetImage(GetIcon(unread_notifications > 0)); | 248 status_icon_->SetImage(GetIcon(unread_notifications)); |
217 | 249 |
218 string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); | 250 string16 product_name(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); |
219 if (unread_notifications > 0) { | 251 if (unread_notifications > 0) { |
220 string16 str_unread_count = base::FormatNumber(unread_notifications); | 252 string16 str_unread_count = base::FormatNumber(unread_notifications); |
221 status_icon_->SetToolTip(l10n_util::GetStringFUTF16( | 253 status_icon_->SetToolTip(l10n_util::GetStringFUTF16( |
222 IDS_MESSAGE_CENTER_TOOLTIP_UNREAD, product_name, str_unread_count)); | 254 IDS_MESSAGE_CENTER_TOOLTIP_UNREAD, product_name, str_unread_count)); |
223 } else { | 255 } else { |
224 status_icon_->SetToolTip(l10n_util::GetStringFUTF16( | 256 status_icon_->SetToolTip(l10n_util::GetStringFUTF16( |
225 IDS_MESSAGE_CENTER_TOOLTIP, product_name)); | 257 IDS_MESSAGE_CENTER_TOOLTIP, product_name)); |
226 } | 258 } |
(...skipping 21 matching lines...) Expand all Loading... |
248 | 280 |
249 message_center::MessageCenterBubble* | 281 message_center::MessageCenterBubble* |
250 WebNotificationTrayWin::GetMessageCenterBubbleForTest() { | 282 WebNotificationTrayWin::GetMessageCenterBubbleForTest() { |
251 if (!message_center_bubble_.get()) | 283 if (!message_center_bubble_.get()) |
252 return NULL; | 284 return NULL; |
253 return static_cast<message_center::MessageCenterBubble*>( | 285 return static_cast<message_center::MessageCenterBubble*>( |
254 message_center_bubble_->bubble()); | 286 message_center_bubble_->bubble()); |
255 } | 287 } |
256 | 288 |
257 } // namespace message_center | 289 } // namespace message_center |
OLD | NEW |