Home | History | Annotate | Download | only in notifications
      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:
    205   explicit NotificationPanelTester(NotificationPanel* panel)
    206       : panel_(panel) {
    207   }
    208 
    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