diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h index 9a46f7de1c8be0be7610e071faf4a11fe417c9b1..5722fff546a2be0ef776b2dc57c0799210389ba3 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 5e21af0f0fb4041f429297bc6ccfaa241b68bf41..8695325d884b836129be66fcfa4517424e237323 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 6d537c96a6930fe4e531dc11e71fc82a3b28256d..d7ea5fb87b61fedf9e42bc8227e60d0c7b7b2865 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 ce8e5825f979cd65e4163570cf3744e78dc63711..7711a2a26eb11f16d9e067d17c854ba5b30b5dd4 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 151308c538ab07c28988c54d03ed55faabfb22a7..001e238e7e57cdf505e51352195570a6040338c2 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 a5c922359c7c210f67a3bbb840519286381712d4..90f58a2cf6925c8bc983e6ac2da455d8b8e53ac0 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 3d8f3c58817471e6b3de4e7720c35a2efc163ddc..5f31db8d62f90022bab3f17cfe325ce09b80dfa1 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 abd2be99be1fa287c19c756883cb83837d14e39d..25e705eb9738fb42ad0190972c4ee37dcf1f61d4 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 c365a27f0ecc0b79bc9b7b1f30ffb62b93f58bd4..aa3a931db2894a8b26a684a3d1ca19a3d3d97286 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 25d8467da6d11230c666fbc4b29fdbc711836822..2629725c111d58af2aed66fa7b399c9e0afdd281 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 8a443bb8e62e4448a0cfa93f9187a0224772653e..f57a2d3481edf8b4c0a2ccdc332049d9be40ae7c 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 c3056f794c1bae32a7fef3a4d53838dd82a89b5b..084c87f7cda3e1f73fb423c599a5c9d027497a95 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 8943f0a66e58466c1bcab1e825ec7387eb64a819..9f25c6b0a7eb1634dda463af4bfef8db645a3792 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 c54deac0e507ed9726674b02c81d14995baaceeb..e60952e7b63327c2a13987194c389d0494739b41 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(); }