| 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 |