OLD | NEW |
---|---|
(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/compiler_specific.h" | |
11 #include "base/logging.h" | |
12 #include "base/message_loop.h" | |
13 #include "base/time.h" | |
14 #include "cc/layer_tree_impl.h" | |
15 #include "cc/top_controls_animation.h" | |
16 #include "ui/gfx/transform.h" | |
17 #include "ui/gfx/vector2d_f.h" | |
18 | |
19 namespace cc { | |
20 | |
21 // static | |
22 scoped_ptr<TopControlsManager> TopControlsManager::create( | |
23 TopControlsDelegate* delegate, bool enabled, float topControlsHeight) { | |
24 return make_scoped_ptr(new TopControlsManager(delegate, enabled, | |
25 topControlsHeight)); | |
26 } | |
27 | |
28 TopControlsManager::TopControlsManager(TopControlsDelegate* delegate, | |
29 bool enabled, float topControlsHeight) | |
30 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), | |
31 delegate_(delegate), | |
32 enabled_(enabled), | |
33 is_overlay_mode_(false), | |
34 top_controls_height_(topControlsHeight), | |
35 controls_top_offset_(0), | |
36 content_top_offset_(topControlsHeight), | |
37 top_controls_auto_hide_trigger_time_(-1), | |
38 previous_root_scroll_offset_(-1.f) { | |
aelias_OOO_until_Jul13
2012/12/19 08:31:18
Use 0 here, not -1.
Ted C
2012/12/19 21:34:17
I need some value to ensure it doesn't update whil
| |
39 CHECK(delegate_); | |
40 } | |
41 | |
42 TopControlsManager::~TopControlsManager() { | |
43 } | |
44 | |
45 void TopControlsManager::updateDrawPositions() { | |
46 if (!enabled_ || !rootScrollLayer()) | |
47 return; | |
48 | |
49 // If the scroll position has changed underneath us (i.e. a javascript | |
50 // scroll), then simulate a scroll that covers the delta. | |
51 float scrollTotalY = rootScrollLayerTotalScrollY(); | |
52 if (previous_root_scroll_offset_ >= 0 | |
53 && scrollTotalY != previous_root_scroll_offset_) { | |
54 scrollBy(gfx::Vector2dF(0, scrollTotalY - previous_root_scroll_offset_)); | |
55 startAnimationIfNecessary(); | |
56 previous_root_scroll_offset_ = rootScrollLayerTotalScrollY(); | |
57 } | |
58 | |
59 float offsetTop = is_overlay_mode_ ? 0 : content_top_offset_; | |
60 | |
61 // The two layers that need to be transformed are the clip layer and root | |
62 // scrollbar layers, which are the only two children of the root layer. | |
63 LayerImpl* rootLayer = delegate_->activeTree()->RootLayer(); | |
64 for (size_t i = 0; i < rootLayer->children().size(); ++i) { | |
65 LayerImpl* childLayer = rootLayer->children()[i]; | |
66 gfx::Transform transform; | |
67 transform.Translate(0, offsetTop); | |
68 childLayer->setImplTransform(transform); | |
69 } | |
70 | |
71 // TODO(tedchoc): Adjust fixed position layers as well. | |
72 } | |
73 | |
74 void TopControlsManager::scrollBegin() { | |
75 resetAnimations(); | |
76 previous_root_scroll_offset_ = -1; | |
aelias_OOO_until_Jul13
2012/12/19 08:31:18
I don't think it's a good idea to have -1 as a mag
| |
77 } | |
78 | |
79 gfx::Vector2dF TopControlsManager::scrollBy(const gfx::Vector2dF pendingDelta) { | |
80 if (!enabled_) | |
81 return pendingDelta; | |
82 | |
83 float scrollTotalY = rootScrollLayerTotalScrollY(); | |
84 float scrollDeltaY = pendingDelta.y(); | |
85 | |
86 float previousControlsOffset = controls_top_offset_; | |
87 float previousContentOffset = content_top_offset_; | |
88 bool previousWasOverlay = is_overlay_mode_; | |
89 | |
90 controls_top_offset_ -= scrollDeltaY; | |
91 controls_top_offset_ = std::min( | |
92 std::max(controls_top_offset_, -top_controls_height_), 0.f); | |
93 | |
94 if (scrollTotalY > 0 || (scrollTotalY == 0 | |
95 && content_top_offset_ < scrollDeltaY)) { | |
96 is_overlay_mode_ = true; | |
97 content_top_offset_ = 0; | |
98 } else if (scrollTotalY <= 0 && (scrollDeltaY < 0 | |
99 || (scrollDeltaY > 0 && content_top_offset_ > 0))) { | |
100 is_overlay_mode_ = false; | |
101 content_top_offset_ -= scrollDeltaY; | |
102 } | |
103 content_top_offset_ = std::max( | |
104 std::min(content_top_offset_, | |
105 controls_top_offset_ + top_controls_height_), 0.f); | |
106 | |
107 gfx::Vector2dF appliedDelta; | |
108 if (!previousWasOverlay) | |
109 appliedDelta.set_y(previousContentOffset - content_top_offset_); | |
110 | |
111 if (is_overlay_mode_ != previousWasOverlay | |
112 || previousControlsOffset != controls_top_offset_ | |
113 || previousContentOffset != content_top_offset_) { | |
114 delegate_->setNeedsRedraw(); | |
115 delegate_->setNeedsUpdateDrawProperties(); | |
116 } | |
117 | |
118 return pendingDelta - appliedDelta; | |
119 } | |
120 | |
121 void TopControlsManager::scrollEnd() { | |
122 if (!enabled_) | |
123 return; | |
124 startAnimationIfNecessary(); | |
125 previous_root_scroll_offset_ = rootScrollLayerTotalScrollY(); | |
126 } | |
127 | |
128 void TopControlsManager::animate(base::TimeTicks monotonicTime) { | |
129 if (!enabled_) | |
130 return; | |
131 | |
132 if (!top_controls_animation_ || !rootScrollLayer()) | |
133 return; | |
134 | |
135 double time = (monotonicTime - base::TimeTicks()).InSecondsF(); | |
136 float newOffset = top_controls_animation_->scrollOffsetAtTime(monotonicTime); | |
137 gfx::Vector2dF scrollVector(0.f, -(newOffset - controls_top_offset_)); | |
138 scrollBy(scrollVector); | |
139 delegate_->setNeedsRedraw(); | |
140 | |
141 if (top_controls_animation_->isAnimationCompleteAtTime(monotonicTime)) { | |
142 top_controls_animation_.reset(); | |
143 startAnimationIfNecessary(); | |
144 } | |
145 } | |
146 | |
147 void TopControlsManager::resetAnimations() { | |
148 if (!enabled_) | |
149 return; | |
150 if (top_controls_animation_) | |
151 top_controls_animation_.reset(); | |
152 top_controls_auto_hide_trigger_time_ = -1; | |
153 } | |
154 | |
155 LayerImpl* TopControlsManager::rootScrollLayer() { | |
156 return delegate_->activeTree()->root_scroll_layer(); | |
157 } | |
158 | |
159 float TopControlsManager::rootScrollLayerTotalScrollY() { | |
160 LayerImpl* layer = rootScrollLayer(); | |
161 if (!layer) | |
162 return 0; | |
163 gfx::Vector2dF scrollTotal = layer->scrollOffset() + layer->scrollDelta(); | |
164 return scrollTotal.y(); | |
165 } | |
166 | |
167 void TopControlsManager::startAnimationIfNecessary() { | |
168 if (!enabled_) | |
169 return; | |
170 | |
171 if (!is_overlay_mode_) | |
172 return; | |
173 | |
174 float scrollTotalY; | |
aelias_OOO_until_Jul13
2012/12/19 08:31:18
This may be uninitialized. Just change it to:
flo
Ted C
2012/12/19 21:34:17
Done.
| |
175 if (rootScrollLayer()) | |
176 scrollTotalY = rootScrollLayerTotalScrollY(); | |
177 | |
178 if (controls_top_offset_ != 0 | |
179 && controls_top_offset_ != -top_controls_height_) { | |
180 top_controls_animation_ = TopControlsAnimation::create( | |
181 controls_top_offset_, | |
182 top_controls_height_, | |
183 base::TimeTicks::Now(), | |
184 base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs)); | |
185 top_controls_animation_->setDirection( | |
186 controls_top_offset_ >= -(top_controls_height_ * 0.75f)); | |
aelias_OOO_until_Jul13
2012/12/19 08:31:18
Promote 0.75f to a constant at the top of this fil
Ted C
2012/12/19 21:34:17
Done.
| |
187 delegate_->setNeedsRedraw(); | |
188 } else if (controls_top_offset_ == 0 && scrollTotalY != 0) { | |
189 MessageLoop* loop = MessageLoop::current(); | |
190 DCHECK(loop); | |
191 if (loop) { | |
192 int64 triggerTime = top_controls_auto_hide_trigger_time_ = | |
193 (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds(); | |
194 loop->PostDelayedTask( | |
195 FROM_HERE, | |
196 base::Bind(&TopControlsManager::startAutoHideAnimation, | |
197 weak_ptr_factory_.GetWeakPtr(), triggerTime), | |
198 base::TimeDelta::FromMilliseconds(kAutoHideDelayMs)); | |
199 } | |
200 } | |
201 } | |
202 | |
203 void TopControlsManager::startAutoHideAnimation(int64 triggeredTime) { | |
204 if (!enabled_) | |
205 return; | |
206 | |
207 if (triggeredTime != top_controls_auto_hide_trigger_time_) | |
208 return; | |
209 | |
210 top_controls_animation_ = TopControlsAnimation::create( | |
211 controls_top_offset_, | |
212 top_controls_height_, | |
213 base::TimeTicks::Now(), | |
214 base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs)); | |
215 top_controls_animation_->setDirection(false); | |
216 delegate_->setNeedsRedraw(); | |
217 } | |
218 | |
219 } // namespace cc | |
OLD | NEW |