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