OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ash/system/web_notification/web_notification_tray.h" | 5 #include "ash/system/web_notification/web_notification_tray.h" |
6 | 6 |
7 #include "ash/system/status_area_widget.h" | 7 #include "ash/system/status_area_widget.h" |
8 #include "ash/system/tray/tray_bubble_view.h" | 8 #include "ash/system/tray/tray_bubble_view.h" |
9 #include "ash/system/tray/tray_constants.h" | 9 #include "ash/system/tray/tray_constants.h" |
10 #include "ash/system/tray/tray_views.h" | 10 #include "ash/system/tray/tray_views.h" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
14 #include "base/timer.h" | 14 #include "base/timer.h" |
15 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
16 #include "grit/ash_strings.h" | 16 #include "grit/ash_strings.h" |
17 #include "grit/ui_resources.h" | 17 #include "grit/ui_resources.h" |
18 #include "ui/aura/window.h" | 18 #include "ui/aura/window.h" |
19 #include "ui/base/l10n/l10n_util.h" | 19 #include "ui/base/l10n/l10n_util.h" |
20 #include "ui/base/models/simple_menu_model.h" | 20 #include "ui/base/models/simple_menu_model.h" |
21 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
22 #include "ui/compositor/layer_animation_observer.h" | 22 #include "ui/compositor/layer_animation_observer.h" |
23 #include "ui/compositor/scoped_layer_animation_settings.h" | 23 #include "ui/compositor/scoped_layer_animation_settings.h" |
24 #include "ui/gfx/image/image_skia_operations.h" | 24 #include "ui/gfx/image/image_skia_operations.h" |
25 #include "ui/gfx/screen.h" | 25 #include "ui/gfx/screen.h" |
26 #include "ui/views/controls/button/button.h" | 26 #include "ui/views/controls/button/button.h" |
| 27 #include "ui/views/controls/button/image_button.h" |
27 #include "ui/views/controls/button/menu_button.h" | 28 #include "ui/views/controls/button/menu_button.h" |
28 #include "ui/views/controls/button/menu_button_listener.h" | 29 #include "ui/views/controls/button/menu_button_listener.h" |
29 #include "ui/views/controls/label.h" | 30 #include "ui/views/controls/label.h" |
30 #include "ui/views/controls/menu/menu_model_adapter.h" | 31 #include "ui/views/controls/menu/menu_model_adapter.h" |
31 #include "ui/views/controls/menu/menu_runner.h" | 32 #include "ui/views/controls/menu/menu_runner.h" |
32 #include "ui/views/layout/box_layout.h" | 33 #include "ui/views/layout/box_layout.h" |
33 #include "ui/views/layout/fill_layout.h" | |
34 #include "ui/views/layout/grid_layout.h" | 34 #include "ui/views/layout/grid_layout.h" |
35 #include "ui/views/painter.h" | 35 #include "ui/views/painter.h" |
36 #include "ui/views/widget/widget_observer.h" | 36 #include "ui/views/widget/widget_observer.h" |
37 | 37 |
38 namespace { | 38 namespace { |
39 | 39 |
40 // Tray constants | 40 // Tray constants |
41 const int kTrayContainerVeritcalPaddingBottomAlignment = 3; | 41 const int kTrayContainerVeritcalPaddingBottomAlignment = 3; |
42 const int kTrayContainerHorizontalPaddingBottomAlignment = 1; | 42 const int kTrayContainerHorizontalPaddingBottomAlignment = 1; |
43 const int kTrayContainerVerticalPaddingVerticalAlignment = 1; | 43 const int kTrayContainerVerticalPaddingVerticalAlignment = 1; |
44 const int kTrayContainerHorizontalPaddingVerticalAlignment = 0; | 44 const int kTrayContainerHorizontalPaddingVerticalAlignment = 0; |
45 const int kPaddingFromLeftEdgeOfSystemTrayBottomAlignment = 8; | 45 const int kPaddingFromLeftEdgeOfSystemTrayBottomAlignment = 8; |
46 const int kPaddingFromTopEdgeOfSystemTrayVerticalAlignment = 10; | 46 const int kPaddingFromTopEdgeOfSystemTrayVerticalAlignment = 10; |
47 const int kTrayWidth = 40; | |
48 const int kTrayHeight = 31; | |
49 const int kTraySideWidth = 32; | |
50 const int kTraySideHeight = 24; | |
51 | 47 |
52 // Web Notification Bubble constants | 48 // Web Notification Bubble constants |
53 const int kWebNotificationBubbleMinHeight = 80; | 49 const int kWebNotificationBubbleMinHeight = 80; |
54 const int kWebNotificationBubbleMaxHeight = 400; | 50 const int kWebNotificationBubbleMaxHeight = 400; |
55 // Delay laying out the Bubble until all notifications have been added and icons | 51 // Delay laying out the Bubble until all notifications have been added and icons |
56 // have had a chance to load. | 52 // have had a chance to load. |
57 const int kUpdateDelayMs = 50; | 53 const int kUpdateDelayMs = 50; |
58 const int kAutocloseDelaySeconds = 5; | 54 const int kAutocloseDelaySeconds = 5; |
59 const SkColor kMessageCountColor = SkColorSetARGB(0xff, 0xff, 0xff, 0xff); | 55 const SkColor kMessageCountColor = SkColorSetARGB(0xff, 0xff, 0xff, 0xff); |
60 const SkColor kNotificationColor = SkColorSetRGB(0xfe, 0xfe, 0xfe); | 56 const SkColor kNotificationColor = SkColorSetRGB(0xfe, 0xfe, 0xfe); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 | 109 |
114 WebNotificationList() | 110 WebNotificationList() |
115 : message_center_visible_(false), | 111 : message_center_visible_(false), |
116 unread_count_(0) { | 112 unread_count_(0) { |
117 } | 113 } |
118 | 114 |
119 void SetMessageCenterVisible(bool visible) { | 115 void SetMessageCenterVisible(bool visible) { |
120 if (message_center_visible_ == visible) | 116 if (message_center_visible_ == visible) |
121 return; | 117 return; |
122 message_center_visible_ = visible; | 118 message_center_visible_ = visible; |
123 if (visible) { | 119 if (!visible) { |
124 // Clear the unread count when the list is shown. | 120 // When the list lis hidden, clear the unread count, and mark all |
| 121 // notifications as read and shown. |
125 unread_count_ = 0; | 122 unread_count_ = 0; |
126 } else { | |
127 // Mark all notifications as read and shown when the list is hidden. | |
128 for (Notifications::iterator iter = notifications_.begin(); | 123 for (Notifications::iterator iter = notifications_.begin(); |
129 iter != notifications_.end(); ++iter) { | 124 iter != notifications_.end(); ++iter) { |
130 iter->is_read = true; | 125 iter->is_read = true; |
131 iter->shown_as_popup = true; | 126 iter->shown_as_popup = true; |
132 } | 127 } |
133 } | 128 } |
134 } | 129 } |
135 | 130 |
136 void AddNotification(const std::string& id, | 131 void AddNotification(const std::string& id, |
137 const string16& title, | 132 const string16& title, |
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 internal::PopupBubbleContentsView* contents_view_; | 1074 internal::PopupBubbleContentsView* contents_view_; |
1080 size_t num_popups_; | 1075 size_t num_popups_; |
1081 | 1076 |
1082 DISALLOW_COPY_AND_ASSIGN(PopupBubble); | 1077 DISALLOW_COPY_AND_ASSIGN(PopupBubble); |
1083 }; | 1078 }; |
1084 | 1079 |
1085 // WebNotificationTray --------------------------------------------------------- | 1080 // WebNotificationTray --------------------------------------------------------- |
1086 | 1081 |
1087 WebNotificationTray::WebNotificationTray( | 1082 WebNotificationTray::WebNotificationTray( |
1088 internal::StatusAreaWidget* status_area_widget) | 1083 internal::StatusAreaWidget* status_area_widget) |
1089 : internal::TrayBackgroundView(status_area_widget), | 1084 : internal::TrayBackgroundView(status_area_widget, false), |
1090 notification_list_(new WebNotificationList()), | 1085 notification_list_(new WebNotificationList()), |
1091 count_label_(NULL), | 1086 button_(NULL), |
1092 delegate_(NULL), | 1087 delegate_(NULL), |
1093 show_message_center_on_unlock_(false) { | 1088 show_message_center_on_unlock_(false) { |
1094 count_label_ = new views::Label(UTF8ToUTF16("0")); | 1089 button_ = new views::ImageButton(this); |
1095 internal::SetupLabelForTray(count_label_); | |
1096 gfx::Font font = count_label_->font(); | |
1097 count_label_->SetFont(font.DeriveFont(0, font.GetStyle() & ~gfx::Font::BOLD)); | |
1098 count_label_->SetHorizontalAlignment(views::Label::ALIGN_CENTER); | |
1099 count_label_->SetEnabledColor(kMessageCountColor); | |
1100 | 1090 |
1101 tray_container()->set_size(gfx::Size(kTrayWidth, kTrayHeight)); | 1091 tray_container()->AddChildView(button_); |
1102 tray_container()->AddChildView(count_label_); | |
1103 | 1092 |
1104 UpdateTray(); | 1093 UpdateTray(); |
1105 } | 1094 } |
1106 | 1095 |
1107 WebNotificationTray::~WebNotificationTray() { | 1096 WebNotificationTray::~WebNotificationTray() { |
1108 // Release any child views that might have back pointers before ~View(). | 1097 // Release any child views that might have back pointers before ~View(). |
1109 notification_list_.reset(); | 1098 notification_list_.reset(); |
1110 message_center_bubble_.reset(); | 1099 message_center_bubble_.reset(); |
1111 popup_bubble_.reset(); | 1100 popup_bubble_.reset(); |
1112 } | 1101 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 status_area_widget()->SetHideSystemNotifications(true); | 1159 status_area_widget()->SetHideSystemNotifications(true); |
1171 UpdateShouldShowLauncher(); | 1160 UpdateShouldShowLauncher(); |
1172 } | 1161 } |
1173 | 1162 |
1174 void WebNotificationTray::HideMessageCenterBubble() { | 1163 void WebNotificationTray::HideMessageCenterBubble() { |
1175 if (!message_center_bubble()) | 1164 if (!message_center_bubble()) |
1176 return; | 1165 return; |
1177 message_center_bubble_.reset(); | 1166 message_center_bubble_.reset(); |
1178 show_message_center_on_unlock_ = false; | 1167 show_message_center_on_unlock_ = false; |
1179 notification_list_->SetMessageCenterVisible(false); | 1168 notification_list_->SetMessageCenterVisible(false); |
| 1169 UpdateTray(); |
1180 status_area_widget()->SetHideSystemNotifications(false); | 1170 status_area_widget()->SetHideSystemNotifications(false); |
1181 UpdateShouldShowLauncher(); | 1171 UpdateShouldShowLauncher(); |
1182 } | 1172 } |
1183 | 1173 |
1184 void WebNotificationTray::SetHidePopupBubble(bool hide) { | 1174 void WebNotificationTray::SetHidePopupBubble(bool hide) { |
1185 if (hide) | 1175 if (hide) |
1186 HidePopupBubble(); | 1176 HidePopupBubble(); |
1187 else | 1177 else |
1188 ShowPopupBubble(); | 1178 ShowPopupBubble(); |
1189 } | 1179 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 if (!popup_bubble()) | 1221 if (!popup_bubble()) |
1232 return false; | 1222 return false; |
1233 return popup_bubble_->bubble_view()->GetBoundsInScreen().Contains( | 1223 return popup_bubble_->bubble_view()->GetBoundsInScreen().Contains( |
1234 gfx::Screen::GetCursorScreenPoint()); | 1224 gfx::Screen::GetCursorScreenPoint()); |
1235 } | 1225 } |
1236 | 1226 |
1237 void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) { | 1227 void WebNotificationTray::SetShelfAlignment(ShelfAlignment alignment) { |
1238 if (alignment == shelf_alignment()) | 1228 if (alignment == shelf_alignment()) |
1239 return; | 1229 return; |
1240 internal::TrayBackgroundView::SetShelfAlignment(alignment); | 1230 internal::TrayBackgroundView::SetShelfAlignment(alignment); |
1241 if (alignment == SHELF_ALIGNMENT_BOTTOM) | |
1242 tray_container()->set_size(gfx::Size(kTrayWidth, kTrayHeight)); | |
1243 else | |
1244 tray_container()->set_size(gfx::Size(kTraySideWidth, kTraySideHeight)); | |
1245 // Destroy any existing bubble so that it will be rebuilt correctly. | 1231 // Destroy any existing bubble so that it will be rebuilt correctly. |
1246 HideMessageCenterBubble(); | 1232 HideMessageCenterBubble(); |
1247 HidePopupBubble(); | 1233 HidePopupBubble(); |
1248 } | 1234 } |
1249 | 1235 |
1250 void WebNotificationTray::AnchorUpdated() { | 1236 void WebNotificationTray::AnchorUpdated() { |
1251 if (popup_bubble_.get()) { | 1237 if (popup_bubble_.get()) { |
1252 popup_bubble_->bubble_view()->UpdateBubble(); | 1238 popup_bubble_->bubble_view()->UpdateBubble(); |
1253 // Ensure that the notification buble is above the launcher/status area. | 1239 // Ensure that the notification buble is above the launcher/status area. |
1254 popup_bubble_->bubble_view()->GetWidget()->StackAtTop(); | 1240 popup_bubble_->bubble_view()->GetWidget()->StackAtTop(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 } | 1286 } |
1301 | 1287 |
1302 void WebNotificationTray::DisableByUrl(const std::string& id) { | 1288 void WebNotificationTray::DisableByUrl(const std::string& id) { |
1303 if (delegate_) | 1289 if (delegate_) |
1304 delegate_->DisableNotificationsFromSource(id); | 1290 delegate_->DisableNotificationsFromSource(id); |
1305 // Will call SendRemoveNotification for each matching notification. | 1291 // Will call SendRemoveNotification for each matching notification. |
1306 notification_list_->SendRemoveNotificationsBySource(this, id); | 1292 notification_list_->SendRemoveNotificationsBySource(this, id); |
1307 } | 1293 } |
1308 | 1294 |
1309 bool WebNotificationTray::PerformAction(const ui::Event& event) { | 1295 bool WebNotificationTray::PerformAction(const ui::Event& event) { |
1310 if (message_center_bubble()) | 1296 ToggleMessageCenterBubble(); |
1311 HideMessageCenterBubble(); | |
1312 else | |
1313 ShowMessageCenterBubble(); | |
1314 return true; | 1297 return true; |
1315 } | 1298 } |
1316 | 1299 |
| 1300 void WebNotificationTray::ButtonPressed(views::Button* sender, |
| 1301 const ui::Event& event) { |
| 1302 DCHECK(sender == button_); |
| 1303 ToggleMessageCenterBubble(); |
| 1304 } |
| 1305 |
1317 void WebNotificationTray::ShowSettings(const std::string& id) { | 1306 void WebNotificationTray::ShowSettings(const std::string& id) { |
1318 if (delegate_) | 1307 if (delegate_) |
1319 delegate_->ShowSettings(id); | 1308 delegate_->ShowSettings(id); |
1320 } | 1309 } |
1321 | 1310 |
1322 void WebNotificationTray::OnClicked(const std::string& id) { | 1311 void WebNotificationTray::OnClicked(const std::string& id) { |
1323 if (delegate_) | 1312 if (delegate_) |
1324 delegate_->OnClicked(id); | 1313 delegate_->OnClicked(id); |
1325 } | 1314 } |
1326 | 1315 |
1327 // Other private methods | 1316 // Other private methods |
1328 | 1317 |
| 1318 void WebNotificationTray::ToggleMessageCenterBubble() { |
| 1319 if (message_center_bubble()) |
| 1320 HideMessageCenterBubble(); |
| 1321 else |
| 1322 ShowMessageCenterBubble(); |
| 1323 UpdateTray(); |
| 1324 } |
| 1325 |
1329 void WebNotificationTray::UpdateTray() { | 1326 void WebNotificationTray::UpdateTray() { |
1330 count_label_->SetText(UTF8ToUTF16( | 1327 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
1331 GetNotificationText(notification_list()->unread_count()))); | 1328 if (notification_list()->unread_count() > 0) { |
| 1329 button_->SetImage(views::CustomButton::BS_NORMAL, rb.GetImageSkiaNamed( |
| 1330 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_NORMAL)); |
| 1331 button_->SetImage(views::CustomButton::BS_HOT, rb.GetImageSkiaNamed( |
| 1332 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_HOVER)); |
| 1333 button_->SetImage(views::CustomButton::BS_PUSHED, rb.GetImageSkiaNamed( |
| 1334 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_ACTIVE_PRESSED)); |
| 1335 } else { |
| 1336 button_->SetImage(views::CustomButton::BS_NORMAL, rb.GetImageSkiaNamed( |
| 1337 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_NORMAL)); |
| 1338 button_->SetImage(views::CustomButton::BS_HOT, rb.GetImageSkiaNamed( |
| 1339 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_HOVER)); |
| 1340 button_->SetImage(views::CustomButton::BS_PUSHED, rb.GetImageSkiaNamed( |
| 1341 IDR_AURA_UBER_TRAY_NOTIFY_BUTTON_INACTIVE_PRESSED)); |
| 1342 } |
| 1343 if (message_center_bubble()) |
| 1344 button_->SetState(views::CustomButton::BS_PUSHED); |
| 1345 else |
| 1346 button_->SetState(views::CustomButton::BS_NORMAL); |
1332 bool is_visible = | 1347 bool is_visible = |
1333 (status_area_widget()->login_status() != user::LOGGED_IN_NONE) && | 1348 (status_area_widget()->login_status() != user::LOGGED_IN_NONE) && |
1334 (status_area_widget()->login_status() != user::LOGGED_IN_LOCKED) && | 1349 (status_area_widget()->login_status() != user::LOGGED_IN_LOCKED) && |
1335 (!notification_list()->notifications().empty()); | 1350 (!notification_list()->notifications().empty()); |
1336 SetVisible(is_visible); | 1351 SetVisible(is_visible); |
1337 Layout(); | 1352 Layout(); |
1338 SchedulePaint(); | 1353 SchedulePaint(); |
1339 } | 1354 } |
1340 | 1355 |
1341 void WebNotificationTray::UpdateTrayAndBubble() { | 1356 void WebNotificationTray::UpdateTrayAndBubble() { |
1342 UpdateTray(); | |
1343 | |
1344 if (message_center_bubble()) | 1357 if (message_center_bubble()) |
1345 message_center_bubble()->ScheduleUpdate(); | 1358 message_center_bubble()->ScheduleUpdate(); |
1346 | 1359 |
1347 if (popup_bubble()) { | 1360 if (popup_bubble()) { |
1348 if (notification_list_->notifications().size() == 0) | 1361 if (notification_list_->notifications().size() == 0) |
1349 HidePopupBubble(); | 1362 HidePopupBubble(); |
1350 else | 1363 else |
1351 popup_bubble()->ScheduleUpdate(); | 1364 popup_bubble()->ScheduleUpdate(); |
1352 } | 1365 } |
| 1366 UpdateTray(); |
1353 } | 1367 } |
1354 | 1368 |
1355 void WebNotificationTray::HideBubble(Bubble* bubble) { | 1369 void WebNotificationTray::HideBubble(Bubble* bubble) { |
1356 if (bubble == message_center_bubble()) { | 1370 if (bubble == message_center_bubble()) { |
1357 HideMessageCenterBubble(); | 1371 HideMessageCenterBubble(); |
1358 } else if (bubble == popup_bubble()) { | 1372 } else if (bubble == popup_bubble()) { |
1359 HidePopupBubble(); | 1373 HidePopupBubble(); |
1360 } | 1374 } |
1361 } | 1375 } |
1362 | 1376 |
(...skipping 17 matching lines...) Expand all Loading... |
1380 return message_center_bubble()->MessageViewsForTest(); | 1394 return message_center_bubble()->MessageViewsForTest(); |
1381 } | 1395 } |
1382 | 1396 |
1383 size_t WebNotificationTray::GetPopupNotificationCountForTest() const { | 1397 size_t WebNotificationTray::GetPopupNotificationCountForTest() const { |
1384 if (!popup_bubble()) | 1398 if (!popup_bubble()) |
1385 return 0; | 1399 return 0; |
1386 return popup_bubble()->MessageViewsForTest(); | 1400 return popup_bubble()->MessageViewsForTest(); |
1387 } | 1401 } |
1388 | 1402 |
1389 } // namespace ash | 1403 } // namespace ash |
OLD | NEW |