Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Side by Side Diff: chrome/browser/ui/search/toolbar_search_animator.cc

Issue 10816027: alternate ntp: toolbar background and separator animation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698