| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/ui/search/toolbar_search_animator.h" | 5 #include "chrome/browser/ui/search/toolbar_search_animator.h" |
| 6 | 6 |
| 7 #include "chrome/browser/ui/search/search_model.h" | 7 #include "chrome/browser/ui/search/search_model.h" |
| 8 #include "chrome/browser/ui/search/search_types.h" | 8 #include "chrome/browser/ui/search/search_types.h" |
| 9 #include "chrome/browser/ui/search/toolbar_search_animator_observer.h" | 9 #include "chrome/browser/ui/search/toolbar_search_animator_observer.h" |
| 10 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 10 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| 11 #include "chrome/browser/ui/webui/instant_ui.h" | 11 #include "chrome/browser/ui/webui/instant_ui.h" |
| 12 #include "ui/base/animation/slide_animation.h" | 12 #include "ui/base/animation/multi_animation.h" |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 | 15 |
| 16 const int kBackgroundChangeDelayMs = 100; | 16 const int kBackgroundChangeDelayMs = 100; |
| 17 const int kBackgroundChangeDurationMs = 200; | 17 const int kBackgroundChangeDurationMs = 200; |
| 18 | 18 |
| 19 const double kMinOpacity = 0.0f; | 19 const double kMinOpacity = 0.0f; |
| 20 const double kMaxOpacity = 1.0f; | 20 const double kMaxOpacity = 1.0f; |
| 21 | 21 |
| 22 } // namespace | 22 } // namespace |
| 23 | 23 |
| 24 namespace chrome { | 24 namespace chrome { |
| 25 namespace search { | 25 namespace search { |
| 26 | 26 |
| 27 ToolbarSearchAnimator::ToolbarSearchAnimator(SearchModel* search_model) | 27 ToolbarSearchAnimator::ToolbarSearchAnimator(SearchModel* search_model) |
| 28 : search_model_(search_model), | 28 : search_model_(search_model) { |
| 29 animate_state_(ANIMATE_STATE_NONE) { | |
| 30 search_model_->AddObserver(this); | 29 search_model_->AddObserver(this); |
| 30 |
| 31 InitBackgroundAnimation(kBackgroundChangeDelayMs, |
| 32 kBackgroundChangeDurationMs); |
| 31 } | 33 } |
| 32 | 34 |
| 33 ToolbarSearchAnimator::~ToolbarSearchAnimator() { | 35 ToolbarSearchAnimator::~ToolbarSearchAnimator() { |
| 36 background_animation_->Stop(); |
| 34 search_model_->RemoveObserver(this); | 37 search_model_->RemoveObserver(this); |
| 35 } | 38 } |
| 36 | 39 |
| 37 void ToolbarSearchAnimator::GetCurrentBackgroundState( | 40 double ToolbarSearchAnimator::GetGradientOpacity() const { |
| 38 BackgroundState* background_state, | 41 if (background_animation_->is_animating()) |
| 39 double* search_background_opacity) const { | 42 return background_animation_->CurrentValueBetween(kMinOpacity, kMaxOpacity); |
| 40 // Should only be called for SEARCH mode. | 43 return search_model_->mode().is_ntp() ? kMinOpacity : kMaxOpacity; |
| 41 DCHECK(search_model_->mode().is_search()); | |
| 42 *background_state = BACKGROUND_STATE_DEFAULT; | |
| 43 *search_background_opacity = -1.0f; | |
| 44 switch (animate_state_) { | |
| 45 case ANIMATE_STATE_WAITING: | |
| 46 *background_state = BACKGROUND_STATE_NTP; | |
| 47 break; | |
| 48 case ANIMATE_STATE_RUNNING: | |
| 49 *background_state = BACKGROUND_STATE_NTP_SEARCH; | |
| 50 *search_background_opacity = background_animation_->CurrentValueBetween( | |
| 51 kMinOpacity, kMaxOpacity); | |
| 52 break; | |
| 53 case ANIMATE_STATE_NONE: | |
| 54 break; | |
| 55 } | |
| 56 } | 44 } |
| 57 | 45 |
| 58 void ToolbarSearchAnimator::FinishAnimation(TabContents* tab_contents) { | 46 void ToolbarSearchAnimator::FinishAnimation(TabContents* tab_contents) { |
| 59 Reset(tab_contents); | 47 Reset(tab_contents); |
| 60 } | 48 } |
| 61 | 49 |
| 62 void ToolbarSearchAnimator::AddObserver( | 50 void ToolbarSearchAnimator::AddObserver( |
| 63 ToolbarSearchAnimatorObserver* observer) { | 51 ToolbarSearchAnimatorObserver* observer) { |
| 64 observers_.AddObserver(observer); | 52 observers_.AddObserver(observer); |
| 65 } | 53 } |
| 66 | 54 |
| 67 void ToolbarSearchAnimator::RemoveObserver( | 55 void ToolbarSearchAnimator::RemoveObserver( |
| 68 ToolbarSearchAnimatorObserver* observer) { | 56 ToolbarSearchAnimatorObserver* observer) { |
| 69 observers_.RemoveObserver(observer); | 57 observers_.RemoveObserver(observer); |
| 70 } | 58 } |
| 71 | 59 |
| 72 void ToolbarSearchAnimator::ModeChanged(const Mode& mode) { | 60 void ToolbarSearchAnimator::ModeChanged(const Mode& old_mode, |
| 73 int delay_ms = kBackgroundChangeDelayMs * | 61 const Mode& new_mode) { |
| 74 InstantUI::GetSlowAnimationScaleFactor(); | 62 // If the mode transitions from |NTP| to |SEARCH| and we're not animating |
| 75 if (mode.is_search() && mode.animate && | 63 // background, start fading in gradient background. |
| 76 animate_state_ == ANIMATE_STATE_NONE) { | 64 // TODO(kuan): check with UX folks if we need to animate from gradient to flat |
| 77 background_change_timer_.Start( | 65 // when mode transitions from |SEARCH| or |DEFAULT| to |NTP|. |
| 78 FROM_HERE, | 66 if (new_mode.animate && old_mode.is_ntp() && new_mode.is_search() && |
| 79 base::TimeDelta::FromMilliseconds(delay_ms), | 67 !background_animation_->is_animating()) { |
| 80 this, | 68 StartBackgroundChange(); |
| 81 &ToolbarSearchAnimator::StartBackgroundChange); | |
| 82 animate_state_ = ANIMATE_STATE_WAITING; | |
| 83 return; | 69 return; |
| 84 } | 70 } |
| 85 // For all other cases, reset |animate_state_| and stop timer or animation. | 71 |
| 72 // If the mode transitions from |SEARCH| to |DEFAULT| and we're already |
| 73 // animating background, let animation continue. |
| 74 if (new_mode.animate && old_mode.is_search() && new_mode.is_default() && |
| 75 background_animation_->is_animating()) { |
| 76 return; |
| 77 } |
| 78 |
| 79 // For all other cases, reset animation. |
| 86 // Stopping animation will jump to the end of it. | 80 // Stopping animation will jump to the end of it. |
| 87 Reset(NULL); | 81 Reset(NULL); |
| 88 } | 82 } |
| 89 | 83 |
| 90 void ToolbarSearchAnimator::AnimationProgressed( | 84 void ToolbarSearchAnimator::AnimationProgressed( |
| 91 const ui::Animation* animation) { | 85 const ui::Animation* animation) { |
| 92 DCHECK_EQ(animation, background_animation_.get()); | 86 DCHECK_EQ(background_animation_.get(), animation); |
| 93 animate_state_ = ANIMATE_STATE_RUNNING; | |
| 94 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, | 87 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, |
| 95 OnToolbarBackgroundAnimatorProgressed()); | 88 OnToolbarBackgroundAnimatorProgressed()); |
| 96 } | 89 } |
| 97 | 90 |
| 98 void ToolbarSearchAnimator::AnimationEnded(const ui::Animation* animation) { | 91 void ToolbarSearchAnimator::AnimationEnded(const ui::Animation* animation) { |
| 99 DCHECK_EQ(animation, background_animation_.get()); | 92 // We only get this callback when |animation| has run its full course. |
| 100 // Only notify observers via OnToolbarBackgroundAnimatorProgressed if the | 93 // If animation was canceled (in Reset()), we won't get an AnimationEnded() |
| 101 // animation has runs its full course i.e |animate_state_| is still | 94 // callback because we had cleared the animation's delegate in Reset(). |
| 102 // ANIMATE_STATE_RUNNING. | 95 DCHECK_EQ(background_animation_.get(), animation); |
| 103 // Animation that is canceled, i.e. |animate_state_| has been set to | 96 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, |
| 104 // ANIMATE_STATE_NONE in Reset, should notify observers via | 97 OnToolbarBackgroundAnimatorProgressed()); |
| 105 // OnToolbarBackgroundAnimatorCanceled. | 98 } |
| 106 if (animate_state_ == ANIMATE_STATE_RUNNING) { | 99 |
| 107 animate_state_ = ANIMATE_STATE_NONE; | 100 void ToolbarSearchAnimator::InitBackgroundAnimation( |
| 108 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, | 101 int background_change_delay_ms, |
| 109 OnToolbarBackgroundAnimatorProgressed()); | 102 int background_change_duration_ms) { |
| 110 } | 103 ui::MultiAnimation::Parts parts; |
| 104 parts.push_back(ui::MultiAnimation::Part( |
| 105 background_change_delay_ms * InstantUI::GetSlowAnimationScaleFactor(), |
| 106 ui::Tween::ZERO)); |
| 107 parts.push_back(ui::MultiAnimation::Part( |
| 108 background_change_duration_ms * InstantUI::GetSlowAnimationScaleFactor(), |
| 109 ui::Tween::LINEAR)); |
| 110 background_animation_.reset(new ui::MultiAnimation(parts)); |
| 111 background_animation_->set_continuous(false); |
| 111 } | 112 } |
| 112 | 113 |
| 113 void ToolbarSearchAnimator::StartBackgroundChange() { | 114 void ToolbarSearchAnimator::StartBackgroundChange() { |
| 114 if (!background_animation_.get()) { | 115 background_animation_->set_delegate(this); |
| 115 background_animation_.reset(new ui::SlideAnimation(this)); | 116 background_animation_->Start(); |
| 116 background_animation_->SetTweenType(ui::Tween::LINEAR); | |
| 117 background_animation_->SetSlideDuration( | |
| 118 kBackgroundChangeDurationMs * InstantUI::GetSlowAnimationScaleFactor()); | |
| 119 } | |
| 120 background_animation_->Reset(0.0); | |
| 121 background_animation_->Show(); | |
| 122 } | 117 } |
| 123 | 118 |
| 124 void ToolbarSearchAnimator::Reset(TabContents* tab_contents) { | 119 void ToolbarSearchAnimator::Reset(TabContents* tab_contents) { |
| 125 bool notify_observers = animate_state_ != ANIMATE_STATE_NONE; | 120 bool notify_background_observers = background_animation_->is_animating(); |
| 126 animate_state_ = ANIMATE_STATE_NONE; | 121 |
| 127 background_change_timer_.Stop(); | 122 // Clear the animation's delegate so that we don't get AnimationEnded() |
| 128 // If animation is still running, stopping it will trigger AnimationEnded | 123 // callback. |
| 129 // where we've prevented from notifying observers via BackgroundChanged; | 124 background_animation_->set_delegate(NULL); |
| 130 // see comments in AnimationEnded. | 125 background_animation_->Stop(); |
| 131 if (background_animation_.get()) | 126 |
| 132 background_animation_->Stop(); | 127 // Notify observers of animation cancelation. |
| 133 if (notify_observers) { | 128 if (notify_background_observers) { |
| 134 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, | 129 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, |
| 135 OnToolbarBackgroundAnimatorCanceled(tab_contents)); | 130 OnToolbarBackgroundAnimatorCanceled(tab_contents)); |
| 136 } | 131 } |
| 137 } | 132 } |
| 138 | 133 |
| 139 } // namespace search | 134 } // namespace search |
| 140 } // namespace chrome | 135 } // namespace chrome |
| OLD | NEW |