This source file includes following definitions.
- GetToastSizeForView
 
- closing_animation_
 
- SetContents
 
- RevealWithAnimation
 
- CloseWithAnimation
 
- SetBoundsInstantly
 
- SetBoundsWithAnimation
 
- StartFadeIn
 
- StartFadeOut
 
- OnBoundsAnimationEndedOrCancelled
 
- AnimationProgressed
 
- AnimationEnded
 
- AnimationCanceled
 
- GetContentsView
 
- WindowClosing
 
- CanActivate
 
- OnDisplayChanged
 
- OnWorkAreaChanged
 
- OnMouseEntered
 
- OnMouseExited
 
- Layout
 
- GetPreferredSize
 
- GetAccessibleState
 
- ClickOnNotification
 
- RemoveNotification
 
- CreateMenuModel
 
- HasClickedListener
 
- ClickOnNotificationButton
 
- CreateWidget
 
- GetClosedToastBounds
 
#include "ui/message_center/views/toast_contents_view.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.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 {
const int kClosedToastWidth = 5;
const int kFadeInOutDuration = 200;
}  
gfx::Size ToastContentsView::GetToastSizeForView(views::View* view) {
  int width = kNotificationWidth + view->GetInsets().width();
  return gfx::Size(width, view->GetHeightForWidth(width));
}
ToastContentsView::ToastContentsView(
    const std::string& notification_id,
    base::WeakPtr<MessagePopupCollection> collection)
    : collection_(collection),
      id_(notification_id),
      is_animating_bounds_(false),
      is_closing_(false),
      closing_animation_(NULL) {
  set_notify_enter_exit_on_child(true);
  
  
  
  set_background(views::Background::CreateSolidBackground(0, 0, 0, 0));
  fade_animation_.reset(new gfx::SlideAnimation(this));
  fade_animation_->SetSlideDuration(kFadeInOutDuration);
  CreateWidget(collection->parent());
}
ToastContentsView::~ToastContentsView() {
  if (collection_)
    collection_->ForgetToast(this);
}
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 (already_has_contents && a11y_feedback_for_updates)
    NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, false);
}
void ToastContentsView::RevealWithAnimation(gfx::Point origin) {
  
  
  
  
  
  origin_ = gfx::Point(origin.x() - preferred_size_.width(),
                       origin.y() - preferred_size_.height());
  gfx::Rect stable_bounds(origin_, preferred_size_);
  SetBoundsInstantly(GetClosedToastBounds(stable_bounds));
  StartFadeIn();
  SetBoundsWithAnimation(stable_bounds);
}
void ToastContentsView::CloseWithAnimation() {
  if (is_closing_)
    return;
  is_closing_ = true;
  StartFadeOut();
}
void ToastContentsView::SetBoundsInstantly(gfx::Rect new_bounds) {
  if (new_bounds == bounds())
    return;
  origin_ = new_bounds.origin();
  if (!GetWidget())
    return;
  GetWidget()->SetBounds(new_bounds);
}
void ToastContentsView::SetBoundsWithAnimation(gfx::Rect new_bounds) {
  if (new_bounds == bounds())
    return;
  origin_ = new_bounds.origin();
  if (!GetWidget())
    return;
  
  
  
  
  animated_bounds_start_ = GetWidget()->GetWindowBoundsInScreen();
  animated_bounds_end_ = new_bounds;
  if (collection_)
    collection_->IncrementDeferCounter();
  if (bounds_animation_.get())
    bounds_animation_->Stop();
  bounds_animation_.reset(new gfx::SlideAnimation(this));
  bounds_animation_->Show();
}
void ToastContentsView::StartFadeIn() {
  
  if (collection_)
    collection_->IncrementDeferCounter();
  fade_animation_->Stop();
  GetWidget()->SetOpacity(0);
  GetWidget()->ShowInactive();
  fade_animation_->Reset(0);
  fade_animation_->Show();
}
void ToastContentsView::StartFadeOut() {
  
  if (collection_)
    collection_->IncrementDeferCounter();
  fade_animation_->Stop();
  closing_animation_ = (is_closing_ ? fade_animation_.get() : NULL);
  fade_animation_->Reset(1);
  fade_animation_->Hide();
}
void ToastContentsView::OnBoundsAnimationEndedOrCancelled(
    const gfx::Animation* animation) {
  if (is_closing_ && closing_animation_ == animation && GetWidget()) {
    views::Widget* widget = GetWidget();
#if defined(USE_AURA)
    
    
    
    
    widget->Hide();
# if defined(OS_WIN)
    widget->SetOpacity(0xFF);
# endif
#endif
    widget->Close();
  }
  
  
  
  
  if (collection_)
    collection_->DecrementDeferCounter();
}
void ToastContentsView::AnimationProgressed(const gfx::Animation* animation) {
  if (animation == bounds_animation_.get()) {
    gfx::Rect current(animation->CurrentValueBetween(
        animated_bounds_start_, animated_bounds_end_));
    GetWidget()->SetBounds(current);
  } else if (animation == fade_animation_.get()) {
    unsigned char opacity =
        static_cast<unsigned char>(fade_animation_->GetCurrentValue() * 255);
    GetWidget()->SetOpacity(opacity);
  }
}
void ToastContentsView::AnimationEnded(const gfx::Animation* animation) {
  OnBoundsAnimationEndedOrCancelled(animation);
}
void ToastContentsView::AnimationCanceled(
    const gfx::Animation* animation) {
  OnBoundsAnimationEndedOrCancelled(animation);
}
views::View* ToastContentsView::GetContentsView() {
  return this;
}
void ToastContentsView::WindowClosing() {
  if (!is_closing_ && collection_.get())
    collection_->ForgetToast(this);
}
bool ToastContentsView::CanActivate() const {
  return false;
}
void ToastContentsView::OnDisplayChanged() {
  views::Widget* widget = GetWidget();
  if (!widget)
    return;
  gfx::NativeView native_view = widget->GetNativeView();
  if (!native_view || !collection_.get())
    return;
  collection_->OnDisplayBoundsChanged(gfx::Screen::GetScreenFor(
      native_view)->GetDisplayNearestWindow(native_view));
}
void ToastContentsView::OnWorkAreaChanged() {
  views::Widget* widget = GetWidget();
  if (!widget)
    return;
  gfx::NativeView native_view = widget->GetNativeView();
  if (!native_view || !collection_.get())
    return;
  collection_->OnDisplayBoundsChanged(gfx::Screen::GetScreenFor(
      native_view)->GetDisplayNearestWindow(native_view));
}
void ToastContentsView::OnMouseEntered(const ui::MouseEvent& event) {
  if (collection_)
    collection_->OnMouseEntered(this);
}
void ToastContentsView::OnMouseExited(const ui::MouseEvent& event) {
  if (collection_)
    collection_->OnMouseExited(this);
}
void ToastContentsView::Layout() {
  if (child_count() > 0) {
    child_at(0)->SetBounds(
        0, 0, preferred_size_.width(), preferred_size_.height());
  }
}
gfx::Size ToastContentsView::GetPreferredSize() {
  return child_count() ? GetToastSizeForView(child_at(0)) : gfx::Size();
}
void ToastContentsView::GetAccessibleState(ui::AXViewState* state) {
  if (child_count() > 0)
    child_at(0)->GetAccessibleState(state);
  state->role = ui::AX_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) {
  
  
  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)
  
  
  
  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(),
                   kClosedToastWidth,
                   bounds.height());
}
}