158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "cc/animation/scrollbar_animation_controller_thinning.h"
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/time/time.h"
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "cc/layers/layer_impl.h"
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "cc/layers/scrollbar_layer_impl_base.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace {
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const float kIdleThicknessScale = 0.4f;
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const float kIdleOpacity = 0.7f;
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f;
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace cc {
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)scoped_ptr<ScrollbarAnimationControllerThinning>
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ScrollbarAnimationControllerThinning::Create(
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    LayerImpl* scroll_layer,
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ScrollbarAnimationControllerClient* client,
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::TimeDelta delay_before_starting,
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::TimeDelta duration) {
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return make_scoped_ptr(new ScrollbarAnimationControllerThinning(
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      scroll_layer, client, delay_before_starting, duration));
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning(
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LayerImpl* scroll_layer,
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ScrollbarAnimationControllerClient* client,
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::TimeDelta delay_before_starting,
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    base::TimeDelta duration)
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    : ScrollbarAnimationController(client, delay_before_starting, duration),
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      scroll_layer_(scroll_layer),
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      mouse_is_over_scrollbar_(false),
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      mouse_is_near_scrollbar_(false),
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      thickness_change_(NONE),
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      opacity_change_(NONE),
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      mouse_move_distance_to_trigger_animation_(
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          kDefaultMouseMoveDistanceToTriggerAnimation) {
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ApplyOpacityAndThumbThicknessScale(kIdleOpacity, kIdleThicknessScale);
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)ScrollbarAnimationControllerThinning::~ScrollbarAnimationControllerThinning() {
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ScrollbarAnimationControllerThinning::RunAnimationFrame(float progress) {
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  float opacity = OpacityAtAnimationProgress(progress);
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  float thumb_thickness_scale = ThumbThicknessScaleAtAnimationProgress(
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      progress);
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ApplyOpacityAndThumbThicknessScale(opacity, thumb_thickness_scale);
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (progress == 1.f) {
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    opacity_change_ = NONE;
551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    thickness_change_ = NONE;
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    StopAnimation();
571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ScrollbarAnimationControllerThinning::DidMouseMoveOffScrollbar() {
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  mouse_is_over_scrollbar_ = false;
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  mouse_is_near_scrollbar_ = false;
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  opacity_change_ = DECREASE;
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  thickness_change_ = DECREASE;
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  StartAnimation();
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ScrollbarAnimationControllerThinning::DidScrollUpdate() {
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ScrollbarAnimationController::DidScrollUpdate();
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ApplyOpacityAndThumbThicknessScale(
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    1, mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale);
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!mouse_is_over_scrollbar_)
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    opacity_change_ = DECREASE;
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void ScrollbarAnimationControllerThinning::DidMouseMoveNear(float distance) {
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool mouse_is_over_scrollbar = distance == 0.0;
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool mouse_is_near_scrollbar =
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      distance < mouse_move_distance_to_trigger_animation_;
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (mouse_is_over_scrollbar == mouse_is_over_scrollbar_ &&
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      mouse_is_near_scrollbar == mouse_is_near_scrollbar_)
84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (mouse_is_over_scrollbar_ != mouse_is_over_scrollbar) {
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    mouse_is_over_scrollbar_ = mouse_is_over_scrollbar;
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    opacity_change_ = mouse_is_over_scrollbar_ ? INCREASE : DECREASE;
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (mouse_is_near_scrollbar_ != mouse_is_near_scrollbar) {
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    mouse_is_near_scrollbar_ = mouse_is_near_scrollbar;
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    thickness_change_ = mouse_is_near_scrollbar_ ? INCREASE : DECREASE;
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  StartAnimation();
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)float ScrollbarAnimationControllerThinning::OpacityAtAnimationProgress(
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    float progress) {
1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (opacity_change_ == NONE)
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return mouse_is_over_scrollbar_ ? 1.f : kIdleOpacity;
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  float factor = opacity_change_ == INCREASE ? progress : (1.f - progress);
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  float ret = ((1.f - kIdleOpacity) * factor) + kIdleOpacity;
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return ret;
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)float
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)ScrollbarAnimationControllerThinning::ThumbThicknessScaleAtAnimationProgress(
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    float progress) {
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (thickness_change_ == NONE)
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale;
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  float factor = thickness_change_ == INCREASE ? progress : (1.f - progress);
1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return ((1.f - kIdleThicknessScale) * factor) + kIdleThicknessScale;
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)float ScrollbarAnimationControllerThinning::AdjustScale(
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    float new_value,
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    float current_value,
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    AnimationChange animation_change) {
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (animation_change == INCREASE && current_value > new_value)
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return current_value;
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (animation_change == DECREASE && current_value < new_value)
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return current_value;
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return new_value;
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ScrollbarAnimationControllerThinning::ApplyOpacityAndThumbThicknessScale(
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    float opacity, float thumb_thickness_scale) {
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!scroll_layer_->scrollbars())
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LayerImpl::ScrollbarSet* scrollbars = scroll_layer_->scrollbars();
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (LayerImpl::ScrollbarSet::iterator it = scrollbars->begin();
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       it != scrollbars->end();
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++it) {
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ScrollbarLayerImplBase* scrollbar = *it;
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (scrollbar->is_overlay_scrollbar()) {
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scrollbar->SetOpacity(
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          AdjustScale(opacity, scrollbar->opacity(), opacity_change_));
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scrollbar->SetThumbThicknessScaleFactor(
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          AdjustScale(thumb_thickness_scale,
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      scrollbar->thumb_thickness_scale_factor(),
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      thickness_change_));
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace cc
150