123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- // 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.
- #ifndef ASH_SYSTEM_MESSAGE_CENTER_UNIFIED_MESSAGE_LIST_VIEW_H_
- #define ASH_SYSTEM_MESSAGE_CENTER_UNIFIED_MESSAGE_LIST_VIEW_H_
- #include "ash/ash_export.h"
- #include "ash/system/unified/unified_system_tray_model.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/scoped_multi_source_observation.h"
- #include "base/scoped_observation.h"
- #include "ui/compositor/throughput_tracker.h"
- #include "ui/message_center/message_center.h"
- #include "ui/message_center/message_center_observer.h"
- #include "ui/message_center/notification_view_controller.h"
- #include "ui/message_center/views/message_view.h"
- #include "ui/views/animation/animation_delegate_views.h"
- #include "ui/views/view.h"
- namespace gfx {
- class LinearAnimation;
- } // namespace gfx
- namespace message_center {
- class MessageView;
- class Notification;
- } // namespace message_center
- namespace ash {
- class UnifiedMessageCenterView;
- class UnifiedSystemTrayModel;
- // Manages list of notifications. The class doesn't know about the ScrollView
- // it's enclosed. This class is used only from UnifiedMessageCenterView.
- class ASH_EXPORT UnifiedMessageListView
- : public views::View,
- public message_center::MessageCenterObserver,
- public message_center::NotificationViewController,
- public message_center::MessageView::Observer,
- public views::AnimationDelegateViews {
- public:
- // |message_center_view| can be null in unit tests.
- UnifiedMessageListView(UnifiedMessageCenterView* message_center_view,
- scoped_refptr<UnifiedSystemTrayModel> model);
- UnifiedMessageListView(const UnifiedMessageListView& other) = delete;
- UnifiedMessageListView& operator=(const UnifiedMessageListView& other) =
- delete;
- ~UnifiedMessageListView() override;
- // Initializes the view with existing notifications. Should be called right
- // after ctor.
- void Init();
- // Starts Clear All animation and removes all notifications. Notifications are
- // removed from MessageCenter at the beginning of the animation.
- void ClearAllWithAnimation();
- // Return the bounds of the specified notification view. If the given id is
- // invalid, return an empty rect.
- gfx::Rect GetNotificationBounds(const std::string& id) const;
- // Return the bounds of the last notification view. If there is no view,
- // return an empty rect.
- gfx::Rect GetLastNotificationBounds() const;
- // Return the bounds of the first notification whose bottom is below
- // |y_offset|.
- gfx::Rect GetNotificationBoundsBelowY(int y_offset) const;
- // Returns all notifications in the view hierarchy that are also in the
- // MessageCenter.
- std::vector<message_center::Notification*> GetAllNotifications() const;
- // Returns all notification ids in the view hierarchy regardless of whether
- // they are in also in the MessageCenter.
- std::vector<std::string> GetAllNotificationIds() const;
- // Returns the notifications in the view hierarchy that are also in the
- // MessageCenter, whose bottom position is above |y_offset|. O(n) where n is
- // number of notifications.
- std::vector<message_center::Notification*> GetNotificationsAboveY(
- int y_offset) const;
- // Returns the notifications in the view hierarchy that are also in the
- // MessageCenter, whose bottom position is below |y_offset|. O(n) where n is
- // number of notifications.
- std::vector<message_center::Notification*> GetNotificationsBelowY(
- int y_offset) const;
- // Same as GetNotificationsAboveY, but returns notifications that are not in
- // the MessageCenter. This is useful for the clear all animation which first
- // removes all notifications before asking for stacked notifications.
- std::vector<std::string> GetNotificationIdsAboveY(int y_offset) const;
- // Returns notifications that are in the view hierarchy below `y_offset`
- // without checking whether they are in the MessageCenter. This is useful for
- // the clear all animation which first removes all notifications before asking
- // for stacked notifications.
- std::vector<std::string> GetNotificationIdsBelowY(int y_offset) const;
- // Returns the total number of notifications in the list.
- int GetTotalNotificationCount() const;
- // Returns the total number of pinned notifications in the list.
- int GetTotalPinnedNotificationCount() const;
- // Returns true if `animation_` is currently in progress.
- bool IsAnimating() const;
- // Returns whether `message_view_container` is being animated for expand or
- // collapse.
- bool IsAnimatingExpandOrCollapseContainer(const views::View* view) const;
- // Called when a notification is slid out so we can run the MOVE_DOWN
- // animation.
- void OnNotificationSlidOut();
- // views::View:
- void ChildPreferredSizeChanged(views::View* child) override;
- void PreferredSizeChanged() override;
- void Layout() override;
- gfx::Size CalculatePreferredSize() const override;
- const char* GetClassName() const override;
- // message_center::NotificationViewController:
- void AnimateResize() override;
- message_center::MessageView* GetMessageViewForNotificationId(
- const std::string& id) override;
- void ConvertNotificationViewToGroupedNotificationView(
- const std::string& ungrouped_notification_id,
- const std::string& new_grouped_notification_id) override;
- void ConvertGroupedNotificationViewToNotificationView(
- const std::string& grouped_notification_id,
- const std::string& new_single_notification_id) override;
- // message_center::MessageCenterObserver:
- void OnNotificationAdded(const std::string& id) override;
- void OnNotificationRemoved(const std::string& id, bool by_user) override;
- void OnNotificationUpdated(const std::string& id) override;
- // message_center::MessageView::Observer:
- void OnSlideStarted(const std::string& notification_id) override;
- void OnCloseButtonPressed(const std::string& notification_id) override;
- void OnSettingsButtonPressed(const std::string& notification_id) override;
- void OnSnoozeButtonPressed(const std::string& notification_id) override;
- // views::AnimationDelegateViews:
- void AnimationEnded(const gfx::Animation* animation) override;
- void AnimationProgressed(const gfx::Animation* animation) override;
- void AnimationCanceled(const gfx::Animation* animation) override;
- bool is_deleting_removed_notifications() const {
- return is_deleting_removed_notifications_;
- }
- protected:
- // Virtual for testing.
- virtual message_center::MessageView* CreateMessageView(
- const message_center::Notification& notification);
- void ConfigureMessageView(message_center::MessageView* message_view);
- // Virtual for testing.
- virtual std::vector<message_center::Notification*> GetStackedNotifications()
- const;
- // Virtual for testing.
- virtual std::vector<std::string> GetNonVisibleNotificationIdsInViewHierarchy()
- const;
- private:
- friend class UnifiedMessageCenterViewTest;
- friend class UnifiedMessageListViewTest;
- friend class UnifiedMessageCenterBubbleTest;
- class Background;
- class MessageViewContainer;
- // UnifiedMessageListView always runs a single animation at one time. When
- // `state_` is IDLE, `animation_->is_animating()` is always false and vice
- // versa.
- enum class State {
- // No animation is running.
- IDLE,
- // Moving down notifications.
- MOVE_DOWN,
- // Part 1 of Clear All animation. Removing all hidden notifications above
- // the visible area.
- CLEAR_ALL_STACKED,
- // Part 2 of Clear All animation. Removing all visible notifications.
- CLEAR_ALL_VISIBLE,
- // Animating an increase or decrease in height of a notification. Only one
- // may animate at a time.
- EXPAND_OR_COLLAPSE
- };
- // Syntactic sugar to downcast.
- static const MessageViewContainer* AsMVC(const views::View* v);
- static MessageViewContainer* AsMVC(views::View* v);
- // Returns the notification with the provided |id|.
- const MessageViewContainer* GetNotificationById(const std::string& id) const;
- MessageViewContainer* GetNotificationById(const std::string& id) {
- return const_cast<MessageViewContainer*>(
- static_cast<const UnifiedMessageListView*>(this)->GetNotificationById(
- id));
- }
- // Returns the first removable notification from the top.
- MessageViewContainer* GetNextRemovableNotification();
- // Current progress of the animation between 0.0 and 1.0. Returns 1.0 when
- // it's not animating.
- double GetCurrentValue() const;
- // Collapses all the existing notifications. It does not trigger
- // PreferredSizeChanged() (See |ignore_size_change_|).
- void CollapseAllNotifications();
- // Updates the borders of notifications. It adds separators between
- // notifications, and rounds notification corners at the top and the bottom.
- // `force_update` indicates if we should update borders on all notifications
- // regardless of their previous state.
- void UpdateBorders(bool force_update);
- // Updates |final_bounds| of all notifications and moves old |final_bounds| to
- // |start_bounds|.
- void UpdateBounds();
- // Resets the animation, and makes all notifications immediately positioned at
- // |final_bounds|.
- void ResetBounds();
- // Interrupts clear all animation and deletes all the remaining notifications.
- // ResetBounds() should be called after that.
- void InterruptClearAll();
- // Deletes all the MessageViewContainer marked as |is_removed|.
- void DeleteRemovedNotifications();
- // Starts the animation for current |state_|.
- void StartAnimation();
- // Updates the state between each Clear All animation phase.
- void UpdateClearAllAnimation();
- UnifiedMessageCenterView* const message_center_view_;
- scoped_refptr<UnifiedSystemTrayModel> model_;
- // Non-null during State::EXPAND_OR_COLLAPSE. Keeps track of the
- // MessageViewContainer that is animating.
- MessageViewContainer* expand_or_collapsing_container_ = nullptr;
- // If true, ChildPreferredSizeChanged() will be ignored. This is used in
- // CollapseAllNotifications() to prevent PreferredSizeChanged() triggered
- // multiple times because of sequential SetExpanded() calls.
- bool ignore_size_change_ = false;
- // If true, OnNotificationRemoved() will be ignored. Used in
- // ClearAllWithAnimation().
- bool ignore_notification_remove_ = false;
- // Manages notification closing animation. UnifiedMessageListView does not use
- // implicit animation.
- const std::unique_ptr<gfx::LinearAnimation> animation_;
- // Measure animation smoothness metrics for `animation_`.
- absl::optional<ui::ThroughputTracker> throughput_tracker_;
- State state_ = State::IDLE;
- // The height the UnifiedMessageListView starts animating from. If not
- // animating, it's ignored.
- int start_height_ = 0;
- // The final height of the UnifiedMessageListView. If not animating, it's same
- // as height().
- int target_height_ = 0;
- // True if the UnifiedMessageListView is currently deleting notifications
- // marked for removal. This check is needed to prevent re-entrancing issues
- // (e.g. crbug.com/933327) caused by the View destructor.
- bool is_deleting_removed_notifications_ = false;
- const bool is_notifications_refresh_enabled_;
- const int message_view_width_;
- base::ScopedObservation<message_center::MessageCenter,
- message_center::MessageCenterObserver>
- message_center_observation_{this};
- base::ScopedMultiSourceObservation<message_center::MessageView,
- message_center::MessageView::Observer>
- message_view_multi_source_observation_{this};
- };
- } // namespace ash
- #endif // ASH_SYSTEM_MESSAGE_CENTER_UNIFIED_MESSAGE_LIST_VIEW_H_
|