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