Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Unified Diff: content/browser/web_contents/aura/overscroll_window_animation.cc

Issue 895543005: Refactor GestureNavigation to eliminate code redundancy (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/web_contents/aura/overscroll_window_animation.cc
diff --git a/content/browser/web_contents/aura/overscroll_window_animation.cc b/content/browser/web_contents/aura/overscroll_window_animation.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ff04dc92aa3e2d7296813f8827759aab9cbbdb2b
--- /dev/null
+++ b/content/browser/web_contents/aura/overscroll_window_animation.cc
@@ -0,0 +1,303 @@
+// Copyright (c) 2015 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_window_animation.h"
+
+#include "base/auto_reset.h"
+#include "content/browser/web_contents/aura/overscroll_window_delegate.h"
+#include "content/browser/web_contents/aura/shadow_layer_delegate.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_view_aura.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "ui/aura/window.h"
+#include "ui/compositor/layer_animation_observer.h"
+#include "ui/compositor/scoped_layer_animation_settings.h"
+
+namespace content {
+
+namespace {
+
+// Responsible for fading out and deleting the layer of the overlay window.
+class OverlayDismissAnimator : public ui::LayerAnimationObserver {
+ public:
+ // Takes ownership of the layer.
+ explicit OverlayDismissAnimator(scoped_ptr<ui::Layer> layer)
+ : layer_(layer.Pass()) {
+ CHECK(layer_.get());
+ }
+
+ // Starts the fadeout animation on the layer. When the animation finishes,
+ // the object deletes itself along with the layer.
+ void Animate() {
+ DCHECK(layer_.get());
+ ui::LayerAnimator* animator = layer_->GetAnimator();
+ // This makes SetOpacity() animate with default duration (which could be
+ // zero, e.g. when running tests).
+ ui::ScopedLayerAnimationSettings settings(animator);
+ animator->AddObserver(this);
+ LOG(ERROR) << "Setting opacity to 0";
+ layer_->SetOpacity(0);
+ }
+
+ // Overridden from ui::LayerAnimationObserver
+ void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
+ LOG(ERROR) << "Deleting dismiss layer";
+ delete this;
+ }
+
+ void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {
+ LOG(ERROR) << "Animation aborted!!!";
+ delete this;
+ }
+
+ void OnLayerAnimationScheduled(
+ ui::LayerAnimationSequence* sequence) override {}
+
+ private:
+ ~OverlayDismissAnimator() override {}
+
+ scoped_ptr<ui::Layer> layer_;
+
+ DISALLOW_COPY_AND_ASSIGN(OverlayDismissAnimator);
+};
+
+} // namespace
+
+OverscrollWindowAnimation::OverscrollWindowAnimation(
+ WebContentsImpl* web_contents,
+ OverscrollNavigationOverlay* ono,
+ aura::Window* web_contents_window)
+ : web_contents_(web_contents),
+ ono_(ono),
+ direction_(OverscrollNavigationOverlay::NONE),
+ web_contents_window_(web_contents_window),
+ slide_layer_(nullptr),
+ fade_out_(false),
+ animation_cancelled_(false),
+ gesture_completed_(false) {
+}
+
+OverscrollWindowAnimation::~OverscrollWindowAnimation() {
+ LOG(ERROR) << "OWA destructor";
+}
+
+void OverscrollWindowAnimation::CancelAnimation() {
+ LOG(ERROR) << "Cancelling animation";
+ animation_cancelled_ = true;
+ fade_out_ = false;
+ gesture_completed_ = true;
+ aura::Window* animate_window = GetWindowToAnimateForOverscroll();
+ if (!animate_window)
+ return;
+ ui::ScopedLayerAnimationSettings settings(
+ animate_window->layer()->GetAnimator());
+ settings.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ settings.SetTweenType(gfx::Tween::EASE_OUT);
+ settings.AddObserver(this);
+ animate_window->SetTransform(gfx::Transform());
+ direction_ = OverscrollNavigationOverlay::NONE;
+}
+
+// We should be able to delete this function.
+void OverscrollWindowAnimation::AbortAllAnimations() {
+ aura::Window* target = GetWindowToAnimateForOverscroll();
+ if (target)
+ target->layer()->GetAnimator()->AbortAllAnimations();
+}
+
+void OverscrollWindowAnimation::DismissOverlay() {
+ LOG(ERROR) << "Dismissing overlay";
+ if (gesture_completed_) {
+ FadeOutOverscrollWindow();
+ return;
+ }
+ fade_out_ = true;
+}
+
+void OverscrollWindowAnimation::OnImplicitAnimationsCompleted() {
+ LOG(ERROR) << "On implicit animations completed";
+ if (!overscroll_window_) {
+ LOG(ERROR) << "Overscroll window already destroyed, returning";
+ return;
+ }
+ gesture_completed_ = true;
+ aura::Window* contents = web_contents_->GetContentNativeView();
+ contents->parent()->StackChildBelow(contents, overscroll_window_.get());
mfomitchev 2015/02/13 22:08:48 Similar to the previous comments - this logic shou
+ contents->SetTransform(gfx::Transform());
+ if (fade_out_) {
+ LOG(ERROR) << "With fade_out_ == true";
+ FadeOutOverscrollWindow();
+ return;
+ }
+ if (animation_cancelled_) {
+ LOG(ERROR) << "With animation_cancelled_ == true";
+ overscroll_window_.reset();
+ overscroll_shadow_.reset();
+ }
+}
+
+gfx::Vector2dF OverscrollWindowAnimation::GetTranslationForOverscroll(
+ float delta_x) {
+ const float bounds_width =
+ static_cast<float>(web_contents_window_->bounds().width());
+ if (direction_ == OverscrollNavigationOverlay::FORWARD)
+ return gfx::Vector2dF(std::max(-bounds_width, delta_x), 0);
+ else
+ return gfx::Vector2dF(std::min(bounds_width, delta_x), 0);
+}
+
+gfx::Rect OverscrollWindowAnimation::GetVisibleBounds() const {
+ return web_contents_window_->bounds();
+}
+
+bool OverscrollWindowAnimation::OnOverscrollUpdate(float delta_x,
+ float delta_y) {
+ if (direction_ == OverscrollNavigationOverlay::NONE)
+ return false;
+ LOG(ERROR) << "OWA: OnOverscrollUpdate";
+ gfx::Vector2dF translate = GetTranslationForOverscroll(delta_x);
+ if (translate.IsZero())
+ return false;
+
+ gfx::Transform transform;
+ transform.Translate(translate.x(), translate.y());
+ aura::Window* animate_window = GetWindowToAnimateForOverscroll();
+ if (animate_window) {
+ animate_window->SetTransform(transform);
+ return true;
+ }
+ return false;
+}
+
+void OverscrollWindowAnimation::OnOverscrollModeChange(
+ OverscrollMode old_mode,
+ OverscrollMode new_mode) {
+ LOG(ERROR) << "OWA: OnOverscrollModeChange";
+ animation_cancelled_ = false;
+ AbortAllAnimations();
+
+ direction_ =
+ ono_->GetNavigationDirection(web_contents_->GetController(), new_mode);
+ // TODO(nsatragno): in this case, show a feedback animation.
+ if (direction_ == OverscrollNavigationOverlay::NONE) {
+ if (overscroll_window_)
+ CancelAnimation();
+ return;
+ }
+ if (overscroll_window_) {
+ LOG(ERROR) << "OWA: SHOULD CREATE LAYER";
+ AddNewLayer();
+ return;
+ }
+
+ StartAnimating();
+}
+
+void OverscrollWindowAnimation::StartAnimating() {
+ LOG(ERROR) << "OWA: StartAnimating";
+ gesture_completed_ = false;
+ OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate(
mfomitchev 2015/02/13 22:08:48 I am not sure this setup code belongs in OWA eithe
+ this, ono_->GetImageForDirection(direction_));
+ overscroll_window_.reset(new aura::Window(overscroll_delegate));
+ overscroll_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
+ overscroll_window_->SetTransparent(true);
+ overscroll_window_->Init(aura::WINDOW_LAYER_TEXTURED);
+ overscroll_window_->layer()->SetMasksToBounds(false);
+ overscroll_window_->SetName("OverscrollOverlay");
+
+ aura::Window* animate_window = GetWindowToAnimateForOverscroll();
+ web_contents_window_->AddChild(overscroll_window_.get());
+
+ if (animate_window == overscroll_window_) {
+ LOG(ERROR) << "animate_window == overscroll_window_";
+ web_contents_window_->StackChildAbove(
+ overscroll_window_.get(), web_contents_->GetContentNativeView());
+ } else {
+ LOG(ERROR) << "animate_window != overscroll_window_";
+ web_contents_window_->StackChildBelow(
+ overscroll_window_.get(), web_contents_->GetContentNativeView());
+ }
+
+ overscroll_window_->SetBounds(GetStarterBounds());
+ overscroll_window_->Show();
+
+ if (!animate_window)
+ LOG(ERROR) << "ERROR: ANIMATE_WINDOW_ IS NULL";
+
+ overscroll_shadow_.reset(new ShadowLayerDelegate(animate_window->layer()));
+}
+
+void OverscrollWindowAnimation::AddNewLayer() {
+ slide_layer_ = ono_->CreateLayerForDirection(direction_);
+ ui::Layer* parent = overscroll_window_->layer()->parent();
mfomitchev 2015/02/13 22:08:48 Same here
+ parent->Add(slide_layer_.get());
+ // TODO stack apropriately.
+ if (direction_ == OverscrollNavigationOverlay::FORWARD)
+ parent->StackAbove(slide_layer_.get(), overscroll_window_->layer());
+ else
+ parent->StackBelow(slide_layer_.get(), overscroll_window_->layer());
+ slide_layer_->SetBounds(GetStarterBounds());
+}
+
+void OverscrollWindowAnimation::FadeOutOverscrollWindow() {
+ fade_out_ = false;
+ LOG(ERROR) << "FadeOutOverscrollWindow";
+ if (!overscroll_window_)
+ return;
+ aura::Window* contents = web_contents_->GetContentNativeView();
+ contents->layer()->SetLayerBrightness(1.f);
+ {
+ ui::ScopedLayerAnimationSettings settings(contents->layer()->GetAnimator());
+ settings.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ settings.SetTweenType(gfx::Tween::EASE_OUT);
+ contents->layer()->SetLayerBrightness(0.f);
+ }
+ scoped_ptr<ui::Layer> dismiss_layer = overscroll_window_->AcquireLayer();
+ overscroll_window_.reset();
+ (new OverlayDismissAnimator(dismiss_layer.Pass()))->Animate();
+ // TODO delete shadow when the dismiss animation finishes?
+ overscroll_shadow_.reset();
+}
+
+gfx::Rect OverscrollWindowAnimation::GetStarterBounds() const {
+ gfx::Rect bounds = gfx::Rect(web_contents_window_->bounds().size());
+ if (direction_ == OverscrollNavigationOverlay::FORWARD) {
+ // The overlay will be sliding in from the right edge towards the left in
+ // non-RTL, or sliding in from the left edge towards the right in RTL.
+ // So position the overlay window accordingly.
+ bounds.Offset(base::i18n::IsRTL() ? -bounds.width() : bounds.width(), 0);
+ }
+ return bounds;
+}
+
+void OverscrollWindowAnimation::OnOverscrollComplete(
+ OverscrollMode overscroll_mode) {
+ LOG(ERROR) << "OWA: OnOverscrollComplete";
+ aura::Window* target = GetWindowToAnimateForOverscroll();
+ ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
+ settings.SetPreemptionStrategy(
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+ settings.SetTweenType(gfx::Tween::EASE_OUT);
+ settings.AddObserver(this);
+ gfx::Transform transform;
+ int content_width =
+ web_contents_->GetRenderWidgetHostView()->GetViewBounds().width();
+ float translate_x = static_cast<float>(
+ direction_ == OverscrollNavigationOverlay::FORWARD ? -content_width
+ : content_width);
+ transform.Translate(translate_x, 0);
+ target->SetTransform(transform);
+ direction_ = OverscrollNavigationOverlay::NONE;
+}
+
+aura::Window* OverscrollWindowAnimation::GetWindowToAnimateForOverscroll()
+ const {
+ return direction_ == OverscrollNavigationOverlay::FORWARD
+ ? overscroll_window_.get()
+ : web_contents_->GetContentNativeView();
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698