Chromium Code Reviews| Index: chrome/browser/ui/views/frame/scroll_end_effect_controller_ash.cc |
| diff --git a/chrome/browser/ui/views/frame/scroll_end_effect_controller_ash.cc b/chrome/browser/ui/views/frame/scroll_end_effect_controller_ash.cc |
| index aa0642821e61bc5cfe4d5932bf978aca44f60377..4f6349d6bc2969037df561b5e99a7f87951a3025 100644 |
| --- a/chrome/browser/ui/views/frame/scroll_end_effect_controller_ash.cc |
| +++ b/chrome/browser/ui/views/frame/scroll_end_effect_controller_ash.cc |
| @@ -4,16 +4,124 @@ |
| #include "chrome/browser/ui/views/frame/scroll_end_effect_controller_ash.h" |
| -ScrollEndEffectController* ScrollEndEffectController::Create() { |
| - return new ScrollEndEffectControllerAsh(); |
| +#include "chrome/browser/ui/views/download/download_shelf_view.h" |
| +#include "chrome/browser/ui/views/frame/browser_frame.h" |
| +#include "chrome/browser/ui/views/frame/browser_view.h" |
| +#include "chrome/browser/ui/views/frame/contents_container.h" |
| +#include "content/public/browser/web_contents.h" |
| +#include "content/public/browser/web_contents_view.h" |
| +#include "ui/aura/window.h" |
| +#include "ui/compositor/layer_type.h" |
| +#include "ui/gfx/animation/tween.h" |
| +#include "ui/gfx/rect_conversions.h" |
| +#include "ui/gfx/safe_integer_conversions.h" |
| +#include "ui/views/controls/single_split_view.h" |
| +#include "ui/views/controls/webview/webview.h" |
| + |
| +namespace { |
| +// This factor is used to control how much translation is applied relative to |
| +// the size of the window. Specifically translation is limited to a max of |
| +// window_size * factor. |
| +const float kScrollEndEffectFactor = 0.05f; |
| +} // namespace |
| + |
| +ScrollEndEffectController* ScrollEndEffectController::Create( |
| + ScrollEndEffectControllerDelegate* delegate) { |
| + return new ScrollEndEffectControllerAsh(delegate); |
| } |
| -ScrollEndEffectControllerAsh::ScrollEndEffectControllerAsh() { |
| +ScrollEndEffectControllerAsh::ScrollEndEffectControllerAsh( |
| + ScrollEndEffectControllerDelegate* delegate) |
| + : delegate_(delegate), |
| + is_effect_active_(false), |
| + start_delta_y_(0), |
| + current_delta_y_(0), |
| + end_delta_y_(0) { |
| + animation_.reset(new gfx::SlideAnimation(this)); |
| + animation_->SetSlideDuration(100); |
| + animation_->SetTweenType(gfx::Tween::EASE_OUT); |
| } |
| ScrollEndEffectControllerAsh::~ScrollEndEffectControllerAsh() { |
| } |
| void ScrollEndEffectControllerAsh::OverscrollUpdate(int delta_y) { |
| - // TODO(rharrison): Implement initial version of scroll end effect |
| + if (!is_effect_active_ && delta_y == 0) |
| + return; |
| + |
| + if (!is_effect_active_) { |
| + ActivateEffect(); |
|
sadrul
2013/10/25 18:28:25
no {}
rharrison
2013/11/18 21:52:26
Done.
|
| + } |
| + |
| + int capped_delta_y = delta_y; |
| + // Limiting the delta size being a proportion of the frame bounds size. |
| + if (capped_delta_y > 0) { |
| + capped_delta_y = std::min(gfx::ToRoundedInt((frame_bounds_.height() * |
| + kScrollEndEffectFactor)), |
| + capped_delta_y); |
| + } else if (capped_delta_y < 0) { |
| + capped_delta_y = -std::min(gfx::ToRoundedInt((frame_bounds_.height() * |
| + kScrollEndEffectFactor)), |
| + -capped_delta_y); |
| + } |
| + |
| + start_delta_y_ = current_delta_y_; |
| + end_delta_y_ = capped_delta_y; |
| + if (end_delta_y_ == 0) { |
| + animation_->Reset(); |
| + animation_->Show(); |
| + if (animation_->GetSlideDuration() == 0) { |
| + AnimationProgressed(animation_.get()); |
| + AnimationEnded(animation_.get()); |
| + } |
| + } else { |
| + animation_->Reset(); |
| + ApplyDelta(end_delta_y_); |
| + } |
| +} |
| + |
| +void ScrollEndEffectControllerAsh::AnimationEnded( |
| + const gfx::Animation* animation) { |
| + if (current_delta_y_ == 0) |
| + DeactivateEffect(); |
| +} |
| + |
| +void ScrollEndEffectControllerAsh::AnimationProgressed( |
| + const gfx::Animation* animation) { |
| + ApplyDelta(gfx::Tween::IntValueBetween(animation_->GetCurrentValue(), |
| + start_delta_y_, |
| + end_delta_y_)); |
| +} |
| + |
| +void ScrollEndEffectControllerAsh::ActivateEffect() { |
| + is_effect_active_ = true; |
| + frame_bounds_ = delegate_->GetFrameBounds(); |
| + delegate_->GetContentsContainer()->ActivateScrollEndEffect(); |
| +} |
| + |
| +void ScrollEndEffectControllerAsh::DeactivateEffect() { |
| + is_effect_active_ = false; |
| + delegate_->SetFrameBounds(frame_bounds_); |
| + delegate_->GetContentsContainer()->DeactivateScrollEndEffect(); |
| +} |
| + |
| +void ScrollEndEffectControllerAsh::ApplyDelta(int delta_y) { |
| + current_delta_y_ = delta_y; |
| + gfx::Rect bounds = frame_bounds_; |
| + |
| + float scale_factor = std::abs(current_delta_y_); |
| + scale_factor /= bounds.height(); |
| + scale_factor = 1 - scale_factor; |
|
sadrul
2013/10/25 18:28:25
float scale_factor = 1 - std::abs(current_delta_y_
rharrison
2013/11/18 21:52:26
Done.
|
| + |
| + bounds.set_height(gfx::ToRoundedInt(bounds.height() * scale_factor)); |
| + bool scrolling_down = current_delta_y_ > 0; |
| + if (scrolling_down) { |
| + gfx::Point bounds_orig = bounds.origin(); |
| + bounds_orig.set_y(bounds_orig.y() + current_delta_y_); |
| + bounds.set_origin(bounds_orig); |
| + } |
| + delegate_->SetFrameBounds(bounds); |
| + delegate_->GetContentsContainer()-> |
| + UpdateScrollEndEffectHeightDelta(frame_bounds_.height() - bounds.height(), |
| + scrolling_down); |
| } |