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_TRAY_BUBBLE_VIEW_H_ 6 #define UI_VIEWS_BUBBLE_TRAY_BUBBLE_VIEW_H_ 7 8 #include "base/memory/scoped_ptr.h" 9 #include "ui/views/bubble/bubble_delegate.h" 10 #include "ui/views/mouse_watcher.h" 11 #include "ui/views/views_export.h" 12 13 // Specialized bubble view for bubbles associated with a tray icon (e.g. the 14 // Ash status area). Mostly this handles custom anchor location and arrow and 15 // border rendering. This also has its own delegate for handling mouse events 16 // and other implementation specific details. 17 18 namespace ui { 19 class LocatedEvent; 20 } 21 22 namespace views { 23 class View; 24 class Widget; 25 } 26 27 namespace views { 28 29 namespace internal { 30 class TrayBubbleBorder; 31 class TrayBubbleContentMask; 32 } 33 34 class VIEWS_EXPORT TrayBubbleView : public views::BubbleDelegateView, 35 public views::MouseWatcherListener { 36 public: 37 // AnchorType differentiates between bubbles that are anchored on a tray 38 // element (ANCHOR_TYPE_TRAY) and display an arrow, or that are floating on 39 // the screen away from the tray (ANCHOR_TYPE_BUBBLE). 40 enum AnchorType { 41 ANCHOR_TYPE_TRAY, 42 ANCHOR_TYPE_BUBBLE, 43 }; 44 45 // AnchorAlignment determines to which side of the anchor the bubble will 46 // align itself. 47 enum AnchorAlignment { 48 ANCHOR_ALIGNMENT_BOTTOM, 49 ANCHOR_ALIGNMENT_LEFT, 50 ANCHOR_ALIGNMENT_RIGHT, 51 ANCHOR_ALIGNMENT_TOP 52 }; 53 54 class VIEWS_EXPORT Delegate { 55 public: 56 typedef TrayBubbleView::AnchorType AnchorType; 57 typedef TrayBubbleView::AnchorAlignment AnchorAlignment; 58 Delegate()59 Delegate() {} ~Delegate()60 virtual ~Delegate() {} 61 62 // Called when the view is destroyed. Any pointers to the view should be 63 // cleared when this gets called. 64 virtual void BubbleViewDestroyed() = 0; 65 66 // Called when the mouse enters/exits the view. 67 // Note: This event will only be called if the mouse gets actively moved by 68 // the user to enter the view. 69 virtual void OnMouseEnteredView() = 0; 70 virtual void OnMouseExitedView() = 0; 71 72 // Called from GetAccessibleState(); should return the appropriate 73 // accessible name for the bubble. 74 virtual base::string16 GetAccessibleNameForBubble() = 0; 75 76 // Passes responsibility for BubbleDelegateView::GetAnchorRect to the 77 // delegate. 78 virtual gfx::Rect GetAnchorRect( 79 views::Widget* anchor_widget, 80 AnchorType anchor_type, 81 AnchorAlignment anchor_alignment) const = 0; 82 83 // Called when a bubble wants to hide/destroy itself (e.g. last visible 84 // child view was closed). 85 virtual void HideBubble(const TrayBubbleView* bubble_view) = 0; 86 87 private: 88 DISALLOW_COPY_AND_ASSIGN(Delegate); 89 }; 90 91 struct VIEWS_EXPORT InitParams { 92 static const int kArrowDefaultOffset; 93 94 InitParams(AnchorType anchor_type, 95 AnchorAlignment anchor_alignment, 96 int min_width, 97 int max_width); 98 AnchorType anchor_type; 99 AnchorAlignment anchor_alignment; 100 int min_width; 101 int max_width; 102 int max_height; 103 bool can_activate; 104 bool close_on_deactivate; 105 SkColor arrow_color; 106 bool first_item_has_no_margin; 107 views::BubbleBorder::Arrow arrow; 108 int arrow_offset; 109 views::BubbleBorder::ArrowPaintType arrow_paint_type; 110 views::BubbleBorder::Shadow shadow; 111 views::BubbleBorder::BubbleAlignment arrow_alignment; 112 }; 113 114 // Constructs and returns a TrayBubbleView. init_params may be modified. 115 static TrayBubbleView* Create(gfx::NativeView parent_window, 116 views::View* anchor, 117 Delegate* delegate, 118 InitParams* init_params); 119 120 virtual ~TrayBubbleView(); 121 122 // Sets up animations, and show the bubble. Must occur after CreateBubble() 123 // is called. 124 void InitializeAndShowBubble(); 125 126 // Called whenever the bubble size or location may have changed. 127 void UpdateBubble(); 128 129 // Sets the maximum bubble height and resizes the bubble. 130 void SetMaxHeight(int height); 131 132 // Sets the bubble width. 133 void SetWidth(int width); 134 135 // Sets whether or not to paint the bubble border arrow. 136 void SetArrowPaintType(views::BubbleBorder::ArrowPaintType arrow_paint_type); 137 138 // Returns the border insets. Called by TrayEventFilter. 139 gfx::Insets GetBorderInsets() const; 140 141 // Called when the delegate is destroyed. reset_delegate()142 void reset_delegate() { delegate_ = NULL; } 143 delegate()144 Delegate* delegate() { return delegate_; } 145 set_gesture_dragging(bool dragging)146 void set_gesture_dragging(bool dragging) { is_gesture_dragging_ = dragging; } is_gesture_dragging()147 bool is_gesture_dragging() const { return is_gesture_dragging_; } 148 149 // Overridden from views::WidgetDelegate. 150 virtual bool CanActivate() const OVERRIDE; 151 virtual views::NonClientFrameView* CreateNonClientFrameView( 152 views::Widget* widget) OVERRIDE; 153 virtual bool WidgetHasHitTestMask() const OVERRIDE; 154 virtual void GetWidgetHitTestMask(gfx::Path* mask) const OVERRIDE; 155 156 // Overridden from views::BubbleDelegateView. 157 virtual gfx::Rect GetAnchorRect() const OVERRIDE; 158 159 // Overridden from views::View. 160 virtual gfx::Size GetPreferredSize() const OVERRIDE; 161 virtual gfx::Size GetMaximumSize() const OVERRIDE; 162 virtual int GetHeightForWidth(int width) const OVERRIDE; 163 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; 164 virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; 165 virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE; 166 167 // Overridden from MouseWatcherListener 168 virtual void MouseMovedOutOfHost() OVERRIDE; 169 170 protected: 171 TrayBubbleView(gfx::NativeView parent_window, 172 views::View* anchor, 173 Delegate* delegate, 174 const InitParams& init_params); 175 176 // Overridden from views::BubbleDelegateView. 177 virtual void Init() OVERRIDE; 178 179 // Overridden from views::View. 180 virtual void ChildPreferredSizeChanged(View* child) OVERRIDE; 181 virtual void ViewHierarchyChanged( 182 const ViewHierarchyChangedDetails& details) OVERRIDE; 183 184 private: 185 InitParams params_; 186 Delegate* delegate_; 187 int preferred_width_; 188 internal::TrayBubbleBorder* bubble_border_; 189 scoped_ptr<internal::TrayBubbleContentMask> bubble_content_mask_; 190 bool is_gesture_dragging_; 191 192 // True once the mouse cursor was actively moved by the user over the bubble. 193 // Only then the OnMouseExitedView() event will get passed on to listeners. 194 bool mouse_actively_entered_; 195 196 // Used to find any mouse movements. 197 scoped_ptr<MouseWatcher> mouse_watcher_; 198 199 DISALLOW_COPY_AND_ASSIGN(TrayBubbleView); 200 }; 201 202 } // namespace views 203 204 #endif // UI_VIEWS_BUBBLE_TRAY_BUBBLE_VIEW_H_ 205