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