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