summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-06 01:33:44 +0000
committersadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-06 01:33:44 +0000
commit5def89eb4f851f06ed7d322ec5308aae6d50fd6b (patch)
tree0f444fb952f841f8405e15a2f78a16fc28de752d
parent398fb9a7e86ba438559268e645d9b992fecc9f6c (diff)
downloadchromium_src-5def89eb4f851f06ed7d322ec5308aae6d50fd6b.zip
chromium_src-5def89eb4f851f06ed7d322ec5308aae6d50fd6b.tar.gz
chromium_src-5def89eb4f851f06ed7d322ec5308aae6d50fd6b.tar.bz2
gesture-nav: Move OverscrollNavigationOverlay into its own file.
BUG=340751 R=mfomitchev@chromium.org, piman@chromium.org, sky@chromium.org Review URL: https://codereview.chromium.org/132203013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249200 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/web_contents/aura/overscroll_navigation_overlay.cc212
-rw-r--r--content/browser/web_contents/aura/overscroll_navigation_overlay.h105
-rw-r--r--content/browser/web_contents/web_contents_view_aura.cc244
-rw-r--r--content/content_browser.gypi2
4 files changed, 320 insertions, 243 deletions
diff --git a/content/browser/web_contents/aura/overscroll_navigation_overlay.cc b/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
new file mode 100644
index 0000000..b82c248
--- /dev/null
+++ b/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
@@ -0,0 +1,212 @@
+// Copyright 2014 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 "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
+
+#include "content/browser/frame_host/navigation_entry_impl.h"
+#include "content/browser/web_contents/aura/image_window_delegate.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "ui/aura/window.h"
+#include "ui/compositor/layer.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/image/image_png_rep.h"
+#include "ui/gfx/image/image_skia.h"
+
+namespace content {
+
+// A LayerDelegate that paints an image for the layer.
+class ImageLayerDelegate : public ui::LayerDelegate {
+ public:
+ ImageLayerDelegate() {}
+
+ virtual ~ImageLayerDelegate() {}
+
+ void SetImage(const gfx::Image& image) {
+ image_ = image;
+ image_size_ = image.AsImageSkia().size();
+ }
+ const gfx::Image& image() const { return image_; }
+
+ private:
+ // Overridden from ui::LayerDelegate:
+ virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
+ if (image_.IsEmpty()) {
+ canvas->DrawColor(SK_ColorGRAY);
+ } else {
+ SkISize size = canvas->sk_canvas()->getDeviceSize();
+ if (size.width() != image_size_.width() ||
+ size.height() != image_size_.height()) {
+ canvas->DrawColor(SK_ColorWHITE);
+ }
+ canvas->DrawImageInt(image_.AsImageSkia(), 0, 0);
+ }
+ }
+
+ // Called when the layer's device scale factor has changed.
+ virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
+ }
+
+ // Invoked prior to the bounds changing. The returned closured is run after
+ // the bounds change.
+ virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
+ return base::Closure();
+ }
+
+ gfx::Image image_;
+ gfx::Size image_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(ImageLayerDelegate);
+};
+
+OverscrollNavigationOverlay::OverscrollNavigationOverlay(
+ WebContentsImpl* web_contents)
+ : web_contents_(web_contents),
+ image_delegate_(NULL),
+ loading_complete_(false),
+ received_paint_update_(false),
+ slide_direction_(SLIDE_UNKNOWN),
+ need_paint_update_(true) {
+}
+
+OverscrollNavigationOverlay::~OverscrollNavigationOverlay() {
+}
+
+void OverscrollNavigationOverlay::StartObserving() {
+ loading_complete_ = false;
+ received_paint_update_ = false;
+ Observe(web_contents_);
+
+ // Make sure the overlay window is on top.
+ if (window_.get() && window_->parent())
+ window_->parent()->StackChildAtTop(window_.get());
+}
+
+void OverscrollNavigationOverlay::SetOverlayWindow(
+ scoped_ptr<aura::Window> window,
+ ImageWindowDelegate* delegate) {
+ window_ = window.Pass();
+ if (window_.get() && window_->parent())
+ window_->parent()->StackChildAtTop(window_.get());
+ image_delegate_ = delegate;
+
+ if (window_.get() && delegate->has_image()) {
+ window_slider_.reset(new WindowSlider(this,
+ window_->parent(),
+ window_.get()));
+ slide_direction_ = SLIDE_UNKNOWN;
+ } else {
+ window_slider_.reset();
+ }
+}
+
+void OverscrollNavigationOverlay::SetupForTesting() {
+ need_paint_update_ = false;
+}
+
+void OverscrollNavigationOverlay::StopObservingIfDone() {
+ // If there is a screenshot displayed in the overlay window, then wait for
+ // the navigated page to complete loading and some paint update before
+ // hiding the overlay.
+ // If there is no screenshot in the overlay window, then hide this view
+ // as soon as there is any new painting notification.
+ if ((need_paint_update_ && !received_paint_update_) ||
+ (image_delegate_->has_image() && !loading_complete_)) {
+ return;
+ }
+
+ // If a slide is in progress, then do not destroy the window or the slide.
+ if (window_slider_.get() && window_slider_->IsSlideInProgress())
+ return;
+
+ Observe(NULL);
+ window_slider_.reset();
+ window_.reset();
+ image_delegate_ = NULL;
+}
+
+ui::Layer* OverscrollNavigationOverlay::CreateSlideLayer(int offset) {
+ const NavigationControllerImpl& controller = web_contents_->GetController();
+ const NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
+ controller.GetEntryAtOffset(offset));
+
+ gfx::Image image;
+ if (entry && entry->screenshot().get()) {
+ std::vector<gfx::ImagePNGRep> image_reps;
+ image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(),
+ ui::GetImageScale(
+ ui::GetScaleFactorForNativeView(window_.get()))));
+ image = gfx::Image(image_reps);
+ }
+ if (!layer_delegate_)
+ layer_delegate_.reset(new ImageLayerDelegate());
+ layer_delegate_->SetImage(image);
+
+ ui::Layer* layer = new ui::Layer(ui::LAYER_TEXTURED);
+ layer->set_delegate(layer_delegate_.get());
+ return layer;
+}
+
+ui::Layer* OverscrollNavigationOverlay::CreateBackLayer() {
+ if (!web_contents_->GetController().CanGoBack())
+ return NULL;
+ slide_direction_ = SLIDE_BACK;
+ return CreateSlideLayer(-1);
+}
+
+ui::Layer* OverscrollNavigationOverlay::CreateFrontLayer() {
+ if (!web_contents_->GetController().CanGoForward())
+ return NULL;
+ slide_direction_ = SLIDE_FRONT;
+ return CreateSlideLayer(1);
+}
+
+void OverscrollNavigationOverlay::OnWindowSlideComplete() {
+ if (slide_direction_ == SLIDE_UNKNOWN) {
+ window_slider_.reset();
+ StopObservingIfDone();
+ return;
+ }
+
+ // Change the image used for the overlay window.
+ image_delegate_->SetImage(layer_delegate_->image());
+ window_->layer()->SetTransform(gfx::Transform());
+ window_->SchedulePaintInRect(gfx::Rect(window_->bounds().size()));
+
+ SlideDirection direction = slide_direction_;
+ slide_direction_ = SLIDE_UNKNOWN;
+
+ // Reset state and wait for the new navigation page to complete
+ // loading/painting.
+ StartObserving();
+
+ // Perform the navigation.
+ if (direction == SLIDE_BACK)
+ web_contents_->GetController().GoBack();
+ else if (direction == SLIDE_FRONT)
+ web_contents_->GetController().GoForward();
+ else
+ NOTREACHED();
+}
+
+void OverscrollNavigationOverlay::OnWindowSlideAborted() {
+ StopObservingIfDone();
+}
+
+void OverscrollNavigationOverlay::OnWindowSliderDestroyed() {
+ // The slider has just been destroyed. Release the ownership.
+ WindowSlider* slider ALLOW_UNUSED = window_slider_.release();
+ StopObservingIfDone();
+}
+
+void OverscrollNavigationOverlay::DidFirstVisuallyNonEmptyPaint(int32 page_id) {
+ received_paint_update_ = true;
+ StopObservingIfDone();
+}
+
+void OverscrollNavigationOverlay::DidStopLoading(RenderViewHost* host) {
+ loading_complete_ = true;
+ StopObservingIfDone();
+}
+
+} // namespace content
diff --git a/content/browser/web_contents/aura/overscroll_navigation_overlay.h b/content/browser/web_contents/aura/overscroll_navigation_overlay.h
new file mode 100644
index 0000000..29f2622
--- /dev/null
+++ b/content/browser/web_contents/aura/overscroll_navigation_overlay.h
@@ -0,0 +1,105 @@
+// Copyright 2014 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.
+
+#ifndef CONTENT_BROWSER_WEB_CONTENTS_AURA_OVERSCROLL_NAVIGATION_OVERLAY_H_
+#define CONTENT_BROWSER_WEB_CONTENTS_AURA_OVERSCROLL_NAVIGATION_OVERLAY_H_
+
+#include "base/macros.h"
+#include "content/browser/web_contents/aura/window_slider.h"
+#include "content/public/browser/web_contents_observer.h"
+
+namespace content {
+
+class ImageLayerDelegate;
+class ImageWindowDelegate;
+
+// When a history navigation is triggered at the end of an overscroll
+// navigation, it is necessary to show the history-screenshot until the page is
+// done navigating and painting. This class accomplishes this by showing the
+// screenshot window on top of the page until the page has completed loading and
+// painting.
+class OverscrollNavigationOverlay : public WebContentsObserver,
+ public WindowSlider::Delegate {
+ public:
+ explicit OverscrollNavigationOverlay(WebContentsImpl* web_contents);
+ virtual ~OverscrollNavigationOverlay();
+
+ bool has_window() const { return !!window_.get(); }
+
+ // Starts observing |web_contents_| for page load/paint updates. This function
+ // makes sure that the screenshot window is stacked on top, so that it hides
+ // the content window behind it, and destroys the screenshot window when the
+ // page is done loading/painting.
+ void StartObserving();
+
+ // Sets the screenshot window and the delegate. This takes ownership of
+ // |window|.
+ // Note that ImageWindowDelegate manages its own lifetime, so this function
+ // does not take ownership of |delegate|.
+ void SetOverlayWindow(scoped_ptr<aura::Window> window,
+ ImageWindowDelegate* delegate);
+
+ // Sets up the overlay for tests.
+ void SetupForTesting();
+
+ private:
+ enum SlideDirection {
+ SLIDE_UNKNOWN,
+ SLIDE_BACK,
+ SLIDE_FRONT
+ };
+
+ // Stop observing the page if the page-load has completed and the page has
+ // been painted, and a window-slide isn't in progress.
+ void StopObservingIfDone();
+
+ // Creates a layer to be used for window-slide. |offset| is the offset of the
+ // NavigationEntry for the screenshot image to display.
+ ui::Layer* CreateSlideLayer(int offset);
+
+ // Overridden from WindowSlider::Delegate:
+ virtual ui::Layer* CreateBackLayer() OVERRIDE;
+ virtual ui::Layer* CreateFrontLayer() OVERRIDE;
+ virtual void OnWindowSlideComplete() OVERRIDE;
+ virtual void OnWindowSlideAborted() OVERRIDE;
+ virtual void OnWindowSliderDestroyed() OVERRIDE;
+
+ // Overridden from WebContentsObserver:
+ virtual void DidFirstVisuallyNonEmptyPaint(int32 page_id) OVERRIDE;
+ virtual void DidStopLoading(RenderViewHost* host) OVERRIDE;
+
+ // The WebContents which is being navigated.
+ WebContentsImpl* web_contents_;
+
+ // The screenshot overlay window.
+ scoped_ptr<aura::Window> window_;
+
+ // This is the WindowDelegate of |window_|. The delegate manages its own
+ // lifetime (destroys itself when |window_| is destroyed).
+ ImageWindowDelegate* image_delegate_;
+
+ bool loading_complete_;
+ bool received_paint_update_;
+
+ // The |WindowSlider| that allows sliding history layers while the page is
+ // being reloaded.
+ scoped_ptr<WindowSlider> window_slider_;
+
+ // The direction of the in-progress slide (if any).
+ SlideDirection slide_direction_;
+
+ // The LayerDelegate used for the back/front layers during a slide.
+ scoped_ptr<ImageLayerDelegate> layer_delegate_;
+
+ // During tests, the aura windows don't get any paint updates. So the overlay
+ // container keeps waiting for a paint update it never receives, causing a
+ // timeout. So during tests, disable the wait for paint updates.
+ bool need_paint_update_;
+
+ DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlay);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_CONTENTS_AURA_OVERSCROLL_NAVIGATION_OVERLAY_H_
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc
index ad5623c..aa3be21 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -19,6 +19,7 @@
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/web_contents/aura/image_window_delegate.h"
+#include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
#include "content/browser/web_contents/aura/shadow_layer_delegate.h"
#include "content/browser/web_contents/aura/window_slider.h"
#include "content/browser/web_contents/touch_editable_impl_aura.h"
@@ -441,251 +442,8 @@ int ConvertAuraEventFlagsToWebInputEventModifiers(int aura_event_flags) {
return web_input_event_modifiers;
}
-// A LayerDelegate that paints an image for the layer.
-class ImageLayerDelegate : public ui::LayerDelegate {
- public:
- ImageLayerDelegate() {}
-
- virtual ~ImageLayerDelegate() {}
-
- void SetImage(const gfx::Image& image) {
- image_ = image;
- image_size_ = image.AsImageSkia().size();
- }
- const gfx::Image& image() const { return image_; }
-
- private:
- // Overridden from ui::LayerDelegate:
- virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
- if (image_.IsEmpty()) {
- canvas->DrawColor(SK_ColorGRAY);
- } else {
- SkISize size = canvas->sk_canvas()->getDeviceSize();
- if (size.width() != image_size_.width() ||
- size.height() != image_size_.height()) {
- canvas->DrawColor(SK_ColorWHITE);
- }
- canvas->DrawImageInt(image_.AsImageSkia(), 0, 0);
- }
- }
-
- // Called when the layer's device scale factor has changed.
- virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
- }
-
- // Invoked prior to the bounds changing. The returned closured is run after
- // the bounds change.
- virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
- return base::Closure();
- }
-
- gfx::Image image_;
- gfx::Size image_size_;
-
- DISALLOW_COPY_AND_ASSIGN(ImageLayerDelegate);
-};
-
} // namespace
-// When a history navigation is triggered at the end of an overscroll
-// navigation, it is necessary to show the history-screenshot until the page is
-// done navigating and painting. This class accomplishes this by showing the
-// screenshot window on top of the page until the page has completed loading and
-// painting.
-class OverscrollNavigationOverlay : public WebContentsObserver,
- public WindowSlider::Delegate {
- public:
- explicit OverscrollNavigationOverlay(WebContentsImpl* web_contents)
- : web_contents_(web_contents),
- image_delegate_(NULL),
- loading_complete_(false),
- received_paint_update_(false),
- slide_direction_(SLIDE_UNKNOWN),
- need_paint_update_(true) {
- }
-
- virtual ~OverscrollNavigationOverlay() {
- }
-
- bool has_window() const { return !!window_.get(); }
-
- void StartObserving() {
- loading_complete_ = false;
- received_paint_update_ = false;
- Observe(web_contents_);
-
- // Make sure the overlay window is on top.
- if (window_.get() && window_->parent())
- window_->parent()->StackChildAtTop(window_.get());
- }
-
- void SetOverlayWindow(scoped_ptr<aura::Window> window,
- ImageWindowDelegate* delegate) {
- window_ = window.Pass();
- if (window_.get() && window_->parent())
- window_->parent()->StackChildAtTop(window_.get());
- image_delegate_ = delegate;
-
- if (window_.get() && delegate->has_image()) {
- window_slider_.reset(new WindowSlider(this,
- window_->parent(),
- window_.get()));
- slide_direction_ = SLIDE_UNKNOWN;
- } else {
- window_slider_.reset();
- }
- }
-
- void SetupForTesting() {
- need_paint_update_ = false;
- }
-
- private:
- // Stop observing the page if the page-load has completed and the page has
- // been painted, and a window-slide isn't in progress.
- void StopObservingIfDone() {
- // If there is a screenshot displayed in the overlay window, then wait for
- // the navigated page to complete loading and some paint update before
- // hiding the overlay.
- // If there is no screenshot in the overlay window, then hide this view
- // as soon as there is any new painting notification.
- if ((need_paint_update_ && !received_paint_update_) ||
- (image_delegate_->has_image() && !loading_complete_)) {
- return;
- }
-
- // If a slide is in progress, then do not destroy the window or the slide.
- if (window_slider_.get() && window_slider_->IsSlideInProgress())
- return;
-
- Observe(NULL);
- window_slider_.reset();
- window_.reset();
- image_delegate_ = NULL;
- }
-
- // Creates a layer to be used for window-slide. |offset| is the offset of the
- // NavigationEntry for the screenshot image to display.
- ui::Layer* CreateSlideLayer(int offset) {
- const NavigationControllerImpl& controller = web_contents_->GetController();
- const NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
- controller.GetEntryAtOffset(offset));
-
- gfx::Image image;
- if (entry && entry->screenshot().get()) {
- std::vector<gfx::ImagePNGRep> image_reps;
- image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(),
- ui::GetImageScale(
- ui::GetScaleFactorForNativeView(window_.get()))));
- image = gfx::Image(image_reps);
- }
- layer_delegate_.SetImage(image);
-
- ui::Layer* layer = new ui::Layer(ui::LAYER_TEXTURED);
- layer->set_delegate(&layer_delegate_);
- return layer;
- }
-
- // Overridden from WindowSlider::Delegate:
- virtual ui::Layer* CreateBackLayer() OVERRIDE {
- if (!web_contents_->GetController().CanGoBack())
- return NULL;
- slide_direction_ = SLIDE_BACK;
- return CreateSlideLayer(-1);
- }
-
- virtual ui::Layer* CreateFrontLayer() OVERRIDE {
- if (!web_contents_->GetController().CanGoForward())
- return NULL;
- slide_direction_ = SLIDE_FRONT;
- return CreateSlideLayer(1);
- }
-
- virtual void OnWindowSlideComplete() OVERRIDE {
- if (slide_direction_ == SLIDE_UNKNOWN) {
- window_slider_.reset();
- StopObservingIfDone();
- return;
- }
-
- // Change the image used for the overlay window.
- image_delegate_->SetImage(layer_delegate_.image());
- window_->layer()->SetTransform(gfx::Transform());
- window_->SchedulePaintInRect(gfx::Rect(window_->bounds().size()));
-
- SlideDirection direction = slide_direction_;
- slide_direction_ = SLIDE_UNKNOWN;
-
- // Reset state and wait for the new navigation page to complete
- // loading/painting.
- StartObserving();
-
- // Perform the navigation.
- if (direction == SLIDE_BACK)
- web_contents_->GetController().GoBack();
- else if (direction == SLIDE_FRONT)
- web_contents_->GetController().GoForward();
- else
- NOTREACHED();
- }
-
- virtual void OnWindowSlideAborted() OVERRIDE {
- StopObservingIfDone();
- }
-
- virtual void OnWindowSliderDestroyed() OVERRIDE {
- // The slider has just been destroyed. Release the ownership.
- WindowSlider* slider ALLOW_UNUSED = window_slider_.release();
- StopObservingIfDone();
- }
-
- // Overridden from WebContentsObserver:
- virtual void DidFirstVisuallyNonEmptyPaint(int32 page_id) OVERRIDE {
- received_paint_update_ = true;
- StopObservingIfDone();
- }
-
- virtual void DidStopLoading(RenderViewHost* host) OVERRIDE {
- loading_complete_ = true;
- StopObservingIfDone();
- }
-
- // The WebContents which is being navigated.
- WebContentsImpl* web_contents_;
-
- scoped_ptr<aura::Window> window_;
-
- // This is the WindowDelegate of |window_|. The delegate manages its own
- // lifetime (destroys itself when |window_| is destroyed).
- ImageWindowDelegate* image_delegate_;
-
- bool loading_complete_;
- bool received_paint_update_;
-
- enum SlideDirection {
- SLIDE_UNKNOWN,
- SLIDE_BACK,
- SLIDE_FRONT
- };
-
- // The |WindowSlider| that allows sliding history layers while the page is
- // being reloaded.
- scoped_ptr<WindowSlider> window_slider_;
-
- // The direction of the in-progress slide (if any).
- SlideDirection slide_direction_;
-
- // The LayerDelegate used for the back/front layers during a slide.
- ImageLayerDelegate layer_delegate_;
-
- // During tests, the aura windows don't get any paint updates. So the overlay
- // container keeps waiting for a paint update it never receives, causing a
- // timeout. So during tests, disable the wait for paint updates.
- bool need_paint_update_;
-
- DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlay);
-};
-
class WebContentsViewAura::WindowObserver
: public aura::WindowObserver, public aura::RootWindowObserver {
public:
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 76cc65d..d265433 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -1215,6 +1215,8 @@
'browser/vibration/vibration_provider_android.h',
'browser/web_contents/aura/image_window_delegate.cc',
'browser/web_contents/aura/image_window_delegate.h',
+ 'browser/web_contents/aura/overscroll_navigation_overlay.cc',
+ 'browser/web_contents/aura/overscroll_navigation_overlay.h',
'browser/web_contents/aura/shadow_layer_delegate.cc',
'browser/web_contents/aura/shadow_layer_delegate.h',
'browser/web_contents/aura/window_slider.cc',