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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 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.
4
5 #include "content/browser/web_contents/aura/overscroll_window_animation.h"
6
7 #include "base/auto_reset.h"
8 #include "content/browser/web_contents/aura/overscroll_window_delegate.h"
9 #include "content/browser/web_contents/aura/shadow_layer_delegate.h"
10 #include "content/browser/web_contents/web_contents_impl.h"
11 #include "content/browser/web_contents/web_contents_view_aura.h"
12 #include "content/public/browser/render_widget_host_view.h"
13 #include "ui/aura/window.h"
14 #include "ui/compositor/layer_animation_observer.h"
15 #include "ui/compositor/scoped_layer_animation_settings.h"
16
17 namespace content {
18
19 namespace {
20
21 // Responsible for fading out and deleting the layer of the overlay window.
22 class OverlayDismissAnimator : public ui::LayerAnimationObserver {
23 public:
24 // Takes ownership of the layer.
25 explicit OverlayDismissAnimator(scoped_ptr<ui::Layer> layer)
26 : layer_(layer.Pass()) {
27 CHECK(layer_.get());
28 }
29
30 // Starts the fadeout animation on the layer. When the animation finishes,
31 // the object deletes itself along with the layer.
32 void Animate() {
33 DCHECK(layer_.get());
34 ui::LayerAnimator* animator = layer_->GetAnimator();
35 // This makes SetOpacity() animate with default duration (which could be
36 // zero, e.g. when running tests).
37 ui::ScopedLayerAnimationSettings settings(animator);
38 animator->AddObserver(this);
39 LOG(ERROR) << "Setting opacity to 0";
40 layer_->SetOpacity(0);
41 }
42
43 // Overridden from ui::LayerAnimationObserver
44 void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
45 LOG(ERROR) << "Deleting dismiss layer";
46 delete this;
47 }
48
49 void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {
50 LOG(ERROR) << "Animation aborted!!!";
51 delete this;
52 }
53
54 void OnLayerAnimationScheduled(
55 ui::LayerAnimationSequence* sequence) override {}
56
57 private:
58 ~OverlayDismissAnimator() override {}
59
60 scoped_ptr<ui::Layer> layer_;
61
62 DISALLOW_COPY_AND_ASSIGN(OverlayDismissAnimator);
63 };
64
65 } // namespace
66
67 OverscrollWindowAnimation::OverscrollWindowAnimation(
68 WebContentsImpl* web_contents,
69 OverscrollNavigationOverlay* ono,
70 aura::Window* web_contents_window)
71 : web_contents_(web_contents),
72 ono_(ono),
73 direction_(OverscrollNavigationOverlay::NONE),
74 web_contents_window_(web_contents_window),
75 slide_layer_(nullptr),
76 fade_out_(false),
77 animation_cancelled_(false),
78 gesture_completed_(false) {
79 }
80
81 OverscrollWindowAnimation::~OverscrollWindowAnimation() {
82 LOG(ERROR) << "OWA destructor";
83 }
84
85 void OverscrollWindowAnimation::CancelAnimation() {
86 LOG(ERROR) << "Cancelling animation";
87 animation_cancelled_ = true;
88 fade_out_ = false;
89 gesture_completed_ = true;
90 aura::Window* animate_window = GetWindowToAnimateForOverscroll();
91 if (!animate_window)
92 return;
93 ui::ScopedLayerAnimationSettings settings(
94 animate_window->layer()->GetAnimator());
95 settings.SetPreemptionStrategy(
96 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
97 settings.SetTweenType(gfx::Tween::EASE_OUT);
98 settings.AddObserver(this);
99 animate_window->SetTransform(gfx::Transform());
100 direction_ = OverscrollNavigationOverlay::NONE;
101 }
102
103 // We should be able to delete this function.
104 void OverscrollWindowAnimation::AbortAllAnimations() {
105 aura::Window* target = GetWindowToAnimateForOverscroll();
106 if (target)
107 target->layer()->GetAnimator()->AbortAllAnimations();
108 }
109
110 void OverscrollWindowAnimation::DismissOverlay() {
111 LOG(ERROR) << "Dismissing overlay";
112 if (gesture_completed_) {
113 FadeOutOverscrollWindow();
114 return;
115 }
116 fade_out_ = true;
117 }
118
119 void OverscrollWindowAnimation::OnImplicitAnimationsCompleted() {
120 LOG(ERROR) << "On implicit animations completed";
121 if (!overscroll_window_) {
122 LOG(ERROR) << "Overscroll window already destroyed, returning";
123 return;
124 }
125 gesture_completed_ = true;
126 aura::Window* contents = web_contents_->GetContentNativeView();
127 contents->parent()->StackChildBelow(contents, overscroll_window_.get());
mfomitchev 2015/02/13 22:08:48 Similar to the previous comments - this logic shou
128 contents->SetTransform(gfx::Transform());
129 if (fade_out_) {
130 LOG(ERROR) << "With fade_out_ == true";
131 FadeOutOverscrollWindow();
132 return;
133 }
134 if (animation_cancelled_) {
135 LOG(ERROR) << "With animation_cancelled_ == true";
136 overscroll_window_.reset();
137 overscroll_shadow_.reset();
138 }
139 }
140
141 gfx::Vector2dF OverscrollWindowAnimation::GetTranslationForOverscroll(
142 float delta_x) {
143 const float bounds_width =
144 static_cast<float>(web_contents_window_->bounds().width());
145 if (direction_ == OverscrollNavigationOverlay::FORWARD)
146 return gfx::Vector2dF(std::max(-bounds_width, delta_x), 0);
147 else
148 return gfx::Vector2dF(std::min(bounds_width, delta_x), 0);
149 }
150
151 gfx::Rect OverscrollWindowAnimation::GetVisibleBounds() const {
152 return web_contents_window_->bounds();
153 }
154
155 bool OverscrollWindowAnimation::OnOverscrollUpdate(float delta_x,
156 float delta_y) {
157 if (direction_ == OverscrollNavigationOverlay::NONE)
158 return false;
159 LOG(ERROR) << "OWA: OnOverscrollUpdate";
160 gfx::Vector2dF translate = GetTranslationForOverscroll(delta_x);
161 if (translate.IsZero())
162 return false;
163
164 gfx::Transform transform;
165 transform.Translate(translate.x(), translate.y());
166 aura::Window* animate_window = GetWindowToAnimateForOverscroll();
167 if (animate_window) {
168 animate_window->SetTransform(transform);
169 return true;
170 }
171 return false;
172 }
173
174 void OverscrollWindowAnimation::OnOverscrollModeChange(
175 OverscrollMode old_mode,
176 OverscrollMode new_mode) {
177 LOG(ERROR) << "OWA: OnOverscrollModeChange";
178 animation_cancelled_ = false;
179 AbortAllAnimations();
180
181 direction_ =
182 ono_->GetNavigationDirection(web_contents_->GetController(), new_mode);
183 // TODO(nsatragno): in this case, show a feedback animation.
184 if (direction_ == OverscrollNavigationOverlay::NONE) {
185 if (overscroll_window_)
186 CancelAnimation();
187 return;
188 }
189 if (overscroll_window_) {
190 LOG(ERROR) << "OWA: SHOULD CREATE LAYER";
191 AddNewLayer();
192 return;
193 }
194
195 StartAnimating();
196 }
197
198 void OverscrollWindowAnimation::StartAnimating() {
199 LOG(ERROR) << "OWA: StartAnimating";
200 gesture_completed_ = false;
201 OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate(
mfomitchev 2015/02/13 22:08:48 I am not sure this setup code belongs in OWA eithe
202 this, ono_->GetImageForDirection(direction_));
203 overscroll_window_.reset(new aura::Window(overscroll_delegate));
204 overscroll_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
205 overscroll_window_->SetTransparent(true);
206 overscroll_window_->Init(aura::WINDOW_LAYER_TEXTURED);
207 overscroll_window_->layer()->SetMasksToBounds(false);
208 overscroll_window_->SetName("OverscrollOverlay");
209
210 aura::Window* animate_window = GetWindowToAnimateForOverscroll();
211 web_contents_window_->AddChild(overscroll_window_.get());
212
213 if (animate_window == overscroll_window_) {
214 LOG(ERROR) << "animate_window == overscroll_window_";
215 web_contents_window_->StackChildAbove(
216 overscroll_window_.get(), web_contents_->GetContentNativeView());
217 } else {
218 LOG(ERROR) << "animate_window != overscroll_window_";
219 web_contents_window_->StackChildBelow(
220 overscroll_window_.get(), web_contents_->GetContentNativeView());
221 }
222
223 overscroll_window_->SetBounds(GetStarterBounds());
224 overscroll_window_->Show();
225
226 if (!animate_window)
227 LOG(ERROR) << "ERROR: ANIMATE_WINDOW_ IS NULL";
228
229 overscroll_shadow_.reset(new ShadowLayerDelegate(animate_window->layer()));
230 }
231
232 void OverscrollWindowAnimation::AddNewLayer() {
233 slide_layer_ = ono_->CreateLayerForDirection(direction_);
234 ui::Layer* parent = overscroll_window_->layer()->parent();
mfomitchev 2015/02/13 22:08:48 Same here
235 parent->Add(slide_layer_.get());
236 // TODO stack apropriately.
237 if (direction_ == OverscrollNavigationOverlay::FORWARD)
238 parent->StackAbove(slide_layer_.get(), overscroll_window_->layer());
239 else
240 parent->StackBelow(slide_layer_.get(), overscroll_window_->layer());
241 slide_layer_->SetBounds(GetStarterBounds());
242 }
243
244 void OverscrollWindowAnimation::FadeOutOverscrollWindow() {
245 fade_out_ = false;
246 LOG(ERROR) << "FadeOutOverscrollWindow";
247 if (!overscroll_window_)
248 return;
249 aura::Window* contents = web_contents_->GetContentNativeView();
250 contents->layer()->SetLayerBrightness(1.f);
251 {
252 ui::ScopedLayerAnimationSettings settings(contents->layer()->GetAnimator());
253 settings.SetPreemptionStrategy(
254 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
255 settings.SetTweenType(gfx::Tween::EASE_OUT);
256 contents->layer()->SetLayerBrightness(0.f);
257 }
258 scoped_ptr<ui::Layer> dismiss_layer = overscroll_window_->AcquireLayer();
259 overscroll_window_.reset();
260 (new OverlayDismissAnimator(dismiss_layer.Pass()))->Animate();
261 // TODO delete shadow when the dismiss animation finishes?
262 overscroll_shadow_.reset();
263 }
264
265 gfx::Rect OverscrollWindowAnimation::GetStarterBounds() const {
266 gfx::Rect bounds = gfx::Rect(web_contents_window_->bounds().size());
267 if (direction_ == OverscrollNavigationOverlay::FORWARD) {
268 // The overlay will be sliding in from the right edge towards the left in
269 // non-RTL, or sliding in from the left edge towards the right in RTL.
270 // So position the overlay window accordingly.
271 bounds.Offset(base::i18n::IsRTL() ? -bounds.width() : bounds.width(), 0);
272 }
273 return bounds;
274 }
275
276 void OverscrollWindowAnimation::OnOverscrollComplete(
277 OverscrollMode overscroll_mode) {
278 LOG(ERROR) << "OWA: OnOverscrollComplete";
279 aura::Window* target = GetWindowToAnimateForOverscroll();
280 ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
281 settings.SetPreemptionStrategy(
282 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
283 settings.SetTweenType(gfx::Tween::EASE_OUT);
284 settings.AddObserver(this);
285 gfx::Transform transform;
286 int content_width =
287 web_contents_->GetRenderWidgetHostView()->GetViewBounds().width();
288 float translate_x = static_cast<float>(
289 direction_ == OverscrollNavigationOverlay::FORWARD ? -content_width
290 : content_width);
291 transform.Translate(translate_x, 0);
292 target->SetTransform(transform);
293 direction_ = OverscrollNavigationOverlay::NONE;
294 }
295
296 aura::Window* OverscrollWindowAnimation::GetWindowToAnimateForOverscroll()
297 const {
298 return direction_ == OverscrollNavigationOverlay::FORWARD
299 ? overscroll_window_.get()
300 : web_contents_->GetContentNativeView();
301 }
302
303 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698