• 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 #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.
set_fade_away_on_close(bool fade_away_on_close)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