1 // Copyright (c) 2012 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 UI_VIEWS_BUBBLE_BUBBLE_DELEGATE_H_ 6 #define UI_VIEWS_BUBBLE_BUBBLE_DELEGATE_H_ 7 8 #include "base/gtest_prod_util.h" 9 #include "ui/views/bubble/bubble_border.h" 10 #include "ui/views/widget/widget.h" 11 #include "ui/views/widget/widget_delegate.h" 12 #include "ui/views/widget/widget_observer.h" 13 14 namespace gfx { 15 class FontList; 16 class Rect; 17 } 18 19 namespace views { 20 21 class BubbleFrameView; 22 23 // BubbleDelegateView creates frame and client views for bubble Widgets. 24 // BubbleDelegateView itself is the client's contents view. 25 class VIEWS_EXPORT BubbleDelegateView : public WidgetDelegateView, 26 public WidgetObserver { 27 public: 28 BubbleDelegateView(); 29 BubbleDelegateView(View* anchor_view, BubbleBorder::Arrow arrow); 30 virtual ~BubbleDelegateView(); 31 32 // Create and initialize the bubble Widget(s) with proper bounds. 33 static Widget* CreateBubble(BubbleDelegateView* bubble_delegate); 34 35 // WidgetDelegateView overrides: 36 virtual BubbleDelegateView* AsBubbleDelegate() OVERRIDE; 37 virtual bool ShouldShowCloseButton() const OVERRIDE; 38 virtual View* GetContentsView() OVERRIDE; 39 virtual NonClientFrameView* CreateNonClientFrameView(Widget* widget) OVERRIDE; 40 virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE; 41 42 // WidgetObserver overrides: 43 virtual void OnWidgetDestroying(Widget* widget) OVERRIDE; 44 virtual void OnWidgetVisibilityChanging(Widget* widget, bool visible) 45 OVERRIDE; 46 virtual void OnWidgetVisibilityChanged(Widget* widget, bool visible) 47 OVERRIDE; 48 virtual void OnWidgetActivationChanged(Widget* widget, bool active) OVERRIDE; 49 virtual void OnWidgetBoundsChanged(Widget* widget, 50 const gfx::Rect& new_bounds) OVERRIDE; 51 close_on_esc()52 bool close_on_esc() const { return close_on_esc_; } set_close_on_esc(bool close_on_esc)53 void set_close_on_esc(bool close_on_esc) { close_on_esc_ = close_on_esc; } 54 close_on_deactivate()55 bool close_on_deactivate() const { return close_on_deactivate_; } set_close_on_deactivate(bool close)56 void set_close_on_deactivate(bool close) { close_on_deactivate_ = close; } 57 58 View* GetAnchorView() const; anchor_widget()59 Widget* anchor_widget() const { return anchor_widget_; } 60 61 // The anchor rect is used in the absence of an assigned anchor view. anchor_rect()62 const gfx::Rect& anchor_rect() const { return anchor_rect_; } 63 arrow()64 BubbleBorder::Arrow arrow() const { return arrow_; } set_arrow(BubbleBorder::Arrow arrow)65 void set_arrow(BubbleBorder::Arrow arrow) { arrow_ = arrow; } 66 shadow()67 BubbleBorder::Shadow shadow() const { return shadow_; } set_shadow(BubbleBorder::Shadow shadow)68 void set_shadow(BubbleBorder::Shadow shadow) { shadow_ = shadow; } 69 color()70 SkColor color() const { return color_; } set_color(SkColor color)71 void set_color(SkColor color) { 72 color_ = color; 73 color_explicitly_set_ = true; 74 } 75 margins()76 const gfx::Insets& margins() const { return margins_; } set_margins(const gfx::Insets & margins)77 void set_margins(const gfx::Insets& margins) { margins_ = margins; } 78 anchor_view_insets()79 const gfx::Insets& anchor_view_insets() const { return anchor_view_insets_; } set_anchor_view_insets(const gfx::Insets & i)80 void set_anchor_view_insets(const gfx::Insets& i) { anchor_view_insets_ = i; } 81 parent_window()82 gfx::NativeView parent_window() const { return parent_window_; } set_parent_window(gfx::NativeView window)83 void set_parent_window(gfx::NativeView window) { parent_window_ = window; } 84 accept_events()85 bool accept_events() const { return accept_events_; } set_accept_events(bool accept_events)86 void set_accept_events(bool accept_events) { accept_events_ = accept_events; } 87 border_accepts_events()88 bool border_accepts_events() const { return border_accepts_events_; } set_border_accepts_events(bool event)89 void set_border_accepts_events(bool event) { border_accepts_events_ = event; } 90 adjust_if_offscreen()91 bool adjust_if_offscreen() const { return adjust_if_offscreen_; } set_adjust_if_offscreen(bool adjust)92 void set_adjust_if_offscreen(bool adjust) { adjust_if_offscreen_ = adjust; } 93 94 // Get the arrow's anchor rect in screen space. 95 virtual gfx::Rect GetAnchorRect() const; 96 97 // Allows delegates to provide custom parameters before widget initialization. 98 virtual void OnBeforeBubbleWidgetInit(Widget::InitParams* params, 99 Widget* widget) const; 100 101 // Sets the bubble alignment relative to the anchor. This may only be called 102 // after calling CreateBubble. 103 void SetAlignment(BubbleBorder::BubbleAlignment alignment); 104 105 // Sets the bubble arrow paint type. 106 void SetArrowPaintType(BubbleBorder::ArrowPaintType paint_type); 107 108 // Call this method when the anchor bounds have changed to reposition the 109 // bubble. The bubble is automatically repositioned when the anchor view 110 // bounds change as a result of the widget's bounds changing. 111 void OnAnchorBoundsChanged(); 112 113 protected: 114 // Get bubble bounds from the anchor rect and client view's preferred size. 115 virtual gfx::Rect GetBubbleBounds(); 116 117 // Return a FontList to use for the title of the bubble. 118 // (The default is MediumFont). 119 virtual const gfx::FontList& GetTitleFontList() const; 120 121 // View overrides: 122 virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; 123 virtual void OnNativeThemeChanged(const ui::NativeTheme* theme) OVERRIDE; 124 125 // Perform view initialization on the contents for bubble sizing. 126 virtual void Init(); 127 128 // Sets the anchor view or rect and repositions the bubble. Note that if a 129 // valid view gets passed, the anchor rect will get ignored. If the view gets 130 // deleted, but no new view gets set, the last known anchor postion will get 131 // returned. 132 void SetAnchorView(View* anchor_view); 133 void SetAnchorRect(const gfx::Rect& rect); 134 135 // Resize and potentially move the bubble to fit the content's preferred size. 136 void SizeToContents(); 137 138 BubbleFrameView* GetBubbleFrameView() const; 139 140 private: 141 friend class BubbleBorderDelegate; 142 friend class BubbleWindowTargeter; 143 144 FRIEND_TEST_ALL_PREFIXES(BubbleDelegateTest, CreateDelegate); 145 FRIEND_TEST_ALL_PREFIXES(BubbleDelegateTest, NonClientHitTest); 146 147 // Update the bubble color from |theme|, unless it was explicitly set. 148 void UpdateColorsFromTheme(const ui::NativeTheme* theme); 149 150 // Handles widget visibility changes. 151 void HandleVisibilityChanged(Widget* widget, bool visible); 152 153 // Flags controlling bubble closure on the escape key and deactivation. 154 bool close_on_esc_; 155 bool close_on_deactivate_; 156 157 // The view and widget to which this bubble is anchored. Since an anchor view 158 // can be deleted without notice, we store it in the ViewStorage and retrieve 159 // it from there. It will make sure that the view is still valid. 160 const int anchor_view_storage_id_; 161 Widget* anchor_widget_; 162 163 // The anchor rect used in the absence of an anchor view. 164 mutable gfx::Rect anchor_rect_; 165 166 // The arrow's location on the bubble. 167 BubbleBorder::Arrow arrow_; 168 169 // Bubble border shadow to use. 170 BubbleBorder::Shadow shadow_; 171 172 // The background color of the bubble; and flag for when it's explicitly set. 173 SkColor color_; 174 bool color_explicitly_set_; 175 176 // The margins between the content and the inside of the border. 177 gfx::Insets margins_; 178 179 // Insets applied to the |anchor_view_| bounds. 180 gfx::Insets anchor_view_insets_; 181 182 // Specifies whether the bubble (or its border) handles mouse events, etc. 183 bool accept_events_; 184 bool border_accepts_events_; 185 186 // If true (defaults to true), the arrow may be mirrored and moved to fit the 187 // bubble on screen better. It would be a no-op if the bubble has no arrow. 188 bool adjust_if_offscreen_; 189 190 // Parent native window of the bubble. 191 gfx::NativeView parent_window_; 192 193 DISALLOW_COPY_AND_ASSIGN(BubbleDelegateView); 194 }; 195 196 } // namespace views 197 198 #endif // UI_VIEWS_BUBBLE_BUBBLE_DELEGATE_H_ 199