| OLD | NEW | 
|---|
| 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 "cc/input/top_controls_manager.h" | 5 #include "cc/input/top_controls_manager.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 | 8 | 
| 9 #include "base/logging.h" | 9 #include "base/logging.h" | 
| 10 #include "cc/animation/keyframed_animation_curve.h" | 10 #include "cc/animation/keyframed_animation_curve.h" | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 32                                                 top_controls_show_threshold, | 32                                                 top_controls_show_threshold, | 
| 33                                                 top_controls_hide_threshold)); | 33                                                 top_controls_hide_threshold)); | 
| 34 } | 34 } | 
| 35 | 35 | 
| 36 TopControlsManager::TopControlsManager(TopControlsManagerClient* client, | 36 TopControlsManager::TopControlsManager(TopControlsManagerClient* client, | 
| 37                                        float top_controls_show_threshold, | 37                                        float top_controls_show_threshold, | 
| 38                                        float top_controls_hide_threshold) | 38                                        float top_controls_hide_threshold) | 
| 39     : client_(client), | 39     : client_(client), | 
| 40       animation_direction_(NO_ANIMATION), | 40       animation_direction_(NO_ANIMATION), | 
| 41       permitted_state_(BOTH), | 41       permitted_state_(BOTH), | 
| 42       top_controls_height_(0.f), |  | 
| 43       current_scroll_delta_(0.f), | 42       current_scroll_delta_(0.f), | 
| 44       controls_scroll_begin_offset_(0.f), | 43       controls_scroll_begin_offset_(0.f), | 
| 45       top_controls_show_threshold_(top_controls_hide_threshold), | 44       top_controls_show_threshold_(top_controls_hide_threshold), | 
| 46       top_controls_hide_threshold_(top_controls_show_threshold), | 45       top_controls_hide_threshold_(top_controls_show_threshold), | 
| 47       pinch_gesture_active_(false) { | 46       pinch_gesture_active_(false) { | 
| 48   CHECK(client_); | 47   CHECK(client_); | 
| 49 } | 48 } | 
| 50 | 49 | 
| 51 TopControlsManager::~TopControlsManager() { | 50 TopControlsManager::~TopControlsManager() { | 
| 52 } | 51 } | 
| 53 | 52 | 
| 54 float TopControlsManager::ControlsTopOffset() { | 53 float TopControlsManager::ControlsTopOffset() const { | 
| 55   return client_->ControlsTopOffset(); | 54   return ContentTopOffset() - TopControlsHeight(); | 
| 56 } | 55 } | 
| 57 | 56 | 
| 58 float TopControlsManager::ContentTopOffset() { | 57 float TopControlsManager::ContentTopOffset() const { | 
| 59   return client_->ControlsTopOffset() + top_controls_height_; | 58   return TopControlsShownRatio() * TopControlsHeight(); | 
|  | 59 } | 
|  | 60 | 
|  | 61 float TopControlsManager::TopControlsShownRatio() const { | 
|  | 62   return client_->CurrentTopControlsShownRatio(); | 
|  | 63 } | 
|  | 64 | 
|  | 65 float TopControlsManager::TopControlsHeight() const { | 
|  | 66   return client_->TopControlsHeight(); | 
| 60 } | 67 } | 
| 61 | 68 | 
| 62 void TopControlsManager::UpdateTopControlsState(TopControlsState constraints, | 69 void TopControlsManager::UpdateTopControlsState(TopControlsState constraints, | 
| 63                                                 TopControlsState current, | 70                                                 TopControlsState current, | 
| 64                                                 bool animate) { | 71                                                 bool animate) { | 
| 65   DCHECK(!(constraints == SHOWN && current == HIDDEN)); | 72   DCHECK(!(constraints == SHOWN && current == HIDDEN)); | 
| 66   DCHECK(!(constraints == HIDDEN && current == SHOWN)); | 73   DCHECK(!(constraints == HIDDEN && current == SHOWN)); | 
| 67 | 74 | 
| 68   permitted_state_ = constraints; | 75   permitted_state_ = constraints; | 
| 69 | 76 | 
| 70   // Don't do anything if it doesn't matter which state the controls are in. | 77   // Don't do anything if it doesn't matter which state the controls are in. | 
| 71   if (constraints == BOTH && current == BOTH) | 78   if (constraints == BOTH && current == BOTH) | 
| 72     return; | 79     return; | 
| 73 | 80 | 
| 74   // Don't do anything if there is no change in offset. | 81   // Don't do anything if there is no change in offset. | 
| 75   float final_controls_position = 0.f; | 82   float final_shown_ratio = 1.f; | 
| 76   if (constraints == HIDDEN || current == HIDDEN) { | 83   if (constraints == HIDDEN || current == HIDDEN) | 
| 77     final_controls_position = -top_controls_height_; | 84     final_shown_ratio = 0.f; | 
|  | 85   if (final_shown_ratio == TopControlsShownRatio()) | 
|  | 86     return; | 
|  | 87 | 
|  | 88   if (animate) { | 
|  | 89     SetupAnimation(final_shown_ratio ? SHOWING_CONTROLS : HIDING_CONTROLS); | 
|  | 90   } else { | 
|  | 91     ResetAnimations(); | 
|  | 92     client_->SetCurrentTopControlsShownRatio(final_shown_ratio); | 
| 78   } | 93   } | 
| 79   if (final_controls_position == client_->ControlsTopOffset()) { |  | 
| 80     return; |  | 
| 81   } |  | 
| 82 |  | 
| 83   AnimationDirection animation_direction = SHOWING_CONTROLS; |  | 
| 84   if (constraints == HIDDEN || current == HIDDEN) |  | 
| 85     animation_direction = HIDING_CONTROLS; |  | 
| 86   ResetAnimations(); |  | 
| 87   if (animate) { |  | 
| 88     SetupAnimation(animation_direction); |  | 
| 89   } else { |  | 
| 90     client_->SetControlsTopOffset(final_controls_position); |  | 
| 91   } |  | 
| 92   client_->DidChangeTopControlsPosition(); |  | 
| 93 } | 94 } | 
| 94 | 95 | 
| 95 void TopControlsManager::ScrollBegin() { | 96 void TopControlsManager::ScrollBegin() { | 
| 96   DCHECK(!pinch_gesture_active_); | 97   DCHECK(!pinch_gesture_active_); | 
| 97   ResetAnimations(); | 98   ResetAnimations(); | 
| 98   current_scroll_delta_ = 0.f; | 99   current_scroll_delta_ = 0.f; | 
| 99   controls_scroll_begin_offset_ = client_->ControlsTopOffset(); | 100   controls_scroll_begin_offset_ = ContentTopOffset(); | 
| 100 } | 101 } | 
| 101 | 102 | 
| 102 gfx::Vector2dF TopControlsManager::ScrollBy( | 103 gfx::Vector2dF TopControlsManager::ScrollBy( | 
| 103     const gfx::Vector2dF& pending_delta) { | 104     const gfx::Vector2dF& pending_delta) { | 
| 104   if (pinch_gesture_active_) | 105   if (pinch_gesture_active_) | 
| 105     return pending_delta; | 106     return pending_delta; | 
| 106 | 107 | 
| 107   if (permitted_state_ == SHOWN && pending_delta.y() > 0) | 108   if (permitted_state_ == SHOWN && pending_delta.y() > 0) | 
| 108     return pending_delta; | 109     return pending_delta; | 
| 109   else if (permitted_state_ == HIDDEN && pending_delta.y() < 0) | 110   else if (permitted_state_ == HIDDEN && pending_delta.y() < 0) | 
| 110     return pending_delta; | 111     return pending_delta; | 
| 111 | 112 | 
| 112   current_scroll_delta_ += pending_delta.y(); | 113   current_scroll_delta_ += pending_delta.y(); | 
| 113 | 114 | 
| 114   float old_offset = client_->ControlsTopOffset(); | 115   float old_offset = ContentTopOffset(); | 
| 115   SetControlsTopOffset(controls_scroll_begin_offset_ - current_scroll_delta_); | 116   client_->SetCurrentTopControlsShownRatio( | 
|  | 117       (controls_scroll_begin_offset_ - current_scroll_delta_) / | 
|  | 118       TopControlsHeight()); | 
| 116 | 119 | 
| 117   // If the controls are fully visible, treat the current position as the | 120   // If the controls are fully visible, treat the current position as the | 
| 118   // new baseline even if the gesture didn't end. | 121   // new baseline even if the gesture didn't end. | 
| 119   if (client_->ControlsTopOffset() == 0.f) { | 122   if (TopControlsShownRatio() == 1.f) { | 
| 120     current_scroll_delta_ = 0.f; | 123     current_scroll_delta_ = 0.f; | 
| 121     controls_scroll_begin_offset_ = 0.f; | 124     controls_scroll_begin_offset_ = ContentTopOffset(); | 
| 122   } | 125   } | 
| 123 | 126 | 
| 124   ResetAnimations(); | 127   ResetAnimations(); | 
| 125 | 128 | 
| 126   gfx::Vector2dF applied_delta(0.f, old_offset - client_->ControlsTopOffset()); | 129   gfx::Vector2dF applied_delta(0.f, old_offset - ContentTopOffset()); | 
| 127   return pending_delta - applied_delta; | 130   return pending_delta - applied_delta; | 
| 128 } | 131 } | 
| 129 | 132 | 
| 130 void TopControlsManager::ScrollEnd() { | 133 void TopControlsManager::ScrollEnd() { | 
| 131   DCHECK(!pinch_gesture_active_); | 134   DCHECK(!pinch_gesture_active_); | 
| 132   StartAnimationIfNecessary(); | 135   StartAnimationIfNecessary(); | 
| 133 } | 136 } | 
| 134 | 137 | 
| 135 void TopControlsManager::PinchBegin() { | 138 void TopControlsManager::PinchBegin() { | 
| 136   DCHECK(!pinch_gesture_active_); | 139   DCHECK(!pinch_gesture_active_); | 
| 137   pinch_gesture_active_ = true; | 140   pinch_gesture_active_ = true; | 
| 138   StartAnimationIfNecessary(); | 141   StartAnimationIfNecessary(); | 
| 139 } | 142 } | 
| 140 | 143 | 
| 141 void TopControlsManager::PinchEnd() { | 144 void TopControlsManager::PinchEnd() { | 
| 142   DCHECK(pinch_gesture_active_); | 145   DCHECK(pinch_gesture_active_); | 
| 143   // Pinch{Begin,End} will always occur within the scope of Scroll{Begin,End}, | 146   // Pinch{Begin,End} will always occur within the scope of Scroll{Begin,End}, | 
| 144   // so return to a state expected by the remaining scroll sequence. | 147   // so return to a state expected by the remaining scroll sequence. | 
| 145   pinch_gesture_active_ = false; | 148   pinch_gesture_active_ = false; | 
| 146   ScrollBegin(); | 149   ScrollBegin(); | 
| 147 } | 150 } | 
| 148 | 151 | 
| 149 void TopControlsManager::SetControlsTopOffset(float controls_top_offset) { |  | 
| 150   controls_top_offset = std::max(controls_top_offset, -top_controls_height_); |  | 
| 151   controls_top_offset = std::min(controls_top_offset, 0.f); |  | 
| 152 |  | 
| 153   if (client_->ControlsTopOffset() == controls_top_offset) |  | 
| 154     return; |  | 
| 155 |  | 
| 156   client_->SetControlsTopOffset(controls_top_offset); |  | 
| 157 |  | 
| 158   client_->DidChangeTopControlsPosition(); |  | 
| 159 } |  | 
| 160 |  | 
| 161 void TopControlsManager::SetTopControlsHeight(float top_controls_height) { |  | 
| 162   DCHECK_GE(top_controls_height, 0); |  | 
| 163 |  | 
| 164   if (top_controls_height == top_controls_height_) |  | 
| 165     return; |  | 
| 166 |  | 
| 167   ResetAnimations(); |  | 
| 168   float top_controls_offset = client_->ControlsTopOffset(); |  | 
| 169   top_controls_height_ = top_controls_height; |  | 
| 170   SetControlsTopOffset(top_controls_offset); |  | 
| 171   StartAnimationIfNecessary(); |  | 
| 172 } |  | 
| 173 |  | 
| 174 gfx::Vector2dF TopControlsManager::Animate(base::TimeTicks monotonic_time) { | 152 gfx::Vector2dF TopControlsManager::Animate(base::TimeTicks monotonic_time) { | 
| 175   if (!top_controls_animation_ || !client_->HaveRootScrollLayer()) | 153   if (!top_controls_animation_ || !client_->HaveRootScrollLayer()) | 
| 176     return gfx::Vector2dF(); | 154     return gfx::Vector2dF(); | 
| 177 | 155 | 
| 178   base::TimeDelta time = monotonic_time - base::TimeTicks(); | 156   base::TimeDelta time = monotonic_time - base::TimeTicks(); | 
| 179 | 157 | 
| 180   float old_offset = client_->ControlsTopOffset(); | 158   float old_offset = ContentTopOffset(); | 
| 181   SetControlsTopOffset(top_controls_animation_->GetValue(time)); | 159   client_->SetCurrentTopControlsShownRatio( | 
|  | 160       top_controls_animation_->GetValue(time)); | 
| 182 | 161 | 
| 183   if (IsAnimationCompleteAtTime(monotonic_time)) | 162   if (IsAnimationCompleteAtTime(monotonic_time)) | 
| 184     ResetAnimations(); | 163     ResetAnimations(); | 
| 185 | 164 | 
| 186   gfx::Vector2dF scroll_delta(0.f, client_->ControlsTopOffset() - old_offset); | 165   gfx::Vector2dF scroll_delta(0.f, ContentTopOffset() - old_offset); | 
| 187   return scroll_delta; | 166   return scroll_delta; | 
| 188 } | 167 } | 
| 189 | 168 | 
| 190 void TopControlsManager::ResetAnimations() { | 169 void TopControlsManager::ResetAnimations() { | 
| 191   top_controls_animation_ = nullptr; | 170   top_controls_animation_ = nullptr; | 
| 192   animation_direction_ = NO_ANIMATION; | 171   animation_direction_ = NO_ANIMATION; | 
| 193 } | 172 } | 
| 194 | 173 | 
| 195 void TopControlsManager::SetupAnimation(AnimationDirection direction) { | 174 void TopControlsManager::SetupAnimation(AnimationDirection direction) { | 
| 196   DCHECK(direction != NO_ANIMATION); | 175   DCHECK_NE(NO_ANIMATION, direction); | 
| 197 | 176   DCHECK_IMPLIES(direction == HIDING_CONTROLS, TopControlsShownRatio() > 0.f); | 
| 198   if (direction == SHOWING_CONTROLS && client_->ControlsTopOffset() == 0) | 177   DCHECK_IMPLIES(direction == SHOWING_CONTROLS, TopControlsShownRatio() < 1.f); | 
| 199     return; |  | 
| 200 |  | 
| 201   if (direction == HIDING_CONTROLS && |  | 
| 202       client_->ControlsTopOffset() == -top_controls_height_) { |  | 
| 203     return; |  | 
| 204   } |  | 
| 205 | 178 | 
| 206   if (top_controls_animation_ && animation_direction_ == direction) | 179   if (top_controls_animation_ && animation_direction_ == direction) | 
| 207     return; | 180     return; | 
| 208 | 181 | 
| 209   top_controls_animation_ = KeyframedFloatAnimationCurve::Create(); | 182   top_controls_animation_ = KeyframedFloatAnimationCurve::Create(); | 
| 210   base::TimeDelta start_time = gfx::FrameTime::Now() - base::TimeTicks(); | 183   base::TimeDelta start_time = gfx::FrameTime::Now() - base::TimeTicks(); | 
| 211   top_controls_animation_->AddKeyframe( | 184   top_controls_animation_->AddKeyframe( | 
| 212       FloatKeyframe::Create(start_time, client_->ControlsTopOffset(), nullptr)); | 185       FloatKeyframe::Create(start_time, TopControlsShownRatio(), nullptr)); | 
| 213   float max_ending_offset = | 186   float max_ending_ratio = (direction == SHOWING_CONTROLS ? 1 : -1); | 
| 214       (direction == SHOWING_CONTROLS ? 1 : -1) * top_controls_height_; |  | 
| 215   top_controls_animation_->AddKeyframe(FloatKeyframe::Create( | 187   top_controls_animation_->AddKeyframe(FloatKeyframe::Create( | 
| 216       start_time + base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs), | 188       start_time + base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs), | 
| 217       client_->ControlsTopOffset() + max_ending_offset, | 189       TopControlsShownRatio() + max_ending_ratio, | 
| 218       EaseTimingFunction::Create())); | 190       EaseTimingFunction::Create())); | 
| 219   animation_direction_ = direction; | 191   animation_direction_ = direction; | 
| 220   client_->DidChangeTopControlsPosition(); | 192   client_->DidChangeTopControlsPosition(); | 
| 221 } | 193 } | 
| 222 | 194 | 
| 223 void TopControlsManager::StartAnimationIfNecessary() { | 195 void TopControlsManager::StartAnimationIfNecessary() { | 
| 224   if (client_->ControlsTopOffset() != 0 | 196   if (TopControlsShownRatio() == 0.f || TopControlsShownRatio() == 1.f) | 
| 225       && client_->ControlsTopOffset() != -top_controls_height_) { | 197     return; | 
| 226     AnimationDirection show_controls = NO_ANIMATION; |  | 
| 227 | 198 | 
| 228     float top_controls_show_height = | 199   if (TopControlsShownRatio() >= 1.f - top_controls_hide_threshold_) { | 
| 229         top_controls_height_ * top_controls_hide_threshold_; | 200     // If we're showing so much that the hide threshold won't trigger, show. | 
| 230     float top_controls_hide_height = | 201     SetupAnimation(SHOWING_CONTROLS); | 
| 231         top_controls_height_ * (1.f - top_controls_show_threshold_); | 202   } else if (TopControlsShownRatio() <= top_controls_show_threshold_) { | 
| 232     if (client_->ControlsTopOffset() >= -top_controls_show_height) { | 203     // If we're showing so little that the show threshold won't trigger, hide. | 
| 233       // If we're showing so much that the hide threshold won't trigger, show. | 204     SetupAnimation(HIDING_CONTROLS); | 
| 234       show_controls = SHOWING_CONTROLS; | 205   } else { | 
| 235     } else if (client_->ControlsTopOffset() <= -top_controls_hide_height) { | 206     // If we could be either showing or hiding, we determine which one to | 
| 236       // If we're showing so little that the show threshold won't trigger, hide. | 207     // do based on whether or not the total scroll delta was moving up or | 
| 237       show_controls = HIDING_CONTROLS; | 208     // down. | 
| 238     } else { | 209     SetupAnimation(current_scroll_delta_ <= 0.f ? SHOWING_CONTROLS | 
| 239       // If we could be either showing or hiding, we determine which one to | 210                                                 : HIDING_CONTROLS); | 
| 240       // do based on whether or not the total scroll delta was moving up or |  | 
| 241       // down. |  | 
| 242       show_controls = current_scroll_delta_ <= 0.f ? |  | 
| 243           SHOWING_CONTROLS : HIDING_CONTROLS; |  | 
| 244     } |  | 
| 245 |  | 
| 246     if (show_controls != NO_ANIMATION) |  | 
| 247       SetupAnimation(show_controls); |  | 
| 248   } | 211   } | 
| 249 } | 212 } | 
| 250 | 213 | 
| 251 bool TopControlsManager::IsAnimationCompleteAtTime(base::TimeTicks time) { | 214 bool TopControlsManager::IsAnimationCompleteAtTime(base::TimeTicks time) { | 
| 252   if (!top_controls_animation_) | 215   if (!top_controls_animation_) | 
| 253     return true; | 216     return true; | 
| 254 | 217 | 
| 255   base::TimeDelta animation_time = time - base::TimeTicks(); | 218   base::TimeDelta animation_time = time - base::TimeTicks(); | 
| 256   float new_offset = top_controls_animation_->GetValue(animation_time); | 219   float new_ratio = top_controls_animation_->GetValue(animation_time); | 
| 257 | 220 | 
| 258   if ((animation_direction_ == SHOWING_CONTROLS && new_offset >= 0) || | 221   if ((animation_direction_ == SHOWING_CONTROLS && new_ratio >= 1.f) || | 
| 259       (animation_direction_ == HIDING_CONTROLS | 222       (animation_direction_ == HIDING_CONTROLS && new_ratio <= 0.f)) { | 
| 260           && new_offset <= -top_controls_height_)) { |  | 
| 261     return true; | 223     return true; | 
| 262   } | 224   } | 
| 263   return false; | 225   return false; | 
| 264 } | 226 } | 
| 265 | 227 | 
| 266 }  // namespace cc | 228 }  // namespace cc | 
| OLD | NEW | 
|---|