Index: ui/message_center/message_center_tray.cc |
diff --git a/ui/message_center/message_center_tray.cc b/ui/message_center/message_center_tray.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9db7e07ebc45b6011b9f8752eeb4669d0a5ed88f |
--- /dev/null |
+++ b/ui/message_center/message_center_tray.cc |
@@ -0,0 +1,270 @@ |
+// 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 "ui/message_center/message_center_tray.h" |
+ |
+#include "base/memory/singleton.h" |
+#include "base/utf_string_conversions.h" |
+#include "ui/message_center/message_center_bubble.h" |
+#include "ui/message_center/message_popup_bubble.h" |
+#include "ui/views/bubble/tray_bubble_view.h" |
+#include "ui/views/widget/widget.h" |
+ |
+namespace { |
+ |
+// Helper class that owns the MessageBubbleBase and listens to widget closing |
+// events. |
+class WebNotificationBubbleWrapper : public views::WidgetObserver { |
+ public: |
+ WebNotificationBubbleWrapper( |
+ ui::MessageCenterTray* tray, |
+ message_center::MessageBubbleBase* bubble, |
+ views::TrayBubbleView::InitParams init_params, |
+ gfx::NativeWindow bubble_window_container, |
+ views::View* anchor_view); |
+ virtual ~WebNotificationBubbleWrapper(); |
+ // Convenience accessors. |
+ message_center::MessageBubbleBase* message_bubble() const { |
+ return message_bubble_.get(); |
+ } |
+ views::TrayBubbleView* bubble_view() const { |
+ return message_bubble_->bubble_view(); |
+ } |
+ bool IsMessageBubbleVisible(); |
+ |
+ // views::WidgetObserver overrides: |
+ virtual void OnWidgetClosing(views::Widget* widget) OVERRIDE; |
+ |
+ private: |
+ scoped_ptr<message_center::MessageBubbleBase> message_bubble_; |
+ views::TrayBubbleView* bubble_view_; // unowned |
+ views::Widget* bubble_widget_; |
+ ui::MessageCenterTray* tray_; |
+ DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper); |
+}; |
+ |
+WebNotificationBubbleWrapper::WebNotificationBubbleWrapper( |
+ ui::MessageCenterTray* tray, |
+ message_center::MessageBubbleBase* bubble, |
+ views::TrayBubbleView::InitParams init_params, |
+ gfx::NativeWindow bubble_window_container, |
+ views::View* anchor_view) : |
+ tray_(tray) { |
+ message_bubble_.reset(bubble); |
+ |
+ init_params.close_on_deactivate = false; |
+ init_params.anchor_type = views::TrayBubbleView::ANCHOR_TYPE_TRAY; |
+ |
+ bubble_view_ = views::TrayBubbleView::Create( |
+ bubble_window_container, |
+ anchor_view, |
+ tray_, |
+ &init_params); |
+ |
+ bubble_widget_ = views::BubbleDelegateView::CreateBubble(bubble_view_); |
+ bubble_widget_->AddObserver(this); |
+ bubble_widget_->StackAtTop(); |
+ bubble_widget_->SetAlwaysOnTop(true); |
+ bubble_widget_->Activate(); |
+ |
+ bubble_view_->InitializeAndShowBubble(); |
+ |
+ bubble_view_->set_close_on_deactivate(true); |
+ bubble->InitializeContents(bubble_view_); |
+} |
+ |
+WebNotificationBubbleWrapper::~WebNotificationBubbleWrapper() { |
+ if (bubble_widget_) { |
+ bubble_widget_->RemoveObserver(this); |
+ bubble_widget_->Close(); |
+ } |
+} |
+ |
+void WebNotificationBubbleWrapper::OnWidgetClosing( |
+ views::Widget* widget) { |
+ if (widget == bubble_widget_) { |
+ bubble_widget_->RemoveObserver(this); |
+ bubble_widget_->Close(); |
+ if (bubble_view_) { |
+ tray_->HideBubble(bubble_view_); |
+ } |
+ } |
+} |
+ |
+} // namespace |
+ |
+namespace ui { |
+ |
+MessageCenterTray::MessageCenterTray(MessageCenterTrayHost* host) |
+ : host_(host) { |
+ message_center_ = new message_center::MessageCenter(); |
+ message_center_->AddObserver(this); |
+} |
+ |
+MessageCenterTray::~MessageCenterTray() { |
+ message_center_->RemoveObserver(this); |
+ popup_bubble_.reset(); |
+} |
+ |
+void MessageCenterTray::ShowMessageCenterBubble() { |
+ if (message_center_bubble_.get()) |
+ return; |
+ |
+ host_->OnShowMessageCenterBubble(); |
+ |
+ message_center_->SetMessageCenterVisible(true); |
+ OnChanged(); |
+ HidePopupBubble(); |
+ |
+ message_center::MessageCenterBubble* bubble = |
+ new message_center::MessageCenterBubble(message_center_); |
+ // Delegate to the host to find the system-specific anchor alignment, and to |
+ // modify the InitParams as necessary. |
+ views::TrayBubbleView::AnchorAlignment alignment = |
+ host_->GetAnchorAlignment(); |
+ views::TrayBubbleView::InitParams init_params = |
+ bubble->GetInitParams(alignment); |
+ host_->UpdateInitParams(&init_params); |
+ message_center_bubble_.reset(new WebNotificationBubbleWrapper( |
+ this, |
+ bubble, |
+ init_params, |
+ host_->GetBubbleWindowContainer(), |
+ host_->GetAnchorView())); |
+} |
+ |
+bool MessageCenterTray::HideMessageCenterBubble() { |
+ if (!message_center_bubble_.get()) |
+ return false; |
+ |
+ host_->OnHideMessageCenterBubble(); |
+ |
+ message_center_bubble_.reset(); |
+ message_center_->SetMessageCenterVisible(false); |
+ OnChanged(); |
+ return true; |
+} |
+ |
+void MessageCenterTray::ToggleMessageCenterBubble() { |
+ if (message_center_bubble_.get()) { |
+ HideMessageCenterBubble(); |
+ } else { |
+ ShowMessageCenterBubble(); |
+ } |
+} |
+ |
+void MessageCenterTray::ShowPopupBubble() { |
+ if (!host_->CanShowPopups()) |
+ return; |
+ if (message_center_bubble_) |
+ return; |
+ |
+ OnChanged(); |
+ |
+ // If there is already a popup bubble, just update it. |
+ if (popup_bubble_) { |
+ popup_bubble_->message_bubble()->ScheduleUpdate(); |
+ return; |
+ } |
+ if (message_center_->HasPopupNotifications()) { |
+ message_center::MessagePopupBubble* bubble = |
+ new message_center::MessagePopupBubble(message_center_); |
+ views::TrayBubbleView::AnchorAlignment alignment = |
+ host_->GetAnchorAlignment(); |
+ views::TrayBubbleView::InitParams init_params = |
+ bubble->GetInitParams(alignment); |
+ host_->UpdateInitParams(&init_params); |
+ |
+ // Delegate to the host to find the system-specific anchor alignment, and to |
+ // modify the InitParams as necessary. |
+ popup_bubble_.reset(new WebNotificationBubbleWrapper( |
+ this, |
+ bubble, |
+ init_params, |
+ host_->GetBubbleWindowContainer(), |
+ host_->GetAnchorView())); |
+ bubble->ScheduleUpdate(); |
+ } |
+} |
+ |
+bool MessageCenterTray::HidePopupBubble() { |
+ if (!popup_bubble_.get()) |
+ return false; |
+ popup_bubble_.reset(); |
+ return true; |
+} |
+ |
+views::TrayBubbleView* MessageCenterTray::GetPopupBubbleView() { |
+ if (popup_bubble_.get()) |
+ return popup_bubble_->bubble_view(); |
+ return NULL; |
+} |
+ |
+views::TrayBubbleView* MessageCenterTray::GetMessageCenterBubbleView() { |
+ if (message_center_bubble_.get()) |
+ return message_center_bubble_->bubble_view(); |
+ return NULL; |
+} |
+ |
+void MessageCenterTray::BubbleViewDestroyed() { |
+ if (message_center_bubble_.get()) |
+ message_center_bubble_->message_bubble()->BubbleViewDestroyed(); |
+ if (popup_bubble_.get()) |
+ popup_bubble_->message_bubble()->BubbleViewDestroyed(); |
+} |
+ |
+void MessageCenterTray::OnMouseEnteredView() { |
+ if (popup_bubble_.get()) |
+ popup_bubble_->message_bubble()->OnMouseEnteredView(); |
+} |
+ |
+void MessageCenterTray::OnMouseExitedView() { |
+ if (popup_bubble_.get()) |
+ popup_bubble_->message_bubble()->OnMouseExitedView(); |
+} |
+ |
+string16 MessageCenterTray::GetAccessibleNameForBubble() { |
+ return host_->GetAccessibleNameForBubble(); |
+} |
+ |
+gfx::Rect MessageCenterTray::GetAnchorRect(views::Widget* anchor_widget, |
+ AnchorType anchor_type, |
+ AnchorAlignment anchor_alignment) { |
+ return host_->GetAnchorRect(anchor_widget, anchor_type, anchor_alignment); |
+} |
+ |
+void MessageCenterTray::HideBubble(const views::TrayBubbleView* bubble_view) { |
+ if (message_center_bubble_.get() && |
+ bubble_view == message_center_bubble_->bubble_view()) { |
+ HideMessageCenterBubble(); |
+ } else if (popup_bubble_.get() && |
+ bubble_view == popup_bubble_->bubble_view()) { |
+ HidePopupBubble(); |
+ } |
+} |
+ |
+void MessageCenterTray::OnMessageCenterChanged(bool new_notification) { |
+ if (message_center_bubble_.get()) { |
+ if (message_center_->NotificationCount() == 0) |
+ HideMessageCenterBubble(); |
+ else |
+ message_center_bubble_->message_bubble()->ScheduleUpdate(); |
+ } |
+ if (popup_bubble_.get()) { |
+ if (message_center_->NotificationCount() == 0) |
+ HidePopupBubble(); |
+ else |
+ popup_bubble_->message_bubble()->ScheduleUpdate(); |
+ } |
+ |
+ OnChanged(); |
+ if (new_notification) |
+ ShowPopupBubble(); |
+} |
+ |
+void MessageCenterTray::OnChanged() { |
+ host_->OnMessageCenterTrayChanged(); |
+} |
+ |
+} // namespace ui |