• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 
5 // Draws the view for the balloons.
6 
7 #ifndef CHROME_BROWSER_CHROMEOS_NOTIFICATIONS_NOTIFICATION_PANEL_H_
8 #define CHROME_BROWSER_CHROMEOS_NOTIFICATIONS_NOTIFICATION_PANEL_H_
9 #pragma once
10 
11 #include "base/memory/scoped_ptr.h"
12 #include "base/task.h"
13 #include "chrome/browser/chromeos/frame/panel_controller.h"
14 #include "chrome/browser/chromeos/notifications/balloon_collection_impl.h"
15 #include "content/common/notification_registrar.h"
16 #include "ui/gfx/rect.h"
17 
18 class Balloon;
19 class Notification;
20 
21 namespace views {
22 class ScrollView;
23 }  // namespace views
24 
25 namespace chromeos {
26 
27 class BalloonContainer;
28 class BalloonViewImpl;
29 class NotificationPanelTester;
30 
31 // NotificationPanel is a panel that displays notifications. It has
32 // several states and displays the different portion of notifications
33 // depending on in which state the panel is. The following shows
34 // how the panel's state changes in response to various events.
35 //
36 // TODO(oshima): add remove event and fix state transition graph below.
37 // Event List:
38 //   close: a user pressed close button on the title bar,
39 //          or the system closed the panel.
40 //   new : a new notification is added.
41 //   stale: one of new notifications became stale.
42 //   expand: a user pressed minimized panel to expand.
43 //   minimize: a user pressed the panel's title bar to minimize.
44 //   user: the user's mouse moved over the panel, indicates
45 //         that user is trying to interact with the panel.
46 // For state, see State enum's description below.
47 //
48 //
49 // [CLOSE]<-(event=close)-+     +--(event=stale, cond=has new|sticky)
50 //   |                    |     |         (event=new)
51 //   |                    |     V           |
52 //   +--(event=new)-->[STICKY_AND_NEW]----- +--------(event=user)
53 //   |                  ^           |                      |
54 //   |                  |  (event=stale,                   V
55 //   |                  |  cond=has new, no sticy)  +[ KEEP_SIZE ]<-+
56 //   |          (event=new)   (event=minimize)      |      |        |
57 //   |                  |           |               |      |        |
58 //   |                  |           |  (event=minimize)(event=close)|
59 //   |                  |           +---------------+      |        |
60 //   |                  |           V                      V        |
61 //   |                  [ MINIMIZED ]---(event=close)--> [CLOSE]    |
62 //   |                     |     ^                                  |
63 //   |                     |     |                                  |
64 //   |          (event=expand)  (event=minmize)                 (event=user)
65 //   |                     V     |                                  |
66 //   +--(event=open)---->[  FULL  ]-------------+-------------------+
67 //                         |     ^              |
68 //              (event=close)    +-------(event=stale)(event=new)
69 //                         |
70 //          [CLOSE] <------+
71 //
72 class NotificationPanel : public PanelController::Delegate,
73                           public BalloonCollectionImpl::NotificationUI,
74                           public NotificationObserver {
75  public:
76   enum State {
77     FULL,  // Show all notifications
78     KEEP_SIZE,  // Don't change the size.
79     STICKY_AND_NEW,  // Show only new and sticky notifications.
80     MINIMIZED,  // The panel is minimized.
81     CLOSED,  // The panel is closed.
82   };
83 
84   NotificationPanel();
85   virtual ~NotificationPanel();
86 
87   // Shows/Hides the Panel.
88   void Show();
89   void Hide();
90 
91   // BalloonCollectionImpl::NotificationUI overrides..
92   virtual void Add(Balloon* balloon);
93   virtual bool Update(Balloon* balloon);
94   virtual void Remove(Balloon* balloon);
95   virtual void Show(Balloon* balloon);
96   virtual void ResizeNotification(Balloon* balloon,
97                                   const gfx::Size& size);
98   virtual void SetActiveView(BalloonViewImpl* view);
99 
100   // PanelController::Delegate overrides.
101   virtual string16 GetPanelTitle();
102   virtual SkBitmap GetPanelIcon();
103   virtual bool CanClosePanel();
104   virtual void ClosePanel();
105   virtual void ActivatePanel();
106 
107   // NotificationObserver overrides:
108   virtual void Observe(NotificationType type,
109                        const NotificationSource& source,
110                        const NotificationDetails& details);
111 
112   // Called when a mouse left the panel window.
113   void OnMouseLeave();
114   void OnMouseMotion(const gfx::Point& point);
115 
116   NotificationPanelTester* GetTester();
117 
118  private:
119   friend class NotificationPanelTester;
120 
121   void Init();
122 
123   // Unregister the panel's state change notification.
124   void UnregisterNotification();
125 
126   // Update the Panel Size according to its state.
127   void UpdatePanel(bool update_panel_size);
128 
129   // Scroll the panel so that the |balloon| is visible.
130   void ScrollBalloonToVisible(Balloon* balloon);
131 
132   // Update the container's bounds so that it can show all notifications.
133   void UpdateContainerBounds();
134 
135   // Update the notification's control view state.
136   void UpdateControl();
137 
138   // Returns the panel's preferred bounds in the screen's coordinates.
139   // The position will be controlled by window manager so
140   // the origin is always (0, 0).
141   gfx::Rect GetPreferredBounds();
142 
143   // Returns the bounds that covers sticky and new notifications.
144   gfx::Rect GetStickyNewBounds();
145 
146   void StartStaleTimer(Balloon* balloon);
147 
148   // A callback function that is called when the notification
149   // (that the view is associated with) becomes stale after a timeout.
150   void OnStale(BalloonViewImpl* view);
151 
152   // Set the state. It can also print the
153   void SetState(State, const char* method_name);
154 
155   // Mark the given notification as stale.
156   void MarkStale(const Notification& notification);
157 
158   // Contains all notifications. This is owned by the panel so that we can
159   // re-attach to the widget when closing and opening the panel.
160   scoped_ptr<BalloonContainer> balloon_container_;
161 
162   // The notification panel's widget.
163   views::Widget* panel_widget_;
164 
165   // The notification panel's widget.
166   views::Widget* container_host_;
167 
168   // Panel controller for the notification panel.
169   // This is owned by the panel to compute the panel size before
170   // actually opening the panel.
171   scoped_ptr<PanelController> panel_controller_;
172 
173   // A scrollable parent of the BalloonContainer.
174   scoped_ptr<views::ScrollView> scroll_view_;
175 
176   // Panel's state.
177   State state_;
178 
179   ScopedRunnableMethodFactory<NotificationPanel> task_factory_;
180 
181   // The minimum size of a notification.
182   gfx::Rect min_bounds_;
183 
184   // Stale timeout.
185   int stale_timeout_;
186 
187   // A registrar to subscribe PANEL_STATE_CHANGED event.
188   NotificationRegistrar registrar_;
189 
190   // The notification a mouse pointer is currently on. NULL if the mouse
191   // is out of the panel.
192   BalloonViewImpl* active_;
193 
194   // A balloon that should be visible when it gets some size.
195   Balloon* scroll_to_;
196 
197   // An object that provides interfacce for tests.
198   scoped_ptr<NotificationPanelTester> tester_;
199 
200   DISALLOW_COPY_AND_ASSIGN(NotificationPanel);
201 };
202 
203 class NotificationPanelTester {
204  public:
NotificationPanelTester(NotificationPanel * panel)205   explicit NotificationPanelTester(NotificationPanel* panel)
206       : panel_(panel) {
207   }
208 
state()209   NotificationPanel::State state() {
210     return panel_->state_;
211   }
212 
213   // Returns number of of sticky and new notifications.
214   int GetNotificationCount() const;
215 
216   // Returns number of new notifications.
217   int GetNewNotificationCount() const;
218 
219   // Returns number of of sticky notifications.
220   int GetStickyNotificationCount() const;
221 
222   // Sets the timeout for a notification to become stale.
223   void SetStaleTimeout(int timeout);
224 
225   // Mark the given notification as stale.
226   void MarkStale(const Notification& notification);
227 
228   // Returns the notification panel's PanelController.
229   PanelController* GetPanelController() const;
230 
231   // Returns the BalloonView object of the notification.
232   BalloonViewImpl* GetBalloonView(BalloonCollectionImpl* collection,
233                                   const Notification& notification);
234 
235   // True if the view is in visible in the ScrollView.
236   bool IsVisible(const BalloonViewImpl* view) const;
237 
238   // True if the view is currently active.
239   bool IsActive(const BalloonViewImpl* view) const;
240 
241  private:
242   NotificationPanel* panel_;
243   DISALLOW_COPY_AND_ASSIGN(NotificationPanelTester);
244 };
245 
246 }  // namespace chromeos
247 
248 #endif  // CHROME_BROWSER_CHROMEOS_NOTIFICATIONS_NOTIFICATION_PANEL_H_
249