notification_menu_controller.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Copyright 2018 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. #include "ash/app_menu/notification_menu_controller.h"
  5. #include "ash/app_menu/app_menu_model_adapter.h"
  6. #include "ash/app_menu/notification_menu_view.h"
  7. #include "ash/public/cpp/app_menu_constants.h"
  8. #include "ui/base/models/simple_menu_model.h"
  9. #include "ui/views/controls/menu/menu_item_view.h"
  10. #include "ui/views/controls/menu/submenu_view.h"
  11. namespace ash {
  12. NotificationMenuController::NotificationMenuController(
  13. const std::string& app_id,
  14. views::MenuItemView* root_menu,
  15. AppMenuModelAdapter* app_menu_model_adapter)
  16. : app_id_(app_id),
  17. root_menu_(root_menu),
  18. app_menu_model_adapter_(app_menu_model_adapter) {
  19. DCHECK(app_menu_model_adapter_);
  20. message_center_observation_.Observe(message_center::MessageCenter::Get());
  21. InitializeNotificationMenuView();
  22. }
  23. NotificationMenuController::~NotificationMenuController() = default;
  24. void NotificationMenuController::OnNotificationAdded(
  25. const std::string& notification_id) {
  26. message_center::Notification* notification =
  27. message_center::MessageCenter::Get()->FindVisibleNotificationById(
  28. notification_id);
  29. DCHECK(notification);
  30. if (notification->notifier_id().id != app_id_)
  31. return;
  32. if (!notification_menu_view_) {
  33. InitializeNotificationMenuView();
  34. return;
  35. }
  36. notification_menu_view_->AddNotificationItemView(*notification);
  37. }
  38. void NotificationMenuController::OnNotificationUpdated(
  39. const std::string& notification_id) {
  40. if (!notification_menu_view_)
  41. return;
  42. message_center::Notification* notification =
  43. message_center::MessageCenter::Get()->FindVisibleNotificationById(
  44. notification_id);
  45. DCHECK(notification);
  46. if (notification->notifier_id().id != app_id_)
  47. return;
  48. notification_menu_view_->UpdateNotificationItemView(*notification);
  49. }
  50. void NotificationMenuController::OnNotificationRemoved(
  51. const std::string& notification_id,
  52. bool by_user) {
  53. if (!notification_menu_view_)
  54. return;
  55. // Remove the view from the container.
  56. notification_menu_view_->OnNotificationRemoved(notification_id);
  57. if (!notification_menu_view_->IsEmpty())
  58. return;
  59. // There are no more notifications to show, so remove |item_| from
  60. // |root_menu_|, and remove the entry from the model.
  61. root_menu_->RemoveMenuItem(notification_menu_view_->parent());
  62. app_menu_model_adapter_->model()->RemoveItemAt(
  63. app_menu_model_adapter_->model()
  64. ->GetIndexOfCommandId(NOTIFICATION_CONTAINER)
  65. .value());
  66. notification_menu_view_ = nullptr;
  67. // Notify the root MenuItemView so it knows to resize and re-calculate the
  68. // menu bounds.
  69. root_menu_->ChildrenChanged();
  70. }
  71. ui::Layer* NotificationMenuController::GetSlideOutLayer() {
  72. return notification_menu_view_ ? notification_menu_view_->GetSlideOutLayer()
  73. : nullptr;
  74. }
  75. void NotificationMenuController::OnSlideChanged(bool in_progress) {}
  76. void NotificationMenuController::OnSlideOut() {
  77. // Results in |this| being deleted if there are no more notifications to show.
  78. // Only the displayed NotificationItemView can call OnSlideOut.
  79. message_center::MessageCenter::Get()->RemoveNotification(
  80. notification_menu_view_->GetDisplayedNotificationID(), true);
  81. }
  82. void NotificationMenuController::ActivateNotificationAndClose(
  83. const std::string& notification_id) {
  84. message_center::MessageCenter::Get()->ClickOnNotification(notification_id);
  85. // Results in |this| being deleted.
  86. app_menu_model_adapter_->Cancel();
  87. }
  88. void NotificationMenuController::OnOverflowAddedOrRemoved() {
  89. // Make the root MenuItemView recalculate the menu bounds.
  90. root_menu_->ChildrenChanged();
  91. }
  92. void NotificationMenuController::InitializeNotificationMenuView() {
  93. DCHECK(!notification_menu_view_);
  94. // Initialize the container only if there are notifications to show.
  95. if (message_center::MessageCenter::Get()
  96. ->FindNotificationsByAppId(app_id_)
  97. .empty()) {
  98. return;
  99. }
  100. app_menu_model_adapter_->model()->AddItem(NOTIFICATION_CONTAINER,
  101. std::u16string());
  102. // Add the container MenuItemView to |root_menu_|.
  103. views::MenuItemView* container =
  104. root_menu_->AppendMenuItem(NOTIFICATION_CONTAINER);
  105. notification_menu_view_ = new NotificationMenuView(this, this, app_id_);
  106. container->AddChildView(notification_menu_view_);
  107. for (auto* notification :
  108. message_center::MessageCenter::Get()->FindNotificationsByAppId(
  109. app_id_)) {
  110. notification_menu_view_->AddNotificationItemView(*notification);
  111. }
  112. // Notify the root MenuItemView so it knows to resize and re-calculate the
  113. // menu bounds.
  114. root_menu_->ChildrenChanged();
  115. }
  116. } // namespace ash