Add ICU message format support
[chromium-blink-merge.git] / ui / message_center / views / message_popup_collection.h
bloba8acf67e6f4955726db1e955d37c6b0dfd074265
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
3 // found in the LICENSE file.
5 #ifndef UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_
6 #define UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_
8 #include <list>
9 #include <map>
11 #include "base/compiler_specific.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/timer/timer.h"
15 #include "ui/gfx/geometry/rect.h"
16 #include "ui/gfx/native_widget_types.h"
17 #include "ui/message_center/message_center_export.h"
18 #include "ui/message_center/message_center_observer.h"
19 #include "ui/message_center/views/message_center_controller.h"
20 #include "ui/message_center/views/toast_contents_view.h"
21 #include "ui/views/widget/widget_observer.h"
23 namespace base {
24 class RunLoop;
27 namespace views {
28 class Widget;
31 namespace gfx {
32 class Display;
33 class Screen;
36 namespace message_center {
37 namespace test {
38 class MessagePopupCollectionTest;
41 class MessageCenter;
42 class MessageCenterTray;
43 class MessageViewContextMenuController;
44 class PopupAlignmentDelegate;
46 // Container for popup toasts. Because each toast is a frameless window rather
47 // than a view in a bubble, now the container just manages all of those toasts.
48 // This is similar to chrome/browser/notifications/balloon_collection, but the
49 // contents of each toast are for the message center and layout strategy would
50 // be slightly different.
51 class MESSAGE_CENTER_EXPORT MessagePopupCollection
52 : public MessageCenterController,
53 public MessageCenterObserver {
54 public:
55 // |parent| specifies the parent widget of the toast windows. The default
56 // parent will be used for NULL. Usually each icon is spacing against its
57 // predecessor.
58 MessagePopupCollection(gfx::NativeView parent,
59 MessageCenter* message_center,
60 MessageCenterTray* tray,
61 PopupAlignmentDelegate* alignment_delegate);
62 ~MessagePopupCollection() override;
64 // Overridden from MessageCenterController:
65 void ClickOnNotification(const std::string& notification_id) override;
66 void RemoveNotification(const std::string& notification_id,
67 bool by_user) override;
68 scoped_ptr<ui::MenuModel> CreateMenuModel(
69 const NotifierId& notifier_id,
70 const base::string16& display_source) override;
71 bool HasClickedListener(const std::string& notification_id) override;
72 void ClickOnNotificationButton(const std::string& notification_id,
73 int button_index) override;
75 void MarkAllPopupsShown();
77 // Since these events are really coming from individual toast widgets,
78 // it helps to be able to keep track of the sender.
79 void OnMouseEntered(ToastContentsView* toast_entered);
80 void OnMouseExited(ToastContentsView* toast_exited);
82 // Invoked by toasts when they start/finish their animations.
83 // While "defer counter" is greater then zero, the popup collection does
84 // not perform updates. It is used to wait for various animations and user
85 // actions like serial closing of the toasts, when the remaining toasts "flow
86 // under the mouse".
87 void IncrementDeferCounter();
88 void DecrementDeferCounter();
90 // Runs the next step in update/animate sequence, if the defer counter is not
91 // zero. Otherwise, simply waits when it becomes zero.
92 void DoUpdateIfPossible();
94 // Removes the toast from our internal list of toasts; this is called when the
95 // toast is irrevocably closed (such as within RemoveToast).
96 void ForgetToast(ToastContentsView* toast);
98 // Called when the display bounds has been changed. Used in Windows only.
99 void OnDisplayMetricsChanged(const gfx::Display& display);
101 // Used by ToastContentsView to locate itself.
102 gfx::NativeView parent() const { return parent_; }
104 private:
105 friend class test::MessagePopupCollectionTest;
106 typedef std::list<ToastContentsView*> Toasts;
108 // Iterates toasts and starts closing them.
109 std::set<std::string> CloseAllWidgets();
111 // Called by ToastContentsView when its window is closed.
112 void RemoveToast(ToastContentsView* toast, bool mark_as_shown);
114 // Creates new widgets for new toast notifications, and updates |toasts_| and
115 // |widgets_| correctly.
116 void UpdateWidgets();
118 // Repositions all of the widgets based on the current work area.
119 void RepositionWidgets();
121 // Repositions widgets to the top edge of the notification toast that was
122 // just removed, so that the user can click close button without mouse moves.
123 // See crbug.com/224089
124 void RepositionWidgetsWithTarget();
126 // The base line is an (imaginary) line that would touch the bottom of the
127 // next created notification if bottom-aligned or its top if top-aligned.
128 int GetBaseLine(ToastContentsView* last_toast) const;
130 // Overridden from MessageCenterObserver:
131 void OnNotificationAdded(const std::string& notification_id) override;
132 void OnNotificationRemoved(const std::string& notification_id,
133 bool by_user) override;
134 void OnNotificationUpdated(const std::string& notification_id) override;
136 ToastContentsView* FindToast(const std::string& notification_id) const;
138 // While the toasts are animated, avoid updating the collection, to reduce
139 // user confusion. Instead, update the collection when all animations are
140 // done. This method is run when defer counter is zero, may initiate next
141 // update/animation step.
142 void OnDeferTimerExpired();
144 // "ForTest" methods.
145 views::Widget* GetWidgetForTest(const std::string& id) const;
146 void CreateRunLoopForTest();
147 void WaitForTest();
148 gfx::Rect GetToastRectAt(size_t index) const;
150 gfx::NativeView parent_;
151 MessageCenter* message_center_;
152 MessageCenterTray* tray_;
153 Toasts toasts_;
155 PopupAlignmentDelegate* alignment_delegate_;
157 int defer_counter_;
159 // This is only used to compare with incoming events, do not assume that
160 // the toast will be valid if this pointer is non-NULL.
161 ToastContentsView* latest_toast_entered_;
163 // Denotes a mode when user is clicking the Close button of toasts in a
164 // sequence, w/o moving the mouse. We reposition the toasts so the next one
165 // happens to be right under the mouse, and the user can just dispose of
166 // multipel toasts by clicking. The mode ends when defer_timer_ expires.
167 bool user_is_closing_toasts_by_clicking_;
168 scoped_ptr<base::OneShotTimer<MessagePopupCollection> > defer_timer_;
169 // The top edge to align the position of the next toast during 'close by
170 // clicking" mode.
171 // Only to be used when user_is_closing_toasts_by_clicking_ is true.
172 int target_top_edge_;
174 // Weak, only exists temporarily in tests.
175 scoped_ptr<base::RunLoop> run_loop_for_test_;
177 scoped_ptr<MessageViewContextMenuController> context_menu_controller_;
179 // Gives out weak pointers to toast contents views which have an unrelated
180 // lifetime. Must remain the last member variable.
181 base::WeakPtrFactory<MessagePopupCollection> weak_factory_;
183 DISALLOW_COPY_AND_ASSIGN(MessagePopupCollection);
186 } // namespace message_center
188 #endif // UI_MESSAGE_CENTER_VIEWS_MESSAGE_POPUP_COLLECTION_H_