Chromium Code Reviews| 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 |