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

Side by Side Diff: cc/top_controls_manager.cc

Issue 11552009: Add support for calculating the position of the top controls in the cc layer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 11 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
(Empty)
1 // Copyright 2012 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 "cc/top_controls_manager.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/time.h"
13 #include "cc/layer_tree_impl.h"
14 #include "cc/top_controls_animation.h"
15 #include "cc/top_controls_manager_client.h"
16 #include "ui/gfx/transform.h"
17 #include "ui/gfx/vector2d_f.h"
18
19 namespace cc {
20 namespace {
21 const float kShowHideThreshold = 0.75f;
jamesr 2013/01/08 02:26:48 can you leave a comment here saying where these nu
Ted C 2013/01/08 18:17:33 Done.
22 const int64 kAutoHideDelayMs = 1500;
23 const int64 kShowHideMaxDurationMs = 500;
24 }
25
26 // static
27 scoped_ptr<TopControlsManager> TopControlsManager::Create(
28 TopControlsManagerClient* client, float top_controls_height) {
29 return make_scoped_ptr(new TopControlsManager(client, top_controls_height));
30 }
31
32 TopControlsManager::TopControlsManager(TopControlsManagerClient* client,
33 float top_controls_height)
34 : client_(client),
35 is_overlay_mode_(false),
36 top_controls_height_(top_controls_height),
37 controls_top_offset_(0),
38 content_top_offset_(top_controls_height),
39 previous_root_scroll_offset_(0.f),
40 scroll_readjustment_enabled_(false) {
41 CHECK(client_);
42 }
43
44 TopControlsManager::~TopControlsManager() {
45 }
46
47 void TopControlsManager::UpdateDrawPositions() {
48 if (!RootScrollLayer())
49 return;
50
51 // If the scroll position has changed underneath us (i.e. a javascript
52 // scroll), then simulate a scroll that covers the delta.
53 float scroll_total_y = RootScrollLayerTotalScrollY();
54 if (scroll_readjustment_enabled_
55 && scroll_total_y != previous_root_scroll_offset_) {
56 ScrollBy(gfx::Vector2dF(0, scroll_total_y - previous_root_scroll_offset_));
57 StartAnimationIfNecessary();
58 previous_root_scroll_offset_ = RootScrollLayerTotalScrollY();
59 }
60
61 float offset_top = is_overlay_mode_ ? 0 : content_top_offset_;
62
63 // The two layers that need to be transformed are the clip layer and root
64 // scrollbar layers, which are the only two children of the root layer.
65 LayerImpl* root_layer = client_->activeTree()->RootLayer();
66 for (size_t i = 0; i < root_layer->children().size(); ++i) {
67 LayerImpl* child_layer = root_layer->children()[i];
68 gfx::Transform transform;
69 transform.Translate(0, offset_top);
70 child_layer->setImplTransform(transform);
enne (OOO) 2013/01/08 06:23:05 It seems more than a little dangerous that the top
Ted C 2013/01/08 18:17:33 For adjusting the fixed position layers, that migh
71 }
72
73 // TODO(tedchoc): Adjust fixed position layers as well.
74 }
75
76 void TopControlsManager::ScrollBegin() {
77 ResetAnimations();
78 scroll_readjustment_enabled_ = false;
79 }
80
81 gfx::Vector2dF TopControlsManager::ScrollBy(
82 const gfx::Vector2dF pending_delta) {
83 ResetAnimations();
84 return ScrollInternal(pending_delta);
85 }
86
87 gfx::Vector2dF TopControlsManager::ScrollInternal(
88 const gfx::Vector2dF pending_delta) {
89 float scroll_total_y = RootScrollLayerTotalScrollY();
90 float scroll_delta_y = pending_delta.y();
91
92 float previous_controls_offset = controls_top_offset_;
93 float previous_content_offset = content_top_offset_;
94 bool previous_was_overlay = is_overlay_mode_;
95
96 controls_top_offset_ -= scroll_delta_y;
97 controls_top_offset_ = std::min(
98 std::max(controls_top_offset_, -top_controls_height_), 0.f);
99
100 if (scroll_total_y > 0 || (scroll_total_y == 0
101 && content_top_offset_ < scroll_delta_y)) {
102 is_overlay_mode_ = true;
103 content_top_offset_ = 0;
104 } else if (scroll_total_y <= 0 && (scroll_delta_y < 0
105 || (scroll_delta_y > 0 && content_top_offset_ > 0))) {
106 is_overlay_mode_ = false;
107 content_top_offset_ -= scroll_delta_y;
108 }
109 content_top_offset_ = std::max(
110 std::min(content_top_offset_,
111 controls_top_offset_ + top_controls_height_), 0.f);
112
113 gfx::Vector2dF applied_delta;
114 if (!previous_was_overlay)
115 applied_delta.set_y(previous_content_offset - content_top_offset_);
116
117 if (is_overlay_mode_ != previous_was_overlay
118 || previous_controls_offset != controls_top_offset_
119 || previous_content_offset != content_top_offset_) {
120 client_->setNeedsRedraw();
121 client_->setNeedsUpdateDrawProperties();
122 }
123
124 return pending_delta - applied_delta;
125 }
126
127 void TopControlsManager::ScrollEnd() {
128 StartAnimationIfNecessary();
129 previous_root_scroll_offset_ = RootScrollLayerTotalScrollY();
130 scroll_readjustment_enabled_ = true;
131 }
132
133 void TopControlsManager::Animate(base::TimeTicks monotonic_time) {
134 if (!top_controls_animation_ || !RootScrollLayer())
135 return;
136
137 double time = (monotonic_time - base::TimeTicks()).InSecondsF();
138 float new_offset =
139 top_controls_animation_->ScrollOffsetAtTime(monotonic_time);
140 gfx::Vector2dF scroll_vector(0.f, -(new_offset - controls_top_offset_));
141 ScrollInternal(scroll_vector);
142 client_->setNeedsRedraw();
143
144 if (top_controls_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
145 top_controls_animation_.reset();
146 StartAnimationIfNecessary();
147 }
148 }
149
150 void TopControlsManager::ResetAnimations() {
151 if (top_controls_animation_)
152 top_controls_animation_.reset();
153 auto_hide_timer_.Stop();
154 }
155
156 LayerImpl* TopControlsManager::RootScrollLayer() {
157 return client_->activeTree()->root_scroll_layer();
158 }
159
160 float TopControlsManager::RootScrollLayerTotalScrollY() {
161 LayerImpl* layer = RootScrollLayer();
162 if (!layer)
163 return 0;
164 gfx::Vector2dF scroll_total = layer->scrollOffset() + layer->scrollDelta();
165 return scroll_total.y();
166 }
167
168 void TopControlsManager::StartAnimationIfNecessary() {
169 if (!is_overlay_mode_)
170 return;
171
172 float scroll_total_y = RootScrollLayerTotalScrollY();
173
174 if (controls_top_offset_ != 0
175 && controls_top_offset_ != -top_controls_height_) {
176 top_controls_animation_ = TopControlsAnimation::Create(
177 controls_top_offset_,
178 top_controls_height_,
179 base::TimeTicks::Now(),
180 base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs));
181 top_controls_animation_->SetDirection(
182 controls_top_offset_ >= -(top_controls_height_ * kShowHideThreshold));
183 client_->setNeedsRedraw();
184 } else if (controls_top_offset_ == 0 && scroll_total_y != 0) {
185 auto_hide_timer_.Stop();
186 auto_hide_timer_.Start(FROM_HERE,
187 base::TimeDelta::FromMilliseconds(kAutoHideDelayMs),
188 this,
189 &TopControlsManager::StartAutoHideAnimation);
190 }
191 }
192
193 void TopControlsManager::StartAutoHideAnimation() {
194 top_controls_animation_ = TopControlsAnimation::Create(
195 controls_top_offset_,
196 top_controls_height_,
197 base::TimeTicks::Now(),
198 base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs));
199 top_controls_animation_->SetDirection(false);
200 client_->setNeedsRedraw();
201 }
202
203 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698