OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "cc/input/top_controls_manager.h" | 5 #include "cc/input/browser_controls_offset_manager.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
13 #include "cc/input/top_controls_manager_client.h" | 13 #include "cc/input/browser_controls_offset_manager_client.h" |
14 #include "cc/output/begin_frame_args.h" | 14 #include "cc/output/begin_frame_args.h" |
15 #include "cc/trees/layer_tree_impl.h" | 15 #include "cc/trees/layer_tree_impl.h" |
16 #include "ui/gfx/animation/tween.h" | 16 #include "ui/gfx/animation/tween.h" |
17 #include "ui/gfx/geometry/vector2d_f.h" | 17 #include "ui/gfx/geometry/vector2d_f.h" |
18 #include "ui/gfx/transform.h" | 18 #include "ui/gfx/transform.h" |
19 | 19 |
20 namespace cc { | 20 namespace cc { |
21 namespace { | 21 namespace { |
22 // These constants were chosen empirically for their visually pleasant behavior. | 22 // These constants were chosen empirically for their visually pleasant behavior. |
23 // Contact tedchoc@chromium.org for questions about changing these values. | 23 // Contact tedchoc@chromium.org for questions about changing these values. |
24 const int64_t kShowHideMaxDurationMs = 200; | 24 const int64_t kShowHideMaxDurationMs = 200; |
25 } | 25 } |
26 | 26 |
27 // static | 27 // static |
28 std::unique_ptr<TopControlsManager> TopControlsManager::Create( | 28 std::unique_ptr<BrowserControlsOffsetManager> |
29 TopControlsManagerClient* client, | 29 BrowserControlsOffsetManager::Create(BrowserControlsOffsetManagerClient* client, |
30 float top_controls_show_threshold, | 30 float controls_show_threshold, |
31 float top_controls_hide_threshold) { | 31 float controls_hide_threshold) { |
32 return base::WrapUnique(new TopControlsManager( | 32 return base::WrapUnique(new BrowserControlsOffsetManager( |
33 client, top_controls_show_threshold, top_controls_hide_threshold)); | 33 client, controls_show_threshold, controls_hide_threshold)); |
34 } | 34 } |
35 | 35 |
36 TopControlsManager::TopControlsManager(TopControlsManagerClient* client, | 36 BrowserControlsOffsetManager::BrowserControlsOffsetManager( |
37 float top_controls_show_threshold, | 37 BrowserControlsOffsetManagerClient* client, |
38 float top_controls_hide_threshold) | 38 float controls_show_threshold, |
| 39 float controls_hide_threshold) |
39 : client_(client), | 40 : client_(client), |
40 animation_start_value_(0.f), | 41 animation_start_value_(0.f), |
41 animation_stop_value_(0.f), | 42 animation_stop_value_(0.f), |
42 animation_direction_(NO_ANIMATION), | 43 animation_direction_(NO_ANIMATION), |
43 permitted_state_(BOTH), | 44 permitted_state_(BOTH), |
44 accumulated_scroll_delta_(0.f), | 45 accumulated_scroll_delta_(0.f), |
45 baseline_content_offset_(0.f), | 46 baseline_content_offset_(0.f), |
46 top_controls_show_threshold_(top_controls_hide_threshold), | 47 controls_show_threshold_(controls_hide_threshold), |
47 top_controls_hide_threshold_(top_controls_show_threshold), | 48 controls_hide_threshold_(controls_show_threshold), |
48 pinch_gesture_active_(false) { | 49 pinch_gesture_active_(false) { |
49 CHECK(client_); | 50 CHECK(client_); |
50 } | 51 } |
51 | 52 |
52 TopControlsManager::~TopControlsManager() { | 53 BrowserControlsOffsetManager::~BrowserControlsOffsetManager() {} |
53 } | |
54 | 54 |
55 float TopControlsManager::ControlsTopOffset() const { | 55 float BrowserControlsOffsetManager::ControlsTopOffset() const { |
56 return ContentTopOffset() - TopControlsHeight(); | 56 return ContentTopOffset() - TopControlsHeight(); |
57 } | 57 } |
58 | 58 |
59 float TopControlsManager::ContentTopOffset() const { | 59 float BrowserControlsOffsetManager::ContentTopOffset() const { |
60 return TopControlsShownRatio() * TopControlsHeight(); | 60 return TopControlsShownRatio() * TopControlsHeight(); |
61 } | 61 } |
62 | 62 |
63 float TopControlsManager::TopControlsShownRatio() const { | 63 float BrowserControlsOffsetManager::ContentOffsetInternal() const { |
64 return client_->CurrentTopControlsShownRatio(); | 64 if (!TopControlsHeight()) |
| 65 return BottomControlsShownRatio() * BottomControlsHeight(); |
| 66 return ContentTopOffset(); |
65 } | 67 } |
66 | 68 |
67 float TopControlsManager::TopControlsHeight() const { | 69 float BrowserControlsOffsetManager::TopControlsShownRatio() const { |
| 70 return client_->CurrentBrowserControlsShownRatio(); |
| 71 } |
| 72 |
| 73 float BrowserControlsOffsetManager::TopControlsHeight() const { |
68 return client_->TopControlsHeight(); | 74 return client_->TopControlsHeight(); |
69 } | 75 } |
70 | 76 |
71 float TopControlsManager::BottomControlsHeight() const { | 77 float BrowserControlsOffsetManager::BottomControlsHeight() const { |
72 return client_->BottomControlsHeight(); | 78 return client_->BottomControlsHeight(); |
73 } | 79 } |
74 | 80 |
75 float TopControlsManager::ContentBottomOffset() const { | 81 float BrowserControlsOffsetManager::ContentBottomOffset() const { |
76 return TopControlsShownRatio() * BottomControlsHeight(); | 82 return BottomControlsShownRatio() * BottomControlsHeight(); |
77 } | 83 } |
78 | 84 |
79 float TopControlsManager::BottomControlsShownRatio() const { | 85 float BrowserControlsOffsetManager::BottomControlsShownRatio() const { |
80 return TopControlsShownRatio(); | 86 return TopControlsShownRatio(); |
81 } | 87 } |
82 | 88 |
83 void TopControlsManager::UpdateTopControlsState(TopControlsState constraints, | 89 void BrowserControlsOffsetManager::UpdateBrowserControlsState( |
84 TopControlsState current, | 90 BrowserControlsState constraints, |
85 bool animate) { | 91 BrowserControlsState current, |
| 92 bool animate) { |
86 DCHECK(!(constraints == SHOWN && current == HIDDEN)); | 93 DCHECK(!(constraints == SHOWN && current == HIDDEN)); |
87 DCHECK(!(constraints == HIDDEN && current == SHOWN)); | 94 DCHECK(!(constraints == HIDDEN && current == SHOWN)); |
88 | 95 |
89 permitted_state_ = constraints; | 96 permitted_state_ = constraints; |
90 | 97 |
91 // Don't do anything if it doesn't matter which state the controls are in. | 98 // Don't do anything if it doesn't matter which state the controls are in. |
92 if (constraints == BOTH && current == BOTH) | 99 if (constraints == BOTH && current == BOTH) |
93 return; | 100 return; |
94 | 101 |
95 // Don't do anything if there is no change in offset. | 102 // Don't do anything if there is no change in offset. |
96 float final_shown_ratio = 1.f; | 103 float final_shown_ratio = 1.f; |
97 if (constraints == HIDDEN || current == HIDDEN) | 104 if (constraints == HIDDEN || current == HIDDEN) |
98 final_shown_ratio = 0.f; | 105 final_shown_ratio = 0.f; |
99 if (final_shown_ratio == TopControlsShownRatio()) { | 106 if (final_shown_ratio == TopControlsShownRatio()) { |
100 ResetAnimations(); | 107 ResetAnimations(); |
101 return; | 108 return; |
102 } | 109 } |
103 | 110 |
104 if (animate) { | 111 if (animate) { |
105 SetupAnimation(final_shown_ratio ? SHOWING_CONTROLS : HIDING_CONTROLS); | 112 SetupAnimation(final_shown_ratio ? SHOWING_CONTROLS : HIDING_CONTROLS); |
106 } else { | 113 } else { |
107 ResetAnimations(); | 114 ResetAnimations(); |
108 client_->SetCurrentTopControlsShownRatio(final_shown_ratio); | 115 client_->SetCurrentBrowserControlsShownRatio(final_shown_ratio); |
109 } | 116 } |
110 } | 117 } |
111 | 118 |
112 void TopControlsManager::ScrollBegin() { | 119 void BrowserControlsOffsetManager::ScrollBegin() { |
113 if (pinch_gesture_active_) | 120 if (pinch_gesture_active_) |
114 return; | 121 return; |
115 | 122 |
116 ResetAnimations(); | 123 ResetAnimations(); |
117 ResetBaseline(); | 124 ResetBaseline(); |
118 } | 125 } |
119 | 126 |
120 gfx::Vector2dF TopControlsManager::ScrollBy( | 127 gfx::Vector2dF BrowserControlsOffsetManager::ScrollBy( |
121 const gfx::Vector2dF& pending_delta) { | 128 const gfx::Vector2dF& pending_delta) { |
122 if (!TopControlsHeight()) | 129 // If one or both of the top/bottom controls are showing, the shown ratio |
| 130 // needs to be computed. |
| 131 float controls_height = |
| 132 TopControlsHeight() ? TopControlsHeight() : BottomControlsHeight(); |
| 133 |
| 134 if (!controls_height) |
123 return pending_delta; | 135 return pending_delta; |
124 | 136 |
125 if (pinch_gesture_active_) | 137 if (pinch_gesture_active_) |
126 return pending_delta; | 138 return pending_delta; |
127 | 139 |
128 if (permitted_state_ == SHOWN && pending_delta.y() > 0) | 140 if (permitted_state_ == SHOWN && pending_delta.y() > 0) |
129 return pending_delta; | 141 return pending_delta; |
130 else if (permitted_state_ == HIDDEN && pending_delta.y() < 0) | 142 else if (permitted_state_ == HIDDEN && pending_delta.y() < 0) |
131 return pending_delta; | 143 return pending_delta; |
132 | 144 |
133 accumulated_scroll_delta_ += pending_delta.y(); | 145 accumulated_scroll_delta_ += pending_delta.y(); |
134 | 146 |
135 float old_offset = ContentTopOffset(); | 147 float old_offset = ContentOffsetInternal(); |
136 client_->SetCurrentTopControlsShownRatio( | 148 client_->SetCurrentBrowserControlsShownRatio( |
137 (baseline_content_offset_ - accumulated_scroll_delta_) / | 149 (baseline_content_offset_ - accumulated_scroll_delta_) / controls_height); |
138 TopControlsHeight()); | |
139 | 150 |
140 // If the controls are fully visible, treat the current position as the | 151 // If the controls are fully visible, treat the current position as the |
141 // new baseline even if the gesture didn't end. | 152 // new baseline even if the gesture didn't end. |
142 if (TopControlsShownRatio() == 1.f) | 153 if (TopControlsShownRatio() == 1.f) |
143 ResetBaseline(); | 154 ResetBaseline(); |
144 | 155 |
145 ResetAnimations(); | 156 ResetAnimations(); |
146 | 157 |
147 gfx::Vector2dF applied_delta(0.f, old_offset - ContentTopOffset()); | 158 gfx::Vector2dF applied_delta(0.f, old_offset - ContentOffsetInternal()); |
148 return pending_delta - applied_delta; | 159 return pending_delta - applied_delta; |
149 } | 160 } |
150 | 161 |
151 void TopControlsManager::ScrollEnd() { | 162 void BrowserControlsOffsetManager::ScrollEnd() { |
152 if (pinch_gesture_active_) | 163 if (pinch_gesture_active_) |
153 return; | 164 return; |
154 | 165 |
155 StartAnimationIfNecessary(); | 166 StartAnimationIfNecessary(); |
156 } | 167 } |
157 | 168 |
158 void TopControlsManager::PinchBegin() { | 169 void BrowserControlsOffsetManager::PinchBegin() { |
159 DCHECK(!pinch_gesture_active_); | 170 DCHECK(!pinch_gesture_active_); |
160 pinch_gesture_active_ = true; | 171 pinch_gesture_active_ = true; |
161 StartAnimationIfNecessary(); | 172 StartAnimationIfNecessary(); |
162 } | 173 } |
163 | 174 |
164 void TopControlsManager::PinchEnd() { | 175 void BrowserControlsOffsetManager::PinchEnd() { |
165 DCHECK(pinch_gesture_active_); | 176 DCHECK(pinch_gesture_active_); |
166 // Pinch{Begin,End} will always occur within the scope of Scroll{Begin,End}, | 177 // Pinch{Begin,End} will always occur within the scope of Scroll{Begin,End}, |
167 // so return to a state expected by the remaining scroll sequence. | 178 // so return to a state expected by the remaining scroll sequence. |
168 pinch_gesture_active_ = false; | 179 pinch_gesture_active_ = false; |
169 ScrollBegin(); | 180 ScrollBegin(); |
170 } | 181 } |
171 | 182 |
172 void TopControlsManager::MainThreadHasStoppedFlinging() { | 183 void BrowserControlsOffsetManager::MainThreadHasStoppedFlinging() { |
173 StartAnimationIfNecessary(); | 184 StartAnimationIfNecessary(); |
174 } | 185 } |
175 | 186 |
176 gfx::Vector2dF TopControlsManager::Animate(base::TimeTicks monotonic_time) { | 187 gfx::Vector2dF BrowserControlsOffsetManager::Animate( |
| 188 base::TimeTicks monotonic_time) { |
177 if (!has_animation() || !client_->HaveRootScrollLayer()) | 189 if (!has_animation() || !client_->HaveRootScrollLayer()) |
178 return gfx::Vector2dF(); | 190 return gfx::Vector2dF(); |
179 | 191 |
180 float old_offset = ContentTopOffset(); | 192 float old_offset = ContentOffsetInternal(); |
181 float new_ratio = gfx::Tween::ClampedFloatValueBetween( | 193 float new_ratio = gfx::Tween::ClampedFloatValueBetween( |
182 monotonic_time, animation_start_time_, animation_start_value_, | 194 monotonic_time, animation_start_time_, animation_start_value_, |
183 animation_stop_time_, animation_stop_value_); | 195 animation_stop_time_, animation_stop_value_); |
184 client_->SetCurrentTopControlsShownRatio(new_ratio); | 196 client_->SetCurrentBrowserControlsShownRatio(new_ratio); |
185 | 197 |
186 if (IsAnimationComplete(new_ratio)) | 198 if (IsAnimationComplete(new_ratio)) |
187 ResetAnimations(); | 199 ResetAnimations(); |
188 | 200 |
189 gfx::Vector2dF scroll_delta(0.f, ContentTopOffset() - old_offset); | 201 gfx::Vector2dF scroll_delta(0.f, ContentOffsetInternal() - old_offset); |
190 return scroll_delta; | 202 return scroll_delta; |
191 } | 203 } |
192 | 204 |
193 void TopControlsManager::ResetAnimations() { | 205 void BrowserControlsOffsetManager::ResetAnimations() { |
194 animation_start_time_ = base::TimeTicks(); | 206 animation_start_time_ = base::TimeTicks(); |
195 animation_start_value_ = 0.f; | 207 animation_start_value_ = 0.f; |
196 animation_stop_time_ = base::TimeTicks(); | 208 animation_stop_time_ = base::TimeTicks(); |
197 animation_stop_value_ = 0.f; | 209 animation_stop_value_ = 0.f; |
198 | 210 |
199 animation_direction_ = NO_ANIMATION; | 211 animation_direction_ = NO_ANIMATION; |
200 } | 212 } |
201 | 213 |
202 void TopControlsManager::SetupAnimation(AnimationDirection direction) { | 214 void BrowserControlsOffsetManager::SetupAnimation( |
| 215 AnimationDirection direction) { |
203 DCHECK_NE(NO_ANIMATION, direction); | 216 DCHECK_NE(NO_ANIMATION, direction); |
204 DCHECK(direction != HIDING_CONTROLS || TopControlsShownRatio() > 0.f); | 217 DCHECK(direction != HIDING_CONTROLS || TopControlsShownRatio() > 0.f); |
205 DCHECK(direction != SHOWING_CONTROLS || TopControlsShownRatio() < 1.f); | 218 DCHECK(direction != SHOWING_CONTROLS || TopControlsShownRatio() < 1.f); |
206 | 219 |
207 if (has_animation() && animation_direction_ == direction) | 220 if (has_animation() && animation_direction_ == direction) |
208 return; | 221 return; |
209 | 222 |
210 if (!TopControlsHeight()) { | 223 if (!TopControlsHeight() && !BottomControlsHeight()) { |
211 client_->SetCurrentTopControlsShownRatio( | 224 client_->SetCurrentBrowserControlsShownRatio( |
212 direction == HIDING_CONTROLS ? 0.f : 1.f); | 225 direction == HIDING_CONTROLS ? 0.f : 1.f); |
213 return; | 226 return; |
214 } | 227 } |
215 | 228 |
216 animation_start_time_ = base::TimeTicks::Now(); | 229 animation_start_time_ = base::TimeTicks::Now(); |
217 animation_start_value_ = TopControlsShownRatio(); | 230 animation_start_value_ = TopControlsShownRatio(); |
218 | 231 |
219 const float max_ending_ratio = (direction == SHOWING_CONTROLS ? 1 : -1); | 232 const float max_ending_ratio = (direction == SHOWING_CONTROLS ? 1 : -1); |
220 animation_stop_time_ = | 233 animation_stop_time_ = |
221 animation_start_time_ + | 234 animation_start_time_ + |
222 base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs); | 235 base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs); |
223 animation_stop_value_ = animation_start_value_ + max_ending_ratio; | 236 animation_stop_value_ = animation_start_value_ + max_ending_ratio; |
224 | 237 |
225 animation_direction_ = direction; | 238 animation_direction_ = direction; |
226 client_->DidChangeTopControlsPosition(); | 239 client_->DidChangeBrowserControlsPosition(); |
227 } | 240 } |
228 | 241 |
229 void TopControlsManager::StartAnimationIfNecessary() { | 242 void BrowserControlsOffsetManager::StartAnimationIfNecessary() { |
230 if (TopControlsShownRatio() == 0.f || TopControlsShownRatio() == 1.f) | 243 if (TopControlsShownRatio() == 0.f || TopControlsShownRatio() == 1.f) |
231 return; | 244 return; |
232 | 245 |
233 if (TopControlsShownRatio() >= 1.f - top_controls_hide_threshold_) { | 246 if (TopControlsShownRatio() >= 1.f - controls_hide_threshold_) { |
234 // If we're showing so much that the hide threshold won't trigger, show. | 247 // If we're showing so much that the hide threshold won't trigger, show. |
235 SetupAnimation(SHOWING_CONTROLS); | 248 SetupAnimation(SHOWING_CONTROLS); |
236 } else if (TopControlsShownRatio() <= top_controls_show_threshold_) { | 249 } else if (TopControlsShownRatio() <= controls_show_threshold_) { |
237 // If we're showing so little that the show threshold won't trigger, hide. | 250 // If we're showing so little that the show threshold won't trigger, hide. |
238 SetupAnimation(HIDING_CONTROLS); | 251 SetupAnimation(HIDING_CONTROLS); |
239 } else { | 252 } else { |
240 // If we could be either showing or hiding, we determine which one to | 253 // If we could be either showing or hiding, we determine which one to |
241 // do based on whether or not the total scroll delta was moving up or | 254 // do based on whether or not the total scroll delta was moving up or |
242 // down. | 255 // down. |
243 SetupAnimation(accumulated_scroll_delta_ <= 0.f ? SHOWING_CONTROLS | 256 SetupAnimation(accumulated_scroll_delta_ <= 0.f ? SHOWING_CONTROLS |
244 : HIDING_CONTROLS); | 257 : HIDING_CONTROLS); |
245 } | 258 } |
246 } | 259 } |
247 | 260 |
248 bool TopControlsManager::IsAnimationComplete(float new_ratio) { | 261 bool BrowserControlsOffsetManager::IsAnimationComplete(float new_ratio) { |
249 return (animation_direction_ == SHOWING_CONTROLS && new_ratio >= 1.f) || | 262 return (animation_direction_ == SHOWING_CONTROLS && new_ratio >= 1.f) || |
250 (animation_direction_ == HIDING_CONTROLS && new_ratio <= 0.f); | 263 (animation_direction_ == HIDING_CONTROLS && new_ratio <= 0.f); |
251 } | 264 } |
252 | 265 |
253 void TopControlsManager::ResetBaseline() { | 266 void BrowserControlsOffsetManager::ResetBaseline() { |
254 accumulated_scroll_delta_ = 0.f; | 267 accumulated_scroll_delta_ = 0.f; |
255 baseline_content_offset_ = ContentTopOffset(); | 268 baseline_content_offset_ = ContentOffsetInternal(); |
256 } | 269 } |
257 | 270 |
258 } // namespace cc | 271 } // namespace cc |
OLD | NEW |