Chromium Code Reviews| 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/slide_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 int kSeparatorFadeDurationMs = 100; | |
| 20 | |
| 19 const double kMinOpacity = 0.0f; | 21 const double kMinOpacity = 0.0f; |
| 20 const double kMaxOpacity = 1.0f; | 22 const double kMaxOpacity = 1.0f; |
| 21 | 23 |
| 22 } // namespace | 24 } // namespace |
| 23 | 25 |
| 24 namespace chrome { | 26 namespace chrome { |
| 25 namespace search { | 27 namespace search { |
| 26 | 28 |
| 27 ToolbarSearchAnimator::ToolbarSearchAnimator(SearchModel* search_model) | 29 ToolbarSearchAnimator::ToolbarSearchAnimator(SearchModel* search_model) |
| 28 : search_model_(search_model), | 30 : search_model_(search_model), |
| 29 animate_state_(ANIMATE_STATE_NONE) { | 31 background_animate_state_(ANIMATE_STATE_NONE), |
| 32 separator_animate_state_(ANIMATE_STATE_NONE), | |
| 33 ALLOW_THIS_IN_INITIALIZER_LIST(background_animation_(this)), | |
| 34 ALLOW_THIS_IN_INITIALIZER_LIST(separator_animation_(this)), | |
| 35 from_mode_(Mode::MODE_DEFAULT), | |
| 36 to_mode_(Mode::MODE_DEFAULT), | |
| 37 modes_initialized_(false) { | |
| 30 search_model_->AddObserver(this); | 38 search_model_->AddObserver(this); |
| 39 | |
| 40 background_animation_.SetTweenType(ui::Tween::LINEAR); | |
| 41 background_animation_.SetSlideDuration( | |
| 42 kBackgroundChangeDurationMs * InstantUI::GetSlowAnimationScaleFactor()); | |
| 43 | |
| 44 separator_animation_.SetTweenType(ui::Tween::LINEAR); | |
| 45 separator_animation_.SetSlideDuration( | |
| 46 kSeparatorFadeDurationMs * InstantUI::GetSlowAnimationScaleFactor()); | |
| 31 } | 47 } |
| 32 | 48 |
| 33 ToolbarSearchAnimator::~ToolbarSearchAnimator() { | 49 ToolbarSearchAnimator::~ToolbarSearchAnimator() { |
| 50 background_animation_.Stop(); | |
| 51 separator_animation_.Stop(); | |
| 34 search_model_->RemoveObserver(this); | 52 search_model_->RemoveObserver(this); |
| 35 } | 53 } |
| 36 | 54 |
| 37 void ToolbarSearchAnimator::GetCurrentBackgroundState( | 55 double ToolbarSearchAnimator::GetGradientOpacity() const { |
| 38 BackgroundState* background_state, | 56 switch (background_animate_state_) { |
| 39 double* search_background_opacity) const { | |
| 40 // Should only be called for SEARCH mode. | |
| 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: | 57 case ANIMATE_STATE_WAITING: |
| 46 *background_state = BACKGROUND_STATE_NTP; | 58 return kMinOpacity; |
| 47 break; | |
| 48 case ANIMATE_STATE_RUNNING: | 59 case ANIMATE_STATE_RUNNING: |
| 49 *background_state = BACKGROUND_STATE_NTP_SEARCH; | 60 return background_animation_.CurrentValueBetween(kMinOpacity, |
| 50 *search_background_opacity = background_animation_->CurrentValueBetween( | 61 kMaxOpacity); |
| 51 kMinOpacity, kMaxOpacity); | |
| 52 break; | |
| 53 case ANIMATE_STATE_NONE: | 62 case ANIMATE_STATE_NONE: |
| 54 break; | 63 default: |
|
dhollowa
2012/07/24 00:24:49
You can remove |default:|.
kuan
2012/07/30 23:21:02
doesn't build if removed: "control reaches end of
| |
| 64 return to_mode_ == Mode::MODE_NTP ? kMinOpacity : kMaxOpacity; | |
| 55 } | 65 } |
| 56 } | 66 } |
| 57 | 67 |
| 68 double ToolbarSearchAnimator::GetSeparatorOpacity() const { | |
| 69 switch (separator_animate_state_) { | |
| 70 case ANIMATE_STATE_RUNNING: | |
| 71 return separator_animation_.CurrentValueBetween(kMinOpacity, kMaxOpacity); | |
| 72 case ANIMATE_STATE_NONE: | |
| 73 // ANIMATE_STATE_WAITING is not applicable for separator fading, but specify | |
| 74 // here to be complete. | |
| 75 case ANIMATE_STATE_WAITING: | |
| 76 default: | |
|
dhollowa
2012/07/24 00:24:49
You can remove |default:|.
kuan
2012/07/30 23:21:02
ditto.
| |
| 77 return to_mode_ == Mode::MODE_DEFAULT ? kMaxOpacity : kMinOpacity; | |
| 78 } | |
| 79 } | |
| 80 | |
| 58 void ToolbarSearchAnimator::FinishAnimation(TabContents* tab_contents) { | 81 void ToolbarSearchAnimator::FinishAnimation(TabContents* tab_contents) { |
| 59 Reset(tab_contents); | 82 Reset(tab_contents); |
| 60 } | 83 } |
| 61 | 84 |
| 62 void ToolbarSearchAnimator::AddObserver( | 85 void ToolbarSearchAnimator::AddObserver( |
| 63 ToolbarSearchAnimatorObserver* observer) { | 86 ToolbarSearchAnimatorObserver* observer) { |
| 64 observers_.AddObserver(observer); | 87 observers_.AddObserver(observer); |
| 65 } | 88 } |
| 66 | 89 |
| 67 void ToolbarSearchAnimator::RemoveObserver( | 90 void ToolbarSearchAnimator::RemoveObserver( |
| 68 ToolbarSearchAnimatorObserver* observer) { | 91 ToolbarSearchAnimatorObserver* observer) { |
| 69 observers_.RemoveObserver(observer); | 92 observers_.RemoveObserver(observer); |
| 70 } | 93 } |
| 71 | 94 |
| 72 void ToolbarSearchAnimator::ModeChanged(const Mode& mode) { | 95 void ToolbarSearchAnimator::ModeChanged(const Mode& mode) { |
| 73 int delay_ms = kBackgroundChangeDelayMs * | 96 // Only check to animate if modes have been intiailized via the very first |
| 74 InstantUI::GetSlowAnimationScaleFactor(); | 97 // ModeChanged call; this prevents the undesirable effect of animating from |
| 75 if (mode.is_search() && mode.animate && | 98 // the default initialized mode of |DEFAULT| to NTP or SEARCH mode, e.g. to |
|
dhollowa
2012/07/24 00:24:49
nit: ...|NTP| or |SEARCH|... and various comments
kuan
2012/07/30 23:21:02
Done.
| |
| 76 animate_state_ == ANIMATE_STATE_NONE) { | 99 // fade out toolbar separator. |
| 100 if (!modes_initialized_) { | |
| 101 from_mode_ = mode.mode; | |
|
dhollowa
2012/07/24 00:24:49
nit: from_mode_ = to_mode_ = mode.mode;
kuan
2012/07/30 23:21:02
Done.
| |
| 102 to_mode_ = from_mode_; | |
| 103 modes_initialized_ = true; | |
| 104 return; | |
| 105 } | |
| 106 | |
| 107 Mode::Type old_to_mode = to_mode_; | |
| 108 to_mode_ = mode.mode; | |
| 109 | |
| 110 // If mode transitions from NTP to SEARCH and we're not animating background, | |
| 111 // start timer to fade in gradient background. | |
| 112 // TODO(kuan): check with UX if we need to animate from gradient to flat when | |
| 113 // mode transitions from SEARCH/DEFAULT to NTP. | |
| 114 if (mode.animate && from_mode_ == Mode::MODE_NTP && mode.is_search() && | |
|
dhollowa
2012/07/24 00:24:49
This would read more clearly if you used s/mode.is
kuan
2012/07/30 23:21:02
Done.
| |
| 115 background_animate_state_ == ANIMATE_STATE_NONE) { | |
| 77 background_change_timer_.Start( | 116 background_change_timer_.Start( |
| 78 FROM_HERE, | 117 FROM_HERE, |
| 79 base::TimeDelta::FromMilliseconds(delay_ms), | 118 base::TimeDelta::FromMilliseconds(kBackgroundChangeDelayMs * |
| 119 InstantUI::GetSlowAnimationScaleFactor()), | |
| 80 this, | 120 this, |
| 81 &ToolbarSearchAnimator::StartBackgroundChange); | 121 &ToolbarSearchAnimator::StartBackgroundChange); |
| 82 animate_state_ = ANIMATE_STATE_WAITING; | 122 background_animate_state_ = ANIMATE_STATE_WAITING; |
| 83 return; | 123 return; |
| 84 } | 124 } |
| 85 // For all other cases, reset |animate_state_| and stop timer or animation. | 125 |
| 126 // If mode transitions from non-DEFAULT to DEFAULT, fade in separator; | |
| 127 // if we're already fading out separator, reverse to fade it in. | |
| 128 // Note that if we're still fading in gradient background when this mode | |
| 129 // transition happens (e.g. when user quickly hits enter on the auto-completed | |
| 130 // query in omnibox, triggering mode to transition from SEARCH to DEFAULT), | |
| 131 // we should continue fading in the gradient background to its full course. | |
| 132 // TODO(kuan): however, for now, sometimes, the first auto-completed query in | |
| 133 // omnibox is pre-rendered and gets swapped in when chosen by user, causing | |
| 134 // OnTabDetached for original tab to be fired, and hence causing us to Reset, | |
| 135 // immediately jumping to end state of background animation. I'll look into | |
| 136 // this together with the above TODO for reverse background animation. | |
| 137 if (mode.animate && | |
| 138 ((from_mode_ != Mode::MODE_DEFAULT && mode.is_default()) || | |
|
dhollowa
2012/07/24 00:24:49
You're guaranteed that from_mode_ is not equal to
kuan
2012/07/30 23:21:02
Done.
| |
| 139 (separator_animate_state_ == ANIMATE_STATE_RUNNING && | |
| 140 separator_animation_.IsClosing()))) { | |
| 141 if (separator_animate_state_ == ANIMATE_STATE_RUNNING) { | |
| 142 from_mode_ = old_to_mode; | |
|
dhollowa
2012/07/24 00:24:49
This conditional setting of the |from_mode_| varia
kuan
2012/07/30 23:21:02
Done.
| |
| 143 } else { | |
| 144 separator_animation_.Reset(0.0); | |
| 145 separator_animate_state_ = ANIMATE_STATE_RUNNING; | |
| 146 } | |
| 147 separator_animation_.Show(); | |
| 148 return; | |
| 149 } | |
| 150 | |
| 151 // If mode transitions from DEFAULT to non-DEFAULT, fade out separator; | |
| 152 // if we're already fading in separator, reverse to fade it out. | |
| 153 // TODO(kuan): for now, if we're still fading in gradient background when this | |
| 154 // mode transition happens (e.g. when user quickly hits back button on a | |
| 155 // website that he/she just entered from a SEARCH mode, triggering mode to | |
| 156 // transition from DEFAULT to NTP), we'll continue fading in the gradient | |
| 157 // background to its full course, which is undesirable. I'll handle this | |
| 158 // together with the above TODO for reverse background animation. | |
| 159 if (mode.animate && | |
| 160 ((from_mode_ == Mode::MODE_DEFAULT && !mode.is_default()) || | |
| 161 (separator_animate_state_ == ANIMATE_STATE_RUNNING && | |
| 162 separator_animation_.IsShowing()))) { | |
| 163 if (separator_animate_state_ == ANIMATE_STATE_RUNNING) { | |
| 164 from_mode_ = old_to_mode; | |
| 165 } else { | |
| 166 separator_animation_.Reset(1.0); | |
| 167 separator_animate_state_ = ANIMATE_STATE_RUNNING; | |
| 168 } | |
| 169 separator_animation_.Hide(); | |
| 170 return; | |
| 171 } | |
| 172 | |
| 173 // For all other cases, reset animate states and stop timer or animation(s). | |
| 86 // Stopping animation will jump to the end of it. | 174 // Stopping animation will jump to the end of it. |
| 87 Reset(NULL); | 175 Reset(NULL); |
| 88 } | 176 } |
| 89 | 177 |
| 90 void ToolbarSearchAnimator::AnimationProgressed( | 178 void ToolbarSearchAnimator::AnimationProgressed( |
| 91 const ui::Animation* animation) { | 179 const ui::Animation* animation) { |
| 92 DCHECK_EQ(animation, background_animation_.get()); | 180 if (animation == &background_animation_) { |
| 93 animate_state_ = ANIMATE_STATE_RUNNING; | 181 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, |
| 94 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, | 182 OnToolbarBackgroundAnimatorProgressed()); |
| 95 OnToolbarBackgroundAnimatorProgressed()); | 183 return; |
| 184 } | |
| 185 | |
| 186 if (animation == &separator_animation_) { | |
| 187 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, | |
| 188 OnToolbarSeparatorAnimatorProgressed()); | |
| 189 } | |
| 96 } | 190 } |
| 97 | 191 |
| 98 void ToolbarSearchAnimator::AnimationEnded(const ui::Animation* animation) { | 192 void ToolbarSearchAnimator::AnimationEnded(const ui::Animation* animation) { |
| 99 DCHECK_EQ(animation, background_animation_.get()); | 193 from_mode_ = to_mode_; |
| 100 // Only notify observers via OnToolbarBackgroundAnimatorProgressed if the | 194 |
| 101 // animation has runs its full course i.e |animate_state_| is still | 195 // Only notify observers via OnToolbarBackgroundAnimatorProgressed or |
| 102 // ANIMATE_STATE_RUNNING. | 196 // OnToolbarSeparatorAnimatorProgressed if the animation has runs its full |
| 103 // Animation that is canceled, i.e. |animate_state_| has been set to | 197 // course i.e animate state is still ANIMATE_STATE_RUNNING. |
| 198 // Animation that is canceled, i.e. animate state has been set to | |
| 104 // ANIMATE_STATE_NONE in Reset, should notify observers via | 199 // ANIMATE_STATE_NONE in Reset, should notify observers via |
| 105 // OnToolbarBackgroundAnimatorCanceled. | 200 // OnToolbarBackgroundAnimatorCanceled or OnToolbarSeparatorAnimatorCanceled. |
| 106 if (animate_state_ == ANIMATE_STATE_RUNNING) { | 201 if (animation == &background_animation_) { |
| 107 animate_state_ = ANIMATE_STATE_NONE; | 202 if (background_animate_state_ == ANIMATE_STATE_RUNNING) { |
| 108 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, | 203 background_animate_state_ = ANIMATE_STATE_NONE; |
| 109 OnToolbarBackgroundAnimatorProgressed()); | 204 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, |
| 205 OnToolbarBackgroundAnimatorProgressed()); | |
| 206 } | |
| 207 return; | |
| 208 } | |
| 209 | |
| 210 if (animation == &separator_animation_) { | |
| 211 if (separator_animate_state_ == ANIMATE_STATE_RUNNING) { | |
| 212 separator_animate_state_ = ANIMATE_STATE_NONE; | |
| 213 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, | |
| 214 OnToolbarSeparatorAnimatorProgressed()); | |
| 215 } | |
| 110 } | 216 } |
| 111 } | 217 } |
| 112 | 218 |
| 113 void ToolbarSearchAnimator::StartBackgroundChange() { | 219 void ToolbarSearchAnimator::StartBackgroundChange() { |
| 114 if (!background_animation_.get()) { | 220 background_animation_.Reset(0.0); |
| 115 background_animation_.reset(new ui::SlideAnimation(this)); | 221 background_animation_.Show(); |
| 116 background_animation_->SetTweenType(ui::Tween::LINEAR); | 222 background_animate_state_ = ANIMATE_STATE_RUNNING; |
| 117 background_animation_->SetSlideDuration( | |
| 118 kBackgroundChangeDurationMs * InstantUI::GetSlowAnimationScaleFactor()); | |
| 119 } | |
| 120 background_animation_->Reset(0.0); | |
| 121 background_animation_->Show(); | |
| 122 } | 223 } |
| 123 | 224 |
| 124 void ToolbarSearchAnimator::Reset(TabContents* tab_contents) { | 225 void ToolbarSearchAnimator::Reset(TabContents* tab_contents) { |
| 125 bool notify_observers = animate_state_ != ANIMATE_STATE_NONE; | 226 bool notify_background_observers = |
| 126 animate_state_ = ANIMATE_STATE_NONE; | 227 background_animate_state_ != ANIMATE_STATE_NONE; |
| 228 bool notify_separator_observers = | |
| 229 separator_animate_state_ != ANIMATE_STATE_NONE; | |
| 230 background_animate_state_ = ANIMATE_STATE_NONE; | |
| 231 separator_animate_state_ = ANIMATE_STATE_NONE; | |
| 232 from_mode_ = to_mode_; | |
| 127 background_change_timer_.Stop(); | 233 background_change_timer_.Stop(); |
| 128 // If animation is still running, stopping it will trigger AnimationEnded | 234 // If animation is still running, stopping it will trigger AnimationEnded |
| 129 // where we've prevented from notifying observers via BackgroundChanged; | 235 // where we've prevented from firing OnToolbarBackgroundAnimatorProgressed |
| 130 // see comments in AnimationEnded. | 236 // and OnToolbarSeparatorAnimatorProgressed notifications; see comments in |
| 131 if (background_animation_.get()) | 237 // AnimationEnded. |
| 132 background_animation_->Stop(); | 238 background_animation_.Stop(); |
| 133 if (notify_observers) { | 239 separator_animation_.Stop(); |
| 240 if (notify_background_observers) { | |
| 134 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, | 241 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, |
| 135 OnToolbarBackgroundAnimatorCanceled(tab_contents)); | 242 OnToolbarBackgroundAnimatorCanceled(tab_contents)); |
| 136 } | 243 } |
| 244 if (notify_separator_observers) { | |
| 245 FOR_EACH_OBSERVER(ToolbarSearchAnimatorObserver, observers_, | |
| 246 OnToolbarSeparatorAnimatorCanceled()); | |
| 247 } | |
| 137 } | 248 } |
| 138 | 249 |
| 139 } // namespace search | 250 } // namespace search |
| 140 } // namespace chrome | 251 } // namespace chrome |
| OLD | NEW |