Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / content / browser / web_contents / aura / overscroll_window_animation.cc
blobef9e79d272e9b644ddd9af1f17cdb8123cab0f63
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/web_contents/aura/overscroll_window_animation.h"
7 #include <algorithm>
9 #include "base/i18n/rtl.h"
10 #include "content/browser/web_contents/aura/shadow_layer_delegate.h"
11 #include "content/browser/web_contents/web_contents_impl.h"
12 #include "ui/aura/window.h"
13 #include "ui/compositor/layer_animation_observer.h"
14 #include "ui/compositor/scoped_layer_animation_settings.h"
16 namespace content {
18 namespace {
20 OverscrollWindowAnimation::Direction GetDirectionForMode(OverscrollMode mode) {
21 if (mode == (base::i18n::IsRTL() ? OVERSCROLL_EAST : OVERSCROLL_WEST))
22 return OverscrollWindowAnimation::SLIDE_FRONT;
23 if (mode == (base::i18n::IsRTL() ? OVERSCROLL_WEST : OVERSCROLL_EAST))
24 return OverscrollWindowAnimation::SLIDE_BACK;
25 return OverscrollWindowAnimation::SLIDE_NONE;
28 } // namespace
30 OverscrollWindowAnimation::OverscrollWindowAnimation(Delegate* delegate)
31 : delegate_(delegate),
32 direction_(SLIDE_NONE),
33 overscroll_cancelled_(false) {
34 DCHECK(delegate_);
37 OverscrollWindowAnimation::~OverscrollWindowAnimation() {
40 void OverscrollWindowAnimation::CancelSlide() {
41 overscroll_cancelled_ = true;
42 AnimateTranslation(GetBackLayer(), 0, false);
43 AnimateTranslation(GetFrontLayer(), 0, true);
46 float OverscrollWindowAnimation::GetTranslationForOverscroll(float delta_x) {
47 DCHECK(direction_ != SLIDE_NONE);
48 const float bounds_width = GetVisibleBounds().width();
49 if (direction_ == SLIDE_FRONT)
50 return std::max(-bounds_width, delta_x);
51 else
52 return std::min(bounds_width, delta_x);
55 gfx::Rect OverscrollWindowAnimation::GetVisibleBounds() const {
56 return delegate_->GetMainWindow()->bounds();
59 bool OverscrollWindowAnimation::OnOverscrollUpdate(float delta_x,
60 float delta_y) {
61 if (direction_ == SLIDE_NONE)
62 return false;
63 gfx::Transform front_transform;
64 gfx::Transform back_transform;
65 float translate_x = GetTranslationForOverscroll(delta_x);
66 front_transform.Translate(translate_x, 0);
67 back_transform.Translate(translate_x / 2, 0);
68 GetFrontLayer()->SetTransform(front_transform);
69 GetBackLayer()->SetTransform(back_transform);
70 return true;
73 void OverscrollWindowAnimation::OnImplicitAnimationsCompleted() {
74 if (overscroll_cancelled_) {
75 slide_window_.reset();
76 delegate_->OnOverscrollCancelled();
77 overscroll_cancelled_ = false;
78 } else {
79 delegate_->OnOverscrollCompleted(slide_window_.Pass());
81 direction_ = SLIDE_NONE;
84 void OverscrollWindowAnimation::OnOverscrollModeChange(
85 OverscrollMode old_mode,
86 OverscrollMode new_mode) {
87 Direction new_direction = GetDirectionForMode(new_mode);
88 if (new_direction == SLIDE_NONE) {
89 // The user cancelled the in progress animation.
90 if (is_active())
91 CancelSlide();
92 return;
94 if (is_active()) {
95 slide_window_->layer()->GetAnimator()->StopAnimating();
96 delegate_->GetMainWindow()->layer()->GetAnimator()->StopAnimating();
98 gfx::Rect slide_window_bounds = gfx::Rect(GetVisibleBounds().size());
99 if (new_direction == SLIDE_FRONT) {
100 slide_window_bounds.Offset(base::i18n::IsRTL()
101 ? -slide_window_bounds.width()
102 : slide_window_bounds.width(),
104 } else {
105 slide_window_bounds.Offset(base::i18n::IsRTL()
106 ? slide_window_bounds.width() / 2
107 : -slide_window_bounds.width() / 2,
110 slide_window_ = new_direction == SLIDE_FRONT
111 ? delegate_->CreateFrontWindow(slide_window_bounds)
112 : delegate_->CreateBackWindow(slide_window_bounds);
113 if (!slide_window_) {
114 // Cannot navigate, do not start an overscroll gesture.
115 direction_ = SLIDE_NONE;
116 return;
118 overscroll_cancelled_ = false;
119 direction_ = new_direction;
120 shadow_.reset(new ShadowLayerDelegate(GetFrontLayer()));
123 void OverscrollWindowAnimation::OnOverscrollComplete(
124 OverscrollMode overscroll_mode) {
125 if (!is_active())
126 return;
127 delegate_->OnOverscrollCompleting();
128 int content_width = GetVisibleBounds().width();
129 float translate_x;
130 if ((base::i18n::IsRTL() && direction_ == SLIDE_FRONT) ||
131 (!base::i18n::IsRTL() && direction_ == SLIDE_BACK)) {
132 translate_x = content_width;
133 } else {
134 translate_x = -content_width;
136 AnimateTranslation(GetBackLayer(), translate_x / 2, false);
137 AnimateTranslation(GetFrontLayer(), translate_x, true);
140 void OverscrollWindowAnimation::AnimateTranslation(ui::Layer* layer,
141 float translate_x,
142 bool listen_for_completion) {
143 gfx::Transform transform;
144 transform.Translate(translate_x, 0);
145 ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
146 settings.SetPreemptionStrategy(
147 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
148 settings.SetTweenType(gfx::Tween::EASE_OUT);
149 if (listen_for_completion)
150 settings.AddObserver(this);
151 layer->SetTransform(transform);
154 ui::Layer* OverscrollWindowAnimation::GetFrontLayer() const {
155 DCHECK(direction_ != SLIDE_NONE);
156 if (direction_ == SLIDE_FRONT) {
157 DCHECK(slide_window_);
158 return slide_window_->layer();
160 return delegate_->GetMainWindow()->layer();
163 ui::Layer* OverscrollWindowAnimation::GetBackLayer() const {
164 DCHECK(direction_ != SLIDE_NONE);
165 if (direction_ == SLIDE_BACK) {
166 DCHECK(slide_window_);
167 return slide_window_->layer();
169 return delegate_->GetMainWindow()->layer();
172 } // namespace content