Moves TrayBubbleView out of ash namespace
Creates TrayEventFilter and TrayBubbleWrapper. BUG=150872 For ash.gyp: TBR=ben@chromium.org Review URL: https://codereview.chromium.org/11028134 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161888 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@ -204,12 +204,16 @@
|
||||
'system/tray/tray_background_view.h',
|
||||
'system/tray/tray_bubble_view.cc',
|
||||
'system/tray/tray_bubble_view.h',
|
||||
'system/tray/tray_bubble_wrapper.cc',
|
||||
'system/tray/tray_bubble_wrapper.h',
|
||||
'system/tray/tray_constants.cc',
|
||||
'system/tray/tray_constants.h',
|
||||
'system/tray/tray_details_view.cc',
|
||||
'system/tray/tray_details_view.h',
|
||||
'system/tray/tray_empty.cc',
|
||||
'system/tray/tray_empty.h',
|
||||
'system/tray/tray_event_filter.cc',
|
||||
'system/tray/tray_event_filter.h',
|
||||
'system/tray/tray_image_item.cc',
|
||||
'system/tray/tray_image_item.h',
|
||||
'system/tray/tray_item_more.cc',
|
||||
|
@ -54,7 +54,6 @@ namespace ash {
|
||||
// SystemTray
|
||||
|
||||
using internal::SystemTrayBubble;
|
||||
using internal::TrayBubbleView;
|
||||
|
||||
SystemTray::SystemTray(internal::StatusAreaWidget* status_area_widget)
|
||||
: internal::TrayBackgroundView(status_area_widget),
|
||||
@ -270,18 +269,6 @@ void SystemTray::DestroyNotificationBubble() {
|
||||
status_area_widget()->SetHideWebNotifications(false);
|
||||
}
|
||||
|
||||
void SystemTray::RemoveBubble(SystemTrayBubble* bubble) {
|
||||
if (bubble == bubble_.get()) {
|
||||
DestroyBubble();
|
||||
UpdateNotificationBubble(); // State changed, re-create notifications.
|
||||
Shell::GetInstance()->shelf()->UpdateAutoHideState();
|
||||
} else if (bubble == notification_bubble_) {
|
||||
DestroyNotificationBubble();
|
||||
} else {
|
||||
NOTREACHED();
|
||||
}
|
||||
}
|
||||
|
||||
int SystemTray::GetTrayXOffset(SystemTrayItem* item) const {
|
||||
// Don't attempt to align the arrow if the shelf is on the left or right.
|
||||
if (shelf_alignment() != SHELF_ALIGNMENT_BOTTOM)
|
||||
@ -331,7 +318,8 @@ void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items,
|
||||
ash::Shell::GetInstance()->tray_delegate();
|
||||
views::View* anchor = tray_container();
|
||||
TrayBubbleView::InitParams init_params(TrayBubbleView::ANCHOR_TYPE_TRAY,
|
||||
shelf_alignment());
|
||||
GetAnchorAlignment(),
|
||||
kTrayPopupWidth);
|
||||
init_params.can_activate = can_activate;
|
||||
if (detailed) {
|
||||
// This is the case where a volume control or brightness control bubble
|
||||
@ -344,7 +332,7 @@ void SystemTray::ShowItems(const std::vector<SystemTrayItem*>& items,
|
||||
init_params.arrow_color = kHeaderBackgroundColorDark;
|
||||
}
|
||||
init_params.arrow_offset = arrow_offset;
|
||||
bubble_->InitView(anchor, init_params, delegate->GetUserLoginStatus());
|
||||
bubble_->InitView(anchor, delegate->GetUserLoginStatus(), &init_params);
|
||||
}
|
||||
// Save height of default view for creating detailed views directly.
|
||||
if (!detailed)
|
||||
@ -399,13 +387,15 @@ void SystemTray::UpdateNotificationBubble() {
|
||||
anchor = tray_container();
|
||||
anchor_type = TrayBubbleView::ANCHOR_TYPE_TRAY;
|
||||
}
|
||||
TrayBubbleView::InitParams init_params(anchor_type, shelf_alignment());
|
||||
TrayBubbleView::InitParams init_params(anchor_type,
|
||||
GetAnchorAlignment(),
|
||||
kTrayPopupWidth);
|
||||
init_params.top_color = kBackgroundColor;
|
||||
init_params.arrow_color = kBackgroundColor;
|
||||
init_params.arrow_offset = GetTrayXOffset(notification_items_[0]);
|
||||
user::LoginStatus login_status =
|
||||
Shell::GetInstance()->tray_delegate()->GetUserLoginStatus();
|
||||
notification_bubble_->InitView(anchor, init_params, login_status);
|
||||
notification_bubble_->InitView(anchor, login_status, &init_params);
|
||||
if (notification_bubble_->bubble_view()->child_count() == 0) {
|
||||
// It is possible that none of the items generated actual notifications.
|
||||
DestroyNotificationBubble();
|
||||
@ -450,6 +440,26 @@ string16 SystemTray::GetAccessibleName() {
|
||||
return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_ACCESSIBLE_NAME);
|
||||
}
|
||||
|
||||
void SystemTray::HideBubbleWithView(const TrayBubbleView* bubble_view) {
|
||||
if (bubble_.get() && bubble_view == bubble_->bubble_view()) {
|
||||
DestroyBubble();
|
||||
UpdateNotificationBubble(); // State changed, re-create notifications.
|
||||
Shell::GetInstance()->shelf()->UpdateAutoHideState();
|
||||
} else if (notification_bubble_.get() &&
|
||||
bubble_view == notification_bubble_->bubble_view()) {
|
||||
DestroyNotificationBubble();
|
||||
}
|
||||
}
|
||||
|
||||
bool SystemTray::ClickedOutsideBubble() {
|
||||
if (!bubble_.get() ||
|
||||
bubble_->bubble_type() == SystemTrayBubble::BUBBLE_TYPE_NOTIFICATION) {
|
||||
return false;
|
||||
}
|
||||
HideBubbleWithView(bubble_->bubble_view());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemTray::PerformAction(const ui::Event& event) {
|
||||
// If we're already showing the default view, hide it; otherwise, show it
|
||||
// (and hide any popup that's currently shown).
|
||||
|
@ -159,6 +159,8 @@ class ASH_EXPORT SystemTray : public internal::TrayBackgroundView {
|
||||
virtual void SetShelfAlignment(ShelfAlignment alignment) OVERRIDE;
|
||||
virtual void AnchorUpdated() OVERRIDE;
|
||||
virtual string16 GetAccessibleName() OVERRIDE;
|
||||
virtual void HideBubbleWithView(const TrayBubbleView* bubble_view) OVERRIDE;
|
||||
virtual bool ClickedOutsideBubble() OVERRIDE;
|
||||
|
||||
private:
|
||||
friend class internal::SystemTrayBubble;
|
||||
@ -170,11 +172,6 @@ class ASH_EXPORT SystemTray : public internal::TrayBackgroundView {
|
||||
// Resets |notification_bubble_| and clears any related state.
|
||||
void DestroyNotificationBubble();
|
||||
|
||||
// Called when the widget associated with |bubble| closes. |bubble| should
|
||||
// always == |bubble_|. This triggers destroying |bubble_| and hiding the
|
||||
// launcher if necessary.
|
||||
void RemoveBubble(internal::SystemTrayBubble* bubble);
|
||||
|
||||
const ScopedVector<SystemTrayItem>& items() const { return items_; }
|
||||
|
||||
// Calculates the x-offset for the item in the tray. Returns -1 if its tray
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "ash/system/tray/system_tray.h"
|
||||
#include "ash/system/tray/system_tray_delegate.h"
|
||||
#include "ash/system/tray/system_tray_item.h"
|
||||
#include "ash/system/tray/tray_bubble_wrapper.h"
|
||||
#include "ash/system/tray/tray_constants.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "ui/aura/window.h"
|
||||
@ -126,7 +127,6 @@ SystemTrayBubble::SystemTrayBubble(
|
||||
BubbleType bubble_type)
|
||||
: tray_(tray),
|
||||
bubble_view_(NULL),
|
||||
bubble_widget_(NULL),
|
||||
items_(items),
|
||||
bubble_type_(bubble_type),
|
||||
autoclose_delay_(0) {
|
||||
@ -136,12 +136,7 @@ SystemTrayBubble::~SystemTrayBubble() {
|
||||
DestroyItemViews();
|
||||
// Reset the host pointer in bubble_view_ in case its destruction is deferred.
|
||||
if (bubble_view_)
|
||||
bubble_view_->reset_host();
|
||||
if (bubble_widget_) {
|
||||
bubble_widget_->RemoveObserver(this);
|
||||
// This triggers the destruction of bubble_view_.
|
||||
bubble_widget_->Close();
|
||||
}
|
||||
bubble_view_->reset_delegate();
|
||||
}
|
||||
|
||||
void SystemTrayBubble::UpdateView(
|
||||
@ -209,7 +204,7 @@ void SystemTrayBubble::UpdateView(
|
||||
return;
|
||||
}
|
||||
|
||||
bubble_widget_->GetContentsView()->Layout();
|
||||
bubble_view_->GetWidget()->GetContentsView()->Layout();
|
||||
// Make sure that the bubble is large enough for the default view.
|
||||
if (bubble_type_ == BUBBLE_TYPE_DEFAULT) {
|
||||
bubble_view_->SetMaxHeight(0); // Clear max height limit.
|
||||
@ -234,25 +229,22 @@ void SystemTrayBubble::UpdateView(
|
||||
}
|
||||
|
||||
void SystemTrayBubble::InitView(views::View* anchor,
|
||||
TrayBubbleView::InitParams init_params,
|
||||
user::LoginStatus login_status) {
|
||||
user::LoginStatus login_status,
|
||||
TrayBubbleView::InitParams* init_params) {
|
||||
DCHECK(bubble_view_ == NULL);
|
||||
|
||||
if (bubble_type_ == BUBBLE_TYPE_DETAILED &&
|
||||
init_params.max_height < kDetailedBubbleMaxHeight) {
|
||||
init_params.max_height = kDetailedBubbleMaxHeight;
|
||||
init_params->max_height < kDetailedBubbleMaxHeight) {
|
||||
init_params->max_height = kDetailedBubbleMaxHeight;
|
||||
} else if (bubble_type_ == BUBBLE_TYPE_NOTIFICATION) {
|
||||
init_params.close_on_deactivate = false;
|
||||
init_params->close_on_deactivate = false;
|
||||
}
|
||||
bubble_view_ = TrayBubbleView::Create(anchor, this, init_params);
|
||||
bubble_view_ = TrayBubbleView::Create(
|
||||
tray_->GetBubbleWindowContainer(), anchor, this, init_params);
|
||||
|
||||
CreateItemViews(login_status);
|
||||
|
||||
DCHECK(bubble_widget_ == NULL);
|
||||
bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
|
||||
bubble_widget_->AddObserver(this);
|
||||
|
||||
InitializeAndShowBubble(bubble_widget_, bubble_view_, tray_);
|
||||
bubble_wrapper_.reset(new internal::TrayBubbleWrapper(tray_, bubble_view_));
|
||||
}
|
||||
|
||||
void SystemTrayBubble::BubbleViewDestroyed() {
|
||||
@ -268,15 +260,17 @@ void SystemTrayBubble::OnMouseExitedView() {
|
||||
RestartAutoCloseTimer();
|
||||
}
|
||||
|
||||
void SystemTrayBubble::OnClickedOutsideView() {
|
||||
if (bubble_type_ != BUBBLE_TYPE_NOTIFICATION)
|
||||
bubble_widget_->Close();
|
||||
}
|
||||
|
||||
string16 SystemTrayBubble::GetAccessibleName() {
|
||||
return tray_->GetAccessibleName();
|
||||
}
|
||||
|
||||
gfx::Rect SystemTrayBubble::GetAnchorRect(
|
||||
views::Widget* anchor_widget,
|
||||
TrayBubbleView::AnchorType anchor_type,
|
||||
TrayBubbleView::AnchorAlignment anchor_alignment) {
|
||||
return tray_->GetAnchorRect(anchor_widget, anchor_type, anchor_alignment);
|
||||
}
|
||||
|
||||
void SystemTrayBubble::DestroyItemViews() {
|
||||
for (std::vector<ash::SystemTrayItem*>::iterator it = items_.begin();
|
||||
it != items_.end();
|
||||
@ -315,21 +309,21 @@ void SystemTrayBubble::RestartAutoCloseTimer() {
|
||||
}
|
||||
|
||||
void SystemTrayBubble::Close() {
|
||||
if (bubble_widget_)
|
||||
bubble_widget_->Close();
|
||||
tray_->HideBubbleWithView(bubble_view());
|
||||
}
|
||||
|
||||
void SystemTrayBubble::SetVisible(bool is_visible) {
|
||||
if (!bubble_widget_)
|
||||
if (!bubble_view_)
|
||||
return;
|
||||
views::Widget* bubble_widget = bubble_view_->GetWidget();
|
||||
if (is_visible)
|
||||
bubble_widget_->Show();
|
||||
bubble_widget->Show();
|
||||
else
|
||||
bubble_widget_->Hide();
|
||||
bubble_widget->Hide();
|
||||
}
|
||||
|
||||
bool SystemTrayBubble::IsVisible() {
|
||||
return bubble_widget_ && bubble_widget_->IsVisible();
|
||||
return bubble_view() && bubble_view()->GetWidget()->IsVisible();
|
||||
}
|
||||
|
||||
void SystemTrayBubble::CreateItemViews(user::LoginStatus login_status) {
|
||||
@ -355,11 +349,5 @@ void SystemTrayBubble::CreateItemViews(user::LoginStatus login_status) {
|
||||
}
|
||||
}
|
||||
|
||||
void SystemTrayBubble::OnWidgetClosing(views::Widget* widget) {
|
||||
CHECK_EQ(bubble_widget_, widget);
|
||||
bubble_widget_ = NULL;
|
||||
tray_->RemoveBubble(this);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ash
|
||||
|
@ -8,8 +8,8 @@
|
||||
#include "ash/system/tray/tray_bubble_view.h"
|
||||
#include "ash/system/user/login_status.h"
|
||||
#include "base/base_export.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/timer.h"
|
||||
#include "ui/views/widget/widget_observer.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -20,8 +20,9 @@ class SystemTrayItem;
|
||||
|
||||
namespace internal {
|
||||
|
||||
class SystemTrayBubble : public TrayBubbleView::Host,
|
||||
public views::WidgetObserver {
|
||||
class TrayBubbleWrapper;
|
||||
|
||||
class SystemTrayBubble : public TrayBubbleView::Delegate {
|
||||
public:
|
||||
enum BubbleType {
|
||||
BUBBLE_TYPE_DEFAULT,
|
||||
@ -39,17 +40,19 @@ class SystemTrayBubble : public TrayBubbleView::Host,
|
||||
BubbleType bubble_type);
|
||||
|
||||
// Creates |bubble_view_| and a child views for each member of |items_|.
|
||||
// Also creates |bubble_widget_| and sets up animations.
|
||||
// Also creates |bubble_wrapper_|. |init_params| may be modified.
|
||||
void InitView(views::View* anchor,
|
||||
TrayBubbleView::InitParams init_params,
|
||||
user::LoginStatus login_status);
|
||||
user::LoginStatus login_status,
|
||||
TrayBubbleView::InitParams* init_params);
|
||||
|
||||
// Overridden from TrayBubbleView::Host.
|
||||
// Overridden from TrayBubbleView::Delegate.
|
||||
virtual void BubbleViewDestroyed() OVERRIDE;
|
||||
virtual void OnMouseEnteredView() OVERRIDE;
|
||||
virtual void OnMouseExitedView() OVERRIDE;
|
||||
virtual void OnClickedOutsideView() OVERRIDE;
|
||||
virtual string16 GetAccessibleName() OVERRIDE;
|
||||
virtual gfx::Rect GetAnchorRect(views::Widget* anchor_widget,
|
||||
AnchorType anchor_type,
|
||||
AnchorAlignment anchor_alignment) OVERRIDE;
|
||||
|
||||
BubbleType bubble_type() const { return bubble_type_; }
|
||||
TrayBubbleView* bubble_view() const { return bubble_view_; }
|
||||
@ -65,12 +68,9 @@ class SystemTrayBubble : public TrayBubbleView::Host,
|
||||
private:
|
||||
void CreateItemViews(user::LoginStatus login_status);
|
||||
|
||||
// Overridden from views::WidgetObserver:
|
||||
virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
|
||||
|
||||
ash::SystemTray* tray_;
|
||||
TrayBubbleView* bubble_view_;
|
||||
views::Widget* bubble_widget_;
|
||||
scoped_ptr<TrayBubbleWrapper> bubble_wrapper_;
|
||||
std::vector<ash::SystemTrayItem*> items_;
|
||||
BubbleType bubble_type_;
|
||||
|
||||
|
@ -10,10 +10,13 @@
|
||||
#include "ash/system/status_area_widget.h"
|
||||
#include "ash/system/status_area_widget_delegate.h"
|
||||
#include "ash/system/tray/tray_constants.h"
|
||||
#include "ash/wm/window_animations.h"
|
||||
#include "ui/aura/event_filter.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/base/accessibility/accessible_view_state.h"
|
||||
#include "ui/compositor/layer_animation_observer.h"
|
||||
#include "ui/gfx/canvas.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
#include "ui/views/background.h"
|
||||
#include "ui/views/layout/box_layout.h"
|
||||
@ -29,6 +32,8 @@ const int kTrayContainerHorizontalPaddingBottomAlignment = 1;
|
||||
const int kTrayContainerVerticalPaddingVerticalAlignment = 1;
|
||||
const int kTrayContainerHorizontalPaddingVerticalAlignment = 1;
|
||||
|
||||
const int kAnimationDurationForPopupMS = 200;
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace ash {
|
||||
@ -277,5 +282,83 @@ void TrayBackgroundView::SetBorder() {
|
||||
}
|
||||
}
|
||||
|
||||
void TrayBackgroundView::InitializeBubbleAnimations(
|
||||
views::Widget* bubble_widget) {
|
||||
ash::SetWindowVisibilityAnimationType(
|
||||
bubble_widget->GetNativeWindow(),
|
||||
ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
|
||||
ash::SetWindowVisibilityAnimationTransition(
|
||||
bubble_widget->GetNativeWindow(),
|
||||
ash::ANIMATE_BOTH);
|
||||
ash::SetWindowVisibilityAnimationDuration(
|
||||
bubble_widget->GetNativeWindow(),
|
||||
base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
|
||||
}
|
||||
|
||||
aura::Window* TrayBackgroundView::GetBubbleWindowContainer() const {
|
||||
return ash::Shell::GetContainer(
|
||||
tray_container()->GetWidget()->GetNativeWindow()->GetRootWindow(),
|
||||
ash::internal::kShellWindowId_SettingBubbleContainer);
|
||||
}
|
||||
|
||||
gfx::Rect TrayBackgroundView::GetAnchorRect(
|
||||
views::Widget* anchor_widget,
|
||||
TrayBubbleView::AnchorType anchor_type,
|
||||
TrayBubbleView::AnchorAlignment anchor_alignment) const {
|
||||
gfx::Rect rect;
|
||||
if (anchor_widget && anchor_widget->IsVisible()) {
|
||||
rect = anchor_widget->GetWindowBoundsInScreen();
|
||||
if (anchor_type == TrayBubbleView::ANCHOR_TYPE_TRAY) {
|
||||
if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) {
|
||||
bool rtl = base::i18n::IsRTL();
|
||||
rect.Inset(
|
||||
rtl ? kPaddingFromRightEdgeOfScreenBottomAlignment : 0,
|
||||
0,
|
||||
rtl ? 0 : kPaddingFromRightEdgeOfScreenBottomAlignment,
|
||||
kPaddingFromBottomOfScreenBottomAlignment);
|
||||
} else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT) {
|
||||
rect.Inset(0, 0, kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
|
||||
kPaddingFromBottomOfScreenVerticalAlignment);
|
||||
} else {
|
||||
rect.Inset(kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
|
||||
0, 0, kPaddingFromBottomOfScreenVerticalAlignment);
|
||||
}
|
||||
} else if (anchor_type == TrayBubbleView::ANCHOR_TYPE_BUBBLE) {
|
||||
// Invert the offsets to align with the bubble below.
|
||||
if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT) {
|
||||
rect.Inset(kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
|
||||
0, 0, kPaddingFromBottomOfScreenVerticalAlignment);
|
||||
} else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT) {
|
||||
rect.Inset(0, 0, kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
|
||||
kPaddingFromBottomOfScreenVerticalAlignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jennyz): May need to add left/right alignment in the following code.
|
||||
if (rect.IsEmpty()) {
|
||||
rect = Shell::GetScreen()->GetPrimaryDisplay().bounds();
|
||||
rect = gfx::Rect(
|
||||
base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreenBottomAlignment :
|
||||
rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment,
|
||||
rect.height() - kPaddingFromBottomOfScreenBottomAlignment,
|
||||
0, 0);
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
TrayBubbleView::AnchorAlignment TrayBackgroundView::GetAnchorAlignment() const {
|
||||
switch (shelf_alignment_) {
|
||||
case SHELF_ALIGNMENT_BOTTOM:
|
||||
return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
|
||||
case SHELF_ALIGNMENT_LEFT:
|
||||
return TrayBubbleView::ANCHOR_ALIGNMENT_LEFT;
|
||||
case SHELF_ALIGNMENT_RIGHT:
|
||||
return TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT;
|
||||
}
|
||||
NOTREACHED();
|
||||
return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ash
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "ash/ash_export.h"
|
||||
#include "ash/launcher/background_animator.h"
|
||||
#include "ash/system/tray/tray_bubble_view.h"
|
||||
#include "ash/system/tray/tray_views.h"
|
||||
#include "ash/wm/shelf_types.h"
|
||||
|
||||
@ -82,8 +83,17 @@ class ASH_EXPORT TrayBackgroundView : public internal::ActionableView,
|
||||
// Called when the anchor (tray or bubble) may have moved or changed.
|
||||
virtual void AnchorUpdated() {}
|
||||
|
||||
// Called from GetAccessibleState, must return a valid accessible name.
|
||||
virtual string16 GetAccessibleName() = 0;
|
||||
|
||||
// Hides the bubble associated with |bubble_view|. Called when the widget
|
||||
// is closed.
|
||||
virtual void HideBubbleWithView(const TrayBubbleView* bubble_view) = 0;
|
||||
|
||||
// Called by the bubble wrapper when a click event occurs outside the bubble.
|
||||
// May close the bubble. Returns true if the event is handled.
|
||||
virtual bool ClickedOutsideBubble() = 0;
|
||||
|
||||
// Sets |contents| as a child.
|
||||
void SetContents(views::View* contents);
|
||||
|
||||
@ -96,6 +106,21 @@ class ASH_EXPORT TrayBackgroundView : public internal::ActionableView,
|
||||
bool value,
|
||||
internal::BackgroundAnimator::ChangeType change_type);
|
||||
|
||||
// Initializes animations for the bubble.
|
||||
void InitializeBubbleAnimations(views::Widget* bubble_widget);
|
||||
|
||||
// Returns the window hosting the bubble.
|
||||
aura::Window* GetBubbleWindowContainer() const;
|
||||
|
||||
// Returns the anchor rect for the bubble.
|
||||
gfx::Rect GetAnchorRect(
|
||||
views::Widget* anchor_widget,
|
||||
TrayBubbleView::AnchorType anchor_type,
|
||||
TrayBubbleView::AnchorAlignment anchor_alignment) const;
|
||||
|
||||
// Returns the bubble anchor alignment based on |shelf_alignment_|.
|
||||
TrayBubbleView::AnchorAlignment GetAnchorAlignment() const;
|
||||
|
||||
StatusAreaWidget* status_area_widget() {
|
||||
return status_area_widget_;
|
||||
}
|
||||
|
@ -4,14 +4,6 @@
|
||||
|
||||
#include "ash/system/tray/tray_bubble_view.h"
|
||||
|
||||
#include "ash/root_window_controller.h"
|
||||
#include "ash/shell.h"
|
||||
#include "ash/shell_window_ids.h"
|
||||
#include "ash/system/tray/tray_constants.h"
|
||||
#include "ash/wm/property_util.h"
|
||||
#include "ash/wm/shelf_layout_manager.h"
|
||||
#include "ash/wm/window_animations.h"
|
||||
#include "grit/ash_strings.h"
|
||||
#include "third_party/skia/include/core/SkCanvas.h"
|
||||
#include "third_party/skia/include/core/SkColor.h"
|
||||
#include "third_party/skia/include/core/SkPaint.h"
|
||||
@ -24,21 +16,20 @@
|
||||
#include "ui/gfx/canvas.h"
|
||||
#include "ui/gfx/insets.h"
|
||||
#include "ui/gfx/path.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
#include "ui/views/bubble/bubble_frame_view.h"
|
||||
#include "ui/views/layout/box_layout.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
namespace internal {
|
||||
namespace {
|
||||
|
||||
// Inset the arrow a bit from the edge.
|
||||
const int kArrowMinOffset = 20;
|
||||
const int kBubbleSpacing = 20;
|
||||
|
||||
const int kAnimationDurationForPopupMS = 200;
|
||||
} // namespace
|
||||
|
||||
namespace ash {
|
||||
|
||||
// Custom border for TrayBubbleView. Contains special logic for GetBounds()
|
||||
// to stack bubbles with no arrows correctly. Also calculates the arrow offset.
|
||||
@ -46,9 +37,8 @@ class TrayBubbleBorder : public views::BubbleBorder {
|
||||
public:
|
||||
TrayBubbleBorder(views::View* owner,
|
||||
views::View* anchor,
|
||||
views::BubbleBorder::ArrowLocation arrow_location,
|
||||
TrayBubbleView::InitParams params)
|
||||
: views::BubbleBorder(arrow_location, params.shadow),
|
||||
: views::BubbleBorder(params.arrow_location, params.shadow),
|
||||
owner_(owner),
|
||||
anchor_(anchor),
|
||||
tray_arrow_offset_(params.arrow_offset) {
|
||||
@ -87,7 +77,7 @@ class TrayBubbleBorder : public views::BubbleBorder {
|
||||
arrow_location() == views::BubbleBorder::BOTTOM_LEFT) {
|
||||
// Note: tray_arrow_offset_ is relative to the anchor widget.
|
||||
if (tray_arrow_offset_ ==
|
||||
internal::TrayBubbleView::InitParams::kArrowDefaultOffset) {
|
||||
TrayBubbleView::InitParams::kArrowDefaultOffset) {
|
||||
arrow_offset = kArrowMinOffset;
|
||||
} else {
|
||||
const int width = owner_->GetWidget()->GetContentsView()->width();
|
||||
@ -103,7 +93,7 @@ class TrayBubbleBorder : public views::BubbleBorder {
|
||||
}
|
||||
} else {
|
||||
if (tray_arrow_offset_ ==
|
||||
internal::TrayBubbleView::InitParams::kArrowDefaultOffset) {
|
||||
TrayBubbleView::InitParams::kArrowDefaultOffset) {
|
||||
arrow_offset = kArrowMinOffset;
|
||||
} else {
|
||||
gfx::Point pt(0, tray_arrow_offset_);
|
||||
@ -185,7 +175,7 @@ class TrayBubbleBackground : public views::Background {
|
||||
// enough height. Otherwise, makes sure the bottom rows are visible.
|
||||
class BottomAlignedBoxLayout : public views::BoxLayout {
|
||||
public:
|
||||
explicit BottomAlignedBoxLayout(internal::TrayBubbleView* bubble_view)
|
||||
explicit BottomAlignedBoxLayout(TrayBubbleView* bubble_view)
|
||||
: views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0),
|
||||
bubble_view_(bubble_view) {
|
||||
}
|
||||
@ -213,7 +203,7 @@ class BottomAlignedBoxLayout : public views::BoxLayout {
|
||||
}
|
||||
}
|
||||
|
||||
internal::TrayBubbleView* bubble_view_;
|
||||
TrayBubbleView* bubble_view_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BottomAlignedBoxLayout);
|
||||
};
|
||||
@ -222,62 +212,60 @@ class BottomAlignedBoxLayout : public views::BoxLayout {
|
||||
const int TrayBubbleView::InitParams::kArrowDefaultOffset = -1;
|
||||
|
||||
TrayBubbleView::InitParams::InitParams(AnchorType anchor_type,
|
||||
ShelfAlignment shelf_alignment)
|
||||
AnchorAlignment anchor_alignment,
|
||||
int bubble_width)
|
||||
: anchor_type(anchor_type),
|
||||
shelf_alignment(shelf_alignment),
|
||||
bubble_width(kTrayPopupWidth),
|
||||
anchor_alignment(anchor_alignment),
|
||||
bubble_width(bubble_width),
|
||||
max_height(0),
|
||||
can_activate(false),
|
||||
close_on_deactivate(true),
|
||||
top_color(SK_ColorBLACK),
|
||||
arrow_color(SK_ColorBLACK),
|
||||
arrow_location(views::BubbleBorder::NONE),
|
||||
arrow_offset(kArrowDefaultOffset),
|
||||
shadow(views::BubbleBorder::BIG_SHADOW) {
|
||||
}
|
||||
|
||||
TrayBubbleView* TrayBubbleView::Create(views::View* anchor,
|
||||
Host* host,
|
||||
const InitParams& init_params) {
|
||||
TrayBubbleView* TrayBubbleView::Create(aura::Window* parent_window,
|
||||
views::View* anchor,
|
||||
Delegate* delegate,
|
||||
InitParams* init_params) {
|
||||
// Set arrow_location here so that it can be passed correctly to the
|
||||
// BubbleView constructor.
|
||||
views::BubbleBorder::ArrowLocation arrow_location;
|
||||
if (init_params.anchor_type == ANCHOR_TYPE_TRAY) {
|
||||
if (init_params.shelf_alignment == SHELF_ALIGNMENT_BOTTOM) {
|
||||
arrow_location = base::i18n::IsRTL() ?
|
||||
if (init_params->anchor_type == ANCHOR_TYPE_TRAY) {
|
||||
if (init_params->anchor_alignment == ANCHOR_ALIGNMENT_BOTTOM) {
|
||||
init_params->arrow_location = base::i18n::IsRTL() ?
|
||||
views::BubbleBorder::BOTTOM_LEFT : views::BubbleBorder::BOTTOM_RIGHT;
|
||||
} else if (init_params.shelf_alignment == SHELF_ALIGNMENT_LEFT) {
|
||||
arrow_location = views::BubbleBorder::LEFT_BOTTOM;
|
||||
} else if (init_params->anchor_alignment == ANCHOR_ALIGNMENT_LEFT) {
|
||||
init_params->arrow_location = views::BubbleBorder::LEFT_BOTTOM;
|
||||
} else {
|
||||
arrow_location = views::BubbleBorder::RIGHT_BOTTOM;
|
||||
init_params->arrow_location = views::BubbleBorder::RIGHT_BOTTOM;
|
||||
}
|
||||
} else {
|
||||
arrow_location = views::BubbleBorder::NONE;
|
||||
init_params->arrow_location = views::BubbleBorder::NONE;
|
||||
}
|
||||
|
||||
return new TrayBubbleView(init_params, arrow_location, anchor, host);
|
||||
return new TrayBubbleView(parent_window, anchor, delegate, *init_params);
|
||||
}
|
||||
|
||||
TrayBubbleView::TrayBubbleView(
|
||||
const InitParams& init_params,
|
||||
views::BubbleBorder::ArrowLocation arrow_location,
|
||||
views::View* anchor,
|
||||
Host* host)
|
||||
: views::BubbleDelegateView(anchor, arrow_location),
|
||||
TrayBubbleView::TrayBubbleView(aura::Window* parent_window,
|
||||
views::View* anchor,
|
||||
Delegate* delegate,
|
||||
const InitParams& init_params)
|
||||
: views::BubbleDelegateView(anchor, init_params.arrow_location),
|
||||
params_(init_params),
|
||||
host_(host),
|
||||
delegate_(delegate),
|
||||
bubble_border_(NULL),
|
||||
bubble_background_(NULL),
|
||||
is_gesture_dragging_(false) {
|
||||
set_parent_window(Shell::GetContainer(
|
||||
anchor->GetWidget()->GetNativeWindow()->GetRootWindow(),
|
||||
internal::kShellWindowId_SettingBubbleContainer));
|
||||
set_parent_window(parent_window);
|
||||
set_notify_enter_exit_on_child(true);
|
||||
set_close_on_deactivate(init_params.close_on_deactivate);
|
||||
SetPaintToLayer(true);
|
||||
SetFillsBoundsOpaquely(true);
|
||||
|
||||
bubble_border_ = new TrayBubbleBorder(
|
||||
this, anchor_view(), arrow_location, params_);
|
||||
bubble_border_ = new TrayBubbleBorder(this, anchor_view(), params_);
|
||||
|
||||
bubble_background_ = new TrayBubbleBackground(
|
||||
bubble_border_, init_params.top_color, init_params.arrow_color);
|
||||
@ -290,8 +278,17 @@ TrayBubbleView::TrayBubbleView(
|
||||
|
||||
TrayBubbleView::~TrayBubbleView() {
|
||||
// Inform host items (models) that their views are being destroyed.
|
||||
if (host_)
|
||||
host_->BubbleViewDestroyed();
|
||||
if (delegate_)
|
||||
delegate_->BubbleViewDestroyed();
|
||||
}
|
||||
|
||||
void TrayBubbleView::InitializeAndShowBubble() {
|
||||
// Must occur after call to BubbleDelegateView::CreateBubble().
|
||||
SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
|
||||
bubble_border_->UpdateArrowOffset();
|
||||
|
||||
Show();
|
||||
UpdateBubble();
|
||||
}
|
||||
|
||||
void TrayBubbleView::UpdateBubble() {
|
||||
@ -305,6 +302,10 @@ void TrayBubbleView::SetMaxHeight(int height) {
|
||||
SizeToContents();
|
||||
}
|
||||
|
||||
void TrayBubbleView::GetBorderInsets(gfx::Insets* insets) const {
|
||||
bubble_border_->GetInsets(insets);
|
||||
}
|
||||
|
||||
void TrayBubbleView::Init() {
|
||||
views::BoxLayout* layout = new BottomAlignedBoxLayout(this);
|
||||
layout->set_spread_blank_space(true);
|
||||
@ -312,47 +313,11 @@ void TrayBubbleView::Init() {
|
||||
}
|
||||
|
||||
gfx::Rect TrayBubbleView::GetAnchorRect() {
|
||||
gfx::Rect rect;
|
||||
|
||||
if (anchor_widget() && anchor_widget()->IsVisible()) {
|
||||
rect = anchor_widget()->GetWindowBoundsInScreen();
|
||||
if (params_.anchor_type == ANCHOR_TYPE_TRAY) {
|
||||
if (params_.shelf_alignment == SHELF_ALIGNMENT_BOTTOM) {
|
||||
bool rtl = base::i18n::IsRTL();
|
||||
rect.Inset(
|
||||
rtl ? kPaddingFromRightEdgeOfScreenBottomAlignment : 0,
|
||||
0,
|
||||
rtl ? 0 : kPaddingFromRightEdgeOfScreenBottomAlignment,
|
||||
kPaddingFromBottomOfScreenBottomAlignment);
|
||||
} else if (params_.shelf_alignment == SHELF_ALIGNMENT_LEFT) {
|
||||
rect.Inset(0, 0, kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
|
||||
kPaddingFromBottomOfScreenVerticalAlignment);
|
||||
} else {
|
||||
rect.Inset(kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
|
||||
0, 0, kPaddingFromBottomOfScreenVerticalAlignment);
|
||||
}
|
||||
} else if (params_.anchor_type == ANCHOR_TYPE_BUBBLE) {
|
||||
// Invert the offsets to align with the bubble below.
|
||||
if (params_.shelf_alignment == SHELF_ALIGNMENT_LEFT) {
|
||||
rect.Inset(kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
|
||||
0, 0, kPaddingFromBottomOfScreenVerticalAlignment);
|
||||
} else if (params_.shelf_alignment == SHELF_ALIGNMENT_RIGHT) {
|
||||
rect.Inset(0, 0, kPaddingFromInnerEdgeOfLauncherVerticalAlignment,
|
||||
kPaddingFromBottomOfScreenVerticalAlignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jennyz): May need to add left/right alignment in the following code.
|
||||
if (rect.IsEmpty()) {
|
||||
rect = Shell::GetScreen()->GetPrimaryDisplay().bounds();
|
||||
rect = gfx::Rect(
|
||||
base::i18n::IsRTL() ? kPaddingFromRightEdgeOfScreenBottomAlignment :
|
||||
rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment,
|
||||
rect.height() - kPaddingFromBottomOfScreenBottomAlignment,
|
||||
0, 0);
|
||||
}
|
||||
return rect;
|
||||
if (!delegate_)
|
||||
return gfx::Rect();
|
||||
return delegate_->GetAnchorRect(anchor_widget(),
|
||||
params_.anchor_type,
|
||||
params_.anchor_alignment);
|
||||
}
|
||||
|
||||
bool TrayBubbleView::CanActivate() const {
|
||||
@ -386,19 +351,19 @@ gfx::Size TrayBubbleView::GetPreferredSize() {
|
||||
}
|
||||
|
||||
void TrayBubbleView::OnMouseEntered(const ui::MouseEvent& event) {
|
||||
if (host_)
|
||||
host_->OnMouseEnteredView();
|
||||
if (delegate_)
|
||||
delegate_->OnMouseEnteredView();
|
||||
}
|
||||
|
||||
void TrayBubbleView::OnMouseExited(const ui::MouseEvent& event) {
|
||||
if (host_)
|
||||
host_->OnMouseExitedView();
|
||||
if (delegate_)
|
||||
delegate_->OnMouseExitedView();
|
||||
}
|
||||
|
||||
void TrayBubbleView::GetAccessibleState(ui::AccessibleViewState* state) {
|
||||
if (params_.can_activate) {
|
||||
state->role = ui::AccessibilityTypes::ROLE_WINDOW;
|
||||
state->name = host_->GetAccessibleName();
|
||||
state->name = delegate_->GetAccessibleName();
|
||||
}
|
||||
}
|
||||
|
||||
@ -416,101 +381,4 @@ void TrayBubbleView::ViewHierarchyChanged(bool is_add,
|
||||
}
|
||||
}
|
||||
|
||||
TrayBubbleView::Host::Host()
|
||||
: widget_(NULL),
|
||||
bubble_view_(NULL),
|
||||
tray_view_(NULL) {
|
||||
Shell::GetInstance()->AddEnvEventFilter(this);
|
||||
}
|
||||
|
||||
TrayBubbleView::Host::~Host() {
|
||||
Shell::GetInstance()->RemoveEnvEventFilter(this);
|
||||
}
|
||||
|
||||
void TrayBubbleView::Host::InitializeAndShowBubble(views::Widget* widget,
|
||||
TrayBubbleView* bubble_view,
|
||||
views::View* tray_view) {
|
||||
widget_ = widget;
|
||||
bubble_view_ = bubble_view;
|
||||
tray_view_ = tray_view;
|
||||
|
||||
// Must occur after call to BubbleDelegateView::CreateBubble().
|
||||
bubble_view->SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
|
||||
|
||||
bubble_view->bubble_border()->UpdateArrowOffset();
|
||||
|
||||
// Setup animation.
|
||||
ash::SetWindowVisibilityAnimationType(
|
||||
widget->GetNativeWindow(),
|
||||
ash::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
|
||||
ash::SetWindowVisibilityAnimationTransition(
|
||||
widget->GetNativeWindow(),
|
||||
ash::ANIMATE_BOTH);
|
||||
ash::SetWindowVisibilityAnimationDuration(
|
||||
widget->GetNativeWindow(),
|
||||
base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMS));
|
||||
|
||||
bubble_view->Show();
|
||||
bubble_view->UpdateBubble();
|
||||
}
|
||||
|
||||
bool TrayBubbleView::Host::PreHandleKeyEvent(aura::Window* target,
|
||||
ui::KeyEvent* event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TrayBubbleView::Host::PreHandleMouseEvent(aura::Window* target,
|
||||
ui::MouseEvent* event) {
|
||||
if (event->type() == ui::ET_MOUSE_PRESSED)
|
||||
ProcessLocatedEvent(target, *event);
|
||||
return false;
|
||||
}
|
||||
|
||||
ui::TouchStatus TrayBubbleView::Host::PreHandleTouchEvent(
|
||||
aura::Window* target,
|
||||
ui::TouchEvent* event) {
|
||||
if (event->type() == ui::ET_TOUCH_PRESSED)
|
||||
ProcessLocatedEvent(target, *event);
|
||||
return ui::TOUCH_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
ui::EventResult TrayBubbleView::Host::PreHandleGestureEvent(
|
||||
aura::Window* target,
|
||||
ui::GestureEvent* event) {
|
||||
return ui::ER_UNHANDLED;
|
||||
}
|
||||
|
||||
void TrayBubbleView::Host::ProcessLocatedEvent(
|
||||
aura::Window* target, const ui::LocatedEvent& event) {
|
||||
if (target) {
|
||||
// Don't process events that occurred inside an embedded menu.
|
||||
RootWindowController* root_controller =
|
||||
GetRootWindowController(target->GetRootWindow());
|
||||
if (root_controller && root_controller->GetContainer(
|
||||
ash::internal::kShellWindowId_MenuContainer)->Contains(target)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!widget_)
|
||||
return;
|
||||
gfx::Rect bounds = widget_->GetWindowBoundsInScreen();
|
||||
gfx::Insets insets;
|
||||
bubble_view_->bubble_border()->GetInsets(&insets);
|
||||
bounds.Inset(insets);
|
||||
if (bounds.Contains(event.root_location()))
|
||||
return;
|
||||
if (tray_view_) {
|
||||
// If the user clicks on the parent tray, don't process the event here,
|
||||
// let the tray logic handle the event and determine show/hide behavior.
|
||||
bounds = tray_view_->GetWidget()->GetClientAreaBoundsInScreen();
|
||||
if (bounds.Contains(event.root_location()))
|
||||
return;
|
||||
}
|
||||
// Handle clicking outside the bubble and tray. We don't block the event, so
|
||||
// it will also be handled by whatever widget was clicked on.
|
||||
OnClickedOutsideView();
|
||||
}
|
||||
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ash
|
||||
|
@ -5,8 +5,6 @@
|
||||
#ifndef ASH_SYSTEM_TRAY_TRAY_BUBBLE_VIEW_H_
|
||||
#define ASH_SYSTEM_TRAY_TRAY_BUBBLE_VIEW_H_
|
||||
|
||||
#include "ash/wm/shelf_types.h"
|
||||
#include "ui/aura/event_filter.h"
|
||||
#include "ui/views/bubble/bubble_delegate.h"
|
||||
|
||||
namespace ui {
|
||||
@ -19,7 +17,6 @@ class Widget;
|
||||
}
|
||||
|
||||
namespace ash {
|
||||
namespace internal {
|
||||
|
||||
class TrayBubbleBorder;
|
||||
class TrayBubbleBackground;
|
||||
@ -33,83 +30,78 @@ class TrayBubbleView : public views::BubbleDelegateView {
|
||||
ANCHOR_TYPE_BUBBLE
|
||||
};
|
||||
|
||||
class Host : public aura::EventFilter {
|
||||
public:
|
||||
Host();
|
||||
virtual ~Host();
|
||||
enum AnchorAlignment {
|
||||
ANCHOR_ALIGNMENT_BOTTOM,
|
||||
ANCHOR_ALIGNMENT_LEFT,
|
||||
ANCHOR_ALIGNMENT_RIGHT
|
||||
};
|
||||
|
||||
// Set widget_ and tray_view_, set up animations, and show the bubble.
|
||||
// Must occur after bubble_view->CreateBubble() is called.
|
||||
void InitializeAndShowBubble(views::Widget* widget,
|
||||
TrayBubbleView* bubble_view,
|
||||
views::View* tray_view);
|
||||
class Delegate {
|
||||
public:
|
||||
typedef TrayBubbleView::AnchorType AnchorType;
|
||||
typedef TrayBubbleView::AnchorAlignment AnchorAlignment;
|
||||
|
||||
Delegate() {}
|
||||
virtual ~Delegate() {}
|
||||
|
||||
virtual void BubbleViewDestroyed() = 0;
|
||||
virtual void OnMouseEnteredView() = 0;
|
||||
virtual void OnMouseExitedView() = 0;
|
||||
virtual void OnClickedOutsideView() = 0;
|
||||
virtual string16 GetAccessibleName() = 0;
|
||||
|
||||
// Overridden from aura::EventFilter.
|
||||
virtual bool PreHandleKeyEvent(aura::Window* target,
|
||||
ui::KeyEvent* event) OVERRIDE;
|
||||
virtual bool PreHandleMouseEvent(aura::Window* target,
|
||||
ui::MouseEvent* event) OVERRIDE;
|
||||
virtual ui::TouchStatus PreHandleTouchEvent(
|
||||
aura::Window* target,
|
||||
ui::TouchEvent* event) OVERRIDE;
|
||||
virtual ui::EventResult PreHandleGestureEvent(
|
||||
aura::Window* target,
|
||||
ui::GestureEvent* event) OVERRIDE;
|
||||
virtual gfx::Rect GetAnchorRect(views::Widget* anchor_widget,
|
||||
AnchorType anchor_type,
|
||||
AnchorAlignment anchor_alignment) = 0;
|
||||
|
||||
private:
|
||||
void ProcessLocatedEvent(aura::Window* target,
|
||||
const ui::LocatedEvent& event);
|
||||
|
||||
views::Widget* widget_;
|
||||
TrayBubbleView* bubble_view_;
|
||||
views::View* tray_view_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Host);
|
||||
DISALLOW_COPY_AND_ASSIGN(Delegate);
|
||||
};
|
||||
|
||||
struct InitParams {
|
||||
static const int kArrowDefaultOffset;
|
||||
|
||||
InitParams(AnchorType anchor_type,
|
||||
ShelfAlignment shelf_alignment);
|
||||
AnchorAlignment anchor_alignment,
|
||||
int bubble_width);
|
||||
AnchorType anchor_type;
|
||||
ShelfAlignment shelf_alignment;
|
||||
AnchorAlignment anchor_alignment;
|
||||
int bubble_width;
|
||||
int max_height;
|
||||
bool can_activate;
|
||||
bool close_on_deactivate;
|
||||
SkColor top_color;
|
||||
SkColor arrow_color;
|
||||
views::BubbleBorder::ArrowLocation arrow_location;
|
||||
int arrow_offset;
|
||||
views::BubbleBorder::Shadow shadow;
|
||||
};
|
||||
|
||||
static TrayBubbleView* Create(views::View* anchor,
|
||||
Host* host,
|
||||
const InitParams& init_params);
|
||||
// Constructs and returns a TrayBubbleView. init_params may be modified.
|
||||
static TrayBubbleView* Create(aura::Window* 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);
|
||||
|
||||
// Called when the host is destroyed.
|
||||
void reset_host() { host_ = NULL; }
|
||||
// Returns the border insets. Called by TrayEventFilter.
|
||||
void GetBorderInsets(gfx::Insets* insets) const;
|
||||
|
||||
// Called when the delegate is destroyed.
|
||||
void reset_delegate() { delegate_ = NULL; }
|
||||
|
||||
void set_gesture_dragging(bool dragging) { is_gesture_dragging_ = dragging; }
|
||||
bool is_gesture_dragging() const { return is_gesture_dragging_; }
|
||||
|
||||
TrayBubbleBorder* bubble_border() { return bubble_border_; }
|
||||
|
||||
// Overridden from views::WidgetDelegate.
|
||||
virtual bool CanActivate() const OVERRIDE;
|
||||
virtual views::NonClientFrameView* CreateNonClientFrameView(
|
||||
@ -127,10 +119,10 @@ class TrayBubbleView : public views::BubbleDelegateView {
|
||||
virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
|
||||
|
||||
protected:
|
||||
TrayBubbleView(const InitParams& init_params,
|
||||
views::BubbleBorder::ArrowLocation arrow_location,
|
||||
TrayBubbleView(aura::Window* parent_window,
|
||||
views::View* anchor,
|
||||
Host* host);
|
||||
Delegate* delegate,
|
||||
const InitParams& init_params);
|
||||
|
||||
// Overridden from views::BubbleDelegateView.
|
||||
virtual void Init() OVERRIDE;
|
||||
@ -143,7 +135,7 @@ class TrayBubbleView : public views::BubbleDelegateView {
|
||||
|
||||
private:
|
||||
InitParams params_;
|
||||
Host* host_;
|
||||
Delegate* delegate_;
|
||||
TrayBubbleBorder* bubble_border_;
|
||||
TrayBubbleBackground* bubble_background_;
|
||||
bool is_gesture_dragging_;
|
||||
@ -151,7 +143,6 @@ class TrayBubbleView : public views::BubbleDelegateView {
|
||||
DISALLOW_COPY_AND_ASSIGN(TrayBubbleView);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ash
|
||||
|
||||
#endif // ASH_SYSTEM_TRAY_TRAY_BUBBLE_VIEW_H_
|
||||
|
43
ash/system/tray/tray_bubble_wrapper.cc
Normal file
43
ash/system/tray/tray_bubble_wrapper.cc
Normal file
@ -0,0 +1,43 @@
|
||||
// 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.
|
||||
|
||||
#include "ash/system/tray/tray_bubble_wrapper.h"
|
||||
|
||||
#include "ash/system/tray/tray_background_view.h"
|
||||
#include "ash/system/tray/tray_bubble_view.h"
|
||||
#include "ash/system/tray/tray_event_filter.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
namespace ash {
|
||||
namespace internal {
|
||||
|
||||
TrayBubbleWrapper::TrayBubbleWrapper(TrayBackgroundView* tray,
|
||||
TrayBubbleView* bubble_view)
|
||||
: tray_(tray),
|
||||
bubble_view_(bubble_view) {
|
||||
bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
|
||||
bubble_widget_->AddObserver(this);
|
||||
|
||||
bubble_view_->InitializeAndShowBubble();
|
||||
tray_->InitializeBubbleAnimations(bubble_widget_);
|
||||
|
||||
tray_event_filter_.reset(new TrayEventFilter(this));
|
||||
}
|
||||
|
||||
TrayBubbleWrapper::~TrayBubbleWrapper() {
|
||||
tray_event_filter_.reset();
|
||||
if (bubble_widget_) {
|
||||
bubble_widget_->RemoveObserver(this);
|
||||
bubble_widget_->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void TrayBubbleWrapper::OnWidgetClosing(views::Widget* widget) {
|
||||
CHECK_EQ(bubble_widget_, widget);
|
||||
bubble_widget_ = NULL;
|
||||
tray_->HideBubbleWithView(bubble_view_); // May destroy |bubble_view_|
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ash
|
47
ash/system/tray/tray_bubble_wrapper.h
Normal file
47
ash/system/tray/tray_bubble_wrapper.h
Normal file
@ -0,0 +1,47 @@
|
||||
// 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 ASH_SYSTEM_TRAY_TRAY_BUBBLE_WRAPPER_H_
|
||||
#define ASH_SYSTEM_TRAY_TRAY_BUBBLE_WRAPPER_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "ui/views/widget/widget_observer.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
class TrayBubbleView;
|
||||
|
||||
namespace internal {
|
||||
|
||||
class TrayBackgroundView;
|
||||
class TrayEventFilter;
|
||||
|
||||
// Creates and manages the Widget and EventFilter components of a bubble.
|
||||
|
||||
class TrayBubbleWrapper : public views::WidgetObserver {
|
||||
public:
|
||||
TrayBubbleWrapper(TrayBackgroundView* tray, TrayBubbleView* bubble_view);
|
||||
virtual ~TrayBubbleWrapper();
|
||||
|
||||
// views::WidgetObserver overrides:
|
||||
virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
|
||||
|
||||
TrayBackgroundView* tray() { return tray_; }
|
||||
TrayBubbleView* bubble_view() { return bubble_view_; }
|
||||
views::Widget* bubble_widget() { return bubble_widget_; }
|
||||
|
||||
private:
|
||||
TrayBackgroundView* tray_;
|
||||
TrayBubbleView* bubble_view_; // unowned
|
||||
views::Widget* bubble_widget_;
|
||||
scoped_ptr<TrayEventFilter> tray_event_filter_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TrayBubbleWrapper);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ash
|
||||
|
||||
#endif // ASH_SYSTEM_TRAY_TRAY_BUBBLE_WRAPPER_H_
|
93
ash/system/tray/tray_event_filter.cc
Normal file
93
ash/system/tray/tray_event_filter.cc
Normal file
@ -0,0 +1,93 @@
|
||||
// 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.
|
||||
|
||||
#include "ash/system/tray/tray_event_filter.h"
|
||||
|
||||
#include "ash/root_window_controller.h"
|
||||
#include "ash/shell.h"
|
||||
#include "ash/shell_window_ids.h"
|
||||
#include "ash/system/tray/tray_background_view.h"
|
||||
#include "ash/system/tray/tray_bubble_view.h"
|
||||
#include "ash/system/tray/tray_bubble_wrapper.h"
|
||||
#include "ash/system/tray/tray_constants.h"
|
||||
#include "ash/system/tray/tray_event_filter.h"
|
||||
#include "ash/wm/property_util.h"
|
||||
#include "ash/wm/shelf_layout_manager.h"
|
||||
#include "ui/aura/event_filter.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
namespace ash {
|
||||
namespace internal {
|
||||
|
||||
TrayEventFilter::TrayEventFilter(TrayBubbleWrapper* wrapper)
|
||||
: wrapper_(wrapper) {
|
||||
ash::Shell::GetInstance()->AddEnvEventFilter(this);
|
||||
}
|
||||
|
||||
TrayEventFilter::~TrayEventFilter() {
|
||||
ash::Shell::GetInstance()->RemoveEnvEventFilter(this);
|
||||
}
|
||||
|
||||
bool TrayEventFilter::PreHandleKeyEvent(aura::Window* target,
|
||||
ui::KeyEvent* event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TrayEventFilter::PreHandleMouseEvent(aura::Window* target,
|
||||
ui::MouseEvent* event) {
|
||||
if (event->type() == ui::ET_MOUSE_PRESSED)
|
||||
return ProcessLocatedEvent(target, *event);
|
||||
return false;
|
||||
}
|
||||
|
||||
ui::TouchStatus TrayEventFilter::PreHandleTouchEvent(aura::Window* target,
|
||||
ui::TouchEvent* event) {
|
||||
if (event->type() == ui::ET_TOUCH_PRESSED) {
|
||||
if (ProcessLocatedEvent(target, *event))
|
||||
return ui::TOUCH_STATUS_END;
|
||||
}
|
||||
return ui::TOUCH_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
ui::EventResult TrayEventFilter::PreHandleGestureEvent(
|
||||
aura::Window* target,
|
||||
ui::GestureEvent* event) {
|
||||
return ui::ER_UNHANDLED;
|
||||
}
|
||||
|
||||
bool TrayEventFilter::ProcessLocatedEvent(aura::Window* target,
|
||||
const ui::LocatedEvent& event) {
|
||||
if (target) {
|
||||
// Don't process events that occurred inside an embedded menu.
|
||||
ash::internal::RootWindowController* root_controller =
|
||||
ash::GetRootWindowController(target->GetRootWindow());
|
||||
if (root_controller && root_controller->GetContainer(
|
||||
ash::internal::kShellWindowId_MenuContainer)->Contains(target)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!wrapper_->bubble_widget())
|
||||
return false;
|
||||
|
||||
gfx::Rect bounds = wrapper_->bubble_widget()->GetWindowBoundsInScreen();
|
||||
gfx::Insets insets;
|
||||
wrapper_->bubble_view()->GetBorderInsets(&insets);
|
||||
bounds.Inset(insets);
|
||||
if (bounds.Contains(event.root_location()))
|
||||
return false;
|
||||
if (wrapper_->tray()) {
|
||||
// If the user clicks on the parent tray, don't process the event here,
|
||||
// let the tray logic handle the event and determine show/hide behavior.
|
||||
bounds = wrapper_->tray()->GetWidget()->GetClientAreaBoundsInScreen();
|
||||
if (bounds.Contains(event.root_location()))
|
||||
return false;
|
||||
}
|
||||
// Handle clicking outside the bubble and tray and return true if the
|
||||
// event was handled.
|
||||
return wrapper_->tray()->ClickedOutsideBubble();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ash
|
52
ash/system/tray/tray_event_filter.h
Normal file
52
ash/system/tray/tray_event_filter.h
Normal file
@ -0,0 +1,52 @@
|
||||
// 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 ASH_SYSTEM_TRAY_TRAY_EVENT_FILTER_H_
|
||||
#define ASH_SYSTEM_TRAY_TRAY_EVENT_FILTER_H_
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "ui/aura/event_filter.h"
|
||||
#include "ui/base/events/event.h"
|
||||
|
||||
namespace aura {
|
||||
class Window;
|
||||
}
|
||||
|
||||
namespace ash {
|
||||
namespace internal {
|
||||
|
||||
class TrayBubbleWrapper;
|
||||
|
||||
// Handles events for a tray bubble.
|
||||
|
||||
class TrayEventFilter : public aura::EventFilter {
|
||||
public:
|
||||
explicit TrayEventFilter(TrayBubbleWrapper* wrapper);
|
||||
virtual ~TrayEventFilter();
|
||||
|
||||
// Overridden from aura::EventFilter.
|
||||
virtual bool PreHandleKeyEvent(aura::Window* target,
|
||||
ui::KeyEvent* event) OVERRIDE;
|
||||
virtual bool PreHandleMouseEvent(aura::Window* target,
|
||||
ui::MouseEvent* event) OVERRIDE;
|
||||
virtual ui::TouchStatus PreHandleTouchEvent(aura::Window* target,
|
||||
ui::TouchEvent* event) OVERRIDE;
|
||||
virtual ui::EventResult PreHandleGestureEvent(
|
||||
aura::Window* target,
|
||||
ui::GestureEvent* event) OVERRIDE;
|
||||
|
||||
private:
|
||||
// Returns true if the event is handled.
|
||||
bool ProcessLocatedEvent(aura::Window* target,
|
||||
const ui::LocatedEvent& event);
|
||||
|
||||
TrayBubbleWrapper* wrapper_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TrayEventFilter);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ash
|
||||
|
||||
#endif // ASH_SYSTEM_TRAY_TRAY_EVENT_FILTER_H_
|
@ -22,7 +22,6 @@
|
||||
|
||||
namespace ash {
|
||||
|
||||
using internal::TrayBubbleView;
|
||||
using internal::TrayPopupTextButton;
|
||||
|
||||
namespace message_center {
|
||||
@ -197,7 +196,8 @@ MessageCenterBubble::MessageCenterBubble(WebNotificationTray* tray) :
|
||||
init_params.max_height = message_center::kWebNotificationBubbleMaxHeight;
|
||||
init_params.can_activate = true;
|
||||
views::View* anchor = tray_->tray_container();
|
||||
bubble_view_ = TrayBubbleView::Create(anchor, this, init_params);
|
||||
bubble_view_ = TrayBubbleView::Create(
|
||||
tray_->GetBubbleWindowContainer(), anchor, this, &init_params);
|
||||
contents_view_ = new MessageCenterContentsView(tray);
|
||||
|
||||
Initialize(contents_view_);
|
||||
@ -220,11 +220,6 @@ void MessageCenterBubble::UpdateBubbleView() {
|
||||
bubble_view_->UpdateBubble();
|
||||
}
|
||||
|
||||
void MessageCenterBubble::OnClickedOutsideView() {
|
||||
// May delete |this|.
|
||||
tray_->HideMessageCenterBubble();
|
||||
}
|
||||
|
||||
} // namespace message_center
|
||||
|
||||
} // namespace ash
|
||||
|
@ -24,11 +24,9 @@ class MessageCenterBubble : public WebNotificationBubble {
|
||||
|
||||
size_t NumMessageViewsForTest() const;
|
||||
|
||||
// Overridden from TrayBubbleView::Host.
|
||||
// Overridden from TrayBubbleView::Delegate.
|
||||
virtual void BubbleViewDestroyed() OVERRIDE;
|
||||
|
||||
virtual void OnClickedOutsideView() OVERRIDE;
|
||||
|
||||
private:
|
||||
// Overridden from WebNotificationBubble.
|
||||
virtual void UpdateBubbleView() OVERRIDE;
|
||||
|
@ -15,8 +15,6 @@
|
||||
|
||||
namespace ash {
|
||||
|
||||
using internal::TrayBubbleView;
|
||||
|
||||
namespace message_center {
|
||||
|
||||
const int kAutocloseDelaySeconds = 5;
|
||||
@ -76,7 +74,8 @@ PopupBubble::PopupBubble(WebNotificationTray* tray) :
|
||||
init_params.arrow_color = kBackgroundColor;
|
||||
init_params.close_on_deactivate = false;
|
||||
views::View* anchor = tray_->tray_container();
|
||||
bubble_view_ = TrayBubbleView::Create(anchor, this, init_params);
|
||||
bubble_view_ = TrayBubbleView::Create(
|
||||
tray_->GetBubbleWindowContainer(), anchor, this, &init_params);
|
||||
contents_view_ = new PopupBubbleContentsView(tray);
|
||||
|
||||
Initialize(contents_view_);
|
||||
@ -107,7 +106,7 @@ void PopupBubble::UpdateBubbleView() {
|
||||
WebNotificationList::Notifications popup_notifications;
|
||||
tray_->notification_list()->GetPopupNotifications(&popup_notifications);
|
||||
if (popup_notifications.size() == 0) {
|
||||
tray_->HideBubble(this); // deletes |this|!
|
||||
tray_->HideBubbleWithView(bubble_view()); // deletes |this|
|
||||
return;
|
||||
}
|
||||
// Only update the popup tray if the number of visible popup notifications
|
||||
|
@ -28,11 +28,9 @@ class PopupBubble : public WebNotificationBubble {
|
||||
bool dirty() const { return dirty_; }
|
||||
void set_dirty(bool dirty) { dirty_ = dirty; }
|
||||
|
||||
// Overridden from TrayBubbleView::Host.
|
||||
// Overridden from TrayBubbleView::Delegate.
|
||||
virtual void BubbleViewDestroyed() OVERRIDE;
|
||||
|
||||
virtual void OnMouseEnteredView() OVERRIDE;
|
||||
|
||||
virtual void OnMouseExitedView() OVERRIDE;
|
||||
|
||||
private:
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "ash/system/web_notification/web_notification_bubble.h"
|
||||
|
||||
#include "ash/system/tray/tray_bubble_wrapper.h"
|
||||
#include "ash/system/tray/tray_constants.h"
|
||||
#include "ash/system/web_notification/web_notification_tray.h"
|
||||
#include "ash/system/web_notification/web_notification_view.h"
|
||||
@ -13,8 +14,6 @@
|
||||
|
||||
namespace ash {
|
||||
|
||||
using internal::TrayBubbleView;
|
||||
|
||||
namespace message_center {
|
||||
|
||||
// Delay laying out the WebNotificationBubble until all notifications have been
|
||||
@ -24,29 +23,20 @@ const int kUpdateDelayMs = 50;
|
||||
WebNotificationBubble::WebNotificationBubble(WebNotificationTray* tray)
|
||||
: tray_(tray),
|
||||
bubble_view_(NULL),
|
||||
bubble_widget_(NULL),
|
||||
ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
|
||||
}
|
||||
|
||||
void WebNotificationBubble::Initialize(views::View* contents_view) {
|
||||
DCHECK(bubble_view_);
|
||||
|
||||
bubble_view_->AddChildView(contents_view);
|
||||
|
||||
bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_);
|
||||
bubble_widget_->AddObserver(this);
|
||||
|
||||
InitializeAndShowBubble(bubble_widget_, bubble_view_, tray_);
|
||||
bubble_wrapper_.reset(new internal::TrayBubbleWrapper(tray_, bubble_view_));
|
||||
UpdateBubbleView();
|
||||
}
|
||||
|
||||
WebNotificationBubble::~WebNotificationBubble() {
|
||||
if (bubble_view_)
|
||||
bubble_view_->reset_host();
|
||||
if (bubble_widget_) {
|
||||
bubble_widget_->RemoveObserver(this);
|
||||
bubble_widget_->Close();
|
||||
}
|
||||
bubble_view_->reset_delegate();
|
||||
}
|
||||
|
||||
void WebNotificationBubble::ScheduleUpdate() {
|
||||
@ -59,7 +49,7 @@ void WebNotificationBubble::ScheduleUpdate() {
|
||||
}
|
||||
|
||||
bool WebNotificationBubble::IsVisible() const {
|
||||
return bubble_widget_ && bubble_widget_->IsVisible();
|
||||
return bubble_view() && bubble_view()->GetWidget()->IsVisible();
|
||||
}
|
||||
|
||||
void WebNotificationBubble::BubbleViewDestroyed() {
|
||||
@ -72,29 +62,27 @@ void WebNotificationBubble::OnMouseEnteredView() {
|
||||
void WebNotificationBubble::OnMouseExitedView() {
|
||||
}
|
||||
|
||||
void WebNotificationBubble::OnClickedOutsideView() {
|
||||
// May delete |this|.
|
||||
tray_->HideMessageCenterBubble();
|
||||
}
|
||||
|
||||
string16 WebNotificationBubble::GetAccessibleName() {
|
||||
return tray_->GetAccessibleName();
|
||||
}
|
||||
|
||||
// Overridden from views::WidgetObserver:
|
||||
void WebNotificationBubble::OnWidgetClosing(views::Widget* widget) {
|
||||
CHECK_EQ(bubble_widget_, widget);
|
||||
bubble_widget_ = NULL;
|
||||
tray_->HideBubble(this); // Will destroy |this|.
|
||||
gfx::Rect WebNotificationBubble::GetAnchorRect(
|
||||
views::Widget* anchor_widget,
|
||||
TrayBubbleView::AnchorType anchor_type,
|
||||
TrayBubbleView::AnchorAlignment anchor_alignment) {
|
||||
return tray_->GetAnchorRect(anchor_widget, anchor_type, anchor_alignment);
|
||||
}
|
||||
|
||||
TrayBubbleView::InitParams WebNotificationBubble::GetInitParams() {
|
||||
TrayBubbleView::AnchorAlignment anchor_alignment =
|
||||
tray_->GetAnchorAlignment();
|
||||
TrayBubbleView::InitParams init_params(TrayBubbleView::ANCHOR_TYPE_TRAY,
|
||||
tray_->shelf_alignment());
|
||||
anchor_alignment,
|
||||
kTrayPopupWidth);
|
||||
init_params.top_color = kBackgroundColor;
|
||||
init_params.arrow_color = kHeaderBackgroundColorDark;
|
||||
init_params.bubble_width = kWebNotificationWidth;
|
||||
if (tray_->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) {
|
||||
if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) {
|
||||
views::View* anchor = tray_->tray_container();
|
||||
gfx::Point bounds(anchor->width() / 2, 0);
|
||||
|
||||
|
@ -6,21 +6,22 @@
|
||||
#define ASH_SYSTEM_NOTIFICATION_WEB_NOTIFICATION_BUBBLE_H_
|
||||
|
||||
#include "ash/system/tray/tray_bubble_view.h"
|
||||
#include "ui/views/widget/widget_observer.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
class WebNotificationTray;
|
||||
|
||||
using internal::TrayBubbleView;
|
||||
namespace internal {
|
||||
class TrayBubbleWrapper;
|
||||
}
|
||||
|
||||
namespace message_center {
|
||||
|
||||
class WebNotificationContentsView;
|
||||
class WebNotificationView;
|
||||
|
||||
class WebNotificationBubble : public TrayBubbleView::Host,
|
||||
public views::WidgetObserver {
|
||||
class WebNotificationBubble : public TrayBubbleView::Delegate {
|
||||
public:
|
||||
explicit WebNotificationBubble(WebNotificationTray* tray);
|
||||
|
||||
@ -37,29 +38,23 @@ class WebNotificationBubble : public TrayBubbleView::Host,
|
||||
|
||||
bool IsVisible() const;
|
||||
|
||||
views::Widget* bubble_widget() const { return bubble_widget_; }
|
||||
TrayBubbleView* bubble_view() const { return bubble_view_; }
|
||||
|
||||
// Overridden from TrayBubbleView::Host.
|
||||
// Overridden from TrayBubbleView::Delegate.
|
||||
virtual void BubbleViewDestroyed() OVERRIDE;
|
||||
|
||||
virtual void OnMouseEnteredView() OVERRIDE;
|
||||
|
||||
virtual void OnMouseExitedView() OVERRIDE;
|
||||
|
||||
virtual void OnClickedOutsideView() OVERRIDE;
|
||||
|
||||
virtual string16 GetAccessibleName() OVERRIDE;
|
||||
|
||||
// Overridden from views::WidgetObserver:
|
||||
virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE;
|
||||
virtual gfx::Rect GetAnchorRect(views::Widget* anchor_widget,
|
||||
AnchorType anchor_type,
|
||||
AnchorAlignment anchor_alignment) OVERRIDE;
|
||||
|
||||
protected:
|
||||
TrayBubbleView::InitParams GetInitParams();
|
||||
|
||||
WebNotificationTray* tray_;
|
||||
TrayBubbleView* bubble_view_;
|
||||
views::Widget* bubble_widget_;
|
||||
scoped_ptr<internal::TrayBubbleWrapper> bubble_wrapper_;
|
||||
base::WeakPtrFactory<WebNotificationBubble> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WebNotificationBubble);
|
||||
|
@ -350,14 +350,24 @@ void WebNotificationTray::UpdateTrayAndBubble() {
|
||||
UpdateTray();
|
||||
}
|
||||
|
||||
void WebNotificationTray::HideBubble(WebNotificationBubble* bubble) {
|
||||
if (bubble == message_center_bubble()) {
|
||||
void WebNotificationTray::HideBubbleWithView(
|
||||
const TrayBubbleView* bubble_view) {
|
||||
if (message_center_bubble() &&
|
||||
bubble_view == message_center_bubble()->bubble_view()) {
|
||||
HideMessageCenterBubble();
|
||||
} else if (bubble == popup_bubble()) {
|
||||
} else if (popup_bubble() && bubble_view == popup_bubble()->bubble_view()) {
|
||||
HidePopupBubble();
|
||||
}
|
||||
}
|
||||
|
||||
bool WebNotificationTray::ClickedOutsideBubble() {
|
||||
// Only hide the message center.
|
||||
if (!message_center_bubble())
|
||||
return false;
|
||||
HideMessageCenterBubble();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Methods for testing
|
||||
|
||||
size_t WebNotificationTray::GetNotificationCountForTest() const {
|
||||
|
@ -124,6 +124,8 @@ class ASH_EXPORT WebNotificationTray : public internal::TrayBackgroundView,
|
||||
virtual void SetShelfAlignment(ShelfAlignment alignment) OVERRIDE;
|
||||
virtual void AnchorUpdated() OVERRIDE;
|
||||
virtual string16 GetAccessibleName() OVERRIDE;
|
||||
virtual void HideBubbleWithView(const TrayBubbleView* bubble_view) OVERRIDE;
|
||||
virtual bool ClickedOutsideBubble() OVERRIDE;
|
||||
|
||||
// Overridden from internal::ActionableView.
|
||||
virtual bool PerformAction(const ui::Event& event) OVERRIDE;
|
||||
@ -187,9 +189,6 @@ class ASH_EXPORT WebNotificationTray : public internal::TrayBackgroundView,
|
||||
// As above but also updates any visible bubble.
|
||||
void UpdateTrayAndBubble();
|
||||
|
||||
// Hides the specified bubble (called when |bubble| is closed from Views).
|
||||
void HideBubble(message_center::WebNotificationBubble* bubble);
|
||||
|
||||
// Testing accessors.
|
||||
size_t GetNotificationCountForTest() const;
|
||||
bool HasNotificationForTest(const std::string& id) const;
|
||||
|
Reference in New Issue
Block a user