| 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..fcb8f964e6107fa225809ba8f773ad8a90ee0b2e 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,122 @@
|
|
|
| #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();
|
| +
|
| + 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 = 1.0f - static_cast<float>(std::abs(current_delta_y_)) /
|
| + static_cast<float>(bounds.height());
|
| +
|
| + 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);
|
| }
|
|
|