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
18namespace ui {
19class LocatedEvent;
20}
21
22namespace views {
23class View;
24class Widget;
25}
26
27namespace views {
28
29namespace internal {
30class TrayBubbleBorder;
31class TrayBubbleContentMask;
32}
33
34class 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
59    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.
142  void reset_delegate() { delegate_ = NULL; }
143
144  Delegate* delegate() { return delegate_; }
145
146  void set_gesture_dragging(bool dragging) { is_gesture_dragging_ = 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