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

Side by Side Diff: chrome/browser/ui/views/frame/scroll_end_effect_controller_ash.cc

Issue 22265009: Implement initial version of scroll end effect Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/frame/scroll_end_effect_controller_ash.h" 5 #include "chrome/browser/ui/views/frame/scroll_end_effect_controller_ash.h"
6 6
7 ScrollEndEffectController* ScrollEndEffectController::Create() { 7 #include "chrome/browser/ui/views/frame/browser_frame.h"
8 return new ScrollEndEffectControllerAsh(); 8 #include "chrome/browser/ui/views/frame/browser_view.h"
9 #include "content/public/browser/web_contents.h"
10 #include "content/public/browser/web_contents_view.h"
11 #include "ui/aura/window.h"
12 #include "ui/compositor/layer_type.h"
13 #include "ui/gfx/rect.h"
14 #include "ui/gfx/transform.h"
15
16 namespace {
17 // This factor is used to control how much translation is applied relative to
18 // the size of the window. Specifically translation is limited to a max of
19 // window_size * factor.
20 const float kScrollEndEffectFactor = 0.10;
9 } 21 }
10 22
11 ScrollEndEffectControllerAsh::ScrollEndEffectControllerAsh() { 23 ScrollEndEffectController* ScrollEndEffectController::Create(
24 BrowserView* view) {
25 return new ScrollEndEffectControllerAsh(view);
26 }
27
28 ScrollEndEffectControllerAsh::ScrollEndEffectControllerAsh(BrowserView* view)
29 : browser_view_(view),
30 is_effect_active_(false),
31 browser_frame_layer_(NULL),
32 web_contents_layer_(NULL),
33 non_client_layer_(NULL),
34 web_contents_parent_(NULL),
35 non_client_view_(NULL) {
12 } 36 }
13 37
14 ScrollEndEffectControllerAsh::~ScrollEndEffectControllerAsh() { 38 ScrollEndEffectControllerAsh::~ScrollEndEffectControllerAsh() {
15 } 39 }
16 40
17 void ScrollEndEffectControllerAsh::OverscrollUpdate(int delta_y) { 41 void ScrollEndEffectControllerAsh::OverscrollUpdate(int delta_y) {
18 // TODO(rharrison): Implement initial version of scroll end effect 42 if (browser_view_ == NULL || browser_view_->frame() == NULL) {
43 return;
44 }
45
46 if (delta_y == 0 && is_effect_active_) {
47 if (browser_frame_layer_) {
48 ApplyDelta(browser_frame_layer_, browser_frame_layer_->bounds(), 0);
49 DeactivateEffect();
50 }
51 return;
52 }
53
54 if (!is_effect_active_)
55 ActivateEffect();
56
57 int capped_delta_y = delta_y;
58 gfx::Rect bounds = browser_frame_layer_->bounds();
59 // Limiting the delta size being a proportion of the frame bounds size.
60 if (capped_delta_y > 0) {
61 capped_delta_y = std::min(static_cast<int>(roundf(bounds.height() *
62 kScrollEndEffectFactor)),
63 capped_delta_y);
64 } else if (capped_delta_y < 0) {
65 capped_delta_y = -std::min(static_cast<int>(roundf(bounds.height() *
66 kScrollEndEffectFactor)),
67 -capped_delta_y);
68 }
69 ApplyDelta(browser_frame_layer_, bounds, capped_delta_y);
19 } 70 }
71
72 void ScrollEndEffectControllerAsh::ActivateEffect() {
73 is_effect_active_ = true;
74
75 // Get layers for all of the parts to be manipulated
76 browser_frame_layer_ = browser_view_->frame()->GetLayer();
77 web_contents_layer_ = browser_view_-> GetActiveWebContents()->GetView()->
78 GetNativeView()->layer();
79 non_client_view_ = browser_view_->frame()->GetContentsView();
80 non_client_view_->SetPaintToLayer(true);
81 non_client_layer_ = non_client_view_->layer();
82 non_client_layer_->SetFillsBoundsOpaquely(false);
83 // non_client_layer_->SetOpacity(0.5);
84
85 CHECK(web_contents_layer_ != NULL);
sadrul 2013/08/20 16:14:59 CHECK(web_contents_layer_), or CHECK_NE
rharrison 2013/08/20 19:57:41 Done.
86 CHECK(non_client_layer_ != NULL);
87
88 // Setup clipping layers
89 frame_clipping_layer_.reset(new ui::Layer(ui::LAYER_NOT_DRAWN));
90 frame_clipping_layer_->set_name("OverscrollFrameClippingLayer");
91 frame_clipping_layer_->SetMasksToBounds(true);
92 gfx::Rect frame_clipping_bounds = browser_frame_layer_->bounds();
93 frame_clipping_bounds.set_origin(gfx::Point(0,0));
sadrul 2013/08/20 16:14:59 gfx::Point()
rharrison 2013/08/20 19:57:41 Done.
94 frame_clipping_layer_->SetBounds(frame_clipping_bounds);
95
96 web_clipping_layer_.reset(new ui::Layer(ui::LAYER_NOT_DRAWN));
97 web_clipping_layer_->set_name("OverscrollWebClippingLayer");
98 web_clipping_layer_->SetMasksToBounds(true);
99 gfx::Rect web_clipping_bounds = browser_frame_layer_->bounds();
100 non_content_height_ = browser_frame_layer_->bounds().height() -
101 web_contents_layer_->bounds().height();
102 web_clipping_bounds.set_height(browser_frame_layer_->bounds().height() -
103 non_content_height_);
104 web_clipping_bounds.set_origin(gfx::Point(0, non_content_height_));
105 web_clipping_layer_->SetBounds(web_clipping_bounds);
106
107 // Move the web contents since bounds are relative to the parent layer
108 gfx::Rect web_contents_bounds = web_clipping_bounds;
109 web_contents_parent_ = web_contents_layer_->parent();
110 web_contents_bounds.set_origin(gfx::Point(0, 0));
111 web_contents_bounds_ = web_contents_layer_->bounds();
112 web_contents_layer_->SetBounds(web_contents_bounds);
113
114 // Adjust the toplogy of the layer tree to add clipping layers
115 browser_frame_layer_->Add(frame_clipping_layer_.get());
116 frame_clipping_layer_->Add(non_client_layer_);
117 frame_clipping_layer_->Add(web_clipping_layer_.get());
118 web_clipping_layer_->Add(web_contents_layer_);
sadrul 2013/08/20 16:14:59 I think this looks reasonable. Two notes: * Is it
rharrison 2013/08/20 19:57:41 Done.
119 }
120
121 void ScrollEndEffectControllerAsh::DeactivateEffect() {
122 is_effect_active_ = false;
123
124 web_contents_layer_->SetBounds(web_contents_bounds_);
125 web_contents_parent_->Add(web_contents_layer_);
126 web_contents_parent_ = NULL;
127 web_contents_layer_ = NULL;
128
129 frame_clipping_layer_->Remove(non_client_layer_);
130 non_client_view_->SetPaintToLayer(false);
131 non_client_layer_ = NULL;
132 non_client_view_ = NULL;
133
134 frame_clipping_layer_->Remove(web_clipping_layer_.get());
135 web_clipping_layer_.reset();
136 browser_frame_layer_->Remove(frame_clipping_layer_.get());
137 frame_clipping_layer_.reset();
138 browser_frame_layer_ = NULL;
139 }
140
141 void ScrollEndEffectControllerAsh::ApplyDelta(ui::Layer* frame,
142 gfx::Rect bounds,
143 int delta_y) {
144 float scale_factor = std::abs(delta_y);
145 scale_factor /= bounds.height();
146 scale_factor = 1 - scale_factor;
147
148 gfx::Transform frame_transform;
149 if (delta_y > 0) {
150 frame_transform.Translate(0, delta_y);
151 frame_transform.Scale(1, scale_factor);
152 } else {
153 frame_transform.Scale(1, scale_factor);
154 }
155 gfx::Transform counter_transform;
156 CHECK(frame_transform.GetInverse(&counter_transform));
157 frame->SetTransform(frame_transform);
158
159 // Ensure that we apply the counter translation about origin of the web
160 // contents
161 gfx::Transform web_to_frame_transform;
162 web_to_frame_transform.Translate(0, -non_content_height_);
163 gfx::Transform frame_to_web_transform;
164 frame_to_web_transform.Translate(0, non_content_height_);
165 gfx::Transform web_clipping_transform = counter_transform;
166 web_clipping_transform.ConcatTransform(web_to_frame_transform);
167 web_clipping_transform.PreconcatTransform(frame_to_web_transform);
168
169 if (delta_y >= 0) {
170 web_clipping_transform.Translate(0, delta_y);
171 }
172 web_clipping_layer_->SetTransform(web_clipping_transform);
173
174 if (delta_y <= 0) {
175 gfx::Transform web_contents_transform;
176 web_contents_transform.Translate(0, delta_y);
177 web_contents_layer_->SetTransform(web_contents_transform);
178 }
179
180 gfx::Transform non_client_transform = counter_transform;
181 if (delta_y >= 0) {
182 non_client_transform.Translate(0, delta_y);
183 }
184 non_client_layer_->SetTransform(non_client_transform);
185 }
186
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698