123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- // Copyright 2018 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/app_menu/notification_menu_view.h"
- #include "ash/app_menu/notification_item_view.h"
- #include "ash/app_menu/notification_menu_header_view.h"
- #include "ash/app_menu/notification_overflow_view.h"
- #include "ash/public/cpp/app_menu_constants.h"
- #include "ui/base/models/menu_separator_types.h"
- #include "ui/gfx/geometry/point.h"
- #include "ui/gfx/geometry/rect.h"
- #include "ui/gfx/geometry/size.h"
- #include "ui/message_center/public/cpp/notification.h"
- #include "ui/message_center/views/proportional_image_view.h"
- #include "ui/views/controls/menu/menu_config.h"
- #include "ui/views/controls/menu/menu_item_view.h"
- #include "ui/views/controls/menu/menu_separator.h"
- namespace ash {
- NotificationMenuView::NotificationMenuView(
- Delegate* notification_item_view_delegate,
- views::SlideOutControllerDelegate* slide_out_controller_delegate,
- const std::string& app_id)
- : app_id_(app_id),
- notification_item_view_delegate_(notification_item_view_delegate),
- slide_out_controller_delegate_(slide_out_controller_delegate),
- double_separator_(AddChildView(std::make_unique<views::MenuSeparator>(
- ui::MenuSeparatorType::DOUBLE_SEPARATOR))),
- header_view_(
- AddChildView(std::make_unique<NotificationMenuHeaderView>())) {
- DCHECK(notification_item_view_delegate_);
- DCHECK(slide_out_controller_delegate_);
- DCHECK(!app_id_.empty())
- << "Only context menus for applications can show notifications.";
- }
- NotificationMenuView::~NotificationMenuView() = default;
- gfx::Size NotificationMenuView::CalculatePreferredSize() const {
- return gfx::Size(
- views::MenuConfig::instance().touchable_menu_min_width,
- double_separator_->GetPreferredSize().height() +
- header_view_->GetPreferredSize().height() +
- kNotificationItemViewHeight +
- (overflow_view_ ? overflow_view_->GetPreferredSize().height() : 0));
- }
- void NotificationMenuView::Layout() {
- int y = 0;
- double_separator_->SetBoundsRect(gfx::Rect(
- gfx::Point(0, y),
- gfx::Size(views::MenuConfig::instance().touchable_menu_min_width,
- double_separator_->GetPreferredSize().height())));
- y += double_separator_->GetPreferredSize().height();
- header_view_->SetBoundsRect(
- gfx::Rect(gfx::Point(0, y), header_view_->GetPreferredSize()));
- y += header_view_->GetPreferredSize().height();
- auto* item = GetDisplayedNotificationItemView();
- if (item) {
- item->SetBoundsRect(gfx::Rect(gfx::Point(0, y), item->GetPreferredSize()));
- y = item->bounds().bottom();
- }
- if (overflow_view_) {
- overflow_view_->SetBoundsRect(
- gfx::Rect(gfx::Point(0, y), overflow_view_->GetPreferredSize()));
- }
- }
- bool NotificationMenuView::IsEmpty() const {
- return notification_item_views_.empty();
- }
- void NotificationMenuView::AddNotificationItemView(
- const message_center::Notification& notification) {
- auto* old_displayed_item = GetDisplayedNotificationItemView();
- auto notification_view = std::make_unique<NotificationItemView>(
- notification_item_view_delegate_, slide_out_controller_delegate_,
- notification.title(), notification.message(), notification.icon(),
- notification.id());
- notification_item_views_.push_front(
- AddChildView(std::move(notification_view)));
- header_view_->UpdateCounter(notification_item_views_.size());
- if (!old_displayed_item)
- return;
- // Push |old_displayed_notification_item_view| to |overflow_view_|.
- old_displayed_item->SetVisible(false);
- const bool overflow_view_created = !overflow_view_;
- if (!overflow_view_)
- overflow_view_ = AddChildView(std::make_unique<NotificationOverflowView>());
- overflow_view_->AddIcon(old_displayed_item->proportional_image_view(),
- old_displayed_item->notification_id());
- if (overflow_view_created) {
- PreferredSizeChanged();
- // OnOverflowAddedOrRemoved must be called after PreferredSizeChange to
- // ensure that enough room is allocated for the overflow view.
- notification_item_view_delegate_->OnOverflowAddedOrRemoved();
- }
- Layout();
- }
- void NotificationMenuView::UpdateNotificationItemView(
- const message_center::Notification& notification) {
- // Find the view which corresponds to |notification|.
- const auto i = NotificationIterForId(notification.id());
- if (i == notification_item_views_.end())
- return;
- (*i)->UpdateContents(notification.title(), notification.message(),
- notification.icon());
- }
- void NotificationMenuView::OnNotificationRemoved(
- const std::string& notification_id) {
- // Find the view which corresponds to |notification_id|.
- const auto i = NotificationIterForId(notification_id);
- if (i == notification_item_views_.end())
- return;
- const bool removed_displayed_notification =
- *i == GetDisplayedNotificationItemView();
- RemoveChildViewT(*i);
- notification_item_views_.erase(i);
- header_view_->UpdateCounter(notification_item_views_.size());
- if (removed_displayed_notification) {
- // Display the next notification.
- auto* item = GetDisplayedNotificationItemView();
- if (item) {
- item->SetVisible(true);
- if (overflow_view_)
- overflow_view_->RemoveIcon(item->notification_id());
- }
- } else if (overflow_view_) {
- overflow_view_->RemoveIcon(notification_id);
- }
- if (overflow_view_ && overflow_view_->is_empty()) {
- // Remove and delete |overflow_view_|.
- RemoveChildViewT(overflow_view_);
- overflow_view_ = nullptr;
- PreferredSizeChanged();
- notification_item_view_delegate_->OnOverflowAddedOrRemoved();
- }
- }
- ui::Layer* NotificationMenuView::GetSlideOutLayer() {
- auto* item = GetDisplayedNotificationItemView();
- return item ? item->layer() : nullptr;
- }
- const NotificationItemView*
- NotificationMenuView::GetDisplayedNotificationItemView() const {
- return notification_item_views_.empty() ? nullptr
- : notification_item_views_.front();
- }
- const std::string& NotificationMenuView::GetDisplayedNotificationID() const {
- DCHECK(!notification_item_views_.empty());
- return GetDisplayedNotificationItemView()->notification_id();
- }
- NotificationMenuView::NotificationItemViews::iterator
- NotificationMenuView::NotificationIterForId(const std::string& id) {
- return std::find_if(
- notification_item_views_.begin(), notification_item_views_.end(),
- [id](const auto& item) { return item->notification_id() == id; });
- }
- } // namespace ash
|