From 36d5e559795e48dec168fa824129aa55b5b165bc Mon Sep 17 00:00:00 2001
From: "sky@chromium.org"
 <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Mon, 15 Nov 2010 20:45:59 +0000
Subject: [PATCH] Makes the current page dim out when transitioning to instant
 preview.

BUG=none
TEST=none

Review URL: http://codereview.chromium.org/4932001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66164 0039d316-1c4b-4281-b951-d872f2087c98
---
 chrome/browser/cocoa/browser_window_cocoa.h   |  1 +
 chrome/browser/cocoa/browser_window_cocoa.mm  |  4 ++
 chrome/browser/gtk/browser_window_gtk.cc      |  4 ++
 chrome/browser/gtk/browser_window_gtk.h       |  1 +
 chrome/browser/instant/instant_controller.cc  |  3 +
 chrome/browser/instant/instant_delegate.h     |  5 ++
 chrome/browser/ui/browser.cc                  |  8 ++-
 chrome/browser/ui/browser.h                   |  1 +
 chrome/browser/ui/browser_window.h            |  3 +
 chrome/browser/ui/views/frame/browser_view.cc | 14 +++++
 chrome/browser/ui/views/frame/browser_view.h  |  1 +
 .../ui/views/frame/contents_container.cc      | 62 +++++++++++++++++++
 .../ui/views/frame/contents_container.h       | 25 +++++++-
 chrome/test/test_browser_window.h             |  1 +
 14 files changed, 129 insertions(+), 4 deletions(-)

diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h
index 9a46f7de1c8be..5722fff546a2b 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/cocoa/browser_window_cocoa.h
@@ -107,6 +107,7 @@ class BrowserWindowCocoa : public BrowserWindow,
   virtual void Paste();
   virtual void ToggleTabStripMode();
   virtual void OpenTabpose();
+  virtual void PrepareForInstant();
   virtual void ShowInstant(TabContents* preview_contents);
   virtual void HideInstant();
   virtual gfx::Rect GetInstantBounds();
diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm
index 5e21af0f0fb40..8695325d884b8 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/cocoa/browser_window_cocoa.mm
@@ -577,6 +577,10 @@ void BrowserWindowCocoa::OpenTabpose() {
   [controller_ openTabpose];
 }
 
+void BrowserWindowCocoa::PrepareForInstant() {
+  // TODO: implement fade as done on windows.
+}
+
 void BrowserWindowCocoa::ShowInstant(TabContents* preview_contents) {
   [controller_ showInstant:preview_contents];
 }
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index 6d537c96a6930..d7ea5fb87b61f 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -1127,6 +1127,10 @@ void BrowserWindowGtk::Paste() {
   DoCutCopyPaste(this, &RenderViewHost::Paste, "paste-clipboard");
 }
 
+void BrowserWindowGtk::PrepareForInstant() {
+  // TODO: implement fade as done on windows.
+}
+
 void BrowserWindowGtk::ShowInstant(TabContents* preview_contents) {
   contents_container_->SetPreviewContents(preview_contents);
 }
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index ce8e5825f979c..7711a2a26eb11 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -125,6 +125,7 @@ class BrowserWindowGtk : public BrowserWindow,
   virtual void Copy();
   virtual void Paste();
   virtual void ToggleTabStripMode() {}
+  virtual void PrepareForInstant();
   virtual void ShowInstant(TabContents* preview_contents);
   virtual void HideInstant();
   virtual gfx::Rect GetInstantBounds();
diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc
index 151308c538ab0..001e238e7e57c 100644
--- a/chrome/browser/instant/instant_controller.cc
+++ b/chrome/browser/instant/instant_controller.cc
@@ -93,6 +93,9 @@ void InstantController::Update(TabContents* tab_contents,
   if (!loader_manager_.get())
     loader_manager_.reset(new InstantLoaderManager(this));
 
+  if (!is_active_)
+    delegate_->PrepareForInstant();
+
   if (ShouldUpdateNow(template_url_id, match.destination_url)) {
     UpdateLoader(template_url, match.destination_url, match.transition,
                  user_text, suggested_text);
diff --git a/chrome/browser/instant/instant_delegate.h b/chrome/browser/instant/instant_delegate.h
index a5c922359c7c2..90f58a2cf6925 100644
--- a/chrome/browser/instant/instant_delegate.h
+++ b/chrome/browser/instant/instant_delegate.h
@@ -18,6 +18,11 @@ class Rect;
 // InstantController for details.
 class InstantDelegate {
  public:
+  // Invoked when instant starts loading, but before the preview tab contents is
+  // ready to be shown. This may be used to animate between the states.
+  // This is followed by ShowInstant and/or HideInstant.
+  virtual void PrepareForInstant() = 0;
+
   // Invoked when the instant TabContents should be shown.
   virtual void ShowInstant(TabContents* preview_contents) = 0;
 
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 3d8f3c5881747..5f31db8d62f90 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -26,9 +26,6 @@
 #include "gfx/point.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/autofill/autofill_manager.h"
-#if defined(OS_WIN)
-#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
-#endif  // defined(OS_WIN)
 #include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_utils.h"
 #include "chrome/browser/browser_list.h"
@@ -115,6 +112,7 @@
 
 #if defined(OS_WIN)
 #include "app/win_util.h"
+#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h"
 #include "chrome/browser/browser_child_process_host.h"
 #include "chrome/browser/cert_store.h"
 #include "chrome/browser/download/save_package.h"
@@ -3337,6 +3335,10 @@ void Browser::OnStateChanged() {
 ///////////////////////////////////////////////////////////////////////////////
 // Browser, InstantDelegate implementation:
 
+void Browser::PrepareForInstant() {
+  window_->PrepareForInstant();
+}
+
 void Browser::ShowInstant(TabContents* preview_contents) {
   DCHECK(instant_->tab_contents() == GetSelectedTabContents());
   window_->ShowInstant(preview_contents);
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index abd2be99be1fa..25e705eb9738f 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -773,6 +773,7 @@ class Browser : public TabHandlerDelegate,
   virtual void OnStateChanged();
 
   // Overriden from InstantDelegate:
+  virtual void PrepareForInstant();
   virtual void ShowInstant(TabContents* preview_contents);
   virtual void HideInstant();
   virtual void CommitInstant(TabContents* preview_contents);
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index c365a27f0ecc0..aa3a931db2894 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -322,6 +322,9 @@ class BrowserWindow {
   virtual void OpenTabpose() = 0;
 #endif
 
+  // See InstantDelegate for details.
+  virtual void PrepareForInstant() = 0;
+
   // Invoked when instant's tab contents should be shown.
   virtual void ShowInstant(TabContents* preview_contents) = 0;
 
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 25d8467da6d11..2629725c111d5 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1362,11 +1362,24 @@ void BrowserView::ToggleTabStripMode() {
   frame_->TabStripDisplayModeChanged();
 }
 
+void BrowserView::PrepareForInstant() {
+  contents_->FadeActiveContents();
+}
+
 void BrowserView::ShowInstant(TabContents* preview_contents) {
   if (!preview_container_)
     preview_container_ = new TabContentsContainer();
   contents_->SetPreview(preview_container_, preview_contents);
   preview_container_->ChangeTabContents(preview_contents);
+
+#if defined(OS_WIN)
+  // Removing the fade is instant (on windows). We need to force the preview to
+  // draw, otherwise the current page flickers before the new page appears.
+  RedrawWindow(preview_contents->view()->GetContentNativeView(), NULL, NULL,
+               RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN);
+#endif
+
+  contents_->RemoveFade();
 }
 
 void BrowserView::HideInstant() {
@@ -1378,6 +1391,7 @@ void BrowserView::HideInstant() {
   contents_->SetPreview(NULL, NULL);
   delete preview_container_;
   preview_container_ = NULL;
+  contents_->RemoveFade();
 }
 
 gfx::Rect BrowserView::GetInstantBounds() {
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 8a443bb8e62e4..f57a2d3481edf 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -319,6 +319,7 @@ class BrowserView : public BrowserBubbleHost,
   virtual void Copy();
   virtual void Paste();
   virtual void ToggleTabStripMode();
+  virtual void PrepareForInstant();
   virtual void ShowInstant(TabContents* preview_contents);
   virtual void HideInstant();
   virtual gfx::Rect GetInstantBounds();
diff --git a/chrome/browser/ui/views/frame/contents_container.cc b/chrome/browser/ui/views/frame/contents_container.cc
index c3056f794c1ba..084c87f7cda3e 100644
--- a/chrome/browser/ui/views/frame/contents_container.cc
+++ b/chrome/browser/ui/views/frame/contents_container.cc
@@ -4,18 +4,33 @@
 
 #include "chrome/browser/views/frame/contents_container.h"
 
+#include "app/slide_animation.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "views/background.h"
+#include "views/widget/root_view.h"
+#include "views/widget/widget.h"
+
+// Min/max opacity of the overlay.
+static const int kMinOpacity = 0;
+static const int kMaxOpacity = 192;
+
 ContentsContainer::ContentsContainer(views::View* active)
     : active_(active),
       preview_(NULL),
       preview_tab_contents_(NULL),
+      active_overlay_(NULL),
       active_top_margin_(0) {
   AddChildView(active_);
 }
 
 ContentsContainer::~ContentsContainer() {
+  // We don't need to explicitly delete active_overlay_ as it'll be deleted by
+  // virtue of being a child window.
 }
 
 void ContentsContainer::MakePreviewContentsActiveContents() {
+  RemoveFade();
+
   active_ = preview_;
   preview_ = NULL;
   Layout();
@@ -52,6 +67,53 @@ gfx::Rect ContentsContainer::GetPreviewBounds() {
   return gfx::Rect(screen_loc, size());
 }
 
+void ContentsContainer::FadeActiveContents() {
+  if (active_overlay_)
+    return;
+
+#if !defined(OS_WIN)
+  // TODO: fix this. I'm disabling as z-order isn't right on linux so that
+  // overlay ends up obscuring the omnibox.
+  return;
+#endif
+
+  overlay_animation_.reset(new SlideAnimation(this));
+  overlay_animation_->SetDuration(300);
+  overlay_animation_->SetSlideDuration(300);
+  overlay_animation_->Show();
+
+  active_overlay_ = views::Widget::CreatePopupWidget(views::Widget::Transparent,
+                                              views::Widget::NotAcceptEvents,
+                                              views::Widget::DeleteOnDestroy,
+                                              views::Widget::MirrorOriginInRTL);
+  active_overlay_->SetOpacity(0);
+  gfx::Point screen_origin;
+  views::View::ConvertPointToScreen(active_, &screen_origin);
+  gfx::Rect overlay_bounds(screen_origin, active_->size());
+  active_overlay_->Init(active_->GetWidget()->GetNativeView(), overlay_bounds);
+  views::View* content_view = new views::View();
+  content_view->set_background(
+      views::Background::CreateSolidBackground(SK_ColorWHITE));
+  active_overlay_->SetContentsView(content_view);
+  active_overlay_->Show();
+  active_overlay_->MoveAbove(active_->GetWidget());
+}
+
+void ContentsContainer::RemoveFade() {
+  overlay_animation_.reset();
+  if (active_overlay_) {
+    active_overlay_->Close();
+    active_overlay_ = NULL;
+  }
+}
+
+void ContentsContainer::AnimationProgressed(const Animation* animation) {
+  active_overlay_->SetOpacity(
+      Tween::ValueBetween(animation->GetCurrentValue(), kMinOpacity,
+                          kMaxOpacity));
+  active_overlay_->GetRootView()->SchedulePaint();
+}
+
 void ContentsContainer::Layout() {
   // The active view always gets the full bounds.
   active_->SetBounds(0, active_top_margin_, width(),
diff --git a/chrome/browser/ui/views/frame/contents_container.h b/chrome/browser/ui/views/frame/contents_container.h
index 8943f0a66e584..9f25c6b0a7eb1 100644
--- a/chrome/browser/ui/views/frame/contents_container.h
+++ b/chrome/browser/ui/views/frame/contents_container.h
@@ -6,14 +6,21 @@
 #define CHROME_BROWSER_UI_VIEWS_FRAME_CONTENTS_CONTAINER_H_
 #pragma once
 
+#include "app/animation.h"
+#include "base/scoped_ptr.h"
 #include "views/view.h"
 
+class SlideAnimation;
 class TabContents;
 
+namespace views {
+class Widget;
+}
+
 // ContentsContainer is responsible for managing the TabContents views.
 // ContentsContainer has up to two children: one for the currently active
 // TabContents and one for instant's TabContents.
-class ContentsContainer : public views::View {
+class ContentsContainer : public views::View, public AnimationDelegate {
  public:
   explicit ContentsContainer(views::View* active);
   virtual ~ContentsContainer();
@@ -35,9 +42,18 @@ class ContentsContainer : public views::View {
   // retuns the bounds the preview would be shown at.
   gfx::Rect GetPreviewBounds();
 
+  // Fades out the active contents.
+  void FadeActiveContents();
+
+  // Removes the fade. This is done implicitly when the preview is made active.
+  void RemoveFade();
+
   // View overrides:
   virtual void Layout();
 
+  // AnimationDelegate overrides:
+  virtual void AnimationProgressed(const Animation* animation);
+
  private:
   views::View* active_;
 
@@ -45,6 +61,13 @@ class ContentsContainer : public views::View {
 
   TabContents* preview_tab_contents_;
 
+  // Translucent Widget positioned right above the active view that is used to
+  // make the active view appear faded out.
+  views::Widget* active_overlay_;
+
+  // Animation used to vary the opacity of active_overlay.
+  scoped_ptr<SlideAnimation> overlay_animation_;
+
   // The margin between the top and the active view. This is used to make the
   // preview overlap the bookmark bar on the new tab page.
   int active_top_margin_;
diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h
index c54deac0e507e..e60952e7b6332 100644
--- a/chrome/test/test_browser_window.h
+++ b/chrome/test/test_browser_window.h
@@ -103,6 +103,7 @@ class TestBrowserWindow : public BrowserWindow {
   virtual void Paste() {}
   virtual void ToggleTabStripMode() {}
   virtual void OpenTabpose() {}
+  virtual void PrepareForInstant() {}
   virtual void ShowInstant(TabContents* preview_contents) {}
   virtual void HideInstant() {}
   virtual gfx::Rect GetInstantBounds() { return gfx::Rect(); }
-- 
GitLab