| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 #ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_ | 5 #ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_ |
| 6 #define UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_ | 6 #define UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_ |
| 7 | 7 |
| 8 #include <list> | 8 #include <list> |
| 9 #include <map> | 9 #include <map> |
| 10 | 10 |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/gtest_prod_util.h" | 12 #include "base/gtest_prod_util.h" |
| 13 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
| 14 #include "base/timer/timer.h" | 14 #include "base/timer/timer.h" |
| 15 #include "ui/gfx/display.h" | |
| 16 #include "ui/gfx/display_observer.h" | |
| 17 #include "ui/gfx/native_widget_types.h" | 15 #include "ui/gfx/native_widget_types.h" |
| 18 #include "ui/gfx/rect.h" | 16 #include "ui/gfx/rect.h" |
| 19 #include "ui/message_center/message_center_export.h" | 17 #include "ui/message_center/message_center_export.h" |
| 20 #include "ui/message_center/message_center_observer.h" | 18 #include "ui/message_center/message_center_observer.h" |
| 21 #include "ui/message_center/views/message_center_controller.h" | 19 #include "ui/message_center/views/message_center_controller.h" |
| 22 #include "ui/message_center/views/toast_contents_view.h" | 20 #include "ui/message_center/views/toast_contents_view.h" |
| 23 #include "ui/views/widget/widget_observer.h" | 21 #include "ui/views/widget/widget_observer.h" |
| 24 | 22 |
| 25 namespace base { | 23 namespace base { |
| 26 class RunLoop; | 24 class RunLoop; |
| 27 } | 25 } |
| 28 | 26 |
| 29 namespace views { | 27 namespace views { |
| 30 class Widget; | 28 class Widget; |
| 31 } | 29 } |
| 32 | 30 |
| 33 namespace ash { | |
| 34 class WebNotificationTrayTest; | |
| 35 FORWARD_DECLARE_TEST(WebNotificationTrayTest, ManyPopupNotifications); | |
| 36 } | |
| 37 | |
| 38 namespace gfx { | 31 namespace gfx { |
| 32 class Display; |
| 39 class Screen; | 33 class Screen; |
| 40 } | 34 } |
| 41 | 35 |
| 42 namespace message_center { | 36 namespace message_center { |
| 43 namespace test { | 37 namespace test { |
| 44 class MessagePopupCollectionTest; | 38 class MessagePopupCollectionTest; |
| 45 } | 39 } |
| 46 | 40 |
| 47 class MessageCenter; | 41 class MessageCenter; |
| 48 class MessageCenterTray; | 42 class MessageCenterTray; |
| 49 class MessageViewContextMenuController; | 43 class MessageViewContextMenuController; |
| 50 | 44 class PopupAlignmentDelegate; |
| 51 enum PopupAlignment { | |
| 52 POPUP_ALIGNMENT_TOP = 1 << 0, | |
| 53 POPUP_ALIGNMENT_LEFT = 1 << 1, | |
| 54 POPUP_ALIGNMENT_BOTTOM = 1 << 2, | |
| 55 POPUP_ALIGNMENT_RIGHT = 1 << 3, | |
| 56 }; | |
| 57 | 45 |
| 58 // Container for popup toasts. Because each toast is a frameless window rather | 46 // Container for popup toasts. Because each toast is a frameless window rather |
| 59 // than a view in a bubble, now the container just manages all of those toasts. | 47 // than a view in a bubble, now the container just manages all of those toasts. |
| 60 // This is similar to chrome/browser/notifications/balloon_collection, but the | 48 // This is similar to chrome/browser/notifications/balloon_collection, but the |
| 61 // contents of each toast are for the message center and layout strategy would | 49 // contents of each toast are for the message center and layout strategy would |
| 62 // be slightly different. | 50 // be slightly different. |
| 63 class MESSAGE_CENTER_EXPORT MessagePopupCollection | 51 class MESSAGE_CENTER_EXPORT MessagePopupCollection |
| 64 : public MessageCenterController, | 52 : public MessageCenterController, |
| 65 public MessageCenterObserver, | 53 public MessageCenterObserver { |
| 66 public gfx::DisplayObserver { | |
| 67 public: | 54 public: |
| 68 // |parent| specifies the parent widget of the toast windows. The default | 55 // |parent| specifies the parent widget of the toast windows. The default |
| 69 // parent will be used for NULL. Usually each icon is spacing against its | 56 // parent will be used for NULL. Usually each icon is spacing against its |
| 70 // predecessor. If |first_item_has_no_margin| is set however the first item | 57 // predecessor. |
| 71 // does not space against the tray. | |
| 72 MessagePopupCollection(gfx::NativeView parent, | 58 MessagePopupCollection(gfx::NativeView parent, |
| 73 MessageCenter* message_center, | 59 MessageCenter* message_center, |
| 74 MessageCenterTray* tray, | 60 MessageCenterTray* tray, |
| 75 bool first_item_has_no_margin); | 61 PopupAlignmentDelegate* alignment_delegate); |
| 76 virtual ~MessagePopupCollection(); | 62 virtual ~MessagePopupCollection(); |
| 77 | 63 |
| 78 // Overridden from MessageCenterController: | 64 // Overridden from MessageCenterController: |
| 79 virtual void ClickOnNotification(const std::string& notification_id) OVERRIDE; | 65 virtual void ClickOnNotification(const std::string& notification_id) OVERRIDE; |
| 80 virtual void RemoveNotification(const std::string& notification_id, | 66 virtual void RemoveNotification(const std::string& notification_id, |
| 81 bool by_user) OVERRIDE; | 67 bool by_user) OVERRIDE; |
| 82 virtual scoped_ptr<ui::MenuModel> CreateMenuModel( | 68 virtual scoped_ptr<ui::MenuModel> CreateMenuModel( |
| 83 const NotifierId& notifier_id, | 69 const NotifierId& notifier_id, |
| 84 const base::string16& display_source) OVERRIDE; | 70 const base::string16& display_source) OVERRIDE; |
| 85 virtual bool HasClickedListener(const std::string& notification_id) OVERRIDE; | 71 virtual bool HasClickedListener(const std::string& notification_id) OVERRIDE; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 102 void DecrementDeferCounter(); | 88 void DecrementDeferCounter(); |
| 103 | 89 |
| 104 // Runs the next step in update/animate sequence, if the defer counter is not | 90 // Runs the next step in update/animate sequence, if the defer counter is not |
| 105 // zero. Otherwise, simply waits when it becomes zero. | 91 // zero. Otherwise, simply waits when it becomes zero. |
| 106 void DoUpdateIfPossible(); | 92 void DoUpdateIfPossible(); |
| 107 | 93 |
| 108 // Removes the toast from our internal list of toasts; this is called when the | 94 // Removes the toast from our internal list of toasts; this is called when the |
| 109 // toast is irrevocably closed (such as within RemoveToast). | 95 // toast is irrevocably closed (such as within RemoveToast). |
| 110 void ForgetToast(ToastContentsView* toast); | 96 void ForgetToast(ToastContentsView* toast); |
| 111 | 97 |
| 112 // Updates |work_area_| and re-calculates the alignment of notification toasts | 98 // Called when the display bounds has been changed. Used in Windows only. |
| 113 // rearranging them if necessary. | 99 void OnDisplayMetricsChanged(const gfx::Display& display); |
| 114 // This is separated from methods from OnDisplayMetricsChanged(), since | |
| 115 // sometimes the display info has to be specified directly. One example is | |
| 116 // shelf's auto-hide change. When the shelf in ChromeOS is temporarily shown | |
| 117 // from auto hide status, it doesn't change the display's work area but the | |
| 118 // actual work area for toasts should be resized. | |
| 119 void SetDisplayInfo(const gfx::Rect& work_area, | |
| 120 const gfx::Rect& screen_bounds); | |
| 121 | |
| 122 // Overridden from gfx::DislayObserver: | |
| 123 virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE; | |
| 124 virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE; | |
| 125 virtual void OnDisplayMetricsChanged(const gfx::Display& display, | |
| 126 uint32_t metrics) OVERRIDE; | |
| 127 | 100 |
| 128 // Used by ToastContentsView to locate itself. | 101 // Used by ToastContentsView to locate itself. |
| 129 gfx::NativeView parent() const { return parent_; } | 102 gfx::NativeView parent() const { return parent_; } |
| 130 | 103 |
| 131 private: | 104 private: |
| 132 FRIEND_TEST_ALL_PREFIXES(ash::WebNotificationTrayTest, | |
| 133 ManyPopupNotifications); | |
| 134 friend class test::MessagePopupCollectionTest; | 105 friend class test::MessagePopupCollectionTest; |
| 135 friend class ash::WebNotificationTrayTest; | |
| 136 typedef std::list<ToastContentsView*> Toasts; | 106 typedef std::list<ToastContentsView*> Toasts; |
| 137 | 107 |
| 138 // Iterates toasts and starts closing them. | 108 // Iterates toasts and starts closing them. |
| 139 std::set<std::string> CloseAllWidgets(); | 109 std::set<std::string> CloseAllWidgets(); |
| 140 | 110 |
| 141 // Called by ToastContentsView when its window is closed. | 111 // Called by ToastContentsView when its window is closed. |
| 142 void RemoveToast(ToastContentsView* toast, bool mark_as_shown); | 112 void RemoveToast(ToastContentsView* toast, bool mark_as_shown); |
| 143 | 113 |
| 144 // Returns the x-origin for the given toast bounds in the current work area. | |
| 145 int GetToastOriginX(const gfx::Rect& toast_bounds) const; | |
| 146 | |
| 147 // Creates new widgets for new toast notifications, and updates |toasts_| and | 114 // Creates new widgets for new toast notifications, and updates |toasts_| and |
| 148 // |widgets_| correctly. | 115 // |widgets_| correctly. |
| 149 void UpdateWidgets(); | 116 void UpdateWidgets(); |
| 150 | 117 |
| 151 // Repositions all of the widgets based on the current work area. | 118 // Repositions all of the widgets based on the current work area. |
| 152 void RepositionWidgets(); | 119 void RepositionWidgets(); |
| 153 | 120 |
| 154 // Repositions widgets to the top edge of the notification toast that was | 121 // Repositions widgets to the top edge of the notification toast that was |
| 155 // just removed, so that the user can click close button without mouse moves. | 122 // just removed, so that the user can click close button without mouse moves. |
| 156 // See crbug.com/224089 | 123 // See crbug.com/224089 |
| 157 void RepositionWidgetsWithTarget(); | 124 void RepositionWidgetsWithTarget(); |
| 158 | 125 |
| 159 void ComputePopupAlignment(gfx::Rect work_area, gfx::Rect screen_bounds); | |
| 160 | |
| 161 // The base line is an (imaginary) line that would touch the bottom of the | 126 // The base line is an (imaginary) line that would touch the bottom of the |
| 162 // next created notification if bottom-aligned or its top if top-aligned. | 127 // next created notification if bottom-aligned or its top if top-aligned. |
| 163 int GetBaseLine(ToastContentsView* last_toast) const; | 128 int GetBaseLine(ToastContentsView* last_toast) const; |
| 164 | 129 |
| 165 // Overridden from MessageCenterObserver: | 130 // Overridden from MessageCenterObserver: |
| 166 virtual void OnNotificationAdded(const std::string& notification_id) OVERRIDE; | 131 virtual void OnNotificationAdded(const std::string& notification_id) OVERRIDE; |
| 167 virtual void OnNotificationRemoved(const std::string& notification_id, | 132 virtual void OnNotificationRemoved(const std::string& notification_id, |
| 168 bool by_user) OVERRIDE; | 133 bool by_user) OVERRIDE; |
| 169 virtual void OnNotificationUpdated( | 134 virtual void OnNotificationUpdated( |
| 170 const std::string& notification_id) OVERRIDE; | 135 const std::string& notification_id) OVERRIDE; |
| 171 | 136 |
| 172 ToastContentsView* FindToast(const std::string& notification_id) const; | 137 ToastContentsView* FindToast(const std::string& notification_id) const; |
| 173 | 138 |
| 174 // While the toasts are animated, avoid updating the collection, to reduce | 139 // While the toasts are animated, avoid updating the collection, to reduce |
| 175 // user confusion. Instead, update the collection when all animations are | 140 // user confusion. Instead, update the collection when all animations are |
| 176 // done. This method is run when defer counter is zero, may initiate next | 141 // done. This method is run when defer counter is zero, may initiate next |
| 177 // update/animation step. | 142 // update/animation step. |
| 178 void OnDeferTimerExpired(); | 143 void OnDeferTimerExpired(); |
| 179 | 144 |
| 180 // "ForTest" methods. | 145 // "ForTest" methods. |
| 181 views::Widget* GetWidgetForTest(const std::string& id) const; | 146 views::Widget* GetWidgetForTest(const std::string& id) const; |
| 182 void CreateRunLoopForTest(); | 147 void CreateRunLoopForTest(); |
| 183 void WaitForTest(); | 148 void WaitForTest(); |
| 184 gfx::Rect GetToastRectAt(size_t index) const; | 149 gfx::Rect GetToastRectAt(size_t index) const; |
| 185 | 150 |
| 186 gfx::NativeView parent_; | 151 gfx::NativeView parent_; |
| 187 MessageCenter* message_center_; | 152 MessageCenter* message_center_; |
| 188 MessageCenterTray* tray_; | 153 MessageCenterTray* tray_; |
| 189 Toasts toasts_; | 154 Toasts toasts_; |
| 190 gfx::Rect work_area_; | |
| 191 int64 display_id_; | |
| 192 gfx::Screen* screen_; | |
| 193 | 155 |
| 194 // Specifies which corner of the screen popups should show up. This should | 156 PopupAlignmentDelegate* alignment_delegate_; |
| 195 // ideally be the same corner the notification area (systray) is at. | |
| 196 PopupAlignment alignment_; | |
| 197 | 157 |
| 198 int defer_counter_; | 158 int defer_counter_; |
| 199 | 159 |
| 200 // This is only used to compare with incoming events, do not assume that | 160 // This is only used to compare with incoming events, do not assume that |
| 201 // the toast will be valid if this pointer is non-NULL. | 161 // the toast will be valid if this pointer is non-NULL. |
| 202 ToastContentsView* latest_toast_entered_; | 162 ToastContentsView* latest_toast_entered_; |
| 203 | 163 |
| 204 // Denotes a mode when user is clicking the Close button of toasts in a | 164 // Denotes a mode when user is clicking the Close button of toasts in a |
| 205 // sequence, w/o moving the mouse. We reposition the toasts so the next one | 165 // sequence, w/o moving the mouse. We reposition the toasts so the next one |
| 206 // happens to be right under the mouse, and the user can just dispose of | 166 // happens to be right under the mouse, and the user can just dispose of |
| 207 // multipel toasts by clicking. The mode ends when defer_timer_ expires. | 167 // multipel toasts by clicking. The mode ends when defer_timer_ expires. |
| 208 bool user_is_closing_toasts_by_clicking_; | 168 bool user_is_closing_toasts_by_clicking_; |
| 209 scoped_ptr<base::OneShotTimer<MessagePopupCollection> > defer_timer_; | 169 scoped_ptr<base::OneShotTimer<MessagePopupCollection> > defer_timer_; |
| 210 // The top edge to align the position of the next toast during 'close by | 170 // The top edge to align the position of the next toast during 'close by |
| 211 // clicking" mode. | 171 // clicking" mode. |
| 212 // Only to be used when user_is_closing_toasts_by_clicking_ is true. | 172 // Only to be used when user_is_closing_toasts_by_clicking_ is true. |
| 213 int target_top_edge_; | 173 int target_top_edge_; |
| 214 | 174 |
| 215 // Weak, only exists temporarily in tests. | 175 // Weak, only exists temporarily in tests. |
| 216 scoped_ptr<base::RunLoop> run_loop_for_test_; | 176 scoped_ptr<base::RunLoop> run_loop_for_test_; |
| 217 | 177 |
| 218 // True if the first item should not have spacing against the tray. | |
| 219 bool first_item_has_no_margin_; | |
| 220 | |
| 221 scoped_ptr<MessageViewContextMenuController> context_menu_controller_; | 178 scoped_ptr<MessageViewContextMenuController> context_menu_controller_; |
| 222 | 179 |
| 223 // Gives out weak pointers to toast contents views which have an unrelated | 180 // Gives out weak pointers to toast contents views which have an unrelated |
| 224 // lifetime. Must remain the last member variable. | 181 // lifetime. Must remain the last member variable. |
| 225 base::WeakPtrFactory<MessagePopupCollection> weak_factory_; | 182 base::WeakPtrFactory<MessagePopupCollection> weak_factory_; |
| 226 | 183 |
| 227 DISALLOW_COPY_AND_ASSIGN(MessagePopupCollection); | 184 DISALLOW_COPY_AND_ASSIGN(MessagePopupCollection); |
| 228 }; | 185 }; |
| 229 | 186 |
| 230 } // namespace message_center | 187 } // namespace message_center |
| 231 | 188 |
| 232 #endif // UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_ | 189 #endif // UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_ |
| OLD | NEW |