Home | History | Annotate | Download | only in bubble
      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 #ifndef CHROME_BROWSER_UI_VIEWS_BUBBLE_BUBBLE_H_
      6 #define CHROME_BROWSER_UI_VIEWS_BUBBLE_BUBBLE_H_
      7 #pragma once
      8 
      9 #include "chrome/browser/ui/views/bubble/bubble_border.h"
     10 #include "ui/base/animation/animation_delegate.h"
     11 #include "views/accelerator.h"
     12 #include "views/view.h"
     13 
     14 #if defined(OS_WIN)
     15 #include "views/widget/widget_win.h"
     16 #elif defined(OS_LINUX)
     17 #include "views/widget/widget_gtk.h"
     18 #endif
     19 
     20 // Bubble is used to display an arbitrary view above all other windows.
     21 // Think of Bubble as a tooltip that allows you to embed an arbitrary view
     22 // in the tooltip. Additionally the Bubble renders an arrow pointing at
     23 // the region the info bubble is providing the information about.
     24 //
     25 // To use an Bubble, invoke Show() and it'll take care of the rest.  The Bubble
     26 // insets the contents for you, so the contents typically shouldn't have any
     27 // additional margins.
     28 
     29 class BorderContents;
     30 #if defined(OS_WIN)
     31 class BorderWidgetWin;
     32 #endif
     33 class Bubble;
     34 
     35 namespace gfx {
     36 class Path;
     37 }
     38 
     39 namespace ui {
     40 class SlideAnimation;
     41 }
     42 
     43 namespace views {
     44 class Widget;
     45 }
     46 
     47 class BubbleDelegate {
     48  public:
     49   // Called when the Bubble is closing and is about to be deleted.
     50   // |closed_by_escape| is true if the close is the result of the user pressing
     51   // escape.
     52   virtual void BubbleClosing(Bubble* bubble, bool closed_by_escape) = 0;
     53 
     54   // Whether the Bubble should be closed when the Esc key is pressed.
     55   virtual bool CloseOnEscape() = 0;
     56 
     57   // Whether the Bubble should fade in when opening. When trying to determine
     58   // whether to use FadeIn, consider whether the bubble is shown as a direct
     59   // result of a user action or not. For example, if the bubble is being shown
     60   // as a direct result of a mouse-click, we should not use FadeIn. However, if
     61   // the bubble appears as a notification that something happened in the
     62   // background, we use FadeIn.
     63   virtual bool FadeInOnShow() = 0;
     64 
     65   // The name of the window to which this delegate belongs.
     66   virtual std::wstring accessible_name();
     67 };
     68 
     69 // TODO(sky): this code is ifdef-tastic. It might be cleaner to refactor the
     70 // WidgetFoo subclass into a separate class that calls into Bubble.
     71 // That way Bubble has no (or very few) ifdefs.
     72 class Bubble
     73 #if defined(OS_WIN)
     74     : public views::WidgetWin,
     75 #elif defined(OS_LINUX)
     76     : public views::WidgetGtk,
     77 #endif
     78       public views::AcceleratorTarget,
     79       public ui::AnimationDelegate {
     80  public:
     81   // Shows the Bubble.
     82   // |parent| is set as the parent window.
     83   // |contents| are the contents shown in the bubble.
     84   // |position_relative_to| is a rect in screen coordinates at which the Bubble
     85   // will point.
     86   // Show() takes ownership of |contents| and deletes the created Bubble when
     87   // another window is activated. You can explicitly close the bubble by
     88   // invoking Close().
     89   // |arrow_location| specifies preferred bubble alignment.
     90   // You may provide an optional |delegate| to:
     91   //     - Be notified when the Bubble is closed.
     92   //     - Prevent the Bubble from being closed when the Escape key is
     93   //       pressed (the default behavior).
     94   static Bubble* Show(views::Widget* parent,
     95                       const gfx::Rect& position_relative_to,
     96                       BubbleBorder::ArrowLocation arrow_location,
     97                       views::View* contents,
     98                       BubbleDelegate* delegate);
     99 
    100 #if defined(OS_CHROMEOS)
    101   // Shows the Bubble without grabbing the focus. Others are the same as
    102   // above.  TYPE_POPUP widget is used to achieve the focusless effect.
    103   // If |show_while_screen_is_locked| is true, a property is set telling the
    104   // window manager to continue showing the bubble even while the screen is
    105   // locked.
    106   static Bubble* ShowFocusless(views::Widget* parent,
    107                                const gfx::Rect& position_relative_to,
    108                                BubbleBorder::ArrowLocation arrow_location,
    109                                views::View* contents,
    110                                BubbleDelegate* delegate,
    111                                bool show_while_screen_is_locked);
    112 #endif
    113 
    114   // Resizes and potentially moves the Bubble to best accommodate the
    115   // contents preferred size.
    116   void SizeToContents();
    117 
    118   // Whether the Bubble should fade away when it closes. Generally speaking,
    119   // we use FadeOut when the user selects something within the bubble that
    120   // causes the bubble to dismiss. We don't use it when the bubble gets
    121   // deactivated as a result of clicking outside the bubble.
    122   void set_fade_away_on_close(bool fade_away_on_close) {
    123     fade_away_on_close_ = fade_away_on_close;
    124   }
    125 
    126   // Overridden from WidgetWin:
    127   virtual void Close();
    128 
    129   // Overridden from ui::AnimationDelegate:
    130   virtual void AnimationEnded(const ui::Animation* animation);
    131   virtual void AnimationProgressed(const ui::Animation* animation);
    132 
    133   static const SkColor kBackgroundColor;
    134 
    135  protected:
    136   Bubble();
    137 #if defined(OS_CHROMEOS)
    138   Bubble(views::WidgetGtk::Type type, bool show_while_screen_is_locked);
    139 #endif
    140   virtual ~Bubble();
    141 
    142   // Creates the Bubble.
    143   virtual void InitBubble(views::Widget* parent,
    144                           const gfx::Rect& position_relative_to,
    145                           BubbleBorder::ArrowLocation arrow_location,
    146                           views::View* contents,
    147                           BubbleDelegate* delegate);
    148 
    149   // Instantiates and returns the BorderContents this Bubble should use.
    150   // Subclasses can return their own BorderContents implementation.
    151   virtual BorderContents* CreateBorderContents();
    152 
    153 #if defined(OS_WIN)
    154   // Overridden from WidgetWin:
    155   virtual void OnActivate(UINT action, BOOL minimized, HWND window);
    156 #elif defined(OS_LINUX)
    157   // Overridden from WidgetGtk:
    158   virtual void IsActiveChanged();
    159 #endif
    160 
    161 #if defined(OS_WIN)
    162   // The window used to render the padding, border and arrow.
    163   BorderWidgetWin* border_;
    164 #elif defined(OS_LINUX)
    165   // The view displaying the border.
    166   BorderContents* border_contents_;
    167 #endif
    168 
    169  private:
    170   enum ShowStatus {
    171     kOpen,
    172     kClosing,
    173     kClosed
    174   };
    175 
    176   // Closes the window notifying the delegate. |closed_by_escape| is true if
    177   // the close is the result of pressing escape.
    178   void DoClose(bool closed_by_escape);
    179 
    180   // Animates to a visible state.
    181   void FadeIn();
    182   // Animates to a hidden state.
    183   void FadeOut();
    184 
    185   // Animates to a visible/hidden state (visible if |fade_in| is true).
    186   void Fade(bool fade_in);
    187 
    188   // Overridden from AcceleratorTarget:
    189   virtual bool AcceleratorPressed(const views::Accelerator& accelerator);
    190 
    191   // The delegate, if any.
    192   BubbleDelegate* delegate_;
    193 
    194   // The animation used to fade the bubble out.
    195   scoped_ptr<ui::SlideAnimation> animation_;
    196 
    197   // The current visibility status of the bubble.
    198   ShowStatus show_status_;
    199 
    200   // Whether to fade away when the bubble closes.
    201   bool fade_away_on_close_;
    202 
    203 #if defined(OS_CHROMEOS)
    204   // Should we set a property telling the window manager to show this window
    205   // onscreen even when the screen is locked?
    206   bool show_while_screen_is_locked_;
    207 #endif
    208 
    209   gfx::Rect position_relative_to_;
    210   BubbleBorder::ArrowLocation arrow_location_;
    211 
    212   views::View* contents_;
    213 
    214   DISALLOW_COPY_AND_ASSIGN(Bubble);
    215 };
    216 
    217 #endif  // CHROME_BROWSER_UI_VIEWS_BUBBLE_BUBBLE_H_
    218