#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"
-#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_style.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/views/message_popup_collection.h"
#include "ui/message_center/views/message_view.h"
+#include "ui/views/background.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
+#if defined(OS_WIN) && defined(USE_ASH)
+#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
+#endif
+
namespace message_center {
namespace {
}
ToastContentsView::ToastContentsView(
- const Notification* notification,
- base::WeakPtr<MessagePopupCollection> collection,
- MessageCenter* message_center)
+ const std::string& notification_id,
+ base::WeakPtr<MessagePopupCollection> collection)
: collection_(collection),
- message_center_(message_center),
- id_(notification->id()),
+ id_(notification_id),
is_animating_bounds_(false),
is_closing_(false),
closing_animation_(NULL) {
- DCHECK(collection_);
-
set_notify_enter_exit_on_child(true);
// Sets the transparent background. Then, when the message view is slid out,
// the whole toast seems to slide although the actual bound of the widget
fade_animation_.reset(new gfx::SlideAnimation(this));
fade_animation_->SetSlideDuration(kFadeInOutDuration);
+
+ CreateWidget(collection->parent());
}
// This is destroyed when the toast window closes.
ToastContentsView::~ToastContentsView() {
+ if (collection_)
+ collection_->ForgetToast(this);
}
-views::Widget* ToastContentsView::CreateWidget(gfx::NativeView parent) {
- views::Widget::InitParams params(
- views::Widget::InitParams::TYPE_POPUP);
- params.keep_on_top = true;
- if (parent)
- params.parent = parent;
- else
- params.top_level = true;
- params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
- params.delegate = this;
- views::Widget* widget = new views::Widget();
- widget->set_focus_on_creation(false);
- widget->Init(params);
- return widget;
-}
-
-void ToastContentsView::SetContents(MessageView* view) {
+void ToastContentsView::SetContents(MessageView* view,
+ bool a11y_feedback_for_updates) {
bool already_has_contents = child_count() > 0;
RemoveAllChildViews(true);
AddChildView(view);
preferred_size_ = GetToastSizeForView(view);
Layout();
+
// If it has the contents already, this invocation means an update of the
// popup toast, and the new contents should be read through a11y feature.
// The notification type should be ALERT, otherwise the accessibility message
// won't be read for this view which returns ROLE_WINDOW.
- if (already_has_contents) {
- const NotificationList::Notifications& notifications =
- message_center_->GetVisibleNotifications();
- for (NotificationList::Notifications::const_iterator iter =
- notifications.begin(); iter != notifications.end(); ++iter) {
- if ((*iter)->id() != id_)
- continue;
-
- const RichNotificationData& optional = (*iter)->rich_notification_data();
- if (optional.should_make_spoken_feedback_for_popup_updates)
- NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, false);
- break;
- }
- }
+ if (already_has_contents && a11y_feedback_for_updates)
+ NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, false);
}
void ToastContentsView::RevealWithAnimation(gfx::Point origin) {
SetBoundsWithAnimation(stable_bounds);
}
-void ToastContentsView::CloseWithAnimation(bool mark_as_shown) {
+void ToastContentsView::CloseWithAnimation() {
if (is_closing_)
return;
is_closing_ = true;
- if (collection_)
- collection_->RemoveToast(this);
- if (mark_as_shown)
- message_center_->MarkSinglePopupAsShown(id(), false);
StartFadeOut();
}
fade_animation_->Stop();
GetWidget()->SetOpacity(0);
- GetWidget()->Show();
+ GetWidget()->ShowInactive();
fade_animation_->Reset(0);
fade_animation_->Show();
}
}
void ToastContentsView::WindowClosing() {
- if (!is_closing_ && collection_)
- collection_->RemoveToast(this);
+ if (!is_closing_ && collection_.get())
+ collection_->ForgetToast(this);
}
bool ToastContentsView::CanActivate() const {
-#if defined(OS_WIN) && defined(USE_AURA)
- return true;
-#else
return false;
-#endif
}
void ToastContentsView::OnDisplayChanged() {
return;
gfx::NativeView native_view = widget->GetNativeView();
- if (!native_view || !collection_)
+ if (!native_view || !collection_.get())
return;
collection_->OnDisplayBoundsChanged(gfx::Screen::GetScreenFor(
return;
gfx::NativeView native_view = widget->GetNativeView();
- if (!native_view || !collection_)
+ if (!native_view || !collection_.get())
return;
collection_->OnDisplayBoundsChanged(gfx::Screen::GetScreenFor(
state->role = ui::AccessibilityTypes::ROLE_WINDOW;
}
+void ToastContentsView::ClickOnNotification(
+ const std::string& notification_id) {
+ if (collection_)
+ collection_->ClickOnNotification(notification_id);
+}
+
+void ToastContentsView::RemoveNotification(
+ const std::string& notification_id,
+ bool by_user) {
+ if (collection_)
+ collection_->RemoveNotification(notification_id, by_user);
+}
+
+scoped_ptr<ui::MenuModel> ToastContentsView::CreateMenuModel(
+ const NotifierId& notifier_id,
+ const base::string16& display_source) {
+ // Should not reach, the context menu should be handled in
+ // MessagePopupCollection.
+ NOTREACHED();
+ return scoped_ptr<ui::MenuModel>();
+}
+
+bool ToastContentsView::HasClickedListener(
+ const std::string& notification_id) {
+ if (!collection_)
+ return false;
+ return collection_->HasClickedListener(notification_id);
+}
+
+void ToastContentsView::ClickOnNotificationButton(
+ const std::string& notification_id,
+ int button_index) {
+ if (collection_)
+ collection_->ClickOnNotificationButton(notification_id, button_index);
+}
+
+void ToastContentsView::CreateWidget(gfx::NativeView parent) {
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
+ params.keep_on_top = true;
+ if (parent)
+ params.parent = parent;
+ else
+ params.top_level = true;
+ params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
+ params.delegate = this;
+ views::Widget* widget = new views::Widget();
+ widget->set_focus_on_creation(false);
+
+#if defined(OS_WIN) && defined(USE_ASH)
+ // We want to ensure that this toast always goes to the native desktop,
+ // not the Ash desktop (since there is already another toast contents view
+ // there.
+ if (!params.parent)
+ params.native_widget = new views::DesktopNativeWidgetAura(widget);
+#endif
+
+ widget->Init(params);
+}
+
gfx::Rect ToastContentsView::GetClosedToastBounds(gfx::Rect bounds) {
return gfx::Rect(bounds.x() + bounds.width() - kClosedToastWidth,
bounds.y(),