// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_BUBBLE_TRAY_BUBBLE_VIEW_H_
#define UI_VIEWS_BUBBLE_TRAY_BUBBLE_VIEW_H_
#include "base/memory/scoped_ptr.h"
#include "ui/views/bubble/bubble_delegate.h"
#include "ui/views/mouse_watcher.h"
#include "ui/views/views_export.h"
// Specialized bubble view for bubbles associated with a tray icon (e.g. the
// Ash status area). Mostly this handles custom anchor location and arrow and
// border rendering. This also has its own delegate for handling mouse events
// and other implementation specific details.
namespace ui {
class LocatedEvent;
}
namespace views {
class View;
class Widget;
}
namespace views {
namespace internal {
class TrayBubbleBorder;
class TrayBubbleContentMask;
}
class VIEWS_EXPORT TrayBubbleView : public views::BubbleDelegateView,
public views::MouseWatcherListener {
public:
// AnchorType differentiates between bubbles that are anchored on a tray
// element (ANCHOR_TYPE_TRAY) and display an arrow, or that are floating on
// the screen away from the tray (ANCHOR_TYPE_BUBBLE).
enum AnchorType {
ANCHOR_TYPE_TRAY,
ANCHOR_TYPE_BUBBLE,
};
// AnchorAlignment determines to which side of the anchor the bubble will
// align itself.
enum AnchorAlignment {
ANCHOR_ALIGNMENT_BOTTOM,
ANCHOR_ALIGNMENT_LEFT,
ANCHOR_ALIGNMENT_RIGHT,
ANCHOR_ALIGNMENT_TOP
};
class VIEWS_EXPORT Delegate {
public:
typedef TrayBubbleView::AnchorType AnchorType;
typedef TrayBubbleView::AnchorAlignment AnchorAlignment;
Delegate() {}
virtual ~Delegate() {}
// Called when the view is destroyed. Any pointers to the view should be
// cleared when this gets called.
virtual void BubbleViewDestroyed() = 0;
// Called when the mouse enters/exits the view.
// Note: This event will only be called if the mouse gets actively moved by
// the user to enter the view.
virtual void OnMouseEnteredView() = 0;
virtual void OnMouseExitedView() = 0;
// Called from GetAccessibleState(); should return the appropriate
// accessible name for the bubble.
virtual string16 GetAccessibleNameForBubble() = 0;
// Passes responsibility for BubbleDelegateView::GetAnchorRect to the
// delegate.
virtual gfx::Rect GetAnchorRect(views::Widget* anchor_widget,
AnchorType anchor_type,
AnchorAlignment anchor_alignment) = 0;
// Called when a bubble wants to hide/destroy itself (e.g. last visible
// child view was closed).
virtual void HideBubble(const TrayBubbleView* bubble_view) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
struct VIEWS_EXPORT InitParams {
static const int kArrowDefaultOffset;
InitParams(AnchorType anchor_type,
AnchorAlignment anchor_alignment,
int min_width,
int max_width);
AnchorType anchor_type;
AnchorAlignment anchor_alignment;
int min_width;
int max_width;
int max_height;
bool can_activate;
bool close_on_deactivate;
SkColor arrow_color;
bool first_item_has_no_margin;
views::BubbleBorder::Arrow arrow;
int arrow_offset;
views::BubbleBorder::ArrowPaintType arrow_paint_type;
views::BubbleBorder::Shadow shadow;
views::BubbleBorder::BubbleAlignment arrow_alignment;
};
// Constructs and returns a TrayBubbleView. init_params may be modified.
static TrayBubbleView* Create(gfx::NativeView parent_window,
views::View* anchor,
Delegate* delegate,
InitParams* init_params);
virtual ~TrayBubbleView();
// Sets up animations, and show the bubble. Must occur after CreateBubble()
// is called.
void InitializeAndShowBubble();
// Called whenever the bubble size or location may have changed.
void UpdateBubble();
// Sets the maximum bubble height and resizes the bubble.
void SetMaxHeight(int height);
// Sets the bubble width.
void SetWidth(int width);
// Sets whether or not to paint the bubble border arrow.
void SetArrowPaintType(views::BubbleBorder::ArrowPaintType arrow_paint_type);
// Returns the border insets. Called by TrayEventFilter.
gfx::Insets GetBorderInsets() const;
// Called when the delegate is destroyed.
void reset_delegate() { delegate_ = NULL; }
Delegate* delegate() { return delegate_; }
void set_gesture_dragging(bool dragging) { is_gesture_dragging_ = dragging; }
bool is_gesture_dragging() const { return is_gesture_dragging_; }
// Overridden from views::WidgetDelegate.
virtual bool CanActivate() const OVERRIDE;
virtual views::NonClientFrameView* CreateNonClientFrameView(
views::Widget* widget) OVERRIDE;
virtual bool WidgetHasHitTestMask() const OVERRIDE;
virtual void GetWidgetHitTestMask(gfx::Path* mask) const OVERRIDE;
// Overridden from views::BubbleDelegateView.
virtual gfx::Rect GetAnchorRect() OVERRIDE;
// Overridden from views::View.
virtual gfx::Size GetPreferredSize() OVERRIDE;
virtual gfx::Size GetMaximumSize() OVERRIDE;
virtual int GetHeightForWidth(int width) OVERRIDE;
virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
// Overridden from MouseWatcherListener
virtual void MouseMovedOutOfHost() OVERRIDE;
protected:
TrayBubbleView(gfx::NativeView parent_window,
views::View* anchor,
Delegate* delegate,
const InitParams& init_params);
// Overridden from views::BubbleDelegateView.
virtual void Init() OVERRIDE;
// Overridden from views::View.
virtual void ChildPreferredSizeChanged(View* child) OVERRIDE;
virtual void ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) OVERRIDE;
private:
InitParams params_;
Delegate* delegate_;
int preferred_width_;
internal::TrayBubbleBorder* bubble_border_;
scoped_ptr<internal::TrayBubbleContentMask> bubble_content_mask_;
bool is_gesture_dragging_;
// True once the mouse cursor was actively moved by the user over the bubble.
// Only then the OnMouseExitedView() event will get passed on to listeners.
bool mouse_actively_entered_;
// Used to find any mouse movements.
scoped_ptr<MouseWatcher> mouse_watcher_;
DISALLOW_COPY_AND_ASSIGN(TrayBubbleView);
};
} // namespace views
#endif // UI_VIEWS_BUBBLE_TRAY_BUBBLE_VIEW_H_